arch-riscv: Fix CSR instruction behavior 2nd attempts

Change-Id: Id0a9a374281445c7821863f0f74564857d3d8fa2
This commit is contained in:
Roger Chang
2024-04-30 16:33:43 +08:00
parent 1a81144985
commit c1713a0b18
4 changed files with 124 additions and 38 deletions

View File

@@ -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));

View File

@@ -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);
}
}

View File

@@ -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)

View File

@@ -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