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"
26 #include "remoteproc_elf_helpers.h"
29 * rproc_elf_sanity_check() - Sanity Check for ELF32/ELF64 firmware image
30 * @rproc: the remote processor handle
31 * @fw: the ELF firmware image
33 * Make sure this fw image is sane (ie a correct ELF32/ELF64 file).
35 * Return: 0 on success and -EINVAL upon any failure
37 int rproc_elf_sanity_check(struct rproc
*rproc
, const struct firmware
*fw
)
39 const char *name
= rproc
->firmware
;
40 struct device
*dev
= &rproc
->dev
;
42 * ELF files are beginning with the same structure. Thus, to simplify
43 * header parsing, we can use the elf32_hdr one for both elf64 and
46 struct elf32_hdr
*ehdr
;
47 u32 elf_shdr_get_size
;
53 dev_err(dev
, "failed to load %s\n", name
);
57 if (fw
->size
< sizeof(struct elf32_hdr
)) {
58 dev_err(dev
, "Image is too small\n");
62 ehdr
= (struct elf32_hdr
*)fw
->data
;
64 if (memcmp(ehdr
->e_ident
, ELFMAG
, SELFMAG
)) {
65 dev_err(dev
, "Image is corrupted (bad magic)\n");
69 class = ehdr
->e_ident
[EI_CLASS
];
70 if (class != ELFCLASS32
&& class != ELFCLASS64
) {
71 dev_err(dev
, "Unsupported class: %d\n", class);
75 if (class == ELFCLASS64
&& fw
->size
< sizeof(struct elf64_hdr
)) {
76 dev_err(dev
, "elf64 header is too small\n");
80 /* We assume the firmware has the same endianness as the host */
81 # ifdef __LITTLE_ENDIAN
82 if (ehdr
->e_ident
[EI_DATA
] != ELFDATA2LSB
) {
83 # else /* BIG ENDIAN */
84 if (ehdr
->e_ident
[EI_DATA
] != ELFDATA2MSB
) {
86 dev_err(dev
, "Unsupported firmware endianness\n");
90 phoff
= elf_hdr_get_e_phoff(class, fw
->data
);
91 shoff
= elf_hdr_get_e_shoff(class, fw
->data
);
92 phnum
= elf_hdr_get_e_phnum(class, fw
->data
);
93 elf_shdr_get_size
= elf_size_of_shdr(class);
95 if (fw
->size
< shoff
+ elf_shdr_get_size
) {
96 dev_err(dev
, "Image is too small\n");
101 dev_err(dev
, "No loadable segments\n");
105 if (phoff
> fw
->size
) {
106 dev_err(dev
, "Firmware size is too small\n");
110 dev_dbg(dev
, "Firmware is an elf%d file\n",
111 class == ELFCLASS32
? 32 : 64);
115 EXPORT_SYMBOL(rproc_elf_sanity_check
);
118 * rproc_elf_get_boot_addr() - Get rproc's boot address.
119 * @rproc: the remote processor handle
120 * @fw: the ELF firmware image
122 * Note that the boot address is not a configurable property of all remote
123 * processors. Some will always boot at a specific hard-coded address.
125 * Return: entry point address of the ELF image
128 u64
rproc_elf_get_boot_addr(struct rproc
*rproc
, const struct firmware
*fw
)
130 return elf_hdr_get_e_entry(fw_elf_get_class(fw
), fw
->data
);
132 EXPORT_SYMBOL(rproc_elf_get_boot_addr
);
135 * rproc_elf_load_segments() - load firmware segments to memory
136 * @rproc: remote processor which will be booted using these fw segments
137 * @fw: the ELF firmware image
139 * This function loads the firmware segments to memory, where the remote
140 * processor expects them.
142 * Some remote processors will expect their code and data to be placed
143 * in specific device addresses, and can't have them dynamically assigned.
145 * We currently support only those kind of remote processors, and expect
146 * the program header's paddr member to contain those addresses. We then go
147 * through the physically contiguous "carveout" memory regions which we
148 * allocated (and mapped) earlier on behalf of the remote processor,
149 * and "translate" device address to kernel addresses, so we can copy the
150 * segments where they are expected.
152 * Currently we only support remote processors that required carveout
153 * allocations and got them mapped onto their iommus. Some processors
154 * might be different: they might not have iommus, and would prefer to
155 * directly allocate memory for every segment/resource. This is not yet
158 * Return: 0 on success and an appropriate error code otherwise
160 int rproc_elf_load_segments(struct rproc
*rproc
, const struct firmware
*fw
)
162 struct device
*dev
= &rproc
->dev
;
163 const void *ehdr
, *phdr
;
166 const u8
*elf_data
= fw
->data
;
167 u8
class = fw_elf_get_class(fw
);
168 u32 elf_phdr_get_size
= elf_size_of_phdr(class);
171 phnum
= elf_hdr_get_e_phnum(class, ehdr
);
172 phdr
= elf_data
+ elf_hdr_get_e_phoff(class, ehdr
);
174 /* go through the available ELF segments */
175 for (i
= 0; i
< phnum
; i
++, phdr
+= elf_phdr_get_size
) {
176 u64 da
= elf_phdr_get_p_paddr(class, phdr
);
177 u64 memsz
= elf_phdr_get_p_memsz(class, phdr
);
178 u64 filesz
= elf_phdr_get_p_filesz(class, phdr
);
179 u64 offset
= elf_phdr_get_p_offset(class, phdr
);
180 u32 type
= elf_phdr_get_p_type(class, phdr
);
181 bool is_iomem
= false;
184 if (type
!= PT_LOAD
|| !memsz
)
187 dev_dbg(dev
, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
188 type
, da
, memsz
, filesz
);
190 if (filesz
> memsz
) {
191 dev_err(dev
, "bad phdr filesz 0x%llx memsz 0x%llx\n",
197 if (offset
+ filesz
> fw
->size
) {
198 dev_err(dev
, "truncated fw: need 0x%llx avail 0x%zx\n",
199 offset
+ filesz
, fw
->size
);
204 if (!rproc_u64_fit_in_size_t(memsz
)) {
205 dev_err(dev
, "size (%llx) does not fit in size_t type\n",
211 /* grab the kernel address for this device address */
212 ptr
= rproc_da_to_va(rproc
, da
, memsz
, &is_iomem
);
214 dev_err(dev
, "bad phdr da 0x%llx mem 0x%llx\n", da
,
220 /* put the segment where the remote processor expects it */
223 memcpy_toio((void __iomem
*)ptr
, elf_data
+ offset
, filesz
);
225 memcpy(ptr
, elf_data
+ offset
, filesz
);
229 * Zero out remaining memory for this segment.
231 * This isn't strictly required since dma_alloc_coherent already
232 * did this for us. albeit harmless, we may consider removing
235 if (memsz
> filesz
) {
237 memset_io((void __iomem
*)(ptr
+ filesz
), 0, memsz
- filesz
);
239 memset(ptr
+ filesz
, 0, memsz
- filesz
);
245 EXPORT_SYMBOL(rproc_elf_load_segments
);
248 find_table(struct device
*dev
, const struct firmware
*fw
)
250 const void *shdr
, *name_table_shdr
;
252 const char *name_table
;
253 struct resource_table
*table
= NULL
;
254 const u8
*elf_data
= (void *)fw
->data
;
255 u8
class = fw_elf_get_class(fw
);
256 size_t fw_size
= fw
->size
;
257 const void *ehdr
= elf_data
;
258 u16 shnum
= elf_hdr_get_e_shnum(class, ehdr
);
259 u32 elf_shdr_get_size
= elf_size_of_shdr(class);
260 u16 shstrndx
= elf_hdr_get_e_shstrndx(class, ehdr
);
262 /* look for the resource table and handle it */
263 /* First, get the section header according to the elf class */
264 shdr
= elf_data
+ elf_hdr_get_e_shoff(class, ehdr
);
265 /* Compute name table section header entry in shdr array */
266 name_table_shdr
= shdr
+ (shstrndx
* elf_shdr_get_size
);
267 /* Finally, compute the name table section address in elf */
268 name_table
= elf_data
+ elf_shdr_get_sh_offset(class, name_table_shdr
);
270 for (i
= 0; i
< shnum
; i
++, shdr
+= elf_shdr_get_size
) {
271 u64 size
= elf_shdr_get_sh_size(class, shdr
);
272 u64 offset
= elf_shdr_get_sh_offset(class, shdr
);
273 u32 name
= elf_shdr_get_sh_name(class, shdr
);
275 if (strcmp(name_table
+ name
, ".resource_table"))
278 table
= (struct resource_table
*)(elf_data
+ offset
);
280 /* make sure we have the entire table */
281 if (offset
+ size
> fw_size
|| offset
+ size
< size
) {
282 dev_err(dev
, "resource table truncated\n");
286 /* make sure table has at least the header */
287 if (sizeof(struct resource_table
) > size
) {
288 dev_err(dev
, "header-less resource table\n");
292 /* we don't support any version beyond the first */
293 if (table
->ver
!= 1) {
294 dev_err(dev
, "unsupported fw ver: %d\n", table
->ver
);
298 /* make sure reserved bytes are zeroes */
299 if (table
->reserved
[0] || table
->reserved
[1]) {
300 dev_err(dev
, "non zero reserved bytes\n");
304 /* make sure the offsets array isn't truncated */
305 if (struct_size(table
, offset
, table
->num
) > size
) {
306 dev_err(dev
, "resource table incomplete\n");
317 * rproc_elf_load_rsc_table() - load the resource table
318 * @rproc: the rproc handle
319 * @fw: the ELF firmware image
321 * This function finds the resource table inside the remote processor's
322 * firmware, load it into the @cached_table and update @table_ptr.
324 * Return: 0 on success, negative errno on failure.
326 int rproc_elf_load_rsc_table(struct rproc
*rproc
, const struct firmware
*fw
)
329 struct device
*dev
= &rproc
->dev
;
330 struct resource_table
*table
= NULL
;
331 const u8
*elf_data
= fw
->data
;
333 u8
class = fw_elf_get_class(fw
);
336 shdr
= find_table(dev
, fw
);
340 sh_offset
= elf_shdr_get_sh_offset(class, shdr
);
341 table
= (struct resource_table
*)(elf_data
+ sh_offset
);
342 tablesz
= elf_shdr_get_sh_size(class, shdr
);
345 * Create a copy of the resource table. When a virtio device starts
346 * and calls vring_new_virtqueue() the address of the allocated vring
347 * will be stored in the cached_table. Before the device is started,
348 * cached_table will be copied into device memory.
350 rproc
->cached_table
= kmemdup(table
, tablesz
, GFP_KERNEL
);
351 if (!rproc
->cached_table
)
354 rproc
->table_ptr
= rproc
->cached_table
;
355 rproc
->table_sz
= tablesz
;
359 EXPORT_SYMBOL(rproc_elf_load_rsc_table
);
362 * rproc_elf_find_loaded_rsc_table() - find the loaded resource table
363 * @rproc: the rproc handle
364 * @fw: the ELF firmware image
366 * This function finds the location of the loaded resource table. Don't
367 * call this function if the table wasn't loaded yet - it's a bug if you do.
369 * Return: pointer to the resource table if it is found or NULL otherwise.
370 * If the table wasn't loaded yet the result is unspecified.
372 struct resource_table
*rproc_elf_find_loaded_rsc_table(struct rproc
*rproc
,
373 const struct firmware
*fw
)
376 u64 sh_addr
, sh_size
;
377 u8
class = fw_elf_get_class(fw
);
378 struct device
*dev
= &rproc
->dev
;
380 shdr
= find_table(&rproc
->dev
, fw
);
384 sh_addr
= elf_shdr_get_sh_addr(class, shdr
);
385 sh_size
= elf_shdr_get_sh_size(class, shdr
);
387 if (!rproc_u64_fit_in_size_t(sh_size
)) {
388 dev_err(dev
, "size (%llx) does not fit in size_t type\n",
393 return rproc_da_to_va(rproc
, sh_addr
, sh_size
, NULL
);
395 EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table
);