[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 01/30] vexpress: Set reset-cbar property for CPUs
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PULL 01/30] vexpress: Set reset-cbar property for CPUs |
Date: |
Mon, 17 Mar 2014 22:11:52 +0000 |
Newer versions of the Linux kernel (as of commit bc41b8724 in 3.12)
now assume that if the CPU is a Cortex-A9 and the reset value of the
PERIPHBASE/CBAR register is zero then the CPU is a specific buggy
single core A9 SoC, and will not try to start other cores. Since we
now have a CPU property for the reset value of the CBAR, we can
just fix the vexpress board model to correctly set CBAR so SMP
works again. To avoid duplicate boilerplate code in both the A9
and A15 daughterboard init functions, we split out the CPU and
private memory region init to its own function.
Signed-off-by: Peter Maydell <address@hidden>
Reported-by: Rob Herring <address@hidden>
Reviewed-by: Peter Crosthwaite <address@hidden>
Message-id: address@hidden
---
hw/arm/vexpress.c | 123 +++++++++++++++++++++++++++---------------------------
1 file changed, 61 insertions(+), 62 deletions(-)
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index ef1707a..67628af 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: */
--
1.9.0
- [Qemu-devel] [PULL 23/30] target-arm: A64: Implement FCVTZS, FCVTZU in the shift-imm categories, (continued)
- [Qemu-devel] [PULL 23/30] target-arm: A64: Implement FCVTZS, FCVTZU in the shift-imm categories, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 17/30] target-arm: A64: List unsupported shift-imm opcodes, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 27/30] target-arm: A64: Implement scalar saturating narrow ops, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 30/30] scripts/qemu-binfmt-conf.sh: Add AArch64 registration, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 11/30] target-arm: A64: Saturating and narrowing shift ops, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 20/30] target-arm: A64: Implement FRINT*, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 29/30] target-arm: A64: Add [UF]RSQRTE (reciprocal root estimate), Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 15/30] target-arm: A64: Implement FCVTN, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 08/30] target-arm: A64: Add last AdvSIMD Integer to FP ops, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 24/30] softfloat: export squash_input_denormal functions, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 01/30] vexpress: Set reset-cbar property for CPUs,
Peter Maydell <=
- [Qemu-devel] [PULL 18/30] target-arm: A64: Add FRECPX (reciprocal exponent), Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 28/30] target-arm: A64: Implement FCVTXN, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 25/30] target-arm: A64: Implement AdvSIMD reciprocal estimate insns URECPE, FRECPE, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 26/30] target-arm: A64: Move handle_2misc_narrow function, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 04/30] virt: Set reset-cbar on CPUs, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 21/30] exec-all.h: Increase MAX_OP_PER_INSTR for ARM A64 decoder, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 02/30] realview-pbx-a9: Set reset-cbar property for CPUs, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 06/30] target-arm: A64: Implement PMULL instruction, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 05/30] target-arm: Add ARM_CP_IO notation to PMCR reginfo, Peter Maydell, 2014/03/17
- [Qemu-devel] [PULL 19/30] target-arm: A64: Implement SRI, Peter Maydell, 2014/03/17