[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