From af435ab59192e6f3cd5a7a013e6d5fe3edb0b6c6 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 23 Mar 2022 10:26:17 -0500 Subject: [PATCH 1/6] Another change required for forcing to work correctly with MIE/MIP and SIE/SIP. --- pipelined/src/privileged/csri.sv | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/pipelined/src/privileged/csri.sv b/pipelined/src/privileged/csri.sv index 8a3f42fd..b3f0f157 100644 --- a/pipelined/src/privileged/csri.sv +++ b/pipelined/src/privileged/csri.sv @@ -95,20 +95,22 @@ module csri #(parameter // else if (WriteUIEM) IE_REGW = (CSRWriteValM & 12'h111) | (IE_REGW & 12'hAAA); // only U field // restricted views of registers - // Add MEIP read-only signal - assign IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable}; + assign IP_REGW = {IntInM[11],1'b0,IP_REGW_writeable}; + + always_comb begin:regs + // Add MEIP read-only signal // Machine Mode - assign MIP_REGW = IP_REGW; - assign MIE_REGW = IE_REGW; + MIP_REGW = IP_REGW; + MIE_REGW = IE_REGW; - // Supervisor mode - if (`S_SUPPORTED) begin - assign SIP_REGW = IP_REGW & MIDELEG_REGW[11:0] & 'h222; // only delegated interrupts visible - assign SIE_REGW = IE_REGW & MIDELEG_REGW[11:0] & 'h222; - end else begin - assign SIP_REGW = 12'b0; - assign SIE_REGW = 12'b0; + // Supervisor mode + if (`S_SUPPORTED) begin + SIP_REGW = IP_REGW & MIDELEG_REGW[11:0] & 'h222; // only delegated interrupts visible + SIE_REGW = IE_REGW & MIDELEG_REGW[11:0] & 'h222; + end else begin + SIP_REGW = 12'b0; + SIE_REGW = 12'b0; + end end - endmodule From 6f6663cd67263ccdbe3fb4a2783fc8c6d355517f Mon Sep 17 00:00:00 2001 From: bbracker Date: Fri, 25 Mar 2022 01:02:22 +0000 Subject: [PATCH 2/6] fix multiple-context PLIC checkpoint generation --- linux/testvector-generation/parsePlicState.py | 2 +- pipelined/testbench/testbench-linux.sv | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/linux/testvector-generation/parsePlicState.py b/linux/testvector-generation/parsePlicState.py index 35ef00b1..b917bfdc 100755 --- a/linux/testvector-generation/parsePlicState.py +++ b/linux/testvector-generation/parsePlicState.py @@ -101,7 +101,7 @@ with open(outDir+'checkpoint-PLIC_INT_PRIORITY', 'w') as outFile: outFile.write(stripZeroes(word[2:])+'\n') with open(outDir+'checkpoint-PLIC_INT_ENABLE', 'w') as outFile: for word in plicIntEnableArray: - outFile.write(word+'\n') + outFile.write(stripZeroes(word)+'\n') with open(outDir+'checkpoint-PLIC_THRESHOLD', 'w') as outFile: for word in plicIntPriorityThresholdArray: outFile.write(stripZeroes(word[2:])+'\n') diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 36153d73..12950b63 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -266,6 +266,19 @@ module testbench; end \ end + `define INIT_CHECKPOINT_PACKED_ARRAY(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ + `MAKE_CHECKPOINT_INIT_SIGNAL(SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ + for (i=ARRAY_MIN; i" in the signal name `define INIT_CHECKPOINT_GENBLK_ARRAY(SIGNAL_BASE,SIGNAL,DIM,ARRAY_MAX,ARRAY_MIN) \ @@ -296,6 +309,7 @@ module testbench; end \ end + genvar i; `INIT_CHECKPOINT_SIMPLE_ARRAY(RF, [`XLEN-1:0],31,1); `INIT_CHECKPOINT_SIMPLE_ARRAY(HPMCOUNTER, [`XLEN-1:0],`COUNTERS-1,0); `INIT_CHECKPOINT_VAL(PC, [`XLEN-1:0]); @@ -333,9 +347,9 @@ module testbench; //`INIT_CHECKPOINT_VAL(UART_LSR, [7:0]); //`INIT_CHECKPOINT_VAL(UART_MSR, [7:0]); `INIT_CHECKPOINT_VAL(UART_SCR, [7:0]); - `INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1); - `INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0); - `INIT_CHECKPOINT_SIMPLE_ARRAY(PLIC_THRESHOLD, [2:0],1,0); + `INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_PRIORITY, [2:0],`PLIC_NUM_SRC,1); + `INIT_CHECKPOINT_PACKED_ARRAY(PLIC_INT_ENABLE, [`PLIC_NUM_SRC:1],1,0); + `INIT_CHECKPOINT_PACKED_ARRAY(PLIC_THRESHOLD, [2:0],1,0); integer memFile; integer readResult; From 61c714ebe6e65885f728da5e3f22be5b085d8ac0 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 25 Mar 2022 13:10:31 -0500 Subject: [PATCH 3/6] I think this version of csri matches what is required in the spec. ExtIntS should not be written into the SEIP register bit. --- pipelined/src/privileged/csri.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelined/src/privileged/csri.sv b/pipelined/src/privileged/csri.sv index 7eff9496..b9a302d2 100644 --- a/pipelined/src/privileged/csri.sv +++ b/pipelined/src/privileged/csri.sv @@ -58,7 +58,7 @@ module csri #(parameter always_comb begin IntInM = 0; IntInM[11] = ExtIntM; // MEIP - IntInM[9] = ExtIntS | (ExtIntM & MIDELEG_REGW[9]); // SEIP + IntInM[9] = (ExtIntM & MIDELEG_REGW[9]); // SEIP IntInM[7] = TimerIntM; // MTIP IntInM[5] = TimerIntM & MIDELEG_REGW[5]; // STIP IntInM[3] = SwIntM; // MSIP From 7ae1d141911386b9d4fecd8c1e2ca3c5c8c609ee Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Fri, 25 Mar 2022 22:57:03 +0000 Subject: [PATCH 4/6] added basic trap tests that do not pass regression yet. updated signature adresses --- pipelined/testbench/tests.vh | 24 +- .../rv64i_m/privilege/Makefrag | 3 +- .../references/WALLY-trap-01.reference_output | 244 +++++++++--------- .../rv64i_m/privilege/src/WALLY-TEST-LIB-64.h | 231 ++++++++++++----- .../rv64i_m/privilege/src/WALLY-trap-01.S | 52 ++-- 5 files changed, 321 insertions(+), 233 deletions(-) diff --git a/pipelined/testbench/tests.vh b/pipelined/testbench/tests.vh index 8ae9bc19..687878bc 100644 --- a/pipelined/testbench/tests.vh +++ b/pipelined/testbench/tests.vh @@ -1450,29 +1450,31 @@ string imperas32f[] = '{ string wally64priv[] = '{ `WALLYTEST, - "rv64i_m/privilege/WALLY-CSR-permission-s-01", "004080", + "rv64i_m/privilege/WALLY-CSR-permission-s-01", "0050a0", //"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-M", "005070", //"rv64i_m/privilege/WALLY-CSR-PERMISSIONS-S", "003070", - "rv64i_m/privilege/WALLY-CSR-permission-u-01", "005080", + "rv64i_m/privilege/WALLY-CSR-permission-u-01", "0050a0", // "rv64i_m/privilege/WALLY-MARCHID", "003070", /* "rv64i_m/privilege/WALLY-MCAUSE", "003070", "rv64i_m/privilege/WALLY-MEDELEG", "003070", "rv64i_m/privilege/WALLY-MHARTID", "003070", "rv64i_m/privilege/WALLY-MIMPID", "003070",*/ - "rv64i_m/privilege/WALLY-minfo-01", "004080", - "rv64i_m/privilege/WALLY-misa-01", "004080", - "rv64i_m/privilege/WALLY-MMU-SV39", "004080", - "rv64i_m/privilege/WALLY-MMU-SV48", "004080", + "rv64i_m/privilege/WALLY-minfo-01", "0040a0", + "rv64i_m/privilege/WALLY-misa-01", "0040a0", + "rv64i_m/privilege/WALLY-MMU-SV39", "0040a0", + "rv64i_m/privilege/WALLY-MMU-SV48", "0040a0", /* "rv64i_m/privilege/WALLY-MSTATUS", "002070", "rv64i_m/privilege/WALLY-MTVEC", "002070", "rv64i_m/privilege/WALLY-MVENDORID", "003070", */ - "rv64i_m/privilege/WALLY-PMA", "004080", - "rv64i_m/privilege/WALLY-PMP", "004080", + "rv64i_m/privilege/WALLY-PMA", "0040a0", + "rv64i_m/privilege/WALLY-PMP", "0040a0", // "rv64i_m/privilege/WALLY-SCAUSE", "002070", - "rv64i_m/privilege/WALLY-scratch-01", "004080", - "rv64i_m/privilege/WALLY-sscratch-s-01", "004080" + "rv64i_m/privilege/WALLY-scratch-01", "0040a0", + "rv64i_m/privilege/WALLY-sscratch-s-01", "0040a0" +// "rv64i_m/privilege/WALLY-trap-01", "0040a0" // "rv64i_m/privilege/WALLY-STVEC", "002070", -// "rv64i_m/privilege/WALLY-UCAUSE", "002070" +// "rv64i_m/privilege/WALLY-UCAUSE", "002070", + }; string wally64periph[] = '{ diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag index adf32839..73ef3c20 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/Makefrag @@ -56,7 +56,8 @@ target_tests_nosim = \ WALLY-MIMPID \ WALLY-MVENDORID \ WALLY-CSR-PERMISSIONS-M \ - WALLY-CSR-PERMISSIONS-S + WALLY-CSR-PERMISSIONS-S \ + WALLY-trap-01 \ # Have all 0's in references! #WALLY-MEPC \ #WALLY-SEPC \ diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output index 6fbd0f38..eef583de 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-trap-01.reference_output @@ -1,3 +1,93 @@ +00000aaa # Test 5.3.1.4: readback value from writing mie to enable interrupts +00000000 +00000001 # mcause from an instruction access fault +00000000 +00000000 # mtval of faulting instruction address (0x0) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +00000002 # mcause from an Illegal instruction +00000000 +00000000 # mtval of faulting instruction (0x0) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +00000003 # mcause from Breakpoint +00000000 +800003ec # mtval of breakpoint instruction adress (0x800003ec) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +00000004 # mcause from load address misaligned +00000000 +800003f5 # mtval of misaligned address (0x800003f5) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +00000005 # mcause from load access +00000000 +00000000 # mtval of accessed adress (0x0) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +00000006 # mcause from store misaligned +00000000 +80000411 # mtval of address with misaligned store instr (0x80000410) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +00000007 # mcause from store access +00000000 +00000000 # mtval of accessed address (0x0) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +0000000b # mcause from M mode ecall +00000000 +00000000 # mtval of ecall (*** defined to be zero for now) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +00000008 # mcause from U mode ecall +00000000 +00000000 # mtval of ecall (*** defined to be zero for now) +00000000 +00000080 # masked out mstatus.MPP = 00 (from U mode), mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +00000009 # mcause from S mode ecall +00000000 +00000000 # mtval of ecall (*** defined to be zero for now) +00000000 +00000880 # masked out mstatus.MPP = 01 (from S mode), mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +000007ec # value to indicate a vectored interrupts +00000000 +00000007 # mcause value from m time interrupt +80000000 +00000000 # mtval for mtime interrupt (0x0) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +000007ec # value to indicate a vectored interrupts +00000000 +00000001 # mcause value from m soft interrupt +80000000 +00000000 # mtval for msoft interrupt (0x0) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +000007ec # value to indicate a vectored interrupts +00000000 +0000000b # mcause value from m ext interrupt +80000000 +00000000 # mtval for mext interrupt (0x0) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +0000b309 # medeleg after attempted write of all 1's (only some bits are writeable) +00000000 +00000222 # mideleg after attempted write of all 1's (only some bits are writeable) +00000000 00000001 # Test 5.3.1.4: mcause from an instruction access fault 00000000 00000000 # mtval of faulting instruction address (0x0) @@ -12,49 +102,67 @@ 00000000 00000003 # mcause from Breakpoint 00000000 -00000000 # mtval of breakpoint instruction adress (*** Determined from make) +800003ec # mtval of breakpoint instruction adress (0x800003ec) 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 00000004 # mcause from load address misaligned 00000000 -00000000 # mtval of misaligned address (*** Determined from make) +800003f5 # mtval of misaligned address (0x800003f5) 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 00000005 # mcause from load access 00000000 -00000000 # mtval of address with access faulting instr (*** Determined from make) +00000000 # mtval of accessed adress (0x0) 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 00000006 # mcause from store misaligned 00000000 -00000000 # mtval of address with misaligned store instr (*** Determined from make) +80000411 # mtval of address with misaligned store instr (0x80000410) 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 00000007 # mcause from store access 00000000 -00000000 # mtval of address with faulting store instr (*** Determined from make) +00000000 # mtval of accessed address (0x0) 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 0000000b # mcause from M mode ecall 00000000 -00000000 # mtval of +00000000 # mtval of ecall (*** defined to be zero for now) 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 -00000008 # mcause from U mode ecall +000007ec # value to indicate a vectored interrupts 00000000 -00000000 # mtval of +00000007 # mcause value from time interrupt +80000000 +00000000 # mtval for mtime interrupt (0x0) 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 -00000009 # mcause from S mode ecall +000007ec # value to indicate a vectored interrupts 00000000 -00000000 # mtval of address with faulting store instr (*** Determined from make) +00000001 # mcause value from m soft interrupt +80000000 +00000000 # mtval for msoft interrupt (0x0) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +000007ec # value to indicate a vectored interrupts +00000000 +0000000b # mcause value from m ext interrupt +80000000 +00000000 # mtval for mext interrupt (0x0) +00000000 +00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 +00000000 +0000000b # mcause from M mode ecall from test termination +00000000 +00000000 # mtval of ecall (*** defined to be zero for now) 00000000 00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0 00000000 @@ -964,119 +1072,3 @@ deadbeef deadbeef deadbeef deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef -deadbeef diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h index 99e000fa..534fd433 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-TEST-LIB-64.h @@ -55,6 +55,99 @@ RVTEST_CODE_BEGIN .endm +// Code to trigger traps goes here so we have consistent mtvals for instruction adresses +// Even if more tests are added. +.macro CAUSE_TRAP_TRIGGERS +j end_trap_triggers + +// The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines +// This effectively includes everything that isn't to do with page faults (virtual memory) + +cause_instr_addr_misaligned: + // cause a misaligned address trap + auipc x28, 0 // get current PC, which is aligned + addi x28, x28, 0x3 // add 1 to pc to create misaligned address + jr x28 // cause instruction address midaligned trap + ret + +cause_instr_access: + la x28, 0x0 // address zero is an address with no memory + sd x1, -8(sp) // push the return adress ontot the stack + addi sp, sp, -8 + jalr x28 // cause instruction access trap + ld x1, 0(sp) // pop return adress back from the stack + addi sp, sp, 8 + ret + +cause_illegal_instr: + .word 0x00000000 // a 32 bit zros is an illegal instruction + ret + +cause_breakpnt: // **** + ebreak + ret + +cause_load_addr_misaligned: + auipc x28, 0 // get current PC, which is aligned + addi x28, x28, 1 + lw x29, 0(x28) // load from a misaligned address + ret + +cause_load_acc: + la x28, 0 // 0 is an address with no memory + lw x29, 0(x28) // load from unimplemented address + ret + +cause_store_addr_misaligned: + auipc x28, 0 // get current PC, which is aligned + addi x28, x28, 1 + sw x29, 0(x28) // store to a misaligned address + ret + +cause_store_acc: + la x28, 0 // 0 is an address with no memory + sw x29, 0(x28) // store to unimplemented address + ret + +cause_ecall: + // *** ASSUMES you have already gone to the mode you need to call this from. + ecall + ret + +cause_time_interrupt: + // The following code works for both RV32 and RV64. + // RV64 alone would be easier using double-word adds and stores + li x28, 0x100 // Desired offset from the present time + la x29, 0x02004000 // MTIMECMP register in CLINT + la x30, 0x0200BFF8 // MTIME register in CLINT + lw x7, 0(x30) // low word of MTIME + lw x31, 4(x30) // high word of MTIME + add x28, x7, x28 // add desired offset to the current time + bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound) + addi x31, x31, 1 // if wrap, increment most significant word + sw x31,4(x29) // store into most significant word of MTIMECMP +nowrap: + sw x28, 0(x29) // store into least significant word of MTIMECMP + loop: j loop // wait until interrupt occurs + ret + +cause_soft_interrupt: + la x28, 0x02000000 // MSIP register in CLINT + li x29, 1 // 1 in the lsb + sw x29, 0(x28) // Write MSIP bit + ret + +cause_ext_interrupt: + li x28, 0x10060000 // load base GPIO memory location + li x29, 0x1 + sw x29, 8(x28) // enable the first pin as an output + sw x29, 28(x28) // set first pin to high interrupt enable + sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt) + ret + +end_trap_triggers: +.endm + .macro TRAP_HANDLER MODE, VECTORED=1, DEBUG=0 // MODE decides which mode this trap handler will be taken in (M or S mode) // Vectored decides whether interrumpts are handled with the vector table at trap_handler_MODE (1) @@ -577,7 +670,7 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a // The previous CSR value before write attempt // *** Most likely 0x2, the mcause for illegal instruction if we don't have write or read access li x30, 0xbad // load bad value to be overwritten by csrr - li x29, \VAL + li x29, \VAL\() csrw \CSR\(), x29 csrr x30, \CSR sd x30, 0(x6) @@ -627,86 +720,86 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a addi x16, x16, 8 .endm -// The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines -// This effectively includes everything that isn't to do with page faults (virtual memory) +// // The following tests involve causing many of the interrupts and exceptions that are easily done in a few lines +// // This effectively includes everything that isn't to do with page faults (virtual memory) -.macro CAUSE_INSTR_ADDR_MISALIGNED - // cause a misaligned address trap - auipc x28, 0 // get current PC, which is aligned - addi x28, x28, 0x1 // add 1 to pc to create misaligned address - jalr x28 // cause instruction address midaligned trap -.endm +// .macro CAUSE_INSTR_ADDR_MISALIGNED +// // cause a misaligned address trap +// auipc x28, 0 // get current PC, which is aligned +// addi x28, x28, 0x1 // add 1 to pc to create misaligned address +// jalr x28 // cause instruction address midaligned trap +// .endm -.macro CAUSE_INSTR_ACCESS - la x28, 0x0 // address zero is an address with no memory - jalr x28 // cause instruction access trap -.endm +// .macro CAUSE_INSTR_ACCESS +// la x28, 0x0 // address zero is an address with no memory +// jalr x28 // cause instruction access trap +// .endm -.macro CAUSE_ILLEGAL_INSTR - .word 0x00000000 // a 32 bit zros is an illegal instruction -.endm +// .macro CAUSE_ILLEGAL_INSTR +// .word 0x00000000 // a 32 bit zros is an illegal instruction +// .endm -.macro CAUSE_BREAKPNT // **** - ebreak -.endm +// .macro CAUSE_BREAKPNT // **** +// ebreak +// .endm -.macro CAUSE_LOAD_ADDR_MISALIGNED - auipc x28, 0 // get current PC, which is aligned - addi x28, x28, 1 - lw x29, 0(x28) // load from a misaligned address -.endm +// .macro CAUSE_LOAD_ADDR_MISALIGNED +// auipc x28, 0 // get current PC, which is aligned +// addi x28, x28, 1 +// lw x29, 0(x28) // load from a misaligned address +// .endm -.macro CAUSE_LOAD_ACC - la x28, 0 // 0 is an address with no memory - lw x29, 0(x28) // load from unimplemented address -.endm +// .macro CAUSE_LOAD_ACC +// la x28, 0 // 0 is an address with no memory +// lw x29, 0(x28) // load from unimplemented address +// .endm -.macro CAUSE_STORE_ADDR_MISALIGNED - auipc x28, 0 // get current PC, which is aligned - addi x28, x28, 1 - sw x29, 0(x28) // store to a misaligned address -.endm +// .macro CAUSE_STORE_ADDR_MISALIGNED +// auipc x28, 0 // get current PC, which is aligned +// addi x28, x28, 1 +// sw x29, 0(x28) // store to a misaligned address +// .endm -.macro CAUSE_STORE_ACC - la x28, 0 // 0 is an address with no memory - sw x29, 0(x28) // store to unimplemented address -.endm +// .macro CAUSE_STORE_ACC +// la x28, 0 // 0 is an address with no memory +// sw x29, 0(x28) // store to unimplemented address +// .endm -.macro CAUSE_ECALL - // *** ASSUMES you have already gone to the mode you need to call this from. - ecall -.endm +// .macro CAUSE_ECALL +// // *** ASSUMES you have already gone to the mode you need to call this from. +// ecall +// .endm -.macro CAUSE_TIME_INTERRUPT - // The following code works for both RV32 and RV64. - // RV64 alone would be easier using double-word adds and stores - li x28, 0x100 // Desired offset from the present time - la x29, 0x02004000 // MTIMECMP register in CLINT - la x30, 0x0200BFF8 // MTIME register in CLINT - lw x7, 0(x30) // low word of MTIME - lw x31, 4(x30) // high word of MTIME - add x28, x7, x28 // add desired offset to the current time - bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound) - addi x31, x31, 1 // if wrap, increment most significant word - sw x31,4(x29) // store into most significant word of MTIMECMP -nowrap: - sw x28, 0(x29) // store into least significant word of MTIMECMP - loop: j loop // wait until interrupt occurs -.endm +// .macro CAUSE_TIME_INTERRUPT +// // The following code works for both RV32 and RV64. +// // RV64 alone would be easier using double-word adds and stores +// li x28, 0x100 // Desired offset from the present time +// la x29, 0x02004000 // MTIMECMP register in CLINT +// la x30, 0x0200BFF8 // MTIME register in CLINT +// lw x7, 0(x30) // low word of MTIME +// lw x31, 4(x30) // high word of MTIME +// add x28, x7, x28 // add desired offset to the current time +// bgtu x28, x7, nowrap // check new time exceeds current time (no wraparound) +// addi x31, x31, 1 // if wrap, increment most significant word +// sw x31,4(x29) // store into most significant word of MTIMECMP +// nowrap: +// sw x28, 0(x29) // store into least significant word of MTIMECMP +// loop: j loop // wait until interrupt occurs +// .endm -.macro CAUSE_SOFT_INTERRUPT - la x28, 0x02000000 // MSIP register in CLINT - li x29, 1 // 1 in the lsb - sw x29, 0(x28) // Write MSIP bit -.endm +// .macro CAUSE_SOFT_INTERRUPT +// la x28, 0x02000000 // MSIP register in CLINT +// li x29, 1 // 1 in the lsb +// sw x29, 0(x28) // Write MSIP bit +// .endm -.macro CAUSE_EXT_INTERRUPT - li x28, 0x10060000 // load base GPIO memory location - li x29, 0x1 - sw x29, 8(x28) // enable the first pin as an output - sw x29, 28(x28) // set first pin to high interrupt enable - sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt) -.endm +// .macro CAUSE_EXT_INTERRUPT +// li x28, 0x10060000 // load base GPIO memory location +// li x29, 0x1 +// sw x29, 8(x28) // enable the first pin as an output +// sw x29, 28(x28) // set first pin to high interrupt enable +// sw x29, 40(x28) // write a 1 to the first output pin (cause interrupt) +// .endm .macro END_TESTS // invokes one final ecall to return to machine mode then terminates this program, so the output is diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S index be1ca650..45d34c34 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-trap-01.S @@ -25,50 +25,50 @@ INIT_TESTS +CAUSE_TRAP_TRIGGERS // initialize code that will cause traps for consistent mtval addresses + TRAP_HANDLER m, DEBUG=1 // turn on recording mtval and status bits on traps li x28, 0x8 csrs mstatus, x28 // set mstatus.MIE bit to 1 -// WRITE_READ_CSR mie, 0xFFFF *** commented out until I can get the trap handler (and spike for time interrupts) to work correctly with interrupts +WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources // *** commented out until I can get the trap handler (and spike for time interrupts) to work correctly with interrupts // test 5.3.1.4 Basic trap tests -// CAUSE_INSTR_ADDR_MISALIGNED //skipped becuase this exception may be impossible when compressed instructions are enabled) -CAUSE_INSTR_ACCESS -CAUSE_ILLEGAL_INSTR -CAUSE_BREAKPNT -CAUSE_LOAD_ADDR_MISALIGNED -CAUSE_LOAD_ACC -CAUSE_STORE_ADDR_MISALIGNED -CAUSE_STORE_ACC +// jal cause_instr_addr_misaligned //skipped becuase this exception may be impossible when compressed instructions are enabled) +jal cause_instr_access +jal cause_illegal_instr +jal cause_breakpnt +jal cause_load_addr_misaligned +jal cause_load_acc +jal cause_store_addr_misaligned +jal cause_store_acc GOTO_U_MODE // Causes M mode ecall GOTO_S_MODE // Causes U mode ecall GOTO_M_MODE // Causes S mode ecall -// CAUSE_TIME_INTERRUPT *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen. -// CAUSE_SOFT_INTERRUPT *** exiting out of the trap handler after these is current;y broken -// CAUSE_EXT_INTERRUPT +jal cause_time_interrupt // *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen. +jal cause_soft_interrupt // *** exiting out of the trap handler after these is current;y broken +jal cause_ext_interrupt // try the traps again with mideleg = medeleg = all 1's to ensure traps still go to M mode from M mode WRITE_READ_CSR medeleg, 0xFFFFFFFFFFFFFFFF WRITE_READ_CSR mideleg, 0xFFFFFFFFFFFFFFFF -// CAUSE_INSTR_ADDR_MISALIGNED //skipped becuase this exception may be impossible when compressed instructions are enabled) -CAUSE_INSTR_ACCESS -CAUSE_ILLEGAL_INSTR -CAUSE_BREAKPNT -CAUSE_LOAD_ADDR_MISALIGNED -CAUSE_LOAD_ACC -CAUSE_STORE_ADDR_MISALIGNED -CAUSE_STORE_ACC -CAUSE_ECALL // M mode ecall -// GOTO_U_MODE // leave these untested since we only need to ensure that from M mode are not delegated -// GOTO_S_MODE +// jal cause_instr_addr_misaligned //skipped becuase this exception may be impossible when compressed instructions are enabled) +jal cause_instr_access +jal cause_illegal_instr +jal cause_breakpnt +jal cause_load_addr_misaligned +jal cause_load_acc +jal cause_store_addr_misaligned +jal cause_store_acc +jal cause_ecall // M mode ecall -// CAUSE_TIME_INTERRUPT *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen. -// CAUSE_SOFT_INTERRUPT *** exiting out of the trap handler after these is current;y broken -// CAUSE_EXT_INTERRUPT +jal cause_time_interrupt // *** intentionally causing this trap seems difficult in spike. although it is possible for it to accidentally happen. +jal cause_soft_interrupt // *** exiting out of the trap handler after these is current;y broken +jal cause_ext_interrupt END_TESTS From 62a330c290a907054d65abfb2dff45d08602125e Mon Sep 17 00:00:00 2001 From: Skylar Litz Date: Sat, 26 Mar 2022 21:28:32 +0000 Subject: [PATCH 5/6] update to match new filesystem organization --- pipelined/regression/buildrootBugFinder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipelined/regression/buildrootBugFinder.py b/pipelined/regression/buildrootBugFinder.py index b6639e71..89a838d2 100755 --- a/pipelined/regression/buildrootBugFinder.py +++ b/pipelined/regression/buildrootBugFinder.py @@ -4,7 +4,7 @@ import sys, os, subprocess def main(): maxGoodCount = 400e6 # num instrs that execute sucessfully starting from 0 currInstrCount = maxGoodCount - linuxTestvectors = "../../tests/linux-testgen/linux-testvectors" + linuxTestvectors = "/opt/riscv/linux-testvectors" if not os.path.exists(linuxTestvectors): sys.stderr.write("Error: Linux testvectors not found at "+linuxTestvectors+"\n") exit(1) @@ -22,7 +22,7 @@ def main(): break checkpoint = checkpointList[0] logFile = logDir+"checkpoint"+str(checkpoint)+".log" - runCommand="{\nvsim -c < Date: Sat, 26 Mar 2022 21:28:57 +0000 Subject: [PATCH 6/6] add AtemptedInstructionCount signal --- pipelined/regression/linux-wave.do | 4 +--- pipelined/testbench/testbench-linux.sv | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pipelined/regression/linux-wave.do b/pipelined/regression/linux-wave.do index 1d59dcbf..770b3d34 100644 --- a/pipelined/regression/linux-wave.do +++ b/pipelined/regression/linux-wave.do @@ -4,6 +4,7 @@ add wave -noupdate /testbench/clk add wave -noupdate /testbench/reset add wave -noupdate /testbench/reset_ext add wave -noupdate -radix unsigned /testbench/InstrCountW +add wave -noupdate -radix unsigned /testbench/AttemptedInstructionCount add wave -noupdate /testbench/dut/core/SATP_REGW add wave -noupdate /testbench/dut/core/IllegalFPUInstrD add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/BPPredWrongE @@ -388,7 +389,6 @@ add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/cor add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PTE add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissF add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissOrDAFaultF -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBMissM add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBWriteF add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBWriteM add wave -noupdate -group AHB -color Gold /testbench/dut/core/ebu/BusState @@ -526,9 +526,7 @@ add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/TakeSpillF add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/SpillF add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/IFUCacheBusStallF add wave -noupdate -color Yellow /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DAPageFault -add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/OtherPageFault add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissF -add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/Accessed add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/WriteAccess add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/TLBPageFault TreeUpdate [SetDefaultTree] diff --git a/pipelined/testbench/testbench-linux.sv b/pipelined/testbench/testbench-linux.sv index 12950b63..da623315 100644 --- a/pipelined/testbench/testbench-linux.sv +++ b/pipelined/testbench/testbench-linux.sv @@ -176,6 +176,7 @@ module testbench; integer CheckMIPFutureM; integer CheckSIPFutureE; integer CheckSIPFutureM; + logic [`XLEN-1:0] AttemptedInstructionCount; // Useful Aliases `define RF dut.core.ieu.dp.regf.rf `define PC dut.core.ifu.pcreg.q @@ -380,11 +381,13 @@ module testbench; traceFileM = $fopen({testvectorDir,"all.txt"}, "r"); traceFileE = $fopen({testvectorDir,"all.txt"}, "r"); InstrCountW = '0; + AttemptedInstructionCount = '0; end else begin // checkpoint //$readmemh({checkpointDir,"ram.txt"}, dut.uncore.ram.ram.RAM); traceFileE = $fopen({checkpointDir,"all.txt"}, "r"); traceFileM = $fopen({checkpointDir,"all.txt"}, "r"); InstrCountW = CHECKPOINT; + AttemptedInstructionCount = CHECKPOINT; // manual checkpoint initializations that don't neatly fit into MACRO force {`STATUS_TSR,`STATUS_TW,`STATUS_TVM,`STATUS_MXR,`STATUS_SUM,`STATUS_MPRV} = initMSTATUS[0][22:17]; force {`STATUS_FS,`STATUS_MPP} = initMSTATUS[0][14:11]; @@ -440,6 +443,9 @@ module testbench; for(index``STAGE = 0; index``STAGE < line``STAGE.len(); index``STAGE++) begin \ //$display("char = %s", line``STAGE[index]); \ if (line``STAGE[index``STAGE] == " " | line``STAGE[index``STAGE] == "\n") begin \ + if (line``STAGE[index``STAGE] == "\n" & `"STAGE`"=="M") begin \ + AttemptedInstructionCount += 1; \ + end \ EndIndex``STAGE = index``STAGE; \ ExpectedTokens``STAGE[TokenIndex``STAGE] = line``STAGE.substr(StartIndex``STAGE, EndIndex``STAGE-1); \ //$display("In Tokenizer %s", line``STAGE.substr(StartIndex, EndIndex-1)); \