Message ID | 6db700da7c07c6337682c73faa91c2444a4aa97a.1592315226.git.balaton@eik.bme.hu (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Mac Old World ROM experiment | expand |
On 16/06/2020 14:47, BALATON Zoltan wrote: > The beige G3 Power Macintosh has a 4MB firmware ROM. Fix the size of > the rom region and fall back to loading a binary image with -bios if > loading ELF image failed. This allows testing emulation with a ROM > image from real hardware as well as using an ELF OpenBIOS image. > > Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> > --- > v4: use load address from ELF to check if ROM is too big > > hw/ppc/mac_oldworld.c | 29 ++++++++++++++++++++--------- > 1 file changed, 20 insertions(+), 9 deletions(-) > > diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c > index f8c204ead7..baf3da6f90 100644 > --- a/hw/ppc/mac_oldworld.c > +++ b/hw/ppc/mac_oldworld.c > @@ -59,6 +59,8 @@ > #define NDRV_VGA_FILENAME "qemu_vga.ndrv" > > #define GRACKLE_BASE 0xfec00000 > +#define PROM_BASE 0xffc00000 > +#define PROM_SIZE (4 * MiB) > > static void fw_cfg_boot_set(void *opaque, const char *boot_device, > Error **errp) > @@ -99,6 +101,7 @@ static void ppc_heathrow_init(MachineState *machine) > SysBusDevice *s; > DeviceState *dev, *pic_dev; > BusState *adb_bus; > + uint64_t bios_addr; > int bios_size; > unsigned int smp_cpus = machine->smp.cpus; > uint16_t ppc_boot_device; > @@ -127,24 +130,32 @@ static void ppc_heathrow_init(MachineState *machine) > > memory_region_add_subregion(sysmem, 0, machine->ram); > > - /* allocate and load BIOS */ > - memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE, > + /* allocate and load firmware ROM */ > + memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE, > &error_fatal); > + memory_region_add_subregion(sysmem, PROM_BASE, bios); > > - if (bios_name == NULL) > + if (!bios_name) { > bios_name = PROM_FILENAME; > + } > filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); > - memory_region_add_subregion(sysmem, PROM_ADDR, bios); > - > - /* Load OpenBIOS (ELF) */ > if (filename) { > - bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, NULL, > - 1, PPC_ELF_MACHINE, 0, 0); > + /* Load OpenBIOS (ELF) */ > + bios_size = load_elf(filename, NULL, NULL, NULL, NULL, &bios_addr, > + NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); > + if (bios_size <= 0) { > + /* or load binary ROM image */ > + bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE); > + bios_addr = PROM_BASE; > + } else { > + /* load_elf sets high 32 bits for some reason, strip those */ > + bios_addr &= 0xffffffffULL; This is certainly the approach I suggested, but this seems wrong - otherwise load_elf() would be broken for quite a few use cases. > + } > g_free(filename); > } else { > bios_size = -1; > } > - if (bios_size < 0 || bios_size > BIOS_SIZE) { > + if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) { > error_report("could not load PowerPC bios '%s'", bios_name); > exit(1); > } (goes and looks) This is similar to how the SPARC32 loader works and it seems fine there: https://git.qemu.org/?p=qemu.git;a=blob;f=hw/sparc/sun4m.c;h=ee52b5cbbcd22284384225c80ad50cdbd1415743;hb=HEAD#l721. Looks like you might have the wrong addr parameter here? ATB, Mark.
On Fri, 26 Jun 2020, Mark Cave-Ayland wrote: > On 16/06/2020 14:47, BALATON Zoltan wrote: >> The beige G3 Power Macintosh has a 4MB firmware ROM. Fix the size of >> the rom region and fall back to loading a binary image with -bios if >> loading ELF image failed. This allows testing emulation with a ROM >> image from real hardware as well as using an ELF OpenBIOS image. >> >> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> >> --- >> v4: use load address from ELF to check if ROM is too big >> >> hw/ppc/mac_oldworld.c | 29 ++++++++++++++++++++--------- >> 1 file changed, 20 insertions(+), 9 deletions(-) >> >> diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c >> index f8c204ead7..baf3da6f90 100644 >> --- a/hw/ppc/mac_oldworld.c >> +++ b/hw/ppc/mac_oldworld.c >> @@ -59,6 +59,8 @@ >> #define NDRV_VGA_FILENAME "qemu_vga.ndrv" >> >> #define GRACKLE_BASE 0xfec00000 >> +#define PROM_BASE 0xffc00000 >> +#define PROM_SIZE (4 * MiB) >> >> static void fw_cfg_boot_set(void *opaque, const char *boot_device, >> Error **errp) >> @@ -99,6 +101,7 @@ static void ppc_heathrow_init(MachineState *machine) >> SysBusDevice *s; >> DeviceState *dev, *pic_dev; >> BusState *adb_bus; >> + uint64_t bios_addr; >> int bios_size; >> unsigned int smp_cpus = machine->smp.cpus; >> uint16_t ppc_boot_device; >> @@ -127,24 +130,32 @@ static void ppc_heathrow_init(MachineState *machine) >> >> memory_region_add_subregion(sysmem, 0, machine->ram); >> >> - /* allocate and load BIOS */ >> - memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE, >> + /* allocate and load firmware ROM */ >> + memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE, >> &error_fatal); >> + memory_region_add_subregion(sysmem, PROM_BASE, bios); >> >> - if (bios_name == NULL) >> + if (!bios_name) { >> bios_name = PROM_FILENAME; >> + } >> filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); >> - memory_region_add_subregion(sysmem, PROM_ADDR, bios); >> - >> - /* Load OpenBIOS (ELF) */ >> if (filename) { >> - bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, NULL, >> - 1, PPC_ELF_MACHINE, 0, 0); >> + /* Load OpenBIOS (ELF) */ >> + bios_size = load_elf(filename, NULL, NULL, NULL, NULL, &bios_addr, >> + NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); >> + if (bios_size <= 0) { >> + /* or load binary ROM image */ >> + bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE); >> + bios_addr = PROM_BASE; >> + } else { >> + /* load_elf sets high 32 bits for some reason, strip those */ >> + bios_addr &= 0xffffffffULL; > > This is certainly the approach I suggested, but this seems wrong - otherwise > load_elf() would be broken for quite a few use cases. > >> + } >> g_free(filename); >> } else { >> bios_size = -1; >> } >> - if (bios_size < 0 || bios_size > BIOS_SIZE) { >> + if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) { >> error_report("could not load PowerPC bios '%s'", bios_name); >> exit(1); >> } > > (goes and looks) > > This is similar to how the SPARC32 loader works and it seems fine there: > https://git.qemu.org/?p=qemu.git;a=blob;f=hw/sparc/sun4m.c;h=ee52b5cbbcd22284384225c80ad50cdbd1415743;hb=HEAD#l721. > Looks like you might have the wrong addr parameter here? I don't get this. Can you explain more please what is wrong and what's the proposed solution? Regards, BALATON Zoltan
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index f8c204ead7..baf3da6f90 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -59,6 +59,8 @@ #define NDRV_VGA_FILENAME "qemu_vga.ndrv" #define GRACKLE_BASE 0xfec00000 +#define PROM_BASE 0xffc00000 +#define PROM_SIZE (4 * MiB) static void fw_cfg_boot_set(void *opaque, const char *boot_device, Error **errp) @@ -99,6 +101,7 @@ static void ppc_heathrow_init(MachineState *machine) SysBusDevice *s; DeviceState *dev, *pic_dev; BusState *adb_bus; + uint64_t bios_addr; int bios_size; unsigned int smp_cpus = machine->smp.cpus; uint16_t ppc_boot_device; @@ -127,24 +130,32 @@ static void ppc_heathrow_init(MachineState *machine) memory_region_add_subregion(sysmem, 0, machine->ram); - /* allocate and load BIOS */ - memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE, + /* allocate and load firmware ROM */ + memory_region_init_rom(bios, NULL, "ppc_heathrow.bios", PROM_SIZE, &error_fatal); + memory_region_add_subregion(sysmem, PROM_BASE, bios); - if (bios_name == NULL) + if (!bios_name) { bios_name = PROM_FILENAME; + } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); - memory_region_add_subregion(sysmem, PROM_ADDR, bios); - - /* Load OpenBIOS (ELF) */ if (filename) { - bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, NULL, - 1, PPC_ELF_MACHINE, 0, 0); + /* Load OpenBIOS (ELF) */ + bios_size = load_elf(filename, NULL, NULL, NULL, NULL, &bios_addr, + NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); + if (bios_size <= 0) { + /* or load binary ROM image */ + bios_size = load_image_targphys(filename, PROM_BASE, PROM_SIZE); + bios_addr = PROM_BASE; + } else { + /* load_elf sets high 32 bits for some reason, strip those */ + bios_addr &= 0xffffffffULL; + } g_free(filename); } else { bios_size = -1; } - if (bios_size < 0 || bios_size > BIOS_SIZE) { + if (bios_size < 0 || bios_addr - PROM_BASE + bios_size > PROM_SIZE) { error_report("could not load PowerPC bios '%s'", bios_name); exit(1); }
The beige G3 Power Macintosh has a 4MB firmware ROM. Fix the size of the rom region and fall back to loading a binary image with -bios if loading ELF image failed. This allows testing emulation with a ROM image from real hardware as well as using an ELF OpenBIOS image. Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> --- v4: use load address from ELF to check if ROM is too big hw/ppc/mac_oldworld.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-)