OpenSBI Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Raymond Mao <raymondmaoca@gmail.com>
To: opensbi@lists.infradead.org
Cc: scott@riscstar.com, dave.patel@riscstar.com,
	raymond.mao@riscstar.com, robin.randhawa@sifive.com,
	samuel.holland@sifive.com, anup.patel@qti.qualcomm.com,
	anuppate@qti.qualcomm.com, anup@brainfault.org,
	dhaval@rivosinc.com, peter.lin@sifive.com
Subject: [PATCH v2 1/4] lib: utils: fdt: add generic domain and property parsing helpers
Date: Fri, 24 Jul 2026 22:38:18 -0400	[thread overview]
Message-ID: <20260725023821.3795618-2-raymondmaoca@gmail.com> (raw)
In-Reply-To: <20260725023821.3795618-1-raymondmaoca@gmail.com>

From: Raymond Mao <raymond.mao@riscstar.com>

Add reusable FDT helpers for domain-oriented and other FDT-based
consumers.

This adds helpers to:
- find a domain instance DT node by exact name match
- parse a single u32 property
- parse a single u64 property
- parse a u32 property list into a bitmask

Also tighten the internal domain-name matching to use exact node-name
matching.

Signed-off-by: Raymond Mao <raymond.mao@riscstar.com>
---
 include/sbi_utils/fdt/fdt_domain.h | 13 +++++
 include/sbi_utils/fdt/fdt_helper.h | 10 ++++
 lib/utils/fdt/fdt_domain.c         | 46 +++++++++++++++++-
 lib/utils/fdt/fdt_helper.c         | 76 ++++++++++++++++++++++++++++++
 4 files changed, 144 insertions(+), 1 deletion(-)

diff --git a/include/sbi_utils/fdt/fdt_domain.h b/include/sbi_utils/fdt/fdt_domain.h
index 8c2dee09..60d51d6c 100644
--- a/include/sbi_utils/fdt/fdt_domain.h
+++ b/include/sbi_utils/fdt/fdt_domain.h
@@ -11,12 +11,18 @@
 #ifndef __FDT_DOMAIN_H__
 #define __FDT_DOMAIN_H__
 
+#include <sbi/sbi_error.h>
 #include <sbi/sbi_types.h>
 
 #ifdef CONFIG_FDT_DOMAIN
 
 struct sbi_domain;
 
+struct fdt_find_domain_offset_info {
+	const char *name;
+	int domain_offset;
+};
+
 /**
  * Iterate over each domains in device tree
  *
@@ -45,6 +51,8 @@ int fdt_iterate_each_memregion(void *fdt, int domain_offset, void *opaque,
 					 int region_offset, u32 region_access,
 					 void *opaque));
 
+int fdt_find_domain_offset(const void *fdt, const struct sbi_domain *dom);
+
 /**
  * Fix up the domain configuration in the device tree
  *
@@ -76,6 +84,11 @@ int fdt_domains_populate(const void *fdt);
 
 static inline void fdt_domain_fixup(void *fdt) { }
 static inline int fdt_domains_populate(const void *fdt) { return 0; }
+static inline int fdt_find_domain_offset(const void *fdt,
+					 const struct sbi_domain *dom)
+{
+	return SBI_ENOENT;
+}
 
 #endif
 
diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 75a564d1..05ca9f79 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -50,6 +50,16 @@ int fdt_parse_hart_id(const void *fdt, int cpu_offset, u32 *hartid);
 
 int fdt_parse_max_enabled_hart_id(const void *fdt, u32 *max_hartid);
 
+int fdt_parse_u32(const void *fdt, int nodeoff, const char *prop_name,
+		  u32 *out_val);
+
+int fdt_parse_u64(const void *fdt, int nodeoff, const char *prop_name,
+		  u64 *out_val);
+
+int fdt_parse_u32_array_bitmask(const void *fdt, int nodeoff,
+				const char *prop_name, u32 max_bits,
+				u32 *out_mask);
+
 int fdt_parse_cbom_block_size(const void *fdt, int cpu_offset, unsigned long  *cbom_block_size);
 
 int fdt_parse_timebase_frequency(const void *fdt, unsigned long *freq);
diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
index 61627db3..af653505 100644
--- a/lib/utils/fdt/fdt_domain.c
+++ b/lib/utils/fdt/fdt_domain.c
@@ -97,6 +97,49 @@ int fdt_iterate_each_memregion(void *fdt, int domain_offset, void *opaque,
 	return 0;
 }
 
+static bool fdt_find_domain_offset_match(void *fdt, int domain_offset,
+					 void *opaque)
+{
+	struct fdt_find_domain_offset_info *info = opaque;
+	const char *name;
+
+	name = fdt_get_name(fdt, domain_offset, NULL);
+	if (name && !strcmp(info->name, name)) {
+		info->domain_offset = domain_offset;
+		return true;
+	}
+
+	return false;
+}
+
+static int fdt_find_domain_offset_iter(void *fdt, int domain_offset,
+				       void *opaque)
+{
+	return fdt_find_domain_offset_match(fdt, domain_offset, opaque) ? 1 : 0;
+}
+
+int fdt_find_domain_offset(const void *fdt, const struct sbi_domain *dom)
+{
+	struct fdt_find_domain_offset_info info;
+	int rc;
+
+	if (!fdt || !dom)
+		return SBI_EINVAL;
+	if (dom == &root)
+		return -1;
+
+	info.name = dom->name;
+	info.domain_offset = -1;
+	rc = fdt_iterate_each_domain((void *)fdt, &info,
+				     fdt_find_domain_offset_iter);
+	if (rc < 0)
+		return rc;
+	if (info.domain_offset >= 0)
+		return info.domain_offset;
+
+	return SBI_ENOENT;
+}
+
 static int fdt_iterate_each_memregion_ro(const void *fdt, int domain_offset, void *opaque,
 					 int (*fn)(const void *fdt, int domain_offset,
 						   int region_offset, u32 region_access,
@@ -114,8 +157,9 @@ struct __fixup_find_domain_offset_info {
 static int __fixup_find_domain_offset(void *fdt, int doff, void *p)
 {
 	struct __fixup_find_domain_offset_info *fdo = p;
+	const char *name = fdt_get_name(fdt, doff, NULL);
 
-	if (!strncmp(fdo->name, fdt_get_name(fdt, doff, NULL), strlen(fdo->name)))
+	if (name && !strcmp(fdo->name, name))
 		*fdo->doffset = doff;
 
 	return 0;
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index ad4efaaf..39c3f3aa 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -250,6 +250,82 @@ int fdt_parse_hart_id(const void *fdt, int cpu_offset, u32 *hartid)
 	return 0;
 }
 
+int fdt_parse_u32(const void *fdt, int nodeoff, const char *prop_name,
+		  u32 *out_val)
+{
+	const fdt32_t *prop;
+	int len;
+
+	if (!fdt || nodeoff < 0 || !prop_name || !out_val)
+		return SBI_EINVAL;
+
+	prop = fdt_getprop(fdt, nodeoff, prop_name, &len);
+	if (!prop)
+		return SBI_ENOENT;
+	if (len != (int)sizeof(fdt32_t))
+		return SBI_EINVAL;
+
+	*out_val = fdt32_to_cpu(prop[0]);
+	return 0;
+}
+
+int fdt_parse_u64(const void *fdt, int nodeoff, const char *prop_name,
+		  u64 *out_val)
+{
+	const fdt32_t *prop;
+	int len;
+
+	if (!fdt || nodeoff < 0 || !prop_name || !out_val)
+		return SBI_EINVAL;
+
+	prop = fdt_getprop(fdt, nodeoff, prop_name, &len);
+	if (!prop)
+		return SBI_ENOENT;
+	if (len != (int)(2 * sizeof(fdt32_t)))
+		return SBI_EINVAL;
+
+	*out_val = ((u64)fdt32_to_cpu(prop[0]) << 32) | fdt32_to_cpu(prop[1]);
+	return 0;
+}
+
+int fdt_parse_u32_array_bitmask(const void *fdt, int nodeoff,
+				const char *prop_name, u32 max_bits,
+				u32 *out_mask)
+{
+	const fdt32_t *prop;
+	u32 mask = 0, count, val;
+	int len, i;
+
+	if (!fdt || nodeoff < 0 || !prop_name || !out_mask || !max_bits ||
+	    max_bits > 32)
+		return SBI_EINVAL;
+
+	*out_mask = 0;
+
+	prop = fdt_getprop(fdt, nodeoff, prop_name, &len);
+	if (!prop)
+		return 0;
+	if (len < 0 || (len % (int)sizeof(fdt32_t)))
+		return SBI_EINVAL;
+
+	count = len / sizeof(fdt32_t);
+	if (count > max_bits)
+		return SBI_EINVAL;
+
+	for (i = 0; i < (int)count; i++) {
+		val = fdt32_to_cpu(prop[i]);
+		if (val >= max_bits)
+			return SBI_EINVAL;
+		if (mask & (1U << val))
+			return SBI_EINVAL;
+
+		mask |= 1U << val;
+	}
+
+	*out_mask = mask;
+	return 0;
+}
+
 int fdt_parse_cbom_block_size(const void *fdt, int cpu_offset, unsigned long *cbom_block_size)
 {
 	int len;
-- 
2.25.1


-- 
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi

  reply	other threads:[~2026-07-25  2:39 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-25  2:38 [PATCH v2 0/4] Add WorldGuard support with wgchecker2 Raymond Mao
2026-07-25  2:38 ` Raymond Mao [this message]
2026-07-25  2:38 ` [PATCH v2 2/4] hart: add WorldGuard CSR IDs and hart extension flags Raymond Mao
2026-07-25  2:38 ` [PATCH v2 3/4] docs: document WorldGuard DT bindings Raymond Mao
2026-07-25  2:38 ` [PATCH v2 4/4] platform: generic: add WorldGuard support with wgchecker2 Raymond Mao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260725023821.3795618-2-raymondmaoca@gmail.com \
    --to=raymondmaoca@gmail.com \
    --cc=anup.patel@qti.qualcomm.com \
    --cc=anup@brainfault.org \
    --cc=anuppate@qti.qualcomm.com \
    --cc=dave.patel@riscstar.com \
    --cc=dhaval@rivosinc.com \
    --cc=opensbi@lists.infradead.org \
    --cc=peter.lin@sifive.com \
    --cc=raymond.mao@riscstar.com \
    --cc=robin.randhawa@sifive.com \
    --cc=samuel.holland@sifive.com \
    --cc=scott@riscstar.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox