-
Notifications
You must be signed in to change notification settings - Fork 856
Description
Is there an existing CVA6 bug for this?
- I have searched the existing bug issues
Bug Description
When executing a csrrwi instruction on CSR 0x3B0 (which corresponds to the machine Physical Memory Protection Address Register 0, pmpaddr0), CVA6 always returns 0x0. Running the same test program on Spike and CVA6 gives different results for the same instruction, even though both use RV64 machine mode and the same initial state. This discrepancy may indicate a difference in how PMP address registers are reset or exposed.
Test Case
.section .text
.globl _start
_start:
la t0, trap_handler
csrw mtvec, t0
csrr t0, mstatus
li t1, 0x00003000 # enable FPU (FS = 0b11)
or t0, t0, t1
csrw mstatus, t0
csrw fcsr, x0 # clear floating-point status
j user_code
user_code:
csrrwi x16, 0x3b0, 12
...
Expected Behavior (Spike)
On Spike (RV64, with PMP enabled), the same ELF produces:
Instruction: csrrwi x16, 0x3b0, 12
Result: x16 = 0x3fffffffffffff
Spike returns the old value of pmpaddr0, with high bits set to 1 (as PMP entries default to all 1s in Spike’s implementation).
Actual Behavior (CVA6)
On CVA6 (same ELF, same instruction), the execution trace shows:
Instruction: csrrwi x16, 0x3b0, 12
Result: x16 = 0x0
CVA6 always returns zero, suggesting that either PMP registers are not implemented or reset to zero by default.
Questions
-
Is PMP (pmpaddr0) implemented and readable in the default CVA6 configuration?
-
Should PMP address registers return 0 by default, or follow Spike’s all-1 initialization?
-
If PMP is not enabled by default, should reading these CSRs raise an exception instead of silently returning 0?
Complete Program Assembly
The complete program assembly is as follows:
# 0 "./test_output_5/CVA6/program.S"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "./test_output_5/CVA6/program.S"
.section .text
.globl _start
_start:
la t0, trap_handler
csrw mtvec, t0
csrr t0, mstatus
li t1, 0x00003000 # enable FPU (FS = 0b11)
or t0, t0, t1
csrw mstatus, t0
csrw fcsr, x0 # clear floating-point status
j user_code
user_code:
csrrwi x16, 0x3b0, 12
exit:
li t0, 1 # always report success (exit code 0)
la t1, tohost
sd t0, 0(t1)
1:
j 1b
.align 2
trap_handler:
csrr t0, mepc # offending PC
csrr t1, mcause # trap cause
slli t5, t1, 1 # clear interrupt bit -> synchronous cause only
srli t1, t5, 1
li t2, 2 # default length (compressed)
li t3, 2 # illegal instruction -> mtval holds encoding
beq t1, t3, use_mtval
li t3, 1 # instruction access fault
beq t1, t3, update_mepc
li t3, 12 # instruction page fault
beq t1, t3, update_mepc
lhu t4, 0(t0) # fetch lower half-word of instruction
j decode_length
use_mtval:
csrr t4, mtval # mtval contains the faulting instruction
decode_length:
andi t4, t4, 3
li t3, 3
bne t4, t3, compressed_len
li t2, 4 # standard 32-bit instruction
j update_mepc
compressed_len:
li t2, 2 # compressed instruction
update_mepc:
add t0, t0, t2 # skip offending instruction
csrw mepc, t0
csrw mcause, x0
csrw mtval, x0
csrw mip, x0
mret
.section .tohost,"aw",@progbits
.align 6
.globl tohost
.globl fromhost
tohost:
.dword 0
fromhost:
.dword 0