From 1c0a9e6984a17cd5e50b48f611e290fcb461ac09 Mon Sep 17 00:00:00 2001 From: espes Date: Sat, 17 Nov 2012 18:39:35 +1100 Subject: [PATCH] Load mcpx rom separately from bios Conflicts: hw/i386/xbox.c --- hw/xbox_pci.c | 68 +++++++++++++++++++++++++++++++++++++---- hw/xbox_pci.h | 3 ++ include/sysemu/sysemu.h | 1 + qemu-options.hx | 8 +++++ vl.c | 4 +++ 5 files changed, 78 insertions(+), 6 deletions(-) diff --git a/hw/xbox_pci.c b/hw/xbox_pci.c index ef9408c7bd..158e5ba5d3 100644 --- a/hw/xbox_pci.c +++ b/hw/xbox_pci.c @@ -20,6 +20,8 @@ #include "qemu/range.h" #include "isa.h" #include "sysbus.h" +#include "sysemu/sysemu.h" +#include "loader.h" #include "pc.h" #include "pci/pci.h" #include "pci/pci_bus.h" @@ -228,20 +230,74 @@ static const TypeInfo xbox_smbus_info = { - - - static int xbox_lpc_initfn(PCIDevice *d) { - XBOX_LPCState *lpc = XBOX_LPC_DEVICE(d); + XBOX_LPCState *s = XBOX_LPC_DEVICE(d); ISABus *isa_bus; isa_bus = isa_bus_new(&d->qdev, get_system_io()); - lpc->isa_bus = isa_bus; + s->isa_bus = isa_bus; + + + /* southbridge chip contains and controls bootrom image. + * can't load it through loader.c because it overlaps with the bios... + */ + char *filename; + int rc, fd = -1; + if (bootrom_name + && (filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bootrom_name))) { + s->bootrom_size = get_image_size(filename); + + if (s->bootrom_size != 512) { + fprintf(stderr, "MCPX bootrom should be 512 bytes, got %d\n", + s->bootrom_size); + return -1; + } + + fd = open(filename, O_RDONLY | O_BINARY); + assert(fd != -1); + rc = read(fd, s->bootrom_data, s->bootrom_size); + assert(rc == s->bootrom_size); + + close(fd); + } + return 0; } + + +static void xbox_lpc_reset(DeviceState *dev) +{ + PCIDevice *d = PCI_DEVICE(dev); + XBOX_LPCState *s = XBOX_LPC_DEVICE(d); + + + if (s->bootrom_size) { + /* qemu's memory region shit is actually kinda broken - + * Trying to execute off a non-page-aligned memory region + * is fucked, so we can't must map in the bootrom. + * + * We need to be able to disable it at runtime, and + * it shouldn't be visible ontop of the bios mirrors. It'll have to + * be a retarded hack. + * + * Be lazy for now and just write it ontop of the bios. + * + * (We do this here since loader.c loads roms into memory in a reset + * handler, and here we /should/ be handler after it.) + */ + + hwaddr bootrom_addr = (uint32_t)(-s->bootrom_size); + cpu_physical_memory_write_rom(bootrom_addr, + s->bootrom_data, + s->bootrom_size); + } + +} + + #if 0 /* Xbox 1.1 uses a config register instead of a bar to set the pm base address */ #define XBOX_LPC_PMBASE 0x84 @@ -305,7 +361,7 @@ static void xbox_lpc_class_init(ObjectClass *klass, void *data) dc->desc = "nForce LPC Bridge"; dc->no_user = 1; - //dc->reset = xbox_lpc_reset; + dc->reset = xbox_lpc_reset; //dc->vmsd = &vmstate_xbox_lpc; } diff --git a/hw/xbox_pci.h b/hw/xbox_pci.h index 3b38f1a2ed..1c180e7966 100644 --- a/hw/xbox_pci.h +++ b/hw/xbox_pci.h @@ -53,6 +53,9 @@ typedef struct XBOX_LPCState { ISABus *isa_bus; XBOX_PMRegs pm; + + int bootrom_size; + uint8_t bootrom_data[512]; } XBOX_LPCState; #define XBOX_PCI_DEVICE(obj) \ diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 6578782fc3..cf0ae33e4e 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -13,6 +13,7 @@ /* vl.c */ extern const char *bios_name; +extern const char *bootrom_name; extern const char *qemu_name; extern uint8_t qemu_uuid[]; diff --git a/qemu-options.hx b/qemu-options.hx index 30fb85d619..ba4881d783 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2624,6 +2624,14 @@ STEXI Set the filename for the BIOS. ETEXI +DEF("bootrom", HAS_ARG, QEMU_OPTION_bootrom, \ + "-bootrom file set the filename for the boot rom\n", QEMU_ARCH_ALL) +STEXI +@item -bootrom @var{file} +@findex -bootrom +Set the filename for the boot rom. +ETEXI + DEF("enable-kvm", 0, QEMU_OPTION_enable_kvm, \ "-enable-kvm enable KVM full virtualization support\n", QEMU_ARCH_ALL) STEXI diff --git a/vl.c b/vl.c index a621aec0a4..f2430f5b1e 100644 --- a/vl.c +++ b/vl.c @@ -182,6 +182,7 @@ int main(int argc, char **argv) static const char *data_dir[16]; static int data_dir_idx; const char *bios_name = NULL; +const char *bootrom_name = NULL; enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; DisplayType display_type = DT_DEFAULT; static int display_remote; @@ -3297,6 +3298,9 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_bios: bios_name = optarg; break; + case QEMU_OPTION_bootrom: + bootrom_name = optarg; + break; case QEMU_OPTION_singlestep: singlestep = 1; break;