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>&copy; 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