From 4b1c24542065380c6cff7ab2baa25e216a0ad38e Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Tue, 14 Feb 2023 10:26:09 +0800 Subject: [PATCH] arch-riscv: Fix the behavior of write to status CSR 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 Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/arch/riscv/insts/standard.hh | 2 +- src/arch/riscv/isa/formats/standard.isa | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/arch/riscv/insts/standard.hh b/src/arch/riscv/insts/standard.hh index afcfd7a915..2dfe73aedf 100644 --- a/src/arch/riscv/insts/standard.hh +++ b/src/arch/riscv/insts/standard.hh @@ -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; } } diff --git a/src/arch/riscv/isa/formats/standard.isa b/src/arch/riscv/isa/formats/standard.isa index 1bd431ac4d..c94a0bcdbd 100644 --- a/src/arch/riscv/isa/formats/standard.isa +++ b/src/arch/riscv/isa/formats/standard.isa @@ -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) { @@ -397,6 +397,7 @@ def template CSRExecute {{ %(code)s; + nonmaskdata = data & ~maskVal; data &= maskVal; if (write) { if (bits(csr, 11, 10) == 0x3) { @@ -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(