]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
hw/core/loader: implement address translation in uimage loader
authorMax Filippov <jcmvbkbc@gmail.com>
Sun, 19 Oct 2014 03:42:22 +0000 (07:42 +0400)
committerMichael Roth <mdroth@linux.vnet.ibm.com>
Wed, 7 Jan 2015 00:39:10 +0000 (18:39 -0600)
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_load
prototype. Update all existing users.

No user-visible functional changes.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
(cherry picked from commit 25bda50a0c7241dcb247483af2b7f961632020cc)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
hw/arm/boot.c
hw/core/loader.c
hw/m68k/an5206.c
hw/m68k/dummy_m68k.c
hw/m68k/mcf5208.c
hw/microblaze/boot.c
hw/openrisc/openrisc_sim.c
hw/ppc/e500.c
hw/ppc/ppc440_bamboo.c
hw/xtensa/xtfpga.c
include/hw/loader.h

index 3d1f4a255b485eb52864e3fefb16c5da9cef37e1..50b6c5c0eea6d7321908cf28d645dbbc14fedb66 100644 (file)
@@ -508,7 +508,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);
     }
     if (kernel_size < 0) {
         entry = info->loader_start + kernel_load_offset;
index 2bf6b8ff856022b2017cc75d79329b864faa21a0..8b84c12dd182a00b80e1891fd9168bfa610e7193 100644 (file)
@@ -456,7 +456,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;
@@ -490,6 +492,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;
         }
@@ -566,15 +571,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);
 }
 
 /*
index 684496a946b5cf352d9735760bb55d0940e349ed..388420edb7e168d35ccc0fba9f8ea13a9aed5627 100644 (file)
@@ -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,
index 6db1b7164e970936a179beb81890ca5627523221..fb9ca0ed3a599e37894c4f90ba4290612eeef650 100644 (file)
@@ -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,
index 2ef617f2b7dd18afc896db40e191f325db74f5d2..07683dbf218af1c201a6da2ae20643ef1b2a0c5e 100644 (file)
@@ -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,
index 6bf36d046fdc313d92ac936766adec2d7048fcbc..a2843cdf993d5a356adc3fcc83b2a0fb169c81ff 100644 (file)
@@ -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;
         }
index b2b4f9b8601a9d8ab11ed023fa1149175089d4ac..123cf4d5e71db7e0ebe47304fa1e0097427c22c6 100644 (file)
@@ -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,
index 1a5b30d3cec4848f7a706c378526003bf2cf11cc..c268b9125277a4ac5106753d80d66e999ee5af18 100644 (file)
@@ -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);
index 81a06d310dfa736bf16e285216ad58493867310f..778970aa9bedff5b2a6ed1e503a4c159082fc0bb 100644 (file)
@@ -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);
index a2dff5a13e047976589ed722f1026bb765bdc963..937d01edfd204d568376a1c70092e2cd8b3328f7 100644 (file)
@@ -325,7 +325,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 {
index 796cbf9b39b33366ec8c134ab9e9089ed41c443e..11b6b5ac7ce9b3cc07ac5b3bef64f5ca31aab19a 100644 (file)
@@ -28,7 +28,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: