arch-riscv: Implement behavior for senvcfg register
This commit adds behavior for writes to the senvcfg register. It also implements the CBIE, CBCFE, and CBZE bitfields of senvcfg.
This commit is contained in:
@@ -782,7 +782,27 @@ ISA::setMiscReg(RegIndex idx, RegVal val)
|
||||
break;
|
||||
case MISCREG_SENVCFG:
|
||||
{
|
||||
setMiscRegNoEffect(idx, val + 1);
|
||||
// panic on write to bitfields that aren't implemented in gem5
|
||||
SENVCFG panic_mask = 0;
|
||||
panic_mask.pmm = 3;
|
||||
|
||||
SENVCFG wpri_mask = 0;
|
||||
wpri_mask.wpri_1 = ~wpri_mask.wpri_1;
|
||||
wpri_mask.wpri_2 = ~wpri_mask.wpri_2;
|
||||
wpri_mask.wpri_3 = ~wpri_mask.wpri_3;
|
||||
|
||||
if ((panic_mask & val) != 0) {
|
||||
panic("Tried to write to an unimplemented bitfield in the "
|
||||
"senvcfg CSR!\nThe attempted write was:\n %" PRIu64 "\n",
|
||||
val);
|
||||
}
|
||||
|
||||
if ((wpri_mask & val) != 0) {
|
||||
warn("Ignoring write to WPRI bit(s) in senvcfg CSR.\n"
|
||||
"The attempted write was:\n %" PRIu64 "\n", val);
|
||||
} else {
|
||||
setMiscRegNoEffect(idx, val);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MISCREG_TSELECT:
|
||||
|
||||
@@ -1003,16 +1003,84 @@ decode QUADRANT default Unknown::unknown() {
|
||||
0x2: decode FUNCT12 {
|
||||
format CBMOp {
|
||||
0x0: cbo_inval({{
|
||||
Mem = 0;
|
||||
}}, mem_flags=[INVALIDATE, DST_POC]);
|
||||
SENVCFG senvcfg = xc->readMiscReg(MISCREG_SENVCFG);
|
||||
auto pm = (PrivilegeMode)xc->readMiscReg(
|
||||
MISCREG_PRV);
|
||||
|
||||
if (pm == PRV_U) {
|
||||
if (senvcfg.cbie == 0) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"Can't execute cbo.clean in current "
|
||||
"privilege mode!", machInst);
|
||||
}
|
||||
else if (senvcfg.cbie == 1){ //flush
|
||||
Mem = 0;
|
||||
}
|
||||
else if (senvcfg.cbie == 3) { // invalidate
|
||||
Mem = 0;
|
||||
} else { //sebvcfg.cbie == 2, reserved
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"Invalid value for senvcfg.cbie!",
|
||||
machInst);
|
||||
}
|
||||
} else if (pm == PRV_M){ // all invalidate
|
||||
Mem = 0;
|
||||
} else if (pm == PRV_S) {
|
||||
// whether it's a flush or invalidate depends on
|
||||
// menvcfg (01 and 11 respectively)
|
||||
Mem = 0;
|
||||
}
|
||||
}}, mem_flags = [INVALIDATE, DST_POC]);
|
||||
// mem_flags might need a conditional to add CLEAN
|
||||
// in certain cases; unsure of syntax for that
|
||||
|
||||
0x1: cbo_clean({{
|
||||
Mem = 0;
|
||||
SENVCFG senvcfg = xc->readMiscReg(MISCREG_SENVCFG);
|
||||
auto pm = (PrivilegeMode)xc->readMiscReg(
|
||||
MISCREG_PRV);
|
||||
|
||||
if (pm == PRV_U && !senvcfg.cbcfe){
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"Can't execute cbo.clean in current "
|
||||
"privilege mode!", machInst);
|
||||
// the specification has more conditions/privilege
|
||||
// modes to check, but menvcfg and henvcfg are not
|
||||
// implemented
|
||||
} else {
|
||||
Mem = 0;
|
||||
}
|
||||
}}, mem_flags=[CLEAN, DST_POC]);
|
||||
0x2: cbo_flush({{
|
||||
Mem = 0;
|
||||
SENVCFG senvcfg = xc->readMiscReg(MISCREG_SENVCFG);
|
||||
auto pm = (PrivilegeMode)xc->readMiscReg(
|
||||
MISCREG_PRV);
|
||||
|
||||
if (pm == PRV_U && !senvcfg.cbcfe){
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"Can't execute cbo.flush in current "
|
||||
"privilege mode!", machInst);
|
||||
// the specification has more conditions/privilege
|
||||
// modes to check, but menvcfg and henvcfg are not
|
||||
// implemented
|
||||
} else {
|
||||
Mem = 0;
|
||||
}
|
||||
}}, mem_flags=[CLEAN, INVALIDATE, DST_POC]);
|
||||
0x4: cbo_zero({{
|
||||
Mem = 0;
|
||||
SENVCFG senvcfg = xc->readMiscReg(MISCREG_SENVCFG);
|
||||
auto pm = (PrivilegeMode)xc->readMiscReg(
|
||||
MISCREG_PRV);
|
||||
|
||||
if (pm == PRV_U && !senvcfg.cbze){
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"Can't execute cbo.zero in current "
|
||||
"privilege mode!", machInst);
|
||||
// the specification has more conditions/privilege
|
||||
// modes to check, but menvcfg and henvcfg are not
|
||||
// implemented
|
||||
} else {
|
||||
Mem = 0;
|
||||
}
|
||||
}}, mem_flags=[CACHE_BLOCK_ZERO]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1265,6 +1265,20 @@ BitUnion64(INTERRUPT)
|
||||
Bitfield<0> usi;
|
||||
EndBitUnion(INTERRUPT)
|
||||
|
||||
|
||||
// From the RISCV specification version 20240411, volume 2,
|
||||
// section 10.1.10, page 98
|
||||
BitUnion64(SENVCFG)
|
||||
Bitfield<63,34> wpri_1;
|
||||
Bitfield<33,32> pmm;
|
||||
Bitfield<31,8> wpri_2;
|
||||
Bitfield<7> cbze;
|
||||
Bitfield<6> cbcfe;
|
||||
Bitfield<5,4> cbie;
|
||||
Bitfield<3,1> wpri_3;
|
||||
Bitfield<0> fiom;
|
||||
EndBitUnion(SENVCFG)
|
||||
|
||||
const off_t MXL_OFFSETS[enums::Num_RiscvType] = {
|
||||
[RV32] = (sizeof(uint32_t) * 8 - 2),
|
||||
[RV64] = (sizeof(uint64_t) * 8 - 2),
|
||||
|
||||
Reference in New Issue
Block a user