diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 3ae9c25ae6..2d56055f79 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -482,12 +482,28 @@ ISA::readMiscReg(RegIndex idx) tc->getCpuPtr()->getInterruptController(tc->threadId())); return ic->readIP(); } + case MISCREG_UIP: + { + return readMiscReg(MISCREG_IP) & UI_MASK[getPrivilegeModeSet()]; + } + case MISCREG_SIP: + { + return readMiscReg(MISCREG_IP) & SI_MASK[getPrivilegeModeSet()]; + } case MISCREG_IE: { auto ic = dynamic_cast( tc->getCpuPtr()->getInterruptController(tc->threadId())); return ic->readIE(); } + case MISCREG_UIE: + { + return readMiscReg(MISCREG_IE) & UI_MASK[getPrivilegeModeSet()]; + } + case MISCREG_SIE: + { + return readMiscReg(MISCREG_IE) & SI_MASK[getPrivilegeModeSet()]; + } case MISCREG_SEPC: case MISCREG_MEPC: { @@ -551,6 +567,16 @@ ISA::readMiscReg(RegIndex idx) return readMiscRegNoEffect(idx); } + case MISCREG_USTATUS: + { + return readMiscReg(MISCREG_STATUS) & + USTATUS_MASKS[rvType()][getPrivilegeModeSet()]; + } + case MISCREG_SSTATUS: + { + return readMiscReg(MISCREG_STATUS) & + SSTATUS_MASKS[rvType()][getPrivilegeModeSet()]; + } case MISCREG_VLENB: { auto rpc = tc->pcState().as(); @@ -698,18 +724,48 @@ ISA::setMiscReg(RegIndex idx, RegVal val) case MISCREG_IP: { + val = val & MI_MASK[getPrivilegeModeSet()]; auto ic = dynamic_cast( tc->getCpuPtr()->getInterruptController(tc->threadId())); ic->setIP(val); } break; + case MISCREG_UIP: + { + RegVal mask = UI_MASK[getPrivilegeModeSet()]; + val = (val & mask) | (readMiscReg(MISCREG_IP) & ~mask); + setMiscReg(MISCREG_IP, val); + } + break; + case MISCREG_SIP: + { + RegVal mask = SI_MASK[getPrivilegeModeSet()]; + val = (val & mask) | (readMiscReg(MISCREG_IP) & ~mask); + setMiscReg(MISCREG_IP, val); + } + break; case MISCREG_IE: { + val = val & MI_MASK[getPrivilegeModeSet()]; auto ic = dynamic_cast( tc->getCpuPtr()->getInterruptController(tc->threadId())); ic->setIE(val); } break; + case MISCREG_UIE: + { + RegVal mask = UI_MASK[getPrivilegeModeSet()]; + val = (val & mask) | (readMiscReg(MISCREG_IE) & ~mask); + setMiscReg(MISCREG_IE, val); + } + break; + case MISCREG_SIE: + { + RegVal mask = SI_MASK[getPrivilegeModeSet()]; + val = (val & mask) | (readMiscReg(MISCREG_IE) & ~mask); + setMiscReg(MISCREG_IE, val); + } + break; case MISCREG_SATP: { // we only support bare and Sv39 mode; setting a different mode @@ -751,6 +807,7 @@ ISA::setMiscReg(RegIndex idx, RegVal val) break; case MISCREG_STATUS: { + val = val & MSTATUS_MASKS[rvType()][getPrivilegeModeSet()]; if (_rvType != RV32) { // SXL and UXL are hard-wired to 64 bit auto cur = readMiscRegNoEffect(idx); @@ -764,6 +821,22 @@ ISA::setMiscReg(RegIndex idx, RegVal val) setMiscRegNoEffect(idx, val); } break; + case MISCREG_USTATUS: + { + RegVal mask = USTATUS_MASKS[rvType()][getPrivilegeModeSet()]; + val = (val & mask) | + (readMiscRegNoEffect(MISCREG_STATUS) & ~mask); + setMiscReg(MISCREG_STATUS, val); + } + break; + case MISCREG_SSTATUS: + { + RegVal mask = SSTATUS_MASKS[rvType()][getPrivilegeModeSet()]; + val = (val & mask) | + (readMiscRegNoEffect(MISCREG_STATUS) & ~mask); + setMiscReg(MISCREG_STATUS, val); + } + break; case MISCREG_VXSAT: { setMiscRegNoEffect(idx, val & 0x1); @@ -787,6 +860,16 @@ ISA::setMiscReg(RegIndex idx, RegVal val) setMiscRegNoEffect(MISCREG_FFLAGS, new_val); } break; + case MISCREG_FFLAGS: + { + setMiscRegNoEffect(MISCREG_FFLAGS, val & FFLAGS_MASK); + } + break; + case MISCREG_FRM: + { + setMiscRegNoEffect(MISCREG_FRM, val & FRM_MASK); + } + break; case MISCREG_FCSR: { setMiscRegNoEffect(MISCREG_FFLAGS, bits(val, 4, 0)); diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index a714e5c585..252aba256c 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -5012,27 +5012,33 @@ decode QUADRANT default Unknown::unknown() { 0x1: csrrw({{ Rd = rvSext(data); data = rvZext(Rs1); - }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); + }}, 'RD != 0', 'true' + , IsSerializeAfter, IsNonSpeculative, No_OpClass); 0x2: csrrs({{ Rd = rvSext(data); data = rvZext(data | Rs1); - }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); + }}, 'true', 'RS1 != 0' + , IsSerializeAfter, IsNonSpeculative, No_OpClass); 0x3: csrrc({{ Rd = rvSext(data); data = rvZext(data & ~Rs1); - }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); + }}, 'true', 'RS1 != 0' + , IsSerializeAfter, IsNonSpeculative, No_OpClass); 0x5: csrrwi({{ Rd = rvSext(data); data = rvZext(uimm); - }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); + }}, 'RD != 0', 'true' + , IsSerializeAfter, IsNonSpeculative, No_OpClass); 0x6: csrrsi({{ Rd = rvSext(data); data = rvZext(data | uimm); - }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); + }}, 'true', 'uimm != 0' + , IsSerializeAfter, IsNonSpeculative, No_OpClass); 0x7: csrrci({{ Rd = rvSext(data); data = rvZext(data & ~uimm); - }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); + }}, 'true', 'uimm != 0' + , IsSerializeAfter, IsNonSpeculative, No_OpClass); } } diff --git a/src/arch/riscv/isa/formats/standard.isa b/src/arch/riscv/isa/formats/standard.isa index 452d7dc099..d2fe233c55 100644 --- a/src/arch/riscv/isa/formats/standard.isa +++ b/src/arch/riscv/isa/formats/standard.isa @@ -333,7 +333,6 @@ def template CSRExecute {{ // We assume a riscv instruction is always run with a riscv ISA. auto isa = static_cast(xc->tcBase()->getIsaPtr()); auto& csr_data = isa->getCSRDataMap(); - auto& csr_masks = isa->getCSRMaskMap(); MISA misa = isa->readMiscRegNoEffect(MISCREG_ISA); auto csr_data_it = csr_data.find(csr); @@ -360,14 +359,10 @@ def template CSRExecute {{ machInst); } - auto mask_it = csr_masks.find(csr); - RegVal maskVal = (mask_it == csr_masks.end()) ? mask(64) - : mask_it->second; - %(op_decl)s; %(op_rd)s; - RegVal data, olddata; + RegVal data = 0; auto lowestAllowedMode = (PrivilegeMode)bits(csr, 9, 8); auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV); if (pm < lowestAllowedMode) { @@ -389,29 +384,20 @@ def template CSRExecute {{ break; } - olddata = rvZext(xc->readMiscReg(midx)); - auto olddata_all = olddata; - - olddata &= maskVal; - DPRINTF(RiscvMisc, "Reading CSR %s: %#x\n", csrName, olddata); - data = olddata; + if (%(read_cond)s) { + data = rvZext(xc->readMiscReg(midx)); + } %(code)s; - data &= maskVal; - if (data != olddata) { + if (%(write_cond)s) { if (bits(csr, 11, 10) == 0x3) { return std::make_shared( csprintf("CSR %s is read-only\n", csrName), machInst); } - auto newdata_all = data; - // We must keep those original bits not in mask. - // olddata and data only contain the bits visable - // in current privilige level. - newdata_all = (olddata_all & ~maskVal) | data; DPRINTF(RiscvMisc, "Writing %#x to CSR %s.\n", - newdata_all, csrName); - xc->setMiscReg(midx, newdata_all); + data, csrName); + xc->setMiscReg(midx, data); } %(op_wb)s; return NoFault; @@ -516,8 +502,10 @@ def format SystemOp(code, *opt_flags) {{ exec_output = BasicExecute.subst(iop) }}; -def format CSROp(code, *opt_flags) {{ - iop = InstObjParams(name, Name, 'CSROp', code, opt_flags) +def format CSROp(code, read_cond, write_cond, *opt_flags) {{ + iop = InstObjParams(name, Name, 'CSROp', + {'code': code, 'read_cond': read_cond, + 'write_cond': write_cond}, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/src/arch/riscv/regs/misc.hh b/src/arch/riscv/regs/misc.hh index a1b7d483c3..9985c20364 100644 --- a/src/arch/riscv/regs/misc.hh +++ b/src/arch/riscv/regs/misc.hh @@ -248,9 +248,18 @@ enum MiscRegIndex NUM_PHYS_MISCREGS, + MISCREG_MSTATUS = MISCREG_STATUS, + MISCREG_MIP = MISCREG_IP, + MISCREG_MIE = MISCREG_IE, // This CSR shared the same space with MISCREG_FFLAGS MISCREG_FFLAGS_EXE = NUM_PHYS_MISCREGS, MISCREG_FCSR, + MISCREG_USTATUS, + MISCREG_UIP, + MISCREG_UIE, + MISCREG_SSTATUS, + MISCREG_SIP, + MISCREG_SIE, NUM_MISCREGS }; @@ -526,10 +535,10 @@ constexpr uint64_t isaExtsFlags() { const std::unordered_map CSRData = { {CSR_USTATUS, - {"ustatus", MISCREG_STATUS, rvTypeFlags(RV64, RV32), + {"ustatus", MISCREG_USTATUS, rvTypeFlags(RV64, RV32), isaExtsFlags('n')}}, {CSR_UIE, - {"uie", MISCREG_IE, rvTypeFlags(RV64, RV32), isaExtsFlags('n')}}, + {"uie", MISCREG_UIE, rvTypeFlags(RV64, RV32), isaExtsFlags('n')}}, {CSR_UTVEC, {"utvec", MISCREG_UTVEC, rvTypeFlags(RV64, RV32), isaExtsFlags('n')}}, {CSR_USCRATCH, @@ -543,7 +552,7 @@ const std::unordered_map CSRData = { {CSR_UTVAL, {"utval", MISCREG_UTVAL, rvTypeFlags(RV64, RV32), isaExtsFlags('n')}}, {CSR_UIP, - {"uip", MISCREG_IP, rvTypeFlags(RV64, RV32), isaExtsFlags('n')}}, + {"uip", MISCREG_UIP, rvTypeFlags(RV64, RV32), isaExtsFlags('n')}}, {CSR_FFLAGS, {"fflags", MISCREG_FFLAGS, rvTypeFlags(RV64, RV32), isaExtsFlags('f')}}, @@ -739,7 +748,7 @@ const std::unordered_map CSRData = { isaExtsFlags()}}, {CSR_SSTATUS, - {"sstatus", MISCREG_STATUS, rvTypeFlags(RV64, RV32), + {"sstatus", MISCREG_SSTATUS, rvTypeFlags(RV64, RV32), isaExtsFlags('s')}}, {CSR_SEDELEG, {"sedeleg", MISCREG_SEDELEG, rvTypeFlags(RV64, RV32), @@ -748,7 +757,7 @@ const std::unordered_map CSRData = { {"sideleg", MISCREG_SIDELEG, rvTypeFlags(RV64, RV32), isaExtsFlags('s')}}, {CSR_SIE, - {"sie", MISCREG_IE, rvTypeFlags(RV64, RV32), isaExtsFlags('s')}}, + {"sie", MISCREG_SIE, rvTypeFlags(RV64, RV32), isaExtsFlags('s')}}, {CSR_STVEC, {"stvec", MISCREG_STVEC, rvTypeFlags(RV64, RV32), isaExtsFlags('s')}}, {CSR_SCOUNTEREN, @@ -765,7 +774,7 @@ const std::unordered_map CSRData = { {CSR_STVAL, {"stval", MISCREG_STVAL, rvTypeFlags(RV64, RV32), isaExtsFlags('s')}}, {CSR_SIP, - {"sip", MISCREG_IP, rvTypeFlags(RV64, RV32), isaExtsFlags('s')}}, + {"sip", MISCREG_SIP, rvTypeFlags(RV64, RV32), isaExtsFlags('s')}}, {CSR_SATP, {"satp", MISCREG_SATP, rvTypeFlags(RV64, RV32), isaExtsFlags('s')}}, @@ -779,7 +788,7 @@ const std::unordered_map CSRData = { {CSR_MHARTID, {"mhartid", MISCREG_HARTID, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, {CSR_MSTATUS, - {"mstatus", MISCREG_STATUS, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, + {"mstatus", MISCREG_MSTATUS, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, {CSR_MISA, {"misa", MISCREG_ISA, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, {CSR_MEDELEG, @@ -787,7 +796,7 @@ const std::unordered_map CSRData = { {CSR_MIDELEG, {"mideleg", MISCREG_MIDELEG, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, {CSR_MIE, - {"mie", MISCREG_IE, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, + {"mie", MISCREG_MIE, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, {CSR_MTVEC, {"mtvec", MISCREG_MTVEC, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, {CSR_MCOUNTEREN, @@ -805,7 +814,7 @@ const std::unordered_map CSRData = { {CSR_MTVAL, {"mtval", MISCREG_MTVAL, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, {CSR_MIP, - {"mip", MISCREG_IP, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, + {"mip", MISCREG_MIP, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, {CSR_PMPCFG0, {"pmpcfg0", MISCREG_PMPCFG0, rvTypeFlags(RV64, RV32), isaExtsFlags()}}, // pmpcfg1 rv32 only