gem5: adapt to Register iface change

This change adapts the gem5 backend to the Register class interface change
in commit 52723a8.  The necessary modifications suggested adding the "misc"
registers from gem5, too.

Change-Id: I32561c3fc905b9cd396e32ce80c791c01d5682fb
This commit is contained in:
Horst Schirmeier
2013-08-29 19:33:55 +02:00
parent 4115de91aa
commit 0e595b38a3
4 changed files with 217 additions and 27 deletions

View File

@ -21,6 +21,15 @@ public:
* \enum GPRegIndex
* Defines the general purpose (GP) register identifier for the ARM
* plattform. Some of them are just aliases.
*
* Must currently stay in sync with register IDs defined in
* simulators/gem5/src/arch/arm/miscregs.hh and
* simulators/gem5/src/arch/arm/intregs.hh
* which we cannot include because they are generated (probably after we need
* them). As integer and "misc" register IDs overlap in gem5, and Fail* needs
* unique IDs, we split at RI_INTREGS_MAX and map to the original IDs in
* sal/gem5/Gem5Wrapper.cc . If more ARM backends emerge, we may need to find
* more sophisticated backend<->Fail* register ID mappings.
*/
enum GPRegIndex {
RI_R0,
@ -44,19 +53,29 @@ enum GPRegIndex {
RI_IP = RI_R15,
RI_R13_SVC,
RI_SP_SVC = RI_R13_SVC,
RI_R14_SVC,
RI_LR_SVC = RI_R14_SVC,
RI_R13_MON,
RI_SP_MON = RI_R13_MON,
RI_R14_MON,
RI_LR_MON = RI_R14_MON,
RI_R13_ABT,
RI_SP_ABT = RI_R13_ABT,
RI_R14_ABT,
RI_LR_ABT = RI_R14_ABT,
RI_R13_UND,
RI_SP_UND = RI_R13_UND,
RI_R14_UND,
RI_LR_UND = RI_R14_UND,
RI_R13_IRQ,
RI_SP_IRQ = RI_R13_IRQ,
RI_R14_IRQ,
RI_LR_IRQ = RI_R14_IRQ,
RI_R8_FIQ,
RI_R9_FIQ,
@ -64,12 +83,183 @@ enum GPRegIndex {
RI_R11_FIQ,
RI_R12_FIQ,
RI_R13_FIQ,
RI_R14_FIQ
};
RI_SP_FIQ = RI_R13_FIQ,
RI_R14_FIQ,
RI_LR_FIQ = RI_R14_FIQ,
// TODO: Enum for misc registers, see (e.g.)
// simulators/gem5/src/arch/arm/miscregs.hh and
// simulators/gem5/src/arch/arm/intregs.hh
RI_INTREGS_MAX,
// misc regs
RI_CPSR = RI_INTREGS_MAX,
RI_CPSR_Q,
RI_SPSR,
RI_SPSR_FIQ,
RI_SPSR_IRQ,
RI_SPSR_SVC,
RI_SPSR_MON,
RI_SPSR_UND,
RI_SPSR_ABT,
RI_FPSR,
RI_FPSID,
RI_FPSCR,
RI_FPSCR_QC, // Cumulative saturation flag
RI_FPSCR_EXC, // Cumulative FP exception flags
RI_FPEXC,
RI_MVFR0,
RI_MVFR1,
RI_SCTLR_RST,
RI_SEV_MAILBOX,
// CP14 registers
RI_CP14_START,
RI_DBGDIDR = RI_CP14_START,
RI_DBGDSCR_INT,
RI_DBGDTRRX_INT,
RI_DBGTRTX_INT,
RI_DBGWFAR,
RI_DBGVCR,
RI_DBGECR,
RI_DBGDSCCR,
RI_DBGSMCR,
RI_DBGDTRRX_EXT,
RI_DBGDSCR_EXT,
RI_DBGDTRTX_EXT,
RI_DBGDRCR,
RI_DBGBVR,
RI_DBGBCR,
RI_DBGBVR_M,
RI_DBGBCR_M,
RI_DBGDRAR,
RI_DBGBXVR_M,
RI_DBGOSLAR,
RI_DBGOSSRR,
RI_DBGOSDLR,
RI_DBGPRCR,
RI_DBGPRSR,
RI_DBGDSAR,
RI_DBGITCTRL,
RI_DBGCLAIMSET,
RI_DBGCLAIMCLR,
RI_DBGAUTHSTATUS,
RI_DBGDEVID2,
RI_DBGDEVID1,
RI_DBGDEVID,
// CP15 registers
RI_CP15_START,
RI_SCTLR = RI_CP15_START,
RI_DCCISW,
RI_DCCIMVAC,
RI_DCCMVAC,
RI_CONTEXTIDR,
RI_TPIDRURW,
RI_TPIDRURO,
RI_TPIDRPRW,
RI_CP15ISB,
RI_CP15DSB,
RI_CP15DMB,
RI_CPACR,
RI_CLIDR,
RI_CCSIDR,
RI_CSSELR,
RI_ICIALLUIS,
RI_ICIALLU,
RI_ICIMVAU,
RI_BPIMVA,
RI_BPIALLIS,
RI_BPIALL,
RI_MIDR,
RI_TTBR0,
RI_TTBR1,
RI_TLBTR,
RI_DACR,
RI_TLBIALLIS,
RI_TLBIMVAIS,
RI_TLBIASIDIS,
RI_TLBIMVAAIS,
RI_ITLBIALL,
RI_ITLBIMVA,
RI_ITLBIASID,
RI_DTLBIALL,
RI_DTLBIMVA,
RI_DTLBIASID,
RI_TLBIALL,
RI_TLBIMVA,
RI_TLBIASID,
RI_TLBIMVAA,
RI_DFSR,
RI_IFSR,
RI_DFAR,
RI_IFAR,
RI_MPIDR,
RI_PRRR,
RI_NMRR,
RI_TTBCR,
RI_ID_PFR0,
RI_CTR,
RI_SCR,
RI_SDER,
RI_PAR,
RI_V2PCWPR,
RI_V2PCWPW,
RI_V2PCWUR,
RI_V2PCWUW,
RI_V2POWPR,
RI_V2POWPW,
RI_V2POWUR,
RI_V2POWUW,
RI_ID_MMFR0,
RI_ID_MMFR2,
RI_ID_MMFR3,
RI_ACTLR,
RI_PMCR,
RI_PMCCNTR,
RI_PMCNTENSET,
RI_PMCNTENCLR,
RI_PMOVSR,
RI_PMSWINC,
RI_PMSELR,
RI_PMCEID0,
RI_PMCEID1,
RI_PMC_OTHER,
RI_PMXEVCNTR,
RI_PMUSERENR,
RI_PMINTENSET,
RI_PMINTENCLR,
RI_ID_ISAR0,
RI_ID_ISAR1,
RI_ID_ISAR2,
RI_ID_ISAR3,
RI_ID_ISAR4,
RI_ID_ISAR5,
RI_CPSR_MODE,
RI_LOCKFLAG,
RI_LOCKADDR,
RI_ID_PFR1,
RI_L2CTLR,
RI_CP15_UNIMP_START,
RI_TCMTR = RI_CP15_UNIMP_START,
RI_ID_DFR0,
RI_ID_AFR0,
RI_ID_MMFR1,
RI_AIDR,
RI_ADFSR,
RI_AIFSR,
RI_DCIMVAC,
RI_DCISW,
RI_MCCSW,
RI_DCCMVAU,
RI_NSACR,
RI_VBAR,
RI_MVBAR,
RI_ISR,
RI_FCEIDR,
RI_L2LATENCY,
RI_CRN15,
RI_CP15_END,
};
} // end-of-namespace: fail

