[PATCH v2 1/3] lib: sbi: domain: add domain registration notifier infrastructure
Pawandeep Oza <[email protected]>
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <[email protected]> |
From: Oza Pawandeep <[email protected]> Introduce a notifier callback mechanism that allows subsystems to register interest in domain registration events. When a new domain is registered via sbi_domain_register(), all registered notifiers are invoked before domain sanitization. The following public interfaces are added to sbi_domain.h: - sbi_domain_register_notifier(): registers a notifier callback. Duplicate (fn, priv) pairs are silently ignored. - sbi_domain_unregister_notifier(): removes a previously registered notifier callback. Signed-off-by: Oza Pawandeep <[email protected]> --- include/sbi/sbi_domain.h | 10 +++++++ lib/sbi/sbi_domain.c | 59 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h index b35ea99f..2471df48 100644 --- a/include/sbi/sbi_domain.h +++ b/include/sbi/sbi_domain.h @@ -358,4 +358,14 @@ int sbi_domain_finalize(struct sbi_scratch *scratch); /** Initialize domains */ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid); +/** Notifier callback */ +typedef void (*sbi_domain_notifier_fn)(const 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); + #endif diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c index 747c346c..99f201cf 100644 --- a/lib/sbi/sbi_domain.c +++ b/lib/sbi/sbi_domain.c @@ -36,7 +36,65 @@ struct sbi_domain root = { .fw_region_inited = false, }; +struct sbi_domain_notifier_entry { + struct sbi_dlist node; + sbi_domain_notifier_fn fn; + void *priv; +}; + + static unsigned long domain_hart_ptr_offset; +static SBI_LIST_HEAD(domain_notifier_list); + +int sbi_domain_register_notifier(sbi_domain_notifier_fn notifier, void *priv) +{ + struct sbi_domain_notifier_entry *entry; + + if (!notifier) + return SBI_EINVAL; + + sbi_list_for_each_entry(entry, &domain_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_notifier_list); + return SBI_OK; +} + +int sbi_domain_unregister_notifier(sbi_domain_notifier_fn notifier, void *priv) +{ + struct sbi_domain_notifier_entry *entry, *tmp; + + if (!notifier) + return SBI_EINVAL; + + sbi_list_for_each_entry_safe(entry, tmp, &domain_notifier_list, node) { + if (entry->fn == notifier && entry->priv == priv) { + sbi_list_del(&entry->node); + sbi_free(entry); + return SBI_OK; + } + } + + return SBI_ENODEV; +} + +void sbi_domain_notify_all(const struct sbi_domain *dom) +{ + struct sbi_domain_notifier_entry *entry; + + sbi_list_for_each_entry(entry, &domain_notifier_list, node) { + if (entry->fn) + entry->fn(dom, entry->priv); + } +} struct sbi_domain *sbi_hartindex_to_domain(u32 hartindex) { @@ -650,6 +708,7 @@ int sbi_domain_register(struct sbi_domain *dom) return SBI_EALREADY; } + sbi_domain_notify_all(dom); /* Sanitize discovered domain */ rc = sanitize_domain(dom); if (rc) { -- 2.43.0 -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi