arch-riscv: Fix interrupt and status CSR behavoir (#1091)

From sepc

> Instructions that access a non-existent CSR are reserved. Attempts to
access a CSR without appropriate privilege level raise
illegal-instruction exceptions or, as described in Section 13.6.1,
virtual-instruction exceptions. Attempts to write a read-only register
raise illegal-instruction exceptions. A read/write register might also
contain some bits that are read-only, in which case writes to the
read-only bits are ignored.

Setting the bit not in the mask should be ignore rather than raise the
illegal exception. The unmask bits of xstatus CSR are `WPRI`, the
unmasks bits of xie are `RO`(above priv v1.12) or `WPRI`(priv v1.11 and
priv v1.10), the unmask bits of xip CSR are `RO`(above priv v1.12) or
`WPRI`(priv v1.11) or `WIRI` (priv v1.10).

Note: The workload of `riscv-ubuntu-20.04-boot` uses the priv v1.10.

More details please see the `RISC-V spec:  Privileged Architecture`
v1.10:
https://github.com/riscv/riscv-isa-manual/releases/tag/riscv-priv-1.10
v1.11(20190608):
https://github.com/riscv/riscv-isa-manual/releases/tag/Ratified-IMFDQC-and-Priv-v1.11
v1.12(20211213):
https://github.com/riscv/riscv-isa-manual/releases/tag/Priv-v1.12

Change-Id: I5d6e964e99b30b71da3dc267cd1575665d922633
This commit is contained in:
Yu-Cheng Chang
2024-05-03 00:07:30 +08:00
committed by GitHub
parent e7566448fa
commit 8b885222b1

View File

@@ -422,20 +422,8 @@ def template CSRExecute {{
xc->setMiscReg(MISCREG_FFLAGS, bits(data, 4, 0));
xc->setMiscReg(MISCREG_FRM, bits(data, 7, 5));
break;
case CSR_MIP: case CSR_MIE:
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) {
xc->setMiscReg(midx, newdata_all);
} else {
return std::make_shared<IllegalInstFault>(
"Only bits in mask are allowed to be set\n",
machInst);
}
break;
default:
xc->setMiscReg(midx, data);
xc->setMiscReg(midx, newdata_all);
break;
}
}