[PATCH v5 10/10] Fix PMA init for MMIO regions

Chao-ying Fu icebergfu at gmail.com
Mon May 19 14:58:47 PDT 2025


From: Vladimir Kondratiev <vladimir.kondratiev at mobileye.com>

Convey MMIO flag as specified by SBI_DOMAIN_MEMREGION_MMIO
to the pma_set(); use this flag to decide upon memory cacheability

Introduce non-architecture bit PMP_MMIO for this new flag, have it
out of valid bit mask for the PMPCFG register to avoid side effects

Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev at mobileye.com>
---
 include/sbi/riscv_asm.h |  2 ++
 lib/sbi/riscv_asm.c     | 10 +++-------
 lib/sbi/sbi_hart.c      | 13 +++++++++++++
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h
index ef48dc8..1bb2be7 100644
--- a/include/sbi/riscv_asm.h
+++ b/include/sbi/riscv_asm.h
@@ -215,6 +215,8 @@ int pmp_disable(unsigned int n);
 /* Check if the matching field is set */
 int is_pmp_entry_mapped(unsigned long entry);
 
+#define PMP_MMIO   _UL(0x100)
+
 int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
 	    unsigned long log2len);
 
diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c
index 7eb02cf..9f31c3e 100644
--- a/lib/sbi/riscv_asm.c
+++ b/lib/sbi/riscv_asm.c
@@ -311,8 +311,7 @@ int is_pmp_entry_mapped(unsigned long entry)
 }
 
 #ifdef CONFIG_PLATFORM_MIPS_P8700
-extern unsigned long _fw_start;
-static void pma_set(unsigned int n, unsigned long addr)
+static void pma_set(unsigned int n, unsigned long prot, unsigned long addr)
 {
 	int pmacfg_csr, pmacfg_shift;
 	unsigned long cfgmask;
@@ -324,10 +323,7 @@ static void pma_set(unsigned int n, unsigned long addr)
 
 	/* Read pmacfg to change cacheability */
 	pmacfg  = (csr_read_num(pmacfg_csr) & cfgmask);
-	if (addr >= (unsigned long)&_fw_start)
-		cca = CCA_CACHE_ENABLE | PMA_SPECULATION;
-	else
-		cca = CCA_CACHE_DISABLE;
+	cca = (prot & PMP_MMIO) ? CCA_CACHE_DISABLE : CCA_CACHE_ENABLE | PMA_SPECULATION;
 	pmacfg |= ((cca << pmacfg_shift) & ~cfgmask);
 	csr_write_num(pmacfg_csr, pmacfg);
 }
@@ -345,7 +341,7 @@ int pmp_set(unsigned int n, unsigned long prot, unsigned long addr,
 		return SBI_EINVAL;
 
 #ifdef CONFIG_PLATFORM_MIPS_P8700
-	pma_set(n, addr);
+	pma_set(n, prot, addr);
 #endif
 
 	/* calculate PMP register and offset */
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index fc4925b..ab56890 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -361,6 +361,13 @@ static unsigned int sbi_hart_get_smepmp_flags(struct sbi_scratch *scratch,
 			pmp_flags |= PMP_X;
 	}
 
+	/*
+	 * indicate whether it is MMIO, to be evaluated by code,
+	 * out of pmpcfg mask
+	 */
+	if (reg->flags & SBI_DOMAIN_MEMREGION_MMIO)
+		pmp_flags |= PMP_MMIO;
+
 	return pmp_flags;
 }
 
@@ -489,6 +496,12 @@ static int sbi_hart_oldpmp_configure(struct sbi_scratch *scratch,
 			pmp_flags |= PMP_W;
 		if (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
 			pmp_flags |= PMP_X;
+		/*
+		 * indicate whether it is MMIO, to be evaluated by code,
+		 * out of pmpcfg mask
+		 */
+		if (reg->flags & SBI_DOMAIN_MEMREGION_MMIO)
+			pmp_flags |= PMP_MMIO;
 
 		pmp_addr = reg->base >> PMP_SHIFT;
 		if (pmp_log2gran <= reg->order && pmp_addr < pmp_addr_max) {
-- 
2.47.1




More information about the opensbi mailing list