apps: machine: zynqmp_r5: correct IPI setting.
[processor-sdk/open-amp.git] / lib / remoteproc / remoteproc_loader.c
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 "metal/alloc.h"
32 #include "openamp/remoteproc_loader.h"
34 /**
35  * remoteproc_loader_init
36  *
37  * Initializes the remoteproc loader.
38  *
39  * @param type - loader type
40  *
41  * @return  - remoteproc_loader
42  */
43 struct remoteproc_loader *remoteproc_loader_init(enum loader_type type)
44 {
46         struct remoteproc_loader *loader;
48         /* Check for valid loader type. */
49         if (type >= LAST_LOADER) {
50                 return RPROC_NULL;
51         }
53         /* Allocate a loader handle. */
54         loader = metal_allocate_memory(sizeof(struct remoteproc_loader));
56         if (!loader) {
57                 return RPROC_NULL;
58         }
60         /* Clear loader handle. */
61         memset(loader, 0, sizeof(struct remoteproc_loader));
63         /* Save loader type. */
64         loader->type = type;
66         switch (type) {
68         case ELF_LOADER:
69                 elf_loader_init(loader);
70                 break;
72         default:
73                 /* Loader not supported. */
74                 metal_free_memory(loader);
75                 loader = RPROC_NULL;
76                 break;
77         }
79         return loader;
80 }
82 /**
83  * remoteproc_loader_delete
84  *
85  * Deletes the remoteproc loader.
86  *
87  * @param loader    - pointer to remoteproc loader
88  *
89  * @return  - 0 if success, error otherwise
90  */
91 int remoteproc_loader_delete(struct remoteproc_loader *loader)
92 {
94         int status = 0;
96         if (!loader) {
97                 return RPROC_ERR_PARAM;
98         }
100         /* Check if a firmware is attached. */
101         if (loader->remote_firmware) {
103                 /* Detach firmware first. */
104                 status = loader->detach_firmware(loader);
105         }
107         /* Recover the allocated memory. */
108         metal_free_memory(loader);
110         return status;
113 /**
114  * remoteproc_loader_attach_firmware
115  *
116  * Attaches an ELF firmware to the loader
117  *
118  * @param loader    - pointer to remoteproc loader
119  * @param firmware  - pointer to the firmware start location
120  *
121  * @return  - 0 if success, error otherwise
122  */
123 int remoteproc_loader_attach_firmware(struct remoteproc_loader *loader,
124                                       void *firmware_image)
127         int status = RPROC_SUCCESS;
129         if (!loader || !firmware_image) {
130                 return RPROC_ERR_PARAM;
131         }
133         if (loader->attach_firmware) {
135                 /* Check if a firmware is already attached. */
136                 if (loader->remote_firmware) {
138                         /* Detach firmware first. */
139                         status = loader->detach_firmware(loader);
140                 }
142                 /* Attach firmware. */
143                 if (!status) {
144                         status =
145                             loader->attach_firmware(loader, firmware_image);
147                         /* Save firmware address. */
148                         if (!status) {
149                                 loader->remote_firmware = firmware_image;
150                         }
151                 }
152         } else {
153                 status = RPROC_ERR_LOADER;
154         }
156         return status;
159 /**
160  * remoteproc_loader_retrieve_entry_point
161  *
162  * Provides entry point address.
163  *
164  * @param loader - pointer to remoteproc loader
165  *
166  * @return  - entrypoint
167  */
168 void *remoteproc_loader_retrieve_entry_point(struct remoteproc_loader *loader)
171         if (!loader) {
172                 return RPROC_NULL;
173         }
175         if (loader->retrieve_entry) {
176                 return loader->retrieve_entry(loader);
177         } else {
178                 return RPROC_NULL;
179         }
182 /**
183  * remoteproc_loader_retrieve_resource_section
184  *
185  * Provides resource section address.
186  *
187  * @param loader - pointer to remoteproc loader
188  * @param size   - pointer to hold size of resource section
189  *
190  * @return  - pointer to resource section
191  */
192 void *remoteproc_loader_retrieve_resource_section(struct remoteproc_loader
193                                                   *loader, unsigned int *size)
196         if (!loader) {
197                 return RPROC_NULL;
198         }
200         if (loader->retrieve_rsc) {
201                 return loader->retrieve_rsc(loader, size);
202         } else {
203                 return RPROC_NULL;
204         }
207 /**
208  * remoteproc_loader_load_remote_firmware
209  *
210  * Loads the firmware in memory
211  *
212  * @param loader - pointer to remoteproc loader
213  *
214  * @return  - 0 if success, error otherwise
215  */
216 int remoteproc_loader_load_remote_firmware(struct remoteproc_loader *loader)
219         if (!loader) {
220                 return RPROC_ERR_PARAM;
221         }
223         if (loader->load_firmware) {
224                 return loader->load_firmware(loader);
225         } else {
226                 return RPROC_ERR_LOADER;
227         }
230 /**
231  * remoteproc_get_load_address
232  *
233  * Provides firmware load address.
234  *
235  * @param loader - pointer to remoteproc loader
236  *
237  * @return  - load address pointer
238  */
239 void *remoteproc_get_load_address(struct remoteproc_loader *loader)
242         if (!loader) {
243                 return RPROC_ERR_PTR;
244         }
246         if (loader->retrieve_load_addr) {
247                 return loader->retrieve_load_addr(loader);
248         } else {
249                 return RPROC_ERR_PTR;
250         }