qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v3 10/32] target-arm: extend Aarch64 SCR.{FIQ|IRQ} h


From: Fabian Aggeler
Subject: [Qemu-devel] [PATCH v3 10/32] target-arm: extend Aarch64 SCR.{FIQ|IRQ} handling
Date: Wed, 11 Jun 2014 01:54:52 +0200

If EL3 is using Aarch64 IRQ/FIQ masking is ignored in
all exception levels other than EL3 if SCR.{FIQ|IRQ} is
set to 1 (routed to EL3).

Signed-off-by: Fabian Aggeler <address@hidden>
---
 target-arm/cpu.h | 98 +++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 72 insertions(+), 26 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index f8531aa..b786a5a 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1195,20 +1195,43 @@ static inline bool arm_excp_unmasked(CPUState *cs, 
unsigned int excp_idx)
      * (table G1-18/G1-19) */
     switch (excp_idx) {
     case EXCP_FIQ:
+        if (arm_feature(env, ARM_FEATURE_EL3) && arm_el_is_aa64(env, 3)) {
+            /* If EL3 is using Aarch64 and FIQs are routed to EL3 masking is
+             * ignored in all exception levels except EL3.
+             */
+            if ((env->cp15.scr_el3 & SCR_FIQ) && cur_el < 3) {
+                return true;
+            }
+            /* If we are in EL3 but FIQs are not routed to EL3 the exception
+             * is not taken but remains pending.
+             */
+            if (!(env->cp15.scr_el3 & SCR_FIQ) && cur_el == 3) {
+                return false;
+            }
+        }
         if (!secure) {
-            if (arm_feature(env, ARM_FEATURE_EL2) &&
-                    (env->cp15.hcr_el2 & HCR_FMO)) {
-                /* CPSR.F/PSTATE.F ignored if
-                 *  - exception is taken from Non-secure state
-                 *  - HCR.FMO == 1
-                 *  - either:  - not in Hyp mode
-                 *             - SCR.FIQ routes exception to monitor mode
-                 */
-                if (cur_el < 2) {
-                    return true;
-                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
-                        (env->cp15.scr_el3 & SCR_FIQ)) {
-                    return true;
+            if (arm_feature(env, ARM_FEATURE_EL2)) {
+                if (env->cp15.hcr_el2 & HCR_FMO) {
+                    /* CPSR.F/PSTATE.F ignored if
+                     *  - exception is taken from Non-secure state
+                     *  - HCR.FMO == 1
+                     *  - either:  - not in Hyp mode
+                     *             - SCR.FIQ routes exception to monitor mode
+                     *               (EL3 in Aarch32)
+                     */
+                    if (cur_el < 2) {
+                        return true;
+                    } else if (arm_feature(env, ARM_FEATURE_EL3) &&
+                            (env->cp15.scr_el3 & SCR_FIQ) &&
+                            !arm_el_is_aa64(env, 3)) {
+                        return true;
+                    }
+                } else if (arm_el_is_aa64(env, 3) &&
+                          (env->cp15.scr_el3 & SCR_RW) &&
+                          cur_el == 2) {
+                    /* FIQs not routed to EL2 but currently in EL2 (A64).
+                     * Exception is not taken but remains pending. */
+                    return false;
                 }
             }
             /* In ARMv7 only applies if both Security Extensions (EL3) and
@@ -1236,20 +1259,43 @@ static inline bool arm_excp_unmasked(CPUState *cs, 
unsigned int excp_idx)
         }
         return !(env->daif & PSTATE_F);
     case EXCP_IRQ:
+        if (arm_feature(env, ARM_FEATURE_EL3) && arm_el_is_aa64(env, 3)) {
+            /* If EL3 is using Aarch64 and IRQs are routed to EL3 masking is
+             * ignored in all exception levels except EL3.
+             */
+            if ((env->cp15.scr_el3 & SCR_IRQ) && cur_el < 3) {
+                return true;
+            }
+            /* If we are in EL3 but IRQ s are not routed to EL3 the exception
+             * is not taken but remains pending.
+             */
+            if (!(env->cp15.scr_el3 & SCR_IRQ) && cur_el == 3) {
+                return false;
+            }
+        }
         if (!secure) {
-            if (arm_feature(env, ARM_FEATURE_EL2) &&
-                    (env->cp15.hcr_el2 & HCR_IMO)) {
-                /* CPSR.I/PSTATE.I ignored if
-                 *  - exception is taken from Non-secure state
-                 *  - HCR.IMO == 1
-                 *  - either:  - not in Hyp mode
-                 *             - SCR.IRQ routes exception to monitor mode
-                 */
-                if (cur_el < 2) {
-                    return true;
-                } else if (arm_feature(env, ARM_FEATURE_EL3) &&
-                        (env->cp15.scr_el3 & SCR_IRQ)) {
-                    return true;
+            if (arm_feature(env, ARM_FEATURE_EL2)) {
+                if (env->cp15.hcr_el2 & HCR_IMO) {
+                    /* CPSR.I/PSTATE.I ignored if
+                     *  - exception is taken from Non-secure state
+                     *  - HCR.IMO == 1
+                     *  - either:  - not in Hyp mode
+                     *             - SCR.IRQ routes exception to monitor mode
+                     *                (EL3 in Aarch32)
+                     */
+                    if (cur_el < 2) {
+                        return true;
+                    } else if (arm_feature(env, ARM_FEATURE_EL3) &&
+                            (env->cp15.scr_el3 & SCR_IRQ) &&
+                            !arm_el_is_aa64(env, 3)) {
+                        return true;
+                    }
+                } else if (arm_el_is_aa64(env, 3) &&
+                          (env->cp15.scr_el3 & SCR_RW) &&
+                          cur_el == 2) {
+                    /* IRQs not routed to EL2 but currently in EL2 (A64).
+                     * Exception is not taken but remains pending. */
+                    return false;
                 }
             }
         }
-- 
1.8.3.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]