]> xenbits.xensource.com Git - qemu-upstream-4.6-testing.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)
committerMax Filippov <jcmvbkbc@gmail.com>
Sun, 2 Nov 2014 21:59:10 +0000 (00:59 +0300)
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>
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 bffbea5e0e73dde70187b73f0eddf9889263bd59..0014c34ddd1eb3b31e621c2d4e1f9c7494fd524a 100644 (file)
@@ -580,7 +580,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) {
index 5f3a8598c5bfd154210983df04703cca0af04f43..bbe6eb3d8250eb926c2f3402b452dc32be7b4888 100644 (file)
@@ -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
index a9ac27089b25ad91dd5173fece4f974b6e2d71c2..f1f13504c0660c98bdd63fd72f7f77728c3d351a 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 957ef82f887fb3e6a837f209d1f09884c09f4442..facd561efa128fa8672bdf8366318462a14c56d6 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 188230f9013612c6563c6a470e9c17806d8290e3..a01a4458e67ece2aeaee3a3112f931f1e3d33713 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 c110033c2eed9bc157e4fb5edc8375285885ca8a..1da0657ddf299ce5bbfc377c10e6d20bb85df171 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 16c85efab511ba4f4da44450af79b21e887efab5..2157d87c19651de833e0a83c5aea9161be67728b 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 0100c3115ba3f48f23608b4aa51fd1be4ee2b51f..a9b33bc4ee6dc2d9d3ea85b7649944b0f60a7bb4 100644 (file)
@@ -328,7 +328,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 9190387b8e5cd32604adba271ba3ec91824d701e..054c6a22b5785fe109e4ccedf4666c35390ae2da 100644 (file)
@@ -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: