arch-riscv: Support combination of privilege modes configuration (#522)
The user can select privilege modes witch is included in the system, not always enable the user and supervisor privilege modes.
This commit is contained in:
@@ -74,6 +74,16 @@ class RiscvType(Enum):
|
||||
vals = ["RV32", "RV64"]
|
||||
|
||||
|
||||
class PrivilegeModeSet(Enum):
|
||||
vals = [
|
||||
"M", # Machine privilege mode only
|
||||
"MU", # Machine and user privlege modes implemented
|
||||
"MNU", # MU privilege modes with user-mode trap
|
||||
"MSU", # Machine, supervisor and user modes implemented
|
||||
"MNSU", # MSU privilege modes with user-mode trap
|
||||
]
|
||||
|
||||
|
||||
class RiscvISA(BaseISA):
|
||||
type = "RiscvISA"
|
||||
cxx_class = "gem5::RiscvISA::ISA"
|
||||
@@ -95,6 +105,11 @@ class RiscvISA(BaseISA):
|
||||
"Length of each vector element in bits. \
|
||||
ELEN in Ch. 2 of RISC-V vector spec",
|
||||
)
|
||||
privilege_mode_set = Param.PrivilegeModeSet(
|
||||
"MSU",
|
||||
"The combination of privilege modes \
|
||||
in Privilege Levels section of RISC-V privileged spec",
|
||||
)
|
||||
|
||||
enable_Zicbom_fs = Param.Bool(True, "Enable Zicbom extension in FS mode")
|
||||
enable_Zicboz_fs = Param.Bool(True, "Enable Zicboz extension in FS mode")
|
||||
|
||||
@@ -73,7 +73,7 @@ SimObject('RiscvFsWorkload.py',
|
||||
SimObject('RiscvInterrupts.py', sim_objects=['RiscvInterrupts'],
|
||||
tags='riscv isa')
|
||||
SimObject('RiscvISA.py', sim_objects=['RiscvISA'],
|
||||
enums=['RiscvType'], tags='riscv isa')
|
||||
enums=['RiscvType', 'PrivilegeModeSet'], tags='riscv isa')
|
||||
SimObject('RiscvMMU.py', sim_objects=['RiscvMMU'], tags='riscv isa')
|
||||
SimObject('RiscvSeWorkload.py', sim_objects=[
|
||||
'RiscvSEWorkload', 'RiscvEmuLinux'], tags='riscv isa')
|
||||
|
||||
@@ -67,6 +67,7 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
if (FullSystem) {
|
||||
PrivilegeMode pp = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV);
|
||||
PrivilegeMode prv = PRV_M;
|
||||
MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
|
||||
STATUS status = tc->readMiscReg(MISCREG_STATUS);
|
||||
|
||||
// According to riscv-privileged-v1.11, if a NMI occurs at the middle
|
||||
@@ -82,18 +83,18 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
} else if (isInterrupt()) {
|
||||
if (pp != PRV_M &&
|
||||
bits(tc->readMiscReg(MISCREG_MIDELEG), _code) != 0) {
|
||||
prv = PRV_S;
|
||||
prv = (misa.rvs) ? PRV_S : ((misa.rvn) ? PRV_U : PRV_M);
|
||||
}
|
||||
if (pp == PRV_U &&
|
||||
if (pp == PRV_U && misa.rvs && misa.rvn &&
|
||||
bits(tc->readMiscReg(MISCREG_SIDELEG), _code) != 0) {
|
||||
prv = PRV_U;
|
||||
}
|
||||
} else {
|
||||
if (pp != PRV_M &&
|
||||
bits(tc->readMiscReg(MISCREG_MEDELEG), _code) != 0) {
|
||||
prv = PRV_S;
|
||||
prv = (misa.rvs) ? PRV_S : ((misa.rvn) ? PRV_U : PRV_M);
|
||||
}
|
||||
if (pp == PRV_U &&
|
||||
if (pp == PRV_U && misa.rvs && misa.rvn &&
|
||||
bits(tc->readMiscReg(MISCREG_SEDELEG), _code) != 0) {
|
||||
prv = PRV_U;
|
||||
}
|
||||
|
||||
@@ -69,21 +69,41 @@ class Interrupts : public BaseInterrupts
|
||||
{
|
||||
INTERRUPT mask = 0;
|
||||
STATUS status = tc->readMiscReg(MISCREG_STATUS);
|
||||
INTERRUPT mideleg = tc->readMiscReg(MISCREG_MIDELEG);
|
||||
INTERRUPT sideleg = tc->readMiscReg(MISCREG_SIDELEG);
|
||||
MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
|
||||
INTERRUPT mideleg = 0;
|
||||
if (misa.rvs || misa.rvn) {
|
||||
mideleg = tc->readMiscReg(MISCREG_MIDELEG);
|
||||
}
|
||||
INTERRUPT sideleg = 0;
|
||||
if (misa.rvs && misa.rvn) {
|
||||
sideleg = tc->readMiscReg(MISCREG_SIDELEG);
|
||||
}
|
||||
PrivilegeMode prv = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV);
|
||||
switch (prv) {
|
||||
case PRV_U:
|
||||
mask.mei = (!sideleg.mei) | (sideleg.mei & status.uie);
|
||||
mask.mti = (!sideleg.mti) | (sideleg.mti & status.uie);
|
||||
mask.msi = (!sideleg.msi) | (sideleg.msi & status.uie);
|
||||
mask.sei = (!sideleg.sei) | (sideleg.sei & status.uie);
|
||||
mask.sti = (!sideleg.sti) | (sideleg.sti & status.uie);
|
||||
mask.ssi = (!sideleg.ssi) | (sideleg.ssi & status.uie);
|
||||
// status.uie is always 0 if misa.rvn is disabled
|
||||
if (misa.rvs) {
|
||||
mask.mei = (!sideleg.mei) | (sideleg.mei & status.uie);
|
||||
mask.mti = (!sideleg.mti) | (sideleg.mti & status.uie);
|
||||
mask.msi = (!sideleg.msi) | (sideleg.msi & status.uie);
|
||||
mask.sei = (!sideleg.sei) | (sideleg.sei & status.uie);
|
||||
mask.sti = (!sideleg.sti) | (sideleg.sti & status.uie);
|
||||
mask.ssi = (!sideleg.ssi) | (sideleg.ssi & status.uie);
|
||||
} else {
|
||||
// According to the RISC-V privilege spec v1.10, if the
|
||||
// S privilege mode is not implemented and user-trap
|
||||
// support, setting mideleg/medeleg bits will delegate the
|
||||
// trap to U-mode trap handler
|
||||
mask.mei = (!mideleg.mei) | (mideleg.mei & status.uie);
|
||||
mask.mti = (!mideleg.mti) | (mideleg.mti & status.uie);
|
||||
mask.msi = (!mideleg.msi) | (mideleg.msi & status.uie);
|
||||
mask.sei = mask.sti = mask.ssi = 0;
|
||||
}
|
||||
if (status.uie)
|
||||
mask.uei = mask.uti = mask.usi = 1;
|
||||
break;
|
||||
case PRV_S:
|
||||
// status.sie is always 0 if misa.rvn is disabled
|
||||
mask.mei = (!mideleg.mei) | (mideleg.mei & status.sie);
|
||||
mask.mti = (!mideleg.mti) | (mideleg.mti & status.sie);
|
||||
mask.msi = (!mideleg.msi) | (mideleg.msi & status.sie);
|
||||
|
||||
@@ -254,9 +254,10 @@ RegClass ccRegClass(CCRegClass, CCRegClassName, 0, debug::IntRegs);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
ISA::ISA(const Params &p) :BaseISA(p),
|
||||
ISA::ISA(const Params &p) : BaseISA(p),
|
||||
_rvType(p.riscv_type), checkAlignment(p.check_alignment),
|
||||
enableRvv(p.enable_rvv),vlen(p.vlen),elen(p.elen)
|
||||
enableRvv(p.enable_rvv), vlen(p.vlen), elen(p.elen),
|
||||
_privilegeModeSet(p.privilege_mode_set)
|
||||
{
|
||||
_regClasses.push_back(&intRegClass);
|
||||
_regClasses.push_back(&floatRegClass);
|
||||
@@ -324,8 +325,25 @@ void ISA::clear()
|
||||
|
||||
// default config arch isa string is rv64(32)imafdc
|
||||
misa.rvi = misa.rvm = misa.rva = misa.rvf = misa.rvd = misa.rvc = 1;
|
||||
// default privlege modes if MSU
|
||||
misa.rvs = misa.rvu = 1;
|
||||
|
||||
switch (getPrivilegeModeSet()) {
|
||||
case enums::M:
|
||||
break;
|
||||
case enums::MU:
|
||||
misa.rvu = 1;
|
||||
break;
|
||||
case enums::MNU:
|
||||
misa.rvu = misa.rvn = 1;
|
||||
break;
|
||||
case enums::MSU:
|
||||
misa.rvs = misa.rvu = 1;
|
||||
break;
|
||||
case enums::MNSU:
|
||||
misa.rvs = misa.rvu = misa.rvn = 1;
|
||||
break;
|
||||
default:
|
||||
panic("Privilege mode set config should not reach here");
|
||||
}
|
||||
|
||||
// mark FS is initial
|
||||
status.fs = INITIAL;
|
||||
@@ -510,6 +528,24 @@ ISA::readMiscReg(RegIndex idx)
|
||||
default:
|
||||
panic("%s: Unknown _rvType: %d", name(), (int)_rvType);
|
||||
}
|
||||
// Check status.mpp
|
||||
MISA misa = readMiscRegNoEffect(MISCREG_ISA);
|
||||
switch(status.mpp) {
|
||||
case PRV_U:
|
||||
status.mpp = (misa.rvu) ? PRV_U : PRV_M;
|
||||
break;
|
||||
case PRV_S:
|
||||
if (misa.rvs)
|
||||
status.mpp = PRV_S;
|
||||
else
|
||||
status.mpp = (misa.rvu) ? PRV_U : PRV_M;
|
||||
break;
|
||||
case PRV_M:
|
||||
break;
|
||||
default:
|
||||
status.mpp = (misa.rvu) ? PRV_U : PRV_M;
|
||||
}
|
||||
|
||||
setMiscRegNoEffect(idx, status);
|
||||
|
||||
return readMiscRegNoEffect(idx);
|
||||
@@ -697,6 +733,9 @@ ISA::setMiscReg(RegIndex idx, RegVal val)
|
||||
if (!getEnableRvv()) {
|
||||
new_misa.rvv = 0;
|
||||
}
|
||||
new_misa.rvn = cur_misa.rvn;
|
||||
new_misa.rvs = cur_misa.rvs;
|
||||
new_misa.rvu = cur_misa.rvu;
|
||||
setMiscRegNoEffect(idx, new_misa);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -94,6 +94,11 @@ class ISA : public BaseISA
|
||||
*/
|
||||
unsigned elen;
|
||||
|
||||
/** The combination of privilege modes
|
||||
* in Privilege Levels section of RISC-V privileged spec
|
||||
*/
|
||||
PrivilegeModeSet _privilegeModeSet;
|
||||
|
||||
public:
|
||||
using Params = RiscvISAParams;
|
||||
|
||||
@@ -124,7 +129,7 @@ class ISA : public BaseISA
|
||||
virtual const std::unordered_map<int, RegVal>&
|
||||
getCSRMaskMap() const
|
||||
{
|
||||
return CSRMasks[_rvType];
|
||||
return CSRMasks[_rvType][_privilegeModeSet];
|
||||
}
|
||||
|
||||
bool alignmentCheckEnabled() const { return checkAlignment; }
|
||||
@@ -164,6 +169,8 @@ class ISA : public BaseISA
|
||||
unsigned getVecLenInBytes() { return vlen >> 3; }
|
||||
unsigned getVecElemLenInBits() { return elen; }
|
||||
|
||||
PrivilegeModeSet getPrivilegeModeSet() { return _privilegeModeSet; }
|
||||
|
||||
virtual Addr getFaultHandlerAddr(
|
||||
RegIndex idx, uint64_t cause, bool intr) const;
|
||||
};
|
||||
|
||||
@@ -4595,6 +4595,12 @@ decode QUADRANT default Unknown::unknown() {
|
||||
xc->pcState());
|
||||
}}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
|
||||
0x2: uret({{
|
||||
MISA misa = xc->readMiscReg(MISCREG_ISA);
|
||||
if (!misa.rvn) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"sret can't execute without N systems",
|
||||
machInst);
|
||||
}
|
||||
STATUS status = xc->readMiscReg(MISCREG_STATUS);
|
||||
status.uie = status.upie;
|
||||
status.upie = 1;
|
||||
@@ -4604,6 +4610,12 @@ decode QUADRANT default Unknown::unknown() {
|
||||
}
|
||||
0x8: decode RS2 {
|
||||
0x2: sret({{
|
||||
MISA misa = xc->readMiscReg(MISCREG_ISA);
|
||||
if (!misa.rvs) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"sret can't execute without RVS",
|
||||
machInst);
|
||||
}
|
||||
STATUS status = xc->readMiscReg(MISCREG_STATUS);
|
||||
auto pm = (PrivilegeMode)xc->readMiscReg(
|
||||
MISCREG_PRV);
|
||||
@@ -4623,11 +4635,12 @@ decode QUADRANT default Unknown::unknown() {
|
||||
}
|
||||
}}, IsSerializeAfter, IsNonSpeculative, IsReturn);
|
||||
0x5: wfi({{
|
||||
MISA misa = xc->readMiscReg(MISCREG_ISA);
|
||||
STATUS status = xc->readMiscReg(MISCREG_STATUS);
|
||||
auto pm = (PrivilegeMode)xc->readMiscReg(
|
||||
MISCREG_PRV);
|
||||
if (pm == PRV_U ||
|
||||
(pm == PRV_S && status.tw == 1)) {
|
||||
if (misa.rvs && (pm == PRV_U ||
|
||||
(pm == PRV_S && status.tw == 1))) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"wfi in user mode or TW enabled",
|
||||
machInst);
|
||||
@@ -4647,6 +4660,12 @@ decode QUADRANT default Unknown::unknown() {
|
||||
IsSerializeAfter, No_OpClass);
|
||||
}
|
||||
0x9: sfence_vma({{
|
||||
MISA misa = xc->readMiscReg(MISCREG_ISA);
|
||||
if (!misa.rvs) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
"sfence_vma can't execute without RVS",
|
||||
machInst);
|
||||
}
|
||||
STATUS status = xc->readMiscReg(MISCREG_STATUS);
|
||||
auto pm = (PrivilegeMode)xc->readMiscReg(MISCREG_PRV);
|
||||
if (pm == PRV_U || (pm == PRV_S && status.tvm == 1)) {
|
||||
|
||||
@@ -334,6 +334,7 @@ def template CSRExecute {{
|
||||
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);
|
||||
if (csr_data_it == csr_data.end()) {
|
||||
@@ -351,6 +352,14 @@ def template CSRExecute {{
|
||||
machInst);
|
||||
}
|
||||
|
||||
MISA csr_exts = csr_data_it->second.isaExts;
|
||||
if ((csr_exts & misa) != csr_exts) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
csprintf("%s is not support in the isa spec %d\n",
|
||||
csrName),
|
||||
machInst);
|
||||
}
|
||||
|
||||
auto mask_it = csr_masks.find(csr);
|
||||
RegVal maskVal = (mask_it == csr_masks.end()) ? mask(64)
|
||||
: mask_it->second;
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#include "arch/generic/pcstate.hh"
|
||||
#include "arch/riscv/regs/vector.hh"
|
||||
#include "enums/PrivilegeModeSet.hh"
|
||||
#include "enums/RiscvType.hh"
|
||||
|
||||
namespace gem5
|
||||
@@ -55,6 +56,8 @@ using RiscvType = enums::RiscvType;
|
||||
constexpr enums::RiscvType RV32 = enums::RV32;
|
||||
constexpr enums::RiscvType RV64 = enums::RV64;
|
||||
|
||||
using PrivilegeModeSet = enums::PrivilegeModeSet;
|
||||
|
||||
class PCState : public GenericISA::UPCState<4>
|
||||
{
|
||||
protected:
|
||||
|
||||
@@ -106,6 +106,10 @@ RiscvProcess64::initState()
|
||||
tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
|
||||
auto *isa = dynamic_cast<ISA*>(tc->getIsaPtr());
|
||||
fatal_if(isa->rvType() != RV64, "RISC V CPU should run in 64 bits mode");
|
||||
MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
|
||||
fatal_if(!(misa.rvu && misa.rvs),
|
||||
"RISC V SE mode can't run without supervisor and user "
|
||||
"privilege modes.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,6 +124,10 @@ RiscvProcess32::initState()
|
||||
tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
|
||||
auto *isa = dynamic_cast<ISA*>(tc->getIsaPtr());
|
||||
fatal_if(isa->rvType() != RV32, "RISC V CPU should run in 32 bits mode");
|
||||
MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
|
||||
fatal_if(!(misa.rvu && misa.rvs),
|
||||
"RISC V SE mode can't run without supervisor and user "
|
||||
"privilege modes.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -167,13 +167,22 @@ getRvType(ThreadContext* tc)
|
||||
return isa->rvType();
|
||||
}
|
||||
|
||||
static PrivilegeModeSet
|
||||
getPrivilegeModeSet(ThreadContext* tc)
|
||||
{
|
||||
auto isa = dynamic_cast<ISA*>(tc->getIsaPtr());
|
||||
panic_if(!isa, "Cannot derive rv_type from non-riscv isa");
|
||||
return isa->getPrivilegeModeSet();
|
||||
}
|
||||
|
||||
template <typename xint>
|
||||
static void
|
||||
setRegNoEffectWithMask(
|
||||
ThreadContext *context, RiscvType type, CSRIndex idx, xint val)
|
||||
ThreadContext *context, RiscvType type, PrivilegeModeSet pms,
|
||||
CSRIndex idx, xint val)
|
||||
{
|
||||
RegVal oldVal, newVal;
|
||||
RegVal mask = CSRMasks[type].at(idx);
|
||||
RegVal mask = CSRMasks[type][pms].at(idx);
|
||||
oldVal = context->readMiscRegNoEffect(CSRData.at(idx).physIndex);
|
||||
newVal = (oldVal & ~mask) | (val & mask);
|
||||
context->setMiscRegNoEffect(CSRData.at(idx).physIndex, newVal);
|
||||
@@ -181,10 +190,12 @@ setRegNoEffectWithMask(
|
||||
|
||||
template <typename xint>
|
||||
static void
|
||||
setRegWithMask(ThreadContext *context, RiscvType type, CSRIndex idx, xint val)
|
||||
setRegWithMask(
|
||||
ThreadContext *context, RiscvType type, PrivilegeModeSet pms,
|
||||
CSRIndex idx, xint val)
|
||||
{
|
||||
RegVal oldVal, newVal;
|
||||
RegVal mask = CSRMasks[type].at(idx);
|
||||
RegVal mask = CSRMasks[type][pms].at(idx);
|
||||
oldVal = context->readMiscReg(CSRData.at(idx).physIndex);
|
||||
newVal = (oldVal & ~mask) | (val & mask);
|
||||
context->setMiscReg(CSRData.at(idx).physIndex, newVal);
|
||||
@@ -207,7 +218,8 @@ RemoteGDB::acc(Addr va, size_t len)
|
||||
|
||||
PrivilegeMode pmode = mmu->getMemPriv(context(), BaseMMU::Read);
|
||||
SATP satp = context()->readMiscReg(MISCREG_SATP);
|
||||
if (pmode != PrivilegeMode::PRV_M &&
|
||||
MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
|
||||
if (misa.rvs && pmode != PrivilegeMode::PRV_M &&
|
||||
satp.mode != AddrXlateMode::BARE) {
|
||||
Walker *walker = mmu->getDataWalker();
|
||||
Fault fault = walker->startFunctional(
|
||||
@@ -225,7 +237,8 @@ void
|
||||
RemoteGDB::Riscv32GdbRegCache::getRegs(ThreadContext *context)
|
||||
{
|
||||
DPRINTF(GDBAcc, "getregs in remotegdb, size %lu\n", size());
|
||||
auto& RVxCSRMasks = CSRMasks[RV32];
|
||||
PrivilegeModeSet pms = getPrivilegeModeSet(context);
|
||||
auto& RVxCSRMasks = CSRMasks[RV32][pms];
|
||||
|
||||
// General registers
|
||||
for (int i = 0; i < int_reg::NumArchRegs; i++) {
|
||||
@@ -339,6 +352,7 @@ void
|
||||
RemoteGDB::Riscv32GdbRegCache::setRegs(ThreadContext *context) const
|
||||
{
|
||||
DPRINTF(GDBAcc, "setregs in remotegdb \n");
|
||||
PrivilegeModeSet pms = getPrivilegeModeSet(context);
|
||||
for (int i = 0; i < int_reg::NumArchRegs; i++)
|
||||
context->setReg(intRegClass[i], r.gpr[i]);
|
||||
context->pcState(r.pc);
|
||||
@@ -347,16 +361,16 @@ RemoteGDB::Riscv32GdbRegCache::setRegs(ThreadContext *context) const
|
||||
for (int i = 0; i < float_reg::NumRegs; i++)
|
||||
context->setReg(floatRegClass[i], r.fpu[i]);
|
||||
|
||||
setRegNoEffectWithMask(context, RV32, CSR_FFLAGS, r.fflags);
|
||||
setRegNoEffectWithMask(context, RV32, CSR_FRM, r.frm);
|
||||
setRegNoEffectWithMask(context, RV32, CSR_FCSR, r.fcsr);
|
||||
setRegNoEffectWithMask(context, RV32, pms, CSR_FFLAGS, r.fflags);
|
||||
setRegNoEffectWithMask(context, RV32, pms, CSR_FRM, r.frm);
|
||||
setRegNoEffectWithMask(context, RV32, pms, CSR_FCSR, r.fcsr);
|
||||
|
||||
// TODO: implement CSR counter registers for mcycle(h), minstret(h)
|
||||
|
||||
// U mode CSR
|
||||
setRegNoEffectWithMask(context, RV32, CSR_USTATUS, r.ustatus);
|
||||
setRegWithMask(context, RV32, CSR_UIE, r.uie);
|
||||
setRegWithMask(context, RV32, CSR_UIP, r.uip);
|
||||
setRegNoEffectWithMask(context, RV32, pms, CSR_USTATUS, r.ustatus);
|
||||
setRegWithMask(context, RV32, pms, CSR_UIE, r.uie);
|
||||
setRegWithMask(context, RV32, pms, CSR_UIP, r.uip);
|
||||
context->setMiscRegNoEffect(
|
||||
CSRData.at(CSR_UTVEC).physIndex, r.utvec);
|
||||
context->setMiscRegNoEffect(
|
||||
@@ -369,9 +383,9 @@ RemoteGDB::Riscv32GdbRegCache::setRegs(ThreadContext *context) const
|
||||
CSRData.at(CSR_UTVAL).physIndex, r.utval);
|
||||
|
||||
// S mode CSR
|
||||
setRegNoEffectWithMask(context, RV32, CSR_SSTATUS, r.sstatus);
|
||||
setRegWithMask(context, RV32, CSR_SIE, r.sie);
|
||||
setRegWithMask(context, RV32, CSR_SIP, r.sip);
|
||||
setRegNoEffectWithMask(context, RV32, pms, CSR_SSTATUS, r.sstatus);
|
||||
setRegWithMask(context, RV32, pms, CSR_SIE, r.sie);
|
||||
setRegWithMask(context, RV32, pms, CSR_SIP, r.sip);
|
||||
context->setMiscRegNoEffect(
|
||||
CSRData.at(CSR_SEDELEG).physIndex, r.sedeleg);
|
||||
context->setMiscRegNoEffect(
|
||||
@@ -392,10 +406,10 @@ RemoteGDB::Riscv32GdbRegCache::setRegs(ThreadContext *context) const
|
||||
CSRData.at(CSR_SATP).physIndex, r.satp);
|
||||
|
||||
// M mode CSR
|
||||
setRegNoEffectWithMask(context, RV32, CSR_MSTATUS, r.mstatus);
|
||||
setRegNoEffectWithMask(context, RV32, CSR_MISA, r.misa);
|
||||
setRegWithMask(context, RV32, CSR_MIE, r.mie);
|
||||
setRegWithMask(context, RV32, CSR_MIP, r.mip);
|
||||
setRegNoEffectWithMask(context, RV32, pms, CSR_MSTATUS, r.mstatus);
|
||||
setRegNoEffectWithMask(context, RV32, pms, CSR_MISA, r.misa);
|
||||
setRegWithMask(context, RV32, pms, CSR_MIE, r.mie);
|
||||
setRegWithMask(context, RV32, pms, CSR_MIP, r.mip);
|
||||
context->setMiscRegNoEffect(
|
||||
CSRData.at(CSR_MEDELEG).physIndex, r.medeleg);
|
||||
context->setMiscRegNoEffect(
|
||||
@@ -420,7 +434,8 @@ void
|
||||
RemoteGDB::Riscv64GdbRegCache::getRegs(ThreadContext *context)
|
||||
{
|
||||
DPRINTF(GDBAcc, "getregs in remotegdb, size %lu\n", size());
|
||||
auto& RVxCSRMasks = CSRMasks[RV64];
|
||||
PrivilegeModeSet pms = getPrivilegeModeSet(context);
|
||||
auto& RVxCSRMasks = CSRMasks[RV64][pms];
|
||||
|
||||
// General registers
|
||||
for (int i = 0; i < int_reg::NumArchRegs; i++) {
|
||||
@@ -528,6 +543,7 @@ void
|
||||
RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const
|
||||
{
|
||||
DPRINTF(GDBAcc, "setregs in remotegdb \n");
|
||||
PrivilegeModeSet pms = getPrivilegeModeSet(context);
|
||||
for (int i = 0; i < int_reg::NumArchRegs; i++)
|
||||
context->setReg(intRegClass[i], r.gpr[i]);
|
||||
context->pcState(r.pc);
|
||||
@@ -536,16 +552,16 @@ RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const
|
||||
for (int i = 0; i < float_reg::NumRegs; i++)
|
||||
context->setReg(floatRegClass[i], r.fpu[i]);
|
||||
|
||||
setRegNoEffectWithMask(context, RV64, CSR_FFLAGS, r.fflags);
|
||||
setRegNoEffectWithMask(context, RV64, CSR_FRM, r.frm);
|
||||
setRegNoEffectWithMask(context, RV64, CSR_FCSR, r.fcsr);
|
||||
setRegNoEffectWithMask(context, RV64, pms, CSR_FFLAGS, r.fflags);
|
||||
setRegNoEffectWithMask(context, RV64, pms, CSR_FRM, r.frm);
|
||||
setRegNoEffectWithMask(context, RV64, pms, CSR_FCSR, r.fcsr);
|
||||
|
||||
// TODO: implement CSR counter registers for mcycle, minstret
|
||||
|
||||
// U mode CSR
|
||||
setRegNoEffectWithMask(context, RV64, CSR_USTATUS, r.ustatus);
|
||||
setRegWithMask(context, RV64, CSR_UIE, r.uie);
|
||||
setRegWithMask(context, RV64, CSR_UIP, r.uip);
|
||||
setRegNoEffectWithMask(context, RV64, pms, CSR_USTATUS, r.ustatus);
|
||||
setRegWithMask(context, RV64, pms, CSR_UIE, r.uie);
|
||||
setRegWithMask(context, RV64, pms, CSR_UIP, r.uip);
|
||||
context->setMiscRegNoEffect(
|
||||
CSRData.at(CSR_UTVEC).physIndex, r.utvec);
|
||||
context->setMiscRegNoEffect(
|
||||
@@ -558,9 +574,10 @@ RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const
|
||||
CSRData.at(CSR_UTVAL).physIndex, r.utval);
|
||||
|
||||
// S mode CSR
|
||||
setRegNoEffectWithMask(context, RV64, CSR_SSTATUS, r.sstatus);
|
||||
setRegWithMask(context, RV64, CSR_SIE, r.sie);
|
||||
setRegWithMask(context, RV64, CSR_SIP, r.sip);
|
||||
setRegNoEffectWithMask(
|
||||
context, RV64, pms, CSR_SSTATUS, r.sstatus);
|
||||
setRegWithMask(context, RV64, pms, CSR_SIE, r.sie);
|
||||
setRegWithMask(context, RV64, pms, CSR_SIP, r.sip);
|
||||
context->setMiscRegNoEffect(
|
||||
CSRData.at(CSR_SEDELEG).physIndex, r.sedeleg);
|
||||
context->setMiscRegNoEffect(
|
||||
@@ -581,10 +598,11 @@ RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const
|
||||
CSRData.at(CSR_SATP).physIndex, r.satp);
|
||||
|
||||
// M mode CSR
|
||||
setRegNoEffectWithMask(context, RV64, CSR_MSTATUS, r.mstatus);
|
||||
setRegNoEffectWithMask(context, RV64, CSR_MISA, r.misa);
|
||||
setRegWithMask(context, RV64, CSR_MIE, r.mie);
|
||||
setRegWithMask(context, RV64, CSR_MIP, r.mip);
|
||||
setRegNoEffectWithMask(
|
||||
context, RV64, pms, CSR_MSTATUS, r.mstatus);
|
||||
setRegNoEffectWithMask(context, RV64, pms, CSR_MISA, r.misa);
|
||||
setRegWithMask(context, RV64, pms, CSR_MIE, r.mie);
|
||||
setRegWithMask(context, RV64, pms, CSR_MIP, r.mip);
|
||||
context->setMiscRegNoEffect(
|
||||
CSRData.at(CSR_MEDELEG).physIndex, r.medeleg);
|
||||
context->setMiscRegNoEffect(
|
||||
|
||||
@@ -341,9 +341,12 @@ TLB::translate(const RequestPtr &req, ThreadContext *tc,
|
||||
|
||||
if (FullSystem) {
|
||||
PrivilegeMode pmode = getMemPriv(tc, mode);
|
||||
MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
|
||||
SATP satp = tc->readMiscReg(MISCREG_SATP);
|
||||
if (pmode == PrivilegeMode::PRV_M || satp.mode == AddrXlateMode::BARE)
|
||||
if (!misa.rvs || pmode == PrivilegeMode::PRV_M ||
|
||||
satp.mode == AddrXlateMode::BARE) {
|
||||
req->setFlags(Request::PHYSICAL);
|
||||
}
|
||||
|
||||
Fault fault;
|
||||
if (req->getFlags() & Request::PHYSICAL) {
|
||||
@@ -434,8 +437,9 @@ TLB::translateFunctional(const RequestPtr &req, ThreadContext *tc,
|
||||
MMU *mmu = static_cast<MMU *>(tc->getMMUPtr());
|
||||
|
||||
PrivilegeMode pmode = mmu->getMemPriv(tc, mode);
|
||||
MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
|
||||
SATP satp = tc->readMiscReg(MISCREG_SATP);
|
||||
if (pmode != PrivilegeMode::PRV_M &&
|
||||
if (misa.rvs && pmode != PrivilegeMode::PRV_M &&
|
||||
satp.mode != AddrXlateMode::BARE) {
|
||||
Walker *walker = mmu->getDataWalker();
|
||||
unsigned logBytes;
|
||||
|
||||
Reference in New Issue
Block a user