[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