Skip to content

Commit

Permalink
arch-riscv: Fix the behavior of write to status CSR
Browse files Browse the repository at this point in the history
According to RISC V spec Volumn I, Section 11.1, the CSR will be
written only if RS1 != 0 or imm != 0. However, after the change
of CL(https://gem5-review.googlesource.com/c/public/gem5/+/67717),
it will cause IllegalInstFault to write status CSR if we don't
change the data.

Example of Instruction Fault for mstatus

```
addi a5, zero, 8
csrc mstatus, a5
```

It will cause instruction fault if mstatus value is 0 due to
"newdata_all == olddata_all". We can just simply check if
the data value is changed out of mask.

Change-Id: Iab4ce7ac646a9105dc04e69c24d084572e28ebab
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67897
Reviewed-by: Yu-hsin Wang <[email protected]>
Maintainer: Jason Lowe-Power <[email protected]>
Tested-by: kokoro <[email protected]>
  • Loading branch information
rogerchang23424 committed Feb 15, 2023
1 parent e10be09 commit 4b1c245
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/arch/riscv/insts/standard.hh
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class CSROp : public RiscvStaticInst
strcmp(mnemonic, "csrrc") == 0 ||
strcmp(mnemonic, "csrrsi") == 0 ||
strcmp(mnemonic, "csrrci") == 0 ){
if (RS1 == 0) {
if (RS1 == 0 || uimm == 0) {
write = false;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/arch/riscv/isa/formats/standard.isa
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def template CSRExecute {{
%(op_decl)s;
%(op_rd)s;

RegVal data = 0, olddata = 0;
RegVal data = 0, olddata = 0, nonmaskdata = 0;
auto lowestAllowedMode = (PrivilegeMode)bits(csr, 9, 8);
auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV);
if (pm < lowestAllowedMode) {
Expand Down Expand Up @@ -397,6 +397,7 @@ def template CSRExecute {{

%(code)s;

nonmaskdata = data & ~maskVal;
data &= maskVal;
if (write) {
if (bits(csr, 11, 10) == 0x3) {
Expand All @@ -419,7 +420,7 @@ def template CSRExecute {{
case CSR_SIP: case CSR_SIE:
case CSR_UIP: case CSR_UIE:
case CSR_MSTATUS: case CSR_SSTATUS: case CSR_USTATUS:
if (newdata_all != olddata_all) {
if (nonmaskdata == 0) {
xc->setMiscReg(midx, newdata_all);
} else {
return std::make_shared<IllegalInstFault>(
Expand Down

0 comments on commit 4b1c245

Please sign in to comment.