aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/virt.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 60736c2062..91e45e04a1 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -288,9 +288,32 @@ static void fdt_add_timer_nodes(const VirtBoardInfo *vbi)
static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
{
int cpu;
+ int addr_cells = 1;
+
+ /*
+ * From Documentation/devicetree/bindings/arm/cpus.txt
+ * On ARM v8 64-bit systems value should be set to 2,
+ * that corresponds to the MPIDR_EL1 register size.
+ * If MPIDR_EL1[63:32] value is equal to 0 on all CPUs
+ * in the system, #address-cells can be set to 1, since
+ * MPIDR_EL1[63:32] bits are not used for CPUs
+ * identification.
+ *
+ * Here we actually don't know whether our system is 32- or 64-bit one.
+ * The simplest way to go is to examine affinity IDs of all our CPUs. If
+ * at least one of them has Aff3 populated, we set #address-cells to 2.
+ */
+ for (cpu = 0; cpu < vbi->smp_cpus; cpu++) {
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
+
+ if (armcpu->mp_affinity & ARM_AFF3_MASK) {
+ addr_cells = 2;
+ break;
+ }
+ }
qemu_fdt_add_subnode(vbi->fdt, "/cpus");
- qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#address-cells", 0x1);
+ qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#address-cells", addr_cells);
qemu_fdt_setprop_cell(vbi->fdt, "/cpus", "#size-cells", 0x0);
for (cpu = vbi->smp_cpus - 1; cpu >= 0; cpu--) {
@@ -307,7 +330,14 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
"enable-method", "psci");
}
- qemu_fdt_setprop_cell(vbi->fdt, nodename, "reg", armcpu->mp_affinity);
+ if (addr_cells == 2) {
+ qemu_fdt_setprop_u64(vbi->fdt, nodename, "reg",
+ armcpu->mp_affinity);
+ } else {
+ qemu_fdt_setprop_cell(vbi->fdt, nodename, "reg",
+ armcpu->mp_affinity);
+ }
+
g_free(nodename);
}
}