arch-riscv: Fix CSR instruction behavior 2nd attempts
Change-Id: Id0a9a374281445c7821863f0f74564857d3d8fa2
This commit is contained in:
@@ -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<RiscvISA::Interrupts *>(
|
||||
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<PCState>();
|
||||
@@ -698,18 +724,48 @@ ISA::setMiscReg(RegIndex idx, RegVal val)
|
||||
|
||||
case MISCREG_IP:
|
||||
{
|
||||
val = val & MI_MASK[getPrivilegeModeSet()];
|
||||
auto ic = dynamic_cast<RiscvISA::Interrupts *>(
|
||||
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<RiscvISA::Interrupts *>(
|
||||
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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -333,7 +333,6 @@ def template CSRExecute {{
|
||||
// We assume a riscv instruction is always run with a riscv ISA.
|
||||
auto isa = static_cast<RiscvISA::ISA*>(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<IllegalInstFault>(
|
||||
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)
|
||||
|
||||
@@ -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<int, CSRMetadata> 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<int, CSRMetadata> 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<int, CSRMetadata> 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<int, CSRMetadata> 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<int, CSRMetadata> 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<int, CSRMetadata> 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<int, CSRMetadata> 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<int, CSRMetadata> 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
|
||||
|
||||
Reference in New Issue
Block a user