Merge branch 'main' of github.com:openhwgroup/cvw into benchmarking

This commit is contained in:
Jordan Carlin 2025-04-17 11:51:02 -07:00
commit a6da729a71
No known key found for this signature in database
21 changed files with 1794 additions and 331 deletions

View file

@ -42,7 +42,7 @@ testfloatsim = "questa" # change to Verilator when Issue #707 about testfloat
standard_tests = [
["rv32e", ["arch32e"]],
["rv32i", ["arch32i"]],
["rv32imc", ["arch32i", "arch32c", "arch32m"]], # add when issue #1321 is fixed: "wally32periph"
["rv32imc", ["arch32i", "arch32c", "arch32m", "wally32periph"]],
["rv32gc", ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32f_divsqrt", "arch32d_divsqrt",
"arch32i", "arch32priv", "arch32c", "arch32m", "arch32a_amo", "arch32zifencei", "arch32zicond",
"arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zfh", "arch32zfh_fma",
@ -448,8 +448,8 @@ def selectTests(args, sims, coverStr):
addTests(tests_buildrootbootlockstep, lockstepsim, coverStr, configs) # lockstep with Questa and ImperasDV runs overnight
# only run RV64GC tests on in code coverage mode
if args.ccov:
addTestsByDir(f"{archVerifDir}/tests/lockstep/rv64/", "rv64gc", coveragesim, coverStr, configs)
addTestsByDir(f"{archVerifDir}/tests/lockstep/priv/rv64/", "rv64gc", coveragesim, coverStr, configs)
addTestsByDir(f"{archVerifDir}/tests/rv64/", "rv64gc", coveragesim, coverStr, configs)
addTestsByDir(f"{archVerifDir}/tests/priv/rv64/", "rv64gc", coveragesim, coverStr, configs) # doesn't help coverage much dh 4/12/25
addTestsByDir(WALLY+"/tests/coverage/", "rv64gc", coveragesim, coverStr, configs)
# Extra tests from riscv-arch-test that should be run as part of the functional coverage suite
addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/pmp", "rv64gc", coveragesim, coverStr, configs)
@ -457,10 +457,10 @@ def selectTests(args, sims, coverStr):
# addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m/F", "rv64gc", coveragesim, coverStr, configs) # doesn't help fdivsqrt coverage 4/3/2025
# run tests in lockstep in functional coverage mode
if args.fcov:
addTestsByDir(f"{archVerifDir}/tests/lockstep/rv32/", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{archVerifDir}/tests/lockstep/rv64/", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{archVerifDir}/tests/lockstep/priv/rv32/", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{archVerifDir}/tests/lockstep/priv/rv64/", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{archVerifDir}/tests/rv32/", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{archVerifDir}/tests/rv64/", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{archVerifDir}/tests/priv/rv32/", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
addTestsByDir(f"{archVerifDir}/tests/priv/rv64/", "rv64gc", coveragesim, coverStr, configs, lockstepMode=1)
# Extra tests from riscv-arch-test that should be run as part of the functional coverage suite
addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv32i_m/vm_sv32", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1)
# addTestsByDir(f"{WALLY}/tests/riscof/work/riscv-arch-test/rv32i_m/pmp32", "rv32gc", coveragesim, coverStr, configs, lockstepMode=1) TODO: Add when working in lockstep

View file

@ -42,16 +42,22 @@ void genCase(FILE *fptr, float16_t x, float16_t y, float16_t z, int mul, int add
char calc[80], flags[80];
float32_t x32, y32, z32, r32;
float xf, yf, zf, rf;
float16_t x2, z2;
float16_t smallest;
if (!mul) y.v = 0x3C00; // force y to 1 to avoid multiply
if (!add) z.v = 0x0000; // force z to 0 to avoid add
if (negp) x.v ^= 0x8000; // flip sign of x to negate p
if (negz) z.v ^= 0x8000; // flip sign of z to negate z
// Negated versions of x and z are used in the mulAdd call where necessary
x2 = x;
z2 = z;
if (negp) x2.v ^= 0x8000; // flip sign of x to negate p
if (negz) z2.v ^= 0x8000; // flip sign of z to negate z
op = roundingMode << 4 | mul<<3 | add<<2 | negp<<1 | negz;
// printf("op = %02x rm %d mul %d add %d negp %d negz %d\n", op, roundingMode, mul, add, negp, negz);
softfloat_exceptionFlags = 0; // clear exceptions
result = f16_mulAdd(x, y, z); // call SoftFloat to compute expected result
result = f16_mulAdd(x2, y, z2); // call SoftFloat to compute expected result
// Extract expected flags from SoftFloat
sprintf(flags, "NV: %d OF: %d UF: %d NX: %d",

View file

@ -346,6 +346,11 @@ coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLi
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboz"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "exclusion-tag: immu-pmpcboaccess"]
# IMMU PMP only makes 4-byte accesses
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "SizeBytesMinus1 = 3'd0"] -item bs 1
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "SizeBytesMinus1 = 3'd1"] -item bs 1
coverage exclude -scope /dut/core/ifu/immu/immu/pmp/pmpchecker -linerange [GetLineNum ${SRC}/mmu/pmpchecker.sv "SizeBytesMinus1 = 3'd7"] -item bs 1
# No irom
set line [GetLineNum ${SRC}/ifu/ifu.sv "~ITLBMissF & ~CacheableF & ~SelIROM"]
coverage exclude -scope /dut/core/ifu -linerange $line-$line -item c 1 -feccondrow 6
@ -442,6 +447,15 @@ coverage exclude -scope /dut/core/priv/priv/trap -linerange [GetLineNum ${SRC}/p
coverage exclude -scope /dut/core/priv/priv/csr/csru/csru -linerange [GetLineNum ${SRC}/privileged/csru.sv "assign WriteFRMM"] -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/priv/priv/csr/csru/csru -linerange [GetLineNum ${SRC}/privileged/csru.sv "assign WriteFFLAGSM"] -item e 1 -fecexprrow 3
# Attempted writes to the nonextistant MTIME register trap, so WriteHPMCOUNTERM cannot be set for that address (0xb01)
coverage exclude -scope /dut/core/priv/priv/csr/counters/counters/cntr[1] -linerange [GetLineNum ${SRC}/privileged/csrc.sv "MTIME traps"] -item e 1 -fecexprrow 2 4
coverage exclude -scope /dut/core/priv/priv/csr/counters/counters/cntr[1] -linerange [GetLineNum ${SRC}/privileged/csrc.sv "assign NextHPMCOUNTERM"] -item b 1
# attempting to write stimecmp with STCE=0 traps, causing CSRSWriteM to go low
coverage exclude -scope /dut/core/priv/priv/csr/csrs/csrs -linerange [GetLineNum ${SRC}/privileged/csrs.sv "assign WriteSTIMECMPM"] -item e 1 -fecexprrow 5
# mode != m_mode and TVM = 1 causes a trap, causing CSRSWriteM to go low
coverage exclude -scope /dut/core/priv/priv/csr/csrs/csrs -linerange [GetLineNum ${SRC}/privileged/csrs.sv "assign WriteSATPM"] -item e 1 -fecexprrow 5 8
####################
# EBU

View file

@ -86,7 +86,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
logic [1:0] NextPageType;
logic [P.SVMODE_BITS-1:0] SvMode;
logic [P.XLEN-1:0] TranslationVAdr;
logic [P.XLEN-1:0] NextPTE;
logic [P.XLEN-1:0] NextPTE, NextPTE2;
logic UpdatePTE;
logic HPTWUpdateDA;
logic [P.PA_BITS-1:0] HPTWReadAdr;
@ -107,8 +107,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
logic DAUFaultM;
logic PBMTOrDAUFaultM;
logic HPTWFaultM;
logic ResetPTE;
// map hptw access faults onto either the original LSU load/store fault or instruction access fault
assign LSUAccessFaultM = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM;
assign PBMTOrDAUFaultM = PBMTFaultM | DAUFaultM;
@ -146,8 +145,9 @@ module hptw import cvw::*; #(parameter cvw_t P) (
// State flops
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrUpdateDAM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
assign PRegEn = HPTWRW[1] & ~DCacheBusStallM | UpdatePTE;
flopenr #(P.XLEN) PTEReg(clk, ResetPTE, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
assign PRegEn = HPTWRW[1] & ~DCacheBusStallM | UpdatePTE | (NextWalkerState == IDLE);
assign NextPTE2 = (NextWalkerState == IDLE) ? '0 : NextPTE;
flopenr #(P.XLEN) PTEReg(clk, reset, PRegEn, NextPTE2, PTE); // Capture page table entry from data cache
// Assign PTE descriptors common across all XLEN values
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
@ -310,7 +310,6 @@ module hptw import cvw::*; #(parameter cvw_t P) (
assign HPTWFlushW = (WalkerState == IDLE & TLBMissOrUpdateDA) | (WalkerState != IDLE & HPTWFaultM);
assign ResetPTE = reset | (NextWalkerState == IDLE);
assign SelHPTW = WalkerState != IDLE;
assign HPTWStall = (WalkerState != IDLE & WalkerState != FAULT) | (WalkerState == IDLE & TLBMissOrUpdateDA);

View file

@ -75,7 +75,13 @@ module mmu import cvw::*; #(parameter cvw_t P,
logic ReadNoAmoAccessM; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults
logic [1:0] PBMemoryType; // PBMT field of PTE during TLB hit, or 00 otherwise
logic AtomicMisalignedCausesAccessFaultM; // Misaligned atomics are not handled by hardware even with ZICCLSM, so it throws an access fault instead of misaligned with ZICCLSM
logic [1:0] EffectivePrivilegeModeW; // Effective privilege mode accounting for MPRV
// Get Effective Privilege Mode
// for DLB, when mstatus.MPRV=1, use mstatus.MPP rather than the current privilege mode
assign EffectivePrivilegeModeW = IMMU ? PrivilegeModeW : (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW);
// only instantiate TLB if Virtual Memory is supported
if (P.VIRTMEM_SUPPORTED) begin:tlb
logic ReadAccess, WriteAccess;
@ -86,7 +92,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
.SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]),
.SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]),
.VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM,
.EffectivePrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM,
.DisableTranslation, .PTE, .PageTypeWriteVal,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss,
.Translate, .TLBPageFault, .UpdateDA, .PBMemoryType);
@ -115,7 +121,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
if (P.PMP_ENTRIES > 0) begin : pmp
pmpchecker #(P) pmpchecker(.PhysicalAddress, .PrivilegeModeW,
pmpchecker #(P) pmpchecker(.PhysicalAddress, .EffectivePrivilegeModeW,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.ExecuteAccessF, .WriteAccessM, .ReadAccessM, .Size, .CMOpM,
.PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM);

