diff mbox

[RFC,2/6] prep: add IBM RS/6000 7248 (43p) machine emulation

Message ID 1363299128-8494-3-git-send-email-hpoussin@reactos.org
State New
Headers show

Commit Message

Hervé Poussineau March 14, 2013, 10:12 p.m. UTC
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 mbox

Patch

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);