arch-arm: CPTR.FPEN controlling SVE enablement
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Fri, 1 May 2020 13:33:25 +0000 (14:33 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Sat, 9 May 2020 21:35:44 +0000 (21:35 +0000)
CheckSveEnabled shouldn't check for .ZEN only.
SVE instructions require Advanced SIMD to be supported as
well (CPTR.FPEN) with the caveat of ZEN check having priority
over the FPEN.

Change-Id: Ia1b5f7df3e25e7ffcad472542cb973635f62637b
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Ciro Santilli <ciro.santilli@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28768
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/insts/static_inst.cc

index 6da8b770e1aa2f5718791071e8a69b5cc2ee4ff7..9ece0e6d29f919dcdd76909d02df95d926cb3f57 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2014, 2016-2019 ARM Limited
+ * Copyright (c) 2010-2014, 2016-2020 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -987,20 +987,33 @@ Fault
 ArmStaticInst::checkSveEnabled(ThreadContext *tc, CPSR cpsr, CPACR cpacr) const
 {
     const ExceptionLevel el = (ExceptionLevel) (uint8_t) cpsr.el;
-    if ((el == EL0 && cpacr.zen != 0x3) ||
-        (el == EL1 && !(cpacr.zen & 0x1)))
-        return sveAccessTrap(EL1);
+    // Check if access disabled in CPACR_EL1
+    if (el <= EL1 && !ELIsInHost(tc, el)) {
+        if ((el == EL0 && cpacr.zen == 0x1) ||
+            (!(cpacr.zen & 0x1)))
+            return sveAccessTrap(EL1);
+
+        if ((el == EL0 && cpacr.fpen == 0x1) ||
+            (!(cpacr.fpen & 0x1)))
+            return advSIMDFPAccessTrap64(EL1);
+    }
 
+    // Check if access disabled in CPTR_EL2
     if (ArmSystem::haveVirtualization(tc) && el <= EL2) {
         CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL2);
         if (cptr_en_check.tz)
             return sveAccessTrap(EL2);
+        if (cptr_en_check.tfp)
+            return advSIMDFPAccessTrap64(EL2);
     }
 
+    // Check if access disabled in CPTR_EL3
     if (ArmSystem::haveSecurity(tc)) {
         CPTR cptr_en_check = tc->readMiscReg(MISCREG_CPTR_EL3);
         if (!cptr_en_check.ez)
             return sveAccessTrap(EL3);
+        if (cptr_en_check.tfp)
+            return advSIMDFPAccessTrap64(EL3);
     }
 
     return NoFault;