arch: Make the (read|set)MiscReg methods virtual.

They will then be accessible through the base class. This adds some
small hypothetical amount of overhead to each call, but a quick test
booting linux on x86 does not show any significant slowdown.

Change-Id: If706ddf173d4e24d85468fb118b45099acf3c05b
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/51237
Tested-by: kokoro <noreply+kokoro@google.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
This commit is contained in:
Gabe Black
2021-10-02 00:07:52 -07:00
parent b3365e767a
commit 5d00ba897f
20 changed files with 263 additions and 219 deletions

View File

@@ -42,6 +42,7 @@
#include "arch/arm/isa.hh"
#include "arch/arm/utility.hh"
#include "base/cast.hh"
#include "base/trace.hh"
#include "debug/Decoder.hh"
#include "sim/full_system.hh"
@@ -58,13 +59,13 @@ Decoder::Decoder(const ArmDecoderParams &params)
: InstDecoder(params, &data),
dvmEnabled(params.dvm_enabled),
data(0), fpscrLen(0), fpscrStride(0),
decoderFlavor(dynamic_cast<ISA *>(params.isa)->decoderFlavor())
decoderFlavor(safe_cast<ISA *>(params.isa)->decoderFlavor())
{
reset();
// Initialize SVE vector length
sveLen = (dynamic_cast<ISA *>(params.isa)
->getCurSveVecLenInBitsAtReset() >> 7) - 1;
sveLen = (safe_cast<ISA *>(params.isa)->
getCurSveVecLenInBitsAtReset() >> 7) - 1;
if (dvmEnabled) {
warn_once(

View File

@@ -56,10 +56,11 @@
namespace gem5
{
class BaseISA;
namespace ArmISA
{
class ISA;
class Decoder : public InstDecoder
{
public: // Public decoder parameters

View File

@@ -58,6 +58,30 @@ class ISA : public BaseISA
{
return new ArmISA::PCState(new_inst_addr);
}
RegVal
readMiscRegNoEffect(RegIndex idx) const override
{
panic("readMiscRegNoEffect not implemented.");
}
RegVal
readMiscReg(RegIndex idx) override
{
panic("readMiscReg not implemented.");
}
void
setMiscRegNoEffect(RegIndex idx, RegVal val) override
{
panic("setMiscRegNoEffect not implemented.");
}
void
setMiscReg(RegIndex idx, RegVal val) override
{
panic("setMiscReg not implemented.");
}
};
} // namespace Iris

View File

@@ -728,12 +728,12 @@ ISA::redirectRegVHE(int misc_reg)
}
RegVal
ISA::readMiscRegNoEffect(int misc_reg) const
ISA::readMiscRegNoEffect(RegIndex idx) const
{
assert(misc_reg < NUM_MISCREGS);
assert(idx < NUM_MISCREGS);
const auto &reg = lookUpMiscReg[misc_reg]; // bit masks
const auto &map = getMiscIndices(misc_reg);
const auto &reg = lookUpMiscReg[idx]; // bit masks
const auto &map = getMiscIndices(idx);
int lower = map.first, upper = map.second;
// NB!: apply architectural masks according to desired register,
// despite possibly getting value from different (mapped) register.
@@ -741,24 +741,24 @@ ISA::readMiscRegNoEffect(int misc_reg) const
|(miscRegs[upper] << 32));
if (val & reg.res0()) {
DPRINTF(MiscRegs, "Reading MiscReg %s with set res0 bits: %#x\n",
miscRegName[misc_reg], val & reg.res0());
miscRegName[idx], val & reg.res0());
}
if ((val & reg.res1()) != reg.res1()) {
DPRINTF(MiscRegs, "Reading MiscReg %s with clear res1 bits: %#x\n",
miscRegName[misc_reg], (val & reg.res1()) ^ reg.res1());
miscRegName[idx], (val & reg.res1()) ^ reg.res1());
}
return (val & ~reg.raz()) | reg.rao(); // enforce raz/rao
}
RegVal
ISA::readMiscReg(int misc_reg)
ISA::readMiscReg(RegIndex idx)
{
CPSR cpsr = 0;
SCR scr = 0;
if (misc_reg == MISCREG_CPSR) {
cpsr = miscRegs[misc_reg];
if (idx == MISCREG_CPSR) {
cpsr = miscRegs[idx];
auto pc = tc->pcState().as<PCState>();
cpsr.j = pc.jazelle() ? 1 : 0;
cpsr.t = pc.thumb() ? 1 : 0;
@@ -766,19 +766,19 @@ ISA::readMiscReg(int misc_reg)
}
#ifndef NDEBUG
auto& miscreg_info = lookUpMiscReg[misc_reg].info;
auto& miscreg_info = lookUpMiscReg[idx].info;
if (!miscreg_info[MISCREG_IMPLEMENTED]) {
if (miscreg_info[MISCREG_WARN_NOT_FAIL])
warn("Unimplemented system register %s read.\n",
miscRegName[misc_reg]);
miscRegName[idx]);
else
panic("Unimplemented system register %s read.\n",
miscRegName[misc_reg]);
miscRegName[idx]);
}
#endif
misc_reg = redirectRegVHE(misc_reg);
idx = redirectRegVHE(idx);
switch (unflattenMiscReg(misc_reg)) {
switch (unflattenMiscReg(idx)) {
case MISCREG_HCR:
case MISCREG_HCR2:
if (!release->has(ArmExtension::VIRTUALIZATION))
@@ -808,7 +808,7 @@ ISA::readMiscReg(int misc_reg)
RegVal val = readMiscRegNoEffect(MISCREG_CPACR);
val &= cpacrMask;
DPRINTF(MiscRegs, "Reading misc reg %s: %#x\n",
miscRegName[misc_reg], val);
miscRegName[idx], val);
return val;
}
case MISCREG_MPIDR:
@@ -817,14 +817,14 @@ ISA::readMiscReg(int misc_reg)
case MISCREG_VMPIDR:
case MISCREG_VMPIDR_EL2:
// top bit defined as RES1
return readMiscRegNoEffect(misc_reg) | 0x80000000;
return readMiscRegNoEffect(idx) | 0x80000000;
case MISCREG_ID_AFR0: // not implemented, so alias MIDR
case MISCREG_REVIDR: // not implemented, so alias MIDR
case MISCREG_MIDR:
cpsr = readMiscRegNoEffect(MISCREG_CPSR);
scr = readMiscRegNoEffect(MISCREG_SCR);
if ((cpsr.mode == MODE_HYP) || isSecure(tc)) {
return readMiscRegNoEffect(misc_reg);
return readMiscRegNoEffect(idx);
} else {
return readMiscRegNoEffect(MISCREG_VPIDR);
}
@@ -882,7 +882,7 @@ ISA::readMiscReg(int misc_reg)
case MISCREG_PMINTENSET_EL1 ... MISCREG_PMOVSSET_EL0:
case MISCREG_PMEVCNTR0_EL0 ... MISCREG_PMEVTYPER5_EL0:
case MISCREG_PMCR ... MISCREG_PMOVSSET:
return pmu->readMiscReg(misc_reg);
return pmu->readMiscReg(idx);
case MISCREG_CPSR_Q:
panic("shouldn't be reading this register seperately\n");
@@ -999,7 +999,7 @@ ISA::readMiscReg(int misc_reg)
return 0x04; // DC ZVA clear 64-byte chunks
case MISCREG_HCPTR:
{
RegVal val = readMiscRegNoEffect(misc_reg);
RegVal val = readMiscRegNoEffect(idx);
// The trap bit associated with CP14 is defined as RAZ
val &= ~(1 << 14);
// If a CP bit in NSACR is 0 then the corresponding bit in
@@ -1050,27 +1050,27 @@ ISA::readMiscReg(int misc_reg)
// Generic Timer registers
case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
return getGenericTimer().readMiscReg(misc_reg);
return getGenericTimer().readMiscReg(idx);
case MISCREG_ICC_AP0R0 ... MISCREG_ICH_LRC15:
case MISCREG_ICC_PMR_EL1 ... MISCREG_ICC_IGRPEN1_EL3:
case MISCREG_ICH_AP0R0_EL2 ... MISCREG_ICH_LR15_EL2:
return getGICv3CPUInterface().readMiscReg(misc_reg);
return getGICv3CPUInterface().readMiscReg(idx);
default:
break;
}
return readMiscRegNoEffect(misc_reg);
return readMiscRegNoEffect(idx);
}
void
ISA::setMiscRegNoEffect(int misc_reg, RegVal val)
ISA::setMiscRegNoEffect(RegIndex idx, RegVal val)
{
assert(misc_reg < NUM_MISCREGS);
assert(idx < NUM_MISCREGS);
const auto &reg = lookUpMiscReg[misc_reg]; // bit masks
const auto &map = getMiscIndices(misc_reg);
const auto &reg = lookUpMiscReg[idx]; // bit masks
const auto &map = getMiscIndices(idx);
int lower = map.first, upper = map.second;
auto v = (val & ~reg.wi()) | reg.rao();
@@ -1078,23 +1078,23 @@ ISA::setMiscRegNoEffect(int misc_reg, RegVal val)
miscRegs[lower] = bits(v, 31, 0);
miscRegs[upper] = bits(v, 63, 32);
DPRINTF(MiscRegs, "Writing MiscReg %s (%d %d:%d) : %#x\n",
miscRegName[misc_reg], misc_reg, lower, upper, v);
miscRegName[idx], idx, lower, upper, v);
} else {
miscRegs[lower] = v;
DPRINTF(MiscRegs, "Writing MiscReg %s (%d %d) : %#x\n",
miscRegName[misc_reg], misc_reg, lower, v);
miscRegName[idx], idx, lower, v);
}
}
void
ISA::setMiscReg(int misc_reg, RegVal val)
ISA::setMiscReg(RegIndex idx, RegVal val)
{
RegVal newVal = val;
bool secure_lookup;
SCR scr;
if (misc_reg == MISCREG_CPSR) {
if (idx == MISCREG_CPSR) {
updateRegMap(val);
@@ -1106,7 +1106,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
}
DPRINTF(Arm, "Updating CPSR from %#x to %#x f:%d i:%d a:%d mode:%#x\n",
miscRegs[misc_reg], cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
miscRegs[idx], cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
PCState pc = tc->pcState().as<PCState>();
pc.nextThumb(cpsr.t);
pc.nextJazelle(cpsr.j);
@@ -1125,7 +1125,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
tc->pcState(pc);
}
setMiscRegNoEffect(misc_reg, newVal);
setMiscRegNoEffect(idx, newVal);
if (old_mode != cpsr.mode) {
getMMUPtr(tc)->invalidateMiscReg();
@@ -1144,19 +1144,19 @@ ISA::setMiscReg(int misc_reg, RegVal val)
}
} else {
#ifndef NDEBUG
auto& miscreg_info = lookUpMiscReg[misc_reg].info;
auto& miscreg_info = lookUpMiscReg[idx].info;
if (!miscreg_info[MISCREG_IMPLEMENTED]) {
if (miscreg_info[MISCREG_WARN_NOT_FAIL])
warn("Unimplemented system register %s write with %#x.\n",
miscRegName[misc_reg], val);
miscRegName[idx], val);
else
panic("Unimplemented system register %s write with %#x.\n",
miscRegName[misc_reg], val);
miscRegName[idx], val);
}
#endif
misc_reg = redirectRegVHE(misc_reg);
idx = redirectRegVHE(idx);
switch (unflattenMiscReg(misc_reg)) {
switch (unflattenMiscReg(idx)) {
case MISCREG_CPACR:
{
@@ -1184,7 +1184,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
newVal &= cpacrMask;
newVal |= old_val & ~cpacrMask;
DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
miscRegName[misc_reg], newVal);
miscRegName[idx], newVal);
}
break;
case MISCREG_CPACR_EL1:
@@ -1198,7 +1198,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
}
newVal &= cpacrMask;
DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
miscRegName[misc_reg], newVal);
miscRegName[idx], newVal);
}
break;
case MISCREG_CPTR_EL2:
@@ -1224,7 +1224,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
cptrMask.res1_9_el2 = ones;
newVal |= cptrMask;
DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
miscRegName[misc_reg], newVal);
miscRegName[idx], newVal);
}
break;
case MISCREG_CPTR_EL3:
@@ -1239,7 +1239,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
}
newVal &= cptrMask;
DPRINTF(MiscRegs, "Writing misc reg %s: %#x\n",
miscRegName[misc_reg], newVal);
miscRegName[idx], newVal);
}
break;
case MISCREG_CSSELR:
@@ -1302,7 +1302,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
newVal = (newVal & (uint32_t)fpscrMask) |
(readMiscRegNoEffect(MISCREG_FPSCR) &
~(uint32_t)fpscrMask);
misc_reg = MISCREG_FPSCR;
idx = MISCREG_FPSCR;
}
break;
case MISCREG_FPCR:
@@ -1319,28 +1319,28 @@ ISA::setMiscReg(int misc_reg, RegVal val)
newVal = (newVal & (uint32_t)fpscrMask) |
(readMiscRegNoEffect(MISCREG_FPSCR) &
~(uint32_t)fpscrMask);
misc_reg = MISCREG_FPSCR;
idx = MISCREG_FPSCR;
}
break;
case MISCREG_CPSR_Q:
{
assert(!(newVal & ~CpsrMaskQ));
newVal = readMiscRegNoEffect(MISCREG_CPSR) | newVal;
misc_reg = MISCREG_CPSR;
idx = MISCREG_CPSR;
}
break;
case MISCREG_FPSCR_QC:
{
newVal = readMiscRegNoEffect(MISCREG_FPSCR) |
(newVal & FpscrQcMask);
misc_reg = MISCREG_FPSCR;
idx = MISCREG_FPSCR;
}
break;
case MISCREG_FPSCR_EXC:
{
newVal = readMiscRegNoEffect(MISCREG_FPSCR) |
(newVal & FpscrExcMask);
misc_reg = MISCREG_FPSCR;
idx = MISCREG_FPSCR;
}
break;
case MISCREG_FPEXC:
@@ -1707,7 +1707,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
case MISCREG_PMINTENSET_EL1 ... MISCREG_PMOVSSET_EL0:
case MISCREG_PMEVCNTR0_EL0 ... MISCREG_PMEVTYPER5_EL0:
case MISCREG_PMCR ... MISCREG_PMOVSSET:
pmu->setMiscReg(misc_reg, newVal);
pmu->setMiscReg(idx, newVal);
break;
@@ -1733,10 +1733,10 @@ ISA::setMiscReg(int misc_reg, RegVal val)
break;
}
case MISCREG_HDFAR: // alias for secure DFAR
misc_reg = MISCREG_DFAR_S;
idx = MISCREG_DFAR_S;
break;
case MISCREG_HIFAR: // alias for secure IFAR
misc_reg = MISCREG_IFAR_S;
idx = MISCREG_IFAR_S;
break;
case MISCREG_ATS1CPR:
addressTranslation(MMU::S1CTran, BaseMMU::Read, 0, val);
@@ -1875,7 +1875,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
CPSR cpsr = miscRegs[MISCREG_CPSR];
cpsr.daif = (uint8_t) ((CPSR) newVal).daif;
newVal = cpsr;
misc_reg = MISCREG_CPSR;
idx = MISCREG_CPSR;
}
break;
case MISCREG_SP_EL0:
@@ -1892,7 +1892,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
CPSR cpsr = miscRegs[MISCREG_CPSR];
cpsr.sp = (uint8_t) ((CPSR) newVal).sp;
newVal = cpsr;
misc_reg = MISCREG_CPSR;
idx = MISCREG_CPSR;
}
break;
case MISCREG_CURRENTEL:
@@ -1900,7 +1900,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
CPSR cpsr = miscRegs[MISCREG_CPSR];
cpsr.el = (uint8_t) ((CPSR) newVal).el;
newVal = cpsr;
misc_reg = MISCREG_CPSR;
idx = MISCREG_CPSR;
}
break;
case MISCREG_PAN:
@@ -1911,7 +1911,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
CPSR cpsr = miscRegs[MISCREG_CPSR];
cpsr.pan = (uint8_t) ((CPSR) newVal).pan;
newVal = cpsr;
misc_reg = MISCREG_CPSR;
idx = MISCREG_CPSR;
}
break;
case MISCREG_UAO:
@@ -1922,7 +1922,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
CPSR cpsr = miscRegs[MISCREG_CPSR];
cpsr.uao = (uint8_t) ((CPSR) newVal).uao;
newVal = cpsr;
misc_reg = MISCREG_CPSR;
idx = MISCREG_CPSR;
}
break;
case MISCREG_AT_S1E1R_Xt:
@@ -1967,18 +1967,18 @@ ISA::setMiscReg(int misc_reg, RegVal val)
return;
case MISCREG_L2CTLR:
warn("miscreg L2CTLR (%s) written with %#x. ignored...\n",
miscRegName[misc_reg], uint32_t(val));
miscRegName[idx], uint32_t(val));
break;
// Generic Timer registers
case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
getGenericTimer().setMiscReg(misc_reg, newVal);
getGenericTimer().setMiscReg(idx, newVal);
break;
case MISCREG_ICC_AP0R0 ... MISCREG_ICH_LRC15:
case MISCREG_ICC_PMR_EL1 ... MISCREG_ICC_IGRPEN1_EL3:
case MISCREG_ICH_AP0R0_EL2 ... MISCREG_ICH_LR15_EL2:
getGICv3CPUInterface().setMiscReg(misc_reg, newVal);
getGICv3CPUInterface().setMiscReg(idx, newVal);
return;
case MISCREG_ZCR_EL3:
case MISCREG_ZCR_EL2:
@@ -1987,7 +1987,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
(getCurSveVecLenInBits() >> 7) - 1);
break;
}
setMiscRegNoEffect(misc_reg, newVal);
setMiscRegNoEffect(idx, newVal);
}
}

View File

@@ -193,10 +193,10 @@ namespace ArmISA
const ArmRelease* getRelease() const { return release; }
RegVal readMiscRegNoEffect(int misc_reg) const;
RegVal readMiscReg(int misc_reg);
void setMiscRegNoEffect(int misc_reg, RegVal val);
void setMiscReg(int misc_reg, RegVal val);
RegVal readMiscRegNoEffect(RegIndex idx) const override;
RegVal readMiscReg(RegIndex idx) override;
void setMiscRegNoEffect(RegIndex idx, RegVal val) override;
void setMiscReg(RegIndex, RegVal val) override;
int
flattenMiscIndex(int reg) const

View File

@@ -70,6 +70,12 @@ class BaseISA : public SimObject
virtual PCStateBase *newPCState(Addr new_inst_addr=0) const = 0;
virtual void clear() {}
virtual RegVal readMiscRegNoEffect(RegIndex idx) const = 0;
virtual RegVal readMiscReg(RegIndex idx) = 0;
virtual void setMiscRegNoEffect(RegIndex idx, RegVal val) = 0;
virtual void setMiscReg(RegIndex idx, RegVal val) = 0;
virtual void takeOverFrom(ThreadContext *new_tc, ThreadContext *old_tc) {}
virtual void setThreadContext(ThreadContext *_tc) { tc = _tc; }

