1 /**
2 ******************************************************************************
3 * @file rsc_table.c
4 * @author MCD Application Team
5 * @brief Ressource table
6 *
7 * This file provides a default resource table requested by remote proc to
8 * load the elf file. It also allows to add debug trace using a shared buffer.
9 *
10 ******************************************************************************
11 * @attention
12 *
13 * <h2><center>© Copyright (c) 2019 STMicroelectronics.
14 * All rights reserved.</center></h2>
15 *
16 * This software component is licensed by ST under BSD 3-Clause license,
17 * the "License"; You may not use this file except in compliance with the
18 * License. You may obtain a copy of the License at:
19 * opensource.org/licenses/BSD-3-Clause
20 *
21 ******************************************************************************
22 */
23
24 /** @addtogroup RSC_TABLE
25 * @{
26 */
27
28 /** @addtogroup resource_table
29 * @{
30 */
31
32 /** @addtogroup resource_table_Private_Includes
33 * @{
34 */
35
36 #if defined(__ICCARM__) || defined (__CC_ARM)
37 #include <stddef.h> /* needed for offsetof definition*/
38 #endif
39 #include "rsc_table.h"
40 #include "openamp/open_amp.h"
41
42 /**
43 * @}
44 */
45
46 /** @addtogroup resource_table_Private_TypesDefinitions
47 * @{
48 */
49
50 /**
51 * @}
52 */
53
54 /** @addtogroup resource_table_Private_Defines
55 * @{
56 */
57
58 /* Place resource table in special ELF section */
59 #if defined(__GNUC__)
60 #define __section_t(S) __attribute__((__section__(#S)))
61 #define __resource __section_t(.resource_table)
62 #endif
63
64 #if defined (LINUX_RPROC_MASTER)
65 #ifdef VIRTIO_MASTER_ONLY
66 #define CONST
67 #else
68 #define CONST const
69 #endif
70 #else
71 #define CONST
72 #endif
73
74 #define RPMSG_IPU_C0_FEATURES 1
75 #define VRING_COUNT 2
76
77 /* VirtIO rpmsg device id */
78 #define VIRTIO_ID_RPMSG_ 7
79
80 #if defined (__LOG_TRACE_IO_)
81 extern char system_log_buf[];
82 #endif
83
84 #if defined(__GNUC__)
85 #if !defined (__CC_ARM) && !defined (LINUX_RPROC_MASTER)
86
87 /* Since GCC is not initializing the resource_table at startup, it is declared as volatile to avoid compiler optimization
88 * for the CM4 (see resource_table_init() below)
89 */
90 volatile struct shared_resource_table __resource __attribute__((used)) resource_table;
91 #else
92 CONST struct shared_resource_table __resource __attribute__((used)) resource_table = {
93 #endif
94 #elif defined(__ICCARM__)
95 __root CONST struct shared_resource_table resource_table @ ".resource_table" = {
96 #endif
97
98 #if defined(__ICCARM__) || defined (__CC_ARM) || defined (LINUX_RPROC_MASTER)
99 .version = 1,
100 #if defined (__LOG_TRACE_IO_)
101 .num = 2,
102 #else
103 .num = 1,
104 #endif
105 .reserved = {0, 0},
106 .offset = {
107 offsetof(struct shared_resource_table, vdev),
108 offsetof(struct shared_resource_table, cm_trace),
109 },
110
111 /* Virtio device entry */
112 .vdev= {
113 RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0,
114 VRING_COUNT, {0, 0},
115 },
116
117 /* Vring rsc entry - part of vdev rsc entry */
118 .vring0 = {VRING_TX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING0_ID, 0},
119 .vring1 = {VRING_RX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING1_ID, 0},
120
121 #if defined (__LOG_TRACE_IO_)
122 .cm_trace = {
123 RSC_TRACE,
124 (uint32_t)system_log_buf, SYSTEM_TRACE_BUF_SZ, 0, "cm4_log",
125 },
126 #endif
127 } ;
128 #endif
129
resource_table_init(int RPMsgRole,void ** table_ptr,int * length)130 void resource_table_init(int RPMsgRole, void **table_ptr, int *length)
131 {
132
133 #if !defined (LINUX_RPROC_MASTER)
134 #if defined (__GNUC__) && ! defined (__CC_ARM)
135 #ifdef VIRTIO_MASTER_ONLY
136
137 /*
138 * Currently the GCC linker doesn't initialize the resource_table global variable at startup
139 * it is done here by the master application.
140 */
141 memset(&resource_table, '\0', sizeof(struct shared_resource_table));
142 resource_table.num = 1;
143 resource_table.version = 1;
144 resource_table.offset[0] = offsetof(struct shared_resource_table, vdev);
145
146 resource_table.vring0.da = VRING_TX_ADDRESS;
147 resource_table.vring0.align = VRING_ALIGNMENT;
148 resource_table.vring0.num = VRING_NUM_BUFFS;
149 resource_table.vring0.notifyid = VRING0_ID;
150
151 resource_table.vring1.da = VRING_RX_ADDRESS;
152 resource_table.vring1.align = VRING_ALIGNMENT;
153 resource_table.vring1.num = VRING_NUM_BUFFS;
154 resource_table.vring1.notifyid = VRING1_ID;
155
156 resource_table.vdev.type = RSC_VDEV;
157 resource_table.vdev.id = VIRTIO_ID_RPMSG_;
158 resource_table.vdev.num_of_vrings=VRING_COUNT;
159 resource_table.vdev.dfeatures = RPMSG_IPU_C0_FEATURES;
160 #else
161
162 /* For the slave application let's wait until the resource_table is correctly initialized */
163 while(resource_table.vring1.da != VRING_RX_ADDRESS)
164 {
165
166 }
167 #endif
168 #endif
169 #endif
170
171 (void)RPMsgRole;
172 *length = sizeof(resource_table);
173 *table_ptr = (void *)&resource_table;
174 }
175