[U-Boot] [PATCH 6/8] ARMv8: PSCI: Fixup the device tree for PSCI v0.2

Arnab Basu
2014-08-27T20:29:59Z

Set the enable-method in the cpu node to psci, create the psci
device tree node and also add a reserve section for the psci code
that lives in in normal RAM, so that the kernel leaves it alone

Signed-off-by: Arnab Basu <arnab.basu@freescale.com>
Reviewed-by: Bhupesh Sharma <bhupesh.sharma@freescale.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/cpu/armv8/cpu-dt.c | 67 +++++++++++++++++++++++++++++++++++++++++
arch/arm/include/asm/system.h | 4 ++
2 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/armv8/cpu-dt.c b/arch/arm/cpu/armv8/cpu-dt.c
index 9792bc0..c2c8fe7 100644
--- a/arch/arm/cpu/armv8/cpu-dt.c
+++ b/arch/arm/cpu/armv8/cpu-dt.c
@@ -9,7 +9,69 @@
#include <fdt_support.h>

#ifdef CONFIG_MP
+#ifdef CONFIG_ARMV8_PSCI

+static void psci_reserve_mem(void *fdt)
+{
+#ifndef CONFIG_ARMV8_SECURE_BASE
+ /* secure code lives in RAM, keep it alive */
+ fdt_add_mem_rsv(fdt, (unsigned long)__secure_start,
+ __secure_end - __secure_start);
+#endif
+}
+
+static int cpu_update_dt_psci(void *fdt)
+{
+ int nodeoff;
+ int tmp;
+
+ psci_reserve_mem(fdt);
+
+ nodeoff = fdt_path_offset(fdt, "/cpus");
+ if (nodeoff < 0) {
+ printf("couldn't find /cpus\n");
+ return nodeoff;
+ }
+
+ /* add 'enable-method = "psci"' to each cpu node */
+ for (tmp = fdt_first_subnode(fdt, nodeoff);
+ tmp >= 0;
+ tmp = fdt_next_subnode(fdt, tmp)) {
+ const struct fdt_property *prop;
+ int len;
+
+ prop = fdt_get_property(fdt, tmp, "device_type", &len);
+ if (!prop)
+ continue;
+ if (len < 4)
+ continue;
+ if (strcmp(prop->data, "cpu"))
+ continue;
+
+ fdt_setprop_string(fdt, tmp, "enable-method", "psci");
+ }
+
+ nodeoff = fdt_path_offset(fdt, "/psci");
+ if (nodeoff < 0) {
+ nodeoff = fdt_path_offset(fdt, "/");
+ if (nodeoff < 0)
+ return nodeoff;
+
+ nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
+ if (nodeoff < 0)
+ return nodeoff;
+ }
+
+ tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci-0.2");
+ if (tmp)
+ return tmp;
+ tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
+ if (tmp)
+ return tmp;
+
+ return 0;
+}
+#else
__weak u64 arch_get_release_addr(u64 cpu_id)
{
return 0;
@@ -51,11 +113,16 @@ static void cpu_update_dt_spin_table(void *blob)
arch_spin_table_reserve_mem(blob);
}
#endif
+#endif

int cpu_update_dt(void *fdt)
{
#ifdef CONFIG_MP
+#ifdef CONFIG_ARMV8_PSCI
+ cpu_update_dt_psci(fdt);
+#else
cpu_update_dt_spin_table(fdt);
#endif
+#endif
return 0;
}
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index d51ba66..a1066d4 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -77,6 +77,10 @@ void gic_init(void);
void gic_send_sgi(unsigned long sgino);
void wait_for_wakeup(void);
void smp_kick_all_cpus(void);
+#ifdef CONFIG_ARMV8_PSCI
+extern char __secure_start[];
+extern char __secure_end[];
+#endif

void flush_l3_cache(void);

--
1.7.7.4