[PATCH v3 5/7] lib: utils/fdt: Used cached CPU DT information

Samuel Holland samuel.holland at sifive.com
Wed Oct 14 04:30:22 PDT 2026


Use the cached information to look up the DT node offset of a hart, or
the hart index from a DT phandle, instead of parsing the DT each time.

The logic should otherwise be equivalent.

Signed-off-by: Samuel Holland <samuel.holland at sifive.com>
---

Changes in v3:
 - Do not use cached offsets in fdt_domain_fixup()
 - Also use the cache in CMO library and TMC0 driver

Changes in v2:
 - Add missing include of fdt_cpu.h in fdt_helper.c

 lib/utils/cache/fdt_cmo_helper.c    | 21 +++++----------
 lib/utils/fdt/fdt_domain.c          | 41 +++++++++--------------------
 lib/utils/fdt/fdt_helper.c          | 24 +++++------------
 lib/utils/hsm/fdt_hsm_sifive_tmc0.c | 23 +++++-----------
 4 files changed, 32 insertions(+), 77 deletions(-)

diff --git a/lib/utils/cache/fdt_cmo_helper.c b/lib/utils/cache/fdt_cmo_helper.c
index bdc5fe19..28034d51 100644
--- a/lib/utils/cache/fdt_cmo_helper.c
+++ b/lib/utils/cache/fdt_cmo_helper.c
@@ -10,6 +10,7 @@
 #include <sbi/sbi_scratch.h>
 #include <sbi_utils/cache/fdt_cache.h>
 #include <sbi_utils/cache/fdt_cmo_helper.h>
+#include <sbi_utils/fdt/fdt_cpu.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 
 static unsigned long flc_offset;
@@ -67,22 +68,12 @@ int fdt_cmo_llc_enable(bool enable)
 
 static int fdt_cmo_cold_init(const void *fdt)
 {
-	struct sbi_scratch *scratch;
 	struct cache_device *dev;
-	int cpu_offset, cpus_offset, rc;
-	u32 hartid;
+	int cpu_offset, rc;
 
-	cpus_offset = fdt_path_offset(fdt, "/cpus");
-	if (cpus_offset < 0)
-		return SBI_EINVAL;
-
-	fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
-		rc = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
-		if (rc)
-			continue;
-
-		scratch = sbi_hartid_to_scratch(hartid);
-		if (!scratch)
+	sbi_for_each_hartindex(i) {
+		cpu_offset = fdt_cpu_hartindex_to_offset(i);
+		if (cpu_offset < 0)
 			continue;
 
 		rc = fdt_next_cache_get(fdt, cpu_offset, &dev);
@@ -91,7 +82,7 @@ static int fdt_cmo_cold_init(const void *fdt)
 		if (rc == SBI_ENOENT)
 			dev = NULL;
 
-		set_hart_flc(scratch, dev);
+		set_hart_flc(sbi_hartindex_to_scratch(i), dev);
 	}
 
 	return SBI_OK;
diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
index 575fbdf0..f143d514 100644
--- a/lib/utils/fdt/fdt_domain.c
+++ b/lib/utils/fdt/fdt_domain.c
@@ -16,6 +16,7 @@
 #include <sbi/sbi_hartmask.h>
 #include <sbi/sbi_heap.h>
 #include <sbi/sbi_scratch.h>
+#include <sbi_utils/fdt/fdt_cpu.h>
 #include <sbi_utils/fdt/fdt_domain.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 
@@ -296,6 +297,7 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
 {
 	u32 val32;
 	u64 val64;
+	u32 hartindex;
 	const u32 *val;
 	const char *inherit;
 	struct sbi_domain *dom;
@@ -303,7 +305,7 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
 	struct parse_region_data preg;
 	struct sbi_domain_memregion *reg;
 	int inheritance_mode = FDT_ROOT_REGION_INHERIT_M_ONLY;
-	int i, err = 0, len, cpu_offset;
+	int err = 0, len;
 
 	dom = sbi_zalloc(sizeof(*dom));
 	if (!dom)
@@ -342,25 +344,11 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
 	SBI_HARTMASK_INIT(mask);
 	dom->possible_harts = mask;
 	val = fdt_getprop(fdt, domain_offset, "possible-harts", &len);
-	len = len / sizeof(u32);
-	if (val && len) {
-		for (i = 0; i < len; i++) {
-			cpu_offset = fdt_node_offset_by_phandle(fdt,
-							fdt32_to_cpu(val[i]));
-			if (cpu_offset < 0) {
-				err = cpu_offset;
-				goto fail_free_all;
-			}
-
-			err = fdt_parse_hart_id(fdt, cpu_offset, &val32);
-			if (err)
-				goto fail_free_all;
-
-			if (!fdt_node_is_enabled(fdt, cpu_offset))
-				continue;
-
-			sbi_hartmask_set_hartid(val32, mask);
-		}
+	len = val ? len / sizeof(u32) : 0;
+	for (int i = 0; i < len; i++) {
+		hartindex = fdt_cpu_phandle_to_hartindex(fdt32_to_cpu(val[i]));
+		if (sbi_hartindex_valid(hartindex))
+			sbi_hartmask_set_hartindex(hartindex, mask);
 	}
 
 	/* Setup memregions from DT */
@@ -414,15 +402,12 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
 	dom->fw_region_inited = root.fw_region_inited;
 
 	/* Read "boot-hart" DT property */
-	val32 = current_hartid();
 	val = fdt_getprop(fdt, domain_offset, "boot-hart", &len);
-	if (val && len >= 4) {
-		cpu_offset = fdt_node_offset_by_phandle(fdt,
-							 fdt32_to_cpu(*val));
-		if (cpu_offset >= 0 && fdt_node_is_enabled(fdt, cpu_offset))
-			fdt_parse_hart_id(fdt, cpu_offset, &val32);
-	}
-	dom->boot_hartid = val32;
+	if (val && len >= 4)
+		hartindex = fdt_cpu_phandle_to_hartindex(fdt32_to_cpu(*val));
+	else
+		hartindex = current_hartindex();
+	dom->boot_hartid = sbi_hartindex_to_hartid(hartindex);
 
 	/* Read "next-arg1" DT property */
 	val64 = 0;
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index c5d76707..34369a62 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -14,6 +14,7 @@
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_hart.h>
+#include <sbi_utils/fdt/fdt_cpu.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/irqchip/aplic.h>
 #include <sbi_utils/irqchip/imsic.h>
@@ -397,32 +398,19 @@ static void fdt_parse_isa_extensions_one_hart(const char *isa,
 
 int fdt_parse_isa_extensions_all_harts(const void *fdt)
 {
-	u32 hartid;
 	const fdt32_t *val;
-	struct sbi_scratch *scratch;
 	struct sbi_hart_features *hfeatures;
-	int err, cpu_offset, cpus_offset, len;
+	int err, cpu_offset, len;
 
 	if (!fdt)
 		return SBI_EINVAL;
 
-	cpus_offset = fdt_path_offset(fdt, "/cpus");
-	if (cpus_offset < 0)
-		return cpus_offset;
-
-	fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
-		err = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
-		if (err)
-			continue;
-
-		if (!fdt_node_is_enabled(fdt, cpu_offset))
+	sbi_for_each_hartindex(i) {
+		cpu_offset = fdt_cpu_hartindex_to_offset(i);
+		if (cpu_offset < 0)
 			continue;
 
-		scratch = sbi_hartid_to_scratch(hartid);
-		if (!scratch)
-			return SBI_ENOENT;
-
-		hfeatures = sbi_hart_features_ptr(scratch);
+		hfeatures = sbi_hart_features_ptr(sbi_hartindex_to_scratch(i));
 		if (!hfeatures)
 			return SBI_ENOENT;
 
diff --git a/lib/utils/hsm/fdt_hsm_sifive_tmc0.c b/lib/utils/hsm/fdt_hsm_sifive_tmc0.c
index 911f55b1..79c50a7b 100644
--- a/lib/utils/hsm/fdt_hsm_sifive_tmc0.c
+++ b/lib/utils/hsm/fdt_hsm_sifive_tmc0.c
@@ -16,6 +16,7 @@
 #include <sbi/sbi_ipi.h>
 #include <sbi/sbi_list.h>
 #include <sbi_utils/cache/fdt_cmo_helper.h>
+#include <sbi_utils/fdt/fdt_cpu.h>
 #include <sbi_utils/fdt/fdt_driver.h>
 #include <sbi_utils/fdt/fdt_helper.h>
 #include <sbi_utils/hsm/fdt_hsm_sifive_inst.h>
@@ -290,30 +291,20 @@ static struct sbi_hsm_device tmc0_hsm_dev = {
 static int sifive_tmc0_bind_cpu(struct sifive_tmc0 *tmc0)
 {
 	const void *fdt = fdt_get_address();
-	struct sbi_scratch *scratch;
-	int cpus_off, cpu_off, rc;
 	const fdt32_t *val;
-	u32 hartid;
+	int cpu_offset;
 
-	cpus_off = fdt_path_offset(fdt, "/cpus");
-	if (cpus_off < 0)
-		return SBI_ENOENT;
-
-	fdt_for_each_subnode(cpu_off, fdt, cpus_off) {
-		rc = fdt_parse_hart_id(fdt, cpu_off, &hartid);
-		if (rc)
-			continue;
-
-		scratch = sbi_hartid_to_scratch(hartid);
-		if (!scratch)
+	sbi_for_each_hartindex(i) {
+		cpu_offset = fdt_cpu_hartindex_to_offset(i);
+		if (cpu_offset < 0)
 			continue;
 
-		val = fdt_getprop(fdt, cpu_off, "power-domains", NULL);
+		val = fdt_getprop(fdt, cpu_offset, "power-domains", NULL);
 		if (!val)
 			return SBI_ENOENT;
 
 		if (tmc0->id == fdt32_to_cpu(val[0])) {
-			tmc0_ptr_set(scratch, tmc0);
+			tmc0_ptr_set(sbi_hartindex_to_scratch(i), tmc0);
 			return SBI_OK;
 		}
 	}
-- 
2.52.0




More information about the opensbi mailing list