diff options
Diffstat (limited to 'hw/ppc/pegasos2.c')
-rw-r--r-- | hw/ppc/pegasos2.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 9b0a6b7..e15cf96 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -14,28 +14,29 @@ #include "hw/sysbus.h" #include "hw/pci/pci_host.h" #include "hw/irq.h" +#include "hw/or-irq.h" #include "hw/pci-host/mv64361.h" #include "hw/isa/vt82c686.h" #include "hw/ide/pci.h" #include "hw/i2c/smbus_eeprom.h" #include "hw/qdev-properties.h" -#include "sysemu/reset.h" -#include "sysemu/runstate.h" -#include "sysemu/qtest.h" +#include "system/reset.h" +#include "system/runstate.h" +#include "system/qtest.h" #include "hw/boards.h" #include "hw/loader.h" #include "hw/fw-path-provider.h" #include "elf.h" #include "qemu/log.h" #include "qemu/error-report.h" -#include "sysemu/kvm.h" +#include "system/kvm.h" #include "kvm_ppc.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qom/qom-qobject.h" -#include "qapi/qmp/qdict.h" +#include "qobject/qdict.h" #include "trace.h" #include "qemu/datadir.h" -#include "sysemu/device_tree.h" +#include "system/device_tree.h" #include "hw/ppc/vof.h" #include <libfdt.h> @@ -73,8 +74,11 @@ OBJECT_DECLARE_TYPE(Pegasos2MachineState, MachineClass, PEGASOS2_MACHINE) struct Pegasos2MachineState { MachineState parent_obj; + PowerPCCPU *cpu; DeviceState *mv; + IRQState pci_irqs[PCI_NUM_PINS]; + OrIRQState orirq[PCI_NUM_PINS]; qemu_irq mv_pirq[PCI_NUM_PINS]; qemu_irq via_pirq[PCI_NUM_PINS]; Vof *vof; @@ -156,8 +160,8 @@ static void pegasos2_init(MachineState *machine) } memory_region_init_rom(rom, NULL, "pegasos2.rom", PROM_SIZE, &error_fatal); memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom); - sz = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, - PPC_ELF_MACHINE, 0, 0); + sz = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0); if (sz <= 0) { sz = load_image_targphys(filename, pm->vof ? 0 : PROM_ADDR, PROM_SIZE); } @@ -177,7 +181,6 @@ static void pegasos2_init(MachineState *machine) pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i); } pci_bus = mv64361_get_pci_bus(pm->mv, 1); - pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS); /* VIA VT8231 South Bridge (multifunction PCI device) */ via = OBJECT(pci_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA)); @@ -209,10 +212,35 @@ static void pegasos2_init(MachineState *machine) /* other PC hardware */ pci_vga_init(pci_bus); + /* PCI interrupt routing: lines from pci.0 and pci.1 are ORed */ + for (int h = 0; h < 2; h++) { + DeviceState *pd; + g_autofree const char *pn = g_strdup_printf("pcihost%d", h); + + pd = DEVICE(object_resolve_path_component(OBJECT(pm->mv), pn)); + assert(pd); + for (i = 0; i < PCI_NUM_PINS; i++) { + OrIRQState *ori = &pm->orirq[i]; + + if (h == 0) { + g_autofree const char *n = g_strdup_printf("pci-orirq[%d]", i); + + object_initialize_child_with_props(OBJECT(pm), n, + ori, sizeof(*ori), + TYPE_OR_IRQ, &error_fatal, + "num-lines", "2", NULL); + qdev_realize(DEVICE(ori), NULL, &error_fatal); + qemu_init_irq(&pm->pci_irqs[i], pegasos2_pci_irq, pm, i); + qdev_connect_gpio_out(DEVICE(ori), 0, &pm->pci_irqs[i]); + } + qdev_connect_gpio_out(pd, i, qdev_get_gpio_in(DEVICE(ori), h)); + } + } + if (machine->kernel_filename) { sz = load_elf(machine->kernel_filename, NULL, NULL, NULL, - &pm->kernel_entry, &pm->kernel_addr, NULL, NULL, 1, - PPC_ELF_MACHINE, 0, 0); + &pm->kernel_entry, &pm->kernel_addr, NULL, NULL, + ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0); if (sz <= 0) { error_report("Could not load kernel '%s'", machine->kernel_filename); @@ -291,14 +319,14 @@ static void pegasos2_superio_write(uint8_t addr, uint8_t val) cpu_physical_memory_write(PCI1_IO_BASE + 0x3f1, &val, 1); } -static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason) +static void pegasos2_machine_reset(MachineState *machine, ResetType type) { Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine); void *fdt; uint64_t d[2]; int sz; - qemu_devices_reset(reason); + qemu_devices_reset(type); if (!pm->vof) { return; /* Firmware should set up machine so nothing to do */ } @@ -389,7 +417,6 @@ static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason) d[1] = cpu_to_be64(pm->kernel_size - (pm->kernel_entry - pm->kernel_addr)); qemu_fdt_setprop(fdt, "/chosen", "qemu,boot-kernel", d, sizeof(d)); - qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt)); g_free(pm->fdt_blob); pm->fdt_blob = fdt; @@ -561,7 +588,7 @@ static bool pegasos2_setprop(MachineState *ms, const char *path, return true; } -static void pegasos2_machine_class_init(ObjectClass *oc, void *data) +static void pegasos2_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc); @@ -592,7 +619,7 @@ static const TypeInfo pegasos2_machine_info = { .parent = TYPE_MACHINE, .class_init = pegasos2_machine_class_init, .instance_size = sizeof(Pegasos2MachineState), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PPC_VIRTUAL_HYPERVISOR }, { TYPE_VOF_MACHINE_IF }, { } |