feat: implement privileged mode support

This commit is contained in:
abnerhexu
2026-06-29 07:00:55 +00:00
parent a32db39c80
commit b6afa61e66
89 changed files with 49571 additions and 43647 deletions

View File

@@ -0,0 +1,93 @@
Running privileged RISC-V tests...
=================================
rv64mi-p-breakpoint: exit=0 PASS
rv64mi-p-csr: exit=0 PASS
rv64mi-p-illegal: exit=0 PASS
rv64mi-p-instret_overflow: exit=1 FAIL
[5] FLUSH exception=0 mtvec=0x0 mepc=0x0 mcause=0x0 frontend_pc=0x80000008
[65] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x0
[66] CSR commit slot0=1 slot1=0 addr=0x744 cmd=5 next=0x800000e8 mtvec=0x800000e8
[71] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800000e8
[72] CSR commit slot0=1 slot1=0 addr=0x180 cmd=5 next=0x800000f8 mtvec=0x800000f8
[77] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800000f8
[83] CSR commit slot0=1 slot1=0 addr=0x3b0 cmd=1 next=0x0 mtvec=0x8000011c
[86] CSR commit slot0=1 slot1=0 addr=0x3a0 cmd=1 next=0x0 mtvec=0x8000011c
[87] CSR commit slot0=1 slot1=0 addr=0x304 cmd=5 next=0x1f mtvec=0x8000011c
[92] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x8000011c
[93] CSR commit slot0=1 slot1=0 addr=0x302 cmd=5 next=0x80000134 mtvec=0x80000134
[95] CSR commit slot0=1 slot1=0 addr=0x303 cmd=5 next=0x0 mtvec=0x80000134
[101] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x80000134
[105] FLUSH exception=0 mtvec=0x80000004 mepc=0x0 mcause=0x0 frontend_pc=0x80000158
[114] FLUSH exception=0 mtvec=0x80000004 mepc=0x0 mcause=0x0 frontend_pc=0x80000170
[120] CSR commit slot0=1 slot1=0 addr=0x300 cmd=5 next=0x0 mtvec=0x80000004
[126] CSR commit slot0=1 slot1=0 addr=0x300 cmd=2 next=0x0 mtvec=0x80000004
[130] CSR commit slot0=1 slot1=0 addr=0x341 cmd=1 next=0x0 mtvec=0x80000004
[133] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001a0 mcause=0x0 frontend_pc=0x800001a8
[141] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x80000004
[142] FLUSH exception=1 mtvec=0x800001b0 mepc=0x800001a0 mcause=0x0 frontend_pc=0x800001b8
[147] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800001b0
[150] FLUSH exception=1 mtvec=0x80000004 mepc=0x800001ac mcause=0x2 frontend_pc=0x800001c0
[171] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001b8 mcause=0x2 frontend_pc=0x80000038
[177] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001b8 mcause=0x2 frontend_pc=0x80000200
[193] FLUSH exception=1 mtvec=0x80000004 mepc=0x800001b8 mcause=0x2 frontend_pc=0x800001f0
[205] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001e4 mcause=0xb frontend_pc=0x80000028
[213] STORE addr=0x80001000 data=0x5 size=2
Loaded segment: paddr=0x80000000 size=576
Loaded segment: paddr=0x80001000 size=72
ELF loaded: entry=0x80000000
[213] TEST FAILED: error code 2
rv64mi-p-ld-misaligned: exit=0 PASS
rv64mi-p-lh-misaligned: exit=0 PASS
rv64mi-p-lw-misaligned: exit=0 PASS
rv64mi-p-ma_addr: exit=0 PASS
rv64mi-p-ma_fetch: exit=0 PASS
rv64mi-p-mcsr: exit=1 FAIL
[5] FLUSH exception=0 mtvec=0x0 mepc=0x0 mcause=0x0 frontend_pc=0x80000008
[63] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x0
[65] CSR commit slot0=1 slot1=0 addr=0x744 cmd=5 next=0x0 mtvec=0x800000e4
[69] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800000e4
[71] CSR commit slot0=1 slot1=0 addr=0x180 cmd=5 next=0x0 mtvec=0x800000f4
[75] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x800000f4
[81] CSR commit slot0=1 slot1=0 addr=0x3b0 cmd=1 next=0x0 mtvec=0x80000118
[84] CSR commit slot0=1 slot1=0 addr=0x3a0 cmd=1 next=0x0 mtvec=0x80000118
[86] CSR commit slot0=1 slot1=0 addr=0x304 cmd=5 next=0x0 mtvec=0x80000118
[90] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x80000118
[92] CSR commit slot0=1 slot1=0 addr=0x302 cmd=5 next=0x0 mtvec=0x80000130
[93] CSR commit slot0=1 slot1=0 addr=0x303 cmd=5 next=0x0 mtvec=0x80000130
[99] CSR commit slot0=1 slot1=0 addr=0x305 cmd=1 next=0x0 mtvec=0x80000130
[104] FLUSH exception=0 mtvec=0x80000004 mepc=0x0 mcause=0x0 frontend_pc=0x80000150
[111] FLUSH exception=0 mtvec=0x80000004 mepc=0x0 mcause=0x0 frontend_pc=0x80000170
[117] CSR commit slot0=1 slot1=0 addr=0x300 cmd=5 next=0x0 mtvec=0x80000004
[121] CSR commit slot0=1 slot1=0 addr=0x300 cmd=2 next=0x0 mtvec=0x80000004
[126] CSR commit slot0=1 slot1=0 addr=0x341 cmd=1 next=0x0 mtvec=0x80000004
[129] FLUSH exception=0 mtvec=0x80000004 mepc=0x8000019c mcause=0x0 frontend_pc=0x800001a0
[149] FLUSH exception=1 mtvec=0x80000004 mepc=0x8000019c mcause=0x0 frontend_pc=0x800001c8
[167] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001c0 mcause=0x2 frontend_pc=0x80000030
[175] FLUSH exception=0 mtvec=0x80000004 mepc=0x800001c0 mcause=0x2 frontend_pc=0x80000038
[185] STORE addr=0x80001000 data=0x53b size=2
Loaded segment: paddr=0x80000000 size=572
Loaded segment: paddr=0x80001000 size=72
ELF loaded: entry=0x80000000
[185] TEST FAILED: error code 669
rv64mi-p-pmpaddr: exit=0 PASS
rv64mi-p-sbreak: exit=0 PASS
rv64mi-p-scall: exit=0 PASS
rv64mi-p-sd-misaligned: exit=0 PASS
rv64mi-p-sh-misaligned: exit=0 PASS
rv64mi-p-sw-misaligned: exit=0 PASS
rv64mi-p-zicntr: exit=0 PASS
rv64si-p-csr: exit=0 PASS
rv64si-p-dirty: exit=124 TIMEOUT
rv64si-p-icache-alias: exit=124 TIMEOUT
rv64si-p-ma_fetch: exit=0 PASS
rv64si-p-sbreak: exit=0 PASS
rv64si-p-scall: exit=0 PASS
rv64si-p-wfi: exit=0 PASS
rv64ui-p-fence_i: exit=0 PASS
=================================
Summary:
PASS: 21
FAIL: 2
TIMEOUT: 2
TOTAL: 25

View File

@@ -0,0 +1,95 @@
Running RISC-V tests...
====================
rv64ui-p-add: PASS
rv64ui-p-addi: PASS
rv64ui-p-addiw: PASS
rv64ui-p-addw: PASS
rv64ui-p-and: PASS
rv64ui-p-andi: PASS
rv64ui-p-auipc: PASS
rv64ui-p-beq: PASS
rv64ui-p-bge: PASS
rv64ui-p-bgeu: PASS
rv64ui-p-blt: PASS
rv64ui-p-bltu: PASS
rv64ui-p-bne: PASS
rv64ui-p-fence_i: PASS
rv64ui-p-jal: PASS
rv64ui-p-jalr: PASS
rv64ui-p-lb: PASS
rv64ui-p-lbu: PASS
rv64ui-p-ld: PASS
rv64ui-p-ld_st: PASS
rv64ui-p-lh: PASS
rv64ui-p-lhu: PASS
rv64ui-p-lui: PASS
rv64ui-p-lw: PASS
rv64ui-p-lwu: PASS
rv64ui-p-ma_data: FAIL
rv64ui-p-or: PASS
rv64ui-p-ori: PASS
rv64ui-p-sb: PASS
rv64ui-p-sd: PASS
rv64ui-p-sh: PASS
rv64ui-p-simple: PASS
rv64ui-p-sll: PASS
rv64ui-p-slli: PASS
rv64ui-p-slliw: PASS
rv64ui-p-sllw: PASS
rv64ui-p-slt: PASS
rv64ui-p-slti: PASS
rv64ui-p-sltiu: PASS
rv64ui-p-sltu: PASS
rv64ui-p-sra: PASS
rv64ui-p-srai: PASS
rv64ui-p-sraiw: PASS
rv64ui-p-sraw: PASS
rv64ui-p-srl: PASS
rv64ui-p-srli: PASS
rv64ui-p-srliw: PASS
rv64ui-p-srlw: PASS
rv64ui-p-st_ld: PASS
rv64ui-p-sub: PASS
rv64ui-p-subw: PASS
rv64ui-p-sw: PASS
rv64ui-p-xor: PASS
rv64ui-p-xori: PASS
rv64um-p-div: PASS
rv64um-p-divu: PASS
rv64um-p-divuw: PASS
rv64um-p-divw: PASS
rv64um-p-mul: PASS
rv64um-p-mulh: PASS
rv64um-p-mulhsu: PASS
rv64um-p-mulhu: PASS
rv64um-p-mulw: PASS
rv64um-p-rem: PASS
rv64um-p-remu: PASS
rv64um-p-remuw: PASS
rv64um-p-remw: PASS
rv64ua-p-amoadd_d: PASS
rv64ua-p-amoadd_w: PASS
rv64ua-p-amoand_d: PASS
rv64ua-p-amoand_w: PASS
rv64ua-p-amomax_d: PASS
rv64ua-p-amomaxu_d: PASS
rv64ua-p-amomaxu_w: PASS
rv64ua-p-amomax_w: PASS
rv64ua-p-amomin_d: PASS
rv64ua-p-amominu_d: PASS
rv64ua-p-amominu_w: PASS
rv64ua-p-amomin_w: PASS
rv64ua-p-amoor_d: PASS
rv64ua-p-amoor_w: PASS
rv64ua-p-amoswap_d: PASS
rv64ua-p-amoswap_w: PASS
rv64ua-p-amoxor_d: PASS
rv64ua-p-amoxor_w: PASS
rv64ua-p-lrsc: PASS
====================
Summary:
PASS: 85
FAIL: 1
TIMEOUT: 0
TOTAL: 86

28
sim/scripts/run_opensbi.sh Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
set -u
TESTBENCH="../verilator/obj_dir/VCore"
OPENSBI_BIN="${OPENSBI_BIN:-../../opensbi/build/platform/generic/firmware/fw_payload.elf}"
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-10}"
if [ ! -x "$TESTBENCH" ]; then
echo "Error: Testbench not found. Run 'make -C sim/verilator compile' first."
exit 1
fi
if [ ! -f "$OPENSBI_BIN" ]; then
echo "Error: OpenSBI payload not found: $OPENSBI_BIN"
echo "Set OPENSBI_BIN to a firmware ELF path."
exit 2
fi
echo "Running OpenSBI payload: $OPENSBI_BIN"
timeout "${TIMEOUT_SECONDS}s" "$TESTBENCH" "$OPENSBI_BIN"
exitcode=$?
if [ "$exitcode" -eq 124 ]; then
echo "OpenSBI run timed out"
exit 124
fi
exit "$exitcode"

View File

@@ -0,0 +1,75 @@
#!/bin/bash
set -u
TESTBENCH="../verilator/obj_dir/VCore"
TESTS_DIR="../../riscv-tests/isa"
RESULTS_DIR="../results"
RESULTS_FILE="$RESULTS_DIR/privileged_test_results.txt"
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-5}"
mkdir -p "$RESULTS_DIR"
if [ ! -x "$TESTBENCH" ]; then
echo "Error: Testbench not found. Run 'make -C sim/verilator compile' first."
exit 1
fi
echo "Running privileged RISC-V tests..." > "$RESULTS_FILE"
echo "=================================" >> "$RESULTS_FILE"
PASS=0
FAIL=0
TIMEOUT=0
shopt -s nullglob
tests=(
"$TESTS_DIR"/rv64mi-p-*
"$TESTS_DIR"/rv64si-p-*
"$TESTS_DIR"/rv64ui-p-fence_i
)
for test in "${tests[@]}"; do
[[ "$test" == *.dump ]] && continue
[ ! -f "$test" ] && continue
testname=$(basename "$test")
printf "Running %s... " "$testname"
output=$(timeout "${TIMEOUT_SECONDS}s" "$TESTBENCH" "$test" 2>&1)
exitcode=$?
if [ "$exitcode" -eq 0 ]; then
echo "PASS"
echo "$testname: exit=0 PASS" >> "$RESULTS_FILE"
PASS=$((PASS + 1))
elif [ "$exitcode" -eq 124 ]; then
echo "TIMEOUT"
echo "$testname: exit=124 TIMEOUT" >> "$RESULTS_FILE"
TIMEOUT=$((TIMEOUT + 1))
else
echo "FAIL (exit code $exitcode)"
echo "$testname: exit=$exitcode FAIL" >> "$RESULTS_FILE"
printf '%s\n' "$output" >> "$RESULTS_FILE"
FAIL=$((FAIL + 1))
fi
done
TOTAL=$((PASS + FAIL + TIMEOUT))
{
echo ""
echo "================================="
echo "Summary:"
echo " PASS: $PASS"
echo " FAIL: $FAIL"
echo " TIMEOUT: $TIMEOUT"
echo " TOTAL: $TOTAL"
} >> "$RESULTS_FILE"
echo ""
echo "Summary:"
echo " PASS: $PASS"
echo " FAIL: $FAIL"
echo " TIMEOUT: $TIMEOUT"
echo " TOTAL: $TOTAL"
echo ""
echo "Results saved to $RESULTS_FILE"

