From 9c9767504d4e2e48015642239cea954d17ea6bef Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 22 May 2026 17:54:17 -0500 Subject: [PATCH] lib: sbi: Drop fw_rw_offset alignment requirement for single fw region In a single fw region scheme, there is no separate PMP created for RW memory. The checks that opensbi does for the alignment between fw_start and fw_rw_start (using fw_rw_offset) and the power of 2 check for fw_rw_offset are no longer necessary. Update sbi_domain_init so that these checks are only done in the non single fw region scheme. Signed-off-by: Nicholas Piggin Co-developed-by: Anirudh Srinivasan Signed-off-by: Anirudh Srinivasan Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20260522-fw_rw_start_alignment-v1-1-362c17331541@oss.tenstorrent.com Signed-off-by: Anup Patel --- lib/sbi/sbi_domain.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c index 3df521fd..fa69170b 100644 --- a/lib/sbi/sbi_domain.c +++ b/lib/sbi/sbi_domain.c @@ -874,20 +874,23 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid) 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); SBI_INIT_LIST_HEAD(&domain_list); - if (scratch->fw_rw_offset == 0 || - (scratch->fw_rw_offset & (scratch->fw_rw_offset - 1)) != 0) { - sbi_printf("%s: fw_rw_offset is not a power of 2 (0x%lx)\n", - __func__, scratch->fw_rw_offset); - return SBI_EINVAL; - } - - if ((scratch->fw_start & (scratch->fw_rw_offset - 1)) != 0) { - sbi_printf("%s: fw_start and fw_rw_offset not aligned\n", - __func__); - return SBI_EINVAL; + if (!fw_single_region) { + if (scratch->fw_rw_offset == 0 || + (scratch->fw_rw_offset & (scratch->fw_rw_offset - 1)) != 0) { + sbi_printf("%s: fw_rw_offset is not a power of 2 (0x%lx)\n", + __func__, scratch->fw_rw_offset); + return SBI_EINVAL; + } + if ((scratch->fw_start & (scratch->fw_rw_offset - 1)) != 0) { + sbi_printf("%s: fw_start and fw_rw_offset not aligned\n", + __func__); + return SBI_EINVAL; + } } domain_hart_ptr_offset = sbi_scratch_alloc_type_offset(void *); @@ -916,7 +919,7 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid) root.possible_harts = root_hmask; /* Root domain firmware memory region */ - if (sbi_platform_single_fw_region(sbi_platform_ptr(scratch))) { + if (fw_single_region) { sbi_domain_memregion_init(scratch->fw_start, scratch->fw_size, (SBI_DOMAIN_MEMREGION_M_READABLE | SBI_DOMAIN_MEMREGION_M_WRITABLE |