[RFC PATCH v5 1/4] lib: sbi_domain: Add domain register finalize notifier

Rahul Pathak rahul.pathak at oss.qualcomm.com
Thu Sep 17 20:09:50 PDT 2026


sbi domain registeration notifier is invoked when
memory regions of the domains are not finalized. The root
domain is registered early and the drivers keep adding
the regions until sbi_domain_finalize() is called. Such regions
are added to the root after root domain is already registered
and notification for that has already been sent.

Per-domain configuration which is based on the final memory
regions of the domains especially the root domain is not
possible only with a domain register notifier.

Add a domain finalize notifier for such case which is called
for every domain once all the domains are already registered and
their memory regions are finalized.

Signed-off-by: Rahul Pathak <rahul.pathak at oss.qualcomm.com>
---
 include/sbi/sbi_domain.h | 16 ++++++++
 lib/sbi/sbi_domain.c     | 80 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+)

diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index 39e6fc81..a96d709d 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -362,10 +362,26 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid);
 typedef void (*sbi_domain_notifier_fn)(const struct sbi_domain *dom,
                                       void *priv);
 
+/**
+ * Domain finalize notifier callback
+ *
+ * Invoked from sbi_domain_finalize  function after every domain gets
+ * registered and memory regions of all domains are finalized.
+ */
+typedef int (*sbi_domain_finalize_notifier_fn)(struct sbi_domain *dom, void *priv);
+
 /** Regitser domain notifier */
 int sbi_domain_register_notifier(sbi_domain_notifier_fn notifier, void *priv);
 
 /** Unregitser domain notifier */
 int sbi_domain_unregister_notifier(sbi_domain_notifier_fn notifier, void *priv);
 
+/** Register domain finalize notifier */
+int sbi_domain_register_finalize_notifier(sbi_domain_finalize_notifier_fn notifier,
+					  void *priv);
+
+/** Unregister domain finalize notifier */
+int sbi_domain_unregister_finalize_notifier(sbi_domain_finalize_notifier_fn notifier,
+					    void *priv);
+
 #endif
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index c0583efc..913f8142 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -42,8 +42,15 @@ struct sbi_domain_notifier_entry {
 };
 
 
+struct sbi_domain_finalize_notifier_entry {
+	struct sbi_dlist			node;
+	sbi_domain_finalize_notifier_fn		fn;
+	void					*priv;
+};
+
 static unsigned long domain_hart_ptr_offset;
 static SBI_LIST_HEAD(domain_notifier_list);
+static SBI_LIST_HEAD(domain_finalize_notifier_list);
 
 int sbi_domain_register_notifier(sbi_domain_notifier_fn notifier, void *priv)
 {
@@ -95,6 +102,67 @@ void sbi_domain_notify_all(const struct sbi_domain *dom)
 	}
 }
 
+int sbi_domain_register_finalize_notifier(sbi_domain_finalize_notifier_fn notifier, void *priv)
+{
+	struct sbi_domain_finalize_notifier_entry *entry;
+
+	if (!notifier)
+		return SBI_EINVAL;
+
+	sbi_list_for_each_entry(entry, &domain_finalize_notifier_list, node) {
+		if (entry->fn == notifier && entry->priv == priv)
+			return SBI_OK;
+	}
+
+	entry = sbi_zalloc(sizeof(*entry));
+	if (!entry)
+		return SBI_ENOMEM;
+
+	entry->fn = notifier;
+	entry->priv = priv;
+	sbi_list_add_tail(&entry->node, &domain_finalize_notifier_list);
+
+	return SBI_OK;
+}
+
+int sbi_domain_unregister_finalize_notifier(sbi_domain_finalize_notifier_fn notifier, void *priv)
+{
+	struct sbi_domain_finalize_notifier_entry *entry, *tmp;
+
+	if (!notifier)
+		return SBI_EINVAL;
+
+	sbi_list_for_each_entry_safe(entry, tmp, &domain_finalize_notifier_list, node) {
+		if (entry->fn == notifier && entry->priv == priv) {
+			sbi_list_del(&entry->node);
+			sbi_free(entry);
+			return SBI_OK;
+		}
+	}
+
+	return SBI_ENODEV;
+}
+
+static int sbi_domain_notify_finalize_all(void)
+{
+	struct sbi_domain_finalize_notifier_entry *entry;
+	struct sbi_domain *dom;
+	int rc;
+
+	sbi_list_for_each_entry(entry, &domain_finalize_notifier_list, node) {
+		if (!entry->fn)
+			continue;
+
+		sbi_domain_for_each(dom) {
+			rc = entry->fn(dom, entry->priv);
+			if (rc)
+				return rc;
+		}
+	}
+
+	return 0;
+}
+
 struct sbi_domain *sbi_hartindex_to_domain(u32 hartindex)
 {
 	struct sbi_scratch *scratch;
@@ -924,6 +992,18 @@ int sbi_domain_finalize(struct sbi_scratch *scratch)
 	 */
 	domain_finalized = true;
 
+	/*
+	 * All domains are registered and their memory regions are final
+	 * so notify the subsystems which derive per-domain configuration
+	 * from the domain memory regions.
+	 */
+	rc = sbi_domain_notify_finalize_all();
+	if (rc) {
+		sbi_printf("%s: domain finalize notifier failed (error %d)\n",
+			   __func__, rc);
+		return rc;
+	}
+
 	return 0;
 }
 
-- 
2.53.0




More information about the opensbi mailing list