[PATCH v2 2/3] lib: sbi_domain: Re-work boot-time assignment of HARTs to non-ROOT domains
Anup Patel
anup at brainfault.org
Sat Sep 5 05:47:42 PDT 2026
On Fri, Aug 28, 2026 at 6:15 PM Yu-Chien Peter Lin <peter.lin at sifive.com> wrote:
>
> Hi Anup,
>
> On Mon, Aug 17, 2026 at 08:00:24PM +0530, Anup Patel wrote:
> > 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.
> >
> > This allows us to drop the OpenSBI specific DT property from each CPU DT
> > node (aka "opensbi-domain" Dt property).
> >
> > Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
> > ---
> > docs/domain_support.md | 20 +++----
> > include/sbi/sbi_domain.h | 4 +-
> > include/sbi_utils/fdt/fdt_domain.h | 3 +-
> > lib/sbi/sbi_domain.c | 34 ++++++-----
> > lib/utils/fdt/fdt_domain.c | 95 +++---------------------------
> > 5 files changed, 35 insertions(+), 121 deletions(-)
> >
> > diff --git a/docs/domain_support.md b/docs/domain_support.md
> > index e267a9f7..82f155e1 100644
> > --- a/docs/domain_support.md
> > +++ b/docs/domain_support.md
> > @@ -207,15 +207,14 @@ The DT properties of a domain instance DT node are as follows:
> >
> > ### Assigning HART To Domain Instance
> >
> > -By default, all HARTs are assigned to **the ROOT domain**. The OpenSBI
> > -platform support can provide the HART to domain instance assignment using
> > -platform specific callback.
> > +At boot-time, a HART is assigned to a non-ROOT domain 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**.
> >
> > -The HART to domain instance assignment can be parsed from the device tree
> > -using optional DT property **opensbi-domain** in each CPU DT node. The
> > -value of DT property **opensbi-domain** is the DT phandle of the domain
> > -instance DT node. If **opensbi-domain** DT property is not specified then
> > -corresponding HART is assigned to **the ROOT domain**.
> > +At runtime, the assignment of a HART can change from one domain to
> > +another domain as long as the HART is listed in possible HARTs of
> > +both domains.
> >
> > ### Domain Configuration Only Accessible to OpenSBI
> >
> > @@ -289,7 +288,6 @@ be done:
> > device_type = "cpu";
> > reg = <0x00>;
> > compatible = "riscv";
> > - opensbi-domain = <&tdomain>;
> > ...
> > };
> >
> > @@ -297,7 +295,6 @@ be done:
> > device_type = "cpu";
> > reg = <0x01>;
> > compatible = "riscv";
> > - opensbi-domain = <&udomain>;
> > ...
> > };
> >
> > @@ -305,7 +302,6 @@ be done:
> > device_type = "cpu";
> > reg = <0x02>;
> > compatible = "riscv";
> > - opensbi-domain = <&udomain>;
> > ...
> > };
> >
> > @@ -313,7 +309,6 @@ be done:
> > device_type = "cpu";
> > reg = <0x03>;
> > compatible = "riscv";
> > - opensbi-domain = <&udomain>;
> > ...
> > };
> >
> > @@ -321,7 +316,6 @@ be done:
> > device_type = "cpu";
> > reg = <0x04>;
> > compatible = "riscv";
> > - opensbi-domain = <&udomain>;
> > ...
> > };
> > };
> > diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
> > index 16edd4ce..b6731c04 100644
> > --- a/include/sbi/sbi_domain.h
> > +++ b/include/sbi/sbi_domain.h
> > @@ -328,12 +328,10 @@ void sbi_domain_dump_all(const char *suffix);
> > /**
> > * Register a new domain
> > * @param dom pointer to domain
> > - * @param assign_mask pointer to HART mask of HARTs assigned to the domain
> > *
> > * @return 0 on success and negative error code on failure
> > */
> > -int sbi_domain_register(struct sbi_domain *dom,
> > - const struct sbi_hartmask *assign_mask);
> > +int sbi_domain_register(struct sbi_domain *dom);
> >
> > /**
> > * Add a memory range with its flags to the root domain
> > diff --git a/include/sbi_utils/fdt/fdt_domain.h b/include/sbi_utils/fdt/fdt_domain.h
> > index 8c2dee09..a366b271 100644
> > --- a/include/sbi_utils/fdt/fdt_domain.h
> > +++ b/include/sbi_utils/fdt/fdt_domain.h
> > @@ -50,8 +50,7 @@ int fdt_iterate_each_memregion(void *fdt, int domain_offset, void *opaque,
> > *
> > * This routine:
> > * 1. Disables MMIO devices not accessible to the coldboot HART domain
> > - * 2. Removes "opensbi-domain" DT property from CPU DT nodes
> > - * 3. Removes domain configuration DT node under /chosen DT node
> > + * 2. Removes domain configuration DT node under /chosen DT node
> > *
> > * It is recommended that platform support call this function in
> > * their final_init() platform operation.
> > diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
> > index fa69170b..af753459 100644
> > --- a/lib/sbi/sbi_domain.c
> > +++ b/lib/sbi/sbi_domain.c
> > @@ -625,16 +625,14 @@ void sbi_domain_dump_all(const char *suffix)
> > }
> > }
> >
> > -int sbi_domain_register(struct sbi_domain *dom,
> > - const struct sbi_hartmask *assign_mask)
> > +int sbi_domain_register(struct sbi_domain *dom)
> > {
> > - u32 i;
> > - int rc;
> > + u32 i, cold_hartid = current_hartid();
> > struct sbi_domain *tdom;
> > - u32 cold_hartid = current_hartid();
> > + int rc;
> >
> > /* Sanity checks */
> > - if (!dom || !assign_mask || domain_finalized)
> > + if (!dom || domain_finalized)
> > return SBI_EINVAL;
> >
> > /* Check if domain already discovered */
> > @@ -663,15 +661,21 @@ int sbi_domain_register(struct sbi_domain *dom,
> > /* Clear assigned HARTs of domain */
> > sbi_hartmask_clear_all(&dom->assigned_harts);
> >
> > - /* Assign domain to HART if HART is a possible HART */
> > - sbi_hartmask_for_each_hartindex(i, assign_mask) {
> > - if (!sbi_hartmask_test_hartindex(i, dom->possible_harts))
> > - continue;
> > -
> > + /*
> > + * 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.
> > + */
> > + sbi_hartmask_for_each_hartindex(i, dom->possible_harts) {
> > tdom = sbi_hartindex_to_domain(i);
> > - if (tdom)
> > - sbi_hartmask_clear_hartindex(i,
> > - &tdom->assigned_harts);
> > + if (tdom) {
> > + if (tdom == &root)
> > + sbi_hartmask_clear_hartindex(i, &tdom->assigned_harts);
> > + else
> > + continue;
> > + }
> > +
> > sbi_update_hartindex_to_domain(i, dom);
> > sbi_hartmask_set_hartindex(i, &dom->assigned_harts);
> >
> > @@ -975,7 +979,7 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
> > sbi_hartmask_set_hartindex(i, root_hmask);
> >
> > /* Finally register the root domain */
> > - rc = sbi_domain_register(&root, root_hmask);
> > + rc = sbi_domain_register(&root);
> > if (rc)
> > goto fail_free_root_hmask;
> >
> > diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
> > index 61627db3..3857831d 100644
> > --- a/lib/utils/fdt/fdt_domain.c
> > +++ b/lib/utils/fdt/fdt_domain.c
> > @@ -170,26 +170,11 @@ static int __fixup_disable_devices(void *fdt, int doff, int roff,
> >
> > void fdt_domain_fixup(void *fdt)
> > {
> > - u32 i, dcount;
> > + u32 dcount;
> > int err, poffset, doffset;
> > struct sbi_domain *dom = sbi_domain_thishart_ptr();
> > struct __fixup_find_domain_offset_info fdo;
> >
> > - /* Remove the domain assignment DT property from CPU DT nodes */
> > - poffset = fdt_path_offset(fdt, "/cpus");
> > - if (poffset < 0)
> > - return;
> > - fdt_for_each_subnode(doffset, fdt, poffset) {
> > - err = fdt_parse_hart_id(fdt, doffset, &i);
> > - if (err)
> > - continue;
> > -
> > - if (!fdt_node_is_enabled(fdt, doffset))
> > - continue;
> > -
> > - fdt_nop_property(fdt, doffset, "opensbi-domain");
> > - }
> > -
> > /* Skip device disable for root domain */
> > if (!dom->index)
> > goto skip_device_disable;
> > @@ -315,12 +300,10 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> > const char *inherit;
> > struct sbi_domain *dom;
> > struct sbi_hartmask *mask;
> > - struct sbi_hartmask assign_mask;
> > struct parse_region_data preg;
> > - int *cold_domain_offset = opaque;
> > struct sbi_domain_memregion *reg;
> > int inheritance_mode = FDT_ROOT_REGION_INHERIT_M_ONLY;
> > - int i, err = 0, len, cpus_offset, cpu_offset, doffset;
> > + int i, err = 0, len, cpus_offset, cpu_offset;
> >
> > dom = sbi_zalloc(sizeof(*dom));
> > if (!dom)
> > @@ -440,7 +423,7 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> > val64 = fdt32_to_cpu(val[0]);
> > val64 = (val64 << 32) | fdt32_to_cpu(val[1]);
> > } else {
> > - val64 = sbi_scratch_thishart_ptr()->next_arg1;
> > + val64 = root.next_arg1;
> > }
> > dom->next_arg1 = val64;
> >
> > @@ -451,8 +434,7 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> > val64 = fdt32_to_cpu(val[0]);
> > val64 = (val64 << 32) | fdt32_to_cpu(val[1]);
> > } else {
> > - if (domain_offset == *cold_domain_offset)
> > - val64 = sbi_scratch_thishart_ptr()->next_addr;
> > + val64 = root.next_addr;
> > }
> > dom->next_addr = val64;
> >
> > @@ -464,8 +446,7 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> > if (val32 != 0x0 && val32 != 0x1)
> > val32 = 0x1;
> > } else {
> > - if (domain_offset == *cold_domain_offset)
> > - val32 = sbi_scratch_thishart_ptr()->next_mode;
> > + val32 = root.next_mode;
> > }
> > dom->next_mode = val32;
>
> We may update domain_support.md accordingly to reflect these changes.
> https://github.com/riscv-software-src/opensbi/blob/4e79fd7de59f1b2899092c1a84ce68c8ebc68f93/docs/domain_support.md?plain=1#L186-L202
Okay, I will update domain_support.md.
>
> >
> > @@ -490,37 +471,8 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> > goto fail_free_all;
> > }
> >
> > - /* HART to domain assignment mask based on CPU DT nodes */
> > - sbi_hartmask_clear_all(&assign_mask);
> > - fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
>
> cpus_offset is unused now in __fdt_parse_domain().
Good catch, I will remove cpus_offset.
Regards,
Anup
More information about the opensbi
mailing list