View file

@ -33,6 +33,7 @@
module pmpadrdec import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic [1:0] Size,
input logic [7:0] PMPCfg,
input logic [P.PA_BITS-3:0] PMPAdr,
input logic FirstMatch,
@ -52,7 +53,7 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
logic PAltPMPAdr;
logic [P.PA_BITS-1:0] CurrentAdrFull;
logic [1:0] AdrMode;
logic [P.PA_BITS-1:0] PMPTop1;
logic [P.PA_BITS-1:0] PMPTop1, PMPTopTOR, PMPTopNaturallyAligned;
assign AdrMode = PMPCfg[4:3];
@ -83,10 +84,12 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
1'b0;
// Report top of region for first matching region
assign PMPTop1 = {PMPAdr,2'b00} | NAMask; // top of the pmp region. All 1s in the lower bits. Used to check the address doesn't pass the top
// PMP should match but fail if the size is too big (8-byte accesses spanning to TOR or NA4 region)
assign PMPTopTOR = {PMPAdr-1, 2'b11}; // TOR goes to (pmpaddr << 2) - 1
assign PMPTopNaturallyAligned = {PMPAdr,2'b00} | NAMask; // top of the pmp region for NA4 and NAPOT. All 1s in the lower bits. Used to check the address doesn't pass the top
assign PMPTop1 = (AdrMode == TOR) ? PMPTopTOR : PMPTopNaturallyAligned;
assign PMPTop = FirstMatch ? PMPTop1 : '0; // AND portion of distributed AND-OR mux (OR portion in pmpchhecker)
// PMP should match but fail if the size is too big (8-byte accesses spanning to TOR or NA4 region)
assign L = PMPCfg[7];
assign X = PMPCfg[2];
assign W = PMPCfg[1];

View file

@ -32,7 +32,7 @@
module pmpchecker import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic [1:0] PrivilegeModeW,
input logic [1:0] EffectivePrivilegeModeW,
// ModelSim has a switch -svinputport which controls whether input ports
// are nets (wires) or vars by default. The default setting of this switch is
// `relaxed`, which means that signals are nets if and only if they are
@ -66,6 +66,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
if (P.PMP_ENTRIES > 0) begin: pmp // prevent complaints about array of no elements when PMP_ENTRIES = 0
pmpadrdec #(P) pmpadrdecs[P.PMP_ENTRIES-1:0](
.PhysicalAddress,
.Size,
.PMPCfg(PMPCFG_ARRAY_REGW),
.PMPAdr(PMPADDR_ARRAY_REGW),
.FirstMatch,
@ -97,8 +98,8 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
assign PhysicalAddressTop = PhysicalAddress + {{P.PA_BITS-3{1'b0}}, SizeBytesMinus1}; // top of the access range
assign TooBig = PhysicalAddressTop > MatchingPMPTop; // check if the access goes beyond the top of the PMP region
// Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW != P.M_MODE) | MatchingL;
// Only enforce PMP checking for effective S and U modes (accounting for mstatus.MPRV) or in Machine mode when L bit is set in selected region
assign EnforcePMP = (EffectivePrivilegeModeW != P.M_MODE) | MatchingL;
assign PMPCBOMAccessFault = EnforcePMP & (|CMOpM[2:0]) & ~MatchingR ; // checking R is sufficient because W implies R in PMP // exclusion-tag: immu-pmpcbom
assign PMPCBOZAccessFault = EnforcePMP & CMOpM[3] & ~MatchingW ; // exclusion-tag: immu-pmpcboz

View file

@ -60,7 +60,7 @@ module tlb import cvw::*; #(parameter cvw_t P,
input logic [1:0] STATUS_MPP,
input logic ENVCFG_PBMTE, // Page-based memory types enabled
input logic ENVCFG_ADUE, // HPTW A/D Update enable
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic [1:0] EffectivePrivilegeModeW, // Current privilege level of the processeor, accounting for mstatus.MPRV
input logic ReadAccess,
input logic WriteAccess,
input logic [3:0] CMOpM,
@ -110,7 +110,7 @@ module tlb import cvw::*; #(parameter cvw_t P,
assign NAPOT4 = (PPN[3:0] == 4'b1000); // 64 KiB contiguous region with pte.napot_bits = 4
tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM, .DisableTranslation,
.EffectivePrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM, .DisableTranslation,
.PTEAccessBits, .CAMHit, .Misaligned, .NAPOT4,
.TLBMiss, .TLBHit, .TLBPageFault,
.UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType);

View file

@ -34,7 +34,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
input logic [1:0] STATUS_MPP,
input logic ENVCFG_PBMTE, // Page-based memory types enabled
input logic ENVCFG_ADUE, // HPTW A/D Update enable
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic [1:0] EffectivePrivilegeModeW, // Current privilege level of the processeor, accounting for mstatus.MPRV
input logic ReadAccess, WriteAccess,
input logic [3:0] CMOpM,
input logic DisableTranslation,
@ -53,8 +53,6 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
);
// Sections of the page table entry
logic [1:0] EffectivePrivilegeMode;
logic [1:0] PTE_PBMT;
logic PTE_RESERVED, PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits
logic UpperBitsUnequal;
@ -66,8 +64,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
logic PreUpdateDA, PrePageFault;
// Grab the sv mode from SATP and determine whether translation should occur
assign EffectivePrivilegeMode = (ITLB == 1) ? PrivilegeModeW : (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW); // DTLB uses MPP mode when MPRV is 1
assign Translate = (SATP_MODE != P.NO_TRANSLATE[P.SVMODE_BITS-1:0]) & (EffectivePrivilegeMode != P.M_MODE) & ~DisableTranslation;
assign Translate = (SATP_MODE != P.NO_TRANSLATE[P.SVMODE_BITS-1:0]) & (EffectivePrivilegeModeW != P.M_MODE) & ~DisableTranslation;
// Determine whether TLB is being used
assign TLBAccess = ReadAccess | WriteAccess | (|CMOpM);
@ -95,7 +92,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
if (ITLB == 1) begin:itlb // Instruction TLB fault checking
// User mode may only execute user mode pages, and supervisor mode may
// only execute non-user mode pages.
assign ImproperPrivilege = ((PrivilegeModeW == P.U_MODE) & ~PTE_U) | ((PrivilegeModeW == P.S_MODE) & PTE_U);
assign ImproperPrivilege = ((EffectivePrivilegeModeW == P.U_MODE) & ~PTE_U) | ((EffectivePrivilegeModeW == P.S_MODE) & PTE_U);
assign PreUpdateDA = ~PTE_A;
assign InvalidAccess = ~PTE_X | ReservedRW;
end else begin:dtlb // Data TLB fault checking
@ -104,8 +101,8 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
// User mode may only load/store from user mode pages, and supervisor mode
// may only access user mode pages when STATUS_SUM is low.
assign ImproperPrivilege = ((EffectivePrivilegeMode == P.U_MODE) & ~PTE_U) |
((EffectivePrivilegeMode == P.S_MODE) & PTE_U & ~STATUS_SUM);
assign ImproperPrivilege = ((EffectivePrivilegeModeW == P.U_MODE) & ~PTE_U) |
((EffectivePrivilegeModeW == P.S_MODE) & PTE_U & ~STATUS_SUM);
// Check for read error. Reads are invalid when the page is not readable
// (and executable pages are not readable) or when the page is neither
// readable nor executable (and executable pages are readable).

View file

@ -129,7 +129,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
// Counter update and write logic
for (i = 0; $unsigned(i) < P.COUNTERS; i = i+1) begin:cntr
assign WriteHPMCOUNTERM[i] = CSRMWriteM & (CSRAdrM == MHPMCOUNTERBASE + i);
assign WriteHPMCOUNTERM[i] = CSRMWriteM & (CSRAdrM == MHPMCOUNTERBASE + i); // coverage tag: MTIME traps
assign NextHPMCOUNTERM[i][P.XLEN-1:0] = WriteHPMCOUNTERM[i] ? CSRWriteValM : HPMCOUNTERPlusM[i][P.XLEN-1:0];
always_ff @(posedge clk) //, posedge reset) // ModelSim doesn't like syntax of passing array element to flop
if (reset) HPMCOUNTER_REGW[i][P.XLEN-1:0] <= '0;

View file

@ -194,7 +194,6 @@ string arch32pmp[] = '{
"rv32i_m/pmp32/src/pmp-TOR-X.S"
};
// Tests commented out pending riscv-arch-test issue #588
string arch64pmp[] = '{
`RISCVARCHTEST,
"rv64i_m/pmp/src/pmp64-CSR-ALL-MODES.S",
@ -203,10 +202,10 @@ string arch64pmp[] = '{
"rv64i_m/pmp/src/pmp64-NA4-U.S",
"rv64i_m/pmp/src/pmp64-NAPOT-M.S",
"rv64i_m/pmp/src/pmp64-NAPOT-S.S",
"rv64i_m/pmp/src/pmp64-NAPOT-U.S"
// "rv64i_m/pmp/src/pmp64-TOR-M.S", TODO: Reenable when Wally top of PMP region bug is fixed
// "rv64i_m/pmp/src/pmp64-TOR-S.S",
// "rv64i_m/pmp/src/pmp64-TOR-U.S"
"rv64i_m/pmp/src/pmp64-NAPOT-U.S",
"rv64i_m/pmp/src/pmp64-TOR-M.S",
"rv64i_m/pmp/src/pmp64-TOR-S.S",
"rv64i_m/pmp/src/pmp64-TOR-U.S"
};
string arch32vm_sv32[] = '{
@ -253,7 +252,6 @@ string arch64priv[] = '{
`RISCVARCHTEST,
"rv64i_m/privilege/src/ebreak.S",
"rv64i_m/privilege/src/ecall.S",
// "rv64i_m/privilege/src/misalign1-jalr-01.S",
"rv64i_m/privilege/src/misalign2-jalr-01.S",
"rv64i_m/privilege/src/misalign-beq-01.S",
"rv64i_m/privilege/src/misalign-bge-01.S",
@ -262,7 +260,7 @@ string arch64priv[] = '{
"rv64i_m/privilege/src/misalign-bltu-01.S",
"rv64i_m/privilege/src/misalign-bne-01.S",
"rv64i_m/privilege/src/misalign-jal-01.S"
// removed because rv64gc supports Zicclsm
// commented out for now because rv64gc supports Zicclsm, but Sail does not yet. Restore when Sail supports Zicclsm.
/* -----\/----- EXCLUDED -----\/-----
"rv64i_m/privilege/src/misalign-ld-01.S",
"rv64i_m/privilege/src/misalign-lh-01.S",
@ -2014,7 +2012,6 @@ string arch32priv[] = '{
`RISCVARCHTEST,
"rv32i_m/privilege/src/ebreak.S",
"rv32i_m/privilege/src/ecall.S",
// "rv32i_m/privilege/src/misalign1-jalr-01.S",
"rv32i_m/privilege/src/misalign2-jalr-01.S",
"rv32i_m/privilege/src/misalign-beq-01.S",
"rv32i_m/privilege/src/misalign-bge-01.S",
@ -3587,6 +3584,7 @@ string wally32priv[] = '{
"rv32i_m/privilege/src/WALLY-endianness-01.S",
"rv32i_m/privilege/src/WALLY-satp-invalid-01.S",
// These peripherals are here instead of wally32periph because they don't work on rv32imc, which lacks a PMP register to configure
"rv32i_m/privilege/src/WALLY-periph-s-01.S",
"rv32i_m/privilege/src/WALLY-gpio-01.S",
"rv32i_m/privilege/src/WALLY-clint-01.S",
"rv32i_m/privilege/src/WALLY-uart-01.S",

View file

@ -31,20 +31,32 @@ main:
li t0, 0x80100770
sd zero, 0(t0)
sd zero, 1(t0)
lr.d t1, (t0)
addi t0, t0, 1
sc.d t2, t1, (t0)
// way 1
li t0, 0x80101770
sd zero, 0(t0)
sd zero, 1(t0)
lr.d t1, (t0)
addi t0, t0, 1
sc.d t2, t1, (t0)
// way 2
li t0, 0x80102770
sd zero, 0(t0)
sd zero, 1(t0)
lr.d t1, (t0)
addi t0, t0, 1
sc.d t2, t1, (t0)
// way 3
li t0, 0x80103770
sd zero, 0(t0)
sd zero, 1(t0)
lr.d t1, (t0)
addi t0, t0, 1
sc.d t2, t1, (t0)
j done

View file

@ -29,8 +29,6 @@ main:
csrw pmpcfg0, t0
csrw pmpcfg2, t0
li t0, 0x80000000
lw t1, 0(t0)
# test hitting region in NA4 mode for IMMU
la t0, pmpjump # address of a jump destination to exercise immu pmpchecker
@ -53,7 +51,133 @@ main:
csrw pmpaddr0, t1
jalr t0
# test hitting region in TOR mode for IMMU
add t2, t1, 1 # top of range
# region 0 TOR at pmpjump
li t3, 0x0F # TOR XWR
csrw pmpcfg0, t3
csrw pmpcfg2, 0
csrw pmpaddr0, t2
jalr t0
# region 1 TOR at pmpjump
li t3, 0x0F00 # TOR XWR
csrw pmpcfg0, t3
csrw pmpcfg2, 0
csrw pmpaddr0, t1
csrw pmpaddr1, t2
jalr t0
# region 1 TOR at pmpjump
li t3, 0x0F00 # TOR XWR
csrw pmpcfg0, t3
csrw pmpcfg2, 0
csrw pmpaddr0, t1
csrw pmpaddr1, t2
jalr t0
# region 8 TOR at pmpjump
li t3, 0x0F # TOR XWR
csrw pmpcfg2, t3
csrw pmpcfg0, 0
csrw pmpaddr7, t1
csrw pmpaddr8, t2
jalr t0
# region 9 TOR at pmpjump
li t3, 0x0F00 # TOR XWR
csrw pmpcfg2, t3
csrw pmpcfg0, 0
csrw pmpaddr8, t1
csrw pmpaddr9, t2
jalr t0
# region 10 TOR at pmpjump
li t3, 0x0F0000 # TOR XWR
csrw pmpcfg2, t3
csrw pmpcfg0, 0
csrw pmpaddr9, t1
csrw pmpaddr10, t2
jalr t0
# region 11 TOR at pmpjump
li t3, 0x0F000000 # TOR XWR
csrw pmpcfg2, t3
csrw pmpcfg0, 0
csrw pmpaddr10, t1
csrw pmpaddr11, t2
jalr t0
# region 12 TOR at pmpjump
li t3, 0x0F00000000 # TOR XWR
csrw pmpcfg2, t3
csrw pmpcfg0, 0
csrw pmpaddr11, t1
csrw pmpaddr12, t2
jalr t0
# region 13 TOR at pmpjump
li t3, 0x0F0000000000 # TOR XWR
csrw pmpcfg2, t3
csrw pmpcfg0, 0
csrw pmpaddr12, t1
csrw pmpaddr13, t2
jalr t0
# region 14 TOR at pmpjump
li t3, 0x0F000000000000 # TOR XWR
csrw pmpcfg2, t3
csrw pmpcfg0, 0
csrw pmpaddr13, t1
csrw pmpaddr14, t2
jalr t0
# region 15 TOR at pmpjump
li t3, 0x0F00000000000000 # TOR XWR
csrw pmpcfg2, t3
csrw pmpcfg0, 0
csrw pmpaddr14, t1
csrw pmpaddr15, t2
jalr t0
# test AMO not causing Load access fault
# assign PMPLoadAccessFaultM = EnforcePMP & ReadAccessM & ~WriteAccessM & ~MatchingR;
la s0, scratch
li t0, 0x0F000C00 # region 3 encompassing all addresses has TOR XWR, region 1 has TOR X only
csrw pmpcfg0, t0
# give only execute access to scratch
# set up TOR region 0-1 to do this (yes, NA4 would work too)
srli t0, s0, 2 # drop bottom two bits
csrw pmpaddr0, t0
addi t0, t0, 1 # next word
csrw pmpaddr1, t0
# everything else has full access, with a big TOR from 0 t0 FFFFFFFF
csrw pmpaddr2, zero
li t0, 0xFFFFFFFF # full range
csrw pmpaddr3, t0
# switch to supervisor mode
li a0, 1
ecall
# test the AMO
amoswap.w t1, zero, (s0) # attempt amo; should get store but not load access fault because this region is X only
li a0, 3
ecall # return to M mode
j done
.align 2
pmpjump:
ret
ret
.align 2
scratch:
.word 0

View file

@ -309,6 +309,9 @@ sretdone:
# exercise sret with rs1 not 0
.word 0x102F8073
# illegal ebreak with nonzero rs1
.word 0x00110073
# cover mret when mpp = 3 and mprv = 1
li a0, 3

View file

@ -28,7 +28,8 @@
//RV_COMPLIANCE_DATA_END
#define RVMODEL_DATA_END \
.align 4; .global end_signature; end_signature:
.align 4;\
.global end_signature; end_signature:
//RVTEST_IO_INIT
#define RVMODEL_IO_INIT
@ -43,21 +44,132 @@
//RVTEST_IO_ASSERT_DFPR_EQ
#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I)
#define RVMODEL_SET_MSW_INT
#define ACCESS_FAULT_ADDRESS 0
#define CLINT_BASE_ADDR 0x02000000
#define PLIC_BASE_ADDR 0x0C000000
#define GPIO_BASE_ADDR 0x10060000
#define RVMODEL_CLEAR_MSW_INT
#define MTIME (CLINT_BASE_ADDR + 0xBFF8)
#define MSIP (CLINT_BASE_ADDR)
#define MTIMECMP (CLINT_BASE_ADDR + 0x4000)
#define MTIMECMPH (CLINT_BASE_ADDR + 0x4004)
#define RVMODEL_CLEAR_MTIMER_INT
#define THRESHOLD_0 (PLIC_BASE_ADDR + 0x200000)
#define THRESHOLD_1 (PLIC_BASE_ADDR + 0x201000)
#define INT_PRIORITY_3 (PLIC_BASE_ADDR + 0x00000C)
#define INT_EN_00 (PLIC_BASE_ADDR + 0x002000)
#define INT_EN_10 (PLIC_BASE_ADDR + 0x002080)
#define RVMODEL_CLEAR_MEXT_INT
#define GPIO_OUTPUT_EN (GPIO_BASE_ADDR + 0x08)
#define GPIO_OUTPUT_VAL (GPIO_BASE_ADDR + 0x0C)
#define RVMODEL_SET_MSW_INT \
li t1, 1; \
li t2, 0x2000000; \
sw t1, 0(t2);
#define RVMODEL_CLEAR_MSW_INT \
li t2, 0x2000000; \
sw x0, 0(t2);
#define RVMODEL_CLEAR_MTIMER_INT \
li t0, -1; \
la t2, MTIMECMP; \
SREG t0, 0(t2); \
#ifdef __riscv_xlen \
#if __riscv_xlen == 32 \
sw t0, 4(t2); \
#endif \
#else \
ERROR: __riscv_xlen not defined; \
#endif
#define RVMODEL_CLEAR_MEXT_INT \
la t0, THRESHOLD_0; \
li t2, 7; \
sw t2, 0(t0); \
la t0, THRESHOLD_1; \
li t2, 7; \
sw t2, 0(t0); \
la t0, INT_PRIORITY_3; \
sw zero, 0(t0); \
la t0, INT_EN_00; \
sw zero, 0(t0); \
la t0, GPIO_BASE_ADDR; \
sw zero, 0x18(t0); \
sw zero, 0x20(t0); \
sw zero, 0x28(t0); \
sw zero, 0x30(t0);
#define RVMODEL_CLR_MSW_INT \
la t0, MSIP; \
lw t2, 0(t0); \
andi t2, t2, -2; \
sw t2, 0(t0);
#define RVMODEL_CLR_MTIMER_INT \
li t0, -1; \
la t2, MTIMECMP; \
SREG t0, 0(t2); \
#ifdef __riscv_xlen \
#if __riscv_xlen == 32 \
sw t0, 4(t2); \
#endif \
#else \
ERROR: __riscv_xlen not defined; \
#endif
#define RVMODEL_CLR_MEXT_INT \
la t0, THRESHOLD_0; \
li t2, 7; \
sw t2, 0(t0); \
la t0, THRESHOLD_1; \
li t2, 7; \
sw t2, 0(t0); \
la t0, INT_PRIORITY_3; \
sw zero, 0(t0); \
la t0, INT_EN_00; \
sw zero, 0(t0); \
la t0, GPIO_BASE_ADDR; \
sw zero, 0x18(t0); \
sw zero, 0x20(t0); \
sw zero, 0x28(t0); \
sw zero, 0x30(t0);
#define RVMODEL_CLR_MSW_INT
#define RVMODEL_CLR_MTIMER_INT
#define RVMODEL_CLR_MEXT_INT
#define RVMODEL_SET_SSW_INT
#define RVMODEL_CLR_SSW_INT
#define RVMODEL_MCLR_SSW_INT \
csrrci t6, mip, 2;
#define RVMODEL_SCLR_SSW_INT \
csrrci t6, sip, 2;
#define RVMODEL_CLR_STIMER_INT
#define RVMODEL_CLR_SEXT_INT
#define RVMODEL_MCLR_STIMER_INT \
li t0, 32; \
csrrc t6, mip, t0;
#define RVMODEL_SCLR_STIMER_INT
#define RVMODEL_CLR_SEXT_INT \
la t0, THRESHOLD_0; \
li t2, 7; \
sw t2, 0(t0); \
la t0, THRESHOLD_1; \
li t2, 7; \
sw t2, 0(t0); \
la t0, INT_PRIORITY_3; \
sw zero, 0(t0); \
la t0, INT_EN_00; \
sw zero, 0(t0); \
la t0, GPIO_BASE_ADDR; \
sw zero, 0x18(t0); \
sw zero, 0x20(t0); \
sw zero, 0x28(t0); \
sw zero, 0x30(t0);
#define RVMODEL_SET_VSW_INT
#define RVMODEL_CLR_VSW_INT
#define RVMODEL_CLR_VTIMER_INT

View file

@ -1,72 +0,0 @@
#ifndef _COMPLIANCE_MODEL_H
#define _COMPLIANCE_MODEL_H
#define RVMODEL_DATA_SECTION \
.pushsection .tohost,"aw",@progbits; \
.align 8; .global tohost; tohost: .dword 0; \
.align 8; .global fromhost; fromhost: .dword 0; \
.popsection; \
.align 8; .global begin_regstate; begin_regstate: \
.word 128; \
.align 8; .global end_regstate; end_regstate: \
.word 4;
//RV_COMPLIANCE_HALT
#define RVMODEL_HALT \
li x1, 1; \
write_tohost: \
sw x1, tohost, t0; \
j write_tohost;
#define RVMODEL_BOOT
//RV_COMPLIANCE_DATA_BEGIN
#define RVMODEL_DATA_BEGIN \
RVMODEL_DATA_SECTION \
.align 4;\
.global begin_signature; begin_signature:
//RV_COMPLIANCE_DATA_END
#define RVMODEL_DATA_END \
.align 4;\
.global end_signature; end_signature:
//RVTEST_IO_INIT
#define RVMODEL_IO_INIT
//RVTEST_IO_WRITE_STR
#define RVMODEL_IO_WRITE_STR(_R, _STR)
//RVTEST_IO_CHECK
#define RVMODEL_IO_CHECK()
//RVTEST_IO_ASSERT_GPR_EQ
#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I)
//RVTEST_IO_ASSERT_SFPR_EQ
#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I)
//RVTEST_IO_ASSERT_DFPR_EQ
#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I)
#define RVMODEL_SET_MSW_INT \
li t1, 1; \
li t2, 0x2000000; \
sw t1, 0(t2);
#define RVMODEL_CLEAR_MSW_INT \
li t2, 0x2000000; \
sw x0, 0(t2);
#define RVMODEL_CLEAR_MTIMER_INT
#define RVMODEL_CLEAR_MEXT_INT
#define RVMODEL_CLR_MSW_INT
#define RVMODEL_CLR_MTIMER_INT
#define RVMODEL_CLR_MEXT_INT
#define RVMODEL_SET_SSW_INT
#define RVMODEL_CLR_SSW_INT
#define RVMODEL_CLR_STIMER_INT
#define RVMODEL_CLR_SEXT_INT
#define RVMODEL_SET_VSW_INT
#define RVMODEL_CLR_VSW_INT
#define RVMODEL_CLR_VTIMER_INT
#define RVMODEL_CLR_VEXT_INT
#endif // _COMPLIANCE_MODEL_H

1
tests/riscof/spike/env/model_test.h vendored Symbolic link
View file

@ -0,0 +1 @@
../../sail_cSim/env/model_test.h

View file

@ -1,20 +1,20 @@
01BEEF00
8000000B
00000000
0000000A
00000004
00000061
00000061
00000068
00000060
00000001
00000000
00000000
00000000
00000000
00000000
00000000
01BEEF01
01BEEF00 # Test 1 interrupt 0
8000000B # MEIP
00000000 # mcausehigh
0000000A # claim ID
00000004 # IIR
00000061 # LSR
00000061 # LSR after reading LSR
00000068 # RBR
00000060 # LSR after erading RBR too
00000001 # SCR
00000000 # null
00000000 # null
00000000 # null
00000000 # null
00000000 # null
00000000 #null
01BEEF01 # Test 1 interrupt 1
8000000B
00000000
00000003
@ -30,7 +30,7 @@ FFFFFFFF
FFF7FFFF
00000000
00000000
01BEEF02
01BEEF02 # Test 1 interrupt 2
8000000B
00000000
00000003
@ -46,7 +46,7 @@ FFFFFFFF
FFFFFFFE
00000000
00000000
01BEEF03
01BEEF03 # Test 1 interrupt 3
8000000B
00000000
0000000A
@ -62,7 +62,7 @@ FFFFFFFE
00000000
00000000
00000000
02BEEF04
02BEEF04 # Test 2 interrupt 4
8000000B
00000000
00000003
@ -78,7 +78,7 @@ FFFFFFFF
FFFF0F0F
00000000
00000000
02BEEF05
02BEEF05 # Test 2 interrupt 5
8000000B
00000000
00000003
@ -94,7 +94,7 @@ FFFFFFFF
CFCFFFFF
00000000
00000000
02BEEF06
02BEEF06 # Test 2 interrupt 6
8000000B
00000000
00000003
@ -110,7 +110,7 @@ CFFFFFFF
CFFFFFFF
00000000
00000000
02BEEF07
02BEEF07 # Test 2 interrupt 7
8000000B
00000000
00000003
@ -126,7 +126,7 @@ FFFFFFFF
F0FFFFFF
00000000
00000000
02BEEF08
02BEEF08 # Test 2 interrupt 8
8000000B
00000000
00000003
@ -142,7 +142,7 @@ FFFFFFFF
FF0000FF
00000000
00000000
02BEEF09
02BEEF09 # Test 2 interrupt 9
8000000B
00000000
00000003
@ -158,7 +158,7 @@ FF0000FF
CC0000CC
00000000
00000000
02BEEF0A
02BEEF0A # Test 2 interrupt 10
8000000B
00000000
00000003
@ -174,7 +174,7 @@ CCFFFFCC
CCFFFFCC
00000000
00000000
02BEEF0B
02BEEF0B Test 2 interrupt 11
8000000B
00000000
00000003
@ -190,7 +190,7 @@ FFFFFFFF
FF3333FF
00000000
00000000
02BEEF0C
02BEEF0C # Test 2 interrupt 12
8000000B
00000000
00000003
@ -206,7 +206,7 @@ FF3333FF
FF3333FF
00000000
00000000
02BEEF0D
02BEEF0D # Test 2 interrupt 13
8000000B
00000000
00000003
@ -222,7 +222,7 @@ FFFFFFFF
33FF3333
00000000
00000000
02BEEF0E
02BEEF0E # Test 2 interrupt 14
8000000B
00000000
00000003
@ -238,7 +238,7 @@ CCCCCCCC
33333333
00000000
00000000
02BEEF0F
02BEEF0F # Test 2 interrupt 15
8000000B
00000000
00000003
@ -254,7 +254,7 @@ FFFFEE00
FFFFEE00
00000000
00000000
02BEEF10 # Something here is failing
02BEEF10 # Test 2 interrupt 16
8000000B
00000000
00000003
@ -270,7 +270,7 @@ FFFFFFFF
FFFFFF00
00000000
00000000
02BEEF11 # this might be wrong
02BEEF11 # Test 2 interrupt 17
8000000B
00000000
00000003
@ -286,7 +286,7 @@ FFFFFFCC # low ip
FFFFFFCC # serviced low ip
00000000
00000000
03BEEF12
03BEEF12 # test 3 interrupt 18
8000000B
00000000
0000000A
@ -302,7 +302,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF13
03BEEF13 # Test 3 interrupt 19
8000000B
00000000
0000000A
@ -318,7 +318,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF14
03BEEF14 # Test 3 interrupt 20
8000000B
00000000
0000000A
@ -334,7 +334,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF15
03BEEF15 # Test 3 interrupt 21
8000000B
00000000
0000000A
@ -350,7 +350,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF16
03BEEF16 # Test 3 interrupt 22
8000000B
00000000
0000000A
@ -366,7 +366,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF17
03BEEF17 # Test 3 interrupt 23
8000000B
00000000
0000000A
@ -382,7 +382,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF18
03BEEF18 # Test 3 interrupt 24
8000000B
00000000
0000000A
@ -398,7 +398,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF19
03BEEF19 # Test 3 interrupt 25
8000000B
00000000
0000000A
@ -414,7 +414,7 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
03BEEF1A
03BEEF1A # Test 3 interrupt 26
8000000B
00000000
0000000A
@ -430,67 +430,3 @@ FFFFFFCC # serviced low ip
00000000
00000000
00000000
04BEEF1B
80000009
00000000
0000000A
00000004
00000061
00000061
00000065
00000060
00000001
000000ff
00000000
00000000
00000000
00000000
00000000
04BEEF1C
80000009
00000000
00000003
00080000
00080000
00080000
00000000
00000000 # is it this one that's failing?
00000000
00080000 # failing
00080000
FFFFFFFF
FFF7FFFF
00000000
00000000
04BEEF1D
80000009
00000000
00000003
00000001
00000001
00000001
00000000
00080000
00000000
00080001
00000001
FFFFFFFF
FFFFFFFE
00000000
00000000
04BEEF1E # this might also be wrong
80000009
00000000
0000000A
00000004
00000061
00000061
0000006e
00000060
00000001
000000ff
00000000
00000000
00000000
00000000
00000000

View file

@ -0,0 +1,496 @@
01BEEF00 # Test 1 interrupt 0
8000000B # MEIP
00000000 # mcausehigh
0000000A # claim ID
00000004 # IIR
00000061 # LSR
00000061 # LSR after reading LSR
00000068 # RBR
00000060 # LSR after erading RBR too
00000001 # SCR
00000000 # null
00000000 # null
00000000 # null
00000000 # null
00000000 # null
00000000 #null
01BEEF01 # Test 1 interrupt 1
8000000B
00000000
00000003
00080000
00080000
00080000
00000000
00000000
00000000
00080000
00080000
FFFFFFFF
FFF7FFFF
00000000
00000000
01BEEF02 # Test 1 interrupt 2
8000000B
00000000
00000003
00000001
00000001
00000001
00000000
00080000
00000000
00080001
00000001
FFFFFFFF
FFFFFFFE
00000000
00000000
01BEEF03 # Test 1 interrupt 3
8000000B
00000000
0000000A
00000004
00000061
00000061
00000065
00000060
00000001
00000000
00000000
00000000
00000000
00000000
00000000
02BEEF04 # Test 2 interrupt 4
8000000B
00000000
00000003
0000F0F0
3030F0F0
0000F0F0
00000000
00000001
00000000
0000F0F1
0000F0F0
FFFFFFFF
FFFF0F0F
00000000
00000000
02BEEF05 # Test 2 interrupt 5
8000000B
00000000
00000003
30300000
3030F0F0
30300000
00000000
0000F0F0
00000000
3030F0F0
30300000
FFFFFFFF
CFCFFFFF
00000000
00000000
02BEEF06 # Test 2 interrupt 6
8000000B
00000000
00000003
30000000
3030F0F0
00000000
00000000
00300000
00000000
30300000
30000000
CFFFFFFF
CFFFFFFF
00000000
00000000
02BEEF07 # Test 2 interrupt 7
8000000B
00000000
00000003
0F000000
0F0F0F0F
0F000000
00000000
30000000
00000000
3F000000
0F000000
FFFFFFFF
F0FFFFFF
00000000
00000000
02BEEF08 # Test 2 interrupt 8
8000000B
00000000
00000003
00FFFF00
00FFFF00
00FFFF00
00000000
00000000
00000000
00FFFF00
00FFFF00
FFFFFFFF
FF0000FF
00000000
00000000
02BEEF09 # Test 2 interrupt 9
8000000B
00000000
00000003
33FFFF33
33FFFF33
33000033
00000000
00000000
00000000
33FFFF33
33FFFF33
FF0000FF
CC0000CC
00000000
00000000
02BEEF0A # Test 2 interrupt 10
8000000B
00000000
00000003
33000033
33000033
00000000
00000000
00FFFF00
00000000
33FFFF33
33000033
CCFFFFCC
CCFFFFCC
00000000
00000000
02BEEF0B Test 2 interrupt 11
8000000B
00000000
00000003
00CCCC00
00CCCC00
00CCCC00
00000000
33000033
00000000
33CCCC33
00CCCC00
FFFFFFFF
FF3333FF
00000000
00000000
02BEEF0C # Test 2 interrupt 12
8000000B
00000000
00000003
00CCCC00
00CCCC00
00000000
00000000
00000000
00000000
00CCCC00
00CCCC00
FF3333FF
FF3333FF
00000000
00000000
02BEEF0D # Test 2 interrupt 13
8000000B
00000000
00000003
CC00CCCC
CCCCCCCC
CC00CCCC
00000000
00CCCC00
00000000
CC00CCCC
CC00CCCC
FFFFFFFF
33FF3333
00000000
00000000
02BEEF0E # Test 2 interrupt 14
8000000B
00000000
00000003
CCCCCCCC
CCCCCCCC
00CC0000
00000000
00000000
00000000
CCCCCCCC
CCCCCCCC
33FF3333
33333333
00000000
00000000
02BEEF0F # Test 2 interrupt 15
8000000B
00000000
00000003
000011FF
FF1111FF
33333333
00000000
FFFFEE00
00000000
FFFFFFFF
000011FF
FFFFEE00
FFFFEE00
00000000
00000000
02BEEF10 # Test 2 interrupt 16
8000000B
00000000
00000003
000000FF
00000000
000000FF
00000000
00000000
00000000
000000FF
000000FF
FFFFFFFF
FFFFFF00
00000000
00000000
02BEEF11 # Test 2 interrupt 17
8000000B
00000000
00000003
00000033 # input
00000000 # output
00000000 # rise ip
00000000 # serviced rise ip
000000CC # fall ip
00000000
000000FF # high ip
00000033 # why is this 0x33?
FFFFFFCC # low ip
FFFFFFCC # serviced low ip
00000000
00000000
03BEEF12 # test 3 interrupt 18
8000000B
00000000
0000000A
00000002
00000061
00000061
0000006C
00000060
00000001
00000000
00000000
00000000
00000000
00000000
00000000
03BEEF13 # Test 3 interrupt 19
8000000B
00000000
0000000A
00000002
00000021
00000021
0000006C
00000020
00000001
00000002
00000000
00000000
00000000
00000000
00000000
03BEEF14 # Test 3 interrupt 20
8000000B
00000000
0000000A
00000004
00000061
00000061
0000006F
00000060
00000001
00000000
00000000
00000000
00000000
00000000
00000000
03BEEF15 # Test 3 interrupt 21
8000000B
00000000
0000000A
00000004
00000061
00000061
00000020
00000060
00000001
00000003
00000000
00000000
00000000
00000000
00000000
03BEEF16 # Test 3 interrupt 22
8000000B
00000000
0000000A
00000004
00000061
00000061
00000074
00000060
00000001
00000020
00000000
00000000
00000000
00000000
00000000
03BEEF17 # Test 3 interrupt 23
8000000B
00000000
0000000A
00000002
00000020
00000020
00000074
00000020
00000001
00000003
00000000
00000000
00000000
00000000
00000000
03BEEF18 # Test 3 interrupt 24
8000000B
00000000
0000000A
00000002
00000020
00000020
00000074
00000020
00000001
00000003
00000000
00000000
00000000
00000000
00000000
03BEEF19 # Test 3 interrupt 25
8000000B
00000000
0000000A
00000004
00000061
00000061
00000065
00000060
00000001
00000003
00000000
00000000
00000000
00000000
00000000
03BEEF1A # Test 3 interrupt 26
8000000B
00000000
0000000A
00000006
00000063
00000061
00000047
00000060
00000001
000000FF
00000000
00000000
00000000
00000000
00000000
04BEEF1B # Test 4 interrupt 27
80000009
00000000
0000000A
00000004
00000061
00000061
00000065
00000060
00000001
000000ff
00000000
00000000
00000000
00000000
00000000
04BEEF1C # Test 4 interrupt 28
80000009
00000000
00000003
00080000
00080000
00080000
00000000
00000000
00000000
00080000
00080000
FFFFFFFF
FFF7FFFF
00000000
00000000
04BEEF1D # Test 4 interrupt 29
80000009
00000000
00000003
00000001
00000001
00000001
00000000
00080000
00000000
00080001
00000001
FFFFFFFF
FFFFFFFE
00000000
00000000
04BEEF1E # Test 4 interrupt 30
80000009
00000000
0000000A
00000004
00000061
00000061
0000006e
00000060
00000001
000000ff
00000000
00000000
00000000
00000000
00000000

View file

@ -1,6 +1,6 @@
///////////////////////////////////////////
// WALLY-PERIPH.S
// 64 bit version
// 32 bit version
//
// Ben Bracker (bbracker@hmc.edu)
//
@ -24,7 +24,6 @@
#include "arch_test.h"
RVTEST_ISA("RV32I_Zicsr")
// this test is blocked, it won't build or run. To unblock it remove the check ISA:=regex(BLOCKED);
RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;def NO_SAIL=True",periph)
.section .text.init
@ -225,9 +224,6 @@ main_code: #####
# load address of trap handler
la t0, trap_handler
csrrw x0, mtvec, t0
# delegate all external interrupts to machine mode
li t0, 0xD00
csrrc x0, mideleg, t0
# set MIE
li t0, 0x8
csrrs x0, mstatus, t0
@ -803,96 +799,9 @@ Intr03BEEF1A:
1: bne t1,a0,1b
li a0, 0
####################################################
##### Test 4 - Signs of Life on PLIC Context 1 #####
####################################################
li a1, 0x04beef00 # group ID
# clear MEIE (good to turn off while configuring peripherals)
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 3 (GPIO) priority = 6
li t0, 0xC000000
li t1, 6
sw t1, 0x0C(t0)
# source 0xA (UART) priority = 7
li t1, 7
sw t1, 0x28(t0)
# disable sources 3,0xA on context 0
li t0, 0x0C002000
li t1, 0
sw t1, 0(t0)
# enable sources 3,0xA on context 1
li t0, 0x0C002080
li t1, 0b10000001000
sw t1, 0(t0)
# ========== Configure UART ==========
# MCR: Loop = 1
li t0, 0x10000000
li t1, 0b10000
sb t1, 4(t0)
# LCR: Use 8 data bits plus odd parity bit
li t1, 0b00001011
sb t1, 3(t0)
# IER: Enable Received Data Available Interrupt
li t1, 0x01
sb t1, 1(t0)
# ========== Configure GPIO ==========
# raise all input_en
li t0, 0x10060000
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# raise all output_en
sw t1, 0x08(t0)
# raise all rise_en
sw t1, 0x18(t0)
# ========== Execute Test ==========
# set MEIE and SEIE
li t0, 0xA00
csrrs x0, mie, t0
Intr04BEEF1B:
# UART TX 'e'
li t0, 0x10000000
li t1, 'e'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr04BEEF1C:
# GPIO raise pin 19
li t0, 0x10060000
li t1, 0x00080000
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# Now let's go bonkers and trigger both!
Intr04BEEF1D:
# TX 'n'
li t0, 0x10000000
li t1, 'n'
sb t1, 0(t0)
Intr04BEEF1E:
# GPIO lower pin 19 raise pin 0
li t0, 0x10060000
li t1, 0x00000001
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00011000
1: bne t1,a0,1b
li a0, 0
# ---------------------------------------------------------------------------------------------
# PLIC Context 1 not in periph because it is unavailable without S mode in rv32imc
# See WALLY-periph-S for a version that does test PLIC context 1
//terminate_test:
// li a0, 2 // Trap handler behavior (go to machine mode)
// ecall // writes mcause to the output.
// csrw mtvec, x4 // restore original trap handler to halt program
RVTEST_CODE_END
RVMODEL_HALT

View file

@ -0,0 +1,922 @@
///////////////////////////////////////////
// WALLY-PERIPH-S.S
// 32 bit version including SEIP tests that require supervisor mode
//
// Ben Bracker (bbracker@hmc.edu)
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// Adapted from Imperas RISCV-TEST_SUITE
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV32I_Zicsr")
RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;def NO_SAIL=True",periph)
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
# ---------------------------------------------------------------------------------------------
j main_code
# 64 byte alignment for vectored traps to align with xtev
.align 6
###################
###################
trap_handler: #####
###################
###################
# save registers
addi sp, sp, 0x28
sw t0, 0x00(sp)
sw t1, 0x08(sp)
sw t2, 0x10(sp)
sw t3, 0x18(sp)
sw t4, 0x20(sp)
# ===================================
# ===== Signature Output Format =====
# ===================================
#
# Base address = <wally_signature>+0x40*<intr_num>
# Use sigout-translator.py for help with this!
#
# <offset>: <contents>
# 0x00: test ID = 0x<group_num>BEEF<intr_num>
# 0x04: mcause (low) = 0x8000000B (MEIP) or 0x80000009 (SEIP)
# 0x08: mcause (high) = 0x00000000
# ----- If GPIO -----
# 0x0C: claim ID = 3
# 0x10: input_val
# 0x14: output_val
# 0x18: incoming rise_ip
# 0x1C: serviced rise_ip = 0
# 0x20: incoming fall_ip
# 0x24: serviced fall_ip = 0
# 0x28: incoming high_ip
# 0x2C: serviced high_ip = 0
# 0x30: incoming low_ip
# 0x34: serviced low_ip = 0
# ----- If UART -----
# 0x0C: claim ID = 0xA
# 0x10: IIR
# 0x14: LSR
# 0x18: LSR (after reading LSR)
# 0x1C: RBR
# 0x20: LSR (after reading RBR too)
# 0x24: IIR (after reading everything else)
# 0x28: SCR
# 0x00: test ID = 0x<group_num>BEEF<intr_num>
la t0, wally_signature
sub t0, s0, t0 # sigout offset
srli t0, t0, 6 # intr_num
add t0, t0, a1
sw t0, 0x00(s0)
# 0x04: mcause (low) = 0x0000000B (MEIP) or 0x00000009 (SEIP)
# 0x08: mcause (high) = 0x80000000
csrrc t0, mcause, x0
andi t1, t0, 0x7FF
sw t0, 0x04(s0)
//srli t0,t0,32
sw x0, 0x08(s0)
# MEIP or SEIP?
# MEIP is on context 0
li t4, 0x0C200004
li t0, 0xB
beq t1, t0, meip
# SEIP is on context 1
li t4, 0x0C201004
meip:
# 0x0C: claim ID
# 3: GPIO
# A: UART
mv t0, t4
lw t1, 0(t0)
sw t1, 0x0C(s0)
li t2, 0xA
beq t1, t2, uart_handler
li t2, 3
bne t1, t2, trap_handler_end
gpio_handler:
# 0x10: input_val
li t0, 0x10060000
lw t1, 0x00(t0)
sw t1, 0x10(s0)
# 0x14: output_val
lw t1, 0x0C(t0)
sw t1, 0x14(s0)
# 0x18: incoming rise_ip
lw t1, 0x1C(t0)
sw t1, 0x18(s0)
# 0x1C: serviced rise_ip = 0
sw t1, 0x1C(t0)
lw t1, 0x1C(t0)
sw t1, 0x1C(s0)
# 0x20: incoming fall_ip
lw t1, 0x24(t0)
sw t1, 0x20(s0)
# 0x24: serviced fall_ip = 0
sw t1, 0x24(t0)
lw t1, 0x24(t0)
sw t1, 0x24(s0)
# 0x28: incoming high_ip
lw t1, 0x2C(t0)
sw t1, 0x28(s0)
# 0x2C: serviced high_ip = 0
sw t1, 0x2C(t0)
lw t1, 0x2C(t0)
sw t1, 0x2C(s0)
# 0x30: incoming low_ip
lw t1, 0x34(t0)
sw t1, 0x30(s0)
# 0x34: serviced low_ip = 0
sw t1, 0x34(t0)
lw t1, 0x34(t0)
sw t1, 0x34(s0)
# disable high_ie and low_ie so interrupt
# is not taken again immediately
li t1, 0
sw t1, 0x28(t0)
sw t1, 0x30(t0)
# signal to main code that gpio was serviced
ori a0, a0, 0b00001000
# signal to plic that gpio was serviced
mv t0, t4
li t1, 3
sw t1, 0(t0)
j trap_handler_end
uart_handler:
# 0x10: IIR
li t0, 0x10000000
lbu t1, 2(t0)
sw t1, 0x10(s0)
# 0x14: LSR
lbu t1, 5(t0)
sw t1, 0x14(s0)
# 0x18: LSR (after reading LSR)
lbu t1, 5(t0)
sw t1, 0x18(s0)
# 0x1C: RBR
lbu t1, 0(t0)
sw t1, 0x1C(s0)
# 0x20: LSR (after reading RBR)
lbu t1, 5(t0)
sw t1, 0x20(s0)
# 0x24: IIR (after reading everything else)
lbu t1, 2(t0)
sw t1, 0x24(s0)
# 0x28: SCR
lbu t1, 7(t0)
sw t1, 0x28(s0)
# signal to main code that uart was serviced
ori a0, a0, 0b00010000
# signal to plic that uart was serviced
mv t0, t4
li t1, 0xA
sw t1, 0(t0)
trap_handler_end:
# increment signature pointer
addi s0,s0,0x40
# restore vars
lw t0, 0x00(sp)
lw t1, 0x08(sp)
lw t2, 0x10(sp)
lw t3, 0x18(sp)
lw t4, 0x20(sp)
addi sp, sp, SEXT_IMM(-0x28)
mret
################
################
main_code: #####
################
################
##########################
##### Initialization #####
##########################
# ========== Global Vars ==========
la s0, wally_signature # signature output base adr
la sp, stack # stack pointer
li a0, 0 # interrupt complete flag
# ========== Configure Privileged Unit ==========
# load address of trap handler
la t0, trap_handler
csrrw x0, mtvec, t0
# delegate all external interrupts to machine mode
li t0, 0xD00
csrrc x0, mideleg, t0
# set MIE
li t0, 0x8
csrrs x0, mstatus, t0
##################################
##### Test 1 - Signs of Life #####
##################################
li a1, 0x01beef00 # group ID
# clear MEIE (good to turn off while configuring peripherals)
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 3 (GPIO) priority = 6
li t0, 0xC000000
li t1, 6
sw t1, 0x0C(t0)
# source 0xA (UART) priority = 7
li t1, 7
sw t1, 0x28(t0)
# enable sources 3,0xA
li t0, 0x0C002000
li t1, 0b10000001000
sw t1, 0(t0)
# ========== Configure UART ==========
# MCR: Loop = 1
li t0, 0x10000000
li t1, 0b10000
sb t1, 4(t0)
# LCR: Use 8 data bits plus odd parity bit
li t1, 0b00001011
sb t1, 3(t0)
# IER: Enable Received Data Available Interrupt
li t1, 0x01
sb t1, 1(t0)
# ========== Configure GPIO ==========
# raise all input_en
li t0, 0x10060000
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# raise all output_en
sw t1, 0x08(t0)
# raise all rise_en
sw t1, 0x18(t0)
# ========== Execute Test ==========
# set MEIE
li t0, 0x800
csrrs x0, mie, t0
Intr01BEEF00:
# UART TX 'h'
li t0, 0x10000000
li t1, 'h'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr01BEEF01:
# GPIO raise pin 19
li t0, 0x10060000
li t1, 0x00080000
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# Now let's go bonkers and trigger both!
Intr01BEEF02:
# TX 'e'
li t0, 0x10000000
li t1, 'e'
sb t1, 0(t0)
Intr01BEEF03:
# GPIO lower pin 19 raise pin 0
li t0, 0x10060000
li t1, 0x00000001
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00011000
1: bne t1,a0,1b
li a0, 0
##################################
##### Test 2 - GPIO Testing #####
##################################
li a1, 0x02beef00 # group ID
# clear MEIE
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 3 (GPIO) priority = 1
li t0, 0xC000000
li t1, 1
sw t1, 0x0C(t0)
# enable source 3
li t0, 0x0C002000
li t1, 0b1000
sw t1, 0(t0)
# ========== Input Enables ==========
# Note that this inherits
# a bit of state from the previous test.
# Namely output_val = 0x00000001
#
# enable some inputs
li t0, 0x10060000
li t1, 0x0000FFFF
sw t1, 0x04(t0)
# enable all outputs
li t1, 0xFFFFFFFF
sw t1, 0x08(t0)
# enable all rising edge interrupts
sw t1, 0x18(t0)
# set MEIE
li t1, 0x800
csrrs x0, mie, t1
# raise some input-disabled pins
# interrupt should not happen
li t1, 0xF0F00001
sw t1, 0x0C(t0)
Intr02BEEF04:
# change some input-enabled pins
# interrupt should happen
li t1, 0x3030F0F0
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
Intr02BEEF05:
# enable some different inputs
# this itself will cause some rise interrupts
li t1, 0xFFFF0000
sw t1, 0x04(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# ========== Output Enables ==========
# enable all fall interrupts
li t1, 0xFFFFFFFF
sw t1, 0x20(t0)
Intr02BEEF06:
# disable some outputs
# should affect input value but not output val register itself
# this itself will cause some fall interrupts
li t1, 0xFF0000FF
sw t1, 0x08(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# change pins whose inputs and/or outputs are disabled
# should not cause any rise or fall interrupts
li t1, 0x300F0F0F
sw t1, 0x0C(t0)
Intr02BEEF07:
# change pins whose inputs and outputs are enabled
li t1, 0x0F0F0F0F
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# ========== Clear GPIO State ==========
# (I've gotten a little annoyed with tests depending
# upon the results of previous tests).
# disable all interrupts
sw x0, 0x18(t0)
sw x0, 0x20(t0)
sw x0, 0x28(t0)
sw x0, 0x30(t0)
# enable all inputs
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# enable all outputs
li t1, 0xFFFFFFFF
sw t1, 0x08(t0)
# set initial output state
sw x0, 0x0C(t0)
# clear all pending interrupts
li t1, 0xFFFFFFFF
sw t1, 0x1C(t0)
sw t1, 0x24(t0)
sw t1, 0x2C(t0)
sw t1, 0x34(t0)
# ========== Rise Interrupt Enables ==========
# enable some rising edge interrupts
li t1, 0x0000FFFF
sw t1, 0x18(t0)
Intr02BEEF08:
# raise some pins
li t1, 0x00FFFF00
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
Intr02BEEF09:
# raise pins whose rise IEs are disabled
# should not cause an interrupt
li t1, 0x33FFFF00
sw t1, 0x0C(t0)
# raise pins whose rise IEs are enabled
li t1, 0x33FFFF33
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# =========== Fall Interrupts ===========
# (admittedly these are already used elsewhere)
# disable all rising edge interrupts
li t1, 0
sw t1, 0x18(t0)
# enable some falling edge interrupts
li t1, 0x0000FFFF
sw t1, 0x20(t0)
Intr02BEEF0A:
# lower some pins
li t1, 0x33000033
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# lower pins whose fall IEs are disabled
# and raise a bunch of other pins
# should not cause an interrupt
li t1, 0x00CCCC33
sw t1, 0x0C(t0)
Intr02BEEF0B:
# lower pins whose fall IEs are enabled
li t1, 0x00CCCC00
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# =========== High Interrupts ===========
# disable all falling edge interrupts
li t1, 0
sw t1, 0x20(t0)
# enable some high_ie's for low pins
# should not cause an interrupt
li t1, 0xFF0000FF
sw t1, 0x28(t0)
Intr02BEEF0C:
# enable some high_ie's for high pins
li t1, 0x0000FFFF
sw t1, 0x28(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# lower all pins
li t1, 0
sw t1, 0x0C(t0)
# lower any existing high_ip's
li t1, 0xFFFFFFFF
sw t1, 0x2C(t0)
# re-enable some high_ie's
li t1, 0xFFFF0000
sw t1, 0x28(t0)
# raise some pins whose high_ie's are disabled
li t1, 0x0000CCCC
sw t1, 0x0C(t0)
# disable some inputs
li t1, 0xFF00FFFF
sw t1, 0x04(t0)
# raise some pins whose inputs are disabled
li t1, 0x00CCCCCC
sw t1, 0x0C(t0)
Intr02BEEF0D:
# raise some pins whose high_ie's and inputs are enabled
li t1, 0xCCCCCCCC
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# =========== Low Interrupts ===========
# disable all high interrupts
li t1, 0
sw t1, 0x28(t0)
# enable all inputs
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# enable some low_ie's for high pins
# should not cause an interrupt
li t1, 0xCC0000CC
sw t1, 0x30(t0)
Intr02BEEF0E:
# enable some low_ie's for low pins
li t1, 0xCCCCFFFF
sw t1, 0x30(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# raise all pins
li t1, 0xFFFFFFFF
sw t1, 0x0C(t0)
# lower any existing low_ip's
# actually takes a little time for vals
# to propagate through synchronizer
# so this extra load is a nop effectively
li t1, 0xFFFFFFFF
sw t1, 0x34(t0)
# re-enable some low_ie's
li t1, 0xFF0000FF
sw t1, 0x30(t0)
# lower some pins whose low_ie's are disabled
li t1, 0xFF1111FF
sw t1, 0x0C(t0)
Intr02BEEF0F:
# disable some inputs of pins whose low_ie's are enabled
li t1, 0x0000FFFF
sw t1, 0x04(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# ========== Clear GPIO State ==========
# disable all interrupts
sw x0, 0x18(t0)
sw x0, 0x20(t0)
sw x0, 0x28(t0)
sw x0, 0x30(t0)
# enable all inputs
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# enable all outputs
li t1, 0xFFFFFFFF
sw t1, 0x08(t0)
# set initial output state
sw x0, 0x0C(t0)
# clear all pending interrupts
li t1, 0xFFFFFFFF
sw t1, 0x1C(t0)
sw t1, 0x24(t0)
sw t1, 0x2C(t0)
sw t1, 0x34(t0)
# ========== Output XOR Test ==========
# enable some inputs
li t1, 0x0000FFFF
sw t1, 0x04(t0)
# enable some outputs
li t1, 0xFF0000FF
sw t1, 0x08(t0)
# enable all rising and falling edge interrupts
li t1, 0xFFFFFFFF
sw t1, 0x18(t0)
sw t1, 0x20(t0)
Intr02BEEF10:
# XOR all outputs
li t1, 0xFFFFFFFF
sw t1, 0x40(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
Intr02BEEF11:
# XOR some outputs
li t1, 0x33333333
sw t1, 0x40(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# ========== Clear GPIO State ==========
# disable all interrupts
sw x0, 0x18(t0)
sw x0, 0x20(t0)
sw x0, 0x28(t0)
sw x0, 0x30(t0)
# enable all inputs
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# enable all outputs
li t1, 0xFFFFFFFF
sw t1, 0x08(t0)
# set initial output state
sw x0, 0x0C(t0)
# clear XOR
li t1, 0x00000000
sw t1, 0x40(t0)
# clear all pending interrupts
li t1, 0xFFFFFFFF
sw t1, 0x1C(t0)
sw t1, 0x24(t0)
sw t1, 0x2C(t0)
sw t1, 0x34(t0)
##################################
##### Test 3 - UART Testing #####
##################################
li a1, 0x03beef00 # group ID
# clear MEIE
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 0xA (UART) priority = 1
li t0, 0xC000000
li t1, 1
sw t1, 0x28(t0)
# enable source 0xA
li t0, 0x0C002000
li t1, 0b10000000000
sw t1, 0(t0)
# ========== Transmitter Holding Register Empty Interrupt (THRE) ==========
# MCR: Loop = 1
li t0, 0x10000000
li t1, 0b00010000
sb t1, 4(t0)
# LCR: Use 8 data bits plus odd parity bit
li t1, 0b00001011
sb t1, 3(t0)
# IER: Disable all interrupts for now
li t1, 0x0
sb t1, 1(t0)
# set MEIE
li t1, 0x800
csrrs x0, mie, t1
# THR: TX 'l'
li t1, 'l'
sb t1, 0(t0)
# wait directly on UART for completion
li t1, 0b01100001
1: lb t2, 5(t0)
bne t1, t2, 1b
Intr03BEEF12:
# IER: enable THR empty intr (ETBEI)
li t1, 0b00000010
sb t1, 1(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# IER: disable THR empty intr (ETBEI)
sb x0, 1(t0)
# THR: TX 'l'
li t1, 'l'
sb t1, 0(t0)
# THR: TX 'o'
li t1, 'o'
sb t1, 0(t0)
Intr03BEEF13:
# IER: enable THR empty intr (ETBEI)
li t1, 0b00000010
sb t1, 1(t0)
# This will take a few cycles before UART finishes TX'ing
# If we see SCR modifications in output, it means UART probably
# did wait until empty THR before triggering the interrupt.
sb t1, 7(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# ========== Received Data Available Intrrupt (ERBFI) & Loop Mode ==========
# Clear SCR
sb x0, 7(t0)
Intr03BEEF14:
# IER: enable RBR ready intr ERBFI
li t1, 0x1
sb t1, 1(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr03BEEF15:
# THR: TX ' '
li t1, 0x20
sb t1, 0(t0)
# This will take a few cycles before UART finishes RX'ing
# If we see SCR modifications in output, it means UART probably
# did wait until received data available before triggering the interrupt.
li t1, 3
sb t1, 7(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr03BEEF16:
# THR: TX 't'
li t1, 't'
sb t1, 0(t0)
# Same shenanigans as before, only now we also confirm
# that you can read the RBR before new data is available
# without messing up the receive interrupt.
lb t1, 0(t0)
sb t1, 7(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# MCR: Loop = 0
li t1, 0b00000000
sb t1, 4(t0)
# Clear SCR
sb x0, 7(t0)
# THR: TX 'h'
# should TX but not not trigger interrupt
li t1, 'h'
sb t1, 0(t0)
# wait directly on UART for completion
li t1, 0b01100000
1: lb t2, 5(t0)
bne t1, t2, 1b
# Can use THRE test from before to verify we are transmitting
# THR: TX 'e'
li t1, 'e'
sb t1, 0(t0)
# THR: TX 'r'
li t1, 'r'
sb t1, 0(t0)
Intr03BEEF17:
# IER: enable THR empty intr (ETBEI) and RBR ready intr (ERBFI)
li t1, 0b00000011
sb t1, 1(t0)
sb t1, 7(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# manually wait until transmitter finishes before enabling loop mode
li t1, 0b01100000
1: lb t2, 5(t0)
bne t1, t2, 1b
# MCR: Loop = 1
li t1, 0b00010000
sb t1, 4(t0)
Intr03BEEF18:
Intr03BEEF19:
# THR: TX 'e'
li t1, 'e'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# wait to finish again
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
# ========== Receiver Line Status Intr (ELSI) & Overrun Error (OE) ==========
# IER: Enable Receiver Line Status Intr (ELSI)
li t1, 0b00000100
sb t1, 1(t0)
li t1, 0xFF
sb t1, 7(t0)
# We can't cause all kinds of interesting errors, but at least we can
# cause an overrun error by transmitting twice without reading.
Intr03BEEF1A:
# THR: TX '\n'
li t1, 0xD
sb t1, 0(t0)
# THR: TX 'G'
li t1, 'G'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
####################################################
##### Test 4 - Signs of Life on PLIC Context 1 #####
####################################################
li a1, 0x04beef00 # group ID
# clear MEIE (good to turn off while configuring peripherals)
li t0, 0x800
csrrc x0, mie, t0
# ========== Configure PLIC ==========
# priority threshold = 0
li t0, 0xC200000
li t1, 0
sw t1, 0(t0)
# source 3 (GPIO) priority = 6
li t0, 0xC000000
li t1, 6
sw t1, 0x0C(t0)
# source 0xA (UART) priority = 7
li t1, 7
sw t1, 0x28(t0)
# disable sources 3,0xA on context 0
li t0, 0x0C002000
li t1, 0
sw t1, 0(t0)
# enable sources 3,0xA on context 1
li t0, 0x0C002080
li t1, 0b10000001000
sw t1, 0(t0)
# ========== Configure UART ==========
# MCR: Loop = 1
li t0, 0x10000000
li t1, 0b10000
sb t1, 4(t0)
# LCR: Use 8 data bits plus odd parity bit
li t1, 0b00001011
sb t1, 3(t0)
# IER: Enable Received Data Available Interrupt
li t1, 0x01
sb t1, 1(t0)
# ========== Configure GPIO ==========
# raise all input_en
li t0, 0x10060000
li t1, 0xFFFFFFFF
sw t1, 0x04(t0)
# raise all output_en
sw t1, 0x08(t0)
# raise all rise_en
sw t1, 0x18(t0)
# ========== Execute Test ==========
# set MEIE and SEIE
li t0, 0xA00
csrrs x0, mie, t0
Intr04BEEF1B:
# UART TX 'e'
li t0, 0x10000000
li t1, 'e'
sb t1, 0(t0)
# wait to finish
li t1, 0b00010000
1: bne t1,a0,1b
li a0, 0
Intr04BEEF1C:
# GPIO raise pin 19
li t0, 0x10060000
li t1, 0x00080000
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00001000
1: bne t1,a0,1b
li a0, 0
# Now let's go bonkers and trigger both!
Intr04BEEF1D:
# TX 'n'
li t0, 0x10000000
li t1, 'n'
sb t1, 0(t0)
Intr04BEEF1E:
# GPIO lower pin 19 raise pin 0
li t0, 0x10060000
li t1, 0x00000001
sw t1, 0x0C(t0)
# wait to finish
li t1, 0b00011000
1: bne t1,a0,1b
li a0, 0
# ---------------------------------------------------------------------------------------------
//terminate_test:
// li a0, 2 // Trap handler behavior (go to machine mode)
// ecall // writes mcause to the output.
// csrw mtvec, x4 // restore original trap handler to halt program
RVTEST_CODE_END
RVMODEL_HALT
RVTEST_DATA_BEGIN
# stack memory (size 16 words)
.align 3
stack:
.fill 16, 8, 0xdeadbeef
#ifdef rvtest_mtrap_routine
mtrap_sigptr:
.fill 64*(XLEN/32),4,0xdeadbeef
#endif
#ifdef rvtest_gpr_save
gpr_save:
.fill 32*(XLEN/32),4,0xdeadbeef
#endif
RVTEST_DATA_END
RVMODEL_DATA_BEGIN
# signature output
wally_signature:
.fill 0x200, 8, 0x00000000
sig_end_canary:
.int 0x0
rvtest_sig_end:
RVMODEL_DATA_END

View file

@ -24,7 +24,6 @@
#include "arch_test.h"
RVTEST_ISA("RV64I_Zicsr")
// this test is blocked, it won't build or run. To unblock it remove the check ISA:=regex(BLOCKED);
RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;def NO_SAIL=True",periph)
.section .text.init
@ -225,9 +224,6 @@ main_code: #####
# load address of trap handler
la t0, trap_handler
csrrw x0, mtvec, t0
# delegate all external interrupts to machine mode
li t0, 0xD00
csrrc x0, mideleg, t0
# set MIE
li t0, 0x8
csrrs x0, mstatus, t0