All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0
@ 2020-01-13  5:54 Keerthy
  2020-01-13  5:54 ` [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib Keerthy
                   ` (8 more replies)
  0 siblings, 9 replies; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

This patch series enables mcu_r5fss0_core0 & main_r5fss0_core0.
Tested for firmware loading and execution on J721e.

Changes in v2:

  * Factored out all the generic elf handling functions under lib/elf.c 

Faiz Abbas (1):
  configs: j721e_evm_r5: Add configs for environment in eMMC

Keerthy (8):
  lib: elf: Move the generic elf loading/validating functions to lib
  arm: k3: Add support for loading non linux remote cores
  armv7R: K3: r5_mpu: Enable execute permission for MCU0 BTCM
  armv7R: K3: Add support for jumping to firmware
  arm: dts: k3-j721e-r5: Add fs_loader node
  arm: dts: k3-j721e-r5: Enable r5fss0 cluster in SPL
  include: configs: j721e_evm: Add env variables for mcu_r5fss0_core0 &
    main_r5fss0_core0
  configs: j721e_evm_r5: Enable R5F remoteproc support

 .../arm/dts/k3-j721e-r5-common-proc-board.dts |  20 ++
 arch/arm/mach-k3/common.c                     | 106 +++++++-
 arch/arm/mach-k3/common.h                     |   2 +
 arch/arm/mach-k3/j721e_init.c                 |  34 +++
 arch/arm/mach-k3/r5_mpu.c                     |   4 +-
 cmd/Kconfig                                   |   1 +
 cmd/elf.c                                     | 229 ----------------
 configs/j721e_evm_a72_defconfig               |   3 +
 configs/j721e_evm_r5_defconfig                |   4 +
 include/configs/j721e_evm.h                   |  10 +
 include/elf.h                                 |   4 +
 lib/Kconfig                                   |   3 +
 lib/Makefile                                  |   1 +
 lib/elf.c                                     | 256 ++++++++++++++++++
 14 files changed, 436 insertions(+), 241 deletions(-)
 create mode 100644 lib/elf.c

-- 
2.17.1

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib
  2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
@ 2020-01-13  5:54 ` Keerthy
  2020-01-17  4:27   ` Lokesh Vutla
  2020-01-13  5:54 ` [PATCH v2 2/9] arm: k3: Add support for loading non linux remote cores Keerthy
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

Move the generic elf loading/validating functions to lib/
so that they can be re-used and accessed by code existing
outside cmd.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Suggested-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
---
Changes in v2:

  * Factored out all the generic elf handling functions under lib/elf.c

 cmd/Kconfig   |   1 +
 cmd/elf.c     | 229 --------------------------------------------
 include/elf.h |   4 +
 lib/Kconfig   |   3 +
 lib/Makefile  |   1 +
 lib/elf.c     | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 265 insertions(+), 229 deletions(-)
 create mode 100644 lib/elf.c

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 298feae24d..6f4f08d02a 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -375,6 +375,7 @@ config CMD_ADTIMG
 config CMD_ELF
 	bool "bootelf, bootvx"
 	default y
+	select ELF
 	help
 	  Boot an ELF/vxWorks image from the memory.
 
diff --git a/cmd/elf.c b/cmd/elf.c
index 32f12a72b9..23cc17aebc 100644
--- a/cmd/elf.c
+++ b/cmd/elf.c
@@ -26,211 +26,6 @@
 #include <linux/linkage.h>
 #endif
 
-/*
- * A very simple ELF64 loader, assumes the image is valid, returns the
- * entry point address.
- *
- * Note if U-Boot is 32-bit, the loader assumes the to segment's
- * physical address and size is within the lower 32-bit address space.
- */
-static unsigned long load_elf64_image_phdr(unsigned long addr)
-{
-	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf64_Phdr *phdr; /* Program header structure pointer */
-	int i;
-
-	ehdr = (Elf64_Ehdr *)addr;
-	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
-
-	/* Load each program header */
-	for (i = 0; i < ehdr->e_phnum; ++i) {
-		void *dst = (void *)(ulong)phdr->p_paddr;
-		void *src = (void *)addr + phdr->p_offset;
-
-		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
-		      i, dst, (ulong)phdr->p_filesz);
-		if (phdr->p_filesz)
-			memcpy(dst, src, phdr->p_filesz);
-		if (phdr->p_filesz != phdr->p_memsz)
-			memset(dst + phdr->p_filesz, 0x00,
-			       phdr->p_memsz - phdr->p_filesz);
-		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
-			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
-		++phdr;
-	}
-
-	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
-					    EF_PPC64_ELFV1_ABI)) {
-		/*
-		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
-		 * descriptor pointer with the first double word being the
-		 * address of the entry point of the function.
-		 */
-		uintptr_t addr = ehdr->e_entry;
-
-		return *(Elf64_Addr *)addr;
-	}
-
-	return ehdr->e_entry;
-}
-
-static unsigned long load_elf64_image_shdr(unsigned long addr)
-{
-	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf64_Shdr *shdr; /* Section header structure pointer */
-	unsigned char *strtab = 0; /* String table pointer */
-	unsigned char *image; /* Binary image pointer */
-	int i; /* Loop counter */
-
-	ehdr = (Elf64_Ehdr *)addr;
-
-	/* Find the section header string table for output info */
-	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
-			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
-
-	if (shdr->sh_type == SHT_STRTAB)
-		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
-
-	/* Load each appropriate section */
-	for (i = 0; i < ehdr->e_shnum; ++i) {
-		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
-				     (i * sizeof(Elf64_Shdr)));
-
-		if (!(shdr->sh_flags & SHF_ALLOC) ||
-		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
-			continue;
-		}
-
-		if (strtab) {
-			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
-			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
-			       &strtab[shdr->sh_name],
-			       (unsigned long)shdr->sh_addr,
-			       (long)shdr->sh_size);
-		}
-
-		if (shdr->sh_type == SHT_NOBITS) {
-			memset((void *)(uintptr_t)shdr->sh_addr, 0,
-			       shdr->sh_size);
-		} else {
-			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
-			memcpy((void *)(uintptr_t)shdr->sh_addr,
-			       (const void *)image, shdr->sh_size);
-		}
-		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
-			    roundup((shdr->sh_addr + shdr->sh_size),
-				     ARCH_DMA_MINALIGN) -
-			            rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
-	}
-
-	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
-					    EF_PPC64_ELFV1_ABI)) {
-		/*
-		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
-		 * descriptor pointer with the first double word being the
-		 * address of the entry point of the function.
-		 */
-		uintptr_t addr = ehdr->e_entry;
-
-		return *(Elf64_Addr *)addr;
-	}
-
-	return ehdr->e_entry;
-}
-
-/*
- * A very simple ELF loader, assumes the image is valid, returns the
- * entry point address.
- *
- * The loader firstly reads the EFI class to see if it's a 64-bit image.
- * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
- */
-static unsigned long load_elf_image_phdr(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf32_Phdr *phdr; /* Program header structure pointer */
-	int i;
-
-	ehdr = (Elf32_Ehdr *)addr;
-	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
-		return load_elf64_image_phdr(addr);
-
-	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
-
-	/* Load each program header */
-	for (i = 0; i < ehdr->e_phnum; ++i) {
-		void *dst = (void *)(uintptr_t)phdr->p_paddr;
-		void *src = (void *)addr + phdr->p_offset;
-
-		debug("Loading phdr %i to 0x%p (%i bytes)\n",
-		      i, dst, phdr->p_filesz);
-		if (phdr->p_filesz)
-			memcpy(dst, src, phdr->p_filesz);
-		if (phdr->p_filesz != phdr->p_memsz)
-			memset(dst + phdr->p_filesz, 0x00,
-			       phdr->p_memsz - phdr->p_filesz);
-		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
-			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
-		++phdr;
-	}
-
-	return ehdr->e_entry;
-}
-
-static unsigned long load_elf_image_shdr(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
-	Elf32_Shdr *shdr; /* Section header structure pointer */
-	unsigned char *strtab = 0; /* String table pointer */
-	unsigned char *image; /* Binary image pointer */
-	int i; /* Loop counter */
-
-	ehdr = (Elf32_Ehdr *)addr;
-	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
-		return load_elf64_image_shdr(addr);
-
-	/* Find the section header string table for output info */
-	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
-			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
-
-	if (shdr->sh_type == SHT_STRTAB)
-		strtab = (unsigned char *)(addr + shdr->sh_offset);
-
-	/* Load each appropriate section */
-	for (i = 0; i < ehdr->e_shnum; ++i) {
-		shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
-				     (i * sizeof(Elf32_Shdr)));
-
-		if (!(shdr->sh_flags & SHF_ALLOC) ||
-		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
-			continue;
-		}
-
-		if (strtab) {
-			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
-			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
-			       &strtab[shdr->sh_name],
-			       (unsigned long)shdr->sh_addr,
-			       (long)shdr->sh_size);
-		}
-
-		if (shdr->sh_type == SHT_NOBITS) {
-			memset((void *)(uintptr_t)shdr->sh_addr, 0,
-			       shdr->sh_size);
-		} else {
-			image = (unsigned char *)addr + shdr->sh_offset;
-			memcpy((void *)(uintptr_t)shdr->sh_addr,
-			       (const void *)image, shdr->sh_size);
-		}
-		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
-			    roundup((shdr->sh_addr + shdr->sh_size),
-				    ARCH_DMA_MINALIGN) -
-			    rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
-	}
-
-	return ehdr->e_entry;
-}
-
 /* Allow ports to override the default behavior */
 static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
 				     int argc, char * const argv[])
@@ -246,30 +41,6 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
 	return ret;
 }
 
-/*
- * Determine if a valid ELF image exists at the given memory location.
- * First look at the ELF header magic field, then make sure that it is
- * executable.
- */
-int valid_elf_image(unsigned long addr)
-{
-	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
-
-	ehdr = (Elf32_Ehdr *)addr;
-
-	if (!IS_ELF(*ehdr)) {
-		printf("## No elf image at address 0x%08lx\n", addr);
-		return 0;
-	}
-
-	if (ehdr->e_type != ET_EXEC) {
-		printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
-		return 0;
-	}
-
-	return 1;
-}
-
 /* Interpreter command to boot an arbitrary ELF image from memory */
 int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
diff --git a/include/elf.h b/include/elf.h
index 81f40191d7..e7c51986df 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -692,6 +692,10 @@ unsigned long elf_hash(const unsigned char *name);
 
 #ifndef __ASSEMBLER__
 int valid_elf_image(unsigned long addr);
+unsigned long load_elf64_image_phdr(unsigned long addr);
+unsigned long load_elf64_image_shdr(unsigned long addr);
+unsigned long load_elf_image_phdr(unsigned long addr);
+unsigned long load_elf_image_shdr(unsigned long addr);
 #endif
 
 #endif /* _ELF_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index d040a87d26..b155ced4b2 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -601,4 +601,7 @@ config TEST_FDTDEC
 config LIB_DATE
 	bool
 
+config ELF
+	bool "enable basic elf loading/validating functions"
+
 endmenu
diff --git a/lib/Makefile b/lib/Makefile
index 6b7b9ce85c..93f22d210e 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -121,6 +121,7 @@ obj-y += vsprintf.o strto.o
 endif
 
 obj-y += date.o
+obj-$(CONFIG_ELF) += elf.o
 
 #
 # Build a fast OID lookup registry from include/linux/oid_registry.h
diff --git a/lib/elf.c b/lib/elf.c
new file mode 100644
index 0000000000..54ac4ee502
--- /dev/null
+++ b/lib/elf.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2001 William L. Pitts
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are freely
+ * permitted provided that the above copyright notice and this
+ * paragraph and the following disclaimer are duplicated in all
+ * such forms.
+ *
+ * This software is provided "AS IS" and without any express or
+ * implied warranties, including, without limitation, the implied
+ * warranties of merchantability and fitness for a particular
+ * purpose.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cpu_func.h>
+#include <elf.h>
+#include <env.h>
+#include <net.h>
+#include <vxworks.h>
+#ifdef CONFIG_X86
+#include <vbe.h>
+#include <asm/e820.h>
+#include <linux/linkage.h>
+#endif
+
+/*
+ * A very simple ELF64 loader, assumes the image is valid, returns the
+ * entry point address.
+ *
+ * Note if U-Boot is 32-bit, the loader assumes the to segment's
+ * physical address and size is within the lower 32-bit address space.
+ */
+unsigned long load_elf64_image_phdr(unsigned long addr)
+{
+	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf64_Phdr *phdr; /* Program header structure pointer */
+	int i;
+
+	ehdr = (Elf64_Ehdr *)addr;
+	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
+
+	/* Load each program header */
+	for (i = 0; i < ehdr->e_phnum; ++i) {
+		void *dst = (void *)(ulong)phdr->p_paddr;
+		void *src = (void *)addr + phdr->p_offset;
+
+		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
+		      i, dst, (ulong)phdr->p_filesz);
+		if (phdr->p_filesz)
+			memcpy(dst, src, phdr->p_filesz);
+		if (phdr->p_filesz != phdr->p_memsz)
+			memset(dst + phdr->p_filesz, 0x00,
+			       phdr->p_memsz - phdr->p_filesz);
+		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
+			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
+		++phdr;
+	}
+
+	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
+					    EF_PPC64_ELFV1_ABI)) {
+		/*
+		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
+		 * descriptor pointer with the first double word being the
+		 * address of the entry point of the function.
+		 */
+		uintptr_t addr = ehdr->e_entry;
+
+		return *(Elf64_Addr *)addr;
+	}
+
+	return ehdr->e_entry;
+}
+
+unsigned long load_elf64_image_shdr(unsigned long addr)
+{
+	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf64_Shdr *shdr; /* Section header structure pointer */
+	unsigned char *strtab = 0; /* String table pointer */
+	unsigned char *image; /* Binary image pointer */
+	int i; /* Loop counter */
+
+	ehdr = (Elf64_Ehdr *)addr;
+
+	/* Find the section header string table for output info */
+	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
+			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
+
+	if (shdr->sh_type == SHT_STRTAB)
+		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
+
+	/* Load each appropriate section */
+	for (i = 0; i < ehdr->e_shnum; ++i) {
+		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
+				     (i * sizeof(Elf64_Shdr)));
+
+		if (!(shdr->sh_flags & SHF_ALLOC) ||
+		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
+			continue;
+		}
+
+		if (strtab) {
+			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
+			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
+			       &strtab[shdr->sh_name],
+			       (unsigned long)shdr->sh_addr,
+			       (long)shdr->sh_size);
+		}
+
+		if (shdr->sh_type == SHT_NOBITS) {
+			memset((void *)(uintptr_t)shdr->sh_addr, 0,
+			       shdr->sh_size);
+		} else {
+			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
+			memcpy((void *)(uintptr_t)shdr->sh_addr,
+			       (const void *)image, shdr->sh_size);
+		}
+		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
+			    roundup((shdr->sh_addr + shdr->sh_size),
+				     ARCH_DMA_MINALIGN) -
+			            rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
+	}
+
+	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
+					    EF_PPC64_ELFV1_ABI)) {
+		/*
+		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
+		 * descriptor pointer with the first double word being the
+		 * address of the entry point of the function.
+		 */
+		uintptr_t addr = ehdr->e_entry;
+
+		return *(Elf64_Addr *)addr;
+	}
+
+	return ehdr->e_entry;
+}
+
+/*
+ * A very simple ELF loader, assumes the image is valid, returns the
+ * entry point address.
+ *
+ * The loader firstly reads the EFI class to see if it's a 64-bit image.
+ * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
+ */
+unsigned long load_elf_image_phdr(unsigned long addr)
+{
+	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf32_Phdr *phdr; /* Program header structure pointer */
+	int i;
+
+	ehdr = (Elf32_Ehdr *)addr;
+	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+		return load_elf64_image_phdr(addr);
+
+	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
+
+	/* Load each program header */
+	for (i = 0; i < ehdr->e_phnum; ++i) {
+		void *dst = (void *)(uintptr_t)phdr->p_paddr;
+		void *src = (void *)addr + phdr->p_offset;
+
+		debug("Loading phdr %i to 0x%p (%i bytes)\n",
+		      i, dst, phdr->p_filesz);
+		if (phdr->p_filesz)
+			memcpy(dst, src, phdr->p_filesz);
+		if (phdr->p_filesz != phdr->p_memsz)
+			memset(dst + phdr->p_filesz, 0x00,
+			       phdr->p_memsz - phdr->p_filesz);
+		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
+			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
+		++phdr;
+	}
+
+	return ehdr->e_entry;
+}
+
+unsigned long load_elf_image_shdr(unsigned long addr)
+{
+	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+	Elf32_Shdr *shdr; /* Section header structure pointer */
+	unsigned char *strtab = 0; /* String table pointer */
+	unsigned char *image; /* Binary image pointer */
+	int i; /* Loop counter */
+
+	ehdr = (Elf32_Ehdr *)addr;
+	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+		return load_elf64_image_shdr(addr);
+
+	/* Find the section header string table for output info */
+	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
+			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
+
+	if (shdr->sh_type == SHT_STRTAB)
+		strtab = (unsigned char *)(addr + shdr->sh_offset);
+
+	/* Load each appropriate section */
+	for (i = 0; i < ehdr->e_shnum; ++i) {
+		shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
+				     (i * sizeof(Elf32_Shdr)));
+
+		if (!(shdr->sh_flags & SHF_ALLOC) ||
+		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
+			continue;
+		}
+
+		if (strtab) {
+			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
+			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
+			       &strtab[shdr->sh_name],
+			       (unsigned long)shdr->sh_addr,
+			       (long)shdr->sh_size);
+		}
+
+		if (shdr->sh_type == SHT_NOBITS) {
+			memset((void *)(uintptr_t)shdr->sh_addr, 0,
+			       shdr->sh_size);
+		} else {
+			image = (unsigned char *)addr + shdr->sh_offset;
+			memcpy((void *)(uintptr_t)shdr->sh_addr,
+			       (const void *)image, shdr->sh_size);
+		}
+		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
+			    roundup((shdr->sh_addr + shdr->sh_size),
+				    ARCH_DMA_MINALIGN) -
+			    rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
+	}
+
+	return ehdr->e_entry;
+}
+
+/*
+ * Determine if a valid ELF image exists at the given memory location.
+ * First look at the ELF header magic field, then make sure that it is
+ * executable.
+ */
+int valid_elf_image(unsigned long addr)
+{
+	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
+
+	ehdr = (Elf32_Ehdr *)addr;
+
+	if (!IS_ELF(*ehdr)) {
+		printf("## No elf image at address 0x%08lx\n", addr);
+		return 0;
+	}
+
+	if (ehdr->e_type != ET_EXEC) {
+		printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
+		return 0;
+	}
+
+	return 1;
+}
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 2/9] arm: k3: Add support for loading non linux remote cores
  2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
  2020-01-13  5:54 ` [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib Keerthy
@ 2020-01-13  5:54 ` Keerthy
  2020-01-13  5:54 ` [PATCH v2 3/9] armv7R: K3: r5_mpu: Enable execute permission for MCU0 BTCM Keerthy
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

Add MAIN domain R5FSS0 remoteproc support from spl. This enables
loading the elf firmware in SPL and starting the remotecore.

In order to start the core, there should be a file with path
"/lib/firmware/j7-main-r5f0_0-fw" under filesystem
of respective boot mode.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
[Guard start_non_linux_remote_cores under CONFIG_FS_LOADER]
Signed-off-by: Andreas Dannenberg <dannenberg@ti.com>
---
 arch/arm/mach-k3/common.c     | 84 ++++++++++++++++++++++++++++++++---
 arch/arm/mach-k3/common.h     |  2 +
 arch/arm/mach-k3/j721e_init.c | 34 ++++++++++++++
 3 files changed, 115 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 50f5b81dfe..377fcbe80b 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -16,6 +16,10 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
+#include <fs_loader.h>
+#include <fs.h>
+#include <env.h>
+#include <elf.h>
 
 struct ti_sci_handle *get_ti_sci_handle(void)
 {
@@ -57,6 +61,74 @@ int early_console_init(void)
 #endif
 
 #ifdef CONFIG_SYS_K3_SPL_ATF
+
+void init_env(void)
+{
+#ifdef CONFIG_SPL_ENV_SUPPORT
+	char *part;
+
+	env_init();
+	env_load();
+	switch (spl_boot_device()) {
+	case BOOT_DEVICE_MMC2:
+		part = env_get("bootpart");
+		env_set("storage_interface", "mmc");
+		env_set("fw_dev_part", part);
+		break;
+	case BOOT_DEVICE_SPI:
+		env_set("storage_interface", "ubi");
+		env_set("fw_ubi_mtdpart", "UBI");
+		env_set("fw_ubi_volume", "UBI0");
+		break;
+	default:
+		printf("%s from device %u not supported!\n",
+		       __func__, spl_boot_device());
+		return;
+	}
+#endif
+}
+
+#ifdef CONFIG_FS_LOADER
+int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
+{
+	struct udevice *fsdev;
+	char *name = NULL;
+	int size = 0;
+
+	*loadaddr = 0;
+#ifdef CONFIG_SPL_ENV_SUPPORT
+	switch (spl_boot_device()) {
+	case BOOT_DEVICE_MMC2:
+		name = env_get(name_fw);
+		*loadaddr = env_get_hex(name_loadaddr, *loadaddr);
+		break;
+	default:
+		printf("Loading rproc fw image from device %u not supported!\n",
+		       spl_boot_device());
+		return 0;
+	}
+#endif
+	if (!*loadaddr)
+		return 0;
+
+	if (!uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &fsdev)) {
+		size = request_firmware_into_buf(fsdev, name, (void *)*loadaddr,
+						 0, 0);
+	}
+
+	return size;
+}
+#else
+int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr)
+{
+	return 0;
+}
+#endif
+
+__weak void start_non_linux_remote_cores(void)
+{
+}
+
 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 {
 	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
@@ -65,15 +137,17 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 	/* Release all the exclusive devices held by SPL before starting ATF */
 	ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci);
 