View File

@@ -2,7 +2,7 @@
TESTBENCH="../verilator/obj_dir/VCore"
TESTS_DIR="../../riscv-tests/isa"
RESULTS_FILE="test_results.txt"
RESULTS_FILE="../results/test_results.txt"
if [ ! -x "$TESTBENCH" ]; then
echo "Error: Testbench not found. Run 'make compile' first."

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. Set medeleg bit 8 and execute ecall from U-mode.
// 2. Expect delegation to S-mode handler when S support is enabled.
// 3. Clear delegation and verify ecall from U-mode traps to M-mode.

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. Toggle MSI, MTI, and MEI pending sources.
// 2. Verify enable bits gate interrupt injection.
// 3. Verify MEI > MTI > MSI priority and S-mode delegation bits.

View File

@@ -0,0 +1,5 @@
// Verilator scenario checklist:
// 1. Start in M-mode after reset.
// 2. Configure mstatus.MPP=S and mepc to an S-mode entry point.
// 3. Execute mret and verify the redirected PC equals mepc.
// 4. Execute an S-mode ecall path and verify trap state is recoverable.

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. sfence.vma in U-mode raises illegal instruction.
// 2. sfence.vma in S/M-mode flushes DTLB state.
// 3. fence.i invalidates ICache and flushes younger instructions.

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. Execute mret and sret with younger instructions in flight.
// 2. Verify commit emits flush and redirect.
// 3. Verify younger side effects are squashed.

View File

@@ -0,0 +1,3 @@
// Verilator scenario checklist:
// 1. Instruction fetch with pc[1:0] != 0 raises instruction address misaligned.
// 2. Load/store addresses not aligned to access size raise load/store address misaligned.

View File

@@ -0,0 +1,4 @@
// Verilator scenario checklist:
// 1. Unmapped instruction fetch raises instruction page fault.
// 2. Unmapped load/store raises load/store page fault.
// 3. U/S permission violations raise page fault instead of access fault.

View File

@@ -20,7 +20,7 @@ endif
SBT = env SBT_OPTS="-Dsbt.boot.directory=/tmp/sbt-boot -Dsbt.ivy.home=/tmp/sbt-ivy" COURSIER_CACHE=/tmp/coursier-cache sbt
CHISEL_DIR = ../..
OOO ?= 0
OOO ?= 1
ifeq ($(OOO),1)
RUN_MAIN = CoreOoO
GENERATED_DIR = $(CHISEL_DIR)/generated-ooo

View File

@@ -206,7 +206,8 @@ int main(int argc, char** argv) {
core->rootp->Core__DOT__frontend__DOT__icache__DOT__missAddr,
(unsigned)core->rootp->Core__DOT__fetchValid,
(unsigned)core->rootp->Core__DOT__fetchReady,
(unsigned)core->rootp->Core__DOT___frontend_io_outValid,
(unsigned)(core->rootp->Core__DOT__frontend__DOT__faultPending |
core->rootp->Core__DOT__frontend__DOT___icache_io_respValid),
(unsigned)core->rootp->Core__DOT__backend__DOT___issue_io_inReady_0,
(unsigned)core->rootp->Core__DOT__backend__DOT__rename__DOT__rob__DOT__count,
(unsigned)core->rootp->Core__DOT__backend__DOT__issue__DOT__queue__DOT__intRs__DOT__freeMask,
@@ -255,18 +256,16 @@ int main(int argc, char** argv) {
(unsigned)core->rootp->Core__DOT__backend__DOT__issue__DOT__queue__DOT__intRs__DOT__issue0OH,
(unsigned)core->rootp->Core__DOT__backend__DOT__issue__DOT__queue__DOT__intRs__DOT__issue1OH);
fprintf(stderr,
"complete: valid=%u/%u idx0=%u exc=%u/%u mis=%u/%u cause=0x%lx/0x%lx redirect=0x%lx/0x%lx\n",
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeValid_0,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeValid_1,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeIdx_0,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeException_0,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeException_1,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeMispredict_0,
(unsigned)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeMispredict_1,
(uint64_t)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeCause_0,
(uint64_t)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeCause_1,
(uint64_t)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeRedirectPc_0,
(uint64_t)core->rootp->Core__DOT__backend__DOT____Vcellinp__rename__io_completeRedirectPc_1);
"complete: valid=%u/%u idx0=%u exc=%u/%u cause=0x%lx/0x%lx redirect=0x%lx/0x%lx\n",
(unsigned)core->rootp->Core__DOT__backend__DOT__completeValid_0,
(unsigned)core->rootp->Core__DOT__backend__DOT__completeValid_1,
(unsigned)core->rootp->Core__DOT__backend__DOT__completeIdx_0,
(unsigned)core->rootp->Core__DOT__backend__DOT__completeException_0,
(unsigned)core->rootp->Core__DOT__backend__DOT__completeException_1,
(uint64_t)core->rootp->Core__DOT__backend__DOT__completeCause_0,
(uint64_t)core->rootp->Core__DOT__backend__DOT__completeCause_1,
(uint64_t)core->rootp->Core__DOT__backend__DOT__completeRedirectPc_0,
(uint64_t)core->rootp->Core__DOT__backend__DOT__completeRedirectPc_1);
exit_code = 2;
}