2 * Remote Processor Framework Elf loader
4 * Copyright (C) 2011 Texas Instruments, Inc.
5 * Copyright (C) 2011 Google, Inc.
7 * Ohad Ben-Cohen <ohad@wizery.com>
8 * Brian Swetland <swetland@google.com>
9 * Mark Grosen <mgrosen@ti.com>
10 * Fernando Guzman Lugo <fernando.lugo@ti.com>
11 * Suman Anna <s-anna@ti.com>
12 * Robert Tivy <rtivy@ti.com>
13 * Armando Uribe De Leon <x0095078@ti.com>
14 * Sjur Brændeland <sjur.brandeland@stericsson.com>
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * version 2 as published by the Free Software Foundation.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
26 #define pr_fmt(fmt) "%s: " fmt, __func__
28 #include <linux/module.h>
29 #include <linux/firmware.h>
30 #include <linux/remoteproc.h>
31 #include <linux/elf.h>
33 #include "remoteproc_internal.h"
36 * rproc_elf_sanity_check() - Sanity Check ELF firmware image
37 * @rproc: the remote processor handle
38 * @fw: the ELF firmware image
40 * Make sure this fw image is sane.
42 int rproc_elf_sanity_check(struct rproc
*rproc
, const struct firmware
*fw
)
44 const char *name
= rproc
->firmware
;
45 struct device
*dev
= &rproc
->dev
;
46 struct elf32_hdr
*ehdr
;
50 dev_err(dev
, "failed to load %s\n", name
);
54 if (fw
->size
< sizeof(struct elf32_hdr
)) {
55 dev_err(dev
, "Image is too small\n");
59 ehdr
= (struct elf32_hdr
*)fw
->data
;
61 /* We only support ELF32 at this point */
62 class = ehdr
->e_ident
[EI_CLASS
];
63 if (class != ELFCLASS32
) {
64 dev_err(dev
, "Unsupported class: %d\n", class);
68 /* We assume the firmware has the same endianness as the host */
69 # ifdef __LITTLE_ENDIAN
70 if (ehdr
->e_ident
[EI_DATA
] != ELFDATA2LSB
) {
71 # else /* BIG ENDIAN */
72 if (ehdr
->e_ident
[EI_DATA
] != ELFDATA2MSB
) {
74 dev_err(dev
, "Unsupported firmware endianness\n");
78 if (fw
->size
< ehdr
->e_shoff
+ sizeof(struct elf32_shdr
)) {
79 dev_err(dev
, "Image is too small\n");
83 if (memcmp(ehdr
->e_ident
, ELFMAG
, SELFMAG
)) {
84 dev_err(dev
, "Image is corrupted (bad magic)\n");
88 if (ehdr
->e_phnum
== 0) {
89 dev_err(dev
, "No loadable segments\n");
93 if (ehdr
->e_phoff
> fw
->size
) {
94 dev_err(dev
, "Firmware size is too small\n");
100 EXPORT_SYMBOL(rproc_elf_sanity_check
);
103 * rproc_elf_get_boot_addr() - Get rproc's boot address.
104 * @rproc: the remote processor handle
105 * @fw: the ELF firmware image
107 * This function returns the entry point address of the ELF
110 * Note that the boot address is not a configurable property of all remote
111 * processors. Some will always boot at a specific hard-coded address.
113 u32
rproc_elf_get_boot_addr(struct rproc
*rproc
, const struct firmware
*fw
)
115 struct elf32_hdr
*ehdr
= (struct elf32_hdr
*)fw
->data
;
117 return ehdr
->e_entry
;
119 EXPORT_SYMBOL(rproc_elf_get_boot_addr
);
122 * rproc_elf_load_segments() - load firmware segments to memory
123 * @rproc: remote processor which will be booted using these fw segments
124 * @fw: the ELF firmware image
126 * This function loads the firmware segments to memory, where the remote
127 * processor expects them.
129 * Some remote processors will expect their code and data to be placed
130 * in specific device addresses, and can't have them dynamically assigned.
132 * We currently support only those kind of remote processors, and expect
133 * the program header's paddr member to contain those addresses. We then go
134 * through the physically contiguous "carveout" memory regions which we
135 * allocated (and mapped) earlier on behalf of the remote processor,
136 * and "translate" device address to kernel addresses, so we can copy the
137 * segments where they are expected.
139 * Currently we only support remote processors that required carveout
140 * allocations and got them mapped onto their iommus. Some processors
141 * might be different: they might not have iommus, and would prefer to
142 * directly allocate memory for every segment/resource. This is not yet
145 int rproc_elf_load_segments(struct rproc
*rproc
, const struct firmware
*fw
)
147 struct device
*dev
= &rproc
->dev
;
148 struct elf32_hdr
*ehdr
;
149 struct elf32_phdr
*phdr
;
151 const u8
*elf_data
= fw
->data
;
153 ehdr
= (struct elf32_hdr
*)elf_data
;
154 phdr
= (struct elf32_phdr
*)(elf_data
+ ehdr
->e_phoff
);
156 /* go through the available ELF segments */
157 for (i
= 0; i
< ehdr
->e_phnum
; i
++, phdr
++) {
158 u32 da
= phdr
->p_paddr
;
159 u32 memsz
= phdr
->p_memsz
;
160 u32 filesz
= phdr
->p_filesz
;
161 u32 offset
= phdr
->p_offset
;
164 if (phdr
->p_type
!= PT_LOAD
)
167 dev_dbg(dev
, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n",
168 phdr
->p_type
, da
, memsz
, filesz
);
170 if (filesz
> memsz
) {
171 dev_err(dev
, "bad phdr filesz 0x%x memsz 0x%x\n",
177 if (offset
+ filesz
> fw
->size
) {
178 dev_err(dev
, "truncated fw: need 0x%x avail 0x%zx\n",
179 offset
+ filesz
, fw
->size
);
184 /* grab the kernel address for this device address */
185 ptr
= rproc_da_to_va(rproc
, da
, memsz
);
187 dev_err(dev
, "bad phdr da 0x%x mem 0x%x\n", da
, memsz
);
192 /* put the segment where the remote processor expects it */
194 memcpy(ptr
, elf_data
+ phdr
->p_offset
, filesz
);
197 * Zero out remaining memory for this segment.
199 * This isn't strictly required since dma_alloc_coherent already
200 * did this for us. albeit harmless, we may consider removing
204 memset(ptr
+ filesz
, 0, memsz
- filesz
);
209 EXPORT_SYMBOL(rproc_elf_load_segments
);
211 static struct elf32_shdr
*
212 find_table(struct device
*dev
, struct elf32_hdr
*ehdr
, size_t fw_size
)
214 struct elf32_shdr
*shdr
;
216 const char *name_table
;
217 struct resource_table
*table
= NULL
;
218 const u8
*elf_data
= (void *)ehdr
;
220 /* look for the resource table and handle it */
221 shdr
= (struct elf32_shdr
*)(elf_data
+ ehdr
->e_shoff
);
222 name_table
= elf_data
+ shdr
[ehdr
->e_shstrndx
].sh_offset
;
224 for (i
= 0; i
< ehdr
->e_shnum
; i
++, shdr
++) {
225 u32 size
= shdr
->sh_size
;
226 u32 offset
= shdr
->sh_offset
;
228 if (strcmp(name_table
+ shdr
->sh_name
, ".resource_table"))
231 table
= (struct resource_table
*)(elf_data
+ offset
);
233 /* make sure we have the entire table */
234 if (offset
+ size
> fw_size
|| offset
+ size
< size
) {
235 dev_err(dev
, "resource table truncated\n");
239 /* make sure table has at least the header */
240 if (sizeof(struct resource_table
) > size
) {
241 dev_err(dev
, "header-less resource table\n");
245 /* we don't support any version beyond the first */
246 if (table
->ver
!= 1) {
247 dev_err(dev
, "unsupported fw ver: %d\n", table
->ver
);
251 /* make sure reserved bytes are zeroes */
252 if (table
->reserved
[0] || table
->reserved
[1]) {
253 dev_err(dev
, "non zero reserved bytes\n");
257 /* make sure the offsets array isn't truncated */
258 if (table
->num
* sizeof(table
->offset
[0]) +
259 sizeof(struct resource_table
) > size
) {
260 dev_err(dev
, "resource table incomplete\n");
271 * rproc_elf_load_rsc_table() - load the resource table
272 * @rproc: the rproc handle
273 * @fw: the ELF firmware image
275 * This function finds the resource table inside the remote processor's
276 * firmware, load it into the @cached_table and update @table_ptr.
278 * Return: 0 on success, negative errno on failure.
280 int rproc_elf_load_rsc_table(struct rproc
*rproc
, const struct firmware
*fw
)
282 struct elf32_hdr
*ehdr
;
283 struct elf32_shdr
*shdr
;
284 struct device
*dev
= &rproc
->dev
;
285 struct resource_table
*table
= NULL
;
286 const u8
*elf_data
= fw
->data
;
289 ehdr
= (struct elf32_hdr
*)elf_data
;
291 shdr
= find_table(dev
, ehdr
, fw
->size
);
295 table
= (struct resource_table
*)(elf_data
+ shdr
->sh_offset
);
296 tablesz
= shdr
->sh_size
;
299 * Create a copy of the resource table. When a virtio device starts
300 * and calls vring_new_virtqueue() the address of the allocated vring
301 * will be stored in the cached_table. Before the device is started,
302 * cached_table will be copied into device memory.
304 rproc
->cached_table
= kmemdup(table
, tablesz
, GFP_KERNEL
);
305 if (!rproc
->cached_table
)
308 rproc
->table_ptr
= rproc
->cached_table
;
309 rproc
->table_sz
= tablesz
;
313 EXPORT_SYMBOL(rproc_elf_load_rsc_table
);
316 * rproc_elf_find_loaded_rsc_table() - find the loaded resource table
317 * @rproc: the rproc handle
318 * @fw: the ELF firmware image
320 * This function finds the location of the loaded resource table. Don't
321 * call this function if the table wasn't loaded yet - it's a bug if you do.
323 * Returns the pointer to the resource table if it is found or NULL otherwise.
324 * If the table wasn't loaded yet the result is unspecified.
326 struct resource_table
*rproc_elf_find_loaded_rsc_table(struct rproc
*rproc
,
327 const struct firmware
*fw
)
329 struct elf32_hdr
*ehdr
= (struct elf32_hdr
*)fw
->data
;
330 struct elf32_shdr
*shdr
;
332 shdr
= find_table(&rproc
->dev
, ehdr
, fw
->size
);
336 return rproc_da_to_va(rproc
, shdr
->sh_addr
, shdr
->sh_size
);
338 EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table
);