View File

@@ -41,10 +41,11 @@
namespace gem5
{
class BaseISA;
namespace MipsISA
{
class ISA;
class Decoder : public InstDecoder
{
protected:

View File

@@ -458,54 +458,52 @@ ISA::getVPENum(ThreadID tid) const
}
RegVal
ISA::readMiscRegNoEffect(int misc_reg, ThreadID tid) const
ISA::readMiscRegNoEffect(RegIndex idx, ThreadID tid) const
{
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
unsigned reg_sel = (bankType[idx] == perThreadContext)
? tid : getVPENum(tid);
DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n",
misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg],
miscRegFile[misc_reg][reg_sel]);
return miscRegFile[misc_reg][reg_sel];
idx / 8, idx % 8, miscRegNames[idx], miscRegFile[idx][reg_sel]);
return miscRegFile[idx][reg_sel];
}
//@TODO: MIPS MT's register view automatically connects
// Status to TCStatus depending on current thread
//template <class TC>
RegVal
ISA::readMiscReg(int misc_reg, ThreadID tid)
ISA::readMiscReg(RegIndex idx, ThreadID tid)
{
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
unsigned reg_sel = (bankType[idx] == perThreadContext)
? tid : getVPENum(tid);
DPRINTF(MipsPRA,
"Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n",
misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg],
miscRegFile[misc_reg][reg_sel]);
idx / 8, idx % 8, miscRegNames[idx], miscRegFile[idx][reg_sel]);
return miscRegFile[misc_reg][reg_sel];
return miscRegFile[idx][reg_sel];
}
void
ISA::setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid)
ISA::setMiscRegNoEffect(RegIndex idx, RegVal val, ThreadID tid)
{
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
unsigned reg_sel = (bankType[idx] == perThreadContext)
? tid : getVPENum(tid);
DPRINTF(MipsPRA,
"[tid:%i] Setting (direct set) CP0 Register:%u "
"Select:%u (%s) to %#x.\n",
tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val);
tid, idx / 8, idx % 8, miscRegNames[idx], val);
miscRegFile[misc_reg][reg_sel] = val;
miscRegFile[idx][reg_sel] = val;
}
void
ISA::setRegMask(int misc_reg, RegVal val, ThreadID tid)
ISA::setRegMask(RegIndex idx, RegVal val, ThreadID tid)
{
unsigned reg_sel = (bankType[misc_reg] == perThreadContext)
unsigned reg_sel = (bankType[idx] == perThreadContext)
? tid : getVPENum(tid);
DPRINTF(MipsPRA,
"[tid:%i] Setting CP0 Register: %u Select: %u (%s) to %#x\n",
tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val);
miscRegFile_WriteMask[misc_reg][reg_sel] = val;
tid, idx / 8, idx % 8, miscRegNames[idx], val);
miscRegFile_WriteMask[idx][reg_sel] = val;
}
// PROGRAMMER'S NOTES:
@@ -513,19 +511,19 @@ ISA::setRegMask(int misc_reg, RegVal val, ThreadID tid)
// be overwritten. Make sure to handle those particular registers
// with care!
void
ISA::setMiscReg(int misc_reg, RegVal val, ThreadID tid)
ISA::setMiscReg(RegIndex idx, RegVal val, ThreadID tid)
{
int reg_sel = (bankType[misc_reg] == perThreadContext)
int reg_sel = (bankType[idx] == perThreadContext)
? tid : getVPENum(tid);
DPRINTF(MipsPRA,
"[tid:%i] Setting CP0 Register:%u "
"Select:%u (%s) to %#x, with effect.\n",
tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val);
tid, idx / 8, idx % 8, miscRegNames[idx], val);
RegVal cp0_val = filterCP0Write(misc_reg, reg_sel, val);
RegVal cp0_val = filterCP0Write(idx, reg_sel, val);
miscRegFile[misc_reg][reg_sel] = cp0_val;
miscRegFile[idx][reg_sel] = cp0_val;
scheduleCP0Update(tc->getCpuPtr(), Cycles(1));
}
@@ -536,22 +534,22 @@ ISA::setMiscReg(int misc_reg, RegVal val, ThreadID tid)
* (setRegWithEffect)
*/
RegVal
ISA::filterCP0Write(int misc_reg, int reg_sel, RegVal val)
ISA::filterCP0Write(RegIndex idx, int reg_sel, RegVal val)
{
RegVal retVal = val;
// Mask off read-only regions
retVal &= miscRegFile_WriteMask[misc_reg][reg_sel];
RegVal curVal = miscRegFile[misc_reg][reg_sel];
retVal &= miscRegFile_WriteMask[idx][reg_sel];
RegVal curVal = miscRegFile[idx][reg_sel];
// Mask off current alue with inverse mask (clear writeable bits)
curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]);
curVal &= (~miscRegFile_WriteMask[idx][reg_sel]);
retVal |= curVal; // Combine the two
DPRINTF(MipsPRA,
"filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, "
"current val: %lx, written val: %x\n",
miscRegFile_WriteMask[misc_reg][reg_sel],
~miscRegFile_WriteMask[misc_reg][reg_sel],
val, miscRegFile[misc_reg][reg_sel], retVal);
miscRegFile_WriteMask[idx][reg_sel],
~miscRegFile_WriteMask[idx][reg_sel],
val, miscRegFile[idx][reg_sel], retVal);
return retVal;
}

View File

@@ -98,18 +98,37 @@ namespace MipsISA
//////////////////////////////////////////////////////////
//@TODO: MIPS MT's register view automatically connects
// Status to TCStatus depending on current thread
void updateCP0ReadView(int misc_reg, ThreadID tid) { }
RegVal readMiscRegNoEffect(int misc_reg, ThreadID tid = 0) const;
void updateCP0ReadView(RegIndex idx, ThreadID tid) { }
RegVal readMiscRegNoEffect(RegIndex idx, ThreadID tid) const;
RegVal
readMiscRegNoEffect(RegIndex idx) const override
{
return readMiscRegNoEffect(idx, 0);
}
//template <class TC>
RegVal readMiscReg(int misc_reg, ThreadID tid = 0);
RegVal readMiscReg(RegIndex idx, ThreadID tid);
RegVal
readMiscReg(RegIndex idx) override
{
return readMiscReg(idx, 0);
}
RegVal filterCP0Write(int misc_reg, int reg_sel, RegVal val);
void setRegMask(int misc_reg, RegVal val, ThreadID tid = 0);
void setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid=0);
RegVal filterCP0Write(RegIndex idx, int reg_sel, RegVal val);
void setRegMask(RegIndex idx, RegVal val, ThreadID tid = 0);
//template <class TC>
void setMiscReg(int misc_reg, RegVal val, ThreadID tid=0);
void setMiscRegNoEffect(RegIndex idx, RegVal val, ThreadID tid);
void
setMiscRegNoEffect(RegIndex idx, RegVal val) override
{
setMiscRegNoEffect(idx, val, 0);
}
void setMiscReg(RegIndex idx, RegVal val, ThreadID tid);
void
setMiscReg(RegIndex idx, RegVal val) override
{
setMiscReg(idx, val, 0);
}
//////////////////////////////////////////////////////////
//

View File

@@ -40,10 +40,11 @@
namespace gem5
{
class BaseISA;
namespace PowerISA
{
class ISA;
class Decoder : public InstDecoder
{
protected:

View File

@@ -53,7 +53,6 @@ namespace PowerISA
class ISA : public BaseISA
{
protected:
RegVal dummy;
RegVal miscRegs[NUM_MISCREGS];
public:
@@ -64,27 +63,25 @@ class ISA : public BaseISA
}
RegVal
readMiscRegNoEffect(int misc_reg) const
readMiscRegNoEffect(RegIndex idx) const override
{
fatal("Power does not currently have any misc regs defined\n");
return dummy;
}
RegVal
readMiscReg(int misc_reg)
{
fatal("Power does not currently have any misc regs defined\n");
return dummy;
}
void
setMiscRegNoEffect(int misc_reg, RegVal val)
readMiscReg(RegIndex idx) override
{
fatal("Power does not currently have any misc regs defined\n");
}
void
setMiscReg(int misc_reg, RegVal val)
setMiscRegNoEffect(RegIndex idx, RegVal val) override
{
fatal("Power does not currently have any misc regs defined\n");
}
void
setMiscReg(RegIndex idx, RegVal val) override
{
fatal("Power does not currently have any misc regs defined\n");
}

View File

@@ -42,10 +42,11 @@
namespace gem5
{
class BaseISA;
namespace RiscvISA
{
class ISA;
class Decoder : public InstDecoder
{
private:

View File

@@ -281,22 +281,19 @@ ISA::hpmCounterEnabled(int misc_reg) const
}
RegVal
ISA::readMiscRegNoEffect(int misc_reg) const
ISA::readMiscRegNoEffect(RegIndex idx) const
{
if (misc_reg > NUM_MISCREGS || misc_reg < 0) {
// Illegal CSR
panic("Illegal CSR index %#x\n", misc_reg);
return -1;
}
// Illegal CSR
panic_if(idx > NUM_MISCREGS, "Illegal CSR index %#x\n", idx);
DPRINTF(RiscvMisc, "Reading MiscReg %s (%d): %#x.\n",
MiscRegNames[misc_reg], misc_reg, miscRegFile[misc_reg]);
return miscRegFile[misc_reg];
MiscRegNames[idx], idx, miscRegFile[idx]);
return miscRegFile[idx];
}
RegVal
ISA::readMiscReg(int misc_reg)
ISA::readMiscReg(RegIndex idx)
{
switch (misc_reg) {
switch (idx) {
case MISCREG_HARTID:
return tc->contextId();
case MISCREG_CYCLE:
@@ -342,7 +339,7 @@ ISA::readMiscReg(int misc_reg)
case MISCREG_MEPC:
{
auto misa = readMiscRegNoEffect(MISCREG_ISA);
auto val = readMiscRegNoEffect(misc_reg);
auto val = readMiscRegNoEffect(idx);
// if compressed instructions are disabled, epc[1] is set to 0
if ((misa & ISA_EXT_C_MASK) == 0)
return mbits(val, 63, 2);
@@ -353,41 +350,39 @@ ISA::readMiscReg(int misc_reg)
default:
// Try reading HPM counters
// As a placeholder, all HPM counters are just cycle counters
if (misc_reg >= MISCREG_HPMCOUNTER03 &&
misc_reg <= MISCREG_HPMCOUNTER31) {
if (hpmCounterEnabled(misc_reg)) {
if (idx >= MISCREG_HPMCOUNTER03 &&
idx <= MISCREG_HPMCOUNTER31) {
if (hpmCounterEnabled(idx)) {
DPRINTF(RiscvMisc, "HPM counter %d: %llu.\n",
misc_reg - MISCREG_CYCLE, tc->getCpuPtr()->curCycle());
idx - MISCREG_CYCLE, tc->getCpuPtr()->curCycle());
return tc->getCpuPtr()->curCycle();
} else {
warn("HPM counter %d disabled.\n", misc_reg - MISCREG_CYCLE);
warn("HPM counter %d disabled.\n", idx - MISCREG_CYCLE);
return 0;
}
}
return readMiscRegNoEffect(misc_reg);
return readMiscRegNoEffect(idx);
}
}
void
ISA::setMiscRegNoEffect(int misc_reg, RegVal val)
ISA::setMiscRegNoEffect(RegIndex idx, RegVal val)
{
if (misc_reg > NUM_MISCREGS || misc_reg < 0) {
// Illegal CSR
panic("Illegal CSR index %#x\n", misc_reg);
}
// Illegal CSR
panic_if(idx > NUM_MISCREGS, "Illegal CSR index %#x\n", idx);
DPRINTF(RiscvMisc, "Setting MiscReg %s (%d) to %#x.\n",
MiscRegNames[misc_reg], misc_reg, val);
miscRegFile[misc_reg] = val;
MiscRegNames[idx], idx, val);
miscRegFile[idx] = val;
}
void
ISA::setMiscReg(int misc_reg, RegVal val)
ISA::setMiscReg(RegIndex idx, RegVal val)
{
if (misc_reg >= MISCREG_CYCLE && misc_reg <= MISCREG_HPMCOUNTER31) {
if (idx >= MISCREG_CYCLE && idx <= MISCREG_HPMCOUNTER31) {
// Ignore writes to HPM counters for now
warn("Ignoring write to %s.\n", CSRData.at(misc_reg).name);
warn("Ignoring write to %s.\n", CSRData.at(idx).name);
} else {
switch (misc_reg) {
switch (idx) {
// From section 3.7.1 of RISCV priv. specs
// V1.12, the odd-numbered configuration
@@ -416,13 +411,13 @@ ISA::setMiscReg(int misc_reg, RegVal val)
// Form pmp_index using the index i and
// PMPCFG register number
// Note: MISCREG_PMPCFG2 - MISCREG_PMPCFG0 = 1
// 8*(misc_reg-MISCREG_PMPCFG0) will be useful
// 8*(idx-MISCREG_PMPCFG0) will be useful
// if a system contains more than 16 PMP entries
uint32_t pmp_index = i+(8*(misc_reg-MISCREG_PMPCFG0));
uint32_t pmp_index = i+(8*(idx-MISCREG_PMPCFG0));
mmu->getPMP()->pmpUpdateCfg(pmp_index,cfg_val);
}
setMiscRegNoEffect(misc_reg, val);
setMiscRegNoEffect(idx, val);
}
break;
case MISCREG_PMPADDR00 ... MISCREG_PMPADDR15:
@@ -432,10 +427,10 @@ ISA::setMiscReg(int misc_reg, RegVal val)
auto mmu = dynamic_cast<RiscvISA::MMU *>
(tc->getMMUPtr());
uint32_t pmp_index = misc_reg-MISCREG_PMPADDR00;
uint32_t pmp_index = idx-MISCREG_PMPADDR00;
mmu->getPMP()->pmpUpdateAddr(pmp_index, val);
setMiscRegNoEffect(misc_reg, val);
setMiscRegNoEffect(idx, val);
}
break;
@@ -457,24 +452,24 @@ ISA::setMiscReg(int misc_reg, RegVal val)
{
// we only support bare and Sv39 mode; setting a different mode
// shall have no effect (see 4.1.12 in priv ISA manual)
SATP cur_val = readMiscRegNoEffect(misc_reg);
SATP cur_val = readMiscRegNoEffect(idx);
SATP new_val = val;
if (new_val.mode != AddrXlateMode::BARE &&
new_val.mode != AddrXlateMode::SV39)
new_val.mode = cur_val.mode;
setMiscRegNoEffect(misc_reg, new_val);
setMiscRegNoEffect(idx, new_val);
}
break;
case MISCREG_TSELECT:
{
// we don't support debugging, so always set a different value
// than written
setMiscRegNoEffect(misc_reg, val + 1);
setMiscRegNoEffect(idx, val + 1);
}
break;
case MISCREG_ISA:
{
auto cur_val = readMiscRegNoEffect(misc_reg);
auto cur_val = readMiscRegNoEffect(idx);
// only allow to disable compressed instructions
// if the following instruction is 4-byte aligned
if ((val & ISA_EXT_C_MASK) == 0 &&
@@ -482,20 +477,20 @@ ISA::setMiscReg(int misc_reg, RegVal val)
2, 0) != 0) {
val |= cur_val & ISA_EXT_C_MASK;
}
setMiscRegNoEffect(misc_reg, val);
setMiscRegNoEffect(idx, val);
}
break;
case MISCREG_STATUS:
{
// SXL and UXL are hard-wired to 64 bit
auto cur = readMiscRegNoEffect(misc_reg);
auto cur = readMiscRegNoEffect(idx);
val &= ~(STATUS_SXL_MASK | STATUS_UXL_MASK);
val |= cur & (STATUS_SXL_MASK | STATUS_UXL_MASK);
setMiscRegNoEffect(misc_reg, val);
setMiscRegNoEffect(idx, val);
}
break;
default:
setMiscRegNoEffect(misc_reg, val);
setMiscRegNoEffect(idx, val);
}
}
}

View File

@@ -84,10 +84,10 @@ class ISA : public BaseISA
}
public:
RegVal readMiscRegNoEffect(int misc_reg) const;
RegVal readMiscReg(int misc_reg);
void setMiscRegNoEffect(int misc_reg, RegVal val);
void setMiscReg(int misc_reg, RegVal val);
RegVal readMiscRegNoEffect(RegIndex idx) const override;
RegVal readMiscReg(RegIndex idx) override;
void setMiscRegNoEffect(RegIndex idx, RegVal val) override;
void setMiscReg(RegIndex idx, RegVal val) override;
bool inUserMode() const override;
void copyRegsFrom(ThreadContext *src) override;

View File

@@ -39,21 +39,21 @@
namespace gem5
{
class BaseISA;
namespace SparcISA
{
class ISA;
class Decoder : public InstDecoder
{
protected:
// The extended machine instruction being generated
ExtMachInst emi;
uint32_t machInst;
RegVal asi;
RegVal asi = 0;
public:
Decoder(const SparcDecoderParams &p) : InstDecoder(p, &machInst), asi(0)
{}
Decoder(const SparcDecoderParams &p) : InstDecoder(p, &machInst) {}
// Use this to give data to the predecoder. This should be used
// when there is control flow.

View File

@@ -373,17 +373,17 @@ ISA::clear()
}
RegVal
ISA::readMiscRegNoEffect(int miscReg) const
ISA::readMiscRegNoEffect(RegIndex idx) const
{
// The three miscRegs are moved up from the switch statement
// The three idxs are moved up from the switch statement
// due to more frequent calls.
if (miscReg == MISCREG_GL)
if (idx == MISCREG_GL)
return gl;
if (miscReg == MISCREG_CWP)
if (idx == MISCREG_CWP)
return cwp;
if (miscReg == MISCREG_TLB_DATA) {
if (idx == MISCREG_TLB_DATA) {
/* Package up all the data for the tlb:
* 6666555555555544444444443333333333222222222211111111110000000000
* 3210987654321098765432109876543210987654321098765432109876543210
@@ -405,7 +405,7 @@ ISA::readMiscRegNoEffect(int miscReg) const
(uint64_t)secContext << 48;
}
switch (miscReg) {
switch (idx) {
// case MISCREG_TLB_DATA:
// [original contents see above]
// case MISCREG_Y:
@@ -529,14 +529,14 @@ ISA::readMiscRegNoEffect(int miscReg) const
case MISCREG_QUEUE_NRES_ERROR_TAIL:
return nres_error_tail;
default:
panic("Miscellaneous register %d not implemented\n", miscReg);
panic("Miscellaneous register %d not implemented\n", idx);
}
}
RegVal
ISA::readMiscReg(int miscReg)
ISA::readMiscReg(RegIndex idx)
{
switch (miscReg) {
switch (idx) {
// tick and stick are aliased to each other in niagra
// well store the tick data in stick and the interrupt bit in tick
case MISCREG_STICK:
@@ -576,15 +576,15 @@ ISA::readMiscReg(int miscReg)
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
case MISCREG_HPSTATE:
return readFSReg(miscReg);
return readFSReg(idx);
}
return readMiscRegNoEffect(miscReg);
return readMiscRegNoEffect(idx);
}
void
ISA::setMiscRegNoEffect(int miscReg, RegVal val)
ISA::setMiscRegNoEffect(RegIndex idx, RegVal val)
{
switch (miscReg) {
switch (idx) {
// case MISCREG_Y:
// y = val;
// break;
@@ -758,16 +758,16 @@ ISA::setMiscRegNoEffect(int miscReg, RegVal val)
nres_error_tail = val;
break;
default:
panic("Miscellaneous register %d not implemented\n", miscReg);
panic("Miscellaneous register %d not implemented\n", idx);
}
}
void
ISA::setMiscReg(int miscReg, RegVal val)
ISA::setMiscReg(RegIndex idx, RegVal val)
{
RegVal new_val = val;
switch (miscReg) {
switch (idx) {
case MISCREG_ASI:
tc->getDecoderPtr()->as<Decoder>().setContext(val);
break;
@@ -832,10 +832,10 @@ ISA::setMiscReg(int miscReg, RegVal val)
case MISCREG_QUEUE_NRES_ERROR_HEAD:
case MISCREG_QUEUE_NRES_ERROR_TAIL:
case MISCREG_HPSTATE:
setFSReg(miscReg, val);
setFSReg(idx, val);
return;
}
setMiscRegNoEffect(miscReg, new_val);
setMiscRegNoEffect(idx, new_val);
}
void

View File

@@ -188,11 +188,11 @@ class ISA : public BaseISA
public:
RegVal readMiscRegNoEffect(int miscReg) const;
RegVal readMiscReg(int miscReg);
RegVal readMiscRegNoEffect(RegIndex idx) const override;
RegVal readMiscReg(RegIndex idx) override;
void setMiscRegNoEffect(int miscReg, RegVal val);
void setMiscReg(int miscReg, RegVal val);
void setMiscRegNoEffect(RegIndex idx, RegVal val) override;
void setMiscReg(RegIndex idx, RegVal val) override;
uint64_t
getExecutingAsid() const override

View File

@@ -49,10 +49,11 @@
namespace gem5
{
class BaseISA;
namespace X86ISA
{
class ISA;
class Decoder : public InstDecoder
{
private:

View File

@@ -202,49 +202,49 @@ ISA::copyRegsFrom(ThreadContext *src)
}
RegVal
ISA::readMiscRegNoEffect(int miscReg) const
ISA::readMiscRegNoEffect(RegIndex idx) const
{
// Make sure we're not dealing with an illegal control register.
// Instructions should filter out these indexes, and nothing else should
// attempt to read them directly.
assert(misc_reg::isValid(miscReg));
assert(misc_reg::isValid(idx));
return regVal[miscReg];
return regVal[idx];
}
RegVal
ISA::readMiscReg(int miscReg)
ISA::readMiscReg(RegIndex idx)
{
if (miscReg == misc_reg::Tsc) {
if (idx == misc_reg::Tsc) {
return regVal[misc_reg::Tsc] + tc->getCpuPtr()->curCycle();
}
if (miscReg == misc_reg::Fsw) {
if (idx == misc_reg::Fsw) {
RegVal fsw = regVal[misc_reg::Fsw];
RegVal top = regVal[misc_reg::X87Top];
return insertBits(fsw, 13, 11, top);
}
if (miscReg == misc_reg::ApicBase) {
if (idx == misc_reg::ApicBase) {
LocalApicBase base = regVal[misc_reg::ApicBase];
base.bsp = (tc->contextId() == 0);
return base;
}
return readMiscRegNoEffect(miscReg);
return readMiscRegNoEffect(idx);
}
void
ISA::setMiscRegNoEffect(int miscReg, RegVal val)
ISA::setMiscRegNoEffect(RegIndex idx, RegVal val)
{
// Make sure we're not dealing with an illegal control register.
// Instructions should filter out these indexes, and nothing else should
// attempt to write to them directly.
assert(misc_reg::isValid(miscReg));
assert(misc_reg::isValid(idx));
HandyM5Reg m5Reg = regVal[misc_reg::M5Reg];
int reg_width = 64;
switch (miscReg) {
switch (idx) {
case misc_reg::X87Top:
reg_width = 3;
break;
@@ -273,18 +273,17 @@ ISA::setMiscRegNoEffect(int miscReg, RegVal val)
break;
}
regVal[miscReg] = val & mask(reg_width);
regVal[idx] = val & mask(reg_width);
}
void
ISA::setMiscReg(int miscReg, RegVal val)
ISA::setMiscReg(RegIndex idx, RegVal val)
{
RegVal newVal = val;
switch(miscReg)
{
switch (idx) {
case misc_reg::Cr0:
{
CR0 toggled = regVal[miscReg] ^ val;
CR0 toggled = regVal[idx] ^ val;
CR0 newCR0 = val;
Efer efer = regVal[misc_reg::Efer];
if (toggled.pg && efer.lme) {
@@ -318,7 +317,7 @@ ISA::setMiscReg(int miscReg, RegVal val)
break;
case misc_reg::Cr4:
{
CR4 toggled = regVal[miscReg] ^ val;
CR4 toggled = regVal[idx] ^ val;
if (toggled.pae || toggled.pse || toggled.pge) {
tc->getMMUPtr()->flushAll();
}
@@ -334,7 +333,7 @@ ISA::setMiscReg(int miscReg, RegVal val)
}
case misc_reg::CsAttr:
{
SegAttr toggled = regVal[miscReg] ^ val;
SegAttr toggled = regVal[idx] ^ val;
SegAttr newCSAttr = val;
if (toggled.longMode) {
if (newCSAttr.longMode) {
@@ -372,7 +371,7 @@ ISA::setMiscReg(int miscReg, RegVal val)
case misc_reg::TsgBase:
case misc_reg::TrBase:
case misc_reg::IdtrBase:
regVal[misc_reg::segEffBase(miscReg - misc_reg::SegBaseBase)] = val;
regVal[misc_reg::segEffBase(idx - misc_reg::SegBaseBase)] = val;
break;
// These segments ignore their bases in 64 bit mode.
// their effective bases must stay equal to their actual bases.
@@ -384,7 +383,7 @@ ISA::setMiscReg(int miscReg, RegVal val)
Efer efer = regVal[misc_reg::Efer];
SegAttr csAttr = regVal[misc_reg::CsAttr];
if (!efer.lma || !csAttr.longMode) // Check for non 64 bit mode.
regVal[misc_reg::segEffBase(miscReg -
regVal[misc_reg::segEffBase(idx -
misc_reg::SegBaseBase)] = val;
}
break;
@@ -398,7 +397,7 @@ ISA::setMiscReg(int miscReg, RegVal val)
/* These should eventually set up breakpoints. */
break;
case misc_reg::Dr4:
miscReg = misc_reg::Dr6;
idx = misc_reg::Dr6;
[[fallthrough]];
case misc_reg::Dr6:
{
@@ -415,7 +414,7 @@ ISA::setMiscReg(int miscReg, RegVal val)
}
break;
case misc_reg::Dr5:
miscReg = misc_reg::Dr7;
idx = misc_reg::Dr7;
[[fallthrough]];
case misc_reg::Dr7:
{
@@ -473,7 +472,7 @@ ISA::setMiscReg(int miscReg, RegVal val)
default:
break;
}
setMiscRegNoEffect(miscReg, newVal);
setMiscRegNoEffect(idx, newVal);
}
void

View File

@@ -72,11 +72,11 @@ class ISA : public BaseISA
ISA(const Params &p);
RegVal readMiscRegNoEffect(int miscReg) const;
RegVal readMiscReg(int miscReg);
RegVal readMiscRegNoEffect(RegIndex idx) const override;
RegVal readMiscReg(RegIndex idx) override;
void setMiscRegNoEffect(int miscReg, RegVal val);
void setMiscReg(int miscReg, RegVal val);
void setMiscRegNoEffect(RegIndex idx, RegVal val) override;
void setMiscReg(RegIndex idx, RegVal val) override;
bool
inUserMode() const override