From dd9439fbace2196c24d90b9274a6014418d5b413 Mon Sep 17 00:00:00 2001
From: Bin Meng <bmeng.cn@gmail.com>
Date: Tue, 17 Mar 2020 07:59:48 -0700
Subject: lib: utils: Add a fdt_cpu_fixup() helper

Add a helper routine to updates the "status" property of a CPU node
in the device tree to "disabled" if that hart is in disabled state.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
---
 include/sbi_utils/fdt/fdt_helper.h | 12 ++++++++++++
 lib/utils/fdt/fdt_helper.c         | 26 ++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 67251f8..d3b065a 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -9,6 +9,18 @@
 #ifndef __FDT_HELPER_H__
 #define __FDT_HELPER_H__
 
+/**
+ * Fix up the CPU node in the device tree
+ *
+ * This routine updates the "status" property of a CPU node in the device tree
+ * to "disabled" if that hart is in disabled state in OpenSBI.
+ *
+ * It is recommended that platform codes call this helper in their final_init()
+ *
+ * @param fdt: device tree blob
+ */
+void fdt_cpu_fixup(void *fdt);
+
 /**
  * Fix up the PLIC node in the device tree
  *
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index fcae968..4ef7a5e 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -12,6 +12,32 @@
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_scratch.h>
 
+void fdt_cpu_fixup(void *fdt)
+{
+	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
+	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
+	char cpu_node[32] = "";
+	int cpu_offset;
+	int err;
+	u32 i;
+
+	err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 32);
+	if (err < 0)
+		return;
+
+	/* assume hart ids are continuous */
+	for (i = 0; i < sbi_platform_hart_count(plat); i++) {
+		sbi_sprintf(cpu_node, "/cpus/cpu@%d", i);
+		cpu_offset = fdt_path_offset(fdt, cpu_node);
+
+		if (sbi_platform_hart_disabled(plat, i))
+			fdt_setprop_string(fdt, cpu_offset, "status",
+					   "disabled");
+
+		memset(cpu_node, 0, sizeof(cpu_node));
+	}
+}
+
 void fdt_plic_fixup(void *fdt, const char *compat)
 {
 	u32 *cells;
-- 
cgit v1.2.3