+	ret = rproc_init();
+	if (ret)
+		panic("rproc failed to be initialized (%d)\n", ret);
+
+	init_env();
+	start_non_linux_remote_cores();
+
 	/*
 	 * It is assumed that remoteproc device 1 is the corresponding
 	 * Cortex-A core which runs ATF. Make sure DT reflects the same.
 	 */
-	ret = rproc_dev_init(1);
-	if (ret)
-		panic("%s: ATF failed to initialize on rproc (%d)\n", __func__,
-		      ret);
-
 	ret = rproc_load(1, spl_image->entry_point, 0x200);
 	if (ret)
 		panic("%s: ATF failed to load on rproc (%d)\n", __func__, ret);
diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h
index 35d1609cdc..f6a1e3aa01 100644
--- a/arch/arm/mach-k3/common.h
+++ b/arch/arm/mach-k3/common.h
@@ -17,3 +17,5 @@
 void setup_k3_mpu_regions(void);
 int early_console_init(void);
 void disable_linefill_optimization(void);
+void start_non_linux_remote_cores(void);
+int load_firmware(char *name_fw, char *name_loadaddr, u32 *loadaddr);
diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c
index 4758739266..e9ca5baf8f 100644
--- a/arch/arm/mach-k3/j721e_init.c
+++ b/arch/arm/mach-k3/j721e_init.c
@@ -18,6 +18,7 @@
 #include <dm.h>
 #include <dm/uclass-internal.h>
 #include <dm/pinctrl.h>
+#include <remoteproc.h>
 
 #ifdef CONFIG_SPL_BUILD
 static void mmr_unlock(u32 base, u32 partition)
@@ -240,3 +241,36 @@ void release_resources_for_core_shutdown(void)
 	}
 }
 #endif
+
+#ifdef CONFIG_SYS_K3_SPL_ATF
+void start_non_linux_remote_cores(void)
+{
+	int size = 0, ret;
+	u32 loadaddr = 0;
+
+	size = load_firmware("mainr5f0_0fwname", "mainr5f0_0loadaddr",
+			     &loadaddr);
+	if (size <= 0)
+		goto err_load;
+
+	/* assuming remoteproc 2 is aliased for the needed remotecore */
+	ret = rproc_load(2, loadaddr, size);
+	if (ret) {
+		printf("Firmware failed to start on rproc (%d)\n", ret);
+		goto err_load;
+	}
+
+	ret = rproc_start(2);
+	if (ret) {
+		printf("Firmware init failed on rproc (%d)\n", ret);
+		goto err_load;
+	}
+
+	printf("Remoteproc 2 started successfully\n");
+
+	return;
+
+err_load:
+	rproc_reset(2);
+}
+#endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 3/9] armv7R: K3: r5_mpu: Enable execute permission for MCU0 BTCM
  2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
  2020-01-13  5:54 ` [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib Keerthy
  2020-01-13  5:54 ` [PATCH v2 2/9] arm: k3: Add support for loading non linux remote cores Keerthy
@ 2020-01-13  5:54 ` Keerthy
  2020-01-13  5:54 ` [PATCH v2 4/9] armv7R: K3: Add support for jumping to firmware Keerthy
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

Enable execute permission for mcu_r5fss0_core0 BTCM so that we can jump
to a firmware directly from SPL.

Signed-off-by: Keerthy <j-keerthy@ti.com>
---
 arch/arm/mach-k3/r5_mpu.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-k3/r5_mpu.c b/arch/arm/mach-k3/r5_mpu.c
index ee076ed877..3d2ff6775a 100644
--- a/arch/arm/mach-k3/r5_mpu.c
+++ b/arch/arm/mach-k3/r5_mpu.c
@@ -26,7 +26,9 @@ struct mpu_region_config k3_mpu_regions[16] = {
 	/* U-Boot's code area marking it as WB and Write allocate */
 	{CONFIG_SYS_SDRAM_BASE, REGION_2, XN_DIS, PRIV_RW_USR_RW,
 	 O_I_WB_RD_WR_ALLOC, REGION_2GB},
-	{0x0, 3, 0x0, 0x0, 0x0, 0x0},
+	/* mcu_r5fss0_core0 BTCM area marking it as WB and Write allocate. */
+	{0x41010000, 3, XN_DIS, PRIV_RW_USR_RW, O_I_WB_RD_WR_ALLOC,
+	 REGION_8MB},
 	{0x0, 4, 0x0, 0x0, 0x0, 0x0},
 	{0x0, 5, 0x0, 0x0, 0x0, 0x0},
 	{0x0, 6, 0x0, 0x0, 0x0, 0x0},
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 4/9] armv7R: K3: Add support for jumping to firmware
  2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
                   ` (2 preceding siblings ...)
  2020-01-13  5:54 ` [PATCH v2 3/9] armv7R: K3: r5_mpu: Enable execute permission for MCU0 BTCM Keerthy
