fastmodel: Move ARM but not CortexA76 specific bits to the IRIS TC.

Now that the IRIS thread context can be specific to ARM, some things
which had been pushed to a different level of abstraction can be mvoed
back. This will hopefully allow more code sharing in the future when
other types of CPUs are supported.

Change-Id: Ic3a5f0db53ebe93e18f7507ed71812bce27b6d01
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23788
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2019-11-05 16:58:14 -08:00
parent 062686655e
commit 31f376f482
4 changed files with 116 additions and 147 deletions

View File

@@ -40,8 +40,7 @@ CortexA76TC::CortexA76TC(
::BaseCPU *cpu, int id, System *system, ::BaseTLB *dtb, ::BaseTLB *itb,
iris::IrisConnectionInterface *iris_if,
const std::string &iris_path) :
ThreadContext(cpu, id, system, dtb, itb, iris_if, iris_path),
vecRegs(TheISA::NumVecRegs), pcRscId(iris::IRIS_UINT64_MAX)
ThreadContext(cpu, id, system, dtb, itb, iris_if, iris_path)
{}
bool
@@ -87,7 +86,6 @@ CortexA76TC::initFromIrisInstance(const ResourceMap &resources)
ThreadContext::initFromIrisInstance(resources);
pcRscId = extractResourceId(resources, "PC");
icountRscId = extractResourceId(resources, "icount");
extractResourceMap(miscRegIds, resources, miscRegIdxNameMap);
@@ -97,54 +95,6 @@ CortexA76TC::initFromIrisInstance(const ResourceMap &resources)
extractResourceMap(vecRegIds, resources, vecRegIdxNameMap);
}
TheISA::PCState
CortexA76TC::pcState() const
{
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
ArmISA::PCState pc;
pc.thumb(cpsr.t);
pc.nextThumb(pc.thumb());
pc.jazelle(cpsr.j);
pc.nextJazelle(cpsr.j);
pc.aarch64(!cpsr.width);
pc.nextAArch64(!cpsr.width);
pc.illegalExec(false);
iris::ResourceReadResult result;
call().resource_read(_instId, result, pcRscId);
Addr addr = result.data.at(0);
if (cpsr.width && cpsr.t)
addr = addr & ~0x1;
pc.set(addr);
return pc;
}
void
CortexA76TC::pcState(const TheISA::PCState &val)
{
Addr pc = val.pc();
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
if (cpsr.width && cpsr.t)
pc = pc | 0x1;
iris::ResourceWriteResult result;
call().resource_write(_instId, result, pcRscId, pc);
}
Addr
CortexA76TC::instAddr() const
{
return pcState().instAddr();
}
Addr
CortexA76TC::nextInstAddr() const
{
return pcState().nextInstAddr();
}
iris::MemorySpaceId
CortexA76TC::getBpSpaceId(Addr pc) const
{
@@ -161,57 +111,6 @@ CortexA76TC::getBpSpaceId(Addr pc) const
return bpSpaceId;
}
uint64_t
CortexA76TC::readIntReg(RegIndex reg_idx) const
{
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
iris::ResourceReadResult result;
if (cpsr.width)
call().resource_read(_instId, result, intReg32Ids.at(reg_idx));
else
call().resource_read(_instId, result, intReg64Ids.at(reg_idx));
return result.data.at(0);
}
void
CortexA76TC::setIntReg(RegIndex reg_idx, uint64_t val)
{
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
iris::ResourceWriteResult result;
if (cpsr.width)
call().resource_write(_instId, result, intReg32Ids.at(reg_idx), val);
else
call().resource_write(_instId, result, intReg64Ids.at(reg_idx), val);
}
const ArmISA::VecRegContainer &
CortexA76TC::readVecReg(const RegId &reg_id) const
{
const RegIndex idx = reg_id.index();
// Ignore accesses to registers which aren't architected. gem5 defines a
// few extra registers which it uses internally in the implementation of
// some instructions.
if (idx >= vecRegIds.size())
return vecRegs.at(idx);
ArmISA::VecRegContainer &reg = vecRegs.at(idx);
iris::ResourceReadResult result;
call().resource_read(_instId, result, vecRegIds.at(idx));
size_t data_size = result.data.size() * (sizeof(*result.data.data()));
size_t size = std::min(data_size, reg.SIZE);
memcpy(reg.raw_ptr<void>(), (void *)result.data.data(), size);
return reg;
}
const ArmISA::VecRegContainer &
CortexA76TC::readVecRegFlat(RegIndex idx) const
{
return readVecReg(RegId(VecRegClass, idx));
}
Iris::ThreadContext::IdxNameMap CortexA76TC::miscRegIdxNameMap({
{ ArmISA::MISCREG_CPSR, "CPSR" },
{ ArmISA::MISCREG_SPSR, "SPSR" },

View File

@@ -46,10 +46,6 @@ class CortexA76TC : public Iris::ThreadContext
static IdxNameMap vecRegIdxNameMap;
static iris::MemorySpaceId bpSpaceId;
// Temporary holding places for the vector reg accessors to return.
// These are not updated live, only when requested.
mutable std::vector<ArmISA::VecRegContainer> vecRegs;
public:
CortexA76TC(::BaseCPU *cpu, int id, System *system,
::BaseTLB *dtb, ::BaseTLB *itb,
@@ -60,30 +56,7 @@ class CortexA76TC : public Iris::ThreadContext
void initFromIrisInstance(const ResourceMap &resources) override;
TheISA::PCState pcState() const override;
void pcState(const TheISA::PCState &val) override;
Addr instAddr() const override;
Addr nextInstAddr() const override;
iris::ResourceId pcRscId;
iris::ResourceId icountRscId;
ResourceIds intReg32Ids;
ResourceIds intReg64Ids;
ResourceIds vecRegIds;
iris::MemorySpaceId getBpSpaceId(Addr pc) const override;
void setIntReg(RegIndex reg_idx, RegVal val) override;
RegVal readIntReg(RegIndex reg_idx) const override;
TheISA::ISA *
getIsaPtr() override
{
panic("%s not implemented.", __FUNCTION__);
}
const VecRegContainer &readVecReg(const RegId &reg) const override;
const VecRegContainer &readVecRegFlat(RegIndex idx) const override;
};
} // namespace FastModel

View File

@@ -244,7 +244,7 @@ ThreadContext::ThreadContext(
BaseCPU *cpu, int id, System *system, ::BaseTLB *dtb, ::BaseTLB *itb,
iris::IrisConnectionInterface *iris_if, const std::string &iris_path) :
_cpu(cpu), _threadId(id), _system(system), _dtb(dtb), _itb(itb),
_irisPath(iris_path), _instId(iris::IRIS_UINT64_MAX), _status(Active),
_irisPath(iris_path), vecRegs(TheISA::NumVecRegs),
comInstEventQueue("instruction-based event queue"),
client(iris_if, "client." + iris_path)
{
@@ -431,6 +431,54 @@ ThreadContext::setStatus(Status new_status)
_status = new_status;
}
ArmISA::PCState
ThreadContext::pcState() const
{
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
ArmISA::PCState pc;
pc.thumb(cpsr.t);
pc.nextThumb(pc.thumb());
pc.jazelle(cpsr.j);
pc.nextJazelle(cpsr.j);
pc.aarch64(!cpsr.width);
pc.nextAArch64(!cpsr.width);
pc.illegalExec(false);
iris::ResourceReadResult result;
call().resource_read(_instId, result, pcRscId);
Addr addr = result.data.at(0);
if (cpsr.width && cpsr.t)
addr = addr & ~0x1;
pc.set(addr);
return pc;
}
void
ThreadContext::pcState(const ArmISA::PCState &val)
{
Addr pc = val.pc();
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
if (cpsr.width && cpsr.t)
pc = pc | 0x1;
iris::ResourceWriteResult result;
call().resource_write(_instId, result, pcRscId, pc);
}
Addr
ThreadContext::instAddr() const
{
return pcState().instAddr();
}
Addr
ThreadContext::nextInstAddr() const
{
return pcState().nextInstAddr();
}
RegVal
ThreadContext::readMiscRegNoEffect(RegIndex misc_reg) const
{
@@ -449,16 +497,52 @@ ThreadContext::setMiscRegNoEffect(RegIndex misc_reg, const RegVal val)
RegVal
ThreadContext::readIntReg(RegIndex reg_idx) const
{
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
iris::ResourceReadResult result;
call().resource_read(_instId, result, intRegIds.at(reg_idx));
if (cpsr.width)
call().resource_read(_instId, result, intReg32Ids.at(reg_idx));
else
call().resource_read(_instId, result, intReg64Ids.at(reg_idx));
return result.data.at(0);
}
void
ThreadContext::setIntReg(RegIndex reg_idx, RegVal val)
{
ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
iris::ResourceWriteResult result;
call().resource_write(_instId, result, intRegIds.at(reg_idx), val);
if (cpsr.width)
call().resource_write(_instId, result, intReg32Ids.at(reg_idx), val);
else
call().resource_write(_instId, result, intReg64Ids.at(reg_idx), val);
}
const ArmISA::VecRegContainer &
ThreadContext::readVecReg(const RegId &reg_id) const
{
const RegIndex idx = reg_id.index();
// Ignore accesses to registers which aren't architected. gem5 defines a
// few extra registers which it uses internally in the implementation of
// some instructions.
if (idx >= vecRegIds.size())
return vecRegs.at(idx);
ArmISA::VecRegContainer &reg = vecRegs.at(idx);
iris::ResourceReadResult result;
call().resource_read(_instId, result, vecRegIds.at(idx));
size_t data_size = result.data.size() * (sizeof(*result.data.data()));
size_t size = std::min(data_size, reg.SIZE);
memcpy(reg.raw_ptr<void>(), (void *)result.data.data(), size);
return reg;
}
const ArmISA::VecRegContainer &
ThreadContext::readVecRegFlat(RegIndex idx) const
{
return readVecReg(RegId(VecRegClass, idx));
}
} // namespace Iris

View File

@@ -63,9 +63,13 @@ class ThreadContext : public ::ThreadContext
::BaseTLB *_itb;
std::string _irisPath;
iris::InstanceId _instId;
iris::InstanceId _instId = iris::IRIS_UINT64_MAX;
Status _status;
// Temporary holding places for the vector reg accessors to return.
// These are not updated live, only when requested.
mutable std::vector<ArmISA::VecRegContainer> vecRegs;
Status _status = Active;
virtual void initFromIrisInstance(const ResourceMap &resources);
@@ -76,7 +80,13 @@ class ThreadContext : public ::ThreadContext
ResourceIds miscRegIds;
ResourceIds intRegIds;
ResourceIds intReg32Ids;
ResourceIds intReg64Ids;
iris::ResourceId pcRscId = iris::IRIS_UINT64_MAX;
iris::ResourceId icountRscId;
ResourceIds vecRegIds;
std::vector<iris::MemorySpaceInfo> memorySpaces;
std::vector<iris::MemorySupportedAddressTranslationResult> translations;
@@ -188,7 +198,7 @@ class ThreadContext : public ::ThreadContext
{
panic("%s not implemented.", __FUNCTION__);
}
TheISA::Decoder *
ArmISA::Decoder *
getDecoderPtr() override
{
panic("%s not implemented.", __FUNCTION__);
@@ -196,6 +206,12 @@ class ThreadContext : public ::ThreadContext
System *getSystemPtr() override { return _cpu->system; }
ArmISA::ISA *
getIsaPtr() override
{
panic("%s not implemented.", __FUNCTION__);
}
Kernel::Statistics *
getKernelStats() override
{
@@ -289,11 +305,7 @@ class ThreadContext : public ::ThreadContext
panic("%s not implemented.", __FUNCTION__);
}
const VecRegContainer &
readVecReg(const RegId &reg) const override
{
panic("%s not implemented.", __FUNCTION__);
}
const VecRegContainer &readVecReg(const RegId &reg) const override;
VecRegContainer &
getWritableVecReg(const RegId &reg) override
{
@@ -412,9 +424,14 @@ class ThreadContext : public ::ThreadContext
panic("%s not implemented.", __FUNCTION__);
}
void pcStateNoRecord(const TheISA::PCState &val) override { pcState(val); }
void pcStateNoRecord(const ArmISA::PCState &val) override { pcState(val); }
MicroPC microPC() const override { return 0; }
ArmISA::PCState pcState() const override;
void pcState(const ArmISA::PCState &val) override;
Addr instAddr() const override;
Addr nextInstAddr() const override;
RegVal readMiscRegNoEffect(RegIndex misc_reg) const override;
RegVal
readMiscReg(RegIndex misc_reg) override
@@ -496,11 +513,7 @@ class ThreadContext : public ::ThreadContext
panic("%s not implemented.", __FUNCTION__);
}
const VecRegContainer &
readVecRegFlat(RegIndex idx) const override
{
panic("%s not implemented.", __FUNCTION__);
}
const VecRegContainer &readVecRegFlat(RegIndex idx) const override;
VecRegContainer &
getWritableVecRegFlat(RegIndex idx) override
{