SCR.{IRQ/FIQ} bits allows to route IRQ/FIQ exceptions to monitor CPU
mode. When taking IRQ exception to monitor mode FIQ exception is
additionally masked.

Signed-off-by: Sergey Fedorov <s.fedo...@samsung.com>
Signed-off-by: Fabian Aggeler <aggel...@ethz.ch>
---
 target-arm/cpu.h    | 2 ++
 target-arm/helper.c | 9 +++++++++
 2 files changed, 11 insertions(+)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index f6261c2..212cb64 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -673,6 +673,8 @@ static inline int arm_feature(CPUARMState *env, int feature)
 }
 
 #define SCR_NS (1U << 0)
+#define SCR_IRQ (1U << 1)
+#define SCR_FIQ (1U << 2)
 
 /* Return true if the processor is in secure state */
 static inline bool arm_is_secure(CPUARMState *env)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index deff3de..a5ba480 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3597,12 +3597,21 @@ void arm_cpu_do_interrupt(CPUState *cs)
         /* Disable IRQ and imprecise data aborts.  */
         mask = CPSR_A | CPSR_I;
         offset = 4;
+        if (env->cp15.c1_scr & SCR_IRQ) {
+            /* IRQ routed to monitor mode */
+            new_mode = ARM_CPU_MODE_MON;
+            mask |= CPSR_F;
+        }
         break;
     case EXCP_FIQ:
         new_mode = ARM_CPU_MODE_FIQ;
         addr = 0x1c;
         /* Disable FIQ, IRQ and imprecise data aborts.  */
         mask = CPSR_A | CPSR_I | CPSR_F;
+        if (env->cp15.c1_scr & SCR_FIQ) {
+            /* FIQ routed to monitor mode */
+            new_mode = ARM_CPU_MODE_MON;
+        }
         offset = 4;
         break;
     case EXCP_SMC:
-- 
1.8.3.2


Reply via email to