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 int idx, status = 0;
62 /* Validate rsc table header fields */
64 /* Minimum rsc table size */
65 if (sizeof(struct resource_table) > size) {
66 return (RPROC_ERR_RSC_TAB_TRUNC);
67 }
69 /* Supported version */
70 if (rsc_table->ver != RSC_TAB_SUPPORTED_VERSION) {
71 return (RPROC_ERR_RSC_TAB_VER);
72 }
74 /* Offset array */
75 if (sizeof(struct resource_table)
76 + rsc_table->num * sizeof(rsc_table->offset[0]) > size) {
77 return (RPROC_ERR_RSC_TAB_TRUNC);
78 }
80 /* Reserved fields - must be zero */
81 if ((rsc_table->reserved[0] != 0 || rsc_table->reserved[1]) != 0) {
82 return RPROC_ERR_RSC_TAB_RSVD;
83 }
85 rsc_start = (unsigned char *)rsc_table;
87 /* Loop through the offset array and parse each resource entry */
88 for (idx = 0; idx < rsc_table->num; idx++) {
89 rsc_offset =
90 (unsigned int *)(rsc_start + rsc_table->offset[idx]);
91 rsc_type = *rsc_offset;
92 status =
93 rsc_handler_table[rsc_type] (rproc, (void *)rsc_offset);
94 if (status != RPROC_SUCCESS) {
95 break;
96 }
97 }
99 return status;
100 }
102 /**
103 * handle_carve_out_rsc
104 *
105 * Carveout resource handler.
106 *
107 * @param rproc - pointer to remote remote_proc
108 * @param rsc - pointer to carveout resource
109 *
110 * @returns - execution status
111 *
112 */
113 int handle_carve_out_rsc(struct remote_proc *rproc, void *rsc)
114 {
115 struct fw_rsc_carveout *carve_rsc = (struct fw_rsc_carveout *)rsc;
117 /* Validate resource fields */
118 if (!carve_rsc) {
119 return RPROC_ERR_RSC_TAB_NP;
120 }
122 if (carve_rsc->reserved) {
123 return RPROC_ERR_RSC_TAB_RSVD;
124 }
126 if (rproc->role == RPROC_MASTER) {
127 /* Map memory region for loading the image */
128 env_map_memory(carve_rsc->da, carve_rsc->da, carve_rsc->len,
129 (SHARED_MEM | UNCACHED));
130 }
132 return RPROC_SUCCESS;
133 }
135 /**
136 * handle_trace_rsc
137 *
138 * Trace resource handler.
139 *
140 * @param rproc - pointer to remote remote_proc
141 * @param rsc - pointer to trace resource
142 *
143 * @returns - execution status
144 *
145 */
146 int handle_trace_rsc(struct remote_proc *rproc, void *rsc)
147 {
148 return RPROC_ERR_RSC_TAB_NS;
149 }
151 /**
152 * handle_dev_mem_rsc
153 *
154 * Device memory resource handler.
155 *
156 * @param rproc - pointer to remote remote_proc
157 * @param rsc - pointer to device memory resource
158 *
159 * @returns - execution status
160 *
161 */
162 int handle_dev_mem_rsc(struct remote_proc *rproc, void *rsc)
163 {
164 return RPROC_ERR_RSC_TAB_NS;
165 }
167 /**
168 * handle_vdev_rsc
169 *
170 * Virtio device resource handler
171 *
172 * @param rproc - pointer to remote remote_proc
173 * @param rsc - pointer to virtio device resource
174 *
175 * @returns - execution status
176 *
177 */
178 int handle_vdev_rsc(struct remote_proc *rproc, void *rsc)
179 {
181 struct fw_rsc_vdev *vdev_rsc = (struct fw_rsc_vdev *)rsc;
182 struct fw_rsc_vdev_vring *vring;
183 struct proc_vdev *vdev;
184 struct proc_vring *vring_table;
185 int idx;
187 if (!vdev_rsc) {
188 return RPROC_ERR_RSC_TAB_NP;
189 }
191 /* Maximum supported vrings per Virtio device */
192 if (vdev_rsc->num_of_vrings > RSC_TAB_MAX_VRINGS) {
193 return RPROC_ERR_RSC_TAB_VDEV_NRINGS;
194 }
196 /* Reserved fields - must be zero */
197 if (vdev_rsc->reserved[0] || vdev_rsc->reserved[1]) {
198 return RPROC_ERR_RSC_TAB_RSVD;
199 }
201 /* Get the Virtio device from HIL proc */
202 vdev = hil_get_vdev_info(rproc->proc);
204 /* Initialize HIL Virtio device resources */
205 vdev->num_vrings = vdev_rsc->num_of_vrings;
206 vdev->dfeatures = vdev_rsc->dfeatures;
207 vdev->gfeatures = vdev_rsc->gfeatures;
208 vring_table = &vdev->vring_info[0];
210 for (idx = 0; idx < vdev_rsc->num_of_vrings; idx++) {
211 vring = &vdev_rsc->vring[idx];
213 /* Initialize HIL vring resources */
214 vring_table[idx].phy_addr = (void *)vring->da;
215 vring_table[idx].num_descs = vring->num;
216 vring_table[idx].align = vring->align;
218 /* Enable access to vring memory regions */
219 env_map_memory(vring->da, vring->da,
220 vring_size(vring->num, vring->align),
221 (SHARED_MEM | UNCACHED));
222 }
224 return RPROC_SUCCESS;
225 }
227 /**
228 * handle_mmu_rsc
229 *
230 * This function parses mmu resource , requested by the peripheral.
231 *
232 * @param rproc - pointer to remote remote_proc
233 * @param rsc - pointer to mmu resource
234 *
235 * @returns - execution status
236 *
237 */
238 int handle_mmu_rsc(struct remote_proc *rproc, void *rsc)
239 {
240 return RPROC_ERR_RSC_TAB_NS;
241 }