diff options
-rw-r--r-- | hw/ppc/e500-ccsr.h | 17 | ||||
-rw-r--r-- | hw/ppc/e500.c | 55 | ||||
-rw-r--r-- | hw/ppce500_pci.c | 29 |
3 files changed, 91 insertions, 10 deletions
diff --git a/hw/ppc/e500-ccsr.h b/hw/ppc/e500-ccsr.h new file mode 100644 index 0000000000..f20f51bcd2 --- /dev/null +++ b/hw/ppc/e500-ccsr.h @@ -0,0 +1,17 @@ +#ifndef E500_CCSR_H +#define E500_CCSR_H + +#include "../sysbus.h" + +typedef struct PPCE500CCSRState { + /*< private >*/ + SysBusDevice parent; + /*< public >*/ + + MemoryRegion ccsr_space; +} PPCE500CCSRState; + +#define TYPE_CCSR "e500-ccsr" +#define CCSR(obj) OBJECT_CHECK(PPCE500CCSRState, (obj), TYPE_CCSR) + +#endif /* E500_CCSR_H */ diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 85389335e5..47e2d4169a 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -17,6 +17,7 @@ #include "config.h" #include "qemu-common.h" #include "e500.h" +#include "e500-ccsr.h" #include "net.h" #include "hw/hw.h" #include "hw/serial.h" @@ -422,8 +423,9 @@ void ppce500_init(PPCE500Params *params) qemu_irq **irqs, *mpic; DeviceState *dev; CPUPPCState *firstenv = NULL; - MemoryRegion *ccsr; + MemoryRegion *ccsr_addr_space; SysBusDevice *s; + PPCE500CCSRState *ccsr; /* Setup CPUs */ if (params->cpu_model == NULL) { @@ -480,12 +482,17 @@ void ppce500_init(PPCE500Params *params) vmstate_register_ram_global(ram); memory_region_add_subregion(address_space_mem, 0, ram); - ccsr = g_malloc0(sizeof(MemoryRegion)); - memory_region_init(ccsr, "e500-ccsr", MPC8544_CCSRBAR_SIZE); - memory_region_add_subregion(address_space_mem, MPC8544_CCSRBAR_BASE, ccsr); + dev = qdev_create(NULL, "e500-ccsr"); + object_property_add_child(qdev_get_machine(), "e500-ccsr", + OBJECT(dev), NULL); + qdev_init_nofail(dev); + ccsr = CCSR(dev); + ccsr_addr_space = &ccsr->ccsr_space; + memory_region_add_subregion(address_space_mem, MPC8544_CCSRBAR_BASE, + ccsr_addr_space); /* MPIC */ - mpic = mpic_init(ccsr, MPC8544_MPIC_REGS_OFFSET, + mpic = mpic_init(ccsr_addr_space, MPC8544_MPIC_REGS_OFFSET, smp_cpus, irqs, NULL); if (!mpic) { @@ -494,13 +501,13 @@ void ppce500_init(PPCE500Params *params) /* Serial */ if (serial_hds[0]) { - serial_mm_init(ccsr, MPC8544_SERIAL0_REGS_OFFSET, + serial_mm_init(ccsr_addr_space, MPC8544_SERIAL0_REGS_OFFSET, 0, mpic[12+26], 399193, serial_hds[0], DEVICE_BIG_ENDIAN); } if (serial_hds[1]) { - serial_mm_init(ccsr, MPC8544_SERIAL1_REGS_OFFSET, + serial_mm_init(ccsr_addr_space, MPC8544_SERIAL1_REGS_OFFSET, 0, mpic[12+26], 399193, serial_hds[1], DEVICE_BIG_ENDIAN); } @@ -509,7 +516,7 @@ void ppce500_init(PPCE500Params *params) dev = qdev_create(NULL, "mpc8544-guts"); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); - memory_region_add_subregion(ccsr, MPC8544_UTIL_OFFSET, + memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET, sysbus_mmio_get_region(s, 0)); /* PCI */ @@ -520,7 +527,7 @@ void ppce500_init(PPCE500Params *params) sysbus_connect_irq(s, 1, mpic[pci_irq_nrs[1]]); sysbus_connect_irq(s, 2, mpic[pci_irq_nrs[2]]); sysbus_connect_irq(s, 3, mpic[pci_irq_nrs[3]]); - memory_region_add_subregion(ccsr, MPC8544_PCI_REGS_OFFSET, + memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET, sysbus_mmio_get_region(s, 0)); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0"); @@ -595,3 +602,33 @@ void ppce500_init(PPCE500Params *params) kvmppc_init(); } } + +static int e500_ccsr_initfn(SysBusDevice *dev) +{ + PPCE500CCSRState *ccsr; + + ccsr = CCSR(dev); + memory_region_init(&ccsr->ccsr_space, "e500-ccsr", + MPC8544_CCSRBAR_SIZE); + return 0; +} + +static void e500_ccsr_class_init(ObjectClass *klass, void *data) +{ + SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + k->init = e500_ccsr_initfn; +} + +static const TypeInfo e500_ccsr_info = { + .name = TYPE_CCSR, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(PPCE500CCSRState), + .class_init = e500_ccsr_class_init, +}; + +static void e500_register_types(void) +{ + type_register_static(&e500_ccsr_info); +} + +type_init(e500_register_types) diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c index 2ff7438d09..54c72b4fd2 100644 --- a/hw/ppce500_pci.c +++ b/hw/ppce500_pci.c @@ -15,6 +15,7 @@ */ #include "hw.h" +#include "hw/ppc/e500-ccsr.h" #include "pci.h" #include "pci_host.h" #include "bswap.h" @@ -92,6 +93,19 @@ struct PPCE500PCIState { MemoryRegion pio; }; +#define TYPE_PPC_E500_PCI_BRIDGE "e500-host-bridge" +#define PPC_E500_PCI_BRIDGE(obj) \ + OBJECT_CHECK(PPCE500PCIBridgeState, (obj), TYPE_PPC_E500_PCI_BRIDGE) + +struct PPCE500PCIBridgeState { + /*< private >*/ + PCIDevice parent; + /*< public >*/ + + MemoryRegion bar0; +}; + +typedef struct PPCE500PCIBridgeState PPCE500PCIBridgeState; typedef struct PPCE500PCIState PPCE500PCIState; static uint64_t pci_reg_read4(void *opaque, hwaddr addr, @@ -310,6 +324,18 @@ static const VMStateDescription vmstate_ppce500_pci = { #include "exec-memory.h" +static int e500_pcihost_bridge_initfn(PCIDevice *d) +{ + PPCE500PCIBridgeState *b = PPC_E500_PCI_BRIDGE(d); + PPCE500CCSRState *ccsr = CCSR(container_get(qdev_get_machine(), + "/e500-ccsr")); + + memory_region_init_alias(&b->bar0, "e500-pci-bar0", &ccsr->ccsr_space, + 0, int128_get64(ccsr->ccsr_space.size)); + pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &b->bar0); + return 0; +} + static int e500_pcihost_initfn(SysBusDevice *dev) { PCIHostState *h; @@ -355,6 +381,7 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + k->init = e500_pcihost_bridge_initfn; k->vendor_id = PCI_VENDOR_ID_FREESCALE; k->device_id = PCI_DEVICE_ID_MPC8533E; k->class_id = PCI_CLASS_PROCESSOR_POWERPC; @@ -364,7 +391,7 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data) static const TypeInfo e500_host_bridge_info = { .name = "e500-host-bridge", .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(PCIDevice), + .instance_size = sizeof(PPCE500PCIBridgeState), .class_init = e500_host_bridge_class_init, }; |