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/remoteproc_loader.h"
32 /**
33 * remoteproc_loader_init
34 *
35 * Initializes the remoteproc loader.
36 *
37 * @param type - loader type
38 *
39 * @return - remoteproc_loader
40 */
41 struct remoteproc_loader *remoteproc_loader_init(enum loader_type type)
42 {
44 struct remoteproc_loader *loader;
46 /* Check for valid loader type. */
47 if (type >= LAST_LOADER) {
48 return RPROC_NULL;
49 }
51 /* Allocate a loader handle. */
52 loader = env_allocate_memory(sizeof(struct remoteproc_loader));
54 if (!loader) {
55 return RPROC_NULL;
56 }
58 /* Clear loader handle. */
59 env_memset(loader, 0, sizeof(struct remoteproc_loader));
61 /* Save loader type. */
62 loader->type = type;
64 switch (type) {
66 case ELF_LOADER:
67 elf_loader_init(loader);
68 break;
70 default:
71 /* Loader not supported. */
72 env_free_memory(loader);
73 loader = RPROC_NULL;
74 break;
75 }
77 return loader;
78 }
80 /**
81 * remoteproc_loader_delete
82 *
83 * Deletes the remoteproc loader.
84 *
85 * @param loader - pointer to remoteproc loader
86 *
87 * @return - 0 if success, error otherwise
88 */
89 int remoteproc_loader_delete(struct remoteproc_loader *loader)
90 {
92 int status = 0;
94 if (!loader) {
95 return RPROC_ERR_PARAM;
96 }
98 /* Check if a firmware is attached. */
99 if (loader->remote_firmware) {
101 /* Detach firmware first. */
102 status = loader->detach_firmware(loader);
103 }
105 /* Recover the allocated memory. */
106 env_free_memory(loader);
108 return status;
109 }
111 /**
112 * remoteproc_loader_attach_firmware
113 *
114 * Attaches an ELF firmware to the loader
115 *
116 * @param loader - pointer to remoteproc loader
117 * @param firmware - pointer to the firmware start location
118 *
119 * @return - 0 if success, error otherwise
120 */
121 int remoteproc_loader_attach_firmware(struct remoteproc_loader *loader,
122 void *firmware_image)
123 {
125 int status = RPROC_SUCCESS;
127 if (!loader || !firmware_image) {
128 return RPROC_ERR_PARAM;
129 }
131 if (loader->attach_firmware) {
133 /* Check if a firmware is already attached. */
134 if (loader->remote_firmware) {
136 /* Detach firmware first. */
137 status = loader->detach_firmware(loader);
138 }
140 /* Attach firmware. */
141 if (!status) {
142 status =
143 loader->attach_firmware(loader, firmware_image);
145 /* Save firmware address. */
146 if (!status) {
147 loader->remote_firmware = firmware_image;
148 }
149 }
150 } else {
151 status = RPROC_ERR_LOADER;
152 }
154 return status;
155 }
157 /**
158 * remoteproc_loader_retrieve_entry_point
159 *
160 * Provides entry point address.
161 *
162 * @param loader - pointer to remoteproc loader
163 *
164 * @return - entrypoint
165 */
166 void *remoteproc_loader_retrieve_entry_point(struct remoteproc_loader *loader)
167 {
169 if (!loader) {
170 return RPROC_NULL;
171 }
173 if (loader->retrieve_entry) {
174 return loader->retrieve_entry(loader);
175 } else {
176 return RPROC_NULL;
177 }
178 }
180 /**
181 * remoteproc_loader_retrieve_resource_section
182 *
183 * Provides resource section address.
184 *
185 * @param loader - pointer to remoteproc loader
186 * @param size - pointer to hold size of resource section
187 *
188 * @return - pointer to resource section
189 */
190 void *remoteproc_loader_retrieve_resource_section(struct remoteproc_loader
191 *loader, unsigned int *size)
192 {
194 if (!loader) {
195 return RPROC_NULL;
196 }
198 if (loader->retrieve_rsc) {
199 return loader->retrieve_rsc(loader, size);
200 } else {
201 return RPROC_NULL;
202 }
203 }
205 /**
206 * remoteproc_loader_load_remote_firmware
207 *
208 * Loads the firmware in memory
209 *
210 * @param loader - pointer to remoteproc loader
211 *
212 * @return - 0 if success, error otherwise
213 */
214 int remoteproc_loader_load_remote_firmware(struct remoteproc_loader *loader)
215 {
217 if (!loader) {
218 return RPROC_ERR_PARAM;
219 }
221 if (loader->load_firmware) {
222 return loader->load_firmware(loader);
223 } else {
224 return RPROC_ERR_LOADER;
225 }
226 }
228 /**
229 * remoteproc_get_load_address
230 *
231 * Provides firmware load address.
232 *
233 * @param loader - pointer to remoteproc loader
234 *
235 * @return - load address pointer
236 */
237 void *remoteproc_get_load_address(struct remoteproc_loader *loader)
238 {
240 if (!loader) {
241 return RPROC_ERR_PTR;
242 }
244 if (loader->retrieve_load_addr) {
245 return loader->retrieve_load_addr(loader);
246 } else {
247 return RPROC_ERR_PTR;
248 }
249 }