[PATCH 1/8] lib: sbi_hart: move sbi_hart_get_smepmp_flags() to sbi_domain

Yu-Chien Peter Lin
2025-08-14T14:16:58Z

Move sbi_hart_get_smepmp_flags() from sbi_hart.c to sbi_domain.c and
rename it to sbi_domain_get_smepmp_flags() to better reflect its
purpose of converting domain memory region flags to PMP configuration.

The function's original parameters (scratch and dom) were unused, so
this refactoring also makes the function cleaner.

Signed-off-by: Yu-Chien Peter Lin <peter.lin@sifive.com>
---
include/sbi/sbi_domain.h | 7 +++++
lib/sbi/sbi_domain.c | 58 ++++++++++++++++++++++++++++++++++
lib/sbi/sbi_hart.c | 67 ++--------------------------------------
3 files changed, 67 insertions(+), 65 deletions(-)

diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h
index e9cff0b1..8a51f289 100644
--- a/include/sbi/sbi_domain.h
+++ b/include/sbi/sbi_domain.h
@@ -249,6 +249,13 @@ void sbi_domain_memregion_init(unsigned long addr,
unsigned long flags,
struct sbi_domain_memregion *reg);

+/*
+ * Returns Smepmp pmpcfg.LRWX encoding for a given region flag.
+ *
+ * @param reg pointer to memory region with flags encoded with permissions
+ */
+unsigned int sbi_domain_get_smepmp_flags(struct sbi_domain_memregion *reg);
+
/**
* Check whether we can access specified address for given mode and
* memory region flags under a domain
diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c
index 461c7e53..1fa56b6a 100644
--- a/lib/sbi/sbi_domain.c
+++ b/lib/sbi/sbi_domain.c
@@ -122,6 +122,64 @@ void sbi_domain_memregion_init(unsigned long addr,
}
}

+unsigned int sbi_domain_get_smepmp_flags(struct sbi_domain_memregion *reg)
+{
+ unsigned int pmp_flags = 0;
+
+ if (SBI_DOMAIN_MEMREGION_IS_SHARED(reg->flags)) {
+ /* Read only for both M and SU modes */
+ if (SBI_DOMAIN_MEMREGION_IS_SUR_MR(reg->flags))
+ pmp_flags = (PMP_L | PMP_R | PMP_W | PMP_X);
+
+ /* Execute for SU but Read/Execute for M mode */
+ else if (SBI_DOMAIN_MEMREGION_IS_SUX_MRX(reg->flags))
+ /* locked region */
+ pmp_flags = (PMP_L | PMP_W | PMP_X);
+
+ /* Execute only for both M and SU modes */
+ else if (SBI_DOMAIN_MEMREGION_IS_SUX_MX(reg->flags))
+ pmp_flags = (PMP_L | PMP_W);
+
+ /* Read/Write for both M and SU modes */
+ else if (SBI_DOMAIN_MEMREGION_IS_SURW_MRW(reg->flags))
+ pmp_flags = (PMP_W | PMP_X);
+
+ /* Read only for SU mode but Read/Write for M mode */
+ else if (SBI_DOMAIN_MEMREGION_IS_SUR_MRW(reg->flags))
+ pmp_flags = (PMP_W);
+ } else if (SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(reg->flags)) {
+ /*
+ * When smepmp is supported and used, M region cannot have RWX
+ * permissions on any region.
+ */
+ if ((reg->flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK)
+ == SBI_DOMAIN_MEMREGION_M_RWX) {
+ sbi_printf("%s: M-mode only regions cannot have"
+ "RWX permissions\n", __func__);
+ return 0;
+ }
+
+ /* M-mode only access regions are always locked */
+ pmp_flags |= PMP_L;
+
+ if (reg->flags & SBI_DOMAIN_MEMREGION_M_READABLE)
+ pmp_flags |= PMP_R;
+ if (reg->flags & SBI_DOMAIN_MEMREGION_M_WRITABLE)
+ pmp_flags |= PMP_W;
+ if (reg->flags & SBI_DOMAIN_MEMREGION_M_EXECUTABLE)
+ pmp_flags |= PMP_X;
+ } else if (SBI_DOMAIN_MEMREGION_SU_ONLY_ACCESS(reg->flags)) {
+ if (reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE)
+ pmp_flags |= PMP_R;
+ if (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE)
+ pmp_flags |= PMP_W;
+ if (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
+ pmp_flags |= PMP_X;
+ }
+
+ return pmp_flags;
+}
+
bool sbi_domain_check_addr(const struct sbi_domain *dom,
unsigned long addr, unsigned long mode,
unsigned long access_flags)
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 6a2d7d6f..c5c3ecb4 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -301,69 +301,6 @@ unsigned int sbi_hart_mhpm_bits(struct sbi_scratch *scratch)
return hfeatures->mhpm_bits;
}

-/*
- * Returns Smepmp flags for a given domain and region based on permissions.
- */
-static unsigned int sbi_hart_get_smepmp_flags(struct sbi_scratch *scratch,
- struct sbi_domain *dom,
- struct sbi_domain_memregion *reg)
-{
- unsigned int pmp_flags = 0;
-
- if (SBI_DOMAIN_MEMREGION_IS_SHARED(reg->flags)) {
- /* Read only for both M and SU modes */
- if (SBI_DOMAIN_MEMREGION_IS_SUR_MR(reg->flags))
- pmp_flags = (PMP_L | PMP_R | PMP_W | PMP_X);
-
- /* Execute for SU but Read/Execute for M mode */
- else if (SBI_DOMAIN_MEMREGION_IS_SUX_MRX(reg->flags))
- /* locked region */
- pmp_flags = (PMP_L | PMP_W | PMP_X);
-
- /* Execute only for both M and SU modes */
- else if (SBI_DOMAIN_MEMREGION_IS_SUX_MX(reg->flags))
- pmp_flags = (PMP_L | PMP_W);
-
- /* Read/Write for both M and SU modes */
- else if (SBI_DOMAIN_MEMREGION_IS_SURW_MRW(reg->flags))
- pmp_flags = (PMP_W | PMP_X);
-
- /* Read only for SU mode but Read/Write for M mode */
- else if (SBI_DOMAIN_MEMREGION_IS_SUR_MRW(reg->flags))
- pmp_flags = (PMP_W);
- } else if (SBI_DOMAIN_MEMREGION_M_ONLY_ACCESS(reg->flags)) {
- /*
- * When smepmp is supported and used, M region cannot have RWX
- * permissions on any region.
- */
- if ((reg->flags & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK)
- == SBI_DOMAIN_MEMREGION_M_RWX) {
- sbi_printf("%s: M-mode only regions cannot have"
- "RWX permissions\n", __func__);
- return 0;
- }
-
- /* M-mode only access regions are always locked */
- pmp_flags |= PMP_L;
-
- if (reg->flags & SBI_DOMAIN_MEMREGION_M_READABLE)
- pmp_flags |= PMP_R;
- if (reg->flags & SBI_DOMAIN_MEMREGION_M_WRITABLE)
- pmp_flags |= PMP_W;
- if (reg->flags & SBI_DOMAIN_MEMREGION_M_EXECUTABLE)
- pmp_flags |= PMP_X;
- } else if (SBI_DOMAIN_MEMREGION_SU_ONLY_ACCESS(reg->flags)) {
- if (reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE)
- pmp_flags |= PMP_R;
- if (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE)
- pmp_flags |= PMP_W;
- if (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
- pmp_flags |= PMP_X;
- }
-
- return pmp_flags;
-}
-
static void sbi_hart_smepmp_set(struct sbi_scratch *scratch,
struct sbi_domain *dom,
struct sbi_domain_memregion *reg,
@@ -420,7 +357,7 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch,
continue;
}

- pmp_flags = sbi_hart_get_smepmp_flags(scratch, dom, reg);
+ pmp_flags = sbi_domain_get_smepmp_flags(reg);
if (!pmp_flags)
return 0;

@@ -446,7 +383,7 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch,
continue;
}

- pmp_flags = sbi_hart_get_smepmp_flags(scratch, dom, reg);
+ pmp_flags = sbi_domain_get_smepmp_flags(reg);
if (!pmp_flags)
return 0;