diff --git a/src/core/sal/arm/ArmArchitecture.hpp b/src/core/sal/arm/ArmArchitecture.hpp index 5ea821fe..1184867e 100644 --- a/src/core/sal/arm/ArmArchitecture.hpp +++ b/src/core/sal/arm/ArmArchitecture.hpp @@ -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 diff --git a/src/core/sal/gem5/Gem5ArmCPU.cc b/src/core/sal/gem5/Gem5ArmCPU.cc index fb5eb552..f8e92a82 100644 --- a/src/core/sal/gem5/Gem5ArmCPU.cc +++ b/src/core/sal/gem5/Gem5ArmCPU.cc @@ -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 diff --git a/src/core/sal/gem5/Gem5Wrapper.cc b/src/core/sal/gem5/Gem5Wrapper.cc index 149c4822..4d3cdb7f 100644 --- a/src/core/sal/gem5/Gem5Wrapper.cc +++ b/src/core/sal/gem5/Gem5Wrapper.cc @@ -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(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(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) diff --git a/src/core/sal/gem5/Gem5Wrapper.hpp b/src/core/sal/gem5/Gem5Wrapper.hpp index c5ecfd21..1c5699e8 100644 --- a/src/core/sal/gem5/Gem5Wrapper.hpp +++ b/src/core/sal/gem5/Gem5Wrapper.hpp @@ -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);