Merge branch 'gem5-register-fix'

This commit is contained in:
Horst Schirmeier
2013-09-02 15:10:52 +02:00
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);