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:
Erin Le
2024-12-05 14:47:44 -08:00
committed by Bobby R. Bruce
parent 3b62f1f8e4
commit e6b931213f
3 changed files with 108 additions and 6 deletions

View File

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

View File

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

View File

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