From: Alexander Graf <agraf@xxxxxxx> Now platform_bus_init_notify and functions it calls were moved to dyn_sysbus_binding.c, remove those functions from e500. PPCE500Params includes a DynSysbusParams struct which contains the settings related to platform device instantiation. Signed-off-by: Eric Auger <eric.auger@xxxxxxxxxx> --- v2 -> v3: - Modify e500.c to use platform_bus_init_notify now implemented in dyn_sysbus_binding - new DynSysbusParams that contains dynamic sysbus settings - PPCE500Params includes a DynSysbusParams struct --- hw/ppc/e500.c | 183 ++++-------------------------------------------------- hw/ppc/e500.h | 7 +-- hw/ppc/e500plat.c | 13 ++-- 3 files changed, 22 insertions(+), 181 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index fe9497a..0741412 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -38,6 +38,7 @@ #include "hw/pci-host/ppce500.h" #include "qemu/error-report.h" #include "hw/net/fsl_etsec/etsec.h" +#include "hw/misc/dyn_sysbus_binding.h" #define EPAPR_MAGIC (0x45504150) #define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb" @@ -196,13 +197,14 @@ static int sysbus_device_create_devtree(Object *obj, void *opaque) static void platform_bus_create_devtree(PPCE500Params *params, void *fdt, const char *mpic) { - gchar *node = g_strdup_printf("/platform@%"PRIx64, params->platform_bus_base); + gchar *node = g_strdup_printf("/platform@%"PRIx64, + params->dyn_sysbus_params.platform_bus_base); const char platcomp[] = "qemu,platform\0simple-bus"; PlatformDevtreeData data; Object *container; - uint64_t addr = params->platform_bus_base; - uint64_t size = params->platform_bus_size; - int irq_start = params->platform_bus_first_irq; + uint64_t addr = params->dyn_sysbus_params.platform_bus_base; + uint64_t size = params->dyn_sysbus_params.platform_bus_size; + int irq_start = params->dyn_sysbus_params.platform_bus_first_irq; /* Create a /platform node that we can put all devices into */ @@ -489,7 +491,7 @@ static int ppce500_load_device_tree(MachineState *machine, qemu_fdt_setprop_cell(fdt, pci, "#address-cells", 3); qemu_fdt_setprop_string(fdt, "/aliases", "pci0", pci); - if (params->has_platform_bus) { + if (params->dyn_sysbus_params.has_platform_bus) { platform_bus_create_devtree(params, fdt, mpic); } @@ -732,169 +734,6 @@ static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr, return mpic; } -typedef struct PlatformBusNotifier { - Notifier notifier; - MemoryRegion *address_space_mem; - qemu_irq *mpic; - PPCE500Params params; -} PlatformBusNotifier; - -typedef struct PlatformBusInitData { - unsigned long *used_irqs; - unsigned long *used_mem; - MemoryRegion *mem; - qemu_irq *irqs; - int device_count; - PPCE500Params *params; -} PlatformBusInitData; - -static int platform_bus_map_irq(PPCE500Params *params, SysBusDevice *sbdev, - int n, unsigned long *used_irqs, - qemu_irq *platform_irqs) -{ - int max_irqs = params->platform_bus_num_irqs; - char *prop = g_strdup_printf("irq[%d]", n); - int irqn = object_property_get_int(OBJECT(sbdev), prop, NULL); - - if (irqn == SYSBUS_DYNAMIC) { - /* Find the first available IRQ */ - irqn = find_first_zero_bit(used_irqs, max_irqs); - } - - if ((irqn >= max_irqs) || test_and_set_bit(irqn, used_irqs)) { - hw_error("e500: IRQ %d is already allocated or no free IRQ left", irqn); - } - - sysbus_connect_irq(sbdev, n, platform_irqs[irqn]); - object_property_set_int(OBJECT(sbdev), irqn, prop, NULL); - - g_free(prop); - return 0; -} - -static int platform_bus_map_mmio(PPCE500Params *params, SysBusDevice *sbdev, - int n, unsigned long *used_mem, - MemoryRegion *pmem) -{ - MemoryRegion *device_mem = sbdev->mmio[n].memory; - uint64_t size = memory_region_size(device_mem); - uint64_t page_size = (1 << E500_PLATFORM_BUS_PAGE_SHIFT); - uint64_t page_mask = page_size - 1; - uint64_t size_pages = (size + page_mask) >> E500_PLATFORM_BUS_PAGE_SHIFT; - uint64_t max_size = params->platform_bus_size; - uint64_t max_pages = max_size >> E500_PLATFORM_BUS_PAGE_SHIFT; - char *prop = g_strdup_printf("mmio[%d]", n); - hwaddr addr = object_property_get_int(OBJECT(sbdev), prop, NULL); - int page; - int i; - - page = addr >> E500_PLATFORM_BUS_PAGE_SHIFT; - if (addr == SYSBUS_DYNAMIC) { - uint64_t size_pages_align; - - /* Align the region to at least its own size granularity */ - if (is_power_of_2(size_pages)) { - size_pages_align = size_pages; - } else { - size_pages_align = pow2floor(size_pages) << 1; - } - - /* Find the first available region that fits */ - page = bitmap_find_next_zero_area(used_mem, max_pages, 0, size_pages, - size_pages_align); - - addr = (uint64_t)page << E500_PLATFORM_BUS_PAGE_SHIFT; - } - - if (page >= max_pages || test_bit(page, used_mem) || - (find_next_bit(used_mem, max_pages, page) < size_pages)) { - hw_error("e500: Memory [%"PRIx64":%"PRIx64" is already allocated or " - "no slot left", addr, size); - } - - for (i = page; i < (page + size_pages); i++) { - set_bit(i, used_mem); - } - - memory_region_add_subregion(pmem, addr, device_mem); - sbdev->mmio[n].addr = addr; - object_property_set_int(OBJECT(sbdev), addr, prop, NULL); - - g_free(prop); - return 0; -} - -static int sysbus_device_check(Object *obj, void *opaque) -{ - PlatformBusInitData *init = opaque; - Object *dev; - SysBusDevice *sbdev; - int i; - - dev = object_dynamic_cast(obj, TYPE_SYS_BUS_DEVICE); - sbdev = (SysBusDevice *)dev; - - if (!sbdev) { - /* Container, traverse it for children */ - return object_child_foreach(obj, sysbus_device_check, opaque); - } - - /* Connect sysbus device to virtual platform bus */ - for (i = 0; i < sbdev->num_irq; i++) { - if (!sbdev->irqp[i]) { - /* This IRQ is an incoming IRQ, we can't wire those here */ - continue; - } - platform_bus_map_irq(init->params, sbdev, i, init->used_irqs, init->irqs); - } - - for (i = 0; i < sbdev->num_mmio; i++) { - platform_bus_map_mmio(init->params, sbdev, i, init->used_mem, init->mem); - } - - return 0; -} - -static void platform_bus_init(PPCE500Params *params, - MemoryRegion *address_space_mem, - qemu_irq *mpic) -{ - uint64_t max_size = params->platform_bus_size; - uint64_t max_pages = max_size >> E500_PLATFORM_BUS_PAGE_SHIFT; - DECLARE_BITMAP(used_irqs, params->platform_bus_num_irqs); - DECLARE_BITMAP(used_mem, max_pages); - MemoryRegion *platform_region = g_new(MemoryRegion, 1); - Object *container; - PlatformBusInitData init = { - .used_irqs = used_irqs, - .used_mem = used_mem, - .mem = platform_region, - .irqs = &mpic[params->platform_bus_first_irq], - .params = params, - }; - - memory_region_init(platform_region, NULL, "platform devices", - params->platform_bus_size); - - bitmap_clear(used_irqs, 0, params->platform_bus_num_irqs); - bitmap_clear(used_mem, 0, max_pages); - - /* Loop through all sysbus devices that were spawened outside the machine */ - container = container_get(qdev_get_machine(), "/peripheral"); - sysbus_device_check(container, &init); - container = container_get(qdev_get_machine(), "/peripheral-anon"); - sysbus_device_check(container, &init); - - memory_region_add_subregion(address_space_mem, params->platform_bus_base, - platform_region); -} - -static void platform_bus_init_notify(Notifier *notifier, void *data) -{ - PlatformBusNotifier *pn = (PlatformBusNotifier *)notifier; - platform_bus_init(&pn->params, pn->address_space_mem, pn->mpic); -} - void ppce500_init(MachineState *machine, PPCE500Params *params) { MemoryRegion *address_space_mem = get_system_memory(); @@ -1047,13 +886,15 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) } /* Platform Devices */ - if (params->has_platform_bus) { - PlatformBusNotifier *notifier = g_new(PlatformBusNotifier, 1); + if (params->dyn_sysbus_params.has_platform_bus) { + DynSysbusNotifier *notifier = g_new(DynSysbusNotifier, 1); + params->dyn_sysbus_params.page_shift = + E500_PLATFORM_BUS_PAGE_SHIFT; notifier->notifier.notify = platform_bus_init_notify; notifier->address_space_mem = address_space_mem; notifier->mpic = mpic; - notifier->params = *params; + notifier->params = params->dyn_sysbus_params; qemu_add_machine_init_done_notifier(¬ifier->notifier); } diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h index f1b2766..c191f9d 100644 --- a/hw/ppc/e500.h +++ b/hw/ppc/e500.h @@ -2,6 +2,7 @@ #define PPCE500_H #include "hw/boards.h" +#include "hw/misc/dyn_sysbus_binding.h" typedef struct PPCE500Params { int pci_first_slot; @@ -11,11 +12,7 @@ typedef struct PPCE500Params { void (*fixup_devtree)(struct PPCE500Params *params, void *fdt); int mpic_version; - bool has_platform_bus; - hwaddr platform_bus_base; - hwaddr platform_bus_size; - int platform_bus_first_irq; - int platform_bus_num_irqs; + DynSysbusParams dyn_sysbus_params; } PPCE500Params; void ppce500_init(MachineState *machine, PPCE500Params *params); diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c index befe1d1..4150a2c 100644 --- a/hw/ppc/e500plat.c +++ b/hw/ppc/e500plat.c @@ -35,11 +35,14 @@ static void e500plat_init(MachineState *machine) .pci_nr_slots = PCI_SLOT_MAX - 1, .fixup_devtree = e500plat_fixup_devtree, .mpic_version = OPENPIC_MODEL_FSL_MPIC_42, - .has_platform_bus = true, - .platform_bus_base = 0xf00000000ULL, - .platform_bus_size = (128ULL * 1024 * 1024), - .platform_bus_first_irq = 5, - .platform_bus_num_irqs = 10, + .dyn_sysbus_params = { + .has_platform_bus = true, + .platform_bus_base = 0xf00000000ULL, + .platform_bus_size = (128ULL * 1024 * 1024), + .platform_bus_first_irq = 5, + .platform_bus_num_irqs = 10, + .page_shift = 12 /* default */ + } }; /* Older KVM versions don't support EPR which breaks guests when we announce -- 1.8.3.2 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm