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.b...@freescale.com>
Reviewed-by: Bhupesh Sharma <bhupesh.sha...@freescale.com>
Cc: Marc Zyngier <marc.zyng...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to