target-xtensa: fix loading uImage kernels on MMUv2 cores
v2 cover target-xtensa: fix loading uImage kernels on MMUv2 cores
Hi,
this series fixes loading uImage kernels on MMUv2 xtensa cores.
U-boot for xtensa always treats uImage load address as virtual address. This is important when booting uImage on xtensa core with MMUv2, because MMUv2 has fixed non-identity virtual-to-physical mapping after reset.
Changes v1->v2:
- drop custom uImage loader interface and add generic translation function instead (suggested by Alexander Graf).
Max Filippov (2):
hw/core/loader: implement address translation in uimage loader hw/xtensa/xtfpga: treat uImage load address as virtual
hw/arm/boot.c | 2 +- hw/core/loader.c | 17 +++++++++++++---- hw/m68k/an5206.c | 3 ++- hw/m68k/dummy_m68k.c | 3 ++- hw/m68k/mcf5208.c | 3 ++- hw/microblaze/boot.c | 3 ++- hw/openrisc/openrisc_sim.c | 2 +- hw/ppc/e500.c | 3 ++- hw/ppc/ppc440_bamboo.c | 3 ++- hw/xtensa/xtfpga.c | 3 ++- include/hw/loader.h | 4 +++- 11 files changed, 32 insertions(+), 14 deletions(-)
Signature · 1 line
1.8.1.4
PATCH v2 2/2 hw/xtensa/xtfpga: treat uImage load address as virtual
U-boot for xtensa always treats uImage load address as virtual address. This is important when booting uImage on xtensa core with MMUv2, because MMUv2 has fixed non-identity virtual-to-physical mapping after reset.
Always do virtual-to-physical translation of uImage load address and load uImage at the translated address. This fixes booting uImage kernels on dc232b and other MMUv2 cores.
---
Changes v1->v2:
- use translate_phys_addr with the new load_uimage interface.
hw/xtensa/xtfpga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
hw/xtensa/xtfpga.c +1 -1
@@ -328,7 +328,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)hwaddr ep;int is_linux; success =load_uimage (kernel_filename, &ep,NULL , &is_linux, -NULL ,NULL ); + translate_phys_addr, cpu);if (success >0 && is_linux) { entry_point = ep; }else {
Signature · 1 line
1.8.1.4
Quoted 5 lines
Am 19.10.2014 um 07:03 schrieb Max Filippov <[email protected]>:
Quoted 7 lines
Hi,
this series fixes loading uImage kernels on MMUv2 xtensa cores.
U-boot for xtensa always treats uImage load address as virtual address. This is important when booting uImage on xtensa core with MMUv2, because MMUv2 has fixed non-identity virtual-to-physical mapping after reset.
Alex
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [Qemu-devel] [PATCH v2 1/2] hw/core/loader: implement address translation in uimage loader
Hi,
Quoted 10 lines · Max Filippov
Such address translation is needed when load address recorded in uImage is a virtual address. When the actual load address is requested, return untranslated address: user that needs the translated address can always apply translation function to it and those that need it untranslated don't need to do the inverse translation.
Add translation function pointer and its parameter to
uimage_loadprototype. Update all existing users.No user-visible functional changes.
Alexander: thanks for the review.
Peter M., Edgar, Jia, Scott, Peter C., Paolo, I wouldn't mind your reviewed/acked-bys or complaints.
Quoted 210 lines
Signed-off-by Max Filippov <[email protected]>---
Changesv1->v2:
- drop custom uImage loader interface and add generic translation function instead (suggested by Alexander Graf).hw/arm/boot.c | 2 +- hw/core/loader.c | 17 +++++++++++++---- hw/m68k/an5206.c | 3 ++- hw/m68k/dummy_m68k.c | 3 ++- hw/m68k/mcf5208.c | 3 ++- hw/microblaze/boot.c | 3 ++- hw/openrisc/openrisc_sim.c | 2 +- hw/ppc/e500.c | 3 ++- hw/ppc/ppc440_bamboo.c | 3 ++- hw/xtensa/xtfpga.c | 3 ++- include/hw/loader.h | 4 +++- 11 files changed, 32 insertions(+), 14 deletions(-)hw/arm/boot.c +1
-1@@ -571,7 +571,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) entry = elf_entry;if (kernel_size <0 ) { kernel_size =load_uimage (info->kernel_filename, &entry,NULL , - &is_linux); + &is_linux,NULL ,NULL ); }/* On aarch64, it's the bootloader's job to uncompress the kernel. */ if (arm_feature (&cpu->env,ARM_FEATURE_AARCH64 ) && kernel_size <0 ) {hw/core/loader.c +13
-4@@ -477,7 +477,9 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,/* Load a U-Boot image. */ static int load_uboot_image (const char *filename,hwaddr *ep,hwaddr *loadaddr, -int *is_linux,uint8_t image_type) +int *is_linux,uint8_t image_type, +uint64_t (*translate_fn)(void *,uint64_t ), +void *translate_opaque) {int fd;int size;@@ -511,6 +513,9 @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,switch (hdr->ih_type) {case IH_TYPE_KERNEL : address = hdr->ih_load; +if (translate_fn) { + address =translate_fn (translate_opaque, address); + }if (loadaddr) { *loadaddr = hdr->ih_load; }@@ -587,15 +592,19 @@ out: }int load_uimage (const char *filename,hwaddr *ep,hwaddr *loadaddr, -int *is_linux) +int *is_linux, +uint64_t (*translate_fn)(void *,uint64_t ), +void *translate_opaque) { -return load_uboot_image (filename, ep, loadaddr, is_linux,IH_TYPE_KERNEL ); +return load_uboot_image (filename, ep, loadaddr, is_linux,IH_TYPE_KERNEL , + translate_fn, translate_opaque); }/* Load a ramdisk. */ int load_ramdisk (const char *filename,hwaddr addr,uint64_t max_sz) { -return load_uboot_image (filename,NULL , &addr,NULL ,IH_TYPE_RAMDISK ); +return load_uboot_image (filename,NULL , &addr,NULL ,IH_TYPE_RAMDISK , +NULL ,NULL ); }/* This simply prevents g_malloc in the function below from allocating hw/m68k/an5206.c +2
-1@@ -74,7 +74,8 @@ static void an5206_init(MachineState *machine) NULL, NULL, 1, ELF_MACHINE, 0); entry = elf_entry;if (kernel_size <0 ) { - kernel_size =load_uimage (kernel_filename, &entry,NULL ,NULL ); + kernel_size =load_uimage (kernel_filename, &entry,NULL ,NULL , +NULL ,NULL ); }if (kernel_size <0 ) { kernel_size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR,hw/m68k/dummy_m68k.c +2
-1@@ -50,7 +50,8 @@ static void dummy_m68k_init(MachineState *machine) NULL, NULL, 1, ELF_MACHINE, 0); entry = elf_entry;if (kernel_size <0 ) { - kernel_size =load_uimage (kernel_filename, &entry,NULL ,NULL ); + kernel_size =load_uimage (kernel_filename, &entry,NULL ,NULL , +NULL ,NULL ); }if (kernel_size <0 ) { kernel_size = load_image_targphys(kernel_filename,hw/m68k/mcf5208.c +2
-1@@ -279,7 +279,8 @@ static void mcf5208evb_init(MachineState *machine) NULL, NULL, 1, ELF_MACHINE, 0); entry = elf_entry;if (kernel_size <0 ) { - kernel_size =load_uimage (kernel_filename, &entry,NULL ,NULL ); + kernel_size =load_uimage (kernel_filename, &entry,NULL ,NULL , +NULL ,NULL ); }if (kernel_size <0 ) { kernel_size = load_image_targphys(kernel_filename, 0x40000000,hw/microblaze/boot.c +2
-1@@ -154,7 +154,8 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,if (kernel_size <0 ) {hwaddr uentry, loadaddr; - kernel_size =load_uimage (kernel_filename, &uentry, &loadaddr,0 ); + kernel_size =load_uimage (kernel_filename, &uentry, &loadaddr,0 , +NULL ,NULL ); boot_info.bootstrap_pc = uentry; high = (loadaddr + kernel_size +3 ) & ~3 ; }hw/openrisc/openrisc_sim.c +1
-1@@ -72,7 +72,7 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size, entry = elf_entry;if (kernel_size <0 ) { kernel_size =load_uimage (kernel_filename, - &entry,NULL ,NULL ); + &entry,NULL ,NULL ,NULL ,NULL ); }if (kernel_size <0 ) { kernel_size = load_image_targphys(kernel_filename,hw/ppc/e500.c +2
-1@@ -830,7 +830,8 @@ void ppce500_init(MachineState *machine, PPCE500Params *params)* Hrm. No ELF image? Try a uImage, maybe someone is giving us an * ePAPR compliant kernel */ - kernel_size =load_uimage (filename, &bios_entry, &loadaddr,NULL ); + kernel_size =load_uimage (filename, &bios_entry, &loadaddr,NULL , +NULL ,NULL );if (kernel_size <0 ) {fprintf (stderr,"qemu: could not load firmware '%s'\n" , filename);exit (1 );hw/ppc/ppc440_bamboo.c +2
-1@@ -253,7 +253,8 @@ static void bamboo_init(MachineState *machine)/* Load kernel. */ if (kernel_filename) { - success =load_uimage (kernel_filename, &entry, &loadaddr,NULL ); + success =load_uimage (kernel_filename, &entry, &loadaddr,NULL , +NULL ,NULL );if (success <0 ) { success =load_elf (kernel_filename,NULL ,NULL , &elf_entry, &elf_lowaddr,NULL ,1 ,ELF_MACHINE ,0 );hw/xtensa/xtfpga.c +2
-1@@ -327,7 +327,8 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine) }else {hwaddr ep;int is_linux; - success =load_uimage (kernel_filename, &ep,NULL , &is_linux); + success =load_uimage (kernel_filename, &ep,NULL , &is_linux, +NULL ,NULL );if (success >0 && is_linux) { entry_point = ep; }else {include/hw/loader.h +3
-2@@ -30,7 +30,9 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),int load_aout (const char *filename,hwaddr addr,int max_sz,int bswap_needed,hwaddr target_page_size);int load_uimage (const char *filename,hwaddr *ep, -hwaddr *loadaddr,int *is_linux); +hwaddr *loadaddr,int *is_linux, +uint64_t (*translate_fn)(void *,uint64_t ), +void *translate_opaque);/** * load_ramdisk: -- 1.8.1.4
Signature · 2 lines
Thanks. -- Max