This commit is contained in:
Rose Thompson 2024-01-26 12:50:36 -06:00
commit cbc44a68ab
4 changed files with 72 additions and 32 deletions

View File

@ -246,6 +246,30 @@ coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerang
# never reaches this when ENVCFG_ADUE_1 because HPTW updates A bit first
coverage exclude -scope /dut/core/ifu/ifu/immu/immu/tlb/tlb/tlbcontrol -linerange [GetLineNum ../src/mmu/tlb/tlbcontrol.sv "assign PrePageFault"] -item e 1 -fecexprrow 18
###############
# HPTW exclusions
###############
# RV64GC HPTW never starts at L1_ADR
set line [GetLineNum ../src/mmu/hptw.sv "InitialWalkerState == L1_ADR"]
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item c 1 -feccondrow 2
# Never possible to get a page fault when neither reading nor writing
set line [GetLineNum ../src/mmu/hptw.sv "assign HPTWLoadPageFault"]
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item e 1 -fecexprrow 7
# Never possible to get a store page fault from an ITLB walk
set line [GetLineNum ../src/mmu/hptw.sv "assign HPTWStoreAmoPageFault"]
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item e 1 -fecexprrow 3
# Never possible to get Access = 0 on a nonleaf PTE with no OtherPageFault (because InvalidRead/Write will be 1 on the nonleaf)
set line [GetLineNum ../src/mmu/hptw.sv "assign HPTWUpdateDA"]
coverage exclude -scope /dut/core/lsu/lsu/hptw/hptw -linerange $line-$line -item e 1 -fecexprrow 3
###############
# Other exclusions
###############
# IMMU PMP does not support CBO instructions
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcbom"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ../src/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboz"]

View File

@ -11,7 +11,7 @@
--override cpu/mvendorid=0x602
--override cpu/marchid=0x24
--override refRoot/cpu/tvec_align=64
--override refRoot/cpu/envcfg_mask=1
--override refRoot/cpu/envcfg_mask=1 # dh 1/26/24 this should be deleted when ImperasDV is updated to allow envcfg.FIOM to be written
# bit manipulation
--override cpu/add_Extensions=B

View File

@ -93,7 +93,6 @@ module hptw import cvw::*; #(parameter cvw_t P) (
logic [P.PA_BITS-1:0] HPTWReadAdr;
logic SelHPTWAdr;
logic [P.XLEN+1:0] HPTWAdrExt;
logic ITLBMissOrUpdateDAF;
logic DTLBMissOrUpdateDAM;
logic LSUAccessFaultM;
logic [P.PA_BITS-1:0] HPTWAdr;
@ -113,12 +112,12 @@ module hptw import cvw::*; #(parameter cvw_t P) (
// map hptw access faults onto either the original LSU load/store fault or instruction access fault
assign LSUAccessFaultM = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM;
assign HPTWFaultM = LSUAccessFaultM | PBMTFaultM;
assign HPTWLoadAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
assign HPTWLoadAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
assign HPTWStoreAmoAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[0];
assign HPTWInstrAccessFault = LSUAccessFaultM & ~DTLBWalk;
assign HPTWLoadPageFault = PBMTFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
assign HPTWStoreAmoPageFault = PBMTFaultM & DTLBWalk & MemRWM[0];
assign HPTWInstrPageFault = PBMTFaultM & ~DTLBWalk;
assign HPTWLoadPageFault = PBMTFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
assign HPTWStoreAmoPageFault = PBMTFaultM & DTLBWalk & MemRWM[0];
assign HPTWInstrPageFault = PBMTFaultM & ~DTLBWalk;
flopr #(7) HPTWAccesFaultReg(clk, reset, {TakeHPTWFault, HPTWLoadAccessFault, HPTWStoreAmoAccessFault, HPTWInstrAccessFault,
HPTWLoadPageFault, HPTWStoreAmoPageFault, HPTWInstrPageFault},
@ -127,17 +126,18 @@ module hptw import cvw::*; #(parameter cvw_t P) (
assign TakeHPTWFault = WalkerState != IDLE;
assign LoadAccessFaultM = TakeHPTWFault ? HPTWLoadAccessFaultDelay : LSULoadAccessFaultM;
// Improve timing by taking HPTW faults off critical path because these are multicycle operations anyway
assign LoadAccessFaultM = TakeHPTWFault ? HPTWLoadAccessFaultDelay : LSULoadAccessFaultM;
assign StoreAmoAccessFaultM = TakeHPTWFault ? HPTWStoreAmoAccessFaultDelay : LSUStoreAmoAccessFaultM;
assign HPTWInstrAccessFaultF = TakeHPTWFault ? HPTWInstrAccessFaultDelay : 1'b0;
assign LoadPageFaultM = TakeHPTWFault ? HPTWLoadPageFaultDelay : LSULoadPageFaultM;
assign StoreAmoPageFaultM = TakeHPTWFault ? HPTWStoreAmoPageFaultDelay : LSUStoreAmoPageFaultM;
assign HPTWInstrPageFaultF = TakeHPTWFault ? HPTWInstrPageFaultDelay : 1'b0;
assign LoadPageFaultM = TakeHPTWFault ? HPTWLoadPageFaultDelay : LSULoadPageFaultM;
assign StoreAmoPageFaultM = TakeHPTWFault ? HPTWStoreAmoPageFaultDelay : LSUStoreAmoPageFaultM;
assign HPTWInstrPageFaultF = TakeHPTWFault ? HPTWInstrPageFaultDelay : 1'b0;
// Extract bits from CSRs and inputs
assign SvMode = SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS];
assign BasePageTablePPN = SATP_REGW[P.PPN_BITS-1:0];
assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissOrUpdateDAF);
assign TLBMiss = (DTLBMissOrUpdateDAM | ITLBMissF);
// Determine which address to translate
mux2 #(P.XLEN) vadrmux(PCSpillF, IEUAdrExtM[P.XLEN-1:0], DTLBWalk, TranslationVAdr);
@ -203,7 +203,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
// memory access. If there is the PTE needs to be updated seting Access
// and possibly also Dirty. Dirty is set if the operation is a store/amo.
// However any other fault should not cause the update, and updates are in software when ENVCFG_ADUE = 0
assign HPTWUpdateDA = ValidLeafPTE & (~Accessed | SetDirty) & ENVCFG_ADUE & ~OtherPageFault;
assign HPTWUpdateDA = ValidLeafPTE & (~Accessed | SetDirty) & ENVCFG_ADUE & ~OtherPageFault;
assign HPTWRW[0] = (WalkerState == UPDATE_PTE); // HPTWRW[0] will always be 0 if ADUE = 0 because HPTWUpdateDA will be 0 so WalkerState never is UPDATE_PTE
assign UpdatePTE = (WalkerState == LEAF) & HPTWUpdateDA; // UpdatePTE will always be 0 if ADUE = 0 because HPTWUpdateDA will be 0
@ -283,7 +283,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState);
always_comb
case (WalkerState)
IDLE: if (TLBMiss & ~DCacheBusStallM) NextWalkerState = InitialWalkerState;
IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState;
else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // first access in SV48
L3_RD: if (DCacheBusStallM) NextWalkerState = L3_RD;
@ -294,7 +294,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
L2_RD: if (DCacheBusStallM) NextWalkerState = L2_RD;
else if(HPTWFaultM) NextWalkerState = FAULT;
else NextWalkerState = L1_ADR;
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
else NextWalkerState = LEAF;
L1_RD: if (DCacheBusStallM) NextWalkerState = L1_RD;
else if(HPTWFaultM) NextWalkerState = FAULT;
@ -320,9 +320,8 @@ module hptw import cvw::*; #(parameter cvw_t P) (
// The FSM directly transistions to IDLE to ready for the next operation when the delayed version will not be high.
assign HPTWAccessFaultDelay = HPTWLoadAccessFaultDelay | HPTWStoreAmoAccessFaultDelay | HPTWInstrAccessFaultDelay;
assign HPTWStall = (WalkerState != IDLE & WalkerState != FAULT) | (WalkerState == IDLE & TLBMiss);
assign HPTWStall = (WalkerState != IDLE & WalkerState != FAULT) | (WalkerState == IDLE & TLBMiss);
assign ITLBMissOrUpdateDAF = ITLBMissF | (P.SVADU_SUPPORTED & InstrUpdateDAF);
assign DTLBMissOrUpdateDAM = DTLBMissM | (P.SVADU_SUPPORTED & DataUpdateDAM);
// HTPW address/data/control muxing

