[RFC PATCH v7 3/6] lib: utils: fdt: Add helper to check for an extension in DT

Rahul Pathak rahul.pathak at oss.qualcomm.com
Sun Nov 1 20:33:54 PST 2026


In the early boot stage a platform may need to
check for an extension in DT. This early stage
can be before the sbi_hart_init is called which
later parses all extensions available on the harts.

Add a new helper function for this detection.

Signed-off-by: Rahul Pathak <rahul.pathak at oss.qualcomm.com>
---
 include/sbi_utils/fdt/fdt_helper.h |  4 ++
 lib/utils/fdt/fdt_helper.c         | 61 +++++++++++++++++++++++-------
 2 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 75a564d1fece..59e369780730 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -12,6 +12,7 @@
 
 #include <sbi/sbi_types.h>
 #include <sbi/sbi_domain.h>
+#include <sbi/sbi_hart.h>
 
 struct fdt_match {
 	const char *compatible;
@@ -56,6 +57,9 @@ int fdt_parse_timebase_frequency(const void *fdt, unsigned long *freq);
 
 int fdt_parse_isa_extensions_all_harts(const void *fdt);
 
+bool fdt_cpu_has_extension(const void *fdt, int cpu_offset,
+			   enum sbi_hart_extensions ext);
+
 int fdt_parse_gaisler_uart_node(const void *fdt, int nodeoffset,
 				struct platform_uart_data *uart);
 
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index 747ba0285b37..d71b8c76a733 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -407,13 +407,56 @@ static void fdt_parse_isa_extensions_one_hart(const char *isa,
 	}
 }
 
+static int fdt_parse_isa_extensions_cpu(const void *fdt, int cpu_offset,
+					unsigned long *extensions)
+{
+	const fdt32_t *val;
+	int len, err;
+
+	val = fdt_getprop(fdt, cpu_offset, "riscv,isa-extensions", &len);
+	if (val && len > 0) {
+		fdt_parse_isa_extensions_one_hart((const char *)val,
+						  extensions, len);
+		return 0;
+	}
+
+	val = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
+	if (!val || len <= 0)
+		return SBI_ENOENT;
+
+	err = fdt_parse_isa_one_hart((const char *)val, extensions);
+
+	return err;
+}
+
+bool fdt_cpu_has_extension(const void *fdt, int cpu_offset,
+			   enum sbi_hart_extensions ext)
+{
+	int err;
+	bool is_ext;
+
+	DECLARE_BITMAP(extensions, SBI_HART_EXT_MAX);
+	bitmap_zero(extensions, SBI_HART_EXT_MAX);
+
+	if (!fdt || ext >= SBI_HART_EXT_MAX)
+		return false;
+
+	err = fdt_parse_isa_extensions_cpu(fdt, cpu_offset, extensions);
+	if (err)
+		return false;
+
+
+	is_ext = __test_bit(ext, extensions) ? true : false;
+
+	return is_ext;
+}
+
 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, cpus_offset;
 
 	if (!fdt)
 		return SBI_EINVAL;
@@ -438,18 +481,8 @@ int fdt_parse_isa_extensions_all_harts(const void *fdt)
 		if (!hfeatures)
 			return SBI_ENOENT;
 
-		val = fdt_getprop(fdt, cpu_offset, "riscv,isa-extensions", &len);
-		if (val && len > 0) {
-			fdt_parse_isa_extensions_one_hart((const char *)val,
-							  hfeatures->extensions, len);
-			continue;
-		}
-
-		val = fdt_getprop(fdt, cpu_offset, "riscv,isa", &len);
-		if (!val || len <= 0)
-			return SBI_ENOENT;
-
-		err = fdt_parse_isa_one_hart((const char *)val, hfeatures->extensions);
+		err = fdt_parse_isa_extensions_cpu(fdt, cpu_offset,
+						   hfeatures->extensions);
 		if (err)
 			return err;
 	}
-- 
2.53.0




More information about the opensbi mailing list