2c2
< * Copyright (c) 2010 ARM Limited
---
> * Copyright (c) 2010, 2012-2013 ARM Limited
46a47
> #include "arch/arm/system.hh"
49a51
> #include "dev/arm/generic_timer.hh"
58a61,127
>
> /**
> * At the moment there are 57 registers which need to be aliased/
> * translated with other registers in the ISA. This enum helps with that
> * translation.
> */
> enum translateTable {
> miscRegTranslateCSSELR_EL1,
> miscRegTranslateSCTLR_EL1,
> miscRegTranslateSCTLR_EL2,
> miscRegTranslateACTLR_EL1,
> miscRegTranslateACTLR_EL2,
> miscRegTranslateCPACR_EL1,
> miscRegTranslateCPTR_EL2,
> miscRegTranslateHCR_EL2,
> miscRegTranslateMDCR_EL2,
> miscRegTranslateHSTR_EL2,
> miscRegTranslateHACR_EL2,
> miscRegTranslateTTBR0_EL1,
> miscRegTranslateTTBR1_EL1,
> miscRegTranslateTTBR0_EL2,
> miscRegTranslateVTTBR_EL2,
> miscRegTranslateTCR_EL1,
> miscRegTranslateTCR_EL2,
> miscRegTranslateVTCR_EL2,
> miscRegTranslateAFSR0_EL1,
> miscRegTranslateAFSR1_EL1,
> miscRegTranslateAFSR0_EL2,
> miscRegTranslateAFSR1_EL2,
> miscRegTranslateESR_EL2,
> miscRegTranslateFAR_EL1,
> miscRegTranslateFAR_EL2,
> miscRegTranslateHPFAR_EL2,
> miscRegTranslatePAR_EL1,
> miscRegTranslateMAIR_EL1,
> miscRegTranslateMAIR_EL2,
> miscRegTranslateAMAIR_EL1,
> miscRegTranslateVBAR_EL1,
> miscRegTranslateVBAR_EL2,
> miscRegTranslateCONTEXTIDR_EL1,
> miscRegTranslateTPIDR_EL0,
> miscRegTranslateTPIDRRO_EL0,
> miscRegTranslateTPIDR_EL1,
> miscRegTranslateTPIDR_EL2,
> miscRegTranslateTEECR32_EL1,
> miscRegTranslateCNTFRQ_EL0,
> miscRegTranslateCNTPCT_EL0,
> miscRegTranslateCNTVCT_EL0,
> miscRegTranslateCNTVOFF_EL2,
> miscRegTranslateCNTKCTL_EL1,
> miscRegTranslateCNTHCTL_EL2,
> miscRegTranslateCNTP_TVAL_EL0,
> miscRegTranslateCNTP_CTL_EL0,
> miscRegTranslateCNTP_CVAL_EL0,
> miscRegTranslateCNTV_TVAL_EL0,
> miscRegTranslateCNTV_CTL_EL0,
> miscRegTranslateCNTV_CVAL_EL0,
> miscRegTranslateCNTHP_TVAL_EL2,
> miscRegTranslateCNTHP_CTL_EL2,
> miscRegTranslateCNTHP_CVAL_EL2,
> miscRegTranslateDACR32_EL2,
> miscRegTranslateIFSR32_EL2,
> miscRegTranslateTEEHBR32_EL1,
> miscRegTranslateSDER32_EL3,
> miscRegTranslateMax
> };
>
61a131,158
> // Parent system
> ArmSystem *system;
>
> // Cached copies of system-level properties
> bool haveSecurity;
> bool haveLPAE;
> bool haveVirtualization;
> bool haveLargeAsid64;
> uint8_t physAddrRange64;
>
> /** Register translation entry used in lookUpMiscReg */
> struct MiscRegLUTEntry {
> uint32_t lower;
> uint32_t upper;
> };
>
> struct MiscRegInitializerEntry {
> uint32_t index;
> struct MiscRegLUTEntry entry;
> };
>
> /** Register table noting all translations */
> static const struct MiscRegInitializerEntry
> MiscRegSwitch[miscRegTranslateMax];
>
> /** Translation table accessible via the value of the register */
> std::vector<struct MiscRegLUTEntry> lookUpMiscReg;
>
68,92c165,196
< switch (cpsr.mode) {
< case MODE_USER:
< case MODE_SYSTEM:
< intRegMap = IntRegUsrMap;
< break;
< case MODE_FIQ:
< intRegMap = IntRegFiqMap;
< break;
< case MODE_IRQ:
< intRegMap = IntRegIrqMap;
< break;
< case MODE_SVC:
< intRegMap = IntRegSvcMap;
< break;
< case MODE_MON:
< intRegMap = IntRegMonMap;
< break;
< case MODE_ABORT:
< intRegMap = IntRegAbtMap;
< break;
< case MODE_UNDEFINED:
< intRegMap = IntRegUndMap;
< break;
< default:
< panic("Unrecognized mode setting in CPSR.\n");
---
> if (cpsr.width == 0) {
> intRegMap = IntReg64Map;
> } else {
> switch (cpsr.mode) {
> case MODE_USER:
> case MODE_SYSTEM:
> intRegMap = IntRegUsrMap;
> break;
> case MODE_FIQ:
> intRegMap = IntRegFiqMap;
> break;
> case MODE_IRQ:
> intRegMap = IntRegIrqMap;
> break;
> case MODE_SVC:
> intRegMap = IntRegSvcMap;
> break;
> case MODE_MON:
> intRegMap = IntRegMonMap;
> break;
> case MODE_ABORT:
> intRegMap = IntRegAbtMap;
> break;
> case MODE_HYP:
> intRegMap = IntRegHypMap;
> break;
> case MODE_UNDEFINED:
> intRegMap = IntRegUndMap;
> break;
> default:
> panic("Unrecognized mode setting in CPSR.\n");
> }
95a200,225
> ::GenericTimer::SystemCounter * getSystemCounter(ThreadContext *tc);
> ::GenericTimer::ArchTimer * getArchTimer(ThreadContext *tc,
> int cpu_id);
>
>
> private:
> inline void assert32(ThreadContext *tc) {
> CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
> assert(cpsr.width);
> }
>
> inline void assert64(ThreadContext *tc) {
> CPSR cpsr M5_VAR_USED = readMiscReg(MISCREG_CPSR, tc);
> assert(!cpsr.width);
> }
>
> void tlbiVA(ThreadContext *tc, MiscReg newVal, uint8_t asid,
> bool secure_lookup, uint8_t target_el);
>
> void tlbiALL(ThreadContext *tc, bool secure_lookup, uint8_t target_el);
>
> void tlbiALLN(ThreadContext *tc, bool hyp, uint8_t target_el);
>
> void tlbiMVA(ThreadContext *tc, MiscReg newVal, bool secure_lookup,
> bool hyp, uint8_t target_el);
>
97a228
> void clear64(const ArmISAParams *p);
112,130c243,258
< } else {
< int mode = reg / intRegsPerMode;
< reg = reg % intRegsPerMode;
< switch (mode) {
< case MODE_USER:
< case MODE_SYSTEM:
< return INTREG_USR(reg);
< case MODE_FIQ:
< return INTREG_FIQ(reg);
< case MODE_IRQ:
< return INTREG_IRQ(reg);
< case MODE_SVC:
< return INTREG_SVC(reg);
< case MODE_MON:
< return INTREG_MON(reg);
< case MODE_ABORT:
< return INTREG_ABT(reg);
< case MODE_UNDEFINED:
< return INTREG_UND(reg);
---
> } else if (reg == INTREG_SPX) {
> CPSR cpsr = miscRegs[MISCREG_CPSR];
> ExceptionLevel el = opModeToEL(
> (OperatingMode) (uint8_t) cpsr.mode);
> if (!cpsr.sp && el != EL0)
> return INTREG_SP0;
> switch (el) {
> case EL3:
> return INTREG_SP3;
> // @todo: uncomment this to enable Virtualization
> // case EL2:
> // return INTREG_SP2;
> case EL1:
> return INTREG_SP1;
> case EL0:
> return INTREG_SP0;
132c260,261
< panic("Flattening into an unknown mode.\n");
---
> panic("Invalid exception level");
> break;
133a263,264
> } else {
> return flattenIntRegModeIndex(reg);
152a284,285
> int flat_idx = reg;
>
154d286
< int spsr_idx = NUM_MISCREGS;
156a289,304
> case MODE_EL0T:
> warn("User mode does not have SPSR\n");
> flat_idx = MISCREG_SPSR;
> break;
> case MODE_EL1T:
> case MODE_EL1H:
> flat_idx = MISCREG_SPSR_EL1;
> break;
> case MODE_EL2T:
> case MODE_EL2H:
> flat_idx = MISCREG_SPSR_EL2;
> break;
> case MODE_EL3T:
> case MODE_EL3H:
> flat_idx = MISCREG_SPSR_EL3;
> break;
159c307
< spsr_idx = MISCREG_SPSR;
---
> flat_idx = MISCREG_SPSR;
162c310
< spsr_idx = MISCREG_SPSR_FIQ;
---
> flat_idx = MISCREG_SPSR_FIQ;
165c313
< spsr_idx = MISCREG_SPSR_IRQ;
---
> flat_idx = MISCREG_SPSR_IRQ;
168c316
< spsr_idx = MISCREG_SPSR_SVC;
---
> flat_idx = MISCREG_SPSR_SVC;
171c319
< spsr_idx = MISCREG_SPSR_MON;
---
> flat_idx = MISCREG_SPSR_MON;
174c322
< spsr_idx = MISCREG_SPSR_ABT;
---
> flat_idx = MISCREG_SPSR_ABT;
175a324,326
> case MODE_HYP:
> flat_idx = MISCREG_SPSR_HYP;
> break;
177c328
< spsr_idx = MISCREG_SPSR_UND;
---
> flat_idx = MISCREG_SPSR_UND;
182c333
< spsr_idx = MISCREG_SPSR;
---
> flat_idx = MISCREG_SPSR;
185c336,390
< return spsr_idx;
---
> } else if (miscRegInfo[reg][MISCREG_MUTEX]) {
> // Mutually exclusive CP15 register
> switch (reg) {
> case MISCREG_PRRR_MAIR0:
> case MISCREG_PRRR_MAIR0_NS:
> case MISCREG_PRRR_MAIR0_S:
> {
> TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
> // If the muxed reg has been flattened, work out the
> // offset and apply it to the unmuxed reg
> int idxOffset = reg - MISCREG_PRRR_MAIR0;
> if (ttbcr.eae)
> flat_idx = flattenMiscIndex(MISCREG_MAIR0 +
> idxOffset);
> else
> flat_idx = flattenMiscIndex(MISCREG_PRRR +
> idxOffset);
> }
> break;
> case MISCREG_NMRR_MAIR1:
> case MISCREG_NMRR_MAIR1_NS:
> case MISCREG_NMRR_MAIR1_S:
> {
> TTBCR ttbcr = readMiscRegNoEffect(MISCREG_TTBCR);
> // If the muxed reg has been flattened, work out the
> // offset and apply it to the unmuxed reg
> int idxOffset = reg - MISCREG_NMRR_MAIR1;
> if (ttbcr.eae)
> flat_idx = flattenMiscIndex(MISCREG_MAIR1 +
> idxOffset);
> else
> flat_idx = flattenMiscIndex(MISCREG_NMRR +
> idxOffset);
> }
> break;
> case MISCREG_PMXEVTYPER_PMCCFILTR:
> {
> PMSELR pmselr = miscRegs[MISCREG_PMSELR];
> if (pmselr.sel == 31)
> flat_idx = flattenMiscIndex(MISCREG_PMCCFILTR);
> else
> flat_idx = flattenMiscIndex(MISCREG_PMXEVTYPER);
> }
> break;
> default:
> panic("Unrecognized misc. register.\n");
> break;
> }
> } else {
> if (miscRegInfo[reg][MISCREG_BANKED]) {
> bool secureReg = haveSecurity &&
> inSecureState(miscRegs[MISCREG_SCR],
> miscRegs[MISCREG_CPSR]);
> flat_idx += secureReg ? 2 : 1;
> }
187c392
< return reg;
---
> return flat_idx;
193a399,404
>
> SERIALIZE_SCALAR(haveSecurity);
> SERIALIZE_SCALAR(haveLPAE);
> SERIALIZE_SCALAR(haveVirtualization);
> SERIALIZE_SCALAR(haveLargeAsid64);
> SERIALIZE_SCALAR(physAddrRange64);
200a412,417
>
> UNSERIALIZE_SCALAR(haveSecurity);
> UNSERIALIZE_SCALAR(haveLPAE);
> UNSERIALIZE_SCALAR(haveVirtualization);
> UNSERIALIZE_SCALAR(haveLargeAsid64);
> UNSERIALIZE_SCALAR(physAddrRange64);