[PATCH 08/11] lib: sbi_domain: Allow adding memrange to a particular domain from drivers

Anup Patel anup.patel at oss.qualcomm.com
Tue Sep 22 20:23:56 PDT 2026


Currently, memregions of non-root domain only populated at domain creation
time which not flexible for drivers which create domain specific resources
(such as MPXY channels). Add new sbi_domain_add_memrange() function which
allows adding memrange to any domain at boot time.

Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
---
 include/sbi/sbi_domain.h | 23 +++++++++++++++++++++--
 lib/sbi/sbi_domain.c     | 35 ++++++++++++++++++-----------------
 2 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index 5e5b2227..d530f939 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -345,6 +345,22 @@ void sbi_domain_dump_all(const char *suffix);
  */
 int sbi_domain_register(struct sbi_domain *dom);
 
+/**
+ * Add a memory range with its flags to a domain
+ * @param dom pointer to domain
+ * @param addr start physical address of memory range
+ * @param size physical size of memory range
+ * @param align alignment of memory region
+ * @param region_flags memory range flags
+ *
+ * @return 0 on success
+ * @return SBI_EALREADY if memory region conflicts with the existing one
+ * @return SBI_EINVAL otherwise
+ */
+int sbi_domain_add_memrange(struct sbi_domain *dom,
+			    unsigned long addr, unsigned long size,
+			    unsigned long align, unsigned long region_flags);
+
 /**
  * Add a memory range with its flags to the root domain
  * @param addr start physical address of memory range
@@ -356,8 +372,11 @@ int sbi_domain_register(struct sbi_domain *dom);
  * @return SBI_EALREADY if memory region conflicts with the existing one
  * @return SBI_EINVAL otherwise
  */
-int sbi_domain_root_add_memrange(unsigned long addr, unsigned long size,
-			   unsigned long align, unsigned long region_flags);
+static inline int sbi_domain_root_add_memrange(unsigned long addr, unsigned long size,
+					  unsigned long align, unsigned long region_flags)
+{
+	return sbi_domain_add_memrange(&root, addr, size, align, region_flags);
+}
 
 /** Startup non-root domains */
 int sbi_domain_startup(struct sbi_scratch *scratch, u32 cold_hartid);
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index c28eeba6..1c95b0fc 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -722,16 +722,16 @@ int sbi_domain_register(struct sbi_domain *dom)
 	return 0;
 }
 
-static int root_add_memregion(const struct sbi_domain_memregion *reg)
+static int add_memregion(struct sbi_domain *dom, const struct sbi_domain_memregion *reg)
 {
 	int rc;
 	bool reg_merged;
 	struct sbi_domain_memregion *nreg, *nreg1;
-	int root_memregs_count = sbi_domain_used_memregions(&root);
+	int memregs_count = sbi_domain_used_memregions(dom);
 
 	/* Sanity checks */
 	if (!reg || domain_finalized ||
-	    (SBI_DOMAIN_MEMREGION_MAX <= root_memregs_count))
+	    (SBI_DOMAIN_MEMREGION_MAX <= memregs_count))
 		return SBI_EINVAL;
 
 	/* Check whether compatible region exists for the new one */
@@ -741,25 +741,25 @@ static int root_add_memregion(const struct sbi_domain_memregion *reg)
 	}
 
 	/* Append the memregion to root memregions */
-	nreg = &root.regions[root_memregs_count];
+	nreg = &dom->regions[memregs_count];
 	sbi_memcpy(nreg, reg, sizeof(*reg));
-	root_memregs_count++;
-	root.regions[root_memregs_count].order = 0;
+	memregs_count++;
+	dom->regions[memregs_count].order = 0;
 
-	/* Sort and optimize root regions */
+	/* Sort and optimize regions */
 	do {
-		/* Sanitize the root domain so that memregions are sorted */
-		rc = sanitize_domain(&root);
+		/* Sanitize the domain so that memregions are sorted */
+		rc = sanitize_domain(dom);
 		if (rc) {
 			sbi_printf("%s: sanity checks failed for"
 				   " %s (error %d)\n", __func__,
-				   root.name, rc);
+				   dom->name, rc);
 			return rc;
 		}
 
 		/* Merge consecutive memregions with same order and flags */
 		reg_merged = false;
-		sbi_domain_for_each_memregion(&root, nreg) {
+		sbi_domain_for_each_memregion(dom, nreg) {
 			nreg1 = nreg + 1;
 			if (!nreg1->order)
 				continue;
@@ -768,12 +768,12 @@ static int root_add_memregion(const struct sbi_domain_memregion *reg)
 			    (nreg->base + BIT(nreg->order)) == nreg1->base &&
 			    nreg->order == nreg1->order &&
 			    nreg->flags == nreg1->flags) {
-				int i1 = nreg1 - root.regions;
+				int i1 = nreg1 - dom->regions;
 				nreg->order++;
 				sbi_memmove(nreg1, nreg1 + 1,
-					    sizeof(*nreg1) * (root_memregs_count - i1));
+					    sizeof(*nreg1) * (memregs_count - i1));
 				reg_merged = true;
-				root_memregs_count--;
+				memregs_count--;
 			}
 		}
 	} while (reg_merged);
@@ -781,8 +781,9 @@ static int root_add_memregion(const struct sbi_domain_memregion *reg)
 	return 0;
 }
 
-int sbi_domain_root_add_memrange(unsigned long addr, unsigned long size,
-			   unsigned long align, unsigned long region_flags)
+int sbi_domain_add_memrange(struct sbi_domain *dom,
+			    unsigned long addr, unsigned long size,
+			    unsigned long align, unsigned long region_flags)
 {
 	int rc;
 	unsigned long pos, end, rsize;
@@ -799,7 +800,7 @@ int sbi_domain_root_add_memrange(unsigned long addr, unsigned long size,
 				(end - pos) : align;
 
 		sbi_domain_memregion_init(pos, rsize, region_flags, &reg);
-		rc = root_add_memregion(&reg);
+		rc = add_memregion(dom, &reg);
 		if (rc)
 			return rc;
 		pos += rsize;
-- 
2.43.0




More information about the opensbi mailing list