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 <string.h>
31 #include "openamp/remoteproc_loader.h"
33 /**
34 * remoteproc_loader_init
35 *
36 * Initializes the remoteproc loader.
37 *
38 * @param type - loader type
39 *
40 * @return - remoteproc_loader
41 */
42 struct remoteproc_loader *remoteproc_loader_init(enum loader_type type)
43 {
45 struct remoteproc_loader *loader;
47 /* Check for valid loader type. */
48 if (type >= LAST_LOADER) {
49 return RPROC_NULL;
50 }
52 /* Allocate a loader handle. */
53 loader = env_allocate_memory(sizeof(struct remoteproc_loader));
55 if (!loader) {
56 return RPROC_NULL;
57 }
59 /* Clear loader handle. */
60 memset(loader, 0, sizeof(struct remoteproc_loader));
62 /* Save loader type. */
63 loader->type = type;
65 switch (type) {
67 case ELF_LOADER:
68 elf_loader_init(loader);
69 break;
71 default:
72 /* Loader not supported. */
73 env_free_memory(loader);
74 loader = RPROC_NULL;
75 break;
76 }
78 return loader;
79 }
81 /**
82 * remoteproc_loader_delete
83 *
84 * Deletes the remoteproc loader.
85 *
86 * @param loader - pointer to remoteproc loader
87 *
88 * @return - 0 if success, error otherwise
89 */
90 int remoteproc_loader_delete(struct remoteproc_loader *loader)
91 {
93 int status = 0;
95 if (!loader) {
96 return RPROC_ERR_PARAM;
97 }
99 /* Check if a firmware is attached. */
100 if (loader->remote_firmware) {
102 /* Detach firmware first. */
103 status = loader->detach_firmware(loader);
104 }
106 /* Recover the allocated memory. */
107 env_free_memory(loader);
109 return status;
110 }
112 /**
113 * remoteproc_loader_attach_firmware
114 *
115 * Attaches an ELF firmware to the loader
116 *
117 * @param loader - pointer to remoteproc loader
118 * @param firmware - pointer to the firmware start location
119 *
120 * @return - 0 if success, error otherwise
121 */
122 int remoteproc_loader_attach_firmware(struct remoteproc_loader *loader,
123 void *firmware_image)
124 {
126 int status = RPROC_SUCCESS;
128 if (!loader || !firmware_image) {
129 return RPROC_ERR_PARAM;
130 }
132 if (loader->attach_firmware) {
134 /* Check if a firmware is already attached. */
135 if (loader->remote_firmware) {
137 /* Detach firmware first. */
138 status = loader->detach_firmware(loader);
139 }
141 /* Attach firmware. */
142 if (!status) {
143 status =
144 loader->attach_firmware(loader, firmware_image);
146 /* Save firmware address. */
147 if (!status) {
148 loader->remote_firmware = firmware_image;
149 }
150 }
151 } else {
152 status = RPROC_ERR_LOADER;
153 }
155 return status;
156 }
158 /**
159 * remoteproc_loader_retrieve_entry_point
160 *
161 * Provides entry point address.
162 *
163 * @param loader - pointer to remoteproc loader
164 *
165 * @return - entrypoint
166 */
167 void *remoteproc_loader_retrieve_entry_point(struct remoteproc_loader *loader)
168 {
170 if (!loader) {
171 return RPROC_NULL;
172 }
174 if (loader->retrieve_entry) {
175 return loader->retrieve_entry(loader);
176 } else {
177 return RPROC_NULL;
178 }
179 }
181 /**
182 * remoteproc_loader_retrieve_resource_section
183 *
184 * Provides resource section address.
185 *
186 * @param loader - pointer to remoteproc loader
187 * @param size - pointer to hold size of resource section
188 *
189 * @return - pointer to resource section
190 */
191 void *remoteproc_loader_retrieve_resource_section(struct remoteproc_loader
192 *loader, unsigned int *size)
193 {
195 if (!loader) {
196 return RPROC_NULL;
197 }
199 if (loader->retrieve_rsc) {
200 return loader->retrieve_rsc(loader, size);
201 } else {
202 return RPROC_NULL;
203 }
204 }
206 /**
207 * remoteproc_loader_load_remote_firmware
208 *
209 * Loads the firmware in memory
210 *
211 * @param loader - pointer to remoteproc loader
212 *
213 * @return - 0 if success, error otherwise
214 */
215 int remoteproc_loader_load_remote_firmware(struct remoteproc_loader *loader)
216 {
218 if (!loader) {
219 return RPROC_ERR_PARAM;
220 }
222 if (loader->load_firmware) {
223 return loader->load_firmware(loader);
224 } else {
225 return RPROC_ERR_LOADER;
226 }
227 }
229 /**
230 * remoteproc_get_load_address
231 *
232 * Provides firmware load address.
233 *
234 * @param loader - pointer to remoteproc loader
235 *
236 * @return - load address pointer
237 */
238 void *remoteproc_get_load_address(struct remoteproc_loader *loader)
239 {
241 if (!loader) {
242 return RPROC_ERR_PTR;
243 }
245 if (loader->retrieve_load_addr) {
246 return loader->retrieve_load_addr(loader);
247 } else {
248 return RPROC_ERR_PTR;
249 }
250 }