From 3620a10c0be7135db500db4322cd58a07cb48636 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 26 Jan 2024 14:55:51 -0800 Subject: [PATCH 1/2] Improved hptw and I CacheWays coverage --- sim/coverage-exclusions-rv64gc.do | 8 ++++++++ src/cache/cache.sv | 5 +++-- src/cache/cacheway.sv | 6 +++--- tests/coverage/fround.S | 18 +++++++++++++++++ tests/coverage/ifu.S | 23 ++++++++++++++++++++++ tests/coverage/tlbmisc.S | 32 +++++++++++++++++++++++++++++-- 6 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 tests/coverage/fround.S diff --git a/sim/coverage-exclusions-rv64gc.do b/sim/coverage-exclusions-rv64gc.do index d64b730be..06e1b6e9f 100644 --- a/sim/coverage-exclusions-rv64gc.do +++ b/sim/coverage-exclusions-rv64gc.do @@ -93,6 +93,11 @@ for {set i 0} {$i < $numcacheways} {incr i} { # below: flushD can't go high during an icache write b/c of pipeline stall coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache SetValidEN"] -item e 1 -fecexprrow 4 coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: cache ClearValidEN"] -item e 1 -fecexprrow 4 + # No CMO to clear valid bits of I$ + coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "// exclusion-tag: icache ClearValidBits"] + coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "// exclusion-tag: icache ClearValidWay"] -item e 1 + # No dirty ways in read-only I$ + coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "// exclusion-tag: icache DirtyWay"] -item e 1 } ## D$ Exclusions. @@ -246,6 +251,9 @@ 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 ############### diff --git a/src/cache/cache.sv b/src/cache/cache.sv index c8f707904..86aba57a0 100644 --- a/src/cache/cache.sv +++ b/src/cache/cache.sv @@ -199,7 +199,7 @@ module cache import cvw::*; #(parameter cvw_t P, // Flush logic ///////////////////////////////////////////////////////////////////////////////////////////// - if (!READ_ONLY_CACHE) begin:flushlogic + if (!READ_ONLY_CACHE) begin:flushlogic // D$ can be flushed // Flush address (line number) assign ResetOrFlushCntRst = reset | FlushCntRst; flopenr #(SETLEN) FlushAdrReg(clk, ResetOrFlushCntRst, FlushAdrCntEn, FlushAdrP1, NextFlushAdr); @@ -213,7 +213,8 @@ module cache import cvw::*; #(parameter cvw_t P, else assign NextFlushWay = FlushWay[NUMWAYS-1]; assign FlushWayFlag = FlushWay[NUMWAYS-1]; end // block: flushlogic - else begin:flushlogic + else begin:flushlogic // I$ is never flushed because it is never dirty + assign FlushWay = 0; assign FlushWayFlag = 0; assign FlushAdrFlag = 0; end diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index d7a5ae34a..cd9d08687 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -100,7 +100,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, ///////////////////////////////////////////////////////////////////////////////////////////// assign SetValidWay = SetValid & SelData; - assign ClearValidWay = ClearValid & SelData; + assign ClearValidWay = ClearValid & SelData; // exclusion-tag: icache ClearValidWay assign SetDirtyWay = SetDirty & SelData; // exclusion-tag: icache SetDirtyWay assign ClearDirtyWay = ClearDirty & SelData; assign SelectedWriteWordEn = (SetValidWay | SetDirtyWay) & ~FlushStage; // exclusion-tag: icache SelectedWiteWordEn @@ -121,7 +121,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, // AND portion of distributed tag multiplexer assign TagWay = SelData ? ReadTag : '0; // AND part of AOMux assign HitDirtyWay = Dirty & ValidWay; - assign DirtyWay = SelDirty & HitDirtyWay; + assign DirtyWay = SelDirty & HitDirtyWay; // exclusion-tag: icache DirtyWay assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay; flop #(1) InvalidateCacheReg(clk, InvalidateCache, InvalidateCacheDelay); @@ -163,7 +163,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, ValidWay <= #1 ValidBits[CacheSetTag]; if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway else if (SetValidEN) ValidBits[CacheSetData] <= #1 SetValidWay; - else if (ClearValidEN) ValidBits[CacheSetData] <= #1 '0; + else if (ClearValidEN) ValidBits[CacheSetData] <= #1 '0; // exclusion-tag: icache ClearValidBits end end diff --git a/tests/coverage/fround.S b/tests/coverage/fround.S new file mode 100644 index 000000000..7d469d773 --- /dev/null +++ b/tests/coverage/fround.S @@ -0,0 +1,18 @@ +// fround.s + +#include "WALLY-init-lib.h" + +# run-elf.bash find this in project description +main: + + bseti t0, zero, 14 # turn on FPU + csrs mstatus, t0 + + # test fround behavior on NaN + li t0, 0x7FC00001 + fmv.w.x ft0, t0 + fround.s ft1, ft0 + j done + +.align 10 +data_start: diff --git a/tests/coverage/ifu.S b/tests/coverage/ifu.S index f387774bf..0866326cc 100644 --- a/tests/coverage/ifu.S +++ b/tests/coverage/ifu.S @@ -74,8 +74,31 @@ main: .hword 0x9C7D // Reserved instruction from line 187 with op = 01, Instr[15:10] = 100111, Instr[6:5] = 11, and 0's everywhere else + # exercise all the cache ways + j way0code +# stress test cache ways by loading stuff from each one and then doing fence.i to invalidate +.align 12 +way0code: + jal way1code + fence.i + j done +.align 12 +way1code: + j way2code + +.align 12 +way2code: + j way3code + +.align 12 +way3code: + j way00code + +.align 12 +way00code: + ret j done diff --git a/tests/coverage/tlbmisc.S b/tests/coverage/tlbmisc.S index a51436e3a..eeb1c7d34 100644 --- a/tests/coverage/tlbmisc.S +++ b/tests/coverage/tlbmisc.S @@ -133,10 +133,18 @@ main: li t0, 0x1000000000 lw t1, 0(t0) + # Bad PBMT on top level PTE + li t0, 0x1800000000 + lw t1, 0(t0) + # Access fault on megapage li t0, 0x81400000 lw t1, 0(t0) + # Access fault walking page tables at megapage level + li t0, 0xC0000000 + 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 @@ -144,6 +152,13 @@ main: sfence.vma amoadd.w t0, t0, 0(t0) + # point top-level page table to an illegal address and verify it faults + li t0, 0x9000000000070000 # trap handler at non-existing memory location + csrw satp, t0 # should cause trap + sfence.vma + nop + + # change back to default trap handler after checking everything that might cause an instruction page fault jal changetodefaulthandler @@ -199,6 +214,9 @@ 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 @@ -229,12 +247,14 @@ instructionpagefaulthandler: csrw mepc, ra # go back to calling function mret -.align 4 # trap handlers must be aligned to multiple of 4 +.align 4 # trap handlers must be aligned to multiple of 16 ipf_handler: # Load trap handler stack pointer tp csrrw tp, mscratch, tp # swap MSCRATCH and tp sd t0, 0(tp) # Save t0 and t1 on the stack sd t1, -8(tp) + li t5, 0x9000000000080010 + csrw satp, t5 # make sure we are pointing to the root page table csrr t0, mcause # Check the cause li t1, 8 # is it an ecall trap? andi t0, t0, 0xFC # if CAUSE = 8, 9, or 11 @@ -251,20 +271,28 @@ ipf: csrrw tp, mscratch, tp # restore tp mret # return from trap +.align 4 # trap handlers must be aligned to multiple of 16 +fixsatptraphandler: + li t5, 0x9000000000080010 # fix satp entry to normal page table root + csrw satp, t5 + mret + .data .align 16 # root Page table situated at 0x80010000 pagetable: - .8byte 0x200044C1 # 0x00000000-0x7F_FFFFFFFF: PTE at 0x80011000 C1 dirty, accessed, valid + .8byte 0x200044C1 # VA 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 + .8byte 0x40000000200044C1 # Bad PBMT at VA 0x180_0000000 # next page table at 0x80011000 .align 12 .8byte 0x00000000000010CF # misaligned gigapage at 0x00000000 .8byte 0x00000000200058C1 # PTE for pages at 0x40000000 pointing to 0x80150000 .8byte 0x00000000200048C1 # gigapage at 0x80000000 pointing to 0x80120000 + .8byte 0x00000000000000C1 # gigapage at VA 0xC0000000 causes access fault # Next page table at 0x80012000 for gigapage at 0x80000000 From e8dde265be782d89080036a8d4805e46d09fbc82 Mon Sep 17 00:00:00 2001 From: David Harris Date: Fri, 26 Jan 2024 16:14:36 -0800 Subject: [PATCH 2/2] More coverage: CacheWay --- sim/coverage-exclusions-rv64gc.do | 2 ++ src/cache/cacheway.sv | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sim/coverage-exclusions-rv64gc.do b/sim/coverage-exclusions-rv64gc.do index 06e1b6e9f..e39128f5a 100644 --- a/sim/coverage-exclusions-rv64gc.do +++ b/sim/coverage-exclusions-rv64gc.do @@ -109,6 +109,8 @@ coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/cachefsm -linerange [Get set numcacheways 4 for {set i 0} {$i < $numcacheways} {incr i} { coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: dcache invalidateway"] -item bes 1 -fecexprrow 4 + # InvalidateCacheDelay is always 0 for D$ because it is flushed, not invalidated + coverage exclude -scope /dut/core/lsu/bus/dcache/dcache/CacheWays[$i] -linerange [GetLineNum ../src/cache/cacheway.sv "exclusion-tag: dcache HitWay"] -item 3 1 -fecexprrow 2 # FlushStage=1 will never happen when SetValidWay=1 since a pipeline stall is asserted by the cache in the fetch stage, which happens before # going into the WRITE_LINE state (and asserting SetValidWay). No TrapM can fire and since StallW is high, a stallM caused by WFIStallM would not cause a flushW. diff --git a/src/cache/cacheway.sv b/src/cache/cacheway.sv index cd9d08687..9c5523cec 100644 --- a/src/cache/cacheway.sv +++ b/src/cache/cacheway.sv @@ -122,7 +122,7 @@ module cacheway import cvw::*; #(parameter cvw_t P, assign TagWay = SelData ? ReadTag : '0; // AND part of AOMux assign HitDirtyWay = Dirty & ValidWay; assign DirtyWay = SelDirty & HitDirtyWay; // exclusion-tag: icache DirtyWay - assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay; + assign HitWay = ValidWay & (ReadTag == PAdr[PA_BITS-1:OFFSETLEN+INDEXLEN]) & ~InvalidateCacheDelay; // exclusion-tag: dcache HitWay flop #(1) InvalidateCacheReg(clk, InvalidateCache, InvalidateCacheDelay);