qemu-arm
[Top][All Lists]
Advanced

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

[Qemu-arm] [PATCH v2 26/26] armv7m: decide whether faults are MemManage


From: Michael Davidsaver
Subject: [Qemu-arm] [PATCH v2 26/26] armv7m: decide whether faults are MemManage or BusFault
Date: Wed, 2 Dec 2015 19:18:53 -0500

General logic is that operations stopped by the MPU are MemManage,
and those which go through the MPU and are caught by the unassigned
handle are BusFault.
---
 target-arm/helper.c | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index c890b3a..630d5c9 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5546,12 +5546,35 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
         break;
     case EXCP_PREFETCH_ABORT:
     case EXCP_DATA_ABORT:
-        /* TODO: if we implemented the MPU registers, this is where we
-         * should set the MMFAR, etc from exception.fsr and exception.vaddress.
-         */
-        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
-        env->v7m.mmfar = env->exception.vaddress;
-        env->v7m.cfsr = (1<<1)|(1<<7); /* DACCVIOL and MMARVALID */
+        switch (env->exception.fsr & 0xf) {
+        case 0x8: /* External Abort */
+            switch (cs->exception_index) {
+            case EXCP_PREFETCH_ABORT:
+                env->v7m.cfsr |= (1<<(8+1)); /* PRECISERR */
+                break;
+            case EXCP_DATA_ABORT:
+                env->v7m.cfsr |= (1<<(8+0)); /* IBUSERR */
+                break;
+            }
+            armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS);
+            env->v7m.bfar = env->exception.vaddress;
+            env->v7m.cfsr |= (1<<(8+7)); /* BFARVALID */
+            break;
+        case 0xd: /* Permission fault */
+        default:
+            switch (cs->exception_index) {
+            case EXCP_PREFETCH_ABORT:
+                env->v7m.cfsr |= (1<<0); /* IACCVIOL */
+                break;
+            case EXCP_DATA_ABORT:
+                env->v7m.cfsr |= (1<<1); /* DACCVIOL */
+                break;
+            }
+            armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
+            env->v7m.mmfar = env->exception.vaddress;
+            env->v7m.cfsr |= (1<<7); /* MMARVALID */
+            break;
+        }
         break;
     case EXCP_BKPT:
         if (semihosting_enabled()) {
-- 
2.1.4




reply via email to

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