@ 2020-01-13  5:54 ` Keerthy
  2020-01-13  5:54 ` [PATCH v2 5/9] arm: dts: k3-j721e-r5: Add fs_loader node Keerthy
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

MCU Domain rf50 is currently shutting down after loading the ATF.
Load elf firmware and jump to firmware post loading ATF.

ROM doesn't enable ATCM memory, so make sure that firmware that
is being loaded doesn't use ATCM memory or override SPL.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 arch/arm/mach-k3/common.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 377fcbe80b..47a1f96ae1 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -131,8 +131,10 @@ __weak void start_non_linux_remote_cores(void)
 
 void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 {
+	typedef void __noreturn (*image_entry_noargs_t)(void);
 	struct ti_sci_handle *ti_sci = get_ti_sci_handle();
-	int ret;
+	u32 loadaddr = 0;
+	int ret, size;
 
 	/* Release all the exclusive devices held by SPL before starting ATF */
 	ti_sci->ops.dev_ops.release_exclusive_devices(ti_sci);
@@ -143,6 +145,9 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 
 	init_env();
 	start_non_linux_remote_cores();
+	size = load_firmware("mcur5f0_0fwname", "mcur5f0_0loadaddr",
+			     &loadaddr);
+
 
 	/*
 	 * It is assumed that remoteproc device 1 is the corresponding
@@ -158,13 +163,18 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
 	ret = rproc_start(1);
 	if (ret)
 		panic("%s: ATF failed to start on rproc (%d)\n", __func__, ret);
+	if (!(size > 0 && valid_elf_image(loadaddr))) {
+		debug("Shutting down...\n");
+		release_resources_for_core_shutdown();
+
+		while (1)
+			asm volatile("wfe");
+	}
 
-	debug("Releasing resources...\n");
-	release_resources_for_core_shutdown();
+	image_entry_noargs_t image_entry =
+		(image_entry_noargs_t)load_elf_image_phdr(loadaddr);
 
-	debug("Finalizing core shutdown...\n");
-	while (1)
-		asm volatile("wfe");
+	image_entry();
 }
 #endif
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 5/9] arm: dts: k3-j721e-r5: Add fs_loader node
  2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
                   ` (3 preceding siblings ...)
  2020-01-13  5:54 ` [PATCH v2 4/9] armv7R: K3: Add support for jumping to firmware Keerthy
@ 2020-01-13  5:54 ` Keerthy
  2020-01-13  5:54 ` [PATCH v2 6/9] arm: dts: k3-j721e-r5: Enable r5fss0 cluster in SPL Keerthy
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

Add fs_loader node which will be needed for loading firmwares
from the boot media/filesystem.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 arch/arm/dts/k3-j721e-r5-common-proc-board.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
index 41af48214f..27df704ce0 100644
--- a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
+++ b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
@@ -18,6 +18,12 @@
 	chosen {
 		stdout-path = "serial2:115200n8";
 		tick-timer = &timer1;
+		firmware-loader = &fs_loader0;
+	};
+
+	fs_loader0: fs_loader at 0 {
+		u-boot,dm-pre-reloc;
+		compatible = "u-boot,fs-loader";
 	};
 
 	a72_0: a72 at 0 {
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 6/9] arm: dts: k3-j721e-r5: Enable r5fss0 cluster in SPL
  2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
                   ` (4 preceding siblings ...)
  2020-01-13  5:54 ` [PATCH v2 5/9] arm: dts: k3-j721e-r5: Add fs_loader node Keerthy
@ 2020-01-13  5:54 ` Keerthy
  2020-01-13  5:54 ` [PATCH v2 7/9] include: configs: j721e_evm: Add env variables for mcu_r5fss0_core0 & main_r5fss0_core0 Keerthy
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

Enable MAIN domain r5fss0 cluster and its core0 in R5 spl.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 arch/arm/dts/k3-j721e-r5-common-proc-board.dts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
index 27df704ce0..d7d149a509 100644
--- a/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
+++ b/arch/arm/dts/k3-j721e-r5-common-proc-board.dts
@@ -13,6 +13,8 @@
 	aliases {
 		remoteproc0 = &sysctrler;
 		remoteproc1 = &a72_0;
+		remoteproc2 = &main_r5fss0_core0;
+		remoteproc3 = &main_r5fss0_core1;
 	};
 
 	chosen {
@@ -190,4 +192,16 @@
 	u-boot,dm-spl;
 };
 
+&main_r5fss0 {
+	u-boot,dm-spl;
+};
+
+&main_r5fss0_core0 {
+	u-boot,dm-spl;
+};
+
+&main_r5fss0_core1 {
+	u-boot,dm-spl;
+};
+
 #include "k3-j721e-common-proc-board-u-boot.dtsi"
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 7/9] include: configs: j721e_evm: Add env variables for mcu_r5fss0_core0 & main_r5fss0_core0
  2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
                   ` (5 preceding siblings ...)
  2020-01-13  5:54 ` [PATCH v2 6/9] arm: dts: k3-j721e-r5: Enable r5fss0 cluster in SPL Keerthy
@ 2020-01-13  5:54 ` Keerthy
  2020-01-13  5:54 ` [PATCH v2 8/9] configs: j721e_evm_r5: Add configs for environment in eMMC Keerthy
  2020-01-13  5:54 ` [PATCH v2 9/9] configs: j721e_evm_r5: Enable R5F remoteproc support Keerthy
  8 siblings, 0 replies; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

Add env variables for mcu_r5fss0_core0 & main_r5fss0_core0 firmware
loadaddr and name.

Signed-off-by: Keerthy <j-keerthy@ti.com>
---
 include/configs/j721e_evm.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/configs/j721e_evm.h b/include/configs/j721e_evm.h
index 84518786c7..d3a9330069 100644
--- a/include/configs/j721e_evm.h
+++ b/include/configs/j721e_evm.h
@@ -76,6 +76,10 @@
 	"mmcdev=1\0"							\
 	"bootpart=1:2\0"						\
 	"bootdir=/boot\0"						\
+	"mainr5f0_0loadaddr=88000000\0"					\
+	"mainr5f0_0fwname=/lib/firmware/j7-main-r5f0_0-fw\0"		\
+	"mcur5f0_0loadaddr=89000000\0"					\
+	"mcur5f0_0fwname=/lib/firmware/j7-mcu-r5f0_0-fw\0"		\
 	"rd_spec=-\0"							\
 	"init_mmc=run args_all args_mmc\0"				\
 	"get_fdt_mmc=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}\0" \
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 8/9] configs: j721e_evm_r5: Add configs for environment in eMMC
  2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
                   ` (6 preceding siblings ...)
  2020-01-13  5:54 ` [PATCH v2 7/9] include: configs: j721e_evm: Add env variables for mcu_r5fss0_core0 & main_r5fss0_core0 Keerthy
@ 2020-01-13  5:54 ` Keerthy
  2020-01-17  5:14   ` Lokesh Vutla
  2020-01-13  5:54 ` [PATCH v2 9/9] configs: j721e_evm_r5: Enable R5F remoteproc support Keerthy
  8 siblings, 1 reply; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

From: Faiz Abbas <faiz_abbas@ti.com>

Add config to save and read back environment from eMMC.

Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
Signed-off-by: Keerthy <j-keerthy@ti.com>
---
 configs/j721e_evm_a72_defconfig | 3 +++
 configs/j721e_evm_r5_defconfig  | 2 ++
 include/configs/j721e_evm.h     | 6 ++++++
 3 files changed, 11 insertions(+)

diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig
index daa661384d..a9ede538eb 100644
--- a/configs/j721e_evm_a72_defconfig
+++ b/configs/j721e_evm_a72_defconfig
@@ -9,6 +9,7 @@ CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
 CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x680000
 CONFIG_SPL_STACK_R_ADDR=0x82000000
 CONFIG_NR_DRAM_BANKS=2
 CONFIG_SPL_FS_FAT=y
@@ -24,6 +25,7 @@ CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs;
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SPL_ENV_SUPPORT=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -50,6 +52,7 @@ CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="k3-j721e-common-proc-board"
 CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
+CONFIG_ENV_IS_IN_MMC=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig
index 10f4f00699..c92be8e513 100644
--- a/configs/j721e_evm_r5_defconfig
+++ b/configs/j721e_evm_r5_defconfig
@@ -10,6 +10,7 @@ CONFIG_SPL_MMC_SUPPORT=y
 CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
 CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x680000
 CONFIG_SPL_STACK_R_ADDR=0x82000000
 CONFIG_SPL_FS_FAT=y
 CONFIG_SPL_LIBDISK_SUPPORT=y
@@ -46,6 +47,7 @@ CONFIG_CMD_FAT=y
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="k3-j721e-r5-common-proc-board"
+CONFIG_ENV_IS_IN_MMC=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
diff --git a/include/configs/j721e_evm.h b/include/configs/j721e_evm.h
index d3a9330069..caeea2da62 100644
--- a/include/configs/j721e_evm.h
+++ b/include/configs/j721e_evm.h
@@ -115,4 +115,10 @@
 /* Now for the remaining common defines */
 #include <configs/ti_armv7_common.h>
 
+/* MMC ENV related defines */
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV		0
+#define CONFIG_SYS_MMC_ENV_PART	1
+#endif
+
 #endif /* __CONFIG_J721E_EVM_H */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 9/9] configs: j721e_evm_r5: Enable R5F remoteproc support
  2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
                   ` (7 preceding siblings ...)
  2020-01-13  5:54 ` [PATCH v2 8/9] configs: j721e_evm_r5: Add configs for environment in eMMC Keerthy
@ 2020-01-13  5:54 ` Keerthy
  8 siblings, 0 replies; 14+ messages in thread
From: Keerthy @ 2020-01-13  5:54 UTC (permalink / raw)
  To: u-boot

Enable r5f remoteproc support in r5 defconfig so that r5s can
be started in spl.

Signed-off-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
 configs/j721e_evm_r5_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig
index c92be8e513..2c0082aaf7 100644
--- a/configs/j721e_evm_r5_defconfig
+++ b/configs/j721e_evm_r5_defconfig
@@ -25,6 +25,7 @@ CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_EARLY_BSS=y
 CONFIG_SPL_ENV_SUPPORT=y
+CONFIG_SPL_FS_EXT4=y
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -89,6 +90,7 @@ CONFIG_SPL_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_TPS65941=y
 CONFIG_K3_SYSTEM_CONTROLLER=y
 CONFIG_REMOTEPROC_TI_K3_ARM64=y
+CONFIG_REMOTEPROC_TI_K3_R5F=y
 CONFIG_DM_RESET=y
 CONFIG_RESET_TI_SCI=y
 CONFIG_DM_SERIAL=y
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib
  2020-01-13  5:54 ` [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib Keerthy
@ 2020-01-17  4:27   ` Lokesh Vutla
  2020-01-17  7:49     ` Simon Goldschmidt
  0 siblings, 1 reply; 14+ messages in thread
From: Lokesh Vutla @ 2020-01-17  4:27 UTC (permalink / raw)
  To: u-boot

Simon,

On 13/01/20 11:24 AM, Keerthy wrote:
> Move the generic elf loading/validating functions to lib/
> so that they can be re-used and accessed by code existing
> outside cmd.
> 
> Signed-off-by: Keerthy <j-keerthy@ti.com>
> Suggested-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>

Are you okay with this patch? If yes, Ill apply to u-boot-ti along with other
patches in this series.

Thanks and regards,
Lokesh

> ---
> Changes in v2:
> 
>   * Factored out all the generic elf handling functions under lib/elf.c
> 
>  cmd/Kconfig   |   1 +
>  cmd/elf.c     | 229 --------------------------------------------
>  include/elf.h |   4 +
>  lib/Kconfig   |   3 +
>  lib/Makefile  |   1 +
>  lib/elf.c     | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 265 insertions(+), 229 deletions(-)
>  create mode 100644 lib/elf.c
> 
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index 298feae24d..6f4f08d02a 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -375,6 +375,7 @@ config CMD_ADTIMG
>  config CMD_ELF
>  	bool "bootelf, bootvx"
>  	default y
> +	select ELF
>  	help
>  	  Boot an ELF/vxWorks image from the memory.
>  
> diff --git a/cmd/elf.c b/cmd/elf.c
> index 32f12a72b9..23cc17aebc 100644
> --- a/cmd/elf.c
> +++ b/cmd/elf.c
> @@ -26,211 +26,6 @@
>  #include <linux/linkage.h>
>  #endif
>  
> -/*
> - * A very simple ELF64 loader, assumes the image is valid, returns the
> - * entry point address.
> - *
> - * Note if U-Boot is 32-bit, the loader assumes the to segment's
> - * physical address and size is within the lower 32-bit address space.
> - */
> -static unsigned long load_elf64_image_phdr(unsigned long addr)
> -{
> -	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> -	Elf64_Phdr *phdr; /* Program header structure pointer */
> -	int i;
> -
> -	ehdr = (Elf64_Ehdr *)addr;
> -	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
> -
> -	/* Load each program header */
> -	for (i = 0; i < ehdr->e_phnum; ++i) {
> -		void *dst = (void *)(ulong)phdr->p_paddr;
> -		void *src = (void *)addr + phdr->p_offset;
> -
> -		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
> -		      i, dst, (ulong)phdr->p_filesz);
> -		if (phdr->p_filesz)
> -			memcpy(dst, src, phdr->p_filesz);
> -		if (phdr->p_filesz != phdr->p_memsz)
> -			memset(dst + phdr->p_filesz, 0x00,
> -			       phdr->p_memsz - phdr->p_filesz);
> -		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> -			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> -		++phdr;
> -	}
> -
> -	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> -					    EF_PPC64_ELFV1_ABI)) {
> -		/*
> -		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> -		 * descriptor pointer with the first double word being the
> -		 * address of the entry point of the function.
> -		 */
> -		uintptr_t addr = ehdr->e_entry;
> -
> -		return *(Elf64_Addr *)addr;
> -	}
> -
> -	return ehdr->e_entry;
> -}
> -
> -static unsigned long load_elf64_image_shdr(unsigned long addr)
> -{
> -	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> -	Elf64_Shdr *shdr; /* Section header structure pointer */
> -	unsigned char *strtab = 0; /* String table pointer */
> -	unsigned char *image; /* Binary image pointer */
> -	int i; /* Loop counter */
> -
> -	ehdr = (Elf64_Ehdr *)addr;
> -
> -	/* Find the section header string table for output info */
> -	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> -			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
> -
> -	if (shdr->sh_type == SHT_STRTAB)
> -		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
> -
> -	/* Load each appropriate section */
> -	for (i = 0; i < ehdr->e_shnum; ++i) {
> -		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> -				     (i * sizeof(Elf64_Shdr)));
> -
> -		if (!(shdr->sh_flags & SHF_ALLOC) ||
> -		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
> -			continue;
> -		}
> -
> -		if (strtab) {
> -			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> -			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> -			       &strtab[shdr->sh_name],
> -			       (unsigned long)shdr->sh_addr,
> -			       (long)shdr->sh_size);
> -		}
> -
> -		if (shdr->sh_type == SHT_NOBITS) {
> -			memset((void *)(uintptr_t)shdr->sh_addr, 0,
> -			       shdr->sh_size);
> -		} else {
> -			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
> -			memcpy((void *)(uintptr_t)shdr->sh_addr,
> -			       (const void *)image, shdr->sh_size);
> -		}
> -		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> -			    roundup((shdr->sh_addr + shdr->sh_size),
> -				     ARCH_DMA_MINALIGN) -
> -			            rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> -	}
> -
> -	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> -					    EF_PPC64_ELFV1_ABI)) {
> -		/*
> -		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> -		 * descriptor pointer with the first double word being the
> -		 * address of the entry point of the function.
> -		 */
> -		uintptr_t addr = ehdr->e_entry;
> -
> -		return *(Elf64_Addr *)addr;
> -	}
> -
> -	return ehdr->e_entry;
> -}
> -
> -/*
> - * A very simple ELF loader, assumes the image is valid, returns the
> - * entry point address.
> - *
> - * The loader firstly reads the EFI class to see if it's a 64-bit image.
> - * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
> - */
> -static unsigned long load_elf_image_phdr(unsigned long addr)
> -{
> -	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> -	Elf32_Phdr *phdr; /* Program header structure pointer */
> -	int i;
> -
> -	ehdr = (Elf32_Ehdr *)addr;
> -	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> -		return load_elf64_image_phdr(addr);
> -
> -	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
> -
> -	/* Load each program header */
> -	for (i = 0; i < ehdr->e_phnum; ++i) {
> -		void *dst = (void *)(uintptr_t)phdr->p_paddr;
> -		void *src = (void *)addr + phdr->p_offset;
> -
> -		debug("Loading phdr %i to 0x%p (%i bytes)\n",
> -		      i, dst, phdr->p_filesz);
> -		if (phdr->p_filesz)
> -			memcpy(dst, src, phdr->p_filesz);
> -		if (phdr->p_filesz != phdr->p_memsz)
> -			memset(dst + phdr->p_filesz, 0x00,
> -			       phdr->p_memsz - phdr->p_filesz);
> -		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> -			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> -		++phdr;
> -	}
> -
> -	return ehdr->e_entry;
> -}
> -
> -static unsigned long load_elf_image_shdr(unsigned long addr)
> -{
> -	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> -	Elf32_Shdr *shdr; /* Section header structure pointer */
> -	unsigned char *strtab = 0; /* String table pointer */
> -	unsigned char *image; /* Binary image pointer */
> -	int i; /* Loop counter */
> -
> -	ehdr = (Elf32_Ehdr *)addr;
> -	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> -		return load_elf64_image_shdr(addr);
> -
> -	/* Find the section header string table for output info */
> -	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> -			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
> -
> -	if (shdr->sh_type == SHT_STRTAB)
> -		strtab = (unsigned char *)(addr + shdr->sh_offset);
> -
> -	/* Load each appropriate section */
> -	for (i = 0; i < ehdr->e_shnum; ++i) {
> -		shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> -				     (i * sizeof(Elf32_Shdr)));
> -
> -		if (!(shdr->sh_flags & SHF_ALLOC) ||
> -		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
> -			continue;
> -		}
> -
> -		if (strtab) {
> -			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> -			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> -			       &strtab[shdr->sh_name],
> -			       (unsigned long)shdr->sh_addr,
> -			       (long)shdr->sh_size);
> -		}
> -
> -		if (shdr->sh_type == SHT_NOBITS) {
> -			memset((void *)(uintptr_t)shdr->sh_addr, 0,
> -			       shdr->sh_size);
> -		} else {
> -			image = (unsigned char *)addr + shdr->sh_offset;
> -			memcpy((void *)(uintptr_t)shdr->sh_addr,
> -			       (const void *)image, shdr->sh_size);
> -		}
> -		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> -			    roundup((shdr->sh_addr + shdr->sh_size),
> -				    ARCH_DMA_MINALIGN) -
> -			    rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> -	}
> -
> -	return ehdr->e_entry;
> -}
> -
>  /* Allow ports to override the default behavior */
>  static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
>  				     int argc, char * const argv[])
> @@ -246,30 +41,6 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
>  	return ret;
>  }
>  
> -/*
> - * Determine if a valid ELF image exists at the given memory location.
> - * First look at the ELF header magic field, then make sure that it is
> - * executable.
> - */
> -int valid_elf_image(unsigned long addr)
> -{
> -	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> -
> -	ehdr = (Elf32_Ehdr *)addr;
> -
> -	if (!IS_ELF(*ehdr)) {
> -		printf("## No elf image at address 0x%08lx\n", addr);
> -		return 0;
> -	}
> -
> -	if (ehdr->e_type != ET_EXEC) {
> -		printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
> -		return 0;
> -	}
> -
> -	return 1;
> -}
> -
>  /* Interpreter command to boot an arbitrary ELF image from memory */
>  int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>  {
> diff --git a/include/elf.h b/include/elf.h
> index 81f40191d7..e7c51986df 100644
> --- a/include/elf.h
> +++ b/include/elf.h
> @@ -692,6 +692,10 @@ unsigned long elf_hash(const unsigned char *name);
>  
>  #ifndef __ASSEMBLER__
>  int valid_elf_image(unsigned long addr);
> +unsigned long load_elf64_image_phdr(unsigned long addr);
> +unsigned long load_elf64_image_shdr(unsigned long addr);
> +unsigned long load_elf_image_phdr(unsigned long addr);
> +unsigned long load_elf_image_shdr(unsigned long addr);
>  #endif
>  
>  #endif /* _ELF_H */
> diff --git a/lib/Kconfig b/lib/Kconfig
> index d040a87d26..b155ced4b2 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -601,4 +601,7 @@ config TEST_FDTDEC
>  config LIB_DATE
>  	bool
>  
> +config ELF
> +	bool "enable basic elf loading/validating functions"
> +
>  endmenu
> diff --git a/lib/Makefile b/lib/Makefile
> index 6b7b9ce85c..93f22d210e 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -121,6 +121,7 @@ obj-y += vsprintf.o strto.o
>  endif
>  
>  obj-y += date.o
> +obj-$(CONFIG_ELF) += elf.o
>  
>  #
>  # Build a fast OID lookup registry from include/linux/oid_registry.h
> diff --git a/lib/elf.c b/lib/elf.c
> new file mode 100644
> index 0000000000..54ac4ee502
> --- /dev/null
> +++ b/lib/elf.c
> @@ -0,0 +1,256 @@
> +/*
> + * Copyright (c) 2001 William L. Pitts
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms are freely
> + * permitted provided that the above copyright notice and this
> + * paragraph and the following disclaimer are duplicated in all
> + * such forms.
> + *
> + * This software is provided "AS IS" and without any express or
> + * implied warranties, including, without limitation, the implied
> + * warranties of merchantability and fitness for a particular
> + * purpose.
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <cpu_func.h>
> +#include <elf.h>
> +#include <env.h>
> +#include <net.h>
> +#include <vxworks.h>
> +#ifdef CONFIG_X86
> +#include <vbe.h>
> +#include <asm/e820.h>
> +#include <linux/linkage.h>
> +#endif
> +
> +/*
> + * A very simple ELF64 loader, assumes the image is valid, returns the
> + * entry point address.
> + *
> + * Note if U-Boot is 32-bit, the loader assumes the to segment's
> + * physical address and size is within the lower 32-bit address space.
> + */
> +unsigned long load_elf64_image_phdr(unsigned long addr)
> +{
> +	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> +	Elf64_Phdr *phdr; /* Program header structure pointer */
> +	int i;
> +
> +	ehdr = (Elf64_Ehdr *)addr;
> +	phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
> +
> +	/* Load each program header */
> +	for (i = 0; i < ehdr->e_phnum; ++i) {
> +		void *dst = (void *)(ulong)phdr->p_paddr;
> +		void *src = (void *)addr + phdr->p_offset;
> +
> +		debug("Loading phdr %i to 0x%p (%lu bytes)\n",
> +		      i, dst, (ulong)phdr->p_filesz);
> +		if (phdr->p_filesz)
> +			memcpy(dst, src, phdr->p_filesz);
> +		if (phdr->p_filesz != phdr->p_memsz)
> +			memset(dst + phdr->p_filesz, 0x00,
> +			       phdr->p_memsz - phdr->p_filesz);
> +		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> +			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> +		++phdr;
> +	}
> +
> +	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> +					    EF_PPC64_ELFV1_ABI)) {
> +		/*
> +		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> +		 * descriptor pointer with the first double word being the
> +		 * address of the entry point of the function.
> +		 */
> +		uintptr_t addr = ehdr->e_entry;
> +
> +		return *(Elf64_Addr *)addr;
> +	}
> +
> +	return ehdr->e_entry;
> +}
> +
> +unsigned long load_elf64_image_shdr(unsigned long addr)
> +{
> +	Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> +	Elf64_Shdr *shdr; /* Section header structure pointer */
> +	unsigned char *strtab = 0; /* String table pointer */
> +	unsigned char *image; /* Binary image pointer */
> +	int i; /* Loop counter */
> +
> +	ehdr = (Elf64_Ehdr *)addr;
> +
> +	/* Find the section header string table for output info */
> +	shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> +			     (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
> +
> +	if (shdr->sh_type == SHT_STRTAB)
> +		strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
> +
> +	/* Load each appropriate section */
> +	for (i = 0; i < ehdr->e_shnum; ++i) {
> +		shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> +				     (i * sizeof(Elf64_Shdr)));
> +
> +		if (!(shdr->sh_flags & SHF_ALLOC) ||
> +		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
> +			continue;
> +		}
> +
> +		if (strtab) {
> +			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> +			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> +			       &strtab[shdr->sh_name],
> +			       (unsigned long)shdr->sh_addr,
> +			       (long)shdr->sh_size);
> +		}
> +
> +		if (shdr->sh_type == SHT_NOBITS) {
> +			memset((void *)(uintptr_t)shdr->sh_addr, 0,
> +			       shdr->sh_size);
> +		} else {
> +			image = (unsigned char *)addr + (ulong)shdr->sh_offset;
> +			memcpy((void *)(uintptr_t)shdr->sh_addr,
> +			       (const void *)image, shdr->sh_size);
> +		}
> +		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> +			    roundup((shdr->sh_addr + shdr->sh_size),
> +				     ARCH_DMA_MINALIGN) -
> +			            rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> +	}
> +
> +	if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> +					    EF_PPC64_ELFV1_ABI)) {
> +		/*
> +		 * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> +		 * descriptor pointer with the first double word being the
> +		 * address of the entry point of the function.
> +		 */
> +		uintptr_t addr = ehdr->e_entry;
> +
> +		return *(Elf64_Addr *)addr;
> +	}
> +
> +	return ehdr->e_entry;
> +}
> +
> +/*
> + * A very simple ELF loader, assumes the image is valid, returns the
> + * entry point address.
> + *
> + * The loader firstly reads the EFI class to see if it's a 64-bit image.
> + * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
> + */
> +unsigned long load_elf_image_phdr(unsigned long addr)
> +{
> +	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> +	Elf32_Phdr *phdr; /* Program header structure pointer */
> +	int i;
> +
> +	ehdr = (Elf32_Ehdr *)addr;
> +	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> +		return load_elf64_image_phdr(addr);
> +
> +	phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
> +
> +	/* Load each program header */
> +	for (i = 0; i < ehdr->e_phnum; ++i) {
> +		void *dst = (void *)(uintptr_t)phdr->p_paddr;
> +		void *src = (void *)addr + phdr->p_offset;
> +
> +		debug("Loading phdr %i to 0x%p (%i bytes)\n",
> +		      i, dst, phdr->p_filesz);
> +		if (phdr->p_filesz)
> +			memcpy(dst, src, phdr->p_filesz);
> +		if (phdr->p_filesz != phdr->p_memsz)
> +			memset(dst + phdr->p_filesz, 0x00,
> +			       phdr->p_memsz - phdr->p_filesz);
> +		flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> +			    roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> +		++phdr;
> +	}
> +
> +	return ehdr->e_entry;
> +}
> +
> +unsigned long load_elf_image_shdr(unsigned long addr)
> +{
> +	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> +	Elf32_Shdr *shdr; /* Section header structure pointer */
> +	unsigned char *strtab = 0; /* String table pointer */
> +	unsigned char *image; /* Binary image pointer */
> +	int i; /* Loop counter */
> +
> +	ehdr = (Elf32_Ehdr *)addr;
> +	if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> +		return load_elf64_image_shdr(addr);
> +
> +	/* Find the section header string table for output info */
> +	shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> +			     (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
> +
> +	if (shdr->sh_type == SHT_STRTAB)
> +		strtab = (unsigned char *)(addr + shdr->sh_offset);
> +
> +	/* Load each appropriate section */
> +	for (i = 0; i < ehdr->e_shnum; ++i) {
> +		shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> +				     (i * sizeof(Elf32_Shdr)));
> +
> +		if (!(shdr->sh_flags & SHF_ALLOC) ||
> +		    shdr->sh_addr == 0 || shdr->sh_size == 0) {
> +			continue;
> +		}
> +
> +		if (strtab) {
> +			debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> +			      (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> +			       &strtab[shdr->sh_name],
> +			       (unsigned long)shdr->sh_addr,
> +			       (long)shdr->sh_size);
> +		}
> +
> +		if (shdr->sh_type == SHT_NOBITS) {
> +			memset((void *)(uintptr_t)shdr->sh_addr, 0,
> +			       shdr->sh_size);
> +		} else {
> +			image = (unsigned char *)addr + shdr->sh_offset;
> +			memcpy((void *)(uintptr_t)shdr->sh_addr,
> +			       (const void *)image, shdr->sh_size);
> +		}
> +		flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> +			    roundup((shdr->sh_addr + shdr->sh_size),
> +				    ARCH_DMA_MINALIGN) -
> +			    rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> +	}
> +
> +	return ehdr->e_entry;
> +}
> +
> +/*
> + * Determine if a valid ELF image exists at the given memory location.
> + * First look at the ELF header magic field, then make sure that it is
> + * executable.
> + */
> +int valid_elf_image(unsigned long addr)
> +{
> +	Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> +
> +	ehdr = (Elf32_Ehdr *)addr;
> +
> +	if (!IS_ELF(*ehdr)) {
> +		printf("## No elf image at address 0x%08lx\n", addr);
> +		return 0;
> +	}
> +
> +	if (ehdr->e_type != ET_EXEC) {
> +		printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
> +		return 0;
> +	}
> +
> +	return 1;
> +}
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 8/9] configs: j721e_evm_r5: Add configs for environment in eMMC
  2020-01-13  5:54 ` [PATCH v2 8/9] configs: j721e_evm_r5: Add configs for environment in eMMC Keerthy
@ 2020-01-17  5:14   ` Lokesh Vutla
  0 siblings, 0 replies; 14+ messages in thread
From: Lokesh Vutla @ 2020-01-17  5:14 UTC (permalink / raw)
  To: u-boot



On 13/01/20 11:24 AM, Keerthy wrote:
> From: Faiz Abbas <faiz_abbas@ti.com>
> 
> Add config to save and read back environment from eMMC.
> 
> Signed-off-by: Faiz Abbas <faiz_abbas@ti.com>
> Signed-off-by: Keerthy <j-keerthy@ti.com>

This is conflicting with https://patchwork.ozlabs.org/patch/1224239/. and this
is breaking boot on J7.

Can you rebase on top of
https://gitlab.denx.de/u-boot/custodians/u-boot-ti/commits/next and repost the
series?

Thanks and regards,
Lokesh

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib
  2020-01-17  4:27   ` Lokesh Vutla
@ 2020-01-17  7:49     ` Simon Goldschmidt
  2020-01-17  8:06       ` Keerthy
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Goldschmidt @ 2020-01-17  7:49 UTC (permalink / raw)
  To: u-boot

On Fri, Jan 17, 2020 at 5:27 AM Lokesh Vutla <lokeshvutla@ti.com> wrote:
>
> Simon,
>
> On 13/01/20 11:24 AM, Keerthy wrote:
> > Move the generic elf loading/validating functions to lib/
> > so that they can be re-used and accessed by code existing
> > outside cmd.
> >
> > Signed-off-by: Keerthy <j-keerthy@ti.com>
> > Suggested-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
>
> Are you okay with this patch? If yes, Ill apply to u-boot-ti along with other
> patches in this series.

Yes.

Reviewed-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>

Regards,
Simon

>
> Thanks and regards,
> Lokesh
>
> > ---
> > Changes in v2:
> >
> >   * Factored out all the generic elf handling functions under lib/elf.c
> >
> >  cmd/Kconfig   |   1 +
> >  cmd/elf.c     | 229 --------------------------------------------
> >  include/elf.h |   4 +
> >  lib/Kconfig   |   3 +
> >  lib/Makefile  |   1 +
> >  lib/elf.c     | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  6 files changed, 265 insertions(+), 229 deletions(-)
> >  create mode 100644 lib/elf.c
> >
> > diff --git a/cmd/Kconfig b/cmd/Kconfig
> > index 298feae24d..6f4f08d02a 100644
> > --- a/cmd/Kconfig
> > +++ b/cmd/Kconfig
> > @@ -375,6 +375,7 @@ config CMD_ADTIMG
> >  config CMD_ELF
> >       bool "bootelf, bootvx"
> >       default y
> > +     select ELF
> >       help
> >         Boot an ELF/vxWorks image from the memory.
> >
> > diff --git a/cmd/elf.c b/cmd/elf.c
> > index 32f12a72b9..23cc17aebc 100644
> > --- a/cmd/elf.c
> > +++ b/cmd/elf.c
> > @@ -26,211 +26,6 @@
> >  #include <linux/linkage.h>
> >  #endif
> >
> > -/*
> > - * A very simple ELF64 loader, assumes the image is valid, returns the
> > - * entry point address.
> > - *
> > - * Note if U-Boot is 32-bit, the loader assumes the to segment's
> > - * physical address and size is within the lower 32-bit address space.
> > - */
> > -static unsigned long load_elf64_image_phdr(unsigned long addr)
> > -{
> > -     Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> > -     Elf64_Phdr *phdr; /* Program header structure pointer */
> > -     int i;
> > -
> > -     ehdr = (Elf64_Ehdr *)addr;
> > -     phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
> > -
> > -     /* Load each program header */
> > -     for (i = 0; i < ehdr->e_phnum; ++i) {
> > -             void *dst = (void *)(ulong)phdr->p_paddr;
> > -             void *src = (void *)addr + phdr->p_offset;
> > -
> > -             debug("Loading phdr %i to 0x%p (%lu bytes)\n",
> > -                   i, dst, (ulong)phdr->p_filesz);
> > -             if (phdr->p_filesz)
> > -                     memcpy(dst, src, phdr->p_filesz);
> > -             if (phdr->p_filesz != phdr->p_memsz)
> > -                     memset(dst + phdr->p_filesz, 0x00,
> > -                            phdr->p_memsz - phdr->p_filesz);
> > -             flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > -                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > -             ++phdr;
> > -     }
> > -
> > -     if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> > -                                         EF_PPC64_ELFV1_ABI)) {
> > -             /*
> > -              * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> > -              * descriptor pointer with the first double word being the
> > -              * address of the entry point of the function.
> > -              */
> > -             uintptr_t addr = ehdr->e_entry;
> > -
> > -             return *(Elf64_Addr *)addr;
> > -     }
> > -
> > -     return ehdr->e_entry;
> > -}
> > -
> > -static unsigned long load_elf64_image_shdr(unsigned long addr)
> > -{
> > -     Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> > -     Elf64_Shdr *shdr; /* Section header structure pointer */
> > -     unsigned char *strtab = 0; /* String table pointer */
> > -     unsigned char *image; /* Binary image pointer */
> > -     int i; /* Loop counter */
> > -
> > -     ehdr = (Elf64_Ehdr *)addr;
> > -
> > -     /* Find the section header string table for output info */
> > -     shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> > -                          (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
> > -
> > -     if (shdr->sh_type == SHT_STRTAB)
> > -             strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
> > -
> > -     /* Load each appropriate section */
> > -     for (i = 0; i < ehdr->e_shnum; ++i) {
> > -             shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> > -                                  (i * sizeof(Elf64_Shdr)));
> > -
> > -             if (!(shdr->sh_flags & SHF_ALLOC) ||
> > -                 shdr->sh_addr == 0 || shdr->sh_size == 0) {
> > -                     continue;
> > -             }
> > -
> > -             if (strtab) {
> > -                     debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> > -                           (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> > -                            &strtab[shdr->sh_name],
> > -                            (unsigned long)shdr->sh_addr,
> > -                            (long)shdr->sh_size);
> > -             }
> > -
> > -             if (shdr->sh_type == SHT_NOBITS) {
> > -                     memset((void *)(uintptr_t)shdr->sh_addr, 0,
> > -                            shdr->sh_size);
> > -             } else {
> > -                     image = (unsigned char *)addr + (ulong)shdr->sh_offset;
> > -                     memcpy((void *)(uintptr_t)shdr->sh_addr,
> > -                            (const void *)image, shdr->sh_size);
> > -             }
> > -             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > -                         roundup((shdr->sh_addr + shdr->sh_size),
> > -                                  ARCH_DMA_MINALIGN) -
> > -                                 rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > -     }
> > -
> > -     if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> > -                                         EF_PPC64_ELFV1_ABI)) {
> > -             /*
> > -              * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> > -              * descriptor pointer with the first double word being the
> > -              * address of the entry point of the function.
> > -              */
> > -             uintptr_t addr = ehdr->e_entry;
> > -
> > -             return *(Elf64_Addr *)addr;
> > -     }
> > -
> > -     return ehdr->e_entry;
> > -}
> > -
> > -/*
> > - * A very simple ELF loader, assumes the image is valid, returns the
> > - * entry point address.
> > - *
> > - * The loader firstly reads the EFI class to see if it's a 64-bit image.
> > - * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
> > - */
> > -static unsigned long load_elf_image_phdr(unsigned long addr)
> > -{
> > -     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > -     Elf32_Phdr *phdr; /* Program header structure pointer */
> > -     int i;
> > -
> > -     ehdr = (Elf32_Ehdr *)addr;
> > -     if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> > -             return load_elf64_image_phdr(addr);
> > -
> > -     phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
> > -
> > -     /* Load each program header */
> > -     for (i = 0; i < ehdr->e_phnum; ++i) {
> > -             void *dst = (void *)(uintptr_t)phdr->p_paddr;
> > -             void *src = (void *)addr + phdr->p_offset;
> > -
> > -             debug("Loading phdr %i to 0x%p (%i bytes)\n",
> > -                   i, dst, phdr->p_filesz);
> > -             if (phdr->p_filesz)
> > -                     memcpy(dst, src, phdr->p_filesz);
> > -             if (phdr->p_filesz != phdr->p_memsz)
> > -                     memset(dst + phdr->p_filesz, 0x00,
> > -                            phdr->p_memsz - phdr->p_filesz);
> > -             flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > -                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > -             ++phdr;
> > -     }
> > -
> > -     return ehdr->e_entry;
> > -}
> > -
> > -static unsigned long load_elf_image_shdr(unsigned long addr)
> > -{
> > -     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > -     Elf32_Shdr *shdr; /* Section header structure pointer */
> > -     unsigned char *strtab = 0; /* String table pointer */
> > -     unsigned char *image; /* Binary image pointer */
> > -     int i; /* Loop counter */
> > -
> > -     ehdr = (Elf32_Ehdr *)addr;
> > -     if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> > -             return load_elf64_image_shdr(addr);
> > -
> > -     /* Find the section header string table for output info */
> > -     shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > -                          (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
> > -
> > -     if (shdr->sh_type == SHT_STRTAB)
> > -             strtab = (unsigned char *)(addr + shdr->sh_offset);
> > -
> > -     /* Load each appropriate section */
> > -     for (i = 0; i < ehdr->e_shnum; ++i) {
> > -             shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > -                                  (i * sizeof(Elf32_Shdr)));
> > -
> > -             if (!(shdr->sh_flags & SHF_ALLOC) ||
> > -                 shdr->sh_addr == 0 || shdr->sh_size == 0) {
> > -                     continue;
> > -             }
> > -
> > -             if (strtab) {
> > -                     debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> > -                           (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> > -                            &strtab[shdr->sh_name],
> > -                            (unsigned long)shdr->sh_addr,
> > -                            (long)shdr->sh_size);
> > -             }
> > -
> > -             if (shdr->sh_type == SHT_NOBITS) {
> > -                     memset((void *)(uintptr_t)shdr->sh_addr, 0,
> > -                            shdr->sh_size);
> > -             } else {
> > -                     image = (unsigned char *)addr + shdr->sh_offset;
> > -                     memcpy((void *)(uintptr_t)shdr->sh_addr,
> > -                            (const void *)image, shdr->sh_size);
> > -             }
> > -             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > -                         roundup((shdr->sh_addr + shdr->sh_size),
> > -                                 ARCH_DMA_MINALIGN) -
> > -                         rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > -     }
> > -
> > -     return ehdr->e_entry;
> > -}
> > -
> >  /* Allow ports to override the default behavior */
> >  static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
> >                                    int argc, char * const argv[])
> > @@ -246,30 +41,6 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
> >       return ret;
> >  }
> >
> > -/*
> > - * Determine if a valid ELF image exists at the given memory location.
> > - * First look at the ELF header magic field, then make sure that it is
> > - * executable.
> > - */
> > -int valid_elf_image(unsigned long addr)
> > -{
> > -     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > -
> > -     ehdr = (Elf32_Ehdr *)addr;
> > -
> > -     if (!IS_ELF(*ehdr)) {
> > -             printf("## No elf image at address 0x%08lx\n", addr);
> > -             return 0;
> > -     }
> > -
> > -     if (ehdr->e_type != ET_EXEC) {
> > -             printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
> > -             return 0;
> > -     }
> > -
> > -     return 1;
> > -}
> > -
> >  /* Interpreter command to boot an arbitrary ELF image from memory */
> >  int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> >  {
> > diff --git a/include/elf.h b/include/elf.h
> > index 81f40191d7..e7c51986df 100644
> > --- a/include/elf.h
> > +++ b/include/elf.h
> > @@ -692,6 +692,10 @@ unsigned long elf_hash(const unsigned char *name);
> >
> >  #ifndef __ASSEMBLER__
> >  int valid_elf_image(unsigned long addr);
> > +unsigned long load_elf64_image_phdr(unsigned long addr);
> > +unsigned long load_elf64_image_shdr(unsigned long addr);
> > +unsigned long load_elf_image_phdr(unsigned long addr);
> > +unsigned long load_elf_image_shdr(unsigned long addr);
> >  #endif
> >
> >  #endif /* _ELF_H */
> > diff --git a/lib/Kconfig b/lib/Kconfig
> > index d040a87d26..b155ced4b2 100644
> > --- a/lib/Kconfig
> > +++ b/lib/Kconfig
> > @@ -601,4 +601,7 @@ config TEST_FDTDEC
> >  config LIB_DATE
> >       bool
> >
> > +config ELF
> > +     bool "enable basic elf loading/validating functions"
> > +
> >  endmenu
> > diff --git a/lib/Makefile b/lib/Makefile
> > index 6b7b9ce85c..93f22d210e 100644
> > --- a/lib/Makefile
> > +++ b/lib/Makefile
> > @@ -121,6 +121,7 @@ obj-y += vsprintf.o strto.o
> >  endif
> >
> >  obj-y += date.o
> > +obj-$(CONFIG_ELF) += elf.o
> >
> >  #
> >  # Build a fast OID lookup registry from include/linux/oid_registry.h
> > diff --git a/lib/elf.c b/lib/elf.c
> > new file mode 100644
> > index 0000000000..54ac4ee502
> > --- /dev/null
> > +++ b/lib/elf.c
> > @@ -0,0 +1,256 @@
> > +/*
> > + * Copyright (c) 2001 William L. Pitts
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms are freely
> > + * permitted provided that the above copyright notice and this
> > + * paragraph and the following disclaimer are duplicated in all
> > + * such forms.
> > + *
> > + * This software is provided "AS IS" and without any express or
> > + * implied warranties, including, without limitation, the implied
> > + * warranties of merchantability and fitness for a particular
> > + * purpose.
> > + */
> > +
> > +#include <common.h>
> > +#include <command.h>
> > +#include <cpu_func.h>
> > +#include <elf.h>
> > +#include <env.h>
> > +#include <net.h>
> > +#include <vxworks.h>
> > +#ifdef CONFIG_X86
> > +#include <vbe.h>
> > +#include <asm/e820.h>
> > +#include <linux/linkage.h>
> > +#endif
> > +
> > +/*
> > + * A very simple ELF64 loader, assumes the image is valid, returns the
> > + * entry point address.
> > + *
> > + * Note if U-Boot is 32-bit, the loader assumes the to segment's
> > + * physical address and size is within the lower 32-bit address space.
> > + */
> > +unsigned long load_elf64_image_phdr(unsigned long addr)
> > +{
> > +     Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> > +     Elf64_Phdr *phdr; /* Program header structure pointer */
> > +     int i;
> > +
> > +     ehdr = (Elf64_Ehdr *)addr;
> > +     phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
> > +
> > +     /* Load each program header */
> > +     for (i = 0; i < ehdr->e_phnum; ++i) {
> > +             void *dst = (void *)(ulong)phdr->p_paddr;
> > +             void *src = (void *)addr + phdr->p_offset;
> > +
> > +             debug("Loading phdr %i to 0x%p (%lu bytes)\n",
> > +                   i, dst, (ulong)phdr->p_filesz);
> > +             if (phdr->p_filesz)
> > +                     memcpy(dst, src, phdr->p_filesz);
> > +             if (phdr->p_filesz != phdr->p_memsz)
> > +                     memset(dst + phdr->p_filesz, 0x00,
> > +                            phdr->p_memsz - phdr->p_filesz);
> > +             flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > +                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > +             ++phdr;
> > +     }
> > +
> > +     if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> > +                                         EF_PPC64_ELFV1_ABI)) {
> > +             /*
> > +              * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> > +              * descriptor pointer with the first double word being the
> > +              * address of the entry point of the function.
> > +              */
> > +             uintptr_t addr = ehdr->e_entry;
> > +
> > +             return *(Elf64_Addr *)addr;
> > +     }
> > +
> > +     return ehdr->e_entry;
> > +}
> > +
> > +unsigned long load_elf64_image_shdr(unsigned long addr)
> > +{
> > +     Elf64_Ehdr *ehdr; /* Elf header structure pointer */
> > +     Elf64_Shdr *shdr; /* Section header structure pointer */
> > +     unsigned char *strtab = 0; /* String table pointer */
> > +     unsigned char *image; /* Binary image pointer */
> > +     int i; /* Loop counter */
> > +
> > +     ehdr = (Elf64_Ehdr *)addr;
> > +
> > +     /* Find the section header string table for output info */
> > +     shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> > +                          (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
> > +
> > +     if (shdr->sh_type == SHT_STRTAB)
> > +             strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
> > +
> > +     /* Load each appropriate section */
> > +     for (i = 0; i < ehdr->e_shnum; ++i) {
> > +             shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
> > +                                  (i * sizeof(Elf64_Shdr)));
> > +
> > +             if (!(shdr->sh_flags & SHF_ALLOC) ||
> > +                 shdr->sh_addr == 0 || shdr->sh_size == 0) {
> > +                     continue;
> > +             }
> > +
> > +             if (strtab) {
> > +                     debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> > +                           (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> > +                            &strtab[shdr->sh_name],
> > +                            (unsigned long)shdr->sh_addr,
> > +                            (long)shdr->sh_size);
> > +             }
> > +
> > +             if (shdr->sh_type == SHT_NOBITS) {
> > +                     memset((void *)(uintptr_t)shdr->sh_addr, 0,
> > +                            shdr->sh_size);
> > +             } else {
> > +                     image = (unsigned char *)addr + (ulong)shdr->sh_offset;
> > +                     memcpy((void *)(uintptr_t)shdr->sh_addr,
> > +                            (const void *)image, shdr->sh_size);
> > +             }
> > +             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > +                         roundup((shdr->sh_addr + shdr->sh_size),
> > +                                  ARCH_DMA_MINALIGN) -
> > +                                 rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > +     }
> > +
> > +     if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
> > +                                         EF_PPC64_ELFV1_ABI)) {
> > +             /*
> > +              * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
> > +              * descriptor pointer with the first double word being the
> > +              * address of the entry point of the function.
> > +              */
> > +             uintptr_t addr = ehdr->e_entry;
> > +
> > +             return *(Elf64_Addr *)addr;
> > +     }
> > +
> > +     return ehdr->e_entry;
> > +}
> > +
> > +/*
> > + * A very simple ELF loader, assumes the image is valid, returns the
> > + * entry point address.
> > + *
> > + * The loader firstly reads the EFI class to see if it's a 64-bit image.
> > + * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
> > + */
> > +unsigned long load_elf_image_phdr(unsigned long addr)
> > +{
> > +     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > +     Elf32_Phdr *phdr; /* Program header structure pointer */
> > +     int i;
> > +
> > +     ehdr = (Elf32_Ehdr *)addr;
> > +     if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> > +             return load_elf64_image_phdr(addr);
> > +
> > +     phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
> > +
> > +     /* Load each program header */
> > +     for (i = 0; i < ehdr->e_phnum; ++i) {
> > +             void *dst = (void *)(uintptr_t)phdr->p_paddr;
> > +             void *src = (void *)addr + phdr->p_offset;
> > +
> > +             debug("Loading phdr %i to 0x%p (%i bytes)\n",
> > +                   i, dst, phdr->p_filesz);
> > +             if (phdr->p_filesz)
> > +                     memcpy(dst, src, phdr->p_filesz);
> > +             if (phdr->p_filesz != phdr->p_memsz)
> > +                     memset(dst + phdr->p_filesz, 0x00,
> > +                            phdr->p_memsz - phdr->p_filesz);
> > +             flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
> > +                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
> > +             ++phdr;
> > +     }
> > +
> > +     return ehdr->e_entry;
> > +}
> > +
> > +unsigned long load_elf_image_shdr(unsigned long addr)
> > +{
> > +     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > +     Elf32_Shdr *shdr; /* Section header structure pointer */
> > +     unsigned char *strtab = 0; /* String table pointer */
> > +     unsigned char *image; /* Binary image pointer */
> > +     int i; /* Loop counter */
> > +
> > +     ehdr = (Elf32_Ehdr *)addr;
> > +     if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
> > +             return load_elf64_image_shdr(addr);
> > +
> > +     /* Find the section header string table for output info */
> > +     shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > +                          (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
> > +
> > +     if (shdr->sh_type == SHT_STRTAB)
> > +             strtab = (unsigned char *)(addr + shdr->sh_offset);
> > +
> > +     /* Load each appropriate section */
> > +     for (i = 0; i < ehdr->e_shnum; ++i) {
> > +             shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
> > +                                  (i * sizeof(Elf32_Shdr)));
> > +
> > +             if (!(shdr->sh_flags & SHF_ALLOC) ||
> > +                 shdr->sh_addr == 0 || shdr->sh_size == 0) {
> > +                     continue;
> > +             }
> > +
> > +             if (strtab) {
> > +                     debug("%sing %s @ 0x%08lx (%ld bytes)\n",
> > +                           (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
> > +                            &strtab[shdr->sh_name],
> > +                            (unsigned long)shdr->sh_addr,
> > +                            (long)shdr->sh_size);
> > +             }
> > +
> > +             if (shdr->sh_type == SHT_NOBITS) {
> > +                     memset((void *)(uintptr_t)shdr->sh_addr, 0,
> > +                            shdr->sh_size);
> > +             } else {
> > +                     image = (unsigned char *)addr + shdr->sh_offset;
> > +                     memcpy((void *)(uintptr_t)shdr->sh_addr,
> > +                            (const void *)image, shdr->sh_size);
> > +             }
> > +             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
> > +                         roundup((shdr->sh_addr + shdr->sh_size),
> > +                                 ARCH_DMA_MINALIGN) -
> > +                         rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
> > +     }
> > +
> > +     return ehdr->e_entry;
> > +}
> > +
> > +/*
> > + * Determine if a valid ELF image exists at the given memory location.
> > + * First look at the ELF header magic field, then make sure that it is
> > + * executable.
> > + */
> > +int valid_elf_image(unsigned long addr)
> > +{
> > +     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
> > +
> > +     ehdr = (Elf32_Ehdr *)addr;
> > +
> > +     if (!IS_ELF(*ehdr)) {
> > +             printf("## No elf image at address 0x%08lx\n", addr);
> > +             return 0;
> > +     }
> > +
> > +     if (ehdr->e_type != ET_EXEC) {
> > +             printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
> > +             return 0;
> > +     }
> > +
> > +     return 1;
> > +}
> >

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib
  2020-01-17  7:49     ` Simon Goldschmidt
