Hi Peng, On Tue, Nov 12, 2019 at 9:47 AM Peng Fan <peng....@nxp.com> wrote: > > Hi Igor. > > > Subject: [PATCH v1] imx: bootaux: elf firmware support > > We also have similar support for i.MX8 DSP firmware loading. Good to see > your patch. > > > > > From: Igor Opaniuk <igor.opan...@toradex.com> > > > > Currently imx-specific bootaux command doesn't support ELF format > > firmware for Cortex-M4 core. > > > > This patches introduces a PoC implementation of handling elf firmware > > (load_elf_image_phdr() was copy-pasted from elf.c just for PoC). > > > > This has the advantage that the user does not need to know to which address > > the binary has been linked to. However, in order to handle and load the elf > > sections to the right address, we need to translate the > > Cortex-M4 core memory addresses to primary/host CPU memory addresses > > (Cortex A7/A9 cores). > > Could an runtime check be added for those aux cores which has > same mapping as host cores?
Could you please provide a list of SoCs where it's actual? > > Thanks, > Peng > > > > This allows to boot firmwares from any location with just using bootaux, > > e.g.: > > > tftp ${loadaddr} hello_world.elf && bootaux ${loadaddr} > > > > Similar translation table can be found in the Linux remoteproc driver [1]. > > > > [1] > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Felixir.b > > ootlin.com%2Flinux%2Flatest%2Fsource%2Fdrivers%2Fremoteproc%2Fimx_r > > proc.c&data=02%7C01%7Cpeng.fan%40nxp.com%7Cb511f03c8e4e4265 > > 154908d766b277aa%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7 > > C637090789004070829&sdata=tJoptyJCnuKIersJt9KmhR8nNYEdnl4SxM > > VKLvA7KNc%3D&reserved=0 > > > > Signed-off-by: Igor Opaniuk <igor.opan...@toradex.com> > > Signed-off-by: Stefan Agner <stefan.ag...@toradex.com> > > --- > > > > arch/arm/include/asm/mach-imx/sys_proto.h | 7 ++ > > arch/arm/mach-imx/imx_bootaux.c | 87 > > +++++++++++++++++++++-- > > arch/arm/mach-imx/mx7/soc.c | 28 ++++++++ > > 3 files changed, 118 insertions(+), 4 deletions(-) > > > > diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h > > b/arch/arm/include/asm/mach-imx/sys_proto.h > > index 52c83ba9e4..4428a7fa0b 100644 > > --- a/arch/arm/include/asm/mach-imx/sys_proto.h > > +++ b/arch/arm/include/asm/mach-imx/sys_proto.h > > @@ -139,6 +139,13 @@ enum boot_dev_type_e { extern struct rom_api > > *g_rom_api; #endif > > > > +/* address translation table */ > > +struct rproc_att { > > + u32 da; /* device address (From Cortex M4 view) */ > > + u32 sa; /* system bus address */ > > + u32 size; /* size of reg range */ > > +}; > > + > > u32 get_nr_cpus(void); > > u32 get_cpu_rev(void); > > u32 get_cpu_speed_grade_hz(void); > > diff --git a/arch/arm/mach-imx/imx_bootaux.c > > b/arch/arm/mach-imx/imx_bootaux.c index 3d9422d5a2..7f4bbfe885 > > 100644 > > --- a/arch/arm/mach-imx/imx_bootaux.c > > +++ b/arch/arm/mach-imx/imx_bootaux.c > > @@ -7,18 +7,94 @@ > > #include <asm/io.h> > > #include <asm/mach-imx/sys_proto.h> > > #include <command.h> > > +#include <elf.h> > > #include <imx_sip.h> > > #include <linux/compiler.h> > > > > -int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) > > +const __weak struct rproc_att hostmap[] = { }; > > + > > +static const struct rproc_att *get_host_mapping(unsigned long auxcore) > > +{ > > + const struct rproc_att *mmap = hostmap; > > + > > + while (mmap && mmap->size) { > > + if (mmap->da <= auxcore && > > + mmap->da + mmap->size > auxcore) > > + return mmap; > > + mmap++; > > + } > > + > > + return NULL; > > +} > > + > > +/* > > + * A very simple elf loader, assumes the image is valid, returns the > > + * entry point address. > > + */ > > +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; > > + phdr = (Elf32_Phdr *)(addr + ehdr->e_phoff); > > + > > + /* Load each program header */ > > + for (i = 0; i < ehdr->e_phnum; ++i, ++phdr) { > > + const struct rproc_att *mmap = > > get_host_mapping(phdr->p_paddr); > > + void *dst, *src; > > + > > + if (phdr->p_type != PT_LOAD) > > + continue; > > + > > + if (!mmap) { > > + printf("Invalid aux core address: %08x", > > + phdr->p_paddr); > > + return 0; > > + } > > + > > + dst = (void *)(phdr->p_paddr - mmap->da) + mmap->sa; > > + 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((unsigned long)dst & > > + ~(CONFIG_SYS_CACHELINE_SIZE - 1), > > + ALIGN(phdr->p_filesz, CONFIG_SYS_CACHELINE_SIZE)); > > + } > > + > > + return ehdr->e_entry; > > +} > > + > > +int arch_auxiliary_core_up(u32 core_id, ulong addr) > > { > > ulong stack, pc; > > > > - if (!boot_private_data) > > + if (!addr) > > return -EINVAL; > > > > - stack = *(u32 *)boot_private_data; > > - pc = *(u32 *)(boot_private_data + 4); > > + if (valid_elf_image(addr)) { > > + stack = 0x0; > > + pc = load_elf_image_phdr(addr); > > + if (!pc) > > + return CMD_RET_FAILURE; > > + > > + } else { > > + /* > > + * Assume binary file with vector table at the beginning. > > + * Cortex-M4 vector tables start with the stack pointer (SP) > > + * and reset vector (initial PC). > > + */ > > + stack = *(u32 *)addr; > > + pc = *(u32 *)(addr + 4); > > + } > > > > /* Set the stack and pc to M4 bootROM */ > > writel(stack, M4_BOOTROM_BASE_ADDR); > > @@ -80,6 +156,9 @@ static int do_bootaux(cmd_tbl_t *cmdtp, int flag, int > > argc, char * const argv[]) > > > > addr = simple_strtoul(argv[1], NULL, 16); > > > > + if (!addr) > > + return CMD_RET_FAILURE; > > + > > printf("## Starting auxiliary core at 0x%08lX ...\n", addr); > > > > ret = arch_auxiliary_core_up(0, addr); diff --git > > a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c index > > 35160f4b37..4aafeed188 100644 > > --- a/arch/arm/mach-imx/mx7/soc.c > > +++ b/arch/arm/mach-imx/mx7/soc.c > > @@ -193,6 +193,34 @@ static void init_cpu_basic(void) #endif } > > > > +#ifdef CONFIG_IMX_BOOTAUX > > +/* > > + * Table of mappings of physical mem regions in both > > + * Cortex-A7 and Cortex-M4 address spaces. > > + * > > + * For additional details check sections 2.1.2 and 2.1.3 in > > + * i.MX7Dual Applications Processor Reference Manual > > + * > > + */ > > +const struct rproc_att hostmap[] = { > > + /* aux core , host core, size */ > > + { 0x00000000, 0x00180000, 0x8000 }, /* OCRAM_S */ > > + { 0x00180000, 0x00180000, 0x8000 }, /* OCRAM_S */ > > + { 0x20180000, 0x00180000, 0x8000 }, /* OCRAM_S */ > > + { 0x1fff8000, 0x007f8000, 0x8000 }, /* TCML */ > > + { 0x20000000, 0x00800000, 0x8000 }, /* TCMU */ > > + { 0x00900000, 0x00900000, 0x20000 }, /* OCRAM_128KB */ > > + { 0x20200000, 0x00900000, 0x20000 }, /* OCRAM_128KB */ > > + { 0x00920000, 0x00920000, 0x20000 }, /* OCRAM_EPDC */ > > + { 0x20220000, 0x00920000, 0x20000 }, /* OCRAM_EPDC */ > > + { 0x00940000, 0x00940000, 0x20000 }, /* OCRAM_PXP */ > > + { 0x20240000, 0x00940000, 0x20000 }, /* OCRAM_PXP */ > > + { 0x10000000, 0x80000000, 0x0fff0000 }, /* DDR Code alias */ > > + { 0x80000000, 0x80000000, 0xe0000000 }, /* DDRC */ > > + { /* sentinel */ } > > +}; > > +#endif > > + > > #ifndef CONFIG_SKIP_LOWLEVEL_INIT > > /* enable all periherial can be accessed in nosec mode */ static void > > init_csu(void) > > -- > > 2.17.1 > -- Best regards - Freundliche GrĂ¼sse - Meilleures salutations Igor Opaniuk mailto: igor.opan...@gmail.com skype: igor.opanyuk +380 (93) 836 40 67 http://ua.linkedin.com/in/iopaniuk _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot