1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
8 #include <remoteproc.h>
10 /* Basic function to verify ELF32 image format */
11 int rproc_elf32_sanity_check(ulong addr, ulong size)
17 pr_debug("Invalid fw address?\n");
21 if (size < sizeof(Elf32_Ehdr)) {
22 pr_debug("Image is too small\n");
26 ehdr = (Elf32_Ehdr *)addr;
27 class = ehdr->e_ident[EI_CLASS];
29 if (!IS_ELF(*ehdr) || ehdr->e_type != ET_EXEC || class != ELFCLASS32) {
30 pr_debug("Not an executable ELF32 image\n");
31 return -EPROTONOSUPPORT;
34 /* We assume the firmware has the same endianness as the host */
35 # ifdef __LITTLE_ENDIAN
36 if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
37 # else /* BIG ENDIAN */
38 if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
40 pr_debug("Unsupported firmware endianness\n");
44 if (size < ehdr->e_shoff + sizeof(Elf32_Shdr)) {
45 pr_debug("Image is too small\n");
49 if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
50 pr_debug("Image is corrupted (bad magic)\n");
54 if (ehdr->e_phnum == 0) {
55 pr_debug("No loadable segments\n");
59 if (ehdr->e_phoff > size) {
60 pr_debug("Firmware size is too small\n");
67 /* Basic function to verify ELF64 image format */
68 int rproc_elf64_sanity_check(ulong addr, ulong size)
70 Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;
74 pr_debug("Invalid fw address?\n");
78 if (size < sizeof(Elf64_Ehdr)) {
79 pr_debug("Image is too small\n");
83 class = ehdr->e_ident[EI_CLASS];
85 if (!IS_ELF(*ehdr) || ehdr->e_type != ET_EXEC || class != ELFCLASS64) {
86 pr_debug("Not an executable ELF64 image\n");
87 return -EPROTONOSUPPORT;
90 /* We assume the firmware has the same endianness as the host */
91 # ifdef __LITTLE_ENDIAN
92 if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
93 # else /* BIG ENDIAN */
94 if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
96 pr_debug("Unsupported firmware endianness\n");
100 if (size < ehdr->e_shoff + sizeof(Elf64_Shdr)) {
101 pr_debug("Image is too small\n");
105 if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
106 pr_debug("Image is corrupted (bad magic)\n");
110 if (ehdr->e_phnum == 0) {
111 pr_debug("No loadable segments\n");
115 if (ehdr->e_phoff > size) {
116 pr_debug("Firmware size is too small\n");
123 /* Basic function to verify ELF image format */
124 int rproc_elf_sanity_check(ulong addr, ulong size)
126 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
129 dev_err(dev, "Invalid firmware address\n");
133 if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
134 return rproc_elf64_sanity_check(addr, size);
136 return rproc_elf32_sanity_check(addr, size);
139 int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size)
141 Elf32_Ehdr *ehdr; /* Elf header structure pointer */
142 Elf32_Phdr *phdr; /* Program header structure pointer */
143 const struct dm_rproc_ops *ops;
146 ret = rproc_elf32_sanity_check(addr, size);
148 dev_err(dev, "Invalid ELF32 Image %d\n", ret);
152 ehdr = (Elf32_Ehdr *)addr;
153 phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
155 ops = rproc_get_ops(dev);
157 /* Load each program header */
158 for (i = 0; i < ehdr->e_phnum; ++i) {
159 void *dst = (void *)(uintptr_t)phdr->p_paddr;
160 void *src = (void *)addr + phdr->p_offset;
162 if (phdr->p_type != PT_LOAD)
165 if (ops->device_to_virt)
166 dst = ops->device_to_virt(dev, (ulong)dst,
169 dev_dbg(dev, "Loading phdr %i to 0x%p (%i bytes)\n",
170 i, dst, phdr->p_filesz);
172 memcpy(dst, src, phdr->p_filesz);
173 if (phdr->p_filesz != phdr->p_memsz)
174 memset(dst + phdr->p_filesz, 0x00,
175 phdr->p_memsz - phdr->p_filesz);
176 flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
177 roundup((unsigned long)dst + phdr->p_filesz,
179 rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
186 int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
188 const struct dm_rproc_ops *ops = rproc_get_ops(dev);
189 u64 da, memsz, filesz, offset;
195 dev_dbg(dev, "%s: addr = 0x%lx size = 0x%lx\n", __func__, addr, size);
197 if (rproc_elf64_sanity_check(addr, size))
200 ehdr = (Elf64_Ehdr *)addr;
201 phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
203 /* go through the available ELF segments */
204 for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
206 memsz = phdr->p_memsz;
207 filesz = phdr->p_filesz;
208 offset = phdr->p_offset;
210 if (phdr->p_type != PT_LOAD)
213 dev_dbg(dev, "%s:phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
214 __func__, phdr->p_type, da, memsz, filesz);
216 ptr = (void *)(uintptr_t)da;
217 if (ops->device_to_virt) {
218 ptr = ops->device_to_virt(dev, da, phdr->p_memsz);
220 dev_err(dev, "bad da 0x%llx mem 0x%llx\n", da,
228 memcpy(ptr, (void *)addr + offset, filesz);
230 memset(ptr + filesz, 0x00, memsz - filesz);
232 flush_cache(rounddown((ulong)ptr, ARCH_DMA_MINALIGN),
233 roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) -
234 rounddown((ulong)ptr, ARCH_DMA_MINALIGN));
240 int rproc_elf_load_image(struct udevice *dev, ulong addr, ulong size)
242 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
245 dev_err(dev, "Invalid firmware address\n");
249 if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
250 return rproc_elf64_load_image(dev, addr, size);
252 return rproc_elf32_load_image(dev, addr, size);
255 static ulong rproc_elf32_get_boot_addr(ulong addr)
257 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
259 return ehdr->e_entry;
262 static ulong rproc_elf64_get_boot_addr(ulong addr)
264 Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;
266 return ehdr->e_entry;
269 ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
271 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
273 if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
274 return rproc_elf64_get_boot_addr(addr);
276 return rproc_elf32_get_boot_addr(addr);