diff options
Diffstat (limited to 'hw/arm')
-rw-r--r-- | hw/arm/exynos4210.c | 16 | ||||
-rw-r--r-- | hw/arm/realview.c | 39 | ||||
-rw-r--r-- | hw/arm/vexpress.c | 123 | ||||
-rw-r--r-- | hw/arm/virt.c | 6 |
4 files changed, 109 insertions, 75 deletions
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 9f137e9acd..6426d168d2 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -143,11 +143,21 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem, unsigned long mem_size; DeviceState *dev; SysBusDevice *busdev; + ObjectClass *cpu_oc; + + cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, "cortex-a9"); + assert(cpu_oc); for (n = 0; n < EXYNOS4210_NCPUS; n++) { - s->cpu[n] = cpu_arm_init("cortex-a9"); - if (!s->cpu[n]) { - fprintf(stderr, "Unable to find CPU %d definition\n", n); + Object *cpuobj = object_new(object_class_get_name(cpu_oc)); + Error *err = NULL; + + s->cpu[n] = ARM_CPU(cpuobj); + object_property_set_int(cpuobj, EXYNOS4210_SMP_PRIVATE_BASE_ADDR, + "reset-cbar", &error_abort); + object_property_set_bool(cpuobj, true, "realized", &err); + if (err) { + error_report("%s", error_get_pretty(err)); exit(1); } } diff --git a/hw/arm/realview.c b/hw/arm/realview.c index 6ef7646002..7e04e507f9 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -18,6 +18,7 @@ #include "hw/i2c/i2c.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" +#include "qemu/error-report.h" #define SMP_BOOT_ADDR 0xe0000000 #define SMP_BOOTREG_ADDR 0x10000030 @@ -49,6 +50,7 @@ static void realview_init(QEMUMachineInitArgs *args, { ARMCPU *cpu = NULL; CPUARMState *env; + ObjectClass *cpu_oc; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram_lo = g_new(MemoryRegion, 1); MemoryRegion *ram_hi = g_new(MemoryRegion, 1); @@ -70,12 +72,14 @@ static void realview_init(QEMUMachineInitArgs *args, uint32_t sys_id; ram_addr_t low_ram_size; ram_addr_t ram_size = args->ram_size; + hwaddr periphbase = 0; switch (board_type) { case BOARD_EB: break; case BOARD_EB_MPCORE: is_mpcore = 1; + periphbase = 0x10100000; break; case BOARD_PB_A8: is_pb = 1; @@ -83,16 +87,37 @@ static void realview_init(QEMUMachineInitArgs *args, case BOARD_PBX_A9: is_mpcore = 1; is_pb = 1; + periphbase = 0x1f000000; break; } + + cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, args->cpu_model); + if (!cpu_oc) { + fprintf(stderr, "Unable to find CPU definition\n"); + exit(1); + } + for (n = 0; n < smp_cpus; n++) { - cpu = cpu_arm_init(args->cpu_model); - if (!cpu) { - fprintf(stderr, "Unable to find CPU definition\n"); + Object *cpuobj = object_new(object_class_get_name(cpu_oc)); + Error *err = NULL; + + if (is_pb && is_mpcore) { + object_property_set_int(cpuobj, periphbase, "reset-cbar", &err); + if (err) { + error_report("%s", error_get_pretty(err)); + exit(1); + } + } + + object_property_set_bool(cpuobj, true, "realized", &err); + if (err) { + error_report("%s", error_get_pretty(err)); exit(1); } - cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ); + + cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpuobj), ARM_CPU_IRQ); } + cpu = ARM_CPU(first_cpu); env = &cpu->env; if (arm_feature(env, ARM_FEATURE_V7)) { if (is_mpcore) { @@ -141,16 +166,10 @@ static void realview_init(QEMUMachineInitArgs *args, sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000); if (is_mpcore) { - hwaddr periphbase; dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore"); qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); - if (is_pb) { - periphbase = 0x1f000000; - } else { - periphbase = 0x10100000; - } sysbus_mmio_map(busdev, 0, periphbase); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index ef1707aef0..67628af588 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -32,6 +32,7 @@ #include "sysemu/blockdev.h" #include "hw/block/flash.h" #include "sysemu/device_tree.h" +#include "qemu/error-report.h" #include <libfdt.h> #define VEXPRESS_BOARD_ID 0x8e0 @@ -173,6 +174,64 @@ struct VEDBoardInfo { DBoardInitFn *init; }; +static void init_cpus(const char *cpu_model, const char *privdev, + hwaddr periphbase, qemu_irq *pic) +{ + ObjectClass *cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); + DeviceState *dev; + SysBusDevice *busdev; + int n; + + if (!cpu_oc) { + fprintf(stderr, "Unable to find CPU definition\n"); + exit(1); + } + + /* Create the actual CPUs */ + for (n = 0; n < smp_cpus; n++) { + Object *cpuobj = object_new(object_class_get_name(cpu_oc)); + Error *err = NULL; + + object_property_set_int(cpuobj, periphbase, "reset-cbar", &err); + if (err) { + error_report("%s", error_get_pretty(err)); + exit(1); + } + object_property_set_bool(cpuobj, true, "realized", &err); + if (err) { + error_report("%s", error_get_pretty(err)); + exit(1); + } + } + + /* Create the private peripheral devices (including the GIC); + * this must happen after the CPUs are created because a15mpcore_priv + * wires itself up to the CPU's generic_timer gpio out lines. + */ + dev = qdev_create(NULL, privdev); + qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); + qdev_init_nofail(dev); + busdev = SYS_BUS_DEVICE(dev); + sysbus_mmio_map(busdev, 0, periphbase); + + /* Interrupts [42:0] are from the motherboard; + * [47:43] are reserved; [63:48] are daughterboard + * peripherals. Note that some documentation numbers + * external interrupts starting from 32 (because there + * are internal interrupts 0..31). + */ + for (n = 0; n < 64; n++) { + pic[n] = qdev_get_gpio_in(dev, n); + } + + /* Connect the CPUs to the GIC */ + for (n = 0; n < smp_cpus; n++) { + DeviceState *cpudev = DEVICE(qemu_get_cpu(n)); + + sysbus_connect_irq(busdev, n, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); + } +} + static void a9_daughterboard_init(const VEDBoardInfo *daughterboard, ram_addr_t ram_size, const char *cpu_model, @@ -181,25 +240,12 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard, MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *lowram = g_new(MemoryRegion, 1); - DeviceState *dev; - SysBusDevice *busdev; - int n; - qemu_irq cpu_irq[4]; ram_addr_t low_ram_size; if (!cpu_model) { cpu_model = "cortex-a9"; } - for (n = 0; n < smp_cpus; n++) { - ARMCPU *cpu = cpu_arm_init(cpu_model); - if (!cpu) { - fprintf(stderr, "Unable to find CPU definition\n"); - exit(1); - } - cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ); - } - if (ram_size > 0x40000000) { /* 1GB is the maximum the address space permits */ fprintf(stderr, "vexpress-a9: cannot model more than 1GB RAM\n"); @@ -221,23 +267,7 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard, memory_region_add_subregion(sysmem, 0x60000000, ram); /* 0x1e000000 A9MPCore (SCU) private memory region */ - dev = qdev_create(NULL, "a9mpcore_priv"); - qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); - qdev_init_nofail(dev); - busdev = SYS_BUS_DEVICE(dev); - sysbus_mmio_map(busdev, 0, 0x1e000000); - for (n = 0; n < smp_cpus; n++) { - sysbus_connect_irq(busdev, n, cpu_irq[n]); - } - /* Interrupts [42:0] are from the motherboard; - * [47:43] are reserved; [63:48] are daughterboard - * peripherals. Note that some documentation numbers - * external interrupts starting from 32 (because the - * A9MP has internal interrupts 0..31). - */ - for (n = 0; n < 64; n++) { - pic[n] = qdev_get_gpio_in(dev, n); - } + init_cpus(cpu_model, "a9mpcore_priv", 0x1e000000, pic); /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */ @@ -296,29 +326,14 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard, const char *cpu_model, qemu_irq *pic) { - int n; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *sram = g_new(MemoryRegion, 1); - qemu_irq cpu_irq[4]; - DeviceState *dev; - SysBusDevice *busdev; if (!cpu_model) { cpu_model = "cortex-a15"; } - for (n = 0; n < smp_cpus; n++) { - ARMCPU *cpu; - - cpu = cpu_arm_init(cpu_model); - if (!cpu) { - fprintf(stderr, "Unable to find CPU definition\n"); - exit(1); - } - cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ); - } - { /* We have to use a separate 64 bit variable here to avoid the gcc * "comparison is always false due to limited range of data type" @@ -337,23 +352,7 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard, memory_region_add_subregion(sysmem, 0x80000000, ram); /* 0x2c000000 A15MPCore private memory region (GIC) */ - dev = qdev_create(NULL, "a15mpcore_priv"); - qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); - qdev_init_nofail(dev); - busdev = SYS_BUS_DEVICE(dev); - sysbus_mmio_map(busdev, 0, 0x2c000000); - for (n = 0; n < smp_cpus; n++) { - sysbus_connect_irq(busdev, n, cpu_irq[n]); - } - /* Interrupts [42:0] are from the motherboard; - * [47:43] are reserved; [63:48] are daughterboard - * peripherals. Note that some documentation numbers - * external interrupts starting from 32 (because there - * are internal interrupts 0..31). - */ - for (n = 0; n < 64; n++) { - pic[n] = qdev_get_gpio_in(dev, n); - } + init_cpus(cpu_model, "a15mpcore_priv", 0x2c000000, pic); /* A15 daughterboard peripherals: */ diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 517f2fe30f..2bbc9313d2 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -390,6 +390,12 @@ static void machvirt_init(QEMUMachineInitArgs *args) if (n > 0) { object_property_set_bool(cpuobj, true, "start-powered-off", NULL); } + + if (object_property_find(cpuobj, "reset-cbar", NULL)) { + object_property_set_int(cpuobj, vbi->memmap[VIRT_CPUPERIPHS].base, + "reset-cbar", &error_abort); + } + object_property_set_bool(cpuobj, true, "realized", NULL); } fdt_add_cpu_nodes(vbi); |