From 286ec26c699a8a3ab58feb3afe6c0c38df11bacd Mon Sep 17 00:00:00 2001 From: Yanqin Li Date: Thu, 19 Sep 2024 16:21:01 +0800 Subject: [PATCH 1/2] feat(svpbmt): support PBMTE --- src/isa/riscv64/init.c | 5 ++++- src/isa/riscv64/system/mmu.c | 17 +++++++++++++---- src/isa/riscv64/system/priv.c | 18 ++++++++++++------ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/isa/riscv64/init.c b/src/isa/riscv64/init.c index 3296a743..5c348bb9 100644 --- a/src/isa/riscv64/init.c +++ b/src/isa/riscv64/init.c @@ -81,7 +81,10 @@ void init_isa() { // as opensbi and linux not support smrnmi, so we init nmie = 1 to pass ci mnstatus->nmie = 1; #endif //CONFIG_RV_SMRNMI - +#ifdef CONFIG_RV_SVPBMT + menvcfg->pbmte = 1; + henvcfg->pbmte = 1; +#endif //CONFIG_RV_SVPBMT #ifdef CONFIG_RV_PMP_ENTRY_16 pmpcfg0->val = 0; pmpcfg2->val = 0; diff --git a/src/isa/riscv64/system/mmu.c b/src/isa/riscv64/system/mmu.c index 9dcf194e..1a93e8f3 100644 --- a/src/isa/riscv64/system/mmu.c +++ b/src/isa/riscv64/system/mmu.c @@ -21,6 +21,7 @@ #include #include "../local-include/csr.h" #include "../local-include/intr.h" +#include "../local-include/rtl.h" typedef union PageTableEntry { struct { @@ -216,6 +217,7 @@ paddr_t gpa_stage(paddr_t gpaddr, vaddr_t vaddr, int type, int trap_type, bool i } max_level = 3; } + bool pbmte = menvcfg->pbmte; word_t pg_base = PGBASE(hgatp->ppn); int level; word_t p_pte; @@ -245,7 +247,7 @@ paddr_t gpa_stage(paddr_t gpaddr, vaddr_t vaddr, int type, int trap_type, bool i if (level < 0) { break; } } else if (!pte.v || (!pte.r && pte.w) || pte.pad) { break; - } else if (ISNDEF(CONFIG_RV_SVPBMT) && pte.pbmt) { + } else if ((ISNDEF(CONFIG_RV_SVPBMT) || !pbmte) && pte.pbmt) { break; } else if (pte.pbmt == 3) { break; @@ -323,6 +325,13 @@ static paddr_t ptw(vaddr_t vaddr, int type) { pg_base = PGBASE(vsatp->ppn); max_level = vsatp->mode == SATP_MODE_Sv39 ? 3 : 4; } +#endif + bool pbmte = menvcfg->pbmte; +#ifdef CONFIG_RVH + if(virt){ + // henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0 + pbmte = henvcfg->pbmte & menvcfg->pbmte; + } #endif word_t p_pte; // pte pointer PTE pte; @@ -341,11 +350,11 @@ static paddr_t ptw(vaddr_t vaddr, int type) { #ifdef CONFIG_MULTICORE_DIFF pte.val = golden_pmem_read(p_pte, PTE_SIZE, 0, 0, 0); #else - #ifdef CONFIG_RVH +#ifdef CONFIG_RVH if(virt){ p_pte = gpa_stage(p_pte, vaddr, MEM_TYPE_READ, type, false, true); } - #endif //CONFIG_RVH +#endif //CONFIG_RVH pte.val = pte_read(p_pte, type, MODE_S, vaddr); #endif #ifdef CONFIG_SHARE @@ -357,7 +366,7 @@ static paddr_t ptw(vaddr_t vaddr, int type) { pg_base = PGBASE((uint64_t)pte.ppn); if (!pte.v || (!pte.r && pte.w) || pte.pad) { goto bad; - } else if (ISNDEF(CONFIG_RV_SVPBMT) && pte.pbmt) { + } else if ((ISNDEF(CONFIG_RV_SVPBMT) || !pbmte) && pte.pbmt) { goto bad; } else if (pte.pbmt == 3) { goto bad; diff --git a/src/isa/riscv64/system/priv.c b/src/isa/riscv64/system/priv.c index c0483781..979ed39f 100644 --- a/src/isa/riscv64/system/priv.c +++ b/src/isa/riscv64/system/priv.c @@ -258,11 +258,14 @@ static inline word_t* csr_decode(uint32_t addr) { #define HSTATUS_WMASK 0 #endif -#define MENVCFG_WMASK_STCE MUXDEF(CONFIG_RV_SSTC, (0x1UL << 63), 0) -#define MENVCFG_WMASK_DTE MUXDEF(CONFIG_RV_SSDBLTRP, (0x1UL << 59), 0) +#define MENVCFG_STCE (0x1UL << 63) +#define MENVCFG_DTE (0x1UL << 59) +#define MENVCFG_PBMTE (0x1UL << 62) + #define MENVCFG_WMASK ( \ - MENVCFG_WMASK_STCE | \ - MENVCFG_WMASK_DTE \ + MUXDEF(CONFIG_RV_SSTC, MENVCFG_STCE, 0) | \ + MUXDEF(CONFIG_RV_SSDBLTRP, MENVCFG_DTE, 0) | \ + MUXDEF(CONFIG_RV_SVPBMT, MENVCFG_PBMTE, 0) \ ) #define HENVCFG_WMASK MENVCFG_WMASK @@ -725,7 +728,8 @@ if (is_read(hie)) { return mie->val & HIE_RMASK & (mideleg->val | MID if (is_read(hvip)) { return mip->val & HVIP_MASK;} if (is_read(henvcfg)) { uint64_t henvcfg_out = henvcfg->val; - henvcfg_out &= menvcfg->val & (MENVCFG_WMASK_STCE | MENVCFG_WMASK_DTE); + /* henvcfg.stce/dte/pbmte is read_only 0 when menvcfg.stce/dte/pbmte = 0 */ + henvcfg_out &= menvcfg->val | ~(MENVCFG_STCE | MENVCFG_DTE | MENVCFG_PBMTE); return henvcfg_out & HENVCFG_WMASK; } #ifdef CONFIG_RV_AIA @@ -950,7 +954,9 @@ static inline void csr_write(word_t *dest, word_t src) { mip->val = mask_bitset(mip->val, HVIP_MASK, src); } else if(is_write(henvcfg)){ - henvcfg->val = mask_bitset(henvcfg->val, HENVCFG_WMASK, src); + /* ignore writes to the henvcfg fields when read-only 0 */ + const uint64_t mask = menvcfg->val | ~(MENVCFG_STCE | MENVCFG_DTE | MENVCFG_PBMTE); + henvcfg->val = mask_bitset(henvcfg->val, HENVCFG_WMASK & mask, src); #ifdef CONFIG_RV_SSDBLTRP if(henvcfg->dte == 0) { vsstatus->sdt = 0; From ab9504d37d59ef73d1912efd9d2fa55396840338 Mon Sep 17 00:00:00 2001 From: Yanqin Li Date: Thu, 19 Sep 2024 17:32:22 +0800 Subject: [PATCH 2/2] feat(svpbmt): code style unified and remove read-only write ignore for no exact statement in spec --- src/isa/riscv64/system/priv.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/isa/riscv64/system/priv.c b/src/isa/riscv64/system/priv.c index 979ed39f..2a8ed8c2 100644 --- a/src/isa/riscv64/system/priv.c +++ b/src/isa/riscv64/system/priv.c @@ -258,14 +258,16 @@ static inline word_t* csr_decode(uint32_t addr) { #define HSTATUS_WMASK 0 #endif -#define MENVCFG_STCE (0x1UL << 63) -#define MENVCFG_DTE (0x1UL << 59) -#define MENVCFG_PBMTE (0x1UL << 62) - +#define MENVCFG_RMASK_STCE (0x1UL << 63) +#define MENVCFG_RMASK_DTE (0x1UL << 59) +#define MENVCFG_RMASK_PBMTE (0x1UL << 62) +#define MENVCFG_WMASK_STCE MUXDEF(CONFIG_RV_SSTC, (0x1UL << 63), 0) +#define MENVCFG_WMASK_DTE MUXDEF(CONFIG_RV_SSDBLTRP, (0x1UL << 59), 0) +#define MENVCFG_WMASK_PBMTE MUXDEF(CONFIG_RV_SSDBLTRP, (0x1UL << 62), 0) #define MENVCFG_WMASK ( \ - MUXDEF(CONFIG_RV_SSTC, MENVCFG_STCE, 0) | \ - MUXDEF(CONFIG_RV_SSDBLTRP, MENVCFG_DTE, 0) | \ - MUXDEF(CONFIG_RV_SVPBMT, MENVCFG_PBMTE, 0) \ + MENVCFG_WMASK_STCE | \ + MENVCFG_WMASK_PBMTE | \ + MENVCFG_WMASK_DTE \ ) #define HENVCFG_WMASK MENVCFG_WMASK @@ -729,7 +731,7 @@ if (is_read(hvip)) { return mip->val & HVIP_MASK;} if (is_read(henvcfg)) { uint64_t henvcfg_out = henvcfg->val; /* henvcfg.stce/dte/pbmte is read_only 0 when menvcfg.stce/dte/pbmte = 0 */ - henvcfg_out &= menvcfg->val | ~(MENVCFG_STCE | MENVCFG_DTE | MENVCFG_PBMTE); + henvcfg_out &= menvcfg->val | ~(MENVCFG_RMASK_STCE | MENVCFG_RMASK_DTE | MENVCFG_RMASK_PBMTE); return henvcfg_out & HENVCFG_WMASK; } #ifdef CONFIG_RV_AIA @@ -954,9 +956,7 @@ static inline void csr_write(word_t *dest, word_t src) { mip->val = mask_bitset(mip->val, HVIP_MASK, src); } else if(is_write(henvcfg)){ - /* ignore writes to the henvcfg fields when read-only 0 */ - const uint64_t mask = menvcfg->val | ~(MENVCFG_STCE | MENVCFG_DTE | MENVCFG_PBMTE); - henvcfg->val = mask_bitset(henvcfg->val, HENVCFG_WMASK & mask, src); + henvcfg->val = mask_bitset(henvcfg->val, HENVCFG_WMASK, src); #ifdef CONFIG_RV_SSDBLTRP if(henvcfg->dte == 0) { vsstatus->sdt = 0;