arch-arm: Fix Fault subsystem adding EL2Enable func
authorJordi Vaquero <jordi.vaquero@metempsy.com>
Thu, 16 Jul 2020 09:57:06 +0000 (11:57 +0200)
committerJordi Vaquero <jordi.vaquero@metempsy.com>
Tue, 21 Jul 2020 14:37:54 +0000 (14:37 +0000)
Change-Id: I7a4f0c22ac31fd56a8976ee8a1d9760cf6055d63
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31374
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/faults.cc
src/arch/arm/faults.hh

index 743e08de33a2c33f3d3899bfcc52911cd728b1ad..40cf6341c1c5f848d13a302de252955cef42f1e7 100644 (file)
@@ -819,17 +819,9 @@ UndefinedInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst)
 bool
 UndefinedInstruction::routeToHyp(ThreadContext *tc) const
 {
-    bool toHyp;
-
-    SCR  scr  = tc->readMiscRegNoEffect(MISCREG_SCR);
     HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
-    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
-
-    // if in Hyp mode then stay in Hyp mode
-    toHyp  = scr.ns && (currEL(tc) == EL2);
-    // if HCR.TGE is set to 1, take to Hyp mode through Hyp Trap vector
-    toHyp |= !inSecureState(scr, cpsr) && hcr.tge && (currEL(tc) == EL0);
-    return toHyp;
+    return fromEL == EL2 ||
+           (EL2Enabled(tc) && (fromEL == EL0) && hcr.tge);
 }
 
 uint32_t
@@ -885,7 +877,8 @@ bool
 SupervisorCall::routeToHyp(ThreadContext *tc) const
 {
     HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
-    return EL2Enabled(tc) && currEL(tc) == EL0 && hcr.tge == 1;
+    return fromEL == EL2 ||
+           (EL2Enabled(tc) && fromEL == EL0 && hcr.tge);
 }
 
 ExceptionClass
@@ -929,6 +922,18 @@ HypervisorCall::HypervisorCall(ExtMachInst _machInst, uint32_t _imm) :
     bStep = true;
 }
 
+bool
+HypervisorCall::routeToMonitor(ThreadContext *tc) const
+{
+    return from64 && fromEL == EL3;
+}
+
+bool
+HypervisorCall::routeToHyp(ThreadContext *tc) const
+{
+    return !from64 || fromEL != EL3;
+}
+
 ExceptionClass
 HypervisorCall::ec(ThreadContext *tc) const
 {
@@ -1301,20 +1306,14 @@ PrefetchAbort::routeToHyp(ThreadContext *tc) const
 {
     bool toHyp;
 
-    SCR  scr  = tc->readMiscRegNoEffect(MISCREG_SCR);
     HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
     HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR);
 
-    // if in Hyp mode then stay in Hyp mode
-    toHyp = scr.ns && (currEL(tc) == EL2);
-    toHyp |= (currEL(tc) <= EL1) && hcr.tge;
-    // otherwise, check whether to take to Hyp mode through Hyp Trap vector
-    toHyp |= (stage2 ||
-              ((source == DebugEvent) && (hdcr.tde || hcr.tge) &&
-               (currEL(tc) != EL2)) ||
-              ((source == SynchronousExternalAbort) && hcr.tge  &&
-               (currEL(tc) == EL0))) && !inSecureState(tc);
-    return toHyp;
+    toHyp = fromEL == EL2;
+    toHyp |=  ArmSystem::haveEL(tc, EL2) && !inSecureState(tc) &&
+        currEL(tc) <= EL1 && (hcr.tge || stage2 ||
+                              (source == DebugEvent && hdcr.tde));
+     return toHyp;
 }
 
 ExceptionClass
@@ -1363,21 +1362,22 @@ DataAbort::routeToHyp(ThreadContext *tc) const
 {
     bool toHyp;
 
-    SCR  scr  = tc->readMiscRegNoEffect(MISCREG_SCR);
     HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
     HDCR hdcr = tc->readMiscRegNoEffect(MISCREG_HDCR);
 
+    bool amo = hcr.amo;
+    if (hcr.tge == 1)
+        amo =  (!HaveVirtHostExt(tc) || hcr.e2h == 0);
+
     // if in Hyp mode then stay in Hyp mode
-    toHyp = scr.ns && (currEL(tc) == EL2);
-    toHyp |= (currEL(tc) <= EL1 && hcr.tge==1);
-    // otherwise, check whether to take to Hyp mode through Hyp Trap vector
-    toHyp |= (stage2 ||
-              ((currEL(tc) != EL2) &&
-               (((source == AsynchronousExternalAbort) && hcr.amo) ||
-                ((source == DebugEvent) && (hdcr.tde || hcr.tge)))) ||
-              ((currEL(tc) == EL0) && hcr.tge &&
-               ((source == AlignmentFault) ||
-                (source == SynchronousExternalAbort)))) && !inSecureState(tc);
+    toHyp = fromEL == EL2 ||
+            (EL2Enabled(tc) && fromEL <= EL1
+                && (hcr.tge || stage2 ||
+                    ((source == AsynchronousExternalAbort) && amo) ||
+                    ((fromEL == EL0) && hcr.tge &&
+                     ((source == AlignmentFault) ||
+                      (source == SynchronousExternalAbort))) ||
+                    ((source == DebugEvent) && (hdcr.tde || hcr.tge))));
     return toHyp;
 }
 
