1 // SPDX-License-Identifier: GPL-2.0-only
3 * Remote Processor Framework Elf loader
5 * Copyright (C) 2011 Texas Instruments, Inc.
6 * Copyright (C) 2011 Google, Inc.
8 * Ohad Ben-Cohen <ohad@wizery.com>
9 * Brian Swetland <swetland@google.com>
10 * Mark Grosen <mgrosen@ti.com>
11 * Fernando Guzman Lugo <fernando.lugo@ti.com>
12 * Suman Anna <s-anna@ti.com>
13 * Robert Tivy <rtivy@ti.com>
14 * Armando Uribe De Leon <x0095078@ti.com>
15 * Sjur Brændeland <sjur.brandeland@stericsson.com>
18 #define pr_fmt(fmt) "%s: " fmt, __func__
20 #include <linux/module.h>
21 #include <linux/firmware.h>
22 #include <linux/remoteproc.h>
23 #include <linux/elf.h>
25 #include "remoteproc_internal.h"
28 * rproc_elf_sanity_check() - Sanity Check ELF firmware image
29 * @rproc: the remote processor handle
30 * @fw: the ELF firmware image
32 * Make sure this fw image is sane.
34 int rproc_elf_sanity_check(struct rproc
*rproc
, const struct firmware
*fw
)
36 const char *name
= rproc
->firmware
;
37 struct device
*dev
= &rproc
->dev
;
38 struct elf32_hdr
*ehdr
;
42 dev_err(dev
, "failed to load %s\n", name
);
46 if (fw
->size
< sizeof(struct elf32_hdr
)) {
47 dev_err(dev
, "Image is too small\n");
51 ehdr
= (struct elf32_hdr
*)fw
->data
;
53 /* We only support ELF32 at this point */
54 class = ehdr
->e_ident
[EI_CLASS
];
55 if (class != ELFCLASS32
) {
56 dev_err(dev
, "Unsupported class: %d\n", class);
60 /* We assume the firmware has the same endianness as the host */
61 # ifdef __LITTLE_ENDIAN
62 if (ehdr
->e_ident
[EI_DATA
] != ELFDATA2LSB
) {
63 # else /* BIG ENDIAN */
64 if (ehdr
->e_ident
[EI_DATA
] != ELFDATA2MSB
) {
66 dev_err(dev
, "Unsupported firmware endianness\n");
70 if (fw
->size
< ehdr
->e_shoff
+ sizeof(struct elf32_shdr
)) {
71 dev_err(dev
, "Image is too small\n");
75 if (memcmp(ehdr
->e_ident
, ELFMAG
, SELFMAG
)) {
76 dev_err(dev
, "Image is corrupted (bad magic)\n");
80 if (ehdr
->e_phnum
== 0) {
81 dev_err(dev
, "No loadable segments\n");
85 if (ehdr
->e_phoff
> fw
->size
) {
86 dev_err(dev
, "Firmware size is too small\n");
92 EXPORT_SYMBOL(rproc_elf_sanity_check
);
95 * rproc_elf_get_boot_addr() - Get rproc's boot address.
96 * @rproc: the remote processor handle
97 * @fw: the ELF firmware image
99 * This function returns the entry point address of the ELF
102 * Note that the boot address is not a configurable property of all remote
103 * processors. Some will always boot at a specific hard-coded address.
105 u32
rproc_elf_get_boot_addr(struct rproc
*rproc
, const struct firmware
*fw
)
107 struct elf32_hdr
*ehdr
= (struct elf32_hdr
*)fw
->data
;
109 return ehdr
->e_entry
;
111 EXPORT_SYMBOL(rproc_elf_get_boot_addr
);
114 * rproc_elf_load_segments() - load firmware segments to memory
115 * @rproc: remote processor which will be booted using these fw segments
116 * @fw: the ELF firmware image
118 * This function loads the firmware segments to memory, where the remote
119 * processor expects them.
121 * Some remote processors will expect their code and data to be placed
122 * in specific device addresses, and can't have them dynamically assigned.
124 * We currently support only those kind of remote processors, and expect
125 * the program header's paddr member to contain those addresses. We then go
126 * through the physically contiguous "carveout" memory regions which we
127 * allocated (and mapped) earlier on behalf of the remote processor,
128 * and "translate" device address to kernel addresses, so we can copy the
129 * segments where they are expected.
131 * Currently we only support remote processors that required carveout
132 * allocations and got them mapped onto their iommus. Some processors
133 * might be different: they might not have iommus, and would prefer to
134 * directly allocate memory for every segment/resource. This is not yet
137 int rproc_elf_load_segments(struct rproc
*rproc
, const struct firmware
*fw
)
139 struct device
*dev
= &rproc
->dev
;
140 struct elf32_hdr
*ehdr
;
141 struct elf32_phdr
*phdr
;
143 const u8
*elf_data
= fw
->data
;
145 ehdr
= (struct elf32_hdr
*)elf_data
;
146 phdr
= (struct elf32_phdr
*)(elf_data
+ ehdr
->e_phoff
);
148 /* go through the available ELF segments */
149 for (i
= 0; i
< ehdr
->e_phnum
; i
++, phdr
++) {
150 u32 da
= phdr
->p_paddr
;
151 u32 memsz
= phdr
->p_memsz
;
152 u32 filesz
= phdr
->p_filesz
;
153 u32 offset
= phdr
->p_offset
;
156 if (phdr
->p_type
!= PT_LOAD
)
159 dev_dbg(dev
, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n",
160 phdr
->p_type
, da
, memsz
, filesz
);
162 if (filesz
> memsz
) {
163 dev_err(dev
, "bad phdr filesz 0x%x memsz 0x%x\n",
169 if (offset
+ filesz
> fw
->size
) {
170 dev_err(dev
, "truncated fw: need 0x%x avail 0x%zx\n",
171 offset
+ filesz
, fw
->size
);
176 /* grab the kernel address for this device address */
177 ptr
= rproc_da_to_va(rproc
, da
, memsz
);
179 dev_err(dev
, "bad phdr da 0x%x mem 0x%x\n", da
, memsz
);
184 /* put the segment where the remote processor expects it */
186 memcpy(ptr
, elf_data
+ phdr
->p_offset
, filesz
);
189 * Zero out remaining memory for this segment.
191 * This isn't strictly required since dma_alloc_coherent already
192 * did this for us. albeit harmless, we may consider removing
196 memset(ptr
+ filesz
, 0, memsz
- filesz
);
201 EXPORT_SYMBOL(rproc_elf_load_segments
);
203 static struct elf32_shdr
*
204 find_table(struct device
*dev
, struct elf32_hdr
*ehdr
, size_t fw_size
)
206 struct elf32_shdr
*shdr
;
208 const char *name_table
;
209 struct resource_table
*table
= NULL
;
210 const u8
*elf_data
= (void *)ehdr
;
212 /* look for the resource table and handle it */
213 shdr
= (struct elf32_shdr
*)(elf_data
+ ehdr
->e_shoff
);
214 name_table
= elf_data
+ shdr
[ehdr
->e_shstrndx
].sh_offset
;
216 for (i
= 0; i
< ehdr
->e_shnum
; i
++, shdr
++) {
217 u32 size
= shdr
->sh_size
;
218 u32 offset
= shdr
->sh_offset
;
220 if (strcmp(name_table
+ shdr
->sh_name
, ".resource_table"))
223 table
= (struct resource_table
*)(elf_data
+ offset
);
225 /* make sure we have the entire table */
226 if (offset
+ size
> fw_size
|| offset
+ size
< size
) {
227 dev_err(dev
, "resource table truncated\n");
231 /* make sure table has at least the header */
232 if (sizeof(struct resource_table
) > size
) {
233 dev_err(dev
, "header-less resource table\n");
237 /* we don't support any version beyond the first */
238 if (table
->ver
!= 1) {
239 dev_err(dev
, "unsupported fw ver: %d\n", table
->ver
);
243 /* make sure reserved bytes are zeroes */
244 if (table
->reserved
[0] || table
->reserved
[1]) {
245 dev_err(dev
, "non zero reserved bytes\n");
249 /* make sure the offsets array isn't truncated */
250 if (struct_size(table
, offset
, table
->num
) > size
) {
251 dev_err(dev
, "resource table incomplete\n");
262 * rproc_elf_load_rsc_table() - load the resource table
263 * @rproc: the rproc handle
264 * @fw: the ELF firmware image
266 * This function finds the resource table inside the remote processor's
267 * firmware, load it into the @cached_table and update @table_ptr.
269 * Return: 0 on success, negative errno on failure.
271 int rproc_elf_load_rsc_table(struct rproc
*rproc
, const struct firmware
*fw
)
273 struct elf32_hdr
*ehdr
;
274 struct elf32_shdr
*shdr
;
275 struct device
*dev
= &rproc
->dev
;
276 struct resource_table
*table
= NULL
;
277 const u8
*elf_data
= fw
->data
;
280 ehdr
= (struct elf32_hdr
*)elf_data
;
282 shdr
= find_table(dev
, ehdr
, fw
->size
);
286 table
= (struct resource_table
*)(elf_data
+ shdr
->sh_offset
);
287 tablesz
= shdr
->sh_size
;
290 * Create a copy of the resource table. When a virtio device starts
291 * and calls vring_new_virtqueue() the address of the allocated vring
292 * will be stored in the cached_table. Before the device is started,
293 * cached_table will be copied into device memory.
295 rproc
->cached_table
= kmemdup(table
, tablesz
, GFP_KERNEL
);
296 if (!rproc
->cached_table
)
299 rproc
->table_ptr
= rproc
->cached_table
;
300 rproc
->table_sz
= tablesz
;
304 EXPORT_SYMBOL(rproc_elf_load_rsc_table
);
307 * rproc_elf_find_loaded_rsc_table() - find the loaded resource table
308 * @rproc: the rproc handle
309 * @fw: the ELF firmware image
311 * This function finds the location of the loaded resource table. Don't
312 * call this function if the table wasn't loaded yet - it's a bug if you do.
314 * Returns the pointer to the resource table if it is found or NULL otherwise.
315 * If the table wasn't loaded yet the result is unspecified.
317 struct resource_table
*rproc_elf_find_loaded_rsc_table(struct rproc
*rproc
,
318 const struct firmware
*fw
)
320 struct elf32_hdr
*ehdr
= (struct elf32_hdr
*)fw
->data
;
321 struct elf32_shdr
*shdr
;
323 shdr
= find_table(&rproc
->dev
, ehdr
, fw
->size
);
327 return rproc_da_to_va(rproc
, shdr
->sh_addr
, shdr
->sh_size
);
329 EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table
);