[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