aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/e500.c
diff options
context:
space:
mode:
authorIgor Mammedov <imammedo@redhat.com>2018-05-10 18:10:56 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-05-10 18:10:56 +0100
commita3fc8396352e945f9d14cac0237ebf9d91745969 (patch)
tree0c8fae5141eeaa45f1ea0fc1f4f8033c21540623 /hw/ppc/e500.c
parent38aefb578dcf918359249ae5b29183255db809c2 (diff)
downloadqemu-a3fc8396352e945f9d14cac0237ebf9d91745969.zip
qemu-a3fc8396352e945f9d14cac0237ebf9d91745969.tar.gz
qemu-a3fc8396352e945f9d14cac0237ebf9d91745969.tar.bz2
platform-bus-device: use device plug callback instead of machine_done notifier
platform-bus were using machine_done notifier to get and map (assign irq/mmio resources) dynamically added sysbus devices after all '-device' options had been processed. That however creates non obvious dependencies on ordering of machine_done notifiers and requires carefull line juggling to keep it working. For example see comment above create_platform_bus() and 'straitforward' arm_load_kernel() had to converted to machine_done notifier and that lead to yet another machine_done notifier to keep it working arm_register_platform_bus_fdt_creator(). Instead of hiding resource assignment in platform-bus-device to magically initialize sysbus devices, use device plug callback and assign resources explicitly at board level at the moment each -device option is being processed. That adds a bunch of machine declaration boiler plate to e500plat board, similar to ARM/x86 but gets rid of hidden machine_done notifier and would allow to remove the dependent notifiers in ARM code simplifying it and making code flow easier to follow. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Acked-by: David Gibson <david@gibson.dropbear.id.au> Message-id: 1525691524-32265-3-git-send-email-imammedo@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ppc/e500.c')
-rw-r--r--hw/ppc/e500.c38
1 files changed, 17 insertions, 21 deletions
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 748a8d2..826053e 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -222,16 +222,15 @@ static void sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque)
}
}
-static void platform_bus_create_devtree(const PPCE500MachineClass *pmc,
+static void platform_bus_create_devtree(PPCE500MachineState *pms,
void *fdt, const char *mpic)
{
+ const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
gchar *node = g_strdup_printf("/platform@%"PRIx64, pmc->platform_bus_base);
const char platcomp[] = "qemu,platform\0simple-bus";
uint64_t addr = pmc->platform_bus_base;
uint64_t size = pmc->platform_bus_size;
int irq_start = pmc->platform_bus_first_irq;
- PlatformBusDevice *pbus;
- DeviceState *dev;
/* Create a /platform node that we can put all devices into */
@@ -246,22 +245,17 @@ static void platform_bus_create_devtree(const PPCE500MachineClass *pmc,
qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", mpic);
- dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE);
- pbus = PLATFORM_BUS_DEVICE(dev);
-
- /* We can only create dt nodes for dynamic devices when they're ready */
- if (pbus->done_gathering) {
- PlatformDevtreeData data = {
- .fdt = fdt,
- .mpic = mpic,
- .irq_start = irq_start,
- .node = node,
- .pbus = pbus,
- };
+ /* Create dt nodes for dynamic devices */
+ PlatformDevtreeData data = {
+ .fdt = fdt,
+ .mpic = mpic,
+ .irq_start = irq_start,
+ .node = node,
+ .pbus = pms->pbus_dev,
+ };
- /* Loop through all dynamic sysbus devices and create nodes for them */
- foreach_dynamic_sysbus_device(sysbus_device_create_devtree, &data);
- }
+ /* Loop through all dynamic sysbus devices and create nodes for them */
+ foreach_dynamic_sysbus_device(sysbus_device_create_devtree, &data);
g_free(node);
}
@@ -533,8 +527,8 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms,
}
g_free(soc);
- if (pmc->has_platform_bus) {
- platform_bus_create_devtree(pmc, fdt, mpic);
+ if (pms->pbus_dev) {
+ platform_bus_create_devtree(pms, fdt, mpic);
}
g_free(mpic);
@@ -953,8 +947,9 @@ void ppce500_init(MachineState *machine)
qdev_prop_set_uint32(dev, "num_irqs", pmc->platform_bus_num_irqs);
qdev_prop_set_uint32(dev, "mmio_size", pmc->platform_bus_size);
qdev_init_nofail(dev);
- s = SYS_BUS_DEVICE(dev);
+ pms->pbus_dev = PLATFORM_BUS_DEVICE(dev);
+ s = SYS_BUS_DEVICE(pms->pbus_dev);
for (i = 0; i < pmc->platform_bus_num_irqs; i++) {
int irqn = pmc->platform_bus_first_irq + i;
sysbus_connect_irq(s, i, qdev_get_gpio_in(mpicdev, irqn));
@@ -1097,6 +1092,7 @@ static const TypeInfo ppce500_info = {
.name = TYPE_PPCE500_MACHINE,
.parent = TYPE_MACHINE,
.abstract = true,
+ .instance_size = sizeof(PPCE500MachineState),
.class_size = sizeof(PPCE500MachineClass),
};