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:
@@ -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 ¶ms)
|
||||
: 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(
|
||||
|
||||
@@ -56,10 +56,11 @@
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
class BaseISA;
|
||||
|
||||
namespace ArmISA
|
||||
{
|
||||
|
||||
class ISA;
|
||||
class Decoder : public InstDecoder
|
||||
{
|
||||
public: // Public decoder parameters
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ® = lookUpMiscReg[misc_reg]; // bit masks
|
||||
const auto &map = getMiscIndices(misc_reg);
|
||||
const auto ® = 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 ® = lookUpMiscReg[misc_reg]; // bit masks
|
||||
const auto &map = getMiscIndices(misc_reg);
|
||||
const auto ® = 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -41,10 +41,11 @@
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
class BaseISA;
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
|
||||
class ISA;
|
||||
class Decoder : public InstDecoder
|
||||
{
|
||||
protected:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
@@ -40,10 +40,11 @@
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
class BaseISA;
|
||||
|
||||
namespace PowerISA
|
||||
{
|
||||
|
||||
class ISA;
|
||||
class Decoder : public InstDecoder
|
||||
{
|
||||
protected:
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -42,10 +42,11 @@
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
class BaseISA;
|
||||
|
||||
namespace RiscvISA
|
||||
{
|
||||
|
||||
class ISA;
|
||||
class Decoder : public InstDecoder
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -49,10 +49,11 @@
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
class BaseISA;
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
|
||||
class ISA;
|
||||
class Decoder : public InstDecoder
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user