diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/an5206.c | 4 | ||||
-rw-r--r-- | hw/arm_boot.c | 4 | ||||
-rw-r--r-- | hw/armv7m.c | 4 | ||||
-rw-r--r-- | hw/axis_dev88.c | 7 | ||||
-rw-r--r-- | hw/dummy_m68k.c | 4 | ||||
-rw-r--r-- | hw/elf_ops.h | 10 | ||||
-rw-r--r-- | hw/etraxfs.c | 7 | ||||
-rw-r--r-- | hw/loader.c | 14 | ||||
-rw-r--r-- | hw/loader.h | 7 | ||||
-rw-r--r-- | hw/mcf5208.c | 4 | ||||
-rw-r--r-- | hw/mips.h | 4 | ||||
-rw-r--r-- | hw/mips_addr.c | 34 | ||||
-rw-r--r-- | hw/mips_malta.c | 24 | ||||
-rw-r--r-- | hw/mips_mipssim.c | 17 | ||||
-rw-r--r-- | hw/mips_r4k.c | 17 | ||||
-rw-r--r-- | hw/multiboot.c | 4 | ||||
-rw-r--r-- | hw/petalogix_s3adsp1800_mmu.c | 11 | ||||
-rw-r--r-- | hw/ppc440_bamboo.c | 4 | ||||
-rw-r--r-- | hw/ppc_newworld.c | 19 | ||||
-rw-r--r-- | hw/ppc_oldworld.c | 21 | ||||
-rw-r--r-- | hw/ppce500_mpc8544ds.c | 4 | ||||
-rw-r--r-- | hw/sun4m.c | 19 | ||||
-rw-r--r-- | hw/sun4u.c | 14 |
23 files changed, 157 insertions, 100 deletions
diff --git a/hw/an5206.c b/hw/an5206.c index a4b83b0f44..f584d8816f 100644 --- a/hw/an5206.c +++ b/hw/an5206.c @@ -68,8 +68,8 @@ static void an5206_init(ram_addr_t ram_size, exit(1); } - kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL, - 1, ELF_MACHINE, 0); + kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + NULL, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; if (kernel_size < 0) { kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL); diff --git a/hw/arm_boot.c b/hw/arm_boot.c index 30a76a56d1..df031a5952 100644 --- a/hw/arm_boot.c +++ b/hw/arm_boot.c @@ -225,8 +225,8 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info) #endif /* Assume that raw images are linux kernels, and ELF images are not. */ - kernel_size = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL, - big_endian, ELF_MACHINE, 1); + kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry, + NULL, NULL, big_endian, ELF_MACHINE, 1); entry = elf_entry; if (kernel_size < 0) { kernel_size = load_uimage(info->kernel_filename, &entry, NULL, diff --git a/hw/armv7m.c b/hw/armv7m.c index 034323d26e..35f75735b9 100644 --- a/hw/armv7m.c +++ b/hw/armv7m.c @@ -215,8 +215,8 @@ qemu_irq *armv7m_init(int flash_size, int sram_size, big_endian = 0; #endif - image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL, - big_endian, ELF_MACHINE, 1); + image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr, + NULL, big_endian, ELF_MACHINE, 1); if (image_size < 0) { image_size = load_image_targphys(kernel_filename, 0, flash_size); lowaddr = 0; diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c index 1a6664957a..5516e42528 100644 --- a/hw/axis_dev88.c +++ b/hw/axis_dev88.c @@ -249,6 +249,11 @@ static void main_cpu_reset(void *opaque) env->pc = bootstrap_pc; } +static uint64_t translate_kernel_address(void *opaque, uint64_t addr) +{ + return addr - 0x80000000LL; +} + static void axisdev88_init (ram_addr_t ram_size, const char *boot_device, @@ -345,7 +350,7 @@ void axisdev88_init (ram_addr_t ram_size, /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis devboard SDK. */ - kernel_size = load_elf(kernel_filename, -0x80000000LL, + kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, &entry, NULL, &high, 0, ELF_MACHINE, 0); bootstrap_pc = entry; if (kernel_size < 0) { diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c index ce45a597db..9c9e6ff009 100644 --- a/hw/dummy_m68k.c +++ b/hw/dummy_m68k.c @@ -43,8 +43,8 @@ static void dummy_m68k_init(ram_addr_t ram_size, /* Load kernel. */ if (kernel_filename) { - kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL, - 1, ELF_MACHINE, 0); + kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + NULL, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; if (kernel_size < 0) { kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL); diff --git a/hw/elf_ops.h b/hw/elf_ops.h index 14b9ec0444..69c07571b6 100644 --- a/hw/elf_ops.h +++ b/hw/elf_ops.h @@ -184,7 +184,9 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, return -1; } -static int glue(load_elf, SZ)(const char *name, int fd, int64_t address_offset, +static int glue(load_elf, SZ)(const char *name, int fd, + uint64_t (*translate_fn)(void *, uint64_t), + void *translate_opaque, int must_swab, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int elf_machine, int clear_lsb) @@ -253,7 +255,11 @@ static int glue(load_elf, SZ)(const char *name, int fd, int64_t address_offset, } /* address_offset is hack for kernel images that are linked at the wrong physical address. */ - addr = ph->p_paddr + address_offset; + if (translate_fn) { + addr = translate_fn(translate_opaque, ph->p_paddr); + } else { + addr = ph->p_paddr; + } snprintf(label, sizeof(label), "phdr #%d: %s", i, name); rom_add_blob_fixed(label, data, mem_size, addr); diff --git a/hw/etraxfs.c b/hw/etraxfs.c index 2f7f3695c5..7405db487e 100644 --- a/hw/etraxfs.c +++ b/hw/etraxfs.c @@ -44,6 +44,11 @@ static void main_cpu_reset(void *opaque) env->pc = bootstrap_pc; } +static uint64_t translate_kernel_address(void *opaque, uint64_t addr) +{ + return addr - 0x80000000LL; +} + static void bareetraxfs_init (ram_addr_t ram_size, const char *boot_device, @@ -137,7 +142,7 @@ void bareetraxfs_init (ram_addr_t ram_size, /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis devboard SDK. */ - kernel_size = load_elf(kernel_filename, -0x80000000LL, + kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, &entry, NULL, &high, 0, ELF_MACHINE, 0); bootstrap_pc = entry; if (kernel_size < 0) { diff --git a/hw/loader.c b/hw/loader.c index 1448887e5e..79a6f95186 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -276,9 +276,9 @@ static void *load_at(int fd, int offset, int size) #include "elf_ops.h" /* return < 0 if error, otherwise the number of bytes loaded in memory */ -int load_elf(const char *filename, int64_t address_offset, - uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, - int big_endian, int elf_machine, int clear_lsb) +int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), + void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, + uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb) { int fd, data_order, target_data_order, must_swab, ret; uint8_t e_ident[EI_NIDENT]; @@ -312,11 +312,11 @@ int load_elf(const char *filename, int64_t address_offset, lseek(fd, 0, SEEK_SET); if (e_ident[EI_CLASS] == ELFCLASS64) { - ret = load_elf64(filename, fd, address_offset, must_swab, pentry, - lowaddr, highaddr, elf_machine, clear_lsb); + ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab, + pentry, lowaddr, highaddr, elf_machine, clear_lsb); } else { - ret = load_elf32(filename, fd, address_offset, must_swab, pentry, - lowaddr, highaddr, elf_machine, clear_lsb); + ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab, + pentry, lowaddr, highaddr, elf_machine, clear_lsb); } close(fd); diff --git a/hw/loader.h b/hw/loader.h index 56676e16c7..1f82fc5e98 100644 --- a/hw/loader.h +++ b/hw/loader.h @@ -5,9 +5,10 @@ int get_image_size(const char *filename); int load_image(const char *filename, uint8_t *addr); /* deprecated */ int load_image_targphys(const char *filename, target_phys_addr_t, int max_sz); -int load_elf(const char *filename, int64_t address_offset, - uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, - int big_endian, int elf_machine, int clear_lsb); +int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), + void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, + uint64_t *highaddr, int big_endian, int elf_machine, + int clear_lsb); int load_aout(const char *filename, target_phys_addr_t addr, int max_sz, int bswap_needed, target_phys_addr_t target_page_size); int load_uimage(const char *filename, target_phys_addr_t *ep, diff --git a/hw/mcf5208.c b/hw/mcf5208.c index 5598611462..5b686c657a 100644 --- a/hw/mcf5208.c +++ b/hw/mcf5208.c @@ -270,8 +270,8 @@ static void mcf5208evb_init(ram_addr_t ram_size, exit(1); } - kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL, - 1, ELF_MACHINE, 0); + kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + NULL, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; if (kernel_size < 0) { kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL); @@ -20,6 +20,10 @@ void mipsnet_init(int base, qemu_irq irq, NICInfo *nd); /* jazz_led.c */ extern void jazz_led_init(target_phys_addr_t base); +/* mips_addr.c */ +uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr); +uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr); + /* mips_int.c */ extern void cpu_mips_irq_init_cpu(CPUState *env); diff --git a/hw/mips_addr.c b/hw/mips_addr.c new file mode 100644 index 0000000000..b96fea0314 --- /dev/null +++ b/hw/mips_addr.c @@ -0,0 +1,34 @@ +/* + * QEMU MIPS address translation support + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "hw.h" +#include "mips.h" + +uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr) +{ + return addr & 0x7fffffffll; +} + +uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr) +{ + return addr | ~0x7fffffffll; +} diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 2d02a10227..91498c262c 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -46,15 +46,7 @@ //#define DEBUG_BOARD_INIT -#ifdef TARGET_MIPS64 -#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL) -#else -#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU) -#endif - -#define ENVP_ADDR (int32_t)0x80002000 -#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000)) - +#define ENVP_ADDR 0x80002000l #define ENVP_NB_ENTRIES 16 #define ENVP_ENTRY_SIZE 256 @@ -681,7 +673,7 @@ static void prom_set(uint32_t* prom_buf, int index, const char *string, ...) /* Kernel */ static int64_t load_kernel (void) { - int64_t kernel_entry, kernel_low, kernel_high; + int64_t kernel_entry, kernel_high; long initrd_size; ram_addr_t initrd_offset; int big_endian; @@ -695,9 +687,9 @@ static int64_t load_kernel (void) big_endian = 0; #endif - if (load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND, - (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low, - (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1) < 0) { + if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high, + big_endian, ELF_MACHINE, 1) < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", loaderparams.kernel_filename); exit(1); @@ -733,8 +725,8 @@ static int64_t load_kernel (void) prom_set(prom_buf, prom_index++, loaderparams.kernel_filename); if (initrd_size > 0) { - prom_set(prom_buf, prom_index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s", - PHYS_TO_VIRT(initrd_offset), initrd_size, + prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s", + cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size, loaderparams.kernel_cmdline); } else { prom_set(prom_buf, prom_index++, loaderparams.kernel_cmdline); @@ -747,7 +739,7 @@ static int64_t load_kernel (void) prom_set(prom_buf, prom_index++, NULL); rom_add_blob_fixed("prom", prom_buf, prom_size, - ENVP_ADDR + VIRT_TO_PHYS_ADDEND); + cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR)); return kernel_entry; } diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c index aa90116760..9a6f50cd15 100644 --- a/hw/mips_mipssim.c +++ b/hw/mips_mipssim.c @@ -35,14 +35,6 @@ #include "loader.h" #include "elf.h" -#ifdef TARGET_MIPS64 -#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL) -#else -#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU) -#endif - -#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000)) - static struct _loaderparams { int ram_size; const char *kernel_filename; @@ -57,7 +49,7 @@ typedef struct ResetData { static int64_t load_kernel(void) { - int64_t entry, kernel_low, kernel_high; + int64_t entry, kernel_high; long kernel_size; long initrd_size; ram_addr_t initrd_offset; @@ -69,9 +61,10 @@ static int64_t load_kernel(void) big_endian = 0; #endif - kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND, - (uint64_t *)&entry, (uint64_t *)&kernel_low, - (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1); + kernel_size = load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, + NULL, (uint64_t *)&entry, NULL, + (uint64_t *)&kernel_high, big_endian, + ELF_MACHINE, 1); if (kernel_size >= 0) { if ((entry & ~0x7fffffffULL) == 0x80000000) entry = (int32_t)entry; diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c index b69d7c3e99..3edc8d5921 100644 --- a/hw/mips_r4k.c +++ b/hw/mips_r4k.c @@ -21,10 +21,6 @@ #include "loader.h" #include "elf.h" -#define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fffffff) - -#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000)) - #define MAX_IDE_BUS 2 static const int ide_iobase[2] = { 0x1f0, 0x170 }; @@ -77,7 +73,7 @@ typedef struct ResetData { static int64_t load_kernel(void) { - int64_t entry, kernel_low, kernel_high; + int64_t entry, kernel_high; long kernel_size, initrd_size, params_size; ram_addr_t initrd_offset; uint32_t *params_buf; @@ -88,9 +84,10 @@ static int64_t load_kernel(void) #else big_endian = 0; #endif - kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND, - (uint64_t *)&entry, (uint64_t *)&kernel_low, - (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1); + kernel_size = load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, + NULL, (uint64_t *)&entry, NULL, + (uint64_t *)&kernel_high, big_endian, + ELF_MACHINE, 1); if (kernel_size >= 0) { if ((entry & ~0x7fffffffULL) == 0x80000000) entry = (int32_t)entry; @@ -132,8 +129,8 @@ static int64_t load_kernel(void) params_buf[1] = tswap32(0x12345678); if (initrd_size > 0) { - snprintf((char *)params_buf + 8, 256, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s", - PHYS_TO_VIRT((uint32_t)initrd_offset), + snprintf((char *)params_buf + 8, 256, "rd_start=0x%" PRIx64 " rd_size=%li %s", + cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size, loaderparams.kernel_cmdline); } else { snprintf((char *)params_buf + 8, 256, "%s", loaderparams.kernel_cmdline); diff --git a/hw/multiboot.c b/hw/multiboot.c index a25fbf6f35..a1b665cd41 100644 --- a/hw/multiboot.c +++ b/hw/multiboot.c @@ -170,8 +170,8 @@ int load_multiboot(void *fw_cfg, uint64_t elf_low, elf_high; int kernel_size; fclose(f); - kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_low, &elf_high, - 0, ELF_MACHINE, 0); + kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + &elf_low, &elf_high, 0, ELF_MACHINE, 0); if (kernel_size < 0) { fprintf(stderr, "Error while loading elf kernel\n"); exit(1); diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c index 8743636302..ea91d65f62 100644 --- a/hw/petalogix_s3adsp1800_mmu.c +++ b/hw/petalogix_s3adsp1800_mmu.c @@ -104,6 +104,11 @@ static int petalogix_load_device_tree(target_phys_addr_t addr, return fdt_size; } +static uint64_t translate_kernel_address(void *opaque, uint64_t addr) +{ + return addr - 0x30000000LL; +} + static void petalogix_s3adsp1800_init(ram_addr_t ram_size, const char *boot_device, @@ -163,13 +168,13 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size, uint32_t base32; /* Boots a kernel elf binary. */ - kernel_size = load_elf(kernel_filename, 0, + kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, &low, &high, 1, ELF_MACHINE, 0); base32 = entry; if (base32 == 0xc0000000) { - kernel_size = load_elf(kernel_filename, -0x30000000LL, - &entry, NULL, NULL, + kernel_size = load_elf(kernel_filename, translate_kernel_address, + NULL, &entry, NULL, NULL, 1, ELF_MACHINE, 0); } /* Always boot into physical ram. */ diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c index efe5a77bab..6ca873ee7e 100644 --- a/hw/ppc440_bamboo.c +++ b/hw/ppc440_bamboo.c @@ -120,8 +120,8 @@ static void bamboo_init(ram_addr_t ram_size, if (kernel_filename) { kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL); if (kernel_size < 0) { - kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr, - NULL, 1, ELF_MACHINE, 0); + kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; loadaddr = elf_lowaddr; } diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index d4f9013fe5..7c100e77a4 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -115,6 +115,11 @@ static int fw_cfg_boot_set(void *opaque, const char *boot_device) return 0; } +static uint64_t translate_kernel_address(void *opaque, uint64_t addr) +{ + return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR; +} + /* PowerPC Mac99 hardware initialisation */ static void ppc_core99_init (ram_addr_t ram_size, const char *boot_device, @@ -180,7 +185,8 @@ static void ppc_core99_init (ram_addr_t ram_size, /* Load OpenBIOS (ELF) */ if (filename) { - bios_size = load_elf(filename, 0, NULL, NULL, NULL, 1, ELF_MACHINE, 0); + bios_size = load_elf(filename, NULL, NULL, NULL, + NULL, NULL, 1, ELF_MACHINE, 0); qemu_free(filename); } else { @@ -232,15 +238,8 @@ static void ppc_core99_init (ram_addr_t ram_size, #endif kernel_base = KERNEL_LOAD_ADDR; - /* Now we can load the kernel. The first step tries to load the kernel - supposing PhysAddr = 0x00000000. If that was wrong the kernel is - loaded again, the new PhysAddr being computed from lowaddr. */ - kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL, - 1, ELF_MACHINE, 0); - if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) { - kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr, - NULL, NULL, NULL, 1, ELF_MACHINE, 0); - } + kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, + NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index 93c95ba659..bdc5bcd92e 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -122,6 +122,12 @@ static int fw_cfg_boot_set(void *opaque, const char *boot_device) return 0; } + +static uint64_t translate_kernel_address(void *opaque, uint64_t addr) +{ + return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR; +} + static void ppc_heathrow_init (ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, @@ -185,8 +191,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size, /* Load OpenBIOS (ELF) */ if (filename) { - bios_size = load_elf(filename, 0, NULL, NULL, NULL, - 1, ELF_MACHINE, 0); + bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL, + 1, ELF_MACHINE, 0); qemu_free(filename); } else { bios_size = -1; @@ -236,15 +242,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size, bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; - /* Now we can load the kernel. The first step tries to load the kernel - supposing PhysAddr = 0x00000000. If that was wrong the kernel is - loaded again, the new PhysAddr being computed from lowaddr. */ - kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL, - 1, ELF_MACHINE, 0); - if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) { - kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr, - NULL, NULL, NULL, 1, ELF_MACHINE, 0); - } + kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, + NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c index 90b4c56698..a83dba4a18 100644 --- a/hw/ppce500_mpc8544ds.c +++ b/hw/ppce500_mpc8544ds.c @@ -231,8 +231,8 @@ static void mpc8544ds_init(ram_addr_t ram_size, if (kernel_filename) { kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL); if (kernel_size < 0) { - kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr, - NULL, 1, ELF_MACHINE, 0); + kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + &elf_lowaddr, NULL, 1, ELF_MACHINE, 0); entry = elf_entry; loadaddr = elf_lowaddr; } diff --git a/hw/sun4m.c b/hw/sun4m.c index 7e26282034..90e661d5c2 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -292,6 +292,11 @@ static void cpu_halt_signal(void *opaque, int irq, int level) cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HALT); } +static uint64_t translate_kernel_address(void *opaque, uint64_t addr) +{ + return addr - 0xf0000000ULL; +} + static unsigned long sun4m_load_kernel(const char *kernel_filename, const char *initrd_filename, ram_addr_t RAM_size) @@ -312,8 +317,8 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename, #else bswap_needed = 0; #endif - kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL, - NULL, 1, ELF_MACHINE, 0); + kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, + NULL, NULL, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, RAM_size - KERNEL_LOAD_ADDR, bswap_needed, @@ -636,6 +641,12 @@ static void afx_register_devices(void) device_init(afx_register_devices); /* Boot PROM (OpenBIOS) */ +static uint64_t translate_prom_address(void *opaque, uint64_t addr) +{ + target_phys_addr_t *base_addr = (target_phys_addr_t *)opaque; + return addr + *base_addr - PROM_VADDR; +} + static void prom_init(target_phys_addr_t addr, const char *bios_name) { DeviceState *dev; @@ -655,8 +666,8 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name) } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL, - 1, ELF_MACHINE, 0); + ret = load_elf(filename, translate_prom_address, &addr, NULL, + NULL, NULL, 1, ELF_MACHINE, 0); if (ret < 0 || ret > PROM_SIZE_MAX) { ret = load_image_targphys(filename, addr, PROM_SIZE_MAX); } diff --git a/hw/sun4u.c b/hw/sun4u.c index f339df38d1..666383607f 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -189,8 +189,8 @@ static unsigned long sun4u_load_kernel(const char *kernel_filename, #else bswap_needed = 0; #endif - kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL, - 1, ELF_MACHINE, 0); + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, + NULL, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, RAM_size - KERNEL_LOAD_ADDR, bswap_needed, @@ -580,6 +580,12 @@ static void pci_ebus_register(void) device_init(pci_ebus_register); +static uint64_t translate_prom_address(void *opaque, uint64_t addr) +{ + target_phys_addr_t *base_addr = (target_phys_addr_t *)opaque; + return addr + *base_addr - PROM_VADDR; +} + /* Boot PROM (OpenBIOS) */ static void prom_init(target_phys_addr_t addr, const char *bios_name) { @@ -600,8 +606,8 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name) } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL, - 1, ELF_MACHINE, 0); + ret = load_elf(filename, translate_prom_address, &addr, + NULL, NULL, NULL, 1, ELF_MACHINE, 0); if (ret < 0 || ret > PROM_SIZE_MAX) { ret = load_image_targphys(filename, addr, PROM_SIZE_MAX); } |