summaryrefslogtreecommitdiff
path: root/src/arch/riscv/isa/formats/standard.isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/riscv/isa/formats/standard.isa')
-rw-r--r--src/arch/riscv/isa/formats/standard.isa14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/arch/riscv/isa/formats/standard.isa b/src/arch/riscv/isa/formats/standard.isa
index e9539fe52..b2f8ee4bf 100644
--- a/src/arch/riscv/isa/formats/standard.isa
+++ b/src/arch/riscv/isa/formats/standard.isa
@@ -256,11 +256,25 @@ def template CSRExecute {{
} else {
DPRINTF(RiscvMisc, "Writing %#x to CSR %s.\n", data,
CSRData.at(csr).name);
+ INTERRUPT oldinterrupt = olddata;
+ INTERRUPT newinterrupt = data;
switch (csr) {
case CSR_FCSR:
xc->setMiscReg(MISCREG_FFLAGS, bits(data, 4, 0));
xc->setMiscReg(MISCREG_FRM, bits(data, 7, 5));
break;
+ case CSR_MIP: case CSR_MIE:
+ if (oldinterrupt.mei == newinterrupt.mei &&
+ oldinterrupt.mti == newinterrupt.mti &&
+ oldinterrupt.msi == newinterrupt.msi) {
+ xc->setMiscReg(CSRData.at(csr).physIndex,data);
+ } else {
+ std::string error = "Interrupt m bits are "
+ "read-only\n";
+ fault = make_shared<IllegalInstFault>(error,
+ machInst);
+ }
+ break;
default:
xc->setMiscReg(CSRData.at(csr).physIndex, data);
break;