[U-Boot] [PATCH v2 7/9] ARMv8: PSCI: Fixup the device tree for PSCI v0.2
Arnab Basu
arnab_basu at rocketmail.com
Mon Jan 12 21:56:58 CET 2015
Set the enable-method in the cpu node to psci, create the psci
device tree node and also add a reserved-memory for the psci code
that lives in in normal RAM, so that the kernel leaves does not map it
Signed-off-by: Arnab Basu <arnab_basu at rocketmail.com>
Cc: Bhupesh Sharma <bhupesh.sharma at freescale.com>
Cc: Marc Zyngier <marc.zyngier at arm.com>
---
arch/arm/cpu/armv8/cpu-dt.c | 111 ++++++++++++++++++++++++++++++++++++++++++
arch/arm/include/asm/system.h | 4 ++
2 files changed, 115 insertions(+)
diff --git a/arch/arm/cpu/armv8/cpu-dt.c b/arch/arm/cpu/armv8/cpu-dt.c
index ce0e3c6..078a627 100644
--- a/arch/arm/cpu/armv8/cpu-dt.c
+++ b/arch/arm/cpu/armv8/cpu-dt.c
@@ -11,7 +11,113 @@
#ifdef CONFIG_MP
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_ARMV8_PSCI
+static void psci_reserve_mem(void *fdt)
+{
+#ifndef CONFIG_ARMV8_SECURE_BASE
+ int nodeoff;
+ int na, ns;
+ int root;
+
+ root = fdt_path_offset(fdt, "/");
+ if (root < 0)
+ return;
+
+ na = fdt_address_cells(fdt, root);
+ ns = fdt_size_cells(fdt, root);
+
+ nodeoff = fdt_path_offset(fdt, "/reserved-memory");
+ if (nodeoff < 0) {
+ nodeoff = fdt_add_subnode(fdt, root, "reserved-memory");
+ if (nodeoff < 0)
+ return;
+ }
+ fdt_setprop_u32(fdt, nodeoff, "#address-cells", na);
+ fdt_setprop_u32(fdt, nodeoff, "#size-cells", ns);
+ fdt_setprop(fdt, nodeoff, "ranges", 0, 0);
+ nodeoff = fdt_add_subnode(fdt, nodeoff, "psci-area");
+ if (nodeoff < 0)
+ return;
+ fdt_setprop_u64(fdt, nodeoff, "reg", (unsigned long)__secure_start);
+ fdt_appendprop_u64(fdt, nodeoff, "reg",
+ (unsigned long)__secure_end
+ - (unsigned long)__secure_start);
+ fdt_setprop(fdt, nodeoff, "no-map", 0, 0);
+#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;
+
+ /* Not checking rv here, our approach is to skip over errors in
+ * individual cpu nodes, hopefully some of the nodes are
+ * processed correctly and those will boot
+ */
+ fdt_setprop_string(fdt, tmp, "enable-method", "psci");
+ }
+
+ /* The PSCI node might be called "/psci" or might be called something
+ * else but contain either of the compatible strings
+ * "arm,psci"/"arm,psci-0.2"
+ */
+ nodeoff = fdt_path_offset(fdt, "/psci");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci");
+ if (nodeoff >= 0)
+ goto init_psci_node;
+
+ nodeoff = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-0.2");
+ if (nodeoff >= 0)
+ goto init_psci2_node;
+
+ nodeoff = fdt_path_offset(fdt, "/");
+ if (nodeoff < 0)
+ return nodeoff;
+
+ nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
+ if (nodeoff < 0)
+ return nodeoff;
+
+init_psci_node:
+ tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci-0.2");
+ if (tmp)
+ return tmp;
+init_psci2_node:
+ tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
+ if (tmp)
+ return tmp;
+
+ return 0;
+}
+#else
__weak u64 arch_get_release_addr(u64 cpu_id)
{
u64 val;
@@ -68,11 +174,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 89f2294..f3f4ace 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.9.1
More information about the U-Boot
mailing list