View File

@ -6,12 +6,12 @@ namespace fail {
regdata_t Gem5ArmCPU::getRegisterContent(const Register* reg) const
{
return GetRegisterContent(m_System, m_Id, reg->getType(), reg->getIndex());
return GetRegisterContent(m_System, m_Id, reg->getId());
}
void Gem5ArmCPU::setRegisterContent(const Register* reg, regdata_t value)
{
SetRegisterContent(m_System, m_Id, reg->getType(), reg->getIndex(), value);
SetRegisterContent(m_System, m_Id, reg->getId(), value);
}
} // end-of-namespace: fail

View File

@ -8,30 +8,31 @@
namespace fail {
// Register-/Memory-related:
regdata_t GetRegisterContent(System* sys, unsigned int id, RegisterType type, size_t idx)
regdata_t GetRegisterContent(System* sys, unsigned int id, size_t idx)
{
switch (type) {
case RT_GP: // pass on...
case RT_FP: return sys->getThreadContext(id)->readIntReg(idx);
case RT_ST: return sys->getThreadContext(id)->readMiscReg(idx);
case RT_IP: return sys->getThreadContext(id)->pcState().pc();
// necessary because gem5 register IDs are not unique
if (idx < RI_INTREGS_MAX) {
switch (idx) {
case RI_IP: return sys->getThreadContext(id)->pcState().pc();
default: return sys->getThreadContext(id)->readIntReg(idx);
}
} else {
return sys->getThreadContext(id)->readMiscReg(idx - RI_INTREGS_MAX);
}
// This shouldn't be reached if a valid register is passed
assert(false && "FATAL ERROR: invalid register type (should never be reached)!");
return 0;
}
void SetRegisterContent(System* sys, unsigned int id, RegisterType type, size_t idx,
regdata_t value)
void SetRegisterContent(System* sys, unsigned int id, size_t idx, regdata_t value)
{
switch (type) {
case RT_GP: // pass on...
case RT_FP: sys->getThreadContext(id)->setIntReg(idx, value); return;
case RT_ST: sys->getThreadContext(id)->setMiscReg(idx, value); return;
case RT_IP: sys->getThreadContext(id)->pcState().pc(static_cast<Addr>(value)); return;
// necessary because gem5 register IDs are not unique
if (idx < RI_INTREGS_MAX) {
switch (idx) {
case RI_IP: sys->getThreadContext(id)->pcState().pc(static_cast<Addr>(value)); break;
default: sys->getThreadContext(id)->setIntReg(idx, value);
}
} else {
sys->getThreadContext(id)->setMiscReg(idx - RI_INTREGS_MAX, value);
}
// This shouldn't be reached if a valid register is passed
assert(false && "FATAL ERROR: Invalid register type (should never be reached)!");
}
void ReadMemory(System* sys, guest_address_t addr, size_t cnt, void *dest)

View File

@ -10,9 +10,8 @@ class System;
namespace fail {
// Register-/Memory-related:
regdata_t GetRegisterContent(System* sys, unsigned int id, RegisterType type, size_t idx);
void SetRegisterContent(System* sys, unsigned int id, RegisterType type, size_t idx,
regdata_t value);
regdata_t GetRegisterContent(System* sys, unsigned int id, size_t idx);
void SetRegisterContent(System* sys, unsigned int id, size_t idx, regdata_t value);
void WriteMemory(System* sys, guest_address_t addr, size_t cnt, void const *src);
void ReadMemory(System* sys, guest_address_t addr, size_t cnt, void *dest);
size_t GetPoolSize(System* sys);