[PATCH 3/3] lib: sbi_domain: Introduce domain intialization order
Pawandeep Oza
pawandeep.oza at oss.qualcomm.com
Fri Aug 14 11:22:48 PDT 2026
On Thu, Aug 6, 2026 at 9:50 PM Anup Patel <anup.patel at oss.qualcomm.com> wrote:
>
> Currently, the domain initialization order is implied by the order
> in which domains are populated by sbi_platform_domains_init() from
> sbi_domain_finalize(). This is not documented anywhere and forces
> unecessary ordering between domain DT nodes.
>
> To address the above, introduce per-domain 32-bit integer to represent
> intialization order (aka "init_order") where domain with a lower
> initialization order will be booted first and two domains must not
> have same initialization order. For DT based domain creation, new
> "init-order" DT property can be used in domain DT node to specify
> the initialization order. The ROOT domain is assumed to have lowest
> initialization order (aka 0xffffffff).
>
> Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
> ---
> docs/domain_support.md | 5 +++++
> include/sbi/sbi_domain.h | 2 ++
> lib/sbi/sbi_domain.c | 21 ++++++++++++++-------
> lib/sbi/sbi_domain_context.c | 15 +++++++++------
> lib/utils/fdt/fdt_domain.c | 8 ++++++++
> 5 files changed, 38 insertions(+), 13 deletions(-)
>
> diff --git a/docs/domain_support.md b/docs/domain_support.md
> index 82f155e1..655bf474 100644
> --- a/docs/domain_support.md
> +++ b/docs/domain_support.md
> @@ -39,6 +39,9 @@ has following details:
>
> * **index** - Logical index of this domain
> * **name** - Name of this domain
> +* **init_order** - Initialization order of this domain. Domain with a
> + lower initialization order will be booted first and two domains must
> + not have same initialization order.
> * **assigned_harts** - HARTs assigned to this domain
> * **possible_harts** - HARTs possible in this domain
> * **regions** - Array of memory regions terminated by a memory region
> @@ -75,6 +78,8 @@ following manner:
>
> * **index** - Logical index of the ROOT domain is always zero
> * **name** - Name of the ROOT domain is "root"
> +* **init_order** - Initialization order of the ROOT domain is always
> + 0xffffffff (aka maximum possible 32-bit value)
> * **assigned_harts** - At boot-time all valid HARTs of a RISC-V platform
> are assigned the ROOT domain which changes later based on OpenSBI
> platform support
> diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
> index b6731c04..b35ea99f 100644
> --- a/include/sbi/sbi_domain.h
> +++ b/include/sbi/sbi_domain.h
> @@ -199,6 +199,8 @@ struct sbi_domain {
> spinlock_t assigned_harts_lock;
> /** Name of this domain */
> char name[64];
> + /** Initialization order of this domain */
> + u32 init_order;
> /** Possible HARTs in this domain */
> const struct sbi_hartmask *possible_harts;
> /** Array of memory regions terminated by a region with order zero */
> diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
> index af753459..747c346c 100644
> --- a/lib/sbi/sbi_domain.c
> +++ b/lib/sbi/sbi_domain.c
> @@ -28,6 +28,7 @@ static bool domain_finalized = false;
>
> struct sbi_domain root = {
> .name = "root",
> + .init_order = -1U,
> .possible_harts = NULL,
> .regions = NULL,
> .system_reset_allowed = true,
> @@ -537,6 +538,9 @@ void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
> sbi_printf("Domain%d Name %s: %s\n",
> dom->index, suffix, dom->name);
>
> + sbi_printf("Domain%d Init Order %s: 0x%x\n",
> + dom->index, suffix, dom->init_order);
> +
> sbi_printf("Domain%d Boot HART %s: %d\n",
> dom->index, suffix, dom->boot_hartid);
>
> @@ -635,9 +639,14 @@ int sbi_domain_register(struct sbi_domain *dom)
> if (!dom || domain_finalized)
> return SBI_EINVAL;
>
> - /* Check if domain already discovered */
> + /*
> + * Ensure that:
> + * 1) Domain not already registered
> + * 2) Initialization order is unique
> + */
> sbi_domain_for_each(tdom) {
> - if (tdom == dom)
> + if (tdom == dom ||
> + tdom->init_order == dom->init_order)
> return SBI_EALREADY;
> }
>
> @@ -662,15 +671,13 @@ int sbi_domain_register(struct sbi_domain *dom)
> sbi_hartmask_clear_all(&dom->assigned_harts);
>
> /*
> - * Assign a non-ROOT domain to a HART on first come first serve
> - * basis if the HART is listed as a possible HART of the non-ROOT
> - * domain. If no non-ROOT domain list a HART as possible HART then
> - * the HART is assigned to the ROOT domain.
> + * Assign HART to a domain with the least initialization order
> + * where the HART is listed as a possible HART of the domain.
> */
> sbi_hartmask_for_each_hartindex(i, dom->possible_harts) {
> tdom = sbi_hartindex_to_domain(i);
> if (tdom) {
> - if (tdom == &root)
> + if (tdom->init_order > dom->init_order)
> sbi_hartmask_clear_hartindex(i, &tdom->assigned_harts);
> else
> continue;
> diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
> index 837ff54f..e39c10fa 100644
> --- a/lib/sbi/sbi_domain_context.c
> +++ b/lib/sbi/sbi_domain_context.c
> @@ -291,28 +291,31 @@ int sbi_domain_context_exit(void)
> }
>
> dom_ctx = ctx->prev_ctx;
> + ctx->prev_ctx = NULL;
>
> /* If no previous caller context */
> if (!dom_ctx) {
> - /* Try to find next uninitialized user-defined domain's context */
> + /* Try to find next uninitialized domain with least initialization order */
> + dom_ctx = NULL;
> sbi_domain_for_each(dom) {
> - if (dom == &root || dom == sbi_domain_thishart_ptr())
> + if (dom == sbi_domain_thishart_ptr())
> continue;
>
> if (!sbi_hartmask_test_hartindex(hartindex, dom->possible_harts))
> continue;
>
> tmp = hart_context_get(dom, hartindex);
> - if (tmp && !tmp->initialized) {
> + if (tmp && tmp->initialized)
> + continue;
> +
> + if (!dom_ctx || tmp->dom->init_order < dom_ctx->dom->init_order) {
> dom_ctx = tmp;
> break;
> }
> }
> }
> -
> - /* Take the root domain context if fail to find */
> if (!dom_ctx)
> - dom_ctx = hart_context_get(&root, hartindex);
> + return SBI_ENOENT;
>
> return switch_to_next_domain_context(ctx, dom_ctx);
> }
> diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
> index 31786e0e..366ab138 100644
> --- a/lib/utils/fdt/fdt_domain.c
> +++ b/lib/utils/fdt/fdt_domain.c
> @@ -331,6 +331,14 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> sizeof(dom->name));
> dom->name[sizeof(dom->name) - 1] = '\0';
>
> + /* Read initalization order */
> + val = fdt_getprop(fdt, domain_offset, "init-order", &len);
> + len = len / sizeof(u32);
> + if (val && len)
> + dom->init_order = fdt32_to_cpu(val[0]);
> + else
> + dom->init_order = (u32)domain_offset;
> +
Oza: if domina doesnt provide following properties then have cleaner
else and explcitly inherit from root domina
val64 = root.next_arg1;
val64 = root.next_addr;
/* Read "next-arg1" DT property */
/* Read "next-addr" DT property */
Reviewed-by: Pawandeep Oza <pawandeep.oza at oss.qualcomm.com>
Tested-by: Pawandeep Oza <pawandeep.oza at oss.qualcomm.com>
> /* Setup possible HARTs mask */
> SBI_HARTMASK_INIT(mask);
> dom->possible_harts = mask;
> --
> 2.43.0
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
More information about the opensbi
mailing list