fastmodel: Implement flattened int reg reading and writing.

Because the fast models (or at least the one we've looked at) give
access to the integer registers mostly based on the current view of
those registers, it does its own flattening and prevents accessing most
of the raw storage locations without this extra level of mapping. To
store to the flattened locations, we need to unflatten the indexes and
in one case shift the mode so that we get the right values.

Some registers which have irrelevant values for fast model (the "PC"
which is actually diverted elsewhere, the zero register, microcode
registers, and the "dummy" register), and those are left out of the
mapping so that they return 0 and blow up gem5 when someone attempts to
set them.

Change-Id: Ia2d315d5ca4c8a65b17ad52beff3a366ca8b3d46
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23791
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Chun-Chen TK Hsu <chunchenhsu@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2019-11-12 16:52:05 -08:00
parent 00d324b8cc
commit d062a82f11
4 changed files with 122 additions and 10 deletions

View File

@@ -93,11 +93,55 @@ CortexA76TC::initFromIrisInstance(const ResourceMap &resources)
extractResourceMap(intReg32Ids, resources, intReg32IdxNameMap);
extractResourceMap(intReg64Ids, resources, intReg64IdxNameMap);
extractResourceMap(flattenedIntIds, resources, flattenedIntIdxNameMap);
extractResourceMap(ccRegIds, resources, ccRegIdxNameMap);
extractResourceMap(vecRegIds, resources, vecRegIdxNameMap);
}
RegVal
CortexA76TC::readIntRegFlat(RegIndex idx) const
{
ArmISA::CPSR orig_cpsr;
auto *non_const_this = const_cast<CortexA76TC *>(this);
if (idx == ArmISA::INTREG_R13_MON || idx == ArmISA::INTREG_R14_MON) {
orig_cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
ArmISA::CPSR new_cpsr = orig_cpsr;
new_cpsr.mode = MODE_MON;
non_const_this->setMiscReg(ArmISA::MISCREG_CPSR, new_cpsr);
}
RegVal val = ThreadContext::readIntRegFlat(idx);
if (idx == ArmISA::INTREG_R13_MON || idx == ArmISA::INTREG_R14_MON) {
non_const_this->setMiscReg(ArmISA::MISCREG_CPSR, orig_cpsr);
}
return val;
}
void
CortexA76TC::setIntRegFlat(RegIndex idx, RegVal val)
{
ArmISA::CPSR orig_cpsr;
if (idx == ArmISA::INTREG_R13_MON || idx == ArmISA::INTREG_R14_MON) {
orig_cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
ArmISA::CPSR new_cpsr = orig_cpsr;
new_cpsr.mode = MODE_MON;
setMiscReg(ArmISA::MISCREG_CPSR, new_cpsr);
}
ThreadContext::setIntRegFlat(idx, val);
if (idx == ArmISA::INTREG_R13_MON || idx == ArmISA::INTREG_R14_MON) {
setMiscReg(ArmISA::MISCREG_CPSR, orig_cpsr);
}
}
RegVal
CortexA76TC::readCCRegFlat(RegIndex idx) const
{
@@ -840,6 +884,48 @@ Iris::ThreadContext::IdxNameMap CortexA76TC::intReg64IdxNameMap({
{ ArmISA::INTREG_SPX, "SP" },
});
Iris::ThreadContext::IdxNameMap CortexA76TC::flattenedIntIdxNameMap({
{ ArmISA::INTREG_R0, "X0" },
{ ArmISA::INTREG_R1, "X1" },
{ ArmISA::INTREG_R2, "X2" },
{ ArmISA::INTREG_R3, "X3" },
{ ArmISA::INTREG_R4, "X4" },
{ ArmISA::INTREG_R5, "X5" },
{ ArmISA::INTREG_R6, "X6" },
{ ArmISA::INTREG_R7, "X7" },
{ ArmISA::INTREG_R8, "X8" },
{ ArmISA::INTREG_R9, "X9" },
{ ArmISA::INTREG_R10, "X10" },
{ ArmISA::INTREG_R11, "X11" },
{ ArmISA::INTREG_R12, "X12" },
{ ArmISA::INTREG_R13, "X13" },
{ ArmISA::INTREG_R14, "X14" },
// Skip PC.
{ ArmISA::INTREG_R13_SVC, "X19" },
{ ArmISA::INTREG_R14_SVC, "X18" },
{ ArmISA::INTREG_R13_MON, "R13" }, // Need to be in monitor mode?
{ ArmISA::INTREG_R14_MON, "R14" }, // Need to be in monitor mode?
{ ArmISA::INTREG_R13_HYP, "X15" },
{ ArmISA::INTREG_R13_ABT, "X21" },
{ ArmISA::INTREG_R14_ABT, "X20" },
{ ArmISA::INTREG_R13_UND, "X23" },
{ ArmISA::INTREG_R14_UND, "X22" },
{ ArmISA::INTREG_R13_IRQ, "X17" },
{ ArmISA::INTREG_R14_IRQ, "X16" },
{ ArmISA::INTREG_R8_FIQ, "X24" },
{ ArmISA::INTREG_R9_FIQ, "X25" },
{ ArmISA::INTREG_R10_FIQ, "X26" },
{ ArmISA::INTREG_R11_FIQ, "X27" },
{ ArmISA::INTREG_R12_FIQ, "X28" },
{ ArmISA::INTREG_R13_FIQ, "X29" },
{ ArmISA::INTREG_R14_FIQ, "X30" },
// Skip zero, ureg0-2, and dummy regs.
{ INTREG_SP0, "SP_EL0" },
{ INTREG_SP1, "SP_EL1" },
{ INTREG_SP2, "SP_EL2" },
{ INTREG_SP3, "SP_EL3" },
});
Iris::ThreadContext::IdxNameMap CortexA76TC::ccRegIdxNameMap({
{ ArmISA::CCREG_NZ, "CPSR" },
{ ArmISA::CCREG_C, "CPSR.C" },

View File

@@ -43,6 +43,7 @@ class CortexA76TC : public Iris::ThreadContext
static IdxNameMap miscRegIdxNameMap;
static IdxNameMap intReg32IdxNameMap;
static IdxNameMap intReg64IdxNameMap;
static IdxNameMap flattenedIntIdxNameMap;
static IdxNameMap ccRegIdxNameMap;
static IdxNameMap vecRegIdxNameMap;
static iris::MemorySpaceId bpSpaceId;
@@ -57,6 +58,9 @@ class CortexA76TC : public Iris::ThreadContext
void initFromIrisInstance(const ResourceMap &resources) override;
RegVal readIntRegFlat(RegIndex idx) const override;
void setIntRegFlat(RegIndex idx, RegVal val) override;
RegVal readCCRegFlat(RegIndex idx) const override;
void setCCRegFlat(RegIndex idx, RegVal val) override;

View File

@@ -520,6 +520,35 @@ ThreadContext::setIntReg(RegIndex reg_idx, RegVal val)
call().resource_write(_instId, result, intReg64Ids.at(reg_idx), val);
}
/*
* The 64 bit version of registers gives us a pre-flattened view of the reg
* file, no matter what mode we're in or if we're currently 32 or 64 bit.
*/
RegVal
ThreadContext::readIntRegFlat(RegIndex idx) const
{
if (idx >= flattenedIntIds.size())
return 0;
iris::ResourceId res_id = flattenedIntIds.at(idx);
if (res_id == iris::IRIS_UINT64_MAX)
return 0;
iris::ResourceReadResult result;
call().resource_read(_instId, result, res_id);
return result.data.at(0);
}
void
ThreadContext::setIntRegFlat(RegIndex idx, uint64_t val)
{
iris::ResourceId res_id =
(idx >= flattenedIntIds.size()) ? iris::IRIS_UINT64_MAX :
flattenedIntIds.at(idx);
panic_if(res_id == iris::IRIS_UINT64_MAX,
"Int reg %d is not supported by fast model.", idx);
iris::ResourceWriteResult result;
call().resource_write(_instId, result, flattenedIntIds.at(idx), val);
}
RegVal
ThreadContext::readCCRegFlat(RegIndex idx) const
{

View File

@@ -83,6 +83,7 @@ class ThreadContext : public ::ThreadContext
ResourceIds miscRegIds;
ResourceIds intReg32Ids;
ResourceIds intReg64Ids;
ResourceIds flattenedIntIds;
ResourceIds ccRegIds;
iris::ResourceId pcRscId = iris::IRIS_UINT64_MAX;
@@ -490,16 +491,8 @@ class ThreadContext : public ::ThreadContext
* serialization code to access all registers.
*/
uint64_t
readIntRegFlat(RegIndex idx) const override
{
panic("%s not implemented.", __FUNCTION__);
}
void
setIntRegFlat(RegIndex idx, uint64_t val) override
{
panic("%s not implemented.", __FUNCTION__);
}
RegVal readIntRegFlat(RegIndex idx) const override;
void setIntRegFlat(RegIndex idx, uint64_t val) override;
RegVal
readFloatRegFlat(RegIndex idx) const override