[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 53/88] hw/core/loader: implement address translatio
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 53/88] hw/core/loader: implement address translation in uimage loader |
Date: |
Thu, 8 Jan 2015 11:33:57 -0600 |
From: Max Filippov <address@hidden>
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: address@hidden
Signed-off-by: Max Filippov <address@hidden>
Reviewed-by: Alexander Graf <address@hidden>
(cherry picked from commit 25bda50a0c7241dcb247483af2b7f961632020cc)
Signed-off-by: Michael Roth <address@hidden>
---
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(-)
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 3d1f4a2..50b6c5c 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -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;
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 2bf6b8f..8b84c12 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -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);
}
/*
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index 684496a..388420e 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -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,
diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
index 6db1b71..fb9ca0e 100644
--- a/hw/m68k/dummy_m68k.c
+++ b/hw/m68k/dummy_m68k.c
@@ -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,
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 2ef617f..07683db 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -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,
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 6bf36d0..a2843cd 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -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;
}
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index b2b4f9b..123cf4d 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -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,
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 1a5b30d..c268b91 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -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);
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 81a06d3..778970a 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -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);
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index a2dff5a..937d01e 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -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 {
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 796cbf9..11b6b5a 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -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:
--
1.9.1
- [Qemu-stable] [PATCH 44/88] vmware-vga: use vmsvga_verify_rect in vmsvga_update_rect, (continued)
- [Qemu-stable] [PATCH 44/88] vmware-vga: use vmsvga_verify_rect in vmsvga_update_rect, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 48/88] libcacard: don't free sign buffer while sign op is pending, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 45/88] vmware-vga: use vmsvga_verify_rect in vmsvga_copy_rect, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 47/88] qcow2: Do not overflow when writing an L1 sector, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 46/88] vmware-vga: use vmsvga_verify_rect in vmsvga_fill_rect, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 40/88] virtio-9p: fix virtio-9p child refcount in transports, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 49/88] Make qemu_shutdown_requested signal-safe, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 51/88] virtio-scsi: sense in virtio_scsi_command_complete, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 50/88] vnc: sanitize bits_per_pixel from the client, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 52/88] tcg/mips: fix store softmmu slow path, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 53/88] hw/core/loader: implement address translation in uimage loader,
Michael Roth <=
- [Qemu-stable] [PATCH 56/88] hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*), Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 21/88] ivshmem: Check ivshmem_read() size argument, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 57/88] esp-pci: fixup deadlock with linux, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 19/88] virtio-balloon: fix integer overflow in memory stats feature, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 55/88] snapshot: add bdrv_drain_all() to bdrv_snapshot_delete() to avoid concurrency problem, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 54/88] hw/xtensa/xtfpga: treat uImage load address as virtual, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 23/88] ivshmem: Fix potential OOB r/w access, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 58/88] target-xtensa: add missing window check for entry, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 60/88] virtio-scsi: work around bug in old BIOSes, Michael Roth, 2015/01/08
- [Qemu-stable] [PATCH 59/88] kvm: Fix memory slot page alignment logic, Michael Roth, 2015/01/08