aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Fedin <p.fedin@samsung.com>2015-09-07 10:39:31 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-09-07 10:39:31 +0100
commit8d45c54d4fd3612bd616afcc5c278394f312927b (patch)
tree29cc92b2627a00b5732f1c10fce87c29d3ab15c0
parent0f4a9e45ec35811ee250ac232d84d3c6d4fcd7fc (diff)
arm/virt: Add full-sized CPU affinity handling
At least with KVM, currently there's no reason why QEMU would not be capable of handling Aff3 != 0. This commit fixes up FDT creation in such a case. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> Message-id: eef5a86e6d9a313780dbc23b35fcb65df42a3e9e.1441366248.git.p.fedin@samsung.com [PMM: folded two overlong lines] Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-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);
}
}