From: Jordi Vaquero Date: Tue, 14 Jul 2020 09:54:30 +0000 (+0200) Subject: arch-arm: Implementing SecureEL2 feature for Armv8 X-Git-Tag: v20.1.0.0~357 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bd25fc971df317f17ea39f46e3f515a26b43ddaa;p=gem5.git arch-arm: Implementing SecureEL2 feature for Armv8 This patch adds Secure EL2 feature. This allows stage1 EL2/EL&0 and stage2 secure translation. The changes are organized as follow: + insts/static_inst.cc: Modify checks for illegalInstruction on eret + isa.cc/hh: Enabling contorl bits + isa/insts/misc.hh/64.hh: Smc fault trigger. + miscregs.cc/hh: Declaration and initialization of new registers + self_debug.cc/hh: Add secureEL2 types for breakpoints + stage2_lookup.cc/hh: Allow stage2 in secure state. + tlb.cc/table_walker.cc: Allow secure state for stage2 and stage 1 EL2&0 translation regime + utility.cc/hh: New function InSecure and refactor of other helpers to enable secure state JIRA: https://gem5.atlassian.net/browse/GEM5-686 Change-Id: Ie59438b1828508e944334420da1d8f4745649056 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31394 Reviewed-by: Giacomo Travaglini Maintainer: Giacomo Travaglini Tested-by: kokoro --- diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py index c4cc51fbf..333ae5f31 100644 --- a/src/arch/arm/ArmSystem.py +++ b/src/arch/arm/ArmSystem.py @@ -75,6 +75,8 @@ class ArmSystem(System): "True if LSE is implemented (ARMv8.1)") have_pan = Param.Bool(True, "True if Priviledge Access Never is implemented (ARMv8.1)") + have_secel2 = Param.Bool(True, + "True if Secure EL2 is implemented (ARMv8)") semihosting = Param.ArmSemihosting(NULL, "Enable support for the Arm semihosting by settings this parameter") diff --git a/src/arch/arm/fastmodel/CortexA76/thread_context.cc b/src/arch/arm/fastmodel/CortexA76/thread_context.cc index 4016d2bf1..4e2bfd22a 100644 --- a/src/arch/arm/fastmodel/CortexA76/thread_context.cc +++ b/src/arch/arm/fastmodel/CortexA76/thread_context.cc @@ -59,7 +59,7 @@ CortexA76TC::translateAddress(Addr &paddr, Addr vaddr) break; } - Iris::CanonicalMsn out_msn = inSecureState(this) ? + Iris::CanonicalMsn out_msn = isSecure(this) ? Iris::PhysicalMemorySecureMsn : Iris::PhysicalMemoryNonSecureMsn; // Figure out what memory spaces match the canonical numbers we need. diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 40cf6341c..300c82c2f 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -977,10 +977,12 @@ ArmFaultVals::offset64(ThreadContext *tc) } else { bool lower_32 = false; if (toEL == EL3) { - if (!inSecureState(tc) && ArmSystem::haveEL(tc, EL2)) + if (EL2Enabled(tc)) lower_32 = ELIs32(tc, EL2); else lower_32 = ELIs32(tc, EL1); + } else if (ELIsInHost(tc, fromEL) && fromEL == EL0 && toEL == EL2) { + lower_32 = ELIs32(tc, EL0); } else { lower_32 = ELIs32(tc, static_cast(toEL - 1)); } @@ -1310,7 +1312,7 @@ PrefetchAbort::routeToHyp(ThreadContext *tc) const HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); toHyp = fromEL == EL2; - toHyp |= ArmSystem::haveEL(tc, EL2) && !inSecureState(tc) && + toHyp |= ArmSystem::haveEL(tc, EL2) && !isSecure(tc) && currEL(tc) <= EL1 && (hcr.tge || stage2 || (source == DebugEvent && hdcr.tde)); return toHyp; diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index 0cbd77645..12586c756 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -634,9 +634,8 @@ ArmStaticInst::softwareBreakpoint32(ExecContext *xc, uint16_t imm) const const auto tc = xc->tcBase(); const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2); - if ((ArmSystem::haveEL(tc, EL2) && !inSecureState(tc) && - !ELIs32(tc, EL2) && (hcr.tge == 1 || mdcr.tde == 1)) || - !ELIs32(tc, EL1)) { + if ((EL2Enabled(tc) && !ELIs32(tc, EL2) && + (hcr.tge || mdcr.tde)) || !ELIs32(tc, EL1)) { // Route to AArch64 Software Breakpoint return std::make_shared(machInst, imm); } else { @@ -728,7 +727,7 @@ ArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc, { const bool have_virtualization = ArmSystem::haveVirtualization(tc); const bool have_security = ArmSystem::haveSecurity(tc); - const bool is_secure = inSecureState(tc); + const bool is_secure = isSecure(tc); const ExceptionLevel cur_el = currEL(tc); if (cur_el == EL0 && ELIs64(tc, EL1)) @@ -908,8 +907,7 @@ ArmStaticInst::trapWFx(ThreadContext *tc, fault = checkForWFxTrap32(tc, EL1, isWfe); } - if ((fault == NoFault) && - ArmSystem::haveEL(tc, EL2) && !inSecureState(scr, cpsr) && + if ((fault == NoFault) && EL2Enabled(tc) && ((curr_el == EL0) || (curr_el == EL1))) { fault = checkForWFxTrap32(tc, EL2, isWfe); @@ -945,7 +943,7 @@ ArmStaticInst::checkSETENDEnabled(ThreadContext *tc, CPSR cpsr) const // Get the index of the banked version of SCTLR: // SCTLR_s or SCTLR_ns. auto banked_sctlr = snsBankedIndex( - MISCREG_SCTLR, tc, !inSecureState(tc)); + MISCREG_SCTLR, tc, !isSecure(tc)); // SCTLR.SED bit is enabling/disabling the ue of SETEND instruction. setend_disabled = ((SCTLR)tc->readMiscRegNoEffect(banked_sctlr)).sed; @@ -1097,22 +1095,34 @@ illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr) if (unknownMode(mode)) return true; - const OperatingMode cur_mode = (OperatingMode) (uint8_t)cpsr.mode; - const ExceptionLevel target_el = opModeToEL(mode); + SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); + HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2)); - SCR scr = ((SCR)tc->readMiscReg(MISCREG_SCR_EL3)); - - if (target_el > opModeToEL(cur_mode)) - return true; - - if (!ArmSystem::haveEL(tc, target_el)) - return true; - - if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && scr.ns && hcr.tge) + //ELFromSPSR + bool valid; + ExceptionLevel target_el = opModeToEL(mode); + if (!spsr.width) { + if (!ArmSystem::highestELIs64(tc)) { + valid = false; + } else if (!ArmSystem::haveEL(tc, target_el)) { + valid = false; + } else if (spsr & 0x2) { + valid = false; + } else if (target_el == EL0 && spsr.sp) { + valid = false; + } else if (target_el == EL2 && ArmSystem::haveEL(tc, EL3) && + !scr.ns && !IsSecureEL2Enabled(tc)) { + valid = false; + } else { + valid = true; + } + } else { + valid = !unknownMode32(mode); + } + if (!valid) return true; - if (target_el == EL2 && ArmSystem::haveEL(tc, EL3) && !scr.ns) + if (target_el > currEL(tc)) return true; bool spsr_mode_is_aarch32 = (spsr.width == 1); @@ -1123,17 +1133,9 @@ illegalExceptionReturn(ThreadContext *tc, CPSR cpsr, CPSR spsr) if (known && (spsr_mode_is_aarch32 != target_el_is_aarch32)) return true; - if (!spsr.width) { - // aarch64 - if (!ArmSystem::highestELIs64(tc)) - return true; - if (spsr & 0x2) - return true; - if (target_el == EL0 && spsr.sp) - return true; - } else { - // aarch32 - return unknownMode32(mode); + if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && hcr.tge && + (IsSecureEL2Enabled(tc) || !isSecureBelowEL3(tc))) { + return true; } return false; @@ -1206,7 +1208,7 @@ ArmStaticInst::generalExceptionsToAArch64(ThreadContext *tc, // AArch64 or TGE is in force and EL2 is using AArch64. HCR hcr = ((HCR)tc->readMiscReg(MISCREG_HCR_EL2)); return (pstateEL == EL0 && !ELIs32(tc, EL1)) || - (ArmSystem::haveEL(tc, EL2) && !inSecureState(tc) && + (ArmSystem::haveEL(tc, EL2) && !isSecure(tc) && !ELIs32(tc, EL2) && hcr.tge); } diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index 8610f996f..2677a105c 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -214,8 +214,7 @@ class ArmStaticInst : public StaticInst { bool privileged = (cpsr.mode != MODE_USER); bool haveVirt = ArmSystem::haveVirtualization(tc); - bool haveSecurity = ArmSystem::haveSecurity(tc); - bool isSecure = inSecureState(scr, cpsr) || !haveSecurity; + bool isSecure = ArmISA::isSecure(tc); uint32_t bitMask = 0; diff --git a/src/arch/arm/interrupts.cc b/src/arch/arm/interrupts.cc index ae1d4357d..13c281e4d 100644 --- a/src/arch/arm/interrupts.cc +++ b/src/arch/arm/interrupts.cc @@ -64,7 +64,7 @@ ArmISA::Interrupts::takeInt(InterruptTypes int_type) const else scr = tc->readMiscReg(MISCREG_SCR_EL3); - bool is_secure = inSecureState(tc); + bool is_secure = isSecure(tc); switch(int_type) { case INT_FIQ: diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh index 99a149264..695fd3986 100644 --- a/src/arch/arm/interrupts.hh +++ b/src/arch/arm/interrupts.hh @@ -145,7 +145,7 @@ class Interrupts : public BaseInterrupts } bool isHypMode = currEL(tc) == EL2; - bool isSecure = inSecureState(tc); + bool isSecure = ArmISA::isSecure(tc); bool allowVIrq = !cpsr.i && imo && !isSecure && !isHypMode; bool allowVFiq = !cpsr.f && fmo && !isSecure && !isHypMode; bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode; @@ -185,7 +185,7 @@ class Interrupts : public BaseInterrupts virtWake = (hcr.vi || interrupts[INT_VIRT_IRQ]) && hcr.imo; virtWake |= (hcr.vf || interrupts[INT_VIRT_FIQ]) && hcr.fmo; virtWake |= hcr.va && hcr.amo; - virtWake &= (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr); + virtWake &= (cpsr.mode != MODE_HYP) && !isSecure(tc); return maskedIntStatus || virtWake; } @@ -195,7 +195,7 @@ class Interrupts : public BaseInterrupts bool useHcrMux; CPSR isr = 0; // ARM ARM states ISR reg uses same bit possitions as CPSR - useHcrMux = (cpsr.mode != MODE_HYP) && !inSecureState(scr, cpsr); + useHcrMux = (cpsr.mode != MODE_HYP) && !isSecure(tc); isr.i = (useHcrMux & hcr.imo) ? (interrupts[INT_VIRT_IRQ] || hcr.vi) : interrupts[INT_IRQ]; isr.f = (useHcrMux & hcr.fmo) ? (interrupts[INT_VIRT_FIQ] || hcr.vf) @@ -247,7 +247,7 @@ class Interrupts : public BaseInterrupts // virtual interrupt, and if its allowed to happen // ARM ARM Issue C section B1.9.9, B1.9.11, and B1.9.13 bool isHypMode = currEL(tc) == EL2; - bool isSecure = inSecureState(tc); + bool isSecure = ArmISA::isSecure(tc); bool allowVIrq = !cpsr.i && imo && !isSecure && !isHypMode; bool allowVFiq = !cpsr.f && fmo && !isSecure && !isHypMode; bool allowVAbort = !cpsr.a && amo && !isSecure && !isHypMode; diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index b71ee6384..9106b433d 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -88,6 +88,7 @@ ISA::ISA(Params *p) : BaseISA(p), system(NULL), physAddrRange = system->physAddrRange(); haveSVE = system->haveSVE(); havePAN = system->havePAN(); + haveSecEL2 = system->haveSecEL2(); sveVL = system->sveVL(); haveLSE = system->haveLSE(); } else { @@ -98,6 +99,7 @@ ISA::ISA(Params *p) : BaseISA(p), system(NULL), physAddrRange = 32; // dummy value haveSVE = true; havePAN = false; + haveSecEL2 = true; sveVL = p->sve_vl_se; haveLSE = true; } @@ -397,6 +399,13 @@ ISA::initID64(const ArmISAParams *p) miscRegs[MISCREG_ID_AA64PFR0_EL1] = insertBits( miscRegs[MISCREG_ID_AA64PFR0_EL1], 35, 32, haveSVE ? 0x1 : 0x0); + // SecEL2 + miscRegs[MISCREG_ID_AA64PFR0_EL1] = insertBits( + miscRegs[MISCREG_ID_AA64PFR0_EL1], 39, 36, + haveSecEL2 ? 0x1 : 0x0); + miscRegs[MISCREG_ID_AA64ISAR0_EL1] = insertBits( + miscRegs[MISCREG_ID_AA64ISAR0_EL1], 39, 36, + haveSecEL2 ? 0x1 : 0x0); // Large ASID support miscRegs[MISCREG_ID_AA64MMFR0_EL1] = insertBits( miscRegs[MISCREG_ID_AA64MMFR0_EL1], 7, 4, @@ -554,7 +563,7 @@ ISA::readMiscReg(int misc_reg) case MISCREG_MIDR: cpsr = readMiscRegNoEffect(MISCREG_CPSR); scr = readMiscRegNoEffect(MISCREG_SCR); - if ((cpsr.mode == MODE_HYP) || inSecureState(scr, cpsr)) { + if ((cpsr.mode == MODE_HYP) || isSecure(tc)) { return readMiscRegNoEffect(misc_reg); } else { return readMiscRegNoEffect(MISCREG_VPIDR); @@ -731,9 +740,7 @@ ISA::readMiscReg(int misc_reg) val &= ~(1 << 14); // If a CP bit in NSACR is 0 then the corresponding bit in // HCPTR is RAO/WI - bool secure_lookup = haveSecurity && - inSecureState(readMiscRegNoEffect(MISCREG_SCR), - readMiscRegNoEffect(MISCREG_CPSR)); + bool secure_lookup = haveSecurity && isSecure(tc); if (!secure_lookup) { RegVal mask = readMiscRegNoEffect(MISCREG_NSACR); val |= (mask ^ 0x7FFF) & 0xBFFF; @@ -764,6 +771,7 @@ ISA::readMiscReg(int misc_reg) (haveVirtualization ? 0x0000000000000200 : 0) | // EL2 (haveSecurity ? 0x0000000000002000 : 0) | // EL3 (haveSVE ? 0x0000000100000000 : 0) | // SVE + (haveSecEL2 ? 0x0000001000000000 : 0) | // SecEL2 (gicv3CpuInterface ? 0x0000000001000000 : 0); case MISCREG_ID_AA64PFR1_EL1: return 0; // bits [63:0] RES0 (reserved for future use) @@ -1968,9 +1976,7 @@ ISA::setMiscReg(int misc_reg, RegVal val) { // If a CP bit in NSACR is 0 then the corresponding bit in // HCPTR is RAO/WI. Same applies to NSASEDIS - secure_lookup = haveSecurity && - inSecureState(readMiscRegNoEffect(MISCREG_SCR), - readMiscRegNoEffect(MISCREG_CPSR)); + secure_lookup = haveSecurity && isSecure(tc); if (!secure_lookup) { RegVal oldValue = readMiscRegNoEffect(MISCREG_HCPTR); RegVal mask = @@ -2464,7 +2470,7 @@ ISA::getCurSveVecLenInBits() const if (el == EL2 || (el == EL0 && ELIsInHost(tc, el))) { len = static_cast(miscRegs[MISCREG_ZCR_EL2]).len; - } else if (haveVirtualization && !inSecureState(tc) && + } else if (haveVirtualization && !isSecure(tc) && (el == EL0 || el == EL1)) { len = std::min( len, diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 00c29bc77..3b90de134 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -95,6 +95,7 @@ namespace ArmISA bool haveSVE; bool haveLSE; bool havePAN; + bool haveSecEL2; /** SVE vector length in quadwords */ unsigned sveVL; @@ -695,7 +696,7 @@ namespace ArmISA if (hcr.e2h == 0x0 || currEL(tc) != EL2) return misc_reg; SCR scr = readMiscRegNoEffect(MISCREG_SCR_EL3); - bool sec_el2 = scr.eel2 && false; + bool sec_el2 = scr.eel2 && haveSecEL2; switch(misc_reg) { case MISCREG_SPSR_EL1: return MISCREG_SPSR_EL2; diff --git a/src/arch/arm/isa/insts/branch.isa b/src/arch/arm/isa/insts/branch.isa index f61d0c56a..0928e66e5 100644 --- a/src/arch/arm/isa/insts/branch.isa +++ b/src/arch/arm/isa/insts/branch.isa @@ -151,11 +151,10 @@ let {{ bxjcode = ''' HSTR hstr = Hstr; CPSR cpsr = Cpsr; - SCR scr = Scr; if (ArmSystem::haveVirtualization(xc->tcBase()) && hstr.tjdbx && - !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { - fault = std::make_shared(machInst, op1, EC_TRAPPED_BXJ); + !isSecure(xc->tcBase()) && (cpsr.mode != MODE_HYP)) { + fault = std::make_shared(machInst, op1, EC_TRAPPED_BXJ); } IWNPC = Op1; ''' diff --git a/src/arch/arm/isa/insts/fp.isa b/src/arch/arm/isa/insts/fp.isa index 9e94b86d2..52b53158c 100644 --- a/src/arch/arm/isa/insts/fp.isa +++ b/src/arch/arm/isa/insts/fp.isa @@ -210,8 +210,7 @@ let {{ vmrsCode = vmrsEnabledCheckCode + ''' CPSR cpsr = Cpsr; - SCR scr = Scr; - if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) { + if (!isSecure(xc->tcBase()) && (cpsr.mode != MODE_HYP)) { HCR hcr = Hcr; bool hypTrap = false; switch(xc->tcBase()->flattenRegId(RegId(MiscRegClass, op1)).index()) { diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 64bf791d5..3ee0d618f 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -95,8 +95,7 @@ let {{ SCR scr = Scr; if ((cpsr.mode != MODE_USER) && FullSystem) { - if (ArmSystem::haveVirtualization(xc->tcBase()) && - !inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP) && hcr.tsc) { + if (EL2Enabled(xc->tcBase()) && (cpsr.mode != MODE_HYP) && hcr.tsc) { fault = std::make_shared(machInst, 0, EC_SMC_TO_HYP); } else { @@ -121,12 +120,11 @@ let {{ hvcCode = ''' CPSR cpsr = Cpsr; - SCR scr = Scr; // Filter out the various cases where this instruction isn't defined if (!FullSystem || !ArmSystem::haveVirtualization(xc->tcBase()) || (cpsr.mode == MODE_USER) || - (ArmSystem::haveSecurity(xc->tcBase()) && (!scr.ns || !scr.hce))) { + (isSecure(xc->tcBase()) && !IsSecureEL2Enabled(xc->tcBase()))) { fault = disabledFault(); } else { fault = std::make_shared(machInst, imm); @@ -936,7 +934,7 @@ let {{ // the register is accessable, in other modes we trap if only if the register // IS accessable. if (undefined || (!can_read && !(fault != NoFault && !inUserMode(Cpsr) && - !inSecureState(Scr, Cpsr)))) { + !isSecure(xc->tcBase())))) { return std::make_shared(machInst, false, mnemonic); } @@ -970,7 +968,7 @@ let {{ // the register is accessable, in other modes we trap if only if the register // IS accessable. if (undefined || (!can_write && !(fault != NoFault && !inUserMode(Cpsr) && - !inSecureState(Scr, Cpsr)))) { + !isSecure(xc->tcBase())))) { return std::make_shared(machInst, false, mnemonic); } @@ -1003,7 +1001,7 @@ let {{ // the register is accessable, in other modes we trap if only if the register // IS accessable. if (undefined || (!can_read && !(fault != NoFault && !inUserMode(Cpsr) && - !inSecureState(Scr, Cpsr)))) { + !isSecure(xc->tcBase())))) { return std::make_shared(machInst, false, mnemonic); } @@ -1037,7 +1035,7 @@ let {{ // the register is accessable, in other modes we trap if only if the register // IS accessable. if (undefined || (!can_write && !(fault != NoFault && !inUserMode(Cpsr) && - !inSecureState(Scr, Cpsr)))) { + !isSecure(xc->tcBase())))) { return std::make_shared(machInst, false, mnemonic); } @@ -1115,7 +1113,7 @@ let {{ // of whether the register is accessible, in other modes we // trap if only if the register IS accessible. if (undefined || (!can_write & !(hypTrap & !inUserMode(Cpsr) & - !inSecureState(Scr, Cpsr)))) { + !isSecure(xc->tcBase())))) { return std::make_shared(machInst, false, mnemonic); } diff --git a/src/arch/arm/isa/insts/misc64.isa b/src/arch/arm/isa/insts/misc64.isa index 656a23445..a8a8be6aa 100644 --- a/src/arch/arm/isa/insts/misc64.isa +++ b/src/arch/arm/isa/insts/misc64.isa @@ -56,7 +56,8 @@ let {{ ExceptionLevel pstate_EL = (ExceptionLevel)(uint8_t)(cpsr.el); bool unalloc_encod = !ArmSystem::haveEL(tc, EL2) || pstate_EL == EL0 || - (pstate_EL == EL1 && inSecureState(tc)); + (pstate_EL == EL1 && (!IsSecureEL2Enabled(tc) && + isSecure(tc))); bool hvc_enable = ArmSystem::haveEL(tc, EL3) ? scr.hce : !hcr.hcd; diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc index 5aa5adab2..932abc391 100644 --- a/src/arch/arm/miscregs.cc +++ b/src/arch/arm/miscregs.cc @@ -2356,6 +2356,14 @@ decodeAArch64SysReg(unsigned op0, unsigned op1, return MISCREG_VTCR_EL2; } break; + case 6: + switch (op2) { + case 0: + return MISCREG_VSTTBR_EL2; + case 2: + return MISCREG_VSTCR_EL2; + } + break; } break; case 5: @@ -4880,6 +4888,10 @@ ISA::initializeMiscRegMetadata() InitReg(MISCREG_VTCR_EL2) .hyp().mon() .mapsTo(MISCREG_VTCR); + InitReg(MISCREG_VSTTBR_EL2) + .hyp().mon(); + InitReg(MISCREG_VSTCR_EL2) + .hyp().mon(); InitReg(MISCREG_TTBR0_EL3) .mon(); InitReg(MISCREG_TCR_EL3) diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 5b09f3407..f683297a1 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -596,6 +596,8 @@ namespace ArmISA MISCREG_TCR_EL2, MISCREG_VTTBR_EL2, MISCREG_VTCR_EL2, + MISCREG_VSTTBR_EL2, + MISCREG_VSTCR_EL2, MISCREG_TTBR0_EL3, MISCREG_TCR_EL3, MISCREG_DACR32_EL2, @@ -1695,6 +1697,8 @@ namespace ArmISA "tcr_el2", "vttbr_el2", "vtcr_el2", + "vsttbr_el2", + "vstcr_el2", "ttbr0_el3", "tcr_el3", "dacr32_el2", diff --git a/src/arch/arm/self_debug.cc b/src/arch/arm/self_debug.cc index 790e04bf6..ef6ad6322 100644 --- a/src/arch/arm/self_debug.cc +++ b/src/arch/arm/self_debug.cc @@ -165,7 +165,7 @@ SelfDebug::isDebugEnabledForEL64(ThreadContext *tc, ExceptionLevel el, bool secure, bool mask) { bool route_to_el2 = ArmSystem::haveEL(tc, EL2) && - !secure && enableTdeTge; + (!secure || HaveSecureEL2Ext(tc)) && enableTdeTge; ExceptionLevel target_el = route_to_el2 ? EL2 : EL1; if (oslk || (bSDD && secure && ArmSystem::haveEL(tc, EL3))) { @@ -269,53 +269,53 @@ BrkPoint::test(ThreadContext *tc, Addr pc, ExceptionLevel el, DBGBCR ctr, break; case 0x8: - if (ArmSystem::haveEL(tc, EL2) && !ELIsInHost(tc, el)) { + if (EL2Enabled(tc) && !ELIsInHost(tc, el)) { v = testVMIDMatch(tc); } break; case 0x9: - if (from_link && ArmSystem::haveEL(tc, EL2) && - !ELIsInHost(tc, el)) { + if (from_link && EL2Enabled(tc) && !ELIsInHost(tc, el)) { v = testVMIDMatch(tc); } break; case 0xa: - if (ArmSystem::haveEL(tc, EL2) && !ELIsInHost(tc, el)) { + if (EL2Enabled(tc) && !ELIsInHost(tc, el)) { v = testContextMatch(tc, true); if (v && !from_link) v = v && testVMIDMatch(tc); } break; case 0xb: - if (from_link && ArmSystem::haveEL(tc, EL2) && - !ELIsInHost(tc, el)) { + if (from_link && EL2Enabled(tc) && !ELIsInHost(tc, el)) { v = testContextMatch(tc, true); v = v && testVMIDMatch(tc); } break; case 0xc: - if (HaveVirtHostExt(tc) && !inSecureState(tc)) + if (HaveVirtHostExt(tc) && (!isSecure(tc)|| HaveSecureEL2Ext(tc))) v = testContextMatch(tc, false); break; case 0xd: - if (HaveVirtHostExt(tc) && from_link && !inSecureState(tc)) - v = testContextMatch(tc, false); + if (HaveVirtHostExt(tc) && from_link && + (!isSecure(tc)|| HaveSecureEL2Ext(tc))) { + v = testContextMatch(tc, false); + } break; case 0xe: - if (HaveVirtHostExt(tc) && !ELIsInHost(tc, el) - && !inSecureState(tc) ) { + if (HaveVirtHostExt(tc) && !ELIsInHost(tc, el) && + (!isSecure(tc)|| HaveSecureEL2Ext(tc))) { v = testContextMatch(tc, true); // CONTEXTIDR_EL1 v = v && testContextMatch(tc, false); // CONTEXTIDR_EL2 } break; case 0xf: - if (HaveVirtHostExt(tc) && !ELIsInHost(tc, el) && from_link - && !inSecureState(tc) ) { + if (HaveVirtHostExt(tc) && !ELIsInHost(tc, el) && from_link && + (!isSecure(tc)|| HaveSecureEL2Ext(tc))) { v = testContextMatch(tc, true); // CONTEXTIDR_EL1 v = v && testContextMatch(tc, false); // CONTEXTIDR_EL2 } @@ -652,8 +652,9 @@ SoftwareStep::debugExceptionReturnSS(ThreadContext *tc, CPSR spsr, bool enabled_dst = false; bool secure = isSecureBelowEL3(tc) || dest == EL3; - CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); - if (cpsr.width) { +// CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); +// if (cpsr.width) { + if (ELIs32(tc, dest)) { enabled_dst = conf->isDebugEnabledForEL32(tc, dest, secure, spsr.d == 1); } else { @@ -760,7 +761,7 @@ VectorCatch::addressMatching(ThreadContext *tc, Addr addr, ExceptionLevel el) Addr vaddress = addr & ~ 0x1f; Addr low_addr = bits(addr, 5, 2); if (vaddress == vbase) { - if (ArmSystem::haveEL(tc, EL3) && !inSecureState(tc)) { + if (ArmSystem::haveEL(tc, EL3) && !isSecure(tc)) { uint32_t bmask = 1UL << (low_addr + 24); match_word = match_word | (DBGVCR) bmask; // Non-secure vectors @@ -772,7 +773,7 @@ VectorCatch::addressMatching(ThreadContext *tc, Addr addr, ExceptionLevel el) } uint32_t mvbase = getVectorBase(tc, true); if (ArmSystem::haveEL(tc, EL3) && ELIs32(tc, EL3) && - inSecureState(tc) && (vaddress == mvbase)) { + isSecure(tc) && (vaddress == mvbase)) { uint32_t bmask = 1UL << (low_addr + 8); match_word = match_word | (DBGVCR) bmask; // Monitor vectors @@ -793,7 +794,7 @@ VectorCatch::addressMatching(ThreadContext *tc, Addr addr, ExceptionLevel el) enabled = match_word != 0x0; // Check for UNPREDICTABLE case - match on Prefetch Abort and // Data Abort vectors - ExceptionLevel ELd = debugTargetFrom(tc, inSecureState(tc)); + ExceptionLevel ELd = debugTargetFrom(tc, isSecure(tc)); if (((match_word & 0x18001818) != 0x0) && ELd == el) { enabled = false; } @@ -818,7 +819,7 @@ VectorCatch::exceptionTrapping(ThreadContext *tc, ExceptionLevel el, } else if (ELIs32(tc, EL3) && fault->getToMode() == MODE_MON) { mask = (DBGVCR) 0x0000DE00; } else { - if (inSecureState(tc)) + if (isSecure(tc)) mask = (DBGVCR) 0x000000DE; else mask = (DBGVCR) 0xDE000000; diff --git a/src/arch/arm/self_debug.hh b/src/arch/arm/self_debug.hh index a1c03eafd..953a2dcda 100644 --- a/src/arch/arm/self_debug.hh +++ b/src/arch/arm/self_debug.hh @@ -341,11 +341,11 @@ class SelfDebug { switch (ssc) { case 0x0: return true; - case 0x1: return !inSecureState(tc); - case 0x2: return inSecureState(tc); + case 0x1: return !isSecure(tc); + case 0x2: return isSecure(tc); case 0x3: { - bool b = hmc? true: inSecureState(tc); + bool b = hmc? true: isSecure(tc); return b; } default: panic("Unreachable value"); @@ -372,10 +372,10 @@ class SelfDebug CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); ExceptionLevel el = (ExceptionLevel) currEL(tc); if (aarch32) { - return isDebugEnabledForEL32(tc, el, inSecureState(tc), + return isDebugEnabledForEL32(tc, el, isSecure(tc), (bool)cpsr.d == 1); } else { - return isDebugEnabledForEL64(tc, el, inSecureState(tc), + return isDebugEnabledForEL64(tc, el, isSecure(tc), (bool)cpsr.d == 1 ); } } @@ -464,7 +464,7 @@ class SelfDebug bool targetAArch32(ThreadContext *tc) { - ExceptionLevel ELd = debugTargetFrom(tc, inSecureState(tc)); + ExceptionLevel ELd = debugTargetFrom(tc, isSecure(tc)); return ELIs32(tc, ELd) && aarch32; } diff --git a/src/arch/arm/semihosting.cc b/src/arch/arm/semihosting.cc index ab21dda1f..bd7b617cf 100644 --- a/src/arch/arm/semihosting.cc +++ b/src/arch/arm/semihosting.cc @@ -244,7 +244,7 @@ ArmSemihosting::portProxy(ThreadContext *tc) static std::unique_ptr port_proxy_s; static System *secure_sys = nullptr; - if (ArmISA::inSecureState(tc)) { + if (ArmISA::isSecure(tc)) { System *sys = tc->getSystemPtr(); if (sys != secure_sys) { if (FullSystem) { diff --git a/src/arch/arm/stage2_lookup.cc b/src/arch/arm/stage2_lookup.cc index 0fe8edd63..93843ab43 100644 --- a/src/arch/arm/stage2_lookup.cc +++ b/src/arch/arm/stage2_lookup.cc @@ -55,7 +55,7 @@ Stage2LookUp::getTe(ThreadContext *tc, TlbEntry *destTe) { fault = stage2Tlb->getTE(&stage2Te, req, tc, mode, this, timing, - functional, false, tranType); + functional, secure, tranType); // Call finish if we're done already if ((fault != NoFault) || (stage2Te != NULL)) { // Since we directly requested the table entry (which we need later on @@ -180,7 +180,7 @@ Stage2LookUp::finish(const Fault &_fault, const RequestPtr &req, // if we haven't got the table entry get it now if ((fault == NoFault) && (stage2Te == NULL)) { fault = stage2Tlb->getTE(&stage2Te, req, tc, mode, this, - timing, functional, false, tranType); + timing, functional, secure, tranType); } // Now we have the stage 2 table entry we need to merge it with the stage diff --git a/src/arch/arm/stage2_lookup.hh b/src/arch/arm/stage2_lookup.hh index a9b014a92..a5a984f9a 100644 --- a/src/arch/arm/stage2_lookup.hh +++ b/src/arch/arm/stage2_lookup.hh @@ -69,15 +69,16 @@ class Stage2LookUp : public BaseTLB::Translation Fault fault; bool complete; bool selfDelete; + bool secure; public: Stage2LookUp(TLB *s1Tlb, TLB *s2Tlb, TlbEntry s1Te, const RequestPtr &_req, TLB::Translation *_transState, BaseTLB::Mode _mode, bool _timing, - bool _functional, TLB::ArmTranslationType _tranType) : + bool _functional, bool _secure, TLB::ArmTranslationType _tranType) : stage1Tlb(s1Tlb), stage2Tlb(s2Tlb), stage1Te(s1Te), s1Req(_req), transState(_transState), mode(_mode), timing(_timing), functional(_functional), tranType(_tranType), stage2Te(nullptr), - fault(NoFault), complete(false), selfDelete(false) + fault(NoFault), complete(false), selfDelete(false), secure(_secure) { req = std::make_shared(); req->setVirt(s1Te.pAddr(s1Req->getVaddr()), s1Req->getSize(), diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc index 8eb37b7b3..3db13d724 100644 --- a/src/arch/arm/system.cc +++ b/src/arch/arm/system.cc @@ -70,6 +70,7 @@ ArmSystem::ArmSystem(Params *p) _sveVL(p->sve_vl), _haveLSE(p->have_lse), _havePAN(p->have_pan), + _haveSecEL2(p->have_secel2), semihosting(p->semihosting), multiProc(p->multi_proc) { diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh index 203be1aff..cffc23586 100644 --- a/src/arch/arm/system.hh +++ b/src/arch/arm/system.hh @@ -128,6 +128,9 @@ class ArmSystem : public System /** True if Priviledge Access Never is implemented */ const unsigned _havePAN; + /** True if Secure EL2 is implemented */ + const unsigned _haveSecEL2; + /** * True if the Semihosting interface is enabled. */ @@ -223,6 +226,9 @@ class ArmSystem : public System /** Returns true if Priviledge Access Never is implemented */ bool havePAN() const { return _havePAN; } + /** Returns true if Priviledge Access Never is implemented */ + bool haveSecEL2() const { return _haveSecEL2; } + /** Returns the supported physical address range in bits if the highest * implemented exception level is 64 bits (ARMv8) */ uint8_t physAddrRange64() const { return _physAddrRange64; } diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index aa3dbf6e2..77f280044 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -267,7 +267,13 @@ TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid, currState->hcr = currState->tc->readMiscReg(MISCREG_HCR_EL2); if (isStage2) { currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1); - currState->vtcr = currState->tc->readMiscReg(MISCREG_VTCR_EL2); + if (currState->secureLookup) { + currState->vtcr = + currState->tc->readMiscReg(MISCREG_VSTCR_EL2); + } else { + currState->vtcr = + currState->tc->readMiscReg(MISCREG_VTCR_EL2); + } } else switch (currState->el) { case EL0: if (HaveVirtHostExt(currState->tc) && @@ -825,8 +831,13 @@ TableWalker::processWalkAArch64() break; case EL1: if (isStage2) { - DPRINTF(TLB, " - Selecting VTTBR0 (AArch64 stage 2)\n"); - ttbr = currState->tc->readMiscReg(MISCREG_VTTBR_EL2); + if (currState->secureLookup) { + DPRINTF(TLB, " - Selecting VSTTBR_EL2 (AArch64 stage 2)\n"); + ttbr = currState->tc->readMiscReg(MISCREG_VSTTBR_EL2); + } else { + DPRINTF(TLB, " - Selecting VTTBR_EL2 (AArch64 stage 2)\n"); + ttbr = currState->tc->readMiscReg(MISCREG_VTTBR_EL2); + } tsz = 64 - currState->vtcr.t0sz64; tg = GrainMap_tg0[currState->vtcr.tg0]; // ARM DDI 0487A.f D7-2148 diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index 0c001b0bc..a6205ced3 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -833,6 +833,8 @@ TLB::checkPermissions64(TlbEntry *te, const RequestPtr &req, Mode mode, bool w = is_write; bool x = is_fetch; + xn = ArmSystem::haveEL(tc, EL3) && isSecure && te->ns && scr.sif; + // grant_read is used for faults from an atomic instruction that // both reads and writes from a memory location. From a ISS point // of view they count as read if a read to that address would have @@ -1351,7 +1353,7 @@ TLB::updateMiscReg(ThreadContext *tc, ArmTranslationType tranType) cpsr = tc->readMiscReg(MISCREG_CPSR); // Dependencies: SCR/SCR_EL3, CPSR - isSecure = inSecureState(tc) && + isSecure = ArmISA::isSecure(tc) && !(tranType & HypMode) && !(tranType & S1S2NsTran); aarch64EL = tranTypeEL(cpsr, tranType); @@ -1420,11 +1422,17 @@ TLB::updateMiscReg(ThreadContext *tc, ArmTranslationType tranType) scr = tc->readMiscReg(MISCREG_SCR_EL3); isPriv = aarch64EL != EL0; if (haveVirtualization) { - vmid = bits(tc->readMiscReg(MISCREG_VTTBR_EL2), 55, 48); + uint64_t vttbr = isSecure? tc->readMiscReg(MISCREG_VSTTBR_EL2): + tc->readMiscReg(MISCREG_VTTBR_EL2); + vmid = bits(vttbr, 55, 48); isHyp = aarch64EL == EL2; isHyp |= tranType & HypMode; isHyp &= (tranType & S1S2NsTran) == 0; isHyp &= (tranType & S1CTran) == 0; + bool vm = hcr.vm; + if (HaveVirtHostExt(tc) && hcr.e2h == 1 && hcr.tge ==1) { + vm = 0; + } if (hcr.e2h == 1 && (aarch64EL == EL2 || (hcr.tge ==1 && aarch64EL == EL0))) { @@ -1436,16 +1444,12 @@ TLB::updateMiscReg(ThreadContext *tc, ArmTranslationType tranType) // Work out if we should skip the first stage of translation and go // directly to stage 2. This value is cached so we don't have to // compute it for every translation. - bool vm = hcr.vm; - if (HaveVirtHostExt(tc) && hcr.e2h == 1 && hcr.tge == 1) { - vm = 0; - } - + bool sec = !isSecure || (isSecure && IsSecureEL2Enabled(tc)); stage2Req = isStage2 || - (vm && !isHyp && !isSecure && + (vm && !isHyp && sec && !(tranType & S1CTran) && (aarch64EL < EL2) && !(tranType & S1E1Tran)); // <--- FIX THIS HACK - stage2DescReq = isStage2 || (vm && !isHyp && !isSecure && + stage2DescReq = isStage2 || (vm && !isHyp && sec && (aarch64EL < EL2)); directToStage2 = !isStage2 && stage2Req && !sctlr.m; } @@ -1494,9 +1498,10 @@ TLB::updateMiscReg(ThreadContext *tc, ArmTranslationType tranType) // Work out if we should skip the first stage of translation and go // directly to stage 2. This value is cached so we don't have to // compute it for every translation. - stage2Req = hcr.vm && !isStage2 && !isHyp && !isSecure && + bool sec = !isSecure || (isSecure && IsSecureEL2Enabled(tc)); + stage2Req = hcr.vm && !isStage2 && !isHyp && sec && !(tranType & S1CTran); - stage2DescReq = hcr.vm && !isStage2 && !isHyp && !isSecure; + stage2DescReq = hcr.vm && !isStage2 && !isHyp && sec; directToStage2 = stage2Req && !sctlr.m; } else { vmid = 0; @@ -1652,7 +1657,8 @@ TLB::getResultTe(TlbEntry **te, const RequestPtr &req, fault = checkPermissions(s1Te, req, mode); if (stage2Req & (fault == NoFault)) { Stage2LookUp *s2Lookup = new Stage2LookUp(this, stage2Tlb, *s1Te, - req, translation, mode, timing, functional, curTranType); + req, translation, mode, timing, functional, !(s1Te->ns), + curTranType); fault = s2Lookup->getTe(tc, mergeTe); if (s2Lookup->isComplete()) { *te = mergeTe; diff --git a/src/arch/arm/tracers/tarmac_record.cc b/src/arch/arm/tracers/tarmac_record.cc index ee2e8e21d..4b7f43d23 100644 --- a/src/arch/arm/tracers/tarmac_record.cc +++ b/src/arch/arm/tracers/tarmac_record.cc @@ -118,7 +118,7 @@ TarmacTracerRecord::TraceInstEntry::TraceInstEntry( bool predicate) : InstEntry(tarmCtx.thread, tarmCtx.pc, tarmCtx.staticInst, predicate) { - secureMode = inSecureState(tarmCtx.thread); + secureMode = isSecure(tarmCtx.thread); auto arm_inst = static_cast( tarmCtx.staticInst.get() diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index 07740a21c..1c448343c 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -171,12 +171,15 @@ sendEvent(ThreadContext *tc) } bool -inSecureState(ThreadContext *tc) +isSecure(ThreadContext *tc) { - SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) : - tc->readMiscReg(MISCREG_SCR); - return ArmSystem::haveSecurity(tc) && inSecureState( - scr, tc->readMiscReg(MISCREG_CPSR)); + CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); + if (ArmSystem::haveEL(tc, EL3) && !cpsr.width && currEL(tc) == EL3) + return true; + if (ArmSystem::haveEL(tc, EL3) && cpsr.width && cpsr.mode == MODE_MON) + return true; + else + return isSecureBelowEL3(tc); } bool @@ -190,14 +193,14 @@ ExceptionLevel debugTargetFrom(ThreadContext *tc, bool secure) { bool route_to_el2; - if (ArmSystem::haveEL(tc, EL2) && !secure){ - if (ELIs32(tc, EL2)){ + if (ArmSystem::haveEL(tc, EL2) && (!secure || HaveSecureEL2Ext(tc))) { + if (ELIs32(tc, EL2)) { const HCR hcr = tc->readMiscReg(MISCREG_HCR); - const HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); + const HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR); route_to_el2 = (hdcr.tde == 1 || hcr.tge == 1); - }else{ + } else { const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2); + const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2); route_to_el2 = (mdcr.tde == 1 || hcr.tge == 1); } }else{ @@ -206,10 +209,10 @@ debugTargetFrom(ThreadContext *tc, bool secure) ExceptionLevel target; if (route_to_el2) { target = EL2; - }else if (ArmSystem::haveEL(tc, EL3) && !ArmSystem::highestELIs64(tc) - && secure){ + } else if (ArmSystem::haveEL(tc, EL3) && !ArmSystem::highestELIs64(tc) + && secure) { target = EL3; - }else{ + } else { target = EL1; } return target; @@ -344,11 +347,12 @@ bool IsSecureEL2Enabled(ThreadContext *tc) { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - if (ArmSystem::haveEL(tc, EL2) && HaveSecureEL2Ext(tc)) { + if (ArmSystem::haveEL(tc, EL2) && HaveSecureEL2Ext(tc) && + !ELIs32(tc, EL2)) { if (ArmSystem::haveEL(tc, EL3)) return !ELIs32(tc, EL3) && scr.eel2; else - return inSecureState(tc); + return isSecure(tc); } return false; } @@ -393,6 +397,20 @@ ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el) return ELStateUsingAArch32K(tc, el, secure); } +bool +haveAArch32EL(ThreadContext *tc, ExceptionLevel el) +{ + if (!ArmSystem::haveEL(tc, el)) + return false; + else if (!ArmSystem::highestELIs64(tc)) + return true; + else if (ArmSystem::highestEL(tc) == el) + return false; + else if (el == EL0) + return true; + return true; +} + std::pair ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure) { @@ -405,30 +423,33 @@ ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure) bool known, aarch32; known = aarch32 = false; - if (ArmSystem::highestELIs64(tc) && ArmSystem::highestEL(tc) == el) { + if (!haveAArch32EL(tc, el)) { // Target EL is the highest one in a system where // the highest is using AArch64. known = true; aarch32 = false; + } else if (secure && el == EL2) { + known = true; aarch32 = false; } else if (!ArmSystem::highestELIs64(tc)) { // All ELs are using AArch32: known = true; aarch32 = true; + } else if (ArmSystem::highestEL(tc) == el) { + known = true; aarch32 = false; } else { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - bool aarch32_below_el3 = (have_el3 && scr.rw == 0); + bool aarch32_below_el3 = have_el3 && scr.rw == 0 && + (!secure || !HaveSecureEL2Ext(tc) || !scr.eel2); HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - bool secEL2 = false; - bool aarch32_at_el1 = (aarch32_below_el3 - || (have_el2 - && (secEL2 || !isSecureBelowEL3(tc)) - && hcr.rw == 0 && !(hcr.e2h && hcr.tge - && HaveVirtHostExt(tc)))); + bool sec_el2 = HaveSecureEL2Ext(tc) && scr.eel2; + bool aarch32_at_el1 = (aarch32_below_el3 || + (have_el2 && (sec_el2 || !secure) && + hcr.rw == 0 && !(hcr.e2h && hcr.tge && + HaveVirtHostExt(tc)))); // Only know if EL0 using AArch32 from PSTATE if (el == EL0 && !aarch32_at_el1) { // EL0 controlled by PSTATE CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); - known = (currEL(tc) == EL0); aarch32 = (cpsr.width == 1); } else { diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index efe9e0808..f00f606ed 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -128,6 +128,8 @@ inPrivilegedMode(ThreadContext *tc) return !inUserMode(tc); } +bool isSecure(ThreadContext *tc); + bool inAArch64(ThreadContext *tc); static inline OperatingMode @@ -256,8 +258,6 @@ inSecureState(SCR scr, CPSR cpsr) } } -bool inSecureState(ThreadContext *tc); - bool isSecureBelowEL3(ThreadContext *tc); bool longDescFormatInUse(ThreadContext *tc);