@@ -2,6 +2,7 @@
* QEMU PREP PCI host
*
* Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2011-2012 Andreas Färber
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,20 +25,29 @@
#include "hw.h"
#include "pci.h"
+#include "pci_internals.h" /* FIXME Needed for struct PCIBus */
#include "pci_host.h"
#include "pc.h"
#include "exec-memory.h"
+#define TYPE_RAVEN_PCI_DEVICE "raven"
+#define TYPE_RAVEN_PCI_HOST "raven-pcihost"
+
+typedef struct RavenPCIState {
+ PCIDevice dev;
+} RavenPCIState;
+
+#define RAVEN_PCI_HOST(obj) \
+ OBJECT_CHECK(PREPPCIState, (obj), TYPE_RAVEN_PCI_HOST)
+
typedef struct PRePPCIState {
PCIHostState host_state;
MemoryRegion intack;
qemu_irq irq[4];
+ PCIBus pci_bus;
+ RavenPCIState pci_dev;
} PREPPCIState;
-typedef struct RavenPCIState {
- PCIDevice dev;
-} RavenPCIState;
-
static inline uint32_t PPC_PCIIO_config(target_phys_addr_t addr)
{
int i;
@@ -94,23 +104,36 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pic[irq_num] , level);
}
-static int raven_pcihost_init(SysBusDevice *dev)
+static void raven_pcihost_initfn(Object *obj)
{
- PCIHostState *h = FROM_SYSBUS(PCIHostState, dev);
- PREPPCIState *s = DO_UPCAST(PREPPCIState, host_state, h);
+ PREPPCIState *s = RAVEN_PCI_HOST(obj);
+ PCIHostState *h = PCI_HOST(obj);
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *address_space_io = get_system_io();
- PCIBus *bus;
+
+ pci_bus_new_inplace(&s->pci_bus, DEVICE(obj), NULL,
+ address_space_mem, address_space_io, 0);
+ h->bus = &s->pci_bus;
+
+ object_initialize(&s->pci_dev, TYPE_RAVEN_PCI_DEVICE);
+ qdev_set_parent_bus(DEVICE(&s->pci_dev), &s->pci_bus.qbus);
+ object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(0, 0), "addr",
+ NULL);
+ qdev_prop_set_bit(DEVICE(&s->pci_dev), "multifunction", false);
+}
+
+static int raven_pcihost_init(SysBusDevice *dev)
+{
+ PCIHostState *h = PCI_HOST(dev);
+ PREPPCIState *s = RAVEN_PCI_HOST(dev);
+ MemoryRegion *address_space_mem = get_system_memory();
int i;
for (i = 0; i < 4; i++) {
sysbus_init_irq(dev, &s->irq[i]);
}
- bus = pci_register_bus(&h->busdev.qdev, NULL,
- prep_set_irq, prep_map_irq, s->irq,
- address_space_mem, address_space_io, 0, 4);
- h->bus = bus;
+ pci_bus_irqs(&s->pci_bus, prep_set_irq, prep_map_irq, s->irq, 4);
memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, s,
"pci-conf-idx", 1);
@@ -127,7 +150,9 @@ static int raven_pcihost_init(SysBusDevice *dev)
memory_region_init_io(&s->intack, &PPC_intack_ops, s, "pci-intack", 1);
memory_region_add_subregion(address_space_mem, 0xbffffff0, &s->intack);
- pci_create_simple(bus, 0, "raven");
+
+ /* TODO Remove once realize propagates to child devices. */
+ qdev_init_nofail(DEVICE(&s->pci_dev));
return 0;
}
@@ -166,8 +191,8 @@ static void raven_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
-static TypeInfo raven_info = {
- .name = "raven",
+static const TypeInfo raven_info = {
+ .name = TYPE_RAVEN_PCI_DEVICE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(RavenPCIState),
.class_init = raven_class_init,
@@ -184,9 +209,10 @@ static void raven_pcihost_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo raven_pcihost_info = {
- .name = "raven-pcihost",
+ .name = TYPE_RAVEN_PCI_HOST,
.parent = TYPE_PCI_HOST,
.instance_size = sizeof(PREPPCIState),
+ .instance_init = raven_pcihost_initfn,
.class_init = raven_pcihost_class_init,
};
Prepares for QOM realize. Signed-off-by: Andreas Färber <andreas.faerber@web.de> --- hw/prep_pci.c | 58 +++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 42 insertions(+), 16 deletions(-)