[PATCH 07/11] lib: sbi_domain: Make domain regions as fixed array
Pawandeep Oza
pawandeep.oza at oss.qualcomm.com
Tue Oct 13 12:47:04 PDT 2026
On Tue, Sep 22, 2026 at 8:24 PM Anup Patel <anup.patel at oss.qualcomm.com> wrote:
>
> Instead of separately allocating domain regions, let us have a fixed
> size array so that regions are automatically allocated along with
> domain allocation and one SBI_DOMAIN_MEMREGION_MAX macro defines
> maximum number of regions for all domains.
>
> Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
> ---
> include/sbi/sbi_domain.h | 3 ++-
> lib/sbi/sbi_domain.c | 42 ++++++++++------------------------
> lib/utils/fdt/fdt_domain.c | 17 +++-----------
> platform/generic/mips/eyeq7h.c | 6 ++---
> 4 files changed, 20 insertions(+), 48 deletions(-)
>
> diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
> index 394e7ddf..5e5b2227 100644
> --- a/include/sbi/sbi_domain.h
> +++ b/include/sbi/sbi_domain.h
> @@ -204,7 +204,8 @@ struct sbi_domain {
> /** Possible HARTs in this domain */
> const struct sbi_hartmask *possible_harts;
> /** Array of memory regions terminated by a region with order zero */
> - struct sbi_domain_memregion *regions;
> +#define SBI_DOMAIN_MEMREGION_MAX 32
> + struct sbi_domain_memregion regions[SBI_DOMAIN_MEMREGION_MAX + 1];
> /** HART id of the HART booting this domain */
> u32 boot_hartid;
> /** Arg1 (or 'a1' register) of next booting stage for this domain */
> diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
> index f5c62509..c28eeba6 100644
> --- a/lib/sbi/sbi_domain.c
> +++ b/lib/sbi/sbi_domain.c
> @@ -24,13 +24,10 @@ SBI_LIST_HEAD(domain_list);
> static u32 domain_count = 0;
> static bool domain_finalized = false;
>
> -#define ROOT_REGION_MAX 32
> -
> struct sbi_domain root = {
> .name = "root",
> .init_order = -1U,
> .possible_harts = NULL,
> - .regions = NULL,
> .system_reset_allowed = true,
> .system_suspend_allowed = true,
> .fw_region_inited = false,
> @@ -225,7 +222,7 @@ bool sbi_domain_check_addr(const struct sbi_domain *dom,
> unsigned long access_flags)
> {
> bool rmmio, mmio = false;
> - struct sbi_domain_memregion *reg;
> + const struct sbi_domain_memregion *reg;
> unsigned long rstart, rend, rflags, rwx = 0, rrwx = 0;
>
> if (!dom)
> @@ -331,7 +328,7 @@ static const struct sbi_domain_memregion *find_region(
> unsigned long addr)
> {
> unsigned long rstart, rend;
> - struct sbi_domain_memregion *reg;
> + const struct sbi_domain_memregion *reg;
>
> sbi_domain_for_each_memregion(dom, reg) {
> rstart = reg->base;
> @@ -349,7 +346,7 @@ static const struct sbi_domain_memregion *find_next_subset_region(
> const struct sbi_domain_memregion *reg,
> unsigned long addr)
> {
> - struct sbi_domain_memregion *sreg, *ret = NULL;
> + const struct sbi_domain_memregion *sreg, *ret = NULL;
>
> sbi_domain_for_each_memregion(dom, sreg) {
> if (sreg == reg || (sreg->base <= addr) ||
> @@ -377,7 +374,7 @@ static void swap_region(struct sbi_domain_memregion* reg1,
> static int sbi_domain_used_memregions(const struct sbi_domain *dom)
> {
> int count = 0;
> - struct sbi_domain_memregion *reg;
> + const struct sbi_domain_memregion *reg;
>
> sbi_domain_for_each_memregion(dom, reg)
> count++;
> @@ -407,11 +404,6 @@ static int sanitize_domain(struct sbi_domain *dom)
> }
>
> /* Check memory regions */
> - if (!dom->regions) {
> - sbi_printf("%s: %s regions is NULL\n",
> - __func__, dom->name);
> - return SBI_EINVAL;
> - }
> sbi_domain_for_each_memregion(dom, reg) {
> if (!is_region_valid(reg)) {
> sbi_printf("%s: %s has invalid region base=0x%lx "
> @@ -550,7 +542,7 @@ void sbi_domain_dump(const struct sbi_domain *dom, const char *suffix)
> {
> u32 i, j, k;
> unsigned long rstart, rend;
> - struct sbi_domain_memregion *reg;
> + const struct sbi_domain_memregion *reg;
>
> sbi_printf("Domain%d Name %s: %s\n",
> dom->index, suffix, dom->name);
> @@ -738,8 +730,8 @@ static int root_add_memregion(const struct sbi_domain_memregion *reg)
> int root_memregs_count = sbi_domain_used_memregions(&root);
>
> /* Sanity checks */
> - if (!reg || domain_finalized || !root.regions ||
> - (ROOT_REGION_MAX <= root_memregs_count))
> + if (!reg || domain_finalized ||
> + (SBI_DOMAIN_MEMREGION_MAX <= root_memregs_count))
> return SBI_EINVAL;
>
> /* Check whether compatible region exists for the new one */
> @@ -901,12 +893,12 @@ int sbi_domain_finalize(struct sbi_scratch *scratch)
>
> int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
> {
> - int rc;
> - struct sbi_hartmask *root_hmask;
> - struct sbi_domain_memregion *root_memregs;
> - int root_memregs_count = 0;
> const struct sbi_platform *plat = sbi_platform_ptr(scratch);
> bool fw_single_region = sbi_platform_single_fw_region(plat);
> + struct sbi_domain_memregion *root_memregs = root.regions;
> + struct sbi_hartmask *root_hmask;
> + int root_memregs_count = 0;
> + int rc;
>
> SBI_INIT_LIST_HEAD(&domain_list);
>
> @@ -933,19 +925,11 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
> if (rc)
> goto fail_free_domain_hart_ptr_offset;
>
> - root_memregs = sbi_calloc(sizeof(*root_memregs), ROOT_REGION_MAX + 1);
> - if (!root_memregs) {
> - sbi_printf("%s: no memory for root regions\n", __func__);
> - rc = SBI_ENOMEM;
> - goto fail_deinit_context;
> - }
> - root.regions = root_memregs;
> -
> root_hmask = sbi_zalloc(sizeof(*root_hmask));
> if (!root_hmask) {
> sbi_printf("%s: no memory for root hartmask\n", __func__);
> rc = SBI_ENOMEM;
> - goto fail_free_root_memregs;
> + goto fail_deinit_context;
> }
> root.possible_harts = root_hmask;
>
> @@ -1014,8 +998,6 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid)
>
> fail_free_root_hmask:
> sbi_free(root_hmask);
> -fail_free_root_memregs:
> - sbi_free(root_memregs);
> fail_deinit_context:
> sbi_domain_context_deinit();
> fail_free_domain_hart_ptr_offset:
> diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c
> index 575fbdf0..e4cce8c3 100644
> --- a/lib/utils/fdt/fdt_domain.c
> +++ b/lib/utils/fdt/fdt_domain.c
> @@ -223,14 +223,12 @@ skip_device_disable:
> fdt_nop_node(fdt, poffset);
> }
>
> -#define FDT_DOMAIN_REGION_MAX_COUNT 16
> #define FDT_ROOT_REGION_INHERIT_M_ONLY 0
> #define FDT_ROOT_REGION_INHERIT_ALL 1
>
> struct parse_region_data {
> struct sbi_domain *dom;
> u32 region_count;
> - u32 max_regions;
> };
>
> static int __fdt_parse_region(const void *fdt, int domain_offset,
> @@ -257,7 +255,7 @@ static int __fdt_parse_region(const void *fdt, int domain_offset,
> return SBI_EINVAL;
>
> /* Find next region of the domain */
> - if (preg->max_regions <= preg->region_count)
> + if (SBI_DOMAIN_MEMREGION_MAX <= preg->region_count)
> return SBI_ENOSPC;
>
> /* Read "base" DT property */
> @@ -309,20 +307,13 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> if (!dom)
> return SBI_ENOMEM;
>
> - dom->regions = sbi_calloc(sizeof(*dom->regions),
> - FDT_DOMAIN_REGION_MAX_COUNT + 1);
> - if (!dom->regions) {
> - err = SBI_ENOMEM;
> - goto fail_free_domain;
> - }
> preg.dom = dom;
> preg.region_count = 0;
> - preg.max_regions = FDT_DOMAIN_REGION_MAX_COUNT;
>
> mask = sbi_zalloc(sizeof(*mask));
> if (!mask) {
> err = SBI_ENOMEM;
> - goto fail_free_regions;
> + goto fail_free_domain;
> }
>
> /* Read DT node name */
> @@ -405,7 +396,7 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
> if (!copy)
> continue;
>
> - if (preg.max_regions <= preg.region_count) {
> + if (SBI_DOMAIN_MEMREGION_MAX <= preg.region_count) {
> err = SBI_EINVAL;
> goto fail_free_all;
> }
> @@ -481,8 +472,6 @@ static int __fdt_parse_domain(const void *fdt, int domain_offset, void *opaque)
>
> fail_free_all:
> sbi_free(mask);
> -fail_free_regions:
> - sbi_free(dom->regions);
> fail_free_domain:
> sbi_free(dom);
> return err;
> diff --git a/platform/generic/mips/eyeq7h.c b/platform/generic/mips/eyeq7h.c
> index 30af096c..f08b5197 100644
> --- a/platform/generic/mips/eyeq7h.c
> +++ b/platform/generic/mips/eyeq7h.c
> @@ -120,7 +120,7 @@ static const struct sbi_hsm_device eyeq7h_hsm = {
> .hart_stop = mips_p8700_hart_stop,
> };
>
> -static struct sbi_domain_memregion *find_last_memregion(const struct sbi_domain *dom)
> +static struct sbi_domain_memregion *find_last_memregion(struct sbi_domain *dom)
> {
> struct sbi_domain_memregion *reg;
>
> @@ -128,7 +128,7 @@ static struct sbi_domain_memregion *find_last_memregion(const struct sbi_domain
> return --reg;
> }
>
> -static int fixup_dram_region(const struct sbi_domain *dom,
> +static int fixup_dram_region(struct sbi_domain *dom,
> struct sbi_domain_memregion *reg)
> {
> const void *fdt = fdt_get_address();
> @@ -297,7 +297,7 @@ static void eyeq7h_init_clusters(void)
>
> static int eyeq7h_early_init(bool cold_boot)
> {
> - const struct sbi_domain *dom;
> + struct sbi_domain *dom;
> struct sbi_domain_memregion *reg;
> int rc;
> unsigned long cm_base;
> --
> 2.43.0
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
Reviewed-by: Pawandeep Oza <pawandeep.oza at oss.qualcomm.com>
Tested-by: Pawandeep Oza <pawandeep.oza at oss.qualcomm.com>
More information about the opensbi
mailing list