From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36607) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a4HcE-0004ag-Qx for qemu-devel@nongnu.org; Wed, 02 Dec 2015 19:19:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a4HcD-00026p-EN for qemu-devel@nongnu.org; Wed, 02 Dec 2015 19:19:18 -0500 From: Michael Davidsaver Date: Wed, 2 Dec 2015 19:18:53 -0500 Message-Id: <1449101933-24928-27-git-send-email-mdavidsaver@gmail.com> In-Reply-To: <1449101933-24928-1-git-send-email-mdavidsaver@gmail.com> References: <1449101933-24928-1-git-send-email-mdavidsaver@gmail.com> Subject: [Qemu-devel] [PATCH v2 26/26] armv7m: decide whether faults are MemManage or BusFault List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Peter Crosthwaite , qemu-arm@nongnu.org, Michael Davidsaver 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