@ 2020-01-17  8:06       ` Keerthy
  0 siblings, 0 replies; 14+ messages in thread
From: Keerthy @ 2020-01-17  8:06 UTC (permalink / raw)
  To: u-boot



On 17/01/20 1:19 pm, Simon Goldschmidt wrote:
> On Fri, Jan 17, 2020 at 5:27 AM Lokesh Vutla <lokeshvutla@ti.com> wrote:
>>
>> Simon,
>>
>> On 13/01/20 11:24 AM, Keerthy wrote:
>>> Move the generic elf loading/validating functions to lib/
>>> so that they can be re-used and accessed by code existing
>>> outside cmd.
>>>
>>> Signed-off-by: Keerthy <j-keerthy@ti.com>
>>> Suggested-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
>>
>> Are you okay with this patch? If yes, Ill apply to u-boot-ti along with other
>> patches in this series.
> 
> Yes.
> 
> Reviewed-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>

Thanks Simon!

> 
> Regards,
> Simon
> 
>>
>> Thanks and regards,
>> Lokesh
>>
>>> ---
>>> Changes in v2:
>>>
>>>    * Factored out all the generic elf handling functions under lib/elf.c
>>>
>>>   cmd/Kconfig   |   1 +
>>>   cmd/elf.c     | 229 --------------------------------------------
>>>   include/elf.h |   4 +
>>>   lib/Kconfig   |   3 +
>>>   lib/Makefile  |   1 +
>>>   lib/elf.c     | 256 ++++++++++++++++++++++++++++++++++++++++++++++++++
>>>   6 files changed, 265 insertions(+), 229 deletions(-)
>>>   create mode 100644 lib/elf.c
>>>
>>> diff --git a/cmd/Kconfig b/cmd/Kconfig
>>> index 298feae24d..6f4f08d02a 100644
>>> --- a/cmd/Kconfig
>>> +++ b/cmd/Kconfig
>>> @@ -375,6 +375,7 @@ config CMD_ADTIMG
>>>   config CMD_ELF
>>>        bool "bootelf, bootvx"
>>>        default y
>>> +     select ELF
>>>        help
>>>          Boot an ELF/vxWorks image from the memory.
>>>
>>> diff --git a/cmd/elf.c b/cmd/elf.c
>>> index 32f12a72b9..23cc17aebc 100644
>>> --- a/cmd/elf.c
>>> +++ b/cmd/elf.c
>>> @@ -26,211 +26,6 @@
>>>   #include <linux/linkage.h>
>>>   #endif
>>>
>>> -/*
>>> - * A very simple ELF64 loader, assumes the image is valid, returns the
>>> - * entry point address.
>>> - *
>>> - * Note if U-Boot is 32-bit, the loader assumes the to segment's
>>> - * physical address and size is within the lower 32-bit address space.
>>> - */
>>> -static unsigned long load_elf64_image_phdr(unsigned long addr)
>>> -{
>>> -     Elf64_Ehdr *ehdr; /* Elf header structure pointer */
>>> -     Elf64_Phdr *phdr; /* Program header structure pointer */
>>> -     int i;
>>> -
>>> -     ehdr = (Elf64_Ehdr *)addr;
>>> -     phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
>>> -
>>> -     /* Load each program header */
>>> -     for (i = 0; i < ehdr->e_phnum; ++i) {
>>> -             void *dst = (void *)(ulong)phdr->p_paddr;
>>> -             void *src = (void *)addr + phdr->p_offset;
>>> -
>>> -             debug("Loading phdr %i to 0x%p (%lu bytes)\n",
>>> -                   i, dst, (ulong)phdr->p_filesz);
>>> -             if (phdr->p_filesz)
>>> -                     memcpy(dst, src, phdr->p_filesz);
>>> -             if (phdr->p_filesz != phdr->p_memsz)
>>> -                     memset(dst + phdr->p_filesz, 0x00,
>>> -                            phdr->p_memsz - phdr->p_filesz);
>>> -             flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
>>> -                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
>>> -             ++phdr;
>>> -     }
>>> -
>>> -     if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
>>> -                                         EF_PPC64_ELFV1_ABI)) {
>>> -             /*
>>> -              * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
>>> -              * descriptor pointer with the first double word being the
>>> -              * address of the entry point of the function.
>>> -              */
>>> -             uintptr_t addr = ehdr->e_entry;
>>> -
>>> -             return *(Elf64_Addr *)addr;
>>> -     }
>>> -
>>> -     return ehdr->e_entry;
>>> -}
>>> -
>>> -static unsigned long load_elf64_image_shdr(unsigned long addr)
>>> -{
>>> -     Elf64_Ehdr *ehdr; /* Elf header structure pointer */
>>> -     Elf64_Shdr *shdr; /* Section header structure pointer */
>>> -     unsigned char *strtab = 0; /* String table pointer */
>>> -     unsigned char *image; /* Binary image pointer */
>>> -     int i; /* Loop counter */
>>> -
>>> -     ehdr = (Elf64_Ehdr *)addr;
>>> -
>>> -     /* Find the section header string table for output info */
>>> -     shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
>>> -                          (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
>>> -
>>> -     if (shdr->sh_type == SHT_STRTAB)
>>> -             strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
>>> -
>>> -     /* Load each appropriate section */
>>> -     for (i = 0; i < ehdr->e_shnum; ++i) {
>>> -             shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
>>> -                                  (i * sizeof(Elf64_Shdr)));
>>> -
>>> -             if (!(shdr->sh_flags & SHF_ALLOC) ||
>>> -                 shdr->sh_addr == 0 || shdr->sh_size == 0) {
>>> -                     continue;
>>> -             }
>>> -
>>> -             if (strtab) {
>>> -                     debug("%sing %s @ 0x%08lx (%ld bytes)\n",
>>> -                           (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
>>> -                            &strtab[shdr->sh_name],
>>> -                            (unsigned long)shdr->sh_addr,
>>> -                            (long)shdr->sh_size);
>>> -             }
>>> -
>>> -             if (shdr->sh_type == SHT_NOBITS) {
>>> -                     memset((void *)(uintptr_t)shdr->sh_addr, 0,
>>> -                            shdr->sh_size);
>>> -             } else {
>>> -                     image = (unsigned char *)addr + (ulong)shdr->sh_offset;
>>> -                     memcpy((void *)(uintptr_t)shdr->sh_addr,
>>> -                            (const void *)image, shdr->sh_size);
>>> -             }
>>> -             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
>>> -                         roundup((shdr->sh_addr + shdr->sh_size),
>>> -                                  ARCH_DMA_MINALIGN) -
>>> -                                 rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
>>> -     }
>>> -
>>> -     if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
>>> -                                         EF_PPC64_ELFV1_ABI)) {
>>> -             /*
>>> -              * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
>>> -              * descriptor pointer with the first double word being the
>>> -              * address of the entry point of the function.
>>> -              */
>>> -             uintptr_t addr = ehdr->e_entry;
>>> -
>>> -             return *(Elf64_Addr *)addr;
>>> -     }
>>> -
>>> -     return ehdr->e_entry;
>>> -}
>>> -
>>> -/*
>>> - * A very simple ELF loader, assumes the image is valid, returns the
>>> - * entry point address.
>>> - *
>>> - * The loader firstly reads the EFI class to see if it's a 64-bit image.
>>> - * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
>>> - */
>>> -static unsigned long load_elf_image_phdr(unsigned long addr)
>>> -{
>>> -     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
>>> -     Elf32_Phdr *phdr; /* Program header structure pointer */
>>> -     int i;
>>> -
>>> -     ehdr = (Elf32_Ehdr *)addr;
>>> -     if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
>>> -             return load_elf64_image_phdr(addr);
>>> -
>>> -     phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
>>> -
>>> -     /* Load each program header */
>>> -     for (i = 0; i < ehdr->e_phnum; ++i) {
>>> -             void *dst = (void *)(uintptr_t)phdr->p_paddr;
>>> -             void *src = (void *)addr + phdr->p_offset;
>>> -
>>> -             debug("Loading phdr %i to 0x%p (%i bytes)\n",
>>> -                   i, dst, phdr->p_filesz);
>>> -             if (phdr->p_filesz)
>>> -                     memcpy(dst, src, phdr->p_filesz);
>>> -             if (phdr->p_filesz != phdr->p_memsz)
>>> -                     memset(dst + phdr->p_filesz, 0x00,
>>> -                            phdr->p_memsz - phdr->p_filesz);
>>> -             flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
>>> -                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
>>> -             ++phdr;
>>> -     }
>>> -
>>> -     return ehdr->e_entry;
>>> -}
>>> -
>>> -static unsigned long load_elf_image_shdr(unsigned long addr)
>>> -{
>>> -     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
>>> -     Elf32_Shdr *shdr; /* Section header structure pointer */
>>> -     unsigned char *strtab = 0; /* String table pointer */
>>> -     unsigned char *image; /* Binary image pointer */
>>> -     int i; /* Loop counter */
>>> -
>>> -     ehdr = (Elf32_Ehdr *)addr;
>>> -     if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
>>> -             return load_elf64_image_shdr(addr);
>>> -
>>> -     /* Find the section header string table for output info */
>>> -     shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
>>> -                          (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
>>> -
>>> -     if (shdr->sh_type == SHT_STRTAB)
>>> -             strtab = (unsigned char *)(addr + shdr->sh_offset);
>>> -
>>> -     /* Load each appropriate section */
>>> -     for (i = 0; i < ehdr->e_shnum; ++i) {
>>> -             shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
>>> -                                  (i * sizeof(Elf32_Shdr)));
>>> -
>>> -             if (!(shdr->sh_flags & SHF_ALLOC) ||
>>> -                 shdr->sh_addr == 0 || shdr->sh_size == 0) {
>>> -                     continue;
>>> -             }
>>> -
>>> -             if (strtab) {
>>> -                     debug("%sing %s @ 0x%08lx (%ld bytes)\n",
>>> -                           (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
>>> -                            &strtab[shdr->sh_name],
>>> -                            (unsigned long)shdr->sh_addr,
>>> -                            (long)shdr->sh_size);
>>> -             }
>>> -
>>> -             if (shdr->sh_type == SHT_NOBITS) {
>>> -                     memset((void *)(uintptr_t)shdr->sh_addr, 0,
>>> -                            shdr->sh_size);
>>> -             } else {
>>> -                     image = (unsigned char *)addr + shdr->sh_offset;
>>> -                     memcpy((void *)(uintptr_t)shdr->sh_addr,
>>> -                            (const void *)image, shdr->sh_size);
>>> -             }
>>> -             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
>>> -                         roundup((shdr->sh_addr + shdr->sh_size),
>>> -                                 ARCH_DMA_MINALIGN) -
>>> -                         rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
>>> -     }
>>> -
>>> -     return ehdr->e_entry;
>>> -}
>>> -
>>>   /* Allow ports to override the default behavior */
>>>   static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
>>>                                     int argc, char * const argv[])
>>> @@ -246,30 +41,6 @@ static unsigned long do_bootelf_exec(ulong (*entry)(int, char * const[]),
>>>        return ret;
>>>   }
>>>
>>> -/*
>>> - * Determine if a valid ELF image exists at the given memory location.
>>> - * First look at the ELF header magic field, then make sure that it is
>>> - * executable.
>>> - */
>>> -int valid_elf_image(unsigned long addr)
>>> -{
>>> -     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
>>> -
>>> -     ehdr = (Elf32_Ehdr *)addr;
>>> -
>>> -     if (!IS_ELF(*ehdr)) {
>>> -             printf("## No elf image at address 0x%08lx\n", addr);
>>> -             return 0;
>>> -     }
>>> -
>>> -     if (ehdr->e_type != ET_EXEC) {
>>> -             printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
>>> -             return 0;
>>> -     }
>>> -
>>> -     return 1;
>>> -}
>>> -
>>>   /* Interpreter command to boot an arbitrary ELF image from memory */
>>>   int do_bootelf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>>>   {
>>> diff --git a/include/elf.h b/include/elf.h
>>> index 81f40191d7..e7c51986df 100644
>>> --- a/include/elf.h
>>> +++ b/include/elf.h
>>> @@ -692,6 +692,10 @@ unsigned long elf_hash(const unsigned char *name);
>>>
>>>   #ifndef __ASSEMBLER__
>>>   int valid_elf_image(unsigned long addr);
>>> +unsigned long load_elf64_image_phdr(unsigned long addr);
>>> +unsigned long load_elf64_image_shdr(unsigned long addr);
>>> +unsigned long load_elf_image_phdr(unsigned long addr);
>>> +unsigned long load_elf_image_shdr(unsigned long addr);
>>>   #endif
>>>
>>>   #endif /* _ELF_H */
>>> diff --git a/lib/Kconfig b/lib/Kconfig
>>> index d040a87d26..b155ced4b2 100644
>>> --- a/lib/Kconfig
>>> +++ b/lib/Kconfig
>>> @@ -601,4 +601,7 @@ config TEST_FDTDEC
>>>   config LIB_DATE
>>>        bool
>>>
>>> +config ELF
>>> +     bool "enable basic elf loading/validating functions"
>>> +
>>>   endmenu
>>> diff --git a/lib/Makefile b/lib/Makefile
>>> index 6b7b9ce85c..93f22d210e 100644
>>> --- a/lib/Makefile
>>> +++ b/lib/Makefile
>>> @@ -121,6 +121,7 @@ obj-y += vsprintf.o strto.o
>>>   endif
>>>
>>>   obj-y += date.o
>>> +obj-$(CONFIG_ELF) += elf.o
>>>
>>>   #
>>>   # Build a fast OID lookup registry from include/linux/oid_registry.h
>>> diff --git a/lib/elf.c b/lib/elf.c
>>> new file mode 100644
>>> index 0000000000..54ac4ee502
>>> --- /dev/null
>>> +++ b/lib/elf.c
>>> @@ -0,0 +1,256 @@
>>> +/*
>>> + * Copyright (c) 2001 William L. Pitts
>>> + * All rights reserved.
>>> + *
>>> + * Redistribution and use in source and binary forms are freely
>>> + * permitted provided that the above copyright notice and this
>>> + * paragraph and the following disclaimer are duplicated in all
>>> + * such forms.
>>> + *
>>> + * This software is provided "AS IS" and without any express or
>>> + * implied warranties, including, without limitation, the implied
>>> + * warranties of merchantability and fitness for a particular
>>> + * purpose.
>>> + */
>>> +
>>> +#include <common.h>
>>> +#include <command.h>
>>> +#include <cpu_func.h>
>>> +#include <elf.h>
>>> +#include <env.h>
>>> +#include <net.h>
>>> +#include <vxworks.h>
>>> +#ifdef CONFIG_X86
>>> +#include <vbe.h>
>>> +#include <asm/e820.h>
>>> +#include <linux/linkage.h>
>>> +#endif
>>> +
>>> +/*
>>> + * A very simple ELF64 loader, assumes the image is valid, returns the
>>> + * entry point address.
>>> + *
>>> + * Note if U-Boot is 32-bit, the loader assumes the to segment's
>>> + * physical address and size is within the lower 32-bit address space.
>>> + */
>>> +unsigned long load_elf64_image_phdr(unsigned long addr)
>>> +{
>>> +     Elf64_Ehdr *ehdr; /* Elf header structure pointer */
>>> +     Elf64_Phdr *phdr; /* Program header structure pointer */
>>> +     int i;
>>> +
>>> +     ehdr = (Elf64_Ehdr *)addr;
>>> +     phdr = (Elf64_Phdr *)(addr + (ulong)ehdr->e_phoff);
>>> +
>>> +     /* Load each program header */
>>> +     for (i = 0; i < ehdr->e_phnum; ++i) {
>>> +             void *dst = (void *)(ulong)phdr->p_paddr;
>>> +             void *src = (void *)addr + phdr->p_offset;
>>> +
>>> +             debug("Loading phdr %i to 0x%p (%lu bytes)\n",
>>> +                   i, dst, (ulong)phdr->p_filesz);
>>> +             if (phdr->p_filesz)
>>> +                     memcpy(dst, src, phdr->p_filesz);
>>> +             if (phdr->p_filesz != phdr->p_memsz)
>>> +                     memset(dst + phdr->p_filesz, 0x00,
>>> +                            phdr->p_memsz - phdr->p_filesz);
>>> +             flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
>>> +                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
>>> +             ++phdr;
>>> +     }
>>> +
>>> +     if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
>>> +                                         EF_PPC64_ELFV1_ABI)) {
>>> +             /*
>>> +              * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
>>> +              * descriptor pointer with the first double word being the
>>> +              * address of the entry point of the function.
>>> +              */
>>> +             uintptr_t addr = ehdr->e_entry;
>>> +
>>> +             return *(Elf64_Addr *)addr;
>>> +     }
>>> +
>>> +     return ehdr->e_entry;
>>> +}
>>> +
>>> +unsigned long load_elf64_image_shdr(unsigned long addr)
>>> +{
>>> +     Elf64_Ehdr *ehdr; /* Elf header structure pointer */
>>> +     Elf64_Shdr *shdr; /* Section header structure pointer */
>>> +     unsigned char *strtab = 0; /* String table pointer */
>>> +     unsigned char *image; /* Binary image pointer */
>>> +     int i; /* Loop counter */
>>> +
>>> +     ehdr = (Elf64_Ehdr *)addr;
>>> +
>>> +     /* Find the section header string table for output info */
>>> +     shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
>>> +                          (ehdr->e_shstrndx * sizeof(Elf64_Shdr)));
>>> +
>>> +     if (shdr->sh_type == SHT_STRTAB)
>>> +             strtab = (unsigned char *)(addr + (ulong)shdr->sh_offset);
>>> +
>>> +     /* Load each appropriate section */
>>> +     for (i = 0; i < ehdr->e_shnum; ++i) {
>>> +             shdr = (Elf64_Shdr *)(addr + (ulong)ehdr->e_shoff +
>>> +                                  (i * sizeof(Elf64_Shdr)));
>>> +
>>> +             if (!(shdr->sh_flags & SHF_ALLOC) ||
>>> +                 shdr->sh_addr == 0 || shdr->sh_size == 0) {
>>> +                     continue;
>>> +             }
>>> +
>>> +             if (strtab) {
>>> +                     debug("%sing %s @ 0x%08lx (%ld bytes)\n",
>>> +                           (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
>>> +                            &strtab[shdr->sh_name],
>>> +                            (unsigned long)shdr->sh_addr,
>>> +                            (long)shdr->sh_size);
>>> +             }
>>> +
>>> +             if (shdr->sh_type == SHT_NOBITS) {
>>> +                     memset((void *)(uintptr_t)shdr->sh_addr, 0,
>>> +                            shdr->sh_size);
>>> +             } else {
>>> +                     image = (unsigned char *)addr + (ulong)shdr->sh_offset;
>>> +                     memcpy((void *)(uintptr_t)shdr->sh_addr,
>>> +                            (const void *)image, shdr->sh_size);
>>> +             }
>>> +             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
>>> +                         roundup((shdr->sh_addr + shdr->sh_size),
>>> +                                  ARCH_DMA_MINALIGN) -
>>> +                                 rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
>>> +     }
>>> +
>>> +     if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
>>> +                                         EF_PPC64_ELFV1_ABI)) {
>>> +             /*
>>> +              * For the 64-bit PowerPC ELF V1 ABI, e_entry is a function
>>> +              * descriptor pointer with the first double word being the
>>> +              * address of the entry point of the function.
>>> +              */
>>> +             uintptr_t addr = ehdr->e_entry;
>>> +
>>> +             return *(Elf64_Addr *)addr;
>>> +     }
>>> +
>>> +     return ehdr->e_entry;
>>> +}
>>> +
>>> +/*
>>> + * A very simple ELF loader, assumes the image is valid, returns the
>>> + * entry point address.
>>> + *
>>> + * The loader firstly reads the EFI class to see if it's a 64-bit image.
>>> + * If yes, call the ELF64 loader. Otherwise continue with the ELF32 loader.
>>> + */
>>> +unsigned long load_elf_image_phdr(unsigned long addr)
>>> +{
>>> +     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
>>> +     Elf32_Phdr *phdr; /* Program header structure pointer */
>>> +     int i;
>>> +
>>> +     ehdr = (Elf32_Ehdr *)addr;
>>> +     if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
>>> +             return load_elf64_image_phdr(addr);
>>> +
>>> +     phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff);
>>> +
>>> +     /* Load each program header */
>>> +     for (i = 0; i < ehdr->e_phnum; ++i) {
>>> +             void *dst = (void *)(uintptr_t)phdr->p_paddr;
>>> +             void *src = (void *)addr + phdr->p_offset;
>>> +
>>> +             debug("Loading phdr %i to 0x%p (%i bytes)\n",
>>> +                   i, dst, phdr->p_filesz);
>>> +             if (phdr->p_filesz)
>>> +                     memcpy(dst, src, phdr->p_filesz);
>>> +             if (phdr->p_filesz != phdr->p_memsz)
>>> +                     memset(dst + phdr->p_filesz, 0x00,
>>> +                            phdr->p_memsz - phdr->p_filesz);
>>> +             flush_cache(rounddown((unsigned long)dst, ARCH_DMA_MINALIGN),
>>> +                         roundup(phdr->p_memsz, ARCH_DMA_MINALIGN));
>>> +             ++phdr;
>>> +     }
>>> +
>>> +     return ehdr->e_entry;
>>> +}
>>> +
>>> +unsigned long load_elf_image_shdr(unsigned long addr)
>>> +{
>>> +     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
>>> +     Elf32_Shdr *shdr; /* Section header structure pointer */
>>> +     unsigned char *strtab = 0; /* String table pointer */
>>> +     unsigned char *image; /* Binary image pointer */
>>> +     int i; /* Loop counter */
>>> +
>>> +     ehdr = (Elf32_Ehdr *)addr;
>>> +     if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
>>> +             return load_elf64_image_shdr(addr);
>>> +
>>> +     /* Find the section header string table for output info */
>>> +     shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
>>> +                          (ehdr->e_shstrndx * sizeof(Elf32_Shdr)));
>>> +
>>> +     if (shdr->sh_type == SHT_STRTAB)
>>> +             strtab = (unsigned char *)(addr + shdr->sh_offset);
>>> +
>>> +     /* Load each appropriate section */
>>> +     for (i = 0; i < ehdr->e_shnum; ++i) {
>>> +             shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff +
>>> +                                  (i * sizeof(Elf32_Shdr)));
>>> +
>>> +             if (!(shdr->sh_flags & SHF_ALLOC) ||
>>> +                 shdr->sh_addr == 0 || shdr->sh_size == 0) {
>>> +                     continue;
>>> +             }
>>> +
>>> +             if (strtab) {
>>> +                     debug("%sing %s @ 0x%08lx (%ld bytes)\n",
>>> +                           (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load",
>>> +                            &strtab[shdr->sh_name],
>>> +                            (unsigned long)shdr->sh_addr,
>>> +                            (long)shdr->sh_size);
>>> +             }
>>> +
>>> +             if (shdr->sh_type == SHT_NOBITS) {
>>> +                     memset((void *)(uintptr_t)shdr->sh_addr, 0,
>>> +                            shdr->sh_size);
>>> +             } else {
>>> +                     image = (unsigned char *)addr + shdr->sh_offset;
>>> +                     memcpy((void *)(uintptr_t)shdr->sh_addr,
>>> +                            (const void *)image, shdr->sh_size);
>>> +             }
>>> +             flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
>>> +                         roundup((shdr->sh_addr + shdr->sh_size),
>>> +                                 ARCH_DMA_MINALIGN) -
>>> +                         rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
>>> +     }
>>> +
>>> +     return ehdr->e_entry;
>>> +}
>>> +
>>> +/*
>>> + * Determine if a valid ELF image exists at the given memory location.
>>> + * First look at the ELF header magic field, then make sure that it is
>>> + * executable.
>>> + */
>>> +int valid_elf_image(unsigned long addr)
>>> +{
>>> +     Elf32_Ehdr *ehdr; /* Elf header structure pointer */
>>> +
>>> +     ehdr = (Elf32_Ehdr *)addr;
>>> +
>>> +     if (!IS_ELF(*ehdr)) {
>>> +             printf("## No elf image at address 0x%08lx\n", addr);
>>> +             return 0;
>>> +     }
>>> +
>>> +     if (ehdr->e_type != ET_EXEC) {
>>> +             printf("## Not a 32-bit elf image at address 0x%08lx\n", addr);
>>> +             return 0;
>>> +     }
>>> +
>>> +     return 1;
>>> +}
>>>

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2020-01-17  8:06 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-13  5:54 [PATCH v2 0/9]k3: Add support for loading main_r5fss0_core0 Keerthy
2020-01-13  5:54 ` [PATCH v2 1/9] lib: elf: Move the generic elf loading/validating functions to lib Keerthy
2020-01-17  4:27   ` Lokesh Vutla
2020-01-17  7:49     ` Simon Goldschmidt
2020-01-17  8:06       ` Keerthy
2020-01-13  5:54 ` [PATCH v2 2/9] arm: k3: Add support for loading non linux remote cores Keerthy
2020-01-13  5:54 ` [PATCH v2 3/9] armv7R: K3: r5_mpu: Enable execute permission for MCU0 BTCM Keerthy
2020-01-13  5:54 ` [PATCH v2 4/9] armv7R: K3: Add support for jumping to firmware Keerthy
2020-01-13  5:54 ` [PATCH v2 5/9] arm: dts: k3-j721e-r5: Add fs_loader node Keerthy
2020-01-13  5:54 ` [PATCH v2 6/9] arm: dts: k3-j721e-r5: Enable r5fss0 cluster in SPL Keerthy
2020-01-13  5:54 ` [PATCH v2 7/9] include: configs: j721e_evm: Add env variables for mcu_r5fss0_core0 & main_r5fss0_core0 Keerthy
2020-01-13  5:54 ` [PATCH v2 8/9] configs: j721e_evm_r5: Add configs for environment in eMMC Keerthy
2020-01-17  5:14   ` Lokesh Vutla
2020-01-13  5:54 ` [PATCH v2 9/9] configs: j721e_evm_r5: Enable R5F remoteproc support Keerthy

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.