1 /*
2 * Copyright (c) 2014, Mentor Graphics Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. Neither the name of Mentor Graphics Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
30 #include "openamp/rsc_table_parser.h"
32 /* Resources handler */
33 rsc_handler rsc_handler_table[] = {
34 handle_carve_out_rsc,
35 handle_trace_rsc,
36 handle_dev_mem_rsc,
37 handle_vdev_rsc,
38 handle_mmu_rsc
39 };
41 /**
42 * handle_rsc_table
43 *
44 * This function parses resource table.
45 *
46 * @param rproc - pointer to remote remote_proc
47 * @param rsc_table - resource table to parse
48 * @param size - size of rsc table
49 *
50 * @returns - execution status
51 *
52 */
53 int handle_rsc_table(struct remote_proc *rproc,
54 struct resource_table *rsc_table, int size)
55 {
57 unsigned char *rsc_start;
58 unsigned int *rsc_offset;
59 unsigned int rsc_type;
60 unsigned int idx;
61 int status = 0;
63 /* Validate rsc table header fields */
65 /* Minimum rsc table size */
66 if (sizeof(struct resource_table) > (unsigned int)size) {
67 return (RPROC_ERR_RSC_TAB_TRUNC);
68 }
70 /* Supported version */
71 if (rsc_table->ver != RSC_TAB_SUPPORTED_VERSION) {
72 return (RPROC_ERR_RSC_TAB_VER);
73 }
75 /* Offset array */
76 if (sizeof(struct resource_table)
77 + rsc_table->num * sizeof(rsc_table->offset[0]) > (unsigned int)size) {
78 return (RPROC_ERR_RSC_TAB_TRUNC);
79 }
81 /* Reserved fields - must be zero */
82 if ((rsc_table->reserved[0] != 0 || rsc_table->reserved[1]) != 0) {
83 return RPROC_ERR_RSC_TAB_RSVD;
84 }
86 rsc_start = (unsigned char *)rsc_table;
88 /* Loop through the offset array and parse each resource entry */
89 for (idx = 0; idx < rsc_table->num; idx++) {
90 rsc_offset =
91 (unsigned int *)(rsc_start + rsc_table->offset[idx]);
92 rsc_type = *rsc_offset;
93 status =
94 rsc_handler_table[rsc_type] (rproc, (void *)rsc_offset);
95 if (status != RPROC_SUCCESS) {
96 break;
97 }
98 }
100 return status;
101 }
103 /**
104 * handle_carve_out_rsc
105 *
106 * Carveout resource handler.
107 *
108 * @param rproc - pointer to remote remote_proc
109 * @param rsc - pointer to carveout resource
110 *
111 * @returns - execution status
112 *
113 */
114 int handle_carve_out_rsc(struct remote_proc *rproc, void *rsc)
115 {
116 struct fw_rsc_carveout *carve_rsc = (struct fw_rsc_carveout *)rsc;
118 /* Validate resource fields */
119 if (!carve_rsc) {
120 return RPROC_ERR_RSC_TAB_NP;
121 }
123 if (carve_rsc->reserved) {
124 return RPROC_ERR_RSC_TAB_RSVD;
125 }
127 if (rproc->role == RPROC_MASTER) {
128 /* Map memory region for loading the image */
129 env_map_memory(carve_rsc->da, carve_rsc->da, carve_rsc->len,
130 (SHARED_MEM | UNCACHED));
131 }
133 return RPROC_SUCCESS;
134 }
136 /**
137 * handle_trace_rsc
138 *
139 * Trace resource handler.
140 *
141 * @param rproc - pointer to remote remote_proc
142 * @param rsc - pointer to trace resource
143 *
144 * @returns - execution status
145 *
146 */
147 int handle_trace_rsc(struct remote_proc *rproc, void *rsc)
148 {
149 (void)rproc;
150 (void)rsc;
152 return RPROC_ERR_RSC_TAB_NS;
153 }
155 /**
156 * handle_dev_mem_rsc
157 *
158 * Device memory resource handler.
159 *
160 * @param rproc - pointer to remote remote_proc
161 * @param rsc - pointer to device memory resource
162 *
163 * @returns - execution status
164 *
165 */
166 int handle_dev_mem_rsc(struct remote_proc *rproc, void *rsc)
167 {
168 (void)rproc;
169 (void)rsc;
171 return RPROC_ERR_RSC_TAB_NS;
172 }
174 /**
175 * handle_vdev_rsc
176 *
177 * Virtio device resource handler
178 *
179 * @param rproc - pointer to remote remote_proc
180 * @param rsc - pointer to virtio device resource
181 *
182 * @returns - execution status
183 *
184 */
185 int handle_vdev_rsc(struct remote_proc *rproc, void *rsc)
186 {
188 struct fw_rsc_vdev *vdev_rsc = (struct fw_rsc_vdev *)rsc;
189 struct fw_rsc_vdev_vring *vring;
190 struct proc_vdev *vdev;
191 struct proc_vring *vring_table;
192 int idx;
194 if (!vdev_rsc) {
195 return RPROC_ERR_RSC_TAB_NP;
196 }
198 /* Maximum supported vrings per Virtio device */
199 if (vdev_rsc->num_of_vrings > RSC_TAB_MAX_VRINGS) {
200 return RPROC_ERR_RSC_TAB_VDEV_NRINGS;
201 }
203 /* Reserved fields - must be zero */
204 if (vdev_rsc->reserved[0] || vdev_rsc->reserved[1]) {
205 return RPROC_ERR_RSC_TAB_RSVD;
206 }
208 /* Get the Virtio device from HIL proc */
209 vdev = hil_get_vdev_info(rproc->proc);
211 /* Initialize HIL Virtio device resources */
212 vdev->num_vrings = vdev_rsc->num_of_vrings;
213 vdev->dfeatures = vdev_rsc->dfeatures;
214 vdev->gfeatures = vdev_rsc->gfeatures;
215 vring_table = &vdev->vring_info[0];
217 for (idx = 0; idx < vdev_rsc->num_of_vrings; idx++) {
218 vring = &vdev_rsc->vring[idx];
220 /* Initialize HIL vring resources */
221 vring_table[idx].phy_addr = (void *)vring->da;
222 vring_table[idx].num_descs = vring->num;
223 vring_table[idx].align = vring->align;
225 /* Enable access to vring memory regions */
226 env_map_memory(vring->da, vring->da,
227 vring_size(vring->num, vring->align),
228 (SHARED_MEM | UNCACHED));
229 }
231 return RPROC_SUCCESS;
232 }
234 /**
235 * handle_mmu_rsc
236 *
237 * This function parses mmu resource , requested by the peripheral.
238 *
239 * @param rproc - pointer to remote remote_proc
240 * @param rsc - pointer to mmu resource
241 *
242 * @returns - execution status
243 *
244 */
245 int handle_mmu_rsc(struct remote_proc *rproc, void *rsc)
246 {
247 (void)rproc;
248 (void)rsc;
250 return RPROC_ERR_RSC_TAB_NS;
251 }