Skip to content

fix(csr): mask xepc[1:0] on sepc and vsepc write (IALIGN=32) - #7

Open
ojasshelke46 wants to merge 1 commit into
bsc-loca:mainfrom
ojasshelke46:fix/xepc-ialign-mask-sepc-vsepc
Open

fix(csr): mask xepc[1:0] on sepc and vsepc write (IALIGN=32)#7
ojasshelke46 wants to merge 1 commit into
bsc-loca:mainfrom
ojasshelke46:fix/xepc-ialign-mask-sepc-vsepc

Conversation

@ojasshelke46

Copy link
Copy Markdown

Summary

On a CSR write, sepc and vsepc mask only bit[0] to zero
({csr_wdata[63:1], 1'b0}), allowing a 2-byte-misaligned value to be
stored in these exception-PC registers.

This core does not implement the C extension — def_pkg ISA_CODE
hardwires the C bit to 0, so IALIGN=32. Per the RISC-V privileged spec
every exception-PC CSR (mepc/sepc/vsepc) must hold a value aligned
to IALIGN, i.e. bits[1:0] read as zero. A misaligned sepc/vsepc is
used as the jump target on SRET and would raise a spurious
instruction-address-misaligned trap that should not be reachable.
mepc already masks bits[1:0] correctly a few lines away in the same block.

Change

Mask bits[1:0] on both writes to match mepc:

  • sepc: sepc_int = {csr_wdata[63:2], 2'b0};
  • vsepc: vsepc_d = {csr_wdata[63:2], 2'b0}; (inside the RVH guard)

Related

#6 applies the same sepc fix (plus an stvec change). This PR
additionally covers vsepc, the RVH virtual-supervisor exception-PC,
which #6 leaves masking only bit[0].

Testing

verilator --lint-only -Wall on csr_bsc.sv: warning set is identical
before and after the change (0 errors, no new warnings, none on the
changed lines). There is no CSR/SRET testbench in-tree to exercise the
path at runtime.

On a CSR write, sepc and vsepc masked only bit[0] to zero
({csr_wdata[63:1], 1'b0}), allowing a 2-byte-misaligned value to be
stored in these exception-PC registers.

This core does not implement the C extension: def_pkg ISA_CODE hardwires
the C bit to 0, so IALIGN=32. The RISC-V privileged spec requires every
exception-PC CSR (mepc/sepc/vsepc) to hold a value aligned to IALIGN,
i.e. bits [1:0] read as zero when IALIGN=32. A misaligned sepc/vsepc is
used as the jump target on SRET and would raise a spurious
instruction-address-misaligned trap that should not be reachable. mepc
already masks bits [1:0] correctly a few lines away in the same block.

Mask bits [1:0] on both writes to match mepc:
  sepc_int = {csr_wdata[63:2], 2'b0};
  vsepc_d  = {csr_wdata[63:2], 2'b0};  // inside the RVH guard
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant