Jordi Vaquero has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/31394 )

Change subject: arch-arm: Implementing SecureEL2 feature for Armv8
......................................................................

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

Change-Id: Ie59438b1828508e944334420da1d8f4745649056
---
M src/arch/arm/insts/static_inst.cc
M src/arch/arm/isa.cc
M src/arch/arm/isa.hh
M src/arch/arm/isa/insts/misc.isa
M src/arch/arm/isa/insts/misc64.isa
M src/arch/arm/miscregs.cc
M src/arch/arm/miscregs.hh
M src/arch/arm/self_debug.cc
M src/arch/arm/self_debug.hh
M src/arch/arm/stage2_lookup.cc
M src/arch/arm/stage2_lookup.hh
M src/arch/arm/table_walker.cc
M src/arch/arm/tlb.cc
M src/arch/arm/utility.cc
M src/arch/arm/utility.hh
15 files changed, 177 insertions(+), 96 deletions(-)



diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc
index c7f3c27..cb89def 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -634,9 +634,8 @@
     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<SoftwareBreakpoint>(machInst, imm);
     } else {
@@ -1094,22 +1093,33 @@
     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))
+    //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 (!ArmSystem::haveEL(tc, target_el))
-        return true;
-
- if (target_el == EL1 && ArmSystem::haveEL(tc, EL2) && scr.ns && hcr.tge)
-        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);
@@ -1120,17 +1130,9 @@
     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;
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 9cb8c2b..40c589a 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -397,6 +397,11 @@
     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, 0x1);
+    miscRegs[MISCREG_ID_AA64ISAR0_EL1] = insertBits(
+        miscRegs[MISCREG_ID_AA64ISAR0_EL1], 39, 36, 0x1);
     // Large ASID support
     miscRegs[MISCREG_ID_AA64MMFR0_EL1] = insertBits(
         miscRegs[MISCREG_ID_AA64MMFR0_EL1], 7, 4,
@@ -507,7 +512,8 @@
                   miscRegName[misc_reg]);
     }
 #endif
-    if (misc_reg != MISCREG_HCR_EL2 && misc_reg != MISCREG_SCR_EL3)
+    if (misc_reg != MISCREG_HCR_EL2 && misc_reg != MISCREG_SCR_EL3 &&
+        misc_reg != MISCREG_ID_AA64PFR0_EL1)
         misc_reg = redirectRegVHE(tc, misc_reg);

     switch (unflattenMiscReg(misc_reg)) {
@@ -760,12 +766,13 @@
                  | (haveTimer          ? 0x00010000 : 0x0);
         }
       case MISCREG_ID_AA64PFR0_EL1:
-        return 0x0000000000000002 | // AArch{64,32} supported at EL0
-               0x0000000000000020                               | // EL1
-               (haveVirtualization    ? 0x0000000000000200 : 0) | // EL2
-               (haveSecurity          ? 0x0000000000002000 : 0) | // EL3
-               (haveSVE               ? 0x0000000100000000 : 0) | // SVE
-               (gicv3CpuInterface     ? 0x0000000001000000 : 0);
+        return readMiscRegNoEffect(MISCREG_ID_AA64PFR0_EL1);
+        //return 0x0000000000000002 | // AArch{64,32} supported at EL0
+        //       0x0000000000000020                               | // EL1
+        //       (haveVirtualization    ? 0x0000000000000200 : 0) | // EL2
+        //       (haveSecurity          ? 0x0000000000002000 : 0) | // EL3
+        //       (haveSVE               ? 0x0000000100000000 : 0) | // SVE
+        //       (gicv3CpuInterface     ? 0x0000000001000000 : 0);
       case MISCREG_ID_AA64PFR1_EL1:
         return 0; // bits [63:0] RES0 (reserved for future use)

@@ -861,7 +868,8 @@
                     miscRegName[misc_reg], val);
         }
 #endif
-        if (misc_reg != MISCREG_HCR_EL2 && misc_reg != MISCREG_SCR_EL3)
+        if (misc_reg != MISCREG_HCR_EL2 && misc_reg != MISCREG_SCR_EL3 &&
+            misc_reg != MISCREG_ID_AA64PFR0_EL1)
             misc_reg = redirectRegVHE(tc, misc_reg);

         switch (unflattenMiscReg(misc_reg)) {
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index bcfada4..da51565 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -695,7 +695,7 @@
             if (hcr.e2h == 0x0 || currEL(tc) != EL2)
                 return misc_reg;
             SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
-            bool secEL2 = scr.eel2 && false;
+            bool secEL2 = scr.eel2 && HaveSecureEL2Ext(tc);
             switch(misc_reg) {
               case MISCREG_SPSR_EL1:
                   return MISCREG_SPSR_EL2;
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa
index 64bf791..a24c4a2 100644
--- a/src/arch/arm/isa/insts/misc.isa
+++ b/src/arch/arm/isa/insts/misc.isa
@@ -95,8 +95,7 @@
     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<HypervisorTrap>(machInst, 0,
                                                      EC_SMC_TO_HYP);
         } else {
@@ -121,12 +120,11 @@

     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))) {
+        (cpsr.mode == MODE_USER)
+        || (isSecure(xc->tcBase()) && !IsSecureEL2Enabled(xc->tcBase()))) {
         fault = disabledFault();
     } else {
         fault = std::make_shared<HypervisorCall>(machInst, imm);
diff --git a/src/arch/arm/isa/insts/misc64.isa b/src/arch/arm/isa/insts/misc64.isa
index 656a234..14d9af0 100644
--- a/src/arch/arm/isa/insts/misc64.isa
+++ b/src/arch/arm/isa/insts/misc64.isa
@@ -56,7 +56,8 @@
     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)
+                                               && inSecureState(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 5579f09..b39a48c 100644
--- a/src/arch/arm/miscregs.cc
+++ b/src/arch/arm/miscregs.cc
@@ -2368,6 +2368,14 @@
                         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:
@@ -4892,6 +4900,13 @@
     InitReg(MISCREG_VTCR_EL2)
       .hyp().mon()
       .mapsTo(MISCREG_VTCR);
+    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 5b09f34..c9f186e 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -596,6 +596,8 @@
         MISCREG_TCR_EL2,
         MISCREG_VTTBR_EL2,
         MISCREG_VTCR_EL2,
+        MISCREG_VSTTBR_EL2,
+        MISCREG_VSTCR_EL2,
         MISCREG_TTBR0_EL3,
         MISCREG_TCR_EL3,
         MISCREG_DACR32_EL2,
@@ -1693,6 +1695,8 @@
         "tcr_el12",
         "ttbr0_el2",
         "tcr_el2",
+        "vsttbr_el2",
+        "vstcr_el2",
         "vttbr_el2",
         "vtcr_el2",
         "ttbr0_el3",
diff --git a/src/arch/arm/self_debug.cc b/src/arch/arm/self_debug.cc
index 790e04b..a916cae 100644
--- a/src/arch/arm/self_debug.cc
+++ b/src/arch/arm/self_debug.cc
@@ -165,7 +165,7 @@
                          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 @@
         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
         }
@@ -653,7 +653,9 @@
         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 {
diff --git a/src/arch/arm/self_debug.hh b/src/arch/arm/self_debug.hh
index a1c03ea..de45c22 100644
--- a/src/arch/arm/self_debug.hh
+++ b/src/arch/arm/self_debug.hh
@@ -341,8 +341,8 @@
     {
         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);
@@ -372,10 +372,10 @@
         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 @@
     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/stage2_lookup.cc b/src/arch/arm/stage2_lookup.cc
index 0fe8edd..93843ab 100644
--- a/src/arch/arm/stage2_lookup.cc
+++ b/src/arch/arm/stage2_lookup.cc
@@ -55,7 +55,7 @@

 {
     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 @@
     // 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 a9b014a..a5a984f 100644
--- a/src/arch/arm/stage2_lookup.hh
+++ b/src/arch/arm/stage2_lookup.hh
@@ -69,15 +69,16 @@
     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<Request>();
         req->setVirt(s1Te.pAddr(s1Req->getVaddr()), s1Req->getSize(),
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index aa3dbf6..273b064 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -267,7 +267,13 @@
         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) &&
@@ -320,7 +326,8 @@

     if (long_desc_format) {
         // Helper variables used for hierarchical permissions
-        currState->secureLookup = currState->isSecure;
+        currState->secureLookup = IsSecureEL2Enabled(currState->tc) ?
+                                     currState->isSecure : false;
         currState->rwTable = true;
         currState->userTable = true;
         currState->xnTable = false;
@@ -552,7 +559,7 @@
         flag.set(Request::UNCACHEABLE);
     }

-    if (currState->isSecure) {
+    if (currState->isSecure && IsSecureEL2Enabled(currState->tc)) {
         flag.set(Request::SECURE);
     }

@@ -825,8 +832,13 @@
         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 381ee96..5477ace 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -833,6 +833,8 @@
     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
@@ -1418,11 +1420,17 @@
         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))) {
@@ -1434,16 +1442,12 @@
// 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;
             }
@@ -1492,9 +1496,10 @@
// 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;
@@ -1650,7 +1655,8 @@
             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/utility.cc b/src/arch/arm/utility.cc
index fe9d2eb..86a6777 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -180,17 +180,35 @@
 }

 bool
+isSecure(ThreadContext *tc)
+{
+    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
 isSecureBelowEL3(ThreadContext *tc)
 {
     SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
-    return ArmSystem::haveEL(tc, EL3) && scr.ns == 0;
+    if (ArmSystem::haveEL(tc, EL3))
+       return scr.ns == 0;
+    else if (ArmSystem::haveEL(tc, EL2) &&
+             (!HaveSecureEL2Ext(tc) || !ArmSystem::highestELIs64(tc)))
+       return false;
+    else
+       return scr.ns == 0;
 }

 ExceptionLevel
 debugTargetFrom(ThreadContext *tc, bool secure)
 {
     bool route_to_el2;
-    if (ArmSystem::haveEL(tc, EL2) && !secure){
+    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);
@@ -344,11 +362,12 @@
 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;
 }
@@ -356,9 +375,8 @@
 bool
 EL2Enabled(ThreadContext *tc)
 {
-    SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
-    return ArmSystem::haveEL(tc, EL2) &&
- (!ArmSystem::haveEL(tc, EL3) || scr.ns || IsSecureEL2Enabled(tc));
+    return  IsSecureEL2Enabled(tc) || (ArmSystem::haveEL(tc, EL2) &&
+                                       !isSecure(tc));
 }

 bool
@@ -392,6 +410,19 @@
     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<bool, bool>
 ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure)
 {
@@ -404,7 +435,7 @@

     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;
@@ -416,12 +447,11 @@
         bool aarch32_below_el3 = (have_el3 && scr.rw == 0);

         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 secEL2 = HaveSecureEL2Ext(tc) && scr.eel2;
+        bool aarch32_at_el1 = (aarch32_below_el3 ||
+                               (have_el2 && (secEL2 || !secure) &&
+                                hcr.rw == 0 && !(hcr.e2h && hcr.tge &&
+                                                 HaveVirtHostExt(tc))));

         // Only know if EL0 using AArch32 from PSTATE
         if (el == EL0 && !aarch32_at_el1) {
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
index 971306f..e1f123a 100644
--- a/src/arch/arm/utility.hh
+++ b/src/arch/arm/utility.hh
@@ -128,6 +128,8 @@
     return !inUserMode(tc);
 }

+bool isSecure(ThreadContext *tc);
+
 bool isSecureBelowEL3(ThreadContext *tc);

 bool inAArch64(ThreadContext *tc);

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/31394
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ie59438b1828508e944334420da1d8f4745649056
Gerrit-Change-Number: 31394
Gerrit-PatchSet: 1
Gerrit-Owner: Jordi Vaquero <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to