@@ -1472,7 +1472,7 @@ Interrupt::routeToHyp(ThreadContext *tc) const
 {
     HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
     return fromEL == EL2 ||
-           (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge == 1 || hcr.imo));
+           (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || hcr.imo));
 }
 
 bool
@@ -1505,7 +1505,7 @@ FastInterrupt::routeToHyp(ThreadContext *tc) const
 {
     HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
     return fromEL == EL2 ||
-           (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge == 1 || hcr.fmo));
+           (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || hcr.fmo));
 }
 
 bool
@@ -1546,7 +1546,7 @@ bool
 PCAlignmentFault::routeToHyp(ThreadContext *tc) const
 {
     HCR  hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
-    return EL2Enabled(tc) && currEL(tc) <= EL1 && hcr.tge == 1;
+    return fromEL == EL2 || (EL2Enabled(tc) && fromEL <= EL1 && hcr.tge);
 }
 
 SPAlignmentFault::SPAlignmentFault()
@@ -1576,21 +1576,18 @@ SystemError::routeToMonitor(ThreadContext *tc) const
     assert(ArmSystem::haveSecurity(tc));
     assert(from64);
     SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
-    return scr.ea;
+    return scr.ea || fromEL == EL3;
 }
 
 bool
 SystemError::routeToHyp(ThreadContext *tc) const
 {
-    bool toHyp;
     assert(from64);
 
-    SCR scr = tc->readMiscRegNoEffect(MISCREG_SCR_EL3);
-    HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR);
+    HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
 
-    toHyp = (!scr.ea && hcr.amo && !inSecureState(tc)) ||
-            (!scr.ea && !scr.rw && !hcr.amo && !inSecureState(tc));
-    return toHyp;
+    return fromEL == EL2 ||
+           (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || hcr.amo));
 }
 
 
@@ -1601,13 +1598,11 @@ SoftwareBreakpoint::SoftwareBreakpoint(ExtMachInst _mach_inst, uint32_t _iss)
 bool
 SoftwareBreakpoint::routeToHyp(ThreadContext *tc) const
 {
-    const bool have_el2 = ArmSystem::haveVirtualization(tc);
-
     const HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
     const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
 
-    return have_el2 && !inSecureState(tc) && fromEL <= EL1 &&
-        (hcr.tge || mdcr.tde);
+    return fromEL == EL2 ||
+           (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde));
 }
 
 ExceptionClass
@@ -1623,13 +1618,10 @@ HardwareBreakpoint::HardwareBreakpoint(Addr _vaddr,  uint32_t _iss)
 bool
 HardwareBreakpoint::routeToHyp(ThreadContext *tc) const
 {
-    const bool have_el2 = ArmSystem::haveVirtualization(tc);
-
     const HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
     const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
 
-    return have_el2 && !inSecureState(tc) && fromEL <= EL1 &&
-        (hcr.tge || mdcr.tde);
+    return EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde);
 }
 
 ExceptionClass
@@ -1704,8 +1696,8 @@ Watchpoint::routeToHyp(ThreadContext *tc) const
     const HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
     const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
 
-    return fromEL == EL2 || (EL2Enabled(tc) && fromEL <= EL1 &&
-                             (hcr.tge || mdcr.tde));
+    return fromEL == EL2 ||
+           (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde));
 }
 
 void
@@ -1744,13 +1736,11 @@ SoftwareStepFault::SoftwareStepFault(ExtMachInst _mach_inst, bool is_ldx,
 bool
 SoftwareStepFault::routeToHyp(ThreadContext *tc) const
 {
-    const bool have_el2 = ArmSystem::haveVirtualization(tc);
-
     const HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
     const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
 
-    return have_el2 && !inSecureState(tc) && fromEL <= EL1 &&
-        (hcr.tge || mdcr.tde);
+    return fromEL == EL2 ||
+           (EL2Enabled(tc) && fromEL <= EL1 && (hcr.tge || mdcr.tde));
 }
 
 ExceptionClass
@@ -1824,6 +1814,13 @@ template class AbortFault<VirtualDataAbort>;
 IllegalInstSetStateFault::IllegalInstSetStateFault()
 {}
 
+bool
+IllegalInstSetStateFault::routeToHyp(ThreadContext *tc) const
+{
+    const HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
+    return EL2Enabled(tc) && fromEL == EL0 && hcr.tge;
+}
+
 bool
 getFaultVAddr(Fault fault, Addr &va)
 {
index 7a2f69edfd7001dd456e4a29162482d992b79f69..b911136781d4a0de9f281872d46a100a0901ea3f 100644 (file)
@@ -406,6 +406,8 @@ class HypervisorCall : public ArmFaultVals<HypervisorCall>
   public:
     HypervisorCall(ExtMachInst _machInst, uint32_t _imm);
 
+    bool routeToHyp(ThreadContext *tc) const override;
+    bool routeToMonitor(ThreadContext *tc) const override;
     ExceptionClass ec(ThreadContext *tc) const override;
     uint32_t vectorCatchFlag() const override { return 0xFFFFFFFF; }
 };
@@ -677,6 +679,8 @@ class IllegalInstSetStateFault : public ArmFaultVals<IllegalInstSetStateFault>
 {
   public:
     IllegalInstSetStateFault();
+
+    bool routeToHyp(ThreadContext *tc) const override;
 };
 
 /*