Machine is very simple (only one PCI host bridge and an ISA bridge). Provide a ibm_43p.cfg file to add more devices to this machine.
Syntax is: qemu-system-ppc -M 43p -readconfig ibm_43p.cfg --- docs/ibm_43p.cfg | 34 ++++++++++++++++++++ hw/ppc/prep.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 docs/ibm_43p.cfg diff --git a/docs/ibm_43p.cfg b/docs/ibm_43p.cfg new file mode 100644 index 0000000..cf80b89 --- /dev/null +++ b/docs/ibm_43p.cfg @@ -0,0 +1,34 @@ +############################################################################ +# +# qemu-system-ppc -M 43p creates a bare machine with just the very essential +# chipset devices being present: +# +# 00.0 - Host bridge +# 0b.0 - ISA bridge +# +# This config file documents the other devices and how they are +# created. You can simply use "-readconfig $thisfile" to create +# them all. + +[device] + driver = "i8042" + +[device] + driver = "pc87312" + config = "12" + +[device] + driver = "pcnet" + addr = "12.0" + +[device] + driver = "isa-ide" + iobase = "0x1f0" + iobase2 = "0x3f6" + irq = "14" + +[device] + driver = "isa-ide" + iobase = "0x170" + iobase2 = "0x376" + irq = "15" diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 2920911..6c5558e 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -30,6 +30,7 @@ #include "sysemu/sysemu.h" #include "hw/isa.h" #include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" #include "hw/pci/pci_host.h" #include "hw/ppc.h" #include "hw/boards.h" @@ -663,6 +664,91 @@ static void ppc_prep_init(QEMUMachineInitArgs *args) audio_init(isa_bus, pci_bus); } +static int prep_set_cmos_checksum(DeviceState *dev, void *opaque) +{ + uint16_t checksum = *(uint16_t*)opaque; + ISADevice *rtc; + + rtc = ISA_DEVICE(object_dynamic_cast(OBJECT(dev), "mc146818rtc")); + if (rtc) { + rtc_set_memory(rtc, 0x2e, checksum & 0xff); + rtc_set_memory(rtc, 0x3e, checksum & 0xff); + rtc_set_memory(rtc, 0x2f, checksum >> 8); + rtc_set_memory(rtc, 0x3f, checksum >> 8); + } + return 0; +} + +static void ibm_43p_init(QEMUMachineInitArgs *args) +{ + CPUPPCState *env = NULL; + uint16_t cmos_checksum; + PowerPCCPU *cpu; + DeviceState *dev; + SysBusDevice *pcihost; + PCIBus *pci_bus; + ISABus *isa_bus; + qemu_irq *cpu_exit_irq; + + /* init CPU */ + if (!args->cpu_model) + args->cpu_model = "604"; + { + cpu = cpu_ppc_init(args->cpu_model); + if (cpu == NULL) { + fprintf(stderr, "Unable to find PowerPC CPU definition\n"); + exit(1); + } + env = &cpu->env; + + if (env->flags & POWERPC_FLAG_RTC_CLK) { + /* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */ + cpu_ppc_tb_init(env, 7812500UL); + } else { + /* Set time-base frequency to 100 Mhz */ + cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); + } + qemu_register_reset(ppc_prep_reset, cpu); + } + if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { + hw_error("Only 6xx bus is supported on PREP machine\n"); + } + + /* PCI host */ + pcihost = SYS_BUS_DEVICE(qdev_create(NULL, "mpc105-pcihost")); + qdev_prop_set_uint32(DEVICE(pcihost), "ram-size", (uint32_t)args->ram_size); + if (bios_name == NULL) + bios_name = "P93H1904.IMG"; + qdev_prop_set_string(DEVICE(pcihost), "bios-name", bios_name); + object_property_add_child(qdev_get_machine(), "eagle", OBJECT(pcihost), NULL); + qdev_init_nofail(DEVICE(pcihost)); + pci_bus = PCI_BUS(qdev_get_child_bus(DEVICE(pcihost), "pci.0")); + if (pci_bus == NULL) { + fprintf(stderr, "Couldn't create PCI host controller.\n"); + exit(1); + } + + /* PCI -> ISA bridge */ + dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(11, 0), "i82378")); + cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); + qdev_connect_gpio_out(dev, 0, + first_cpu->irq_inputs[PPC6xx_INPUT_INT]); + qdev_connect_gpio_out(dev, 1, *cpu_exit_irq); + sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(dev, 9)); + sysbus_connect_irq(pcihost, 1, qdev_get_gpio_in(dev, 11)); + sysbus_connect_irq(pcihost, 2, qdev_get_gpio_in(dev, 9)); + sysbus_connect_irq(pcihost, 3, qdev_get_gpio_in(dev, 11)); + isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0")); + + /* initialize CMOS checksums */ + cmos_checksum = 0x6aa9; + qbus_walk_children(BUS(isa_bus), prep_set_cmos_checksum, NULL, + &cmos_checksum); + + /* Now that we have PCI and ISA, initialize audio subsystem */ + audio_init(isa_bus, pci_bus); +} + static QEMUMachine prep_machine = { .name = "prep", .desc = "PowerPC PREP platform", @@ -671,9 +757,17 @@ static QEMUMachine prep_machine = { DEFAULT_MACHINE_OPTIONS, }; +static QEMUMachine ibm_43p_machine = { + .name = "43p", + .desc = "IBM RS/6000 7248 (43p)", + .init = ibm_43p_init, + .max_cpus = 1, +}; + static void prep_machine_init(void) { qemu_register_machine(&prep_machine); + qemu_register_machine(&ibm_43p_machine); } machine_init(prep_machine_init); -- 1.7.10.4