1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2 /*
3  * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
4  */
5 #include <cpu_func.h>
6 #include <dm.h>
7 #include <elf.h>
8 #include <log.h>
9 #include <mapmem.h>
10 #include <remoteproc.h>
11 #include <asm/cache.h>
12 #include <dm/device_compat.h>
13 #include <linux/compat.h>
14 #include <linux/printk.h>
15 
16 /**
17  * struct resource_table - firmware resource table header
18  * @ver: version number
19  * @num: number of resource entries
20  * @reserved: reserved (must be zero)
21  * @offset: array of offsets pointing at the various resource entries
22  *
23  * A resource table is essentially a list of system resources required
24  * by the remote processor. It may also include configuration entries.
25  * If needed, the remote processor firmware should contain this table
26  * as a dedicated ".resource_table" ELF section.
27  *
28  * Some resources entries are mere announcements, where the host is informed
29  * of specific remoteproc configuration. Other entries require the host to
30  * do something (e.g. allocate a system resource). Sometimes a negotiation
31  * is expected, where the firmware requests a resource, and once allocated,
32  * the host should provide back its details (e.g. address of an allocated
33  * memory region).
34  *
35  * The header of the resource table, as expressed by this structure,
36  * contains a version number (should we need to change this format in the
37  * future), the number of available resource entries, and their offsets
38  * in the table.
39  *
40  * Immediately following this header are the resource entries themselves.
41  */
42 struct resource_table {
43 	u32 ver;
44 	u32 num;
45 	u32 reserved[2];
46 	u32 offset[0];
47 } __packed;
48 
49 /* Basic function to verify ELF32 image format */
rproc_elf32_sanity_check(ulong addr,ulong size)50 int rproc_elf32_sanity_check(ulong addr, ulong size)
51 {
52 	Elf32_Ehdr *ehdr;
53 	char class;
54 
55 	if (!addr) {
56 		pr_debug("Invalid fw address?\n");
57 		return -EFAULT;
58 	}
59 
60 	if (size < sizeof(Elf32_Ehdr)) {
61 		pr_debug("Image is too small\n");
62 		return -ENOSPC;
63 	}
64 
65 	ehdr = (Elf32_Ehdr *)addr;
66 	class = ehdr->e_ident[EI_CLASS];
67 
68 	if (!IS_ELF(*ehdr) || ehdr->e_type != ET_EXEC || class != ELFCLASS32) {
69 		pr_debug("Not an executable ELF32 image\n");
70 		return -EPROTONOSUPPORT;
71 	}
72 
73 	/* We assume the firmware has the same endianness as the host */
74 # ifdef __LITTLE_ENDIAN
75 	if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
76 # else /* BIG ENDIAN */
77 	if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
78 # endif
79 		pr_debug("Unsupported firmware endianness\n");
80 		return -EILSEQ;
81 	}
82 
83 	if (size < ehdr->e_shoff + sizeof(Elf32_Shdr)) {
84 		pr_debug("Image is too small\n");
85 		return -ENOSPC;
86 	}
87 
88 	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
89 		pr_debug("Image is corrupted (bad magic)\n");
90 		return -EBADF;
91 	}
92 
93 	if (ehdr->e_phnum == 0) {
94 		pr_debug("No loadable segments\n");
95 		return -ENOEXEC;
96 	}
97 
98 	if (ehdr->e_phoff > size) {
99 		pr_debug("Firmware size is too small\n");
100 		return -ENOSPC;
101 	}
102 
103 	return 0;
104 }
105 
106 /* Basic function to verify ELF64 image format */
107 int rproc_elf64_sanity_check(ulong addr, ulong size)
108 {
109 	Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;
110 	char class;
111 
112 	if (!addr) {
113 		pr_debug("Invalid fw address?\n");
114 		return -EFAULT;
115 	}
116 
117 	if (size < sizeof(Elf64_Ehdr)) {
118 		pr_debug("Image is too small\n");
119 		return -ENOSPC;
120 	}
121 
122 	class = ehdr->e_ident[EI_CLASS];
123 
124 	if (!IS_ELF(*ehdr) || ehdr->e_type != ET_EXEC || class != ELFCLASS64) {
125 		pr_debug("Not an executable ELF64 image\n");
126 		return -EPROTONOSUPPORT;
127 	}
128 
129 	/* We assume the firmware has the same endianness as the host */
130 # ifdef __LITTLE_ENDIAN
131 	if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) {
132 # else /* BIG ENDIAN */
133 	if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
134 # endif
135 		pr_debug("Unsupported firmware endianness\n");
136 		return -EILSEQ;
137 	}
138 
139 	if (size < ehdr->e_shoff + sizeof(Elf64_Shdr)) {
140 		pr_debug("Image is too small\n");
141 		return -ENOSPC;
142 	}
143 
144 	if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) {
145 		pr_debug("Image is corrupted (bad magic)\n");
146 		return -EBADF;
147 	}
148 
149 	if (ehdr->e_phnum == 0) {
150 		pr_debug("No loadable segments\n");
151 		return -ENOEXEC;
152 	}
153 
154 	if (ehdr->e_phoff > size) {
155 		pr_debug("Firmware size is too small\n");
156 		return -ENOSPC;
157 	}
158 
159 	return 0;
160 }
161 
162 int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size)
163 {
164 	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
165 	Elf32_Phdr *phdr; /* Program header structure pointer */
166 	const struct dm_rproc_ops *ops;
167 	unsigned int i, ret;
168 
169 	ret =  rproc_elf32_sanity_check(addr, size);
170 	if (ret) {
171 		dev_err(dev, "Invalid ELF32 Image %d\n", ret);
172 		return ret;
173 	}
174 
175 	ehdr = (Elf32_Ehdr *)addr;
176 	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
177 
178 	ops = rproc_get_ops(dev);
179 
180 	/* Load each program header */
181 	for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
182 		void *dst = (void *)(uintptr_t)phdr->p_paddr;
183 		void *src = (void *)addr + phdr->p_offset;
184 		ulong dst_addr;
185 
186 		if (phdr->p_type != PT_LOAD)
187 			continue;
188 
189 		if (ops->device_to_virt)
190 			dst = ops->device_to_virt(dev, (ulong)dst,
191 						  phdr->p_memsz);
192 
193 		dev_dbg(dev, "Loading phdr %i to 0x%p (%i bytes)\n",
194 			i, dst, phdr->p_filesz);
195 		if (phdr->p_filesz)
196 			memcpy(dst, src, phdr->p_filesz);
197 		if (phdr->p_filesz != phdr->p_memsz)
198 			memset(dst + phdr->p_filesz, 0x00,
199 			       phdr->p_memsz - phdr->p_filesz);
200 		dst_addr = map_to_sysmem(dst);
201 		flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN),
202 			    roundup(dst_addr + phdr->p_filesz,
203 				    ARCH_DMA_MINALIGN) -
204 			    rounddown(dst_addr, ARCH_DMA_MINALIGN));
205 	}
206 
207 	return 0;
208 }
209 
210 int rproc_elf64_load_image(struct udevice *dev, ulong addr, ulong size)
211 {
212 	const struct dm_rproc_ops *ops = rproc_get_ops(dev);
213 	u64 da, memsz, filesz, offset;
214 	Elf64_Ehdr *ehdr;
215 	Elf64_Phdr *phdr;
216 	int i, ret = 0;
217 	void *ptr;
218 
219 	dev_dbg(dev, "%s: addr = 0x%lx size = 0x%lx\n", __func__, addr, size);
220 
221 	if (rproc_elf64_sanity_check(addr, size))
222 		return -EINVAL;
223 
224 	ehdr = (Elf64_Ehdr *)addr;
225 	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
226 
227 	/* go through the available ELF segments */
228 	for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
229 		da = phdr->p_paddr;
230 		memsz = phdr->p_memsz;
231 		filesz = phdr->p_filesz;
232 		offset = phdr->p_offset;
233 
234 		if (phdr->p_type != PT_LOAD)
235 			continue;
236 
237 		dev_dbg(dev, "%s:phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n",
238 			__func__, phdr->p_type, da, memsz, filesz);
239 
240 		ptr = (void *)(uintptr_t)da;
241 		if (ops->device_to_virt) {
242 			ptr = ops->device_to_virt(dev, da, phdr->p_memsz);
243 			if (!ptr) {
244 				dev_err(dev, "bad da 0x%llx mem 0x%llx\n", da,
245 					memsz);
246 				ret = -EINVAL;
247 				break;
248 			}
249 		}
250 
251 		if (filesz)
252 			memcpy(ptr, (void *)addr + offset, filesz);
253 		if (filesz != memsz)
254 			memset(ptr + filesz, 0x00, memsz - filesz);
255 
256 		flush_cache(rounddown((ulong)ptr, ARCH_DMA_MINALIGN),
257 			    roundup((ulong)ptr + filesz, ARCH_DMA_MINALIGN) -
258 			    rounddown((ulong)ptr, ARCH_DMA_MINALIGN));
259 	}
260 
261 	return ret;
262 }
263 
264 int rproc_elf_load_image(struct udevice *dev, ulong addr, ulong size)
265 {
266 	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
267 
268 	if (!addr) {
269 		dev_err(dev, "Invalid firmware address\n");
270 		return -EFAULT;
271 	}
272 
273 	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
274 		return rproc_elf64_load_image(dev, addr, size);
275 	else
276 		return rproc_elf32_load_image(dev, addr, size);
277 }
278 
279 static ulong rproc_elf32_get_boot_addr(ulong addr)
280 {
281 	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
282 
283 	return ehdr->e_entry;
284 }
285 
286 static ulong rproc_elf64_get_boot_addr(ulong addr)
287 {
288 	Elf64_Ehdr *ehdr = (Elf64_Ehdr *)addr;
289 
290 	return ehdr->e_entry;
291 }
292 
293 ulong rproc_elf_get_boot_addr(struct udevice *dev, ulong addr)
294 {
295 	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)addr;
296 
297 	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
298 		return rproc_elf64_get_boot_addr(addr);
299 	else
300 		return rproc_elf32_get_boot_addr(addr);
301 }
302 
303 /*
304  * Search for the resource table in an ELF32 image.
305  * Returns the address of the resource table section if found, NULL if there is
306  * no resource table section, or error pointer.
307  */
308 static Elf32_Shdr *rproc_elf32_find_rsc_table(struct udevice *dev,
309 					      ulong fw_addr, ulong fw_size)
310 {
311 	int ret;
312 	unsigned int i;
313 	const char *name_table;
314 	struct resource_table *table;
315 	const u8 *elf_data = (void *)fw_addr;
316 	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr;
317 	Elf32_Shdr *shdr;
318 
319 	ret = rproc_elf32_sanity_check(fw_addr, fw_size);
320 	if (ret) {
321 		pr_debug("Invalid ELF32 Image %d\n", ret);
322 		return ERR_PTR(ret);
323 	}
324 
325 	/* look for the resource table and handle it */
326 	shdr = (Elf32_Shdr *)(elf_data + ehdr->e_shoff);
327 	name_table = (const char *)(elf_data +
328 				    shdr[ehdr->e_shstrndx].sh_offset);
329 
330 	for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
331 		u32 size = shdr->sh_size;
332 		u32 offset = shdr->sh_offset;
333 
334 		if (strcmp(name_table + shdr->sh_name, ".resource_table"))
335 			continue;
336 
337 		table = (struct resource_table *)(elf_data + offset);
338 
339 		/* make sure we have the entire table */
340 		if (offset + size > fw_size) {
341 			pr_debug("resource table truncated\n");
342 			return ERR_PTR(-ENOSPC);
343 		}
344 
345 		/* make sure table has at least the header */
346 		if (sizeof(*table) > size) {
347 			pr_debug("header-less resource table\n");
348 			return ERR_PTR(-ENOSPC);
349 		}
350 
351 		/* we don't support any version beyond the first */
352 		if (table->ver != 1) {
353 			pr_debug("unsupported fw ver: %d\n", table->ver);
354 			return ERR_PTR(-EPROTONOSUPPORT);
355 		}
356 
357 		/* make sure reserved bytes are zeroes */
358 		if (table->reserved[0] || table->reserved[1]) {
359 			pr_debug("non zero reserved bytes\n");
360 			return ERR_PTR(-EBADF);
361 		}
362 
363 		/* make sure the offsets array isn't truncated */
364 		if (table->num * sizeof(table->offset[0]) +
365 				 sizeof(*table) > size) {
366 			pr_debug("resource table incomplete\n");
367 			return ERR_PTR(-ENOSPC);
368 		}
369 
370 		return shdr;
371 	}
372 
373 	return NULL;
374 }
375 
376 /* Load the resource table from an ELF32 image */
377 int rproc_elf32_load_rsc_table(struct udevice *dev, ulong fw_addr,
378 			       ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
379 {
380 	const struct dm_rproc_ops *ops;
381 	Elf32_Shdr *shdr;
382 	void *src, *dst;
383 	ulong dst_addr;
384 
385 	shdr = rproc_elf32_find_rsc_table(dev, fw_addr, fw_size);
386 	if (!shdr)
387 		return -ENODATA;
388 	if (IS_ERR(shdr))
389 		return PTR_ERR(shdr);
390 
391 	ops = rproc_get_ops(dev);
392 	*rsc_addr = (ulong)shdr->sh_addr;
393 	*rsc_size = (ulong)shdr->sh_size;
394 
395 	src = (void *)fw_addr + shdr->sh_offset;
396 	if (ops->device_to_virt)
397 		dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
398 	else
399 		dst = (void *)rsc_addr;
400 
401 	dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
402 		(ulong)dst, *rsc_size);
403 
404 	memcpy(dst, src, *rsc_size);
405 	dst_addr = map_to_sysmem(dst);
406 	flush_cache(rounddown(dst_addr, ARCH_DMA_MINALIGN),
407 		    roundup(dst_addr + *rsc_size, ARCH_DMA_MINALIGN) -
408 		    rounddown(dst_addr, ARCH_DMA_MINALIGN));
409 
410 	return 0;
411 }
412 
413 /*
414  * Search for the resource table in an ELF64 image.
415  * Returns the address of the resource table section if found, NULL if there is
416  * no resource table section, or error pointer.
417  */
418 static Elf64_Shdr *rproc_elf64_find_rsc_table(struct udevice *dev,
419 					      ulong fw_addr, ulong fw_size)
420 {
421 	int ret;
422 	unsigned int i;
423 	const char *name_table;
424 	struct resource_table *table;
425 	const u8 *elf_data = (void *)fw_addr;
426 	Elf64_Ehdr *ehdr = (Elf64_Ehdr *)fw_addr;
427 	Elf64_Shdr *shdr;
428 
429 	ret = rproc_elf64_sanity_check(fw_addr, fw_size);
430 	if (ret) {
431 		pr_debug("Invalid ELF64 Image %d\n", ret);
432 		return ERR_PTR(ret);
433 	}
434 
435 	/* look for the resource table and handle it */
436 	shdr = (Elf64_Shdr *)(elf_data + ehdr->e_shoff);
437 	name_table = (const char *)(elf_data +
438 				    shdr[ehdr->e_shstrndx].sh_offset);
439 
440 	for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
441 		u64 size = shdr->sh_size;
442 		u64 offset = shdr->sh_offset;
443 
444 		if (strcmp(name_table + shdr->sh_name, ".resource_table"))
445 			continue;
446 
447 		table = (struct resource_table *)(elf_data + offset);
448 
449 		/* make sure we have the entire table */
450 		if (offset + size > fw_size) {
451 			pr_debug("resource table truncated\n");
452 			return ERR_PTR(-ENOSPC);
453 		}
454 
455 		/* make sure table has at least the header */
456 		if (sizeof(*table) > size) {
457 			pr_debug("header-less resource table\n");
458 			return ERR_PTR(-ENOSPC);
459 		}
460 
461 		/* we don't support any version beyond the first */
462 		if (table->ver != 1) {
463 			pr_debug("unsupported fw ver: %d\n", table->ver);
464 			return ERR_PTR(-EPROTONOSUPPORT);
465 		}
466 
467 		/* make sure reserved bytes are zeroes */
468 		if (table->reserved[0] || table->reserved[1]) {
469 			pr_debug("non zero reserved bytes\n");
470 			return ERR_PTR(-EBADF);
471 		}
472 
473 		/* make sure the offsets array isn't truncated */
474 		if (table->num * sizeof(table->offset[0]) +
475 				 sizeof(*table) > size) {
476 			pr_debug("resource table incomplete\n");
477 			return ERR_PTR(-ENOSPC);
478 		}
479 
480 		return shdr;
481 	}
482 
483 	return NULL;
484 }
485 
486 /* Load the resource table from an ELF64 image */
487 int rproc_elf64_load_rsc_table(struct udevice *dev, ulong fw_addr,
488 			       ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
489 {
490 	const struct dm_rproc_ops *ops;
491 	Elf64_Shdr *shdr;
492 	void *src, *dst;
493 
494 	shdr = rproc_elf64_find_rsc_table(dev, fw_addr, fw_size);
495 	if (!shdr)
496 		return -ENODATA;
497 	if (IS_ERR(shdr))
498 		return PTR_ERR(shdr);
499 
500 	ops = rproc_get_ops(dev);
501 	*rsc_addr = (ulong)shdr->sh_addr;
502 	*rsc_size = (ulong)shdr->sh_size;
503 
504 	src = (void *)fw_addr + shdr->sh_offset;
505 	if (ops->device_to_virt)
506 		dst = (void *)ops->device_to_virt(dev, *rsc_addr, *rsc_size);
507 	else
508 		dst = (void *)rsc_addr;
509 
510 	dev_dbg(dev, "Loading resource table to 0x%8lx (%ld bytes)\n",
511 		(ulong)dst, *rsc_size);
512 
513 	memcpy(dst, src, *rsc_size);
514 	flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
515 		    roundup((unsigned long)dst + *rsc_size,
516 			    ARCH_DMA_MINALIGN) -
517 		    rounddown((unsigned long)dst, ARCH_DMA_MINALIGN));
518 
519 	return 0;
520 }
521 
522 /* Load the resource table from an ELF32 or ELF64 image */
523 int rproc_elf_load_rsc_table(struct udevice *dev, ulong fw_addr,
524 			     ulong fw_size, ulong *rsc_addr, ulong *rsc_size)
525 
526 {
527 	Elf32_Ehdr *ehdr = (Elf32_Ehdr *)fw_addr;
528 
529 	if (!fw_addr)
530 		return -EFAULT;
531 
532 	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
533 		return rproc_elf64_load_rsc_table(dev, fw_addr, fw_size,
534 						  rsc_addr, rsc_size);
535 	else
536 		return rproc_elf32_load_rsc_table(dev, fw_addr, fw_size,
537 						  rsc_addr, rsc_size);
538 }
539