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 int rproc_elf_sanity_check(struct rproc
*rproc
, const struct firmware
*fw
)
37 const char *name
= rproc
->firmware
;
38 struct device
*dev
= &rproc
->dev
;
40 * Elf files are beginning with the same structure. Thus, to simplify
41 * header parsing, we can use the elf32_hdr one for both elf64 and
44 struct elf32_hdr
*ehdr
;
45 u32 elf_shdr_get_size
;
51 dev_err(dev
, "failed to load %s\n", name
);
55 if (fw
->size
< sizeof(struct elf32_hdr
)) {
56 dev_err(dev
, "Image is too small\n");
60 ehdr
= (struct elf32_hdr
*)fw
->data
;
62 if (memcmp(ehdr
->e_ident
, ELFMAG
, SELFMAG
)) {
63 dev_err(dev
, "Image is corrupted (bad magic)\n");
67 class = ehdr
->e_ident
[EI_CLASS
];
68 if (class != ELFCLASS32
&& class != ELFCLASS64
) {
69 dev_err(dev
, "Unsupported class: %d\n", class);
73 if (class == ELFCLASS64
&& fw
->size
< sizeof(struct elf64_hdr
)) {
74 dev_err(dev
, "elf64 header is too small\n");
78 /* We assume the firmware has the same endianness as the host */
79 # ifdef __LITTLE_ENDIAN
80 if (ehdr
->e_ident
[EI_DATA
] != ELFDATA2LSB
) {
81 # else /* BIG ENDIAN */
82 if (ehdr
->e_ident
[EI_DATA
] != ELFDATA2MSB
) {
84 dev_err(dev
, "Unsupported firmware endianness\n");
88 phoff
= elf_hdr_get_e_phoff(class, fw
->data
);
89 shoff
= elf_hdr_get_e_shoff(class, fw
->data
);
90 phnum
= elf_hdr_get_e_phnum(class, fw
->data
);
91 elf_shdr_get_size
= elf_size_of_shdr(class);
93 if (fw
->size
< shoff
+ elf_shdr_get_size
) {
94 dev_err(dev
, "Image is too small\n");
99 dev_err(dev
, "No loadable segments\n");
103 if (phoff
> fw
->size
) {
104 dev_err(dev
, "Firmware size is too small\n");
108 dev_dbg(dev
, "Firmware is an elf%d file\n",
109 class == ELFCLASS32
? 32 : 64);
113 EXPORT_SYMBOL(rproc_elf_sanity_check
);
116 * rproc_elf_sanity_check() - Sanity Check ELF32 firmware image
117 * @rproc: the remote processor handle
118 * @fw: the ELF32 firmware image
120 * Make sure this fw image is sane.
122 int rproc_elf32_sanity_check(struct rproc
*rproc
, const struct firmware
*fw
)
124 int ret
= rproc_elf_sanity_check(rproc
, fw
);
129 if (fw_elf_get_class(fw
) == ELFCLASS32
)
134 EXPORT_SYMBOL(rproc_elf32_sanity_check
);
137 * rproc_elf_get_boot_addr() - Get rproc's boot address.
138 * @rproc: the remote processor handle
139 * @fw: the ELF firmware image
141 * This function returns the entry point address of the ELF
144 * Note that the boot address is not a configurable property of all remote
145 * processors. Some will always boot at a specific hard-coded address.
147 u64
rproc_elf_get_boot_addr(struct rproc
*rproc
, const struct firmware
*fw
)
149 return elf_hdr_get_e_entry(fw_elf_get_class(fw
), fw
->data
);
151 EXPORT_SYMBOL(rproc_elf_get_boot_addr
);
154 * rproc_elf_load_segments() - load firmware segments to memory
155 * @rproc: remote processor which will be booted using these fw segments
156 * @fw: the ELF firmware image
158 * This function loads the firmware segments to memory, where the remote
159 * processor expects them.
161 * Some remote processors will expect their code and data to be placed
162 * in specific device addresses, and can't have them dynamically assigned.
164 * We currently support only those kind of remote processors, and expect
165 * the program header's paddr member to contain those addresses. We then go
166 * through the physically contiguous "carveout" memory regions which we
167 * allocated (and mapped) earlier on behalf of the remote processor,
168 * and "translate" device address to kernel addresses, so we can copy the
169 * segments where they are expected.
171 * Currently we only support remote processors that required carveout
172 * allocations and got them mapped onto their iommus. Some processors
173 * might be different: they might not have iommus, and would prefer to
174 * directly allocate memory for every segment/resource. This is not yet
177 int rproc_elf_load_segments(struct rproc
*rproc
, const struct firmware
*fw
)
179 struct device
*dev
= &rproc
->dev
;
180 const void *ehdr
, *phdr
;
183 const u8
*elf_data
= fw
->data
;
184 u8
class = fw_elf_get_class(fw
);
185 u32 elf_phdr_get_size
= elf_size_of_phdr(class);
188 phnum
= elf_hdr_get_e_phnum(class, ehdr
);
189 phdr
= elf_data
+ elf_hdr_get_e_phoff(class, ehdr
);
191 /* go through the available ELF segments */
192 for (i
= 0; i
< phnum
; i
++, phdr
+= elf_phdr_get_size
) {
193 u64 da
= elf_phdr_get_p_paddr(class, phdr
);
194 u64 memsz
= elf_phdr_get_p_memsz(class, phdr
);
195 u64 filesz
= elf_phdr_get_p_filesz(class, phdr
);
196 u64 offset
= elf_phdr_get_p_offset(class, phdr
);
197 u32 type
= elf_phdr_get_p_type(class, phdr
);
203 dev_dbg(dev
, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
204 type
, da
, memsz
, filesz
);
206 if (filesz
> memsz
) {
207 dev_err(dev
, "bad phdr filesz 0x%llx memsz 0x%llx\n",
213 if (offset
+ filesz
> fw
->size
) {
214 dev_err(dev
, "truncated fw: need 0x%llx avail 0x%zx\n",
215 offset
+ filesz
, fw
->size
);
220 if (!rproc_u64_fit_in_size_t(memsz
)) {
221 dev_err(dev
, "size (%llx) does not fit in size_t type\n",
227 /* grab the kernel address for this device address */
228 ptr
= rproc_da_to_va(rproc
, da
, memsz
);
230 dev_err(dev
, "bad phdr da 0x%llx mem 0x%llx\n", da
,
236 /* put the segment where the remote processor expects it */
238 memcpy(ptr
, elf_data
+ offset
, filesz
);
241 * Zero out remaining memory for this segment.
243 * This isn't strictly required since dma_alloc_coherent already
244 * did this for us. albeit harmless, we may consider removing
248 memset(ptr
+ filesz
, 0, memsz
- filesz
);
252 rproc
->elf_class
= class;
256 EXPORT_SYMBOL(rproc_elf_load_segments
);
259 find_table(struct device
*dev
, const struct firmware
*fw
)
261 const void *shdr
, *name_table_shdr
;
263 const char *name_table
;
264 struct resource_table
*table
= NULL
;
265 const u8
*elf_data
= (void *)fw
->data
;
266 u8
class = fw_elf_get_class(fw
);
267 size_t fw_size
= fw
->size
;
268 const void *ehdr
= elf_data
;
269 u16 shnum
= elf_hdr_get_e_shnum(class, ehdr
);
270 u32 elf_shdr_get_size
= elf_size_of_shdr(class);
271 u16 shstrndx
= elf_hdr_get_e_shstrndx(class, ehdr
);
273 /* look for the resource table and handle it */
274 /* First, get the section header according to the elf class */
275 shdr
= elf_data
+ elf_hdr_get_e_shoff(class, ehdr
);
276 /* Compute name table section header entry in shdr array */
277 name_table_shdr
= shdr
+ (shstrndx
* elf_shdr_get_size
);
278 /* Finally, compute the name table section address in elf */
279 name_table
= elf_data
+ elf_shdr_get_sh_offset(class, name_table_shdr
);
281 for (i
= 0; i
< shnum
; i
++, shdr
+= elf_shdr_get_size
) {
282 u64 size
= elf_shdr_get_sh_size(class, shdr
);
283 u64 offset
= elf_shdr_get_sh_offset(class, shdr
);
284 u32 name
= elf_shdr_get_sh_name(class, shdr
);
286 if (strcmp(name_table
+ name
, ".resource_table"))
289 table
= (struct resource_table
*)(elf_data
+ offset
);
291 /* make sure we have the entire table */
292 if (offset
+ size
> fw_size
|| offset
+ size
< size
) {
293 dev_err(dev
, "resource table truncated\n");
297 /* make sure table has at least the header */
298 if (sizeof(struct resource_table
) > size
) {
299 dev_err(dev
, "header-less resource table\n");
303 /* we don't support any version beyond the first */
304 if (table
->ver
!= 1) {
305 dev_err(dev
, "unsupported fw ver: %d\n", table
->ver
);
309 /* make sure reserved bytes are zeroes */
310 if (table
->reserved
[0] || table
->reserved
[1]) {
311 dev_err(dev
, "non zero reserved bytes\n");
315 /* make sure the offsets array isn't truncated */
316 if (struct_size(table
, offset
, table
->num
) > size
) {
317 dev_err(dev
, "resource table incomplete\n");
328 * rproc_elf_load_rsc_table() - load the resource table
329 * @rproc: the rproc handle
330 * @fw: the ELF firmware image
332 * This function finds the resource table inside the remote processor's
333 * firmware, load it into the @cached_table and update @table_ptr.
335 * Return: 0 on success, negative errno on failure.
337 int rproc_elf_load_rsc_table(struct rproc
*rproc
, const struct firmware
*fw
)
340 struct device
*dev
= &rproc
->dev
;
341 struct resource_table
*table
= NULL
;
342 const u8
*elf_data
= fw
->data
;
344 u8
class = fw_elf_get_class(fw
);
347 shdr
= find_table(dev
, fw
);
351 sh_offset
= elf_shdr_get_sh_offset(class, shdr
);
352 table
= (struct resource_table
*)(elf_data
+ sh_offset
);
353 tablesz
= elf_shdr_get_sh_size(class, shdr
);
356 * Create a copy of the resource table. When a virtio device starts
357 * and calls vring_new_virtqueue() the address of the allocated vring
358 * will be stored in the cached_table. Before the device is started,
359 * cached_table will be copied into device memory.
361 rproc
->cached_table
= kmemdup(table
, tablesz
, GFP_KERNEL
);
362 if (!rproc
->cached_table
)
365 rproc
->table_ptr
= rproc
->cached_table
;
366 rproc
->table_sz
= tablesz
;
370 EXPORT_SYMBOL(rproc_elf_load_rsc_table
);
373 * rproc_elf_find_loaded_rsc_table() - find the loaded resource table
374 * @rproc: the rproc handle
375 * @fw: the ELF firmware image
377 * This function finds the location of the loaded resource table. Don't
378 * call this function if the table wasn't loaded yet - it's a bug if you do.
380 * Returns the pointer to the resource table if it is found or NULL otherwise.
381 * If the table wasn't loaded yet the result is unspecified.
383 struct resource_table
*rproc_elf_find_loaded_rsc_table(struct rproc
*rproc
,
384 const struct firmware
*fw
)
387 u64 sh_addr
, sh_size
;
388 u8
class = fw_elf_get_class(fw
);
389 struct device
*dev
= &rproc
->dev
;
391 shdr
= find_table(&rproc
->dev
, fw
);
395 sh_addr
= elf_shdr_get_sh_addr(class, shdr
);
396 sh_size
= elf_shdr_get_sh_size(class, shdr
);
398 if (!rproc_u64_fit_in_size_t(sh_size
)) {
399 dev_err(dev
, "size (%llx) does not fit in size_t type\n",
404 return rproc_da_to_va(rproc
, sh_addr
, sh_size
);
406 EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table
);