View File

@ -123,6 +123,27 @@ main:
li t0, 0x80806000
jalr ra, t0 # jump to page to exercise ITLB with PBMT !=0 when ENVCFG_PMTE=0
# Load and AMO operation on page table entry that causes access fault
li t0, 0x81000000
lw t1, 0(t0)
sfence.vma
amoadd.w t0, t0, 0(t0)
# Access fault on top level PTE
li t0, 0x1000000000
lw t1, 0(t0)
# Access fault on megapage
li t0, 0x81400000
lw t1, 0(t0)
# AMO operation on page table entry that causes page fault due to malformed PBMT
li t0, 0x81200000
jalr t0 # Attempt to fetch instruction from address causing faulty page walk
lw t1, 0(t0)
sfence.vma
amoadd.w t0, t0, 0(t0)
# change back to default trap handler after checking everything that might cause an instruction page fault
jal changetodefaulthandler
@ -178,8 +199,6 @@ main:
li a0, 1
ecall
# wrap up
li a0, 3 # switch back to machine mode because code at 0x80000000 may not have clean page table entry
ecall
@ -237,32 +256,30 @@ ipf:
.align 16
# root Page table situated at 0x80010000
pagetable:
.8byte 0x200044C1 # 0x00000000-0x80_00000000: PTE at 0x80011000 C1 dirty, accessed, valid
.8byte 0x200044C1 # 0x00000000-0x7F_FFFFFFFF: PTE at 0x80011000 C1 dirty, accessed, valid
.8byte 0x00000000000010CF # misaligned terapage at 0x80_00000000
.8byte 0x00000000000000CF # access fault terapage at 0x100_00000000
# next page table at 0x80011000
.align 12
.8byte 0x00000000000010CF # misaligned gigapage at 0x00000000
.8byte 0x00000000200058C1 # PTE for pages at 0x40000000
.8byte 0x00000000200058C1 # PTE for pages at 0x40000000 pointing to 0x80150000
.8byte 0x00000000200048C1 # gigapage at 0x80000000 pointing to 0x80120000
# Next page table at 0x80012000 for gigapage at 0x80000000
.align 12
.8byte 0x0000000020004CC1 # for VA starting at 80000000 (pointer to NAPOT 64 KiB pages)
.8byte 0x0000000020004CC1 # for VA starting at 80000000 (pointer to NAPOT 64 KiB pages Page table at 80013000)
.8byte 0x0000000020014CCF # for VA starting at 80200000 (misaligned megapage)
.8byte 0x00000000200050C1 # for VA starting at 80400000 (bad PBMT pages)
.8byte 0x00000000200050C1 # for VA starting at 80400000 (bad PBMT pages page table at 0x80014000)
.8byte 0x4000000020004CC1 # for VA starting at 80600000 (bad entry: nonleaf PTE can't have PBMT != 0)
.8byte 0x00000000200054C1 # for VA starting at 80800000 (testing rwx permissiosn with cbom/cboz)
.8byte 0x0000000020004CC1 # for VA starting at 80A00000 (pointer to NAPOT 64 KiB pages like at 80000000)
.8byte 0x00000000200054C1 # for VA starting at 80800000 (testing rwx permissiosn with cbom/cboz . page table at 0x80015000)
.8byte 0x0000000020004CC1 # for VA starting at 80A00000 (pointer to NAPOT 64 KiB pages like at 80000000. page table at 0x80013000)
.8byte 0x0F00000020004CCF # for VA starting at 80C00000 (bad reserved field in bits 60:54)
.8byte 0x000000002000000F # for VA starting at 80E00000 (not dirty or accessed)
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x000000002000000F # for VA starting at 80E00000 (megapage not dirty or accessed)
.8byte 0x0000000000004CC1 # for VA starting at 81000000 (nonleaf pointing to unimplemented memory causes access fault)
.8byte 0x4000000020004CC1 # for VA starting at 81200000 (nonleaf with PBMT nonzero causes page fault)
.8byte 0x00000000000000CF # for VA starting at 81400000 (megapage with access fault)
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
@ -288,7 +305,7 @@ pagetable:
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
# Leaf page table at 0x80013000 with NAPOT pages
# Leaf page table at 0x80013000 with 64 KiB NAPOT pages
.align 12
#80000000
.8byte 0xA0000000200020CF