From nobody Wed Apr 9 00:54:11 2025 Return-Path: qemu-devel-bounces+famz=redhat.com@nongnu.org Received: from zmta03.collab.prod.int.phx2.redhat.com (LHLO zmta03.collab.prod.int.phx2.redhat.com) (10.5.81.10) by zmail26.collab.prod.int.phx2.redhat.com with LMTP; Mon, 4 Sep 2017 08:35:57 -0400 (EDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by zmta03.collab.prod.int.phx2.redhat.com (Postfix) with ESMTP id 0ED2745005 for ; Mon, 4 Sep 2017 08:35:57 -0400 (EDT) Received: by smtp.corp.redhat.com (Postfix) id 0AE4AB9319; Mon, 4 Sep 2017 12:35:57 +0000 (UTC) Delivered-To: famz@redhat.com Received: from mx1.redhat.com (ext-mx05.extmail.prod.ext.phx2.redhat.com [10.5.110.29]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 03640B9310 for ; Mon, 4 Sep 2017 12:35:54 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B7A082C96E0 for ; Mon, 4 Sep 2017 12:35:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B7A082C96E0 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=qemu-devel-bounces+famz=redhat.com@nongnu.org DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com B7A082C96E0 Received: from localhost ([::1]:59570 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1doqbZ-0002ib-08 for famz@redhat.com; Mon, 04 Sep 2017 08:35:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52329) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1doqSE-0004rN-WD for qemu-devel@nongnu.org; Mon, 04 Sep 2017 08:26:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1doqS5-0004eV-5b for qemu-devel@nongnu.org; Mon, 04 Sep 2017 08:26:14 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37108) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1doqS4-0004cC-RX for qemu-devel@nongnu.org; Mon, 04 Sep 2017 08:26:05 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1doqS3-0005Sl-Ru for qemu-devel@nongnu.org; Mon, 04 Sep 2017 13:26:03 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 4 Sep 2017 13:25:40 +0100 Message-Id: <1504527967-29248-10-git-send-email-peter.maydell@linaro.org> In-Reply-To: <1504527967-29248-1-git-send-email-peter.maydell@linaro.org> References: <1504527967-29248-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 09/36] target/arm: Don't store M profile PRIMASK and FAULTMASK in daif X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+famz=redhat.com@nongnu.org Sender: "Qemu-devel" X-Greylist: Sender passed SPF test, Sender IP whitelisted by DNSRBL, ACL 205 matched, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 04 Sep 2017 12:35:54 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Mon, 04 Sep 2017 12:35:54 +0000 (UTC) for IP:'208.118.235.17' DOMAIN:'lists.gnu.org' HELO:'lists.gnu.org' FROM:'redhat.com@nongnu.org' RCPT:'' X-RedHat-Spam-Score: -5.02 (HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_HI,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_PASS) 208.118.235.17 lists.gnu.org 208.118.235.17 lists.gnu.org X-Scanned-By: MIMEDefang 2.78 on 10.5.110.29 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Content-Length: 7149 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" We currently store the M profile CPU register state PRIMASK and FAULTMASK in the daif field of the CPU state in its I and F bits. This is a legacy from the original implementation, which tried to share the cpu_exec_interrupt code between A profile and M profile. We've since separated out the two cases because they are significantly different, so now there is no common code between M and A profile which looks at env->daif: all the uses are either in A-only or M-only code paths. Sharing the state fields now is just confusing, and will make things awkward when we implement v8M, where the PRIMASK and FAULTMASK registers are banked between security states. Switch M profile over to using v7m.faultmask and v7m.primask fields for these registers. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 1501692241-23310-10-git-send-email-peter.maydell@linaro.org --- target/arm/cpu.h | 4 +++- hw/intc/armv7m_nvic.c | 4 ++-- target/arm/cpu.c | 5 ----- target/arm/helper.c | 18 +++++------------- target/arm/machine.c | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 21 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 0b9f937..8ef552a 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -418,6 +418,8 @@ typedef struct CPUARMState { uint32_t bfar; /* BusFault Address */ unsigned mpu_ctrl; /* MPU_CTRL */ int exception; + uint32_t primask; + uint32_t faultmask; } v7m; =20 /* Information associated with an exception about to be taken: @@ -2178,7 +2180,7 @@ static inline int cpu_mmu_index(CPUARMState *env, boo= l ifetch) * we're in a HardFault or NMI handler. */ if ((env->v7m.exception > 0 && env->v7m.exception <=3D 3) - || env->daif & PSTATE_F) { + || env->v7m.faultmask) { return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri); } =20 diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 2e8166a..343bc16 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -167,9 +167,9 @@ static inline int nvic_exec_prio(NVICState *s) CPUARMState *env =3D &s->cpu->env; int running; =20 - if (env->daif & PSTATE_F) { /* FAULTMASK */ + if (env->v7m.faultmask) { running =3D -1; - } else if (env->daif & PSTATE_I) { /* PRIMASK */ + } else if (env->v7m.primask) { running =3D 0; } else if (env->v7m.basepri > 0) { running =3D env->v7m.basepri & nvic_gprio_mask(s); diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 05c038b..b241a63 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -185,11 +185,6 @@ static void arm_cpu_reset(CPUState *s) uint32_t initial_pc; /* Loaded from 0x4 */ uint8_t *rom; =20 - /* For M profile we store FAULTMASK and PRIMASK in the - * PSTATE F and I bits; these are both clear at reset. - */ - env->daif &=3D ~(PSTATE_I | PSTATE_F); - /* The reset value of this bit is IMPDEF, but ARM recommends * that it resets to 1, so QEMU always does that rather than making * it dependent on CPU model. diff --git a/target/arm/helper.c b/target/arm/helper.c index 439ad86..9410856 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6167,7 +6167,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) =20 if (env->v7m.exception !=3D ARMV7M_EXCP_NMI) { /* Auto-clear FAULTMASK on return from other than NMI */ - env->daif &=3D ~PSTATE_F; + env->v7m.faultmask =3D 0; } =20 switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception)) { @@ -8713,12 +8713,12 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t= reg) return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ? env->regs[13] : env->v7m.other_sp; case 16: /* PRIMASK */ - return (env->daif & PSTATE_I) !=3D 0; + return env->v7m.primask; case 17: /* BASEPRI */ case 18: /* BASEPRI_MAX */ return env->v7m.basepri; case 19: /* FAULTMASK */ - return (env->daif & PSTATE_F) !=3D 0; + return env->v7m.faultmask; default: qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special" " register %d\n", reg); @@ -8773,11 +8773,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t mask= reg, uint32_t val) } break; case 16: /* PRIMASK */ - if (val & 1) { - env->daif |=3D PSTATE_I; - } else { - env->daif &=3D ~PSTATE_I; - } + env->v7m.primask =3D val & 1; break; case 17: /* BASEPRI */ env->v7m.basepri =3D val & 0xff; @@ -8788,11 +8784,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t mask= reg, uint32_t val) env->v7m.basepri =3D val; break; case 19: /* FAULTMASK */ - if (val & 1) { - env->daif |=3D PSTATE_F; - } else { - env->daif &=3D ~PSTATE_F; - } + env->v7m.faultmask =3D val & 1; break; case 20: /* CONTROL */ /* Writing to the SPSEL bit only has an effect if we are in diff --git a/target/arm/machine.c b/target/arm/machine.c index 1f66da4..2fb4b762 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -97,6 +97,17 @@ static bool m_needed(void *opaque) return arm_feature(env, ARM_FEATURE_M); } =20 +static const VMStateDescription vmstate_m_faultmask_primask =3D { + .name =3D "cpu/m/faultmask-primask", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(env.v7m.faultmask, ARMCPU), + VMSTATE_UINT32(env.v7m.primask, ARMCPU), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_m =3D { .name =3D "cpu/m", .version_id =3D 4, @@ -115,6 +126,10 @@ static const VMStateDescription vmstate_m =3D { VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU), VMSTATE_INT32(env.v7m.exception, ARMCPU), VMSTATE_END_OF_LIST() + }, + .subsections =3D (const VMStateDescription*[]) { + &vmstate_m_faultmask_primask, + NULL } }; =20 @@ -201,6 +216,24 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t = size, CPUARMState *env =3D &cpu->env; uint32_t val =3D qemu_get_be32(f); =20 + if (arm_feature(env, ARM_FEATURE_M)) { + /* If the I or F bits are set then this is a migration from + * an old QEMU which still stored the M profile FAULTMASK + * and PRIMASK in env->daif. Set v7m.faultmask and v7m.primask + * accordingly, and then clear the bits so they don't confuse + * cpsr_write(). For a new QEMU, the bits here will always be + * clear, and the data is transferred using the + * vmstate_m_faultmask_primask subsection. + */ + if (val & CPSR_F) { + env->v7m.faultmask =3D 1; + } + if (val & CPSR_I) { + env->v7m.primask =3D 1; + } + val &=3D ~(CPSR_F | CPSR_I); + } + env->aarch64 =3D ((val & PSTATE_nRW) =3D=3D 0); =20 if (is_a64(env)) { --=20 2.7.4