Skip to content

OpenC910: Reserved W-only PMP permissions are preserved on readback #56

Description

@KnightGOKU

Summary

OpenC910 accepts and reads back the reserved PMP permission encoding R=0,W=1. According to the RISC-V privileged architecture, the R/W/X field combination with W=1,R=0 is reserved and should not remain visible as an implemented PMP permission state.

The minimal test case is a PMP CSR readback test:

  • write pmpcfg0[7:0] = 0x0a (A=OFF, R=0,W=1,X=0)
  • read pmpcfg0
  • compare the low byte

Expected result:

  • the illegal W-only value is WARL-normalized or otherwise not read back as 0x0a

Actual result on OpenC910:

  • pmpcfg0[7:0] reads back as 0x0a

Testcase idea

The testcase writes the reserved W-only PMP config byte and immediately reads it back:

.include "openc910_min_common.inc"

.text
.align 6
.global main
main:
  li    t0, 0x0a
  csrw  pmpcfg0, t0
  csrr  t1, pmpcfg0
  andi  t1, t1, 0xff
  li    t2, 0x0a
  beq   t1, t2, 1f
  li    a0, 'N'
  jal   ra, oracle_putc
  j     .
1:
  li    a0, 'E'
  jal   ra, oracle_putc
  j     .

If the bug is present, the testcase prints E.

How to reproduce

Build OpenC910's native Verilator simulator

Run this once:

cd openc910/smart_run
make compile SIM=verilator THREADS=8
make buildVerilator

Compile and run the testcase

/opt/riscv/bin/riscv64-unknown-elf-gcc -c -march=rv64gc_zicsr_zifencei -mabi=lp64d -O2 openc910_min_crt0.S -o openc910_min_crt0.o
/opt/riscv/bin/riscv64-unknown-elf-gcc -c -march=rv64gc_zicsr_zifencei -mabi=lp64d -O2 openc910_pmpcfg_w_only_eq_marker.S -o openc910_pmpcfg_w_only_eq_marker.o
/opt/riscv/bin/riscv64-unknown-elf-gcc -nostdlib -nostartfiles -march=rv64gc_zicsr_zifencei -mabi=lp64d -T openc910_min_linker.ld openc910_min_crt0.o openc910_pmpcfg_w_only_eq_marker.o -o openc910_pmpcfg_w_only_eq_marker.elf
/opt/riscv/bin/riscv64-unknown-elf-objcopy -O srec openc910_pmpcfg_w_only_eq_marker.elf openc910_pmpcfg_w_only_eq_marker_inst.hex -j .text* -j .rodata* -j .eh_frame*
/opt/riscv/bin/riscv64-unknown-elf-objcopy -O srec openc910_pmpcfg_w_only_eq_marker.elf openc910_pmpcfg_w_only_eq_marker_data.hex -j .data* -j .bss -j .sbss -j .COMMON
../tests/bin/Srec2vmem openc910_pmpcfg_w_only_eq_marker_inst.hex inst.pat
../tests/bin/Srec2vmem openc910_pmpcfg_w_only_eq_marker_data.hex data.pat
./obj_dir/Vtop

Observed output:

  • E

Meaning:

  • E = the illegal W-only value was preserved on readback
  • no E = the value was normalized or changed

The seed intentionally self-spins after printing the marker, so a local run typically ends at the simulation cutoff afterward.

Test Case: test.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions