From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240554012146.69376353980476; Tue, 12 Sep 2017 11:22:34 -0700 (PDT) Received: from localhost ([::1]:37993 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drppR-0002q6-58 for importer@patchew.org; Tue, 12 Sep 2017 14:22:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43397) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph2-0003Qz-13 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph0-0006RF-SQ for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:51 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37298) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgx-0006Mo-3w; Tue, 12 Sep 2017 14:13:47 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgq-00012z-9z; Tue, 12 Sep 2017 19:13:40 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:48 +0100 Message-Id: <1505240046-11454-2-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 01/19] target/arm: Implement MSR/MRS access to NS banked registers 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" In v8M the MSR and MRS instructions have extra register value encodings to allow secure code to access the non-secure banked version of various special registers. (We don't implement the MSPLIM_NS or PSPLIM_NS aliases, because we don't currently implement the stack limit registers at all.) Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/helper.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 110 insertions(+) diff --git a/target/arm/helper.c b/target/arm/helper.c index 4f41841..f4f2a87 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8892,12 +8892,68 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t= reg) break; case 20: /* CONTROL */ return env->v7m.control[env->v7m.secure]; + case 0x94: /* CONTROL_NS */ + /* We have to handle this here because unprivileged Secure code + * can read the NS CONTROL register. + */ + if (!env->v7m.secure) { + return 0; + } + return env->v7m.control[M_REG_NS]; } =20 if (el =3D=3D 0) { return 0; /* unprivileged reads others as zero */ } =20 + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + switch (reg) { + case 0x88: /* MSP_NS */ + if (!env->v7m.secure) { + return 0; + } + return env->v7m.other_ss_msp; + case 0x89: /* PSP_NS */ + if (!env->v7m.secure) { + return 0; + } + return env->v7m.other_ss_psp; + case 0x90: /* PRIMASK_NS */ + if (!env->v7m.secure) { + return 0; + } + return env->v7m.primask[M_REG_NS]; + case 0x91: /* BASEPRI_NS */ + if (!env->v7m.secure) { + return 0; + } + return env->v7m.basepri[M_REG_NS]; + case 0x93: /* FAULTMASK_NS */ + if (!env->v7m.secure) { + return 0; + } + return env->v7m.faultmask[M_REG_NS]; + case 0x98: /* SP_NS */ + { + /* This gives the non-secure SP selected based on whether we're + * currently in handler mode or not, using the NS CONTROL.SPSE= L. + */ + bool spsel =3D env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSE= L_MASK; + + if (!env->v7m.secure) { + return 0; + } + if (!arm_v7m_is_handler_mode(env) && spsel) { + return env->v7m.other_ss_psp; + } else { + return env->v7m.other_ss_msp; + } + } + default: + break; + } + } + switch (reg) { case 8: /* MSP */ return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MA= SK) ? @@ -8936,6 +8992,60 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t mask= reg, uint32_t val) return; } =20 + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + switch (reg) { + case 0x88: /* MSP_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.other_ss_msp =3D val; + return; + case 0x89: /* PSP_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.other_ss_psp =3D val; + return; + case 0x90: /* PRIMASK_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.primask[M_REG_NS] =3D val & 1; + return; + case 0x91: /* BASEPRI_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.basepri[M_REG_NS] =3D val & 0xff; + return; + case 0x93: /* FAULTMASK_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.faultmask[M_REG_NS] =3D val & 1; + return; + case 0x98: /* SP_NS */ + { + /* This gives the non-secure SP selected based on whether we're + * currently in handler mode or not, using the NS CONTROL.SPSE= L. + */ + bool spsel =3D env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSE= L_MASK; + + if (!env->v7m.secure) { + return; + } + if (!arm_v7m_is_handler_mode(env) && spsel) { + env->v7m.other_ss_psp =3D val; + } else { + env->v7m.other_ss_msp =3D val; + } + return; + } + default: + break; + } + } + switch (reg) { case 0 ... 7: /* xPSR sub-fields */ /* only APSR is actually writable */ --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240179909170.24611085423612; Tue, 12 Sep 2017 11:16:19 -0700 (PDT) Received: from localhost ([::1]:37957 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpjP-0005KY-2W for importer@patchew.org; Tue, 12 Sep 2017 14:16:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43235) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpgx-0003M4-2t for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drpgv-0006N4-QE for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:47 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37276) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgs-0006IX-Mg; Tue, 12 Sep 2017 14:13:42 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgq-00013G-Tx; Tue, 12 Sep 2017 19:13:40 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:49 +0100 Message-Id: <1505240046-11454-3-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 02/19] nvic: Add banked exception states 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" For the v8M security extension, some exceptions must be banked between security states. Add the new vecinfo array which holds the state for the banked exceptions and migrate it if the CPU the NVIC is attached to implements the security extension. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- include/hw/intc/armv7m_nvic.h | 14 +++++++++++++ hw/intc/armv7m_nvic.c | 49 +++++++++++++++++++++++++++++++++++++++= +++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h index 1a4cce7..317601e 100644 --- a/include/hw/intc/armv7m_nvic.h +++ b/include/hw/intc/armv7m_nvic.h @@ -21,6 +21,8 @@ =20 /* Highest permitted number of exceptions (architectural limit) */ #define NVIC_MAX_VECTORS 512 +/* Number of internal exceptions */ +#define NVIC_INTERNAL_VECTORS 16 =20 typedef struct VecInfo { /* Exception priorities can range from -3 to 255; only the unmodifiable @@ -41,6 +43,18 @@ typedef struct NVICState { ARMCPU *cpu; =20 VecInfo vectors[NVIC_MAX_VECTORS]; + /* If the v8M security extension is implemented, some of the internal + * exceptions are banked between security states (ie there exists both + * a Secure and a NonSecure version of the exception and its state): + * HardFault, MemManage, UsageFault, SVCall, PendSV, SysTick (R_PJHV) + * The rest (including all the external exceptions) are not banked, th= ough + * they may be configurable to target either Secure or NonSecure state. + * We store the secure exception state in sec_vectors[] for the banked + * exceptions, and otherwise use only vectors[] (including for excepti= ons + * like SecureFault that unconditionally target Secure state). + * Entries in sec_vectors[] for non-banked exception numbers are unuse= d. + */ + VecInfo sec_vectors[NVIC_INTERNAL_VECTORS]; uint32_t prigroup; =20 /* vectpending and exception_prio are both cached state that can diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index d3e2056..694b9e0 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -47,7 +47,7 @@ * For historical reasons QEMU tends to use "interrupt" and * "exception" more or less interchangeably. */ -#define NVIC_FIRST_IRQ 16 +#define NVIC_FIRST_IRQ NVIC_INTERNAL_VECTORS #define NVIC_MAX_IRQ (NVIC_MAX_VECTORS - NVIC_FIRST_IRQ) =20 /* Effective running priority of the CPU when no exception is active @@ -1158,6 +1158,43 @@ static const VMStateDescription vmstate_VecInfo =3D { } }; =20 +static bool nvic_security_needed(void *opaque) +{ + NVICState *s =3D opaque; + + return arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY); +} + +static int nvic_security_post_load(void *opaque, int version_id) +{ + NVICState *s =3D opaque; + int i; + + /* Check for out of range priority settings */ + if (s->sec_vectors[ARMV7M_EXCP_HARD].prio !=3D -1) { + return 1; + } + for (i =3D ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) { + if (s->sec_vectors[i].prio & ~0xff) { + return 1; + } + } + return 0; +} + +static const VMStateDescription vmstate_nvic_security =3D { + .name =3D "nvic/m-security", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D nvic_security_needed, + .post_load =3D &nvic_security_post_load, + .fields =3D (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS= , 1, + vmstate_VecInfo, VecInfo), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_nvic =3D { .name =3D "armv7m_nvic", .version_id =3D 4, @@ -1195,6 +1232,16 @@ static void armv7m_nvic_reset(DeviceState *dev) s->vectors[ARMV7M_EXCP_NMI].prio =3D -2; s->vectors[ARMV7M_EXCP_HARD].prio =3D -1; =20 + if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { + s->sec_vectors[ARMV7M_EXCP_HARD].enabled =3D 1; + s->sec_vectors[ARMV7M_EXCP_SVC].enabled =3D 1; + s->sec_vectors[ARMV7M_EXCP_PENDSV].enabled =3D 1; + s->sec_vectors[ARMV7M_EXCP_SYSTICK].enabled =3D 1; + + /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC= ) */ + s->sec_vectors[ARMV7M_EXCP_HARD].prio =3D -1; + } + /* Strictly speaking the reset handler should be enabled. * However, we don't simulate soft resets through the NVIC, * and the reset vector should never be pended. --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240362529279.20496784839656; Tue, 12 Sep 2017 11:19:22 -0700 (PDT) Received: from localhost ([::1]:37969 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpmL-0008CI-NB for importer@patchew.org; Tue, 12 Sep 2017 14:19:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43244) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpgx-0003MF-9i for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drpgw-0006NK-4P for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:47 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37276) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgt-0006IX-Kg; Tue, 12 Sep 2017 14:13:43 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgr-00013V-Hy; Tue, 12 Sep 2017 19:13:41 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:50 +0100 Message-Id: <1505240046-11454-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 03/19] nvic: Add cached vectpending_is_s_banked state 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" With banked exceptions, just the exception number in s->vectpending is no longer sufficient to uniquely identify the pending exception. Add a vectpending_is_s_banked bool which is true if the exception is using the sec_vectors[] array. Signed-off-by: Peter Maydell --- include/hw/intc/armv7m_nvic.h | 11 +++++++++-- hw/intc/armv7m_nvic.c | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h index 317601e..87c78b3 100644 --- a/include/hw/intc/armv7m_nvic.h +++ b/include/hw/intc/armv7m_nvic.h @@ -57,10 +57,17 @@ typedef struct NVICState { VecInfo sec_vectors[NVIC_INTERNAL_VECTORS]; uint32_t prigroup; =20 - /* vectpending and exception_prio are both cached state that can - * be recalculated from the vectors[] array and the prigroup field. + /* The following fields are all cached state that can be recalculated + * from the vectors[] and sec_vectors[] arrays and the prigroup field: + * - vectpending + * - vectpending_is_secure + * - exception_prio */ unsigned int vectpending; /* highest prio pending enabled exception */ + /* true if vectpending is a banked secure exception, ie it is in + * sec_vectors[] rather than vectors[] + */ + bool vectpending_is_s_banked; int exception_prio; /* group prio of the highest prio active exception= */ =20 MemoryRegion sysregmem; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 694b9e0..417a456 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -1250,6 +1250,7 @@ static void armv7m_nvic_reset(DeviceState *dev) =20 s->exception_prio =3D NVIC_NOEXC_PRIO; s->vectpending =3D 0; + s->vectpending_is_s_banked =3D false; } =20 static void nvic_systick_trigger(void *opaque, int n, int level) --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 15052403022815.202387739406618; Tue, 12 Sep 2017 11:18:22 -0700 (PDT) Received: from localhost ([::1]:37967 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drplN-0007IY-8E for importer@patchew.org; Tue, 12 Sep 2017 14:18:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43258) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpgx-0003Mw-Or for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drpgw-0006NR-9A for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:47 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37288) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgt-0006Js-5P; Tue, 12 Sep 2017 14:13:43 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgs-000141-6X; Tue, 12 Sep 2017 19:13:42 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:51 +0100 Message-Id: <1505240046-11454-5-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 04/19] nvic: Add cached vectpending_prio state 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Instead of looking up the pending priority in nvic_pending_prio(), cache it in a new state struct field. The calculation of the pending priority given the interrupt number is more complicated in v8M with the security extension, so the caching will be worthwhile. This changes nvic_pending_prio() from returning a full (group + subpriority) priority value to returning a group priority. This doesn't require changes to its callsites because we use it only in comparisons of the form execution_prio > nvic_pending_prio() and execution priority is always a group priority, so a test (exec prio > full prio) is true if and only if (execprio > group_prio). (Architecturally the expected comparison is with the group priority for this sort of "would we preempt" test; we were only doing a test with a full priority as an optimisation to avoid the mask, which is possible precisely because the two comparisons always give the same answer.) Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- include/hw/intc/armv7m_nvic.h | 2 ++ hw/intc/armv7m_nvic.c | 23 +++++++++++++---------- hw/intc/trace-events | 2 +- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h index 87c78b3..329774e 100644 --- a/include/hw/intc/armv7m_nvic.h +++ b/include/hw/intc/armv7m_nvic.h @@ -62,6 +62,7 @@ typedef struct NVICState { * - vectpending * - vectpending_is_secure * - exception_prio + * - vectpending_prio */ unsigned int vectpending; /* highest prio pending enabled exception */ /* true if vectpending is a banked secure exception, ie it is in @@ -69,6 +70,7 @@ typedef struct NVICState { */ bool vectpending_is_s_banked; int exception_prio; /* group prio of the highest prio active exception= */ + int vectpending_prio; /* group prio of the exeception in vectpending */ =20 MemoryRegion sysregmem; MemoryRegion sysreg_ns_mem; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 417a456..8388d64 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -61,10 +61,10 @@ static const uint8_t nvic_id[] =3D { =20 static int nvic_pending_prio(NVICState *s) { - /* return the priority of the current pending interrupt, + /* return the group priority of the current pending interrupt, * or NVIC_NOEXC_PRIO if no interrupt is pending */ - return s->vectpending ? s->vectors[s->vectpending].prio : NVIC_NOEXC_P= RIO; + return s->vectpending_prio; } =20 /* Return the value of the ISCR RETTOBASE bit: @@ -156,10 +156,17 @@ static void nvic_recompute_state(NVICState *s) active_prio &=3D nvic_gprio_mask(s); } =20 + if (pend_prio > 0) { + pend_prio &=3D nvic_gprio_mask(s); + } + s->vectpending =3D pend_irq; + s->vectpending_prio =3D pend_prio; s->exception_prio =3D active_prio; =20 - trace_nvic_recompute_state(s->vectpending, s->exception_prio); + trace_nvic_recompute_state(s->vectpending, + s->vectpending_prio, + s->exception_prio); } =20 /* Return the current execution priority of the CPU @@ -323,7 +330,6 @@ void armv7m_nvic_acknowledge_irq(void *opaque) CPUARMState *env =3D &s->cpu->env; const int pending =3D s->vectpending; const int running =3D nvic_exec_prio(s); - int pendgroupprio; VecInfo *vec; =20 assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); @@ -333,13 +339,9 @@ void armv7m_nvic_acknowledge_irq(void *opaque) assert(vec->enabled); assert(vec->pending); =20 - pendgroupprio =3D vec->prio; - if (pendgroupprio > 0) { - pendgroupprio &=3D nvic_gprio_mask(s); - } - assert(pendgroupprio < running); + assert(s->vectpending_prio < running); =20 - trace_nvic_acknowledge_irq(pending, vec->prio); + trace_nvic_acknowledge_irq(pending, s->vectpending_prio); =20 vec->active =3D 1; vec->pending =3D 0; @@ -1251,6 +1253,7 @@ static void armv7m_nvic_reset(DeviceState *dev) s->exception_prio =3D NVIC_NOEXC_PRIO; s->vectpending =3D 0; s->vectpending_is_s_banked =3D false; + s->vectpending_prio =3D NVIC_NOEXC_PRIO; } =20 static void nvic_systick_trigger(void *opaque, int n, int level) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 4762329..5635a5f 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -167,7 +167,7 @@ gicv3_redist_set_irq(uint32_t cpu, int irq, int level) = "GICv3 redistributor 0x%x gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pen= ding SGI %d" =20 # hw/intc/armv7m_nvic.c -nvic_recompute_state(int vectpending, int exception_prio) "NVIC state reco= mputed: vectpending %d exception_prio %d" +nvic_recompute_state(int vectpending, int vectpending_prio, int exception_= prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_= prio %d" nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d priority %d" nvic_irq_update(int vectpending, int pendprio, int exception_prio, int lev= el) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq lin= e to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq= %d to HardFault: insufficient priority %d >=3D %d" --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240371193383.1102011241144; Tue, 12 Sep 2017 11:19:31 -0700 (PDT) Received: from localhost ([::1]:37970 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpmU-0008MM-Bw for importer@patchew.org; Tue, 12 Sep 2017 14:19:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43373) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph1-0003Qa-5X for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drpgz-0006Q9-4w for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:51 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37292) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgv-0006Ln-BH; Tue, 12 Sep 2017 14:13:45 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgs-00014J-RH; Tue, 12 Sep 2017 19:13:42 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:52 +0100 Message-Id: <1505240046-11454-6-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 05/19] nvic: Implement AIRCR changes for v8M 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The Application Interrupt and Reset Control Register has some changes for v8M: * new bits SYSRESETREQS, BFHFNMINS and PRIS: these all have real state if the security extension is implemented and otherwise are constant * the PRIGROUP field is banked between security states * non-secure code can be blocked from using the SYSRESET bit to reset the system if SYSRESETREQS is set Implement the new state and the changes to register read and write. For the moment we ignore the effects of the secure PRIGROUP. We will implement the effects of PRIS and BFHFNMIS later. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- include/hw/intc/armv7m_nvic.h | 3 ++- target/arm/cpu.h | 12 +++++++++++ hw/intc/armv7m_nvic.c | 49 +++++++++++++++++++++++++++++++++------= ---- target/arm/cpu.c | 7 +++++++ 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h index 329774e..e96e488 100644 --- a/include/hw/intc/armv7m_nvic.h +++ b/include/hw/intc/armv7m_nvic.h @@ -55,7 +55,8 @@ typedef struct NVICState { * Entries in sec_vectors[] for non-banked exception numbers are unuse= d. */ VecInfo sec_vectors[NVIC_INTERNAL_VECTORS]; - uint32_t prigroup; + /* The PRIGROUP field in AIRCR is banked */ + uint32_t prigroup[M_REG_NUM_BANKS]; =20 /* The following fields are all cached state that can be recalculated * from the vectors[] and sec_vectors[] arrays and the prigroup field: diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 5a1f957..7e661c8 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -449,6 +449,7 @@ typedef struct CPUARMState { int exception; uint32_t primask[M_REG_NUM_BANKS]; uint32_t faultmask[M_REG_NUM_BANKS]; + uint32_t aircr; /* only holds r/w state if security extn implement= ed */ uint32_t secure; /* Is CPU in Secure state? (not guest visible) */ } v7m; =20 @@ -1200,6 +1201,17 @@ FIELD(V7M_CCR, STKALIGN, 9, 1) FIELD(V7M_CCR, DC, 16, 1) FIELD(V7M_CCR, IC, 17, 1) =20 +/* V7M AIRCR bits */ +FIELD(V7M_AIRCR, VECTRESET, 0, 1) +FIELD(V7M_AIRCR, VECTCLRACTIVE, 1, 1) +FIELD(V7M_AIRCR, SYSRESETREQ, 2, 1) +FIELD(V7M_AIRCR, SYSRESETREQS, 3, 1) +FIELD(V7M_AIRCR, PRIGROUP, 8, 3) +FIELD(V7M_AIRCR, BFHFNMINS, 13, 1) +FIELD(V7M_AIRCR, PRIS, 14, 1) +FIELD(V7M_AIRCR, ENDIANNESS, 15, 1) +FIELD(V7M_AIRCR, VECTKEY, 16, 16) + /* V7M CFSR bits for MMFSR */ FIELD(V7M_CFSR, IACCVIOL, 0, 1) FIELD(V7M_CFSR, DACCVIOL, 1, 1) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 8388d64..585b1a7 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -129,7 +129,7 @@ static bool nvic_isrpending(NVICState *s) */ static inline uint32_t nvic_gprio_mask(NVICState *s) { - return ~0U << (s->prigroup + 1); + return ~0U << (s->prigroup[M_REG_NS] + 1); } =20 /* Recompute vectpending and exception_prio */ @@ -451,8 +451,21 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offs= et, MemTxAttrs attrs) return val; case 0xd08: /* Vector Table Offset. */ return cpu->env.v7m.vecbase[attrs.secure]; - case 0xd0c: /* Application Interrupt/Reset Control. */ - return 0xfa050000 | (s->prigroup << 8); + case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */ + val =3D 0xfa050000 | (s->prigroup[attrs.secure] << 8); + if (attrs.secure) { + /* s->aircr stores PRIS, BFHFNMINS, SYSRESETREQS */ + val |=3D cpu->env.v7m.aircr; + } else { + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* BFHFNMINS is R/O from NS; other bits are RAZ/WI. If + * security isn't supported then BFHFNMINS is RAO (and + * the bit in env.v7m.aircr is always set). + */ + val |=3D cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK; + } + } + return val; case 0xd10: /* System Control. */ /* TODO: Implement SLEEPONEXIT. */ return 0; @@ -660,22 +673,35 @@ static void nvic_writel(NVICState *s, uint32_t offset= , uint32_t value, case 0xd08: /* Vector Table Offset. */ cpu->env.v7m.vecbase[attrs.secure] =3D value & 0xffffff80; break; - case 0xd0c: /* Application Interrupt/Reset Control. */ - if ((value >> 16) =3D=3D 0x05fa) { - if (value & 4) { - qemu_irq_pulse(s->sysresetreq); + case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */ + if ((value >> R_V7M_AIRCR_VECTKEY_SHIFT) =3D=3D 0x05fa) { + if (value & R_V7M_AIRCR_SYSRESETREQ_MASK) { + if (attrs.secure || + !(cpu->env.v7m.aircr & R_V7M_AIRCR_SYSRESETREQS_MASK))= { + qemu_irq_pulse(s->sysresetreq); + } } - if (value & 2) { + if (value & R_V7M_AIRCR_VECTCLRACTIVE_MASK) { qemu_log_mask(LOG_GUEST_ERROR, "Setting VECTCLRACTIVE when not in DEBUG mod= e " "is UNPREDICTABLE\n"); } - if (value & 1) { + if (value & R_V7M_AIRCR_VECTRESET_MASK) { + /* NB: this bit is RES0 in v8M */ qemu_log_mask(LOG_GUEST_ERROR, "Setting VECTRESET when not in DEBUG mode " "is UNPREDICTABLE\n"); } - s->prigroup =3D extract32(value, 8, 3); + s->prigroup[attrs.secure] =3D extract32(value, + R_V7M_AIRCR_PRIGROUP_SHI= FT, + R_V7M_AIRCR_PRIGROUP_LEN= GTH); + if (attrs.secure) { + /* These bits are only writable by secure */ + cpu->env.v7m.aircr =3D value & + (R_V7M_AIRCR_SYSRESETREQS_MASK | + R_V7M_AIRCR_BFHFNMINS_MASK | + R_V7M_AIRCR_PRIS_MASK); + } nvic_irq_update(s); } break; @@ -1193,6 +1219,7 @@ static const VMStateDescription vmstate_nvic_security= =3D { .fields =3D (VMStateField[]) { VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS= , 1, vmstate_VecInfo, VecInfo), + VMSTATE_UINT32(prigroup[M_REG_S], NVICState), VMSTATE_END_OF_LIST() } }; @@ -1205,7 +1232,7 @@ static const VMStateDescription vmstate_nvic =3D { .fields =3D (VMStateField[]) { VMSTATE_STRUCT_ARRAY(vectors, NVICState, NVIC_MAX_VECTORS, 1, vmstate_VecInfo, VecInfo), - VMSTATE_UINT32(prigroup, NVICState), + VMSTATE_UINT32(prigroup[M_REG_NS], NVICState), VMSTATE_END_OF_LIST() } }; diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 412e94c..6ee169d 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -187,6 +187,13 @@ static void arm_cpu_reset(CPUState *s) =20 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { env->v7m.secure =3D true; + } else { + /* This bit resets to 0 if security is supported, but 1 if + * it is not. The bit is not present in v7M, but we set it + * here so we can avoid having to make checks on it conditional + * on ARM_FEATURE_V8 (we don't let the guest see the bit). + */ + env->v7m.aircr =3D R_V7M_AIRCR_BFHFNMINS_MASK; } =20 /* In v7M the reset value of this bit is IMPDEF, but ARM recommends --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 150524014278940.806321545706396; Tue, 12 Sep 2017 11:15:42 -0700 (PDT) Received: from localhost ([::1]:37955 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpin-0004nO-1Q for importer@patchew.org; Tue, 12 Sep 2017 14:15:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43278) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpgy-0003Nb-8m for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drpgx-0006OM-3M for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:48 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37292) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgu-0006Ln-FK; Tue, 12 Sep 2017 14:13:44 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgt-00014o-Hz; Tue, 12 Sep 2017 19:13:43 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:53 +0100 Message-Id: <1505240046-11454-7-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 06/19] nvic: Make ICSR.RETTOBASE handle banked exceptions 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Update the code in nvic_rettobase() so that it checks the sec_vectors[] array as well as the vectors[] array if needed. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 585b1a7..edaf60c 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -84,9 +84,12 @@ static int nvic_pending_prio(NVICState *s) static bool nvic_rettobase(NVICState *s) { int irq, nhand =3D 0; + bool check_sec =3D arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY); =20 for (irq =3D ARMV7M_EXCP_RESET; irq < s->num_irq; irq++) { - if (s->vectors[irq].active) { + if (s->vectors[irq].active || + (check_sec && irq < NVIC_INTERNAL_VECTORS && + s->sec_vectors[irq].active)) { nhand++; if (nhand =3D=3D 2) { return 0; --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240179110671.6592691555777; Tue, 12 Sep 2017 11:16:19 -0700 (PDT) Received: from localhost ([::1]:37956 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpjO-0005JX-3b for importer@patchew.org; Tue, 12 Sep 2017 14:16:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43418) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph2-0003Rj-I4 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph0-0006R9-Sp for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:52 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37292) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgw-0006Ln-Fp; Tue, 12 Sep 2017 14:13:46 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgu-00015X-8t; Tue, 12 Sep 2017 19:13:44 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:54 +0100 Message-Id: <1505240046-11454-8-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 07/19] nvic: Implement NVIC_ITNS registers 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" For v8M, the NVIC has a new set of registers per interrupt, NVIC_ITNS. These determine whether the interrupt targets Secure or Non-secure state. Implement the register read/write code for these, and make them cause NVIC_IABR, NVIC_ICER, NVIC_ISER, NVIC_ICPR, NVIC_IPR and NVIC_ISPR to RAZ/WI for non-secure accesses to fields corresponding to interrupts which are configured to target secure state. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- include/hw/intc/armv7m_nvic.h | 3 ++ hw/intc/armv7m_nvic.c | 74 +++++++++++++++++++++++++++++++++++++++= ---- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h index e96e488..ac7997c 100644 --- a/include/hw/intc/armv7m_nvic.h +++ b/include/hw/intc/armv7m_nvic.h @@ -58,6 +58,9 @@ typedef struct NVICState { /* The PRIGROUP field in AIRCR is banked */ uint32_t prigroup[M_REG_NUM_BANKS]; =20 + /* v8M NVIC_ITNS state (stored as a bool per bit) */ + bool itns[NVIC_MAX_VECTORS]; + /* The following fields are all cached state that can be recalculated * from the vectors[] and sec_vectors[] arrays and the prigroup field: * - vectpending diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index edaf60c..b97dbe3 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -423,6 +423,25 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offs= et, MemTxAttrs attrs) switch (offset) { case 4: /* Interrupt Control Type. */ return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1; + case 0x380 ... 0x3bf: /* NVIC_ITNS */ + { + int startvec =3D 32 * (offset - 0x380) + NVIC_FIRST_IRQ; + int i; + + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return 0; + } + val =3D 0; + for (i =3D 0; i < 32 && startvec + i < s->num_irq; i++) { + if (s->itns[startvec + i]) { + val |=3D (1 << i); + } + } + return val; + } case 0xd00: /* CPUID Base. */ return cpu->midr; case 0xd04: /* Interrupt Control State. */ @@ -658,6 +677,23 @@ static void nvic_writel(NVICState *s, uint32_t offset,= uint32_t value, ARMCPU *cpu =3D s->cpu; =20 switch (offset) { + case 0x380 ... 0x3bf: /* NVIC_ITNS */ + { + int startvec =3D 32 * (offset - 0x380) + NVIC_FIRST_IRQ; + int i; + + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + break; + } + for (i =3D 0; i < 32 && startvec + i < s->num_irq; i++) { + s->itns[startvec + i] =3D value & (1 << i); + } + nvic_irq_update(s); + break; + } case 0xd04: /* Interrupt Control State. */ if (value & (1 << 31)) { armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI); @@ -966,7 +1002,8 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwad= dr addr, startvec =3D offset - 0x180 + NVIC_FIRST_IRQ; /* vector # */ =20 for (i =3D 0, end =3D size * 8; i < end && startvec + i < s->num_i= rq; i++) { - if (s->vectors[startvec + i].enabled) { + if (s->vectors[startvec + i].enabled && + (attrs.secure || s->itns[startvec + i])) { val |=3D (1 << i); } } @@ -978,7 +1015,8 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwad= dr addr, val =3D 0; startvec =3D offset - 0x280 + NVIC_FIRST_IRQ; /* vector # */ for (i =3D 0, end =3D size * 8; i < end && startvec + i < s->num_i= rq; i++) { - if (s->vectors[startvec + i].pending) { + if (s->vectors[startvec + i].pending && + (attrs.secure || s->itns[startvec + i])) { val |=3D (1 << i); } } @@ -988,7 +1026,8 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwad= dr addr, startvec =3D offset - 0x300 + NVIC_FIRST_IRQ; /* vector # */ =20 for (i =3D 0, end =3D size * 8; i < end && startvec + i < s->num_i= rq; i++) { - if (s->vectors[startvec + i].active) { + if (s->vectors[startvec + i].active && + (attrs.secure || s->itns[startvec + i])) { val |=3D (1 << i); } } @@ -998,7 +1037,9 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwad= dr addr, startvec =3D offset - 0x400 + NVIC_FIRST_IRQ; /* vector # */ =20 for (i =3D 0; i < size && startvec + i < s->num_irq; i++) { - val |=3D s->vectors[startvec + i].prio << (8 * i); + if (attrs.secure || s->itns[startvec + i]) { + val |=3D s->vectors[startvec + i].prio << (8 * i); + } } break; case 0xd18 ... 0xd23: /* System Handler Priority. */ @@ -1055,7 +1096,8 @@ static MemTxResult nvic_sysreg_write(void *opaque, hw= addr addr, startvec =3D 8 * (offset - 0x180) + NVIC_FIRST_IRQ; =20 for (i =3D 0, end =3D size * 8; i < end && startvec + i < s->num_i= rq; i++) { - if (value & (1 << i)) { + if (value & (1 << i) && + (attrs.secure || s->itns[startvec + i])) { s->vectors[startvec + i].enabled =3D setval; } } @@ -1072,7 +1114,8 @@ static MemTxResult nvic_sysreg_write(void *opaque, hw= addr addr, startvec =3D 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */ =20 for (i =3D 0, end =3D size * 8; i < end && startvec + i < s->num_i= rq; i++) { - if (value & (1 << i)) { + if (value & (1 << i) && + (attrs.secure || s->itns[startvec + i])) { s->vectors[startvec + i].pending =3D setval; } } @@ -1084,7 +1127,9 @@ static MemTxResult nvic_sysreg_write(void *opaque, hw= addr addr, startvec =3D 8 * (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */ =20 for (i =3D 0; i < size && startvec + i < s->num_irq; i++) { - set_prio(s, startvec + i, (value >> (i * 8)) & 0xff); + if (attrs.secure || s->itns[startvec + i]) { + set_prio(s, startvec + i, (value >> (i * 8)) & 0xff); + } } nvic_irq_update(s); return MEMTX_OK; @@ -1223,6 +1268,7 @@ static const VMStateDescription vmstate_nvic_security= =3D { VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS= , 1, vmstate_VecInfo, VecInfo), VMSTATE_UINT32(prigroup[M_REG_S], NVICState), + VMSTATE_BOOL_ARRAY(itns, NVICState, NVIC_MAX_VECTORS), VMSTATE_END_OF_LIST() } }; @@ -1284,6 +1330,20 @@ static void armv7m_nvic_reset(DeviceState *dev) s->vectpending =3D 0; s->vectpending_is_s_banked =3D false; s->vectpending_prio =3D NVIC_NOEXC_PRIO; + + if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { + memset(s->itns, 0, sizeof(s->itns)); + } else { + /* This state is constant and not guest accessible in a non-securi= ty + * NVIC; we set the bits to true to avoid having to do a feature + * bit check in the NVIC enable/pend/etc register accessors. + */ + int i; + + for (i =3D NVIC_FIRST_IRQ; i < ARRAY_SIZE(s->itns); i++) { + s->itns[i] =3D true; + } + } } =20 static void nvic_systick_trigger(void *opaque, int n, int level) --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240705310782.8750291181383; Tue, 12 Sep 2017 11:25:05 -0700 (PDT) Received: from localhost ([::1]:38004 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drprs-0005eN-GD for importer@patchew.org; Tue, 12 Sep 2017 14:25:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43478) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph4-0003Tz-3N for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph1-0006S0-Uj for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:54 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37298) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgw-0006Mo-0k; Tue, 12 Sep 2017 14:13:46 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgv-000162-0H; Tue, 12 Sep 2017 19:13:45 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:55 +0100 Message-Id: <1505240046-11454-9-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 08/19] nvic: Handle banked exceptions in nvic_recompute_state() 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Update the nvic_recompute_state() code to handle the security extension and its associated banked registers. Code that uses the resulting cached state (ie the irq acknowledge and complete code) will be updated in a later commit. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++= ++-- hw/intc/trace-events | 1 + 2 files changed, 147 insertions(+), 5 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index b97dbe3..fb824e6 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -54,6 +54,8 @@ * (higher than the highest possible priority value) */ #define NVIC_NOEXC_PRIO 0x100 +/* Maximum priority of non-secure exceptions when AIRCR.PRIS is set */ +#define NVIC_NS_PRIO_LIMIT 0x80 =20 static const uint8_t nvic_id[] =3D { 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 @@ -126,13 +128,139 @@ static bool nvic_isrpending(NVICState *s) return false; } =20 +static bool exc_is_banked(int exc) +{ + /* Return true if this is one of the limited set of exceptions which + * are banked (and thus have state in sec_vectors[]) + */ + return exc =3D=3D ARMV7M_EXCP_HARD || + exc =3D=3D ARMV7M_EXCP_MEM || + exc =3D=3D ARMV7M_EXCP_USAGE || + exc =3D=3D ARMV7M_EXCP_SVC || + exc =3D=3D ARMV7M_EXCP_PENDSV || + exc =3D=3D ARMV7M_EXCP_SYSTICK; +} + /* Return a mask word which clears the subpriority bits from * a priority value for an M-profile exception, leaving only * the group priority. */ -static inline uint32_t nvic_gprio_mask(NVICState *s) +static inline uint32_t nvic_gprio_mask(NVICState *s, bool secure) +{ + return ~0U << (s->prigroup[secure] + 1); +} + +static bool exc_targets_secure(NVICState *s, int exc) +{ + /* Return true if this non-banked exception targets Secure state. */ + if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { + return false; + } + + if (exc >=3D NVIC_FIRST_IRQ) { + return !s->itns[exc]; + } + + /* Function shouldn't be called for banked exceptions. */ + assert(!exc_is_banked(exc)); + + switch (exc) { + case ARMV7M_EXCP_NMI: + case ARMV7M_EXCP_BUS: + return !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK); + case ARMV7M_EXCP_SECURE: + return true; + case ARMV7M_EXCP_DEBUG: + /* TODO: controlled by DEMCR.SDME, which we don't yet implement */ + return false; + default: + /* reset, and reserved (unused) low exception numbers. + * We'll get called by code that loops through all the exception + * numbers, but it doesn't matter what we return here as these + * non-existent exceptions will never be pended or active. + */ + return true; + } +} + +static int exc_group_prio(NVICState *s, int rawprio, bool targets_secure) +{ + /* Return the group priority for this exception, given its raw + * (group-and-subgroup) priority value and whether it is targeting + * secure state or not. + */ + if (rawprio < 0) { + return rawprio; + } + rawprio &=3D nvic_gprio_mask(s, targets_secure); + /* AIRCR.PRIS causes us to squash all NS priorities into the + * lower half of the total range + */ + if (!targets_secure && + (s->cpu->env.v7m.aircr & R_V7M_AIRCR_PRIS_MASK)) { + rawprio =3D (rawprio >> 1) + NVIC_NS_PRIO_LIMIT; + } + return rawprio; +} + +/* Recompute vectpending and exception_prio for a CPU which implements + * the Security extension + */ +static void nvic_recompute_state_secure(NVICState *s) { - return ~0U << (s->prigroup[M_REG_NS] + 1); + int i, bank; + int pend_prio =3D NVIC_NOEXC_PRIO; + int active_prio =3D NVIC_NOEXC_PRIO; + int pend_irq =3D 0; + bool pending_is_s_banked =3D false; + + /* R_CQRV: precedence is by: + * - lowest group priority; if both the same then + * - lowest subpriority; if both the same then + * - lowest exception number; if both the same (ie banked) then + * - secure exception takes precedence + * Compare pseudocode RawExecutionPriority. + * Annoyingly, now we have two prigroup values (for S and NS) + * we can't do the loop comparison on raw priority values. + */ + for (i =3D 1; i < s->num_irq; i++) { + for (bank =3D M_REG_S; bank >=3D M_REG_NS; bank--) { + VecInfo *vec; + int prio; + bool targets_secure; + + if (bank =3D=3D M_REG_S) { + if (!exc_is_banked(i)) { + continue; + } + vec =3D &s->sec_vectors[i]; + targets_secure =3D true; + } else { + vec =3D &s->vectors[i]; + targets_secure =3D !exc_is_banked(i) && exc_targets_secure= (s, i); + } + + prio =3D exc_group_prio(s, vec->prio, targets_secure); + if (vec->enabled && vec->pending && prio < pend_prio) { + pend_prio =3D prio; + pend_irq =3D i; + pending_is_s_banked =3D (bank =3D=3D M_REG_S); + } + if (vec->active && prio < active_prio) { + active_prio =3D prio; + } + } + } + + s->vectpending_is_s_banked =3D pending_is_s_banked; + s->vectpending =3D pend_irq; + s->vectpending_prio =3D pend_prio; + s->exception_prio =3D active_prio; + + trace_nvic_recompute_state_secure(s->vectpending, + s->vectpending_is_s_banked, + s->vectpending_prio, + s->exception_prio); } =20 /* Recompute vectpending and exception_prio */ @@ -143,6 +271,18 @@ static void nvic_recompute_state(NVICState *s) int active_prio =3D NVIC_NOEXC_PRIO; int pend_irq =3D 0; =20 + /* In theory we could write one function that handled both + * the "security extension present" and "not present"; however + * the security related changes significantly complicate the + * recomputation just by themselves and mixing both cases together + * would be even worse, so we retain a separate non-secure-only + * version for CPUs which don't implement the security extension. + */ + if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { + nvic_recompute_state_secure(s); + return; + } + for (i =3D 1; i < s->num_irq; i++) { VecInfo *vec =3D &s->vectors[i]; =20 @@ -156,11 +296,11 @@ static void nvic_recompute_state(NVICState *s) } =20 if (active_prio > 0) { - active_prio &=3D nvic_gprio_mask(s); + active_prio &=3D nvic_gprio_mask(s, false); } =20 if (pend_prio > 0) { - pend_prio &=3D nvic_gprio_mask(s); + pend_prio &=3D nvic_gprio_mask(s, false); } =20 s->vectpending =3D pend_irq; @@ -186,7 +326,8 @@ static inline int nvic_exec_prio(NVICState *s) } else if (env->v7m.primask[env->v7m.secure]) { running =3D 0; } else if (env->v7m.basepri[env->v7m.secure] > 0) { - running =3D env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s); + running =3D env->v7m.basepri[env->v7m.secure] & + nvic_gprio_mask(s, env->v7m.secure); } else { running =3D NVIC_NOEXC_PRIO; /* lower than any possible priority */ } diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 5635a5f..0b1fba3 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -168,6 +168,7 @@ gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 red= istributor 0x%x pending S =20 # hw/intc/armv7m_nvic.c nvic_recompute_state(int vectpending, int vectpending_prio, int exception_= prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_= prio %d" +nvic_recompute_state_secure(int vectpending, bool vectpending_is_s_banked,= int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpend= ing %d is_s_banked %d vectpending_prio %d exception_prio %d" nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d priority %d" nvic_irq_update(int vectpending, int pendprio, int exception_prio, int lev= el) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq lin= e to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq= %d to HardFault: insufficient priority %d >=3D %d" --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240668904337.87289646545446; Tue, 12 Sep 2017 11:24:28 -0700 (PDT) Received: from localhost ([::1]:38002 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drprH-00050x-Ec for importer@patchew.org; Tue, 12 Sep 2017 14:24:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43590) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph6-0003Xa-MJ for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph4-0006Tm-1E for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:56 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37292) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgx-0006Ln-GH; Tue, 12 Sep 2017 14:13:47 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgv-00016V-MS; Tue, 12 Sep 2017 19:13:45 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:56 +0100 Message-Id: <1505240046-11454-10-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 09/19] nvic: Make set_pending and clear_pending take a secure parameter 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Make the armv7m_nvic_set_pending() and armv7m_nvic_clear_pending() functions take a bool indicating whether to pend the secure or non-secure version of a banked interrupt, and update the callsites accordingly. In most callsites we can simply pass the correct security state in; in a couple of cases we use TODO comments to indicate that we will return the code in a subsequent commit. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/cpu.h | 14 ++++++++++- hw/intc/armv7m_nvic.c | 64 ++++++++++++++++++++++++++++++++++++++---------= ---- target/arm/helper.c | 24 +++++++++++-------- hw/intc/trace-events | 4 ++-- 4 files changed, 77 insertions(+), 29 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 7e661c8..7a93354 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1463,7 +1463,19 @@ static inline bool armv7m_nvic_can_take_pending_exce= ption(void *opaque) return true; } #endif -void armv7m_nvic_set_pending(void *opaque, int irq); +/** + * armv7m_nvic_set_pending: mark the specified exception as pending + * @opaque: the NVIC + * @irq: the exception number to mark pending + * @secure: false for non-banked exceptions or for the nonsecure + * version of a banked exception, true for the secure version of a banked + * exception. + * + * Marks the specified exception as pending. Note that we will assert() + * if @secure is true and @irq does not specify one of the fixed set + * of architecturally banked exceptions. + */ +void armv7m_nvic_set_pending(void *opaque, int irq, bool secure); void armv7m_nvic_acknowledge_irq(void *opaque); /** * armv7m_nvic_complete_irq: complete specified interrupt or exception diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index fb824e6..852db11 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -384,31 +384,50 @@ static void nvic_irq_update(NVICState *s) qemu_set_irq(s->excpout, lvl); } =20 -static void armv7m_nvic_clear_pending(void *opaque, int irq) +/** + * armv7m_nvic_clear_pending: mark the specified exception as not pending + * @opaque: the NVIC + * @irq: the exception number to mark as not pending + * @secure: false for non-banked exceptions or for the nonsecure + * version of a banked exception, true for the secure version of a banked + * exception. + * + * Marks the specified exception as not pending. Note that we will assert() + * if @secure is true and @irq does not specify one of the fixed set + * of architecturally banked exceptions. + */ +static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure) { NVICState *s =3D (NVICState *)opaque; VecInfo *vec; =20 assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); =20 - vec =3D &s->vectors[irq]; - trace_nvic_clear_pending(irq, vec->enabled, vec->prio); + if (secure) { + assert(exc_is_banked(irq)); + vec =3D &s->sec_vectors[irq]; + } else { + vec =3D &s->vectors[irq]; + } + trace_nvic_clear_pending(irq, secure, vec->enabled, vec->prio); if (vec->pending) { vec->pending =3D 0; nvic_irq_update(s); } } =20 -void armv7m_nvic_set_pending(void *opaque, int irq) +void armv7m_nvic_set_pending(void *opaque, int irq, bool secure) { NVICState *s =3D (NVICState *)opaque; + bool banked =3D exc_is_banked(irq); VecInfo *vec; =20 assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); + assert(!secure || banked); =20 - vec =3D &s->vectors[irq]; - trace_nvic_set_pending(irq, vec->enabled, vec->prio); + vec =3D (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq]; =20 + trace_nvic_set_pending(irq, secure, vec->enabled, vec->prio); =20 if (irq >=3D ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV) { /* If a synchronous exception is pending then it may be @@ -454,9 +473,20 @@ void armv7m_nvic_set_pending(void *opaque, int irq) "(current priority %d)\n", irq, running); } =20 - /* We can do the escalation, so we take HardFault instead */ + /* We can do the escalation, so we take HardFault instead. + * If BFHFNMINS is set then we escalate to the banked HF for + * the target security state of the original exception; otherw= ise + * we take a Secure HardFault. + */ irq =3D ARMV7M_EXCP_HARD; - vec =3D &s->vectors[irq]; + if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) && + (secure || + !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) { + vec =3D &s->sec_vectors[irq]; + } else { + vec =3D &s->vectors[irq]; + } + /* HF may be banked but there is only one shared HFSR */ s->cpu->env.v7m.hfsr |=3D R_V7M_HFSR_FORCED_MASK; } } @@ -551,7 +581,7 @@ static void set_irq_level(void *opaque, int n, int leve= l) if (level !=3D vec->level) { vec->level =3D level; if (level) { - armv7m_nvic_set_pending(s, n); + armv7m_nvic_set_pending(s, n, false); } } } @@ -837,17 +867,17 @@ static void nvic_writel(NVICState *s, uint32_t offset= , uint32_t value, } case 0xd04: /* Interrupt Control State. */ if (value & (1 << 31)) { - armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI); + armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false); } if (value & (1 << 28)) { - armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV); + armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure); } else if (value & (1 << 27)) { - armv7m_nvic_clear_pending(s, ARMV7M_EXCP_PENDSV); + armv7m_nvic_clear_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure); } if (value & (1 << 26)) { - armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK); + armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure); } else if (value & (1 << 25)) { - armv7m_nvic_clear_pending(s, ARMV7M_EXCP_SYSTICK); + armv7m_nvic_clear_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure= ); } break; case 0xd08: /* Vector Table Offset. */ @@ -1093,7 +1123,7 @@ static void nvic_writel(NVICState *s, uint32_t offset= , uint32_t value, { int excnum =3D (value & 0x1ff) + NVIC_FIRST_IRQ; if (excnum < s->num_irq) { - armv7m_nvic_set_pending(s, excnum); + armv7m_nvic_set_pending(s, excnum, false); } break; } @@ -1495,8 +1525,10 @@ static void nvic_systick_trigger(void *opaque, int n= , int level) /* SysTick just asked us to pend its exception. * (This is different from an external interrupt line's * behaviour.) + * TODO: when we implement the banked systicks we must make + * this pend the correct banked exception. */ - armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK); + armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, false); } } =20 diff --git a/target/arm/helper.c b/target/arm/helper.c index f4f2a87..b64acd8 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6306,7 +6306,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) * stack, directly take a usage fault on the current stack. */ env->v7m.cfsr[env->v7m.secure] |=3D R_V7M_CFSR_INVPC_MASK; - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.sec= ure); v7m_exception_taken(cpu, excret); qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing " "stackframe: failed exception return integrity check= \n"); @@ -6345,8 +6345,11 @@ static void do_v7m_exception_exit(ARMCPU *cpu) * exception return excret specified then this is a UsageFault. */ if (return_to_handler !=3D arm_v7m_is_handler_mode(env)) { - /* Take an INVPC UsageFault by pushing the stack again. */ - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); + /* Take an INVPC UsageFault by pushing the stack again. + * TODO: the v8M version of this code should target the + * background state for this exception. + */ + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, false); env->v7m.cfsr[env->v7m.secure] |=3D R_V7M_CFSR_INVPC_MASK; v7m_push_stack(cpu); v7m_exception_taken(cpu, excret); @@ -6406,20 +6409,20 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) handle it. */ switch (cs->exception_index) { case EXCP_UDEF: - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.sec= ure); env->v7m.cfsr[env->v7m.secure] |=3D R_V7M_CFSR_UNDEFINSTR_MASK; break; case EXCP_NOCP: - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.sec= ure); env->v7m.cfsr[env->v7m.secure] |=3D R_V7M_CFSR_NOCP_MASK; break; case EXCP_INVSTATE: - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.sec= ure); env->v7m.cfsr[env->v7m.secure] |=3D R_V7M_CFSR_INVSTATE_MASK; break; case EXCP_SWI: /* The PC already points to the next instruction. */ - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secur= e); break; case EXCP_PREFETCH_ABORT: case EXCP_DATA_ABORT: @@ -6443,7 +6446,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) env->v7m.bfar); break; } - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false); break; default: /* All other FSR values are either MPU faults or "can't happen @@ -6463,7 +6466,8 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) env->v7m.mmfar[env->v7m.secure]); break; } - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, + env->v7m.secure); break; } break; @@ -6480,7 +6484,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) return; } } - armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false); break; case EXCP_IRQ: break; diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 0b1fba3..94038b6 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -173,8 +173,8 @@ nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d p= riority %d" nvic_irq_update(int vectpending, int pendprio, int exception_prio, int lev= el) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq lin= e to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq= %d to HardFault: insufficient priority %d >=3D %d" nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disa= bled" -nvic_set_pending(int irq, int en, int prio) "NVIC set pending irq %d (enab= led: %d priority %d)" -nvic_clear_pending(int irq, int en, int prio) "NVIC clear pending irq %d (= enabled: %d priority %d)" +nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending= irq %d secure-bank %d (enabled: %d priority %d)" +nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pen= ding irq %d secure-bank %d (enabled: %d priority %d)" nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than= vectpending: setting irq line to 1" nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now acti= ve (prio %d)" nvic_complete_irq(int irq) "NVIC complete IRQ %d" --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240852265702.9298047869923; Tue, 12 Sep 2017 11:27:32 -0700 (PDT) Received: from localhost ([::1]:38018 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpuE-0008ED-8J for importer@patchew.org; Tue, 12 Sep 2017 14:27:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43515) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph4-0003V1-VD for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph2-0006SZ-Lx for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:54 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37306) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgx-0006O6-EL; Tue, 12 Sep 2017 14:13:47 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgw-000170-Bd; Tue, 12 Sep 2017 19:13:46 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:57 +0100 Message-Id: <1505240046-11454-11-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 10/19] nvic: Make SHPR registers banked 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Make the set_prio() function take a bool indicating whether to pend the secure or non-secure version of a banked interrupt, and use this to implement the correct banking semantics for the SHPR registers. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++-= ---- hw/intc/trace-events | 2 +- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 852db11..00c03b4 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -349,15 +349,40 @@ int armv7m_nvic_raw_execution_priority(void *opaque) return s->exception_prio; } =20 -/* caller must call nvic_irq_update() after this */ -static void set_prio(NVICState *s, unsigned irq, uint8_t prio) +/* caller must call nvic_irq_update() after this. + * secure indicates the bank to use for banked exceptions (we assert if + * we are passed secure=3Dtrue for a non-banked exception). + */ +static void set_prio(NVICState *s, unsigned irq, bool secure, uint8_t prio) { assert(irq > ARMV7M_EXCP_NMI); /* only use for configurable prios */ assert(irq < s->num_irq); =20 - s->vectors[irq].prio =3D prio; + if (secure) { + assert(exc_is_banked(irq)); + s->sec_vectors[irq].prio =3D prio; + } else { + s->vectors[irq].prio =3D prio; + } + + trace_nvic_set_prio(irq, secure, prio); +} + +/* Return the current raw priority register value. + * secure indicates the bank to use for banked exceptions (we assert if + * we are passed secure=3Dtrue for a non-banked exception). + */ +static int get_prio(NVICState *s, unsigned irq, bool secure) +{ + assert(irq > ARMV7M_EXCP_NMI); /* only use for configurable prios */ + assert(irq < s->num_irq); =20 - trace_nvic_set_prio(irq, prio); + if (secure) { + assert(exc_is_banked(irq)); + return s->sec_vectors[irq].prio; + } else { + return s->vectors[irq].prio; + } } =20 /* Recompute state and assert irq line accordingly. @@ -1149,6 +1174,47 @@ static bool nvic_user_access_ok(NVICState *s, hwaddr= offset, MemTxAttrs attrs) } } =20 +static int shpr_bank(NVICState *s, int exc, MemTxAttrs attrs) +{ + /* Behaviour for the SHPR register field for this exception: + * return M_REG_NS to use the nonsecure vector (including for + * non-banked exceptions), M_REG_S for the secure version of + * a banked exception, and -1 if this field should RAZ/WI. + */ + switch (exc) { + case ARMV7M_EXCP_MEM: + case ARMV7M_EXCP_USAGE: + case ARMV7M_EXCP_SVC: + case ARMV7M_EXCP_PENDSV: + case ARMV7M_EXCP_SYSTICK: + /* Banked exceptions */ + return attrs.secure; + case ARMV7M_EXCP_BUS: + /* Not banked, RAZ/WI from nonsecure if BFHFNMINS is zero */ + if (!attrs.secure && + !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { + return -1; + } + return M_REG_NS; + case ARMV7M_EXCP_SECURE: + /* Not banked, RAZ/WI from nonsecure */ + if (!attrs.secure) { + return -1; + } + return M_REG_NS; + case ARMV7M_EXCP_DEBUG: + /* Not banked. TODO should RAZ/WI if DEMCR.SDME is set */ + return M_REG_NS; + case 8 ... 10: + case 13: + /* RES0 */ + return -1; + default: + /* Not reachable due to decode of SHPR register addresses */ + g_assert_not_reached(); + } +} + static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, uint64_t *data, unsigned size, MemTxAttrs attrs) @@ -1213,10 +1279,16 @@ static MemTxResult nvic_sysreg_read(void *opaque, h= waddr addr, } } break; - case 0xd18 ... 0xd23: /* System Handler Priority. */ + case 0xd18 ... 0xd23: /* System Handler Priority (SHPR1, SHPR2, SHPR3)= */ val =3D 0; for (i =3D 0; i < size; i++) { - val |=3D s->vectors[(offset - 0xd14) + i].prio << (i * 8); + unsigned hdlidx =3D (offset - 0xd14) + i; + int sbank =3D shpr_bank(s, hdlidx, attrs); + + if (sbank < 0) { + continue; + } + val =3D deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank)); } break; case 0xfe0 ... 0xfff: /* ID. */ @@ -1299,15 +1371,21 @@ static MemTxResult nvic_sysreg_write(void *opaque, = hwaddr addr, =20 for (i =3D 0; i < size && startvec + i < s->num_irq; i++) { if (attrs.secure || s->itns[startvec + i]) { - set_prio(s, startvec + i, (value >> (i * 8)) & 0xff); + set_prio(s, startvec + i, false, (value >> (i * 8)) & 0xff= ); } } nvic_irq_update(s); return MEMTX_OK; - case 0xd18 ... 0xd23: /* System Handler Priority. */ + case 0xd18 ... 0xd23: /* System Handler Priority (SHPR1, SHPR2, SHPR3)= */ for (i =3D 0; i < size; i++) { unsigned hdlidx =3D (offset - 0xd14) + i; - set_prio(s, hdlidx, (value >> (i * 8)) & 0xff); + int newprio =3D extract32(value, i * 8, 8); + int sbank =3D shpr_bank(s, hdlidx, attrs); + + if (sbank < 0) { + continue; + } + set_prio(s, hdlidx, sbank, newprio); } nvic_irq_update(s); return MEMTX_OK; diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 94038b6..29bd308 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -169,7 +169,7 @@ gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 red= istributor 0x%x pending S # hw/intc/armv7m_nvic.c nvic_recompute_state(int vectpending, int vectpending_prio, int exception_= prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_= prio %d" nvic_recompute_state_secure(int vectpending, bool vectpending_is_s_banked,= int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpend= ing %d is_s_banked %d vectpending_prio %d exception_prio %d" -nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d priority %d" +nvic_set_prio(int irq, bool secure, uint8_t prio) "NVIC set irq %d secure-= bank %d priority %d" nvic_irq_update(int vectpending, int pendprio, int exception_prio, int lev= el) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq lin= e to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq= %d to HardFault: insufficient priority %d >=3D %d" nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disa= bled" --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240725291681.103666652076; Tue, 12 Sep 2017 11:25:25 -0700 (PDT) Received: from localhost ([::1]:38005 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpsC-0005yU-7A for importer@patchew.org; Tue, 12 Sep 2017 14:25:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43437) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph3-0003SS-4J for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph1-0006Rv-Rf for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:53 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37306) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgy-0006O6-Fr; Tue, 12 Sep 2017 14:13:48 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgw-00017V-Vq; Tue, 12 Sep 2017 19:13:46 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:58 +0100 Message-Id: <1505240046-11454-12-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 11/19] nvic: Compare group priority for escalation to HF 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" In armv7m_nvic_set_pending() we have to compare the priority of an exception against the execution priority to decide whether it needs to be escalated to HardFault. In the specification this is a comparison against the exception's group priority; for v7M we implemented it as a comparison against the raw exception priority because the two comparisons will always give the same answer. For v8M the existence of AIRCR.PRIS and the possibility of different PRIGROUP values for secure and nonsecure exceptions means we need to explicitly calculate the vector's group priority for this check. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 00c03b4..3361a28 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -478,7 +478,7 @@ void armv7m_nvic_set_pending(void *opaque, int irq, boo= l secure) int running =3D nvic_exec_prio(s); bool escalate =3D false; =20 - if (vec->prio >=3D running) { + if (exc_group_prio(s, vec->prio, secure) >=3D running) { trace_nvic_escalate_prio(irq, vec->prio, running); escalate =3D true; } else if (!vec->enabled) { --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240549214815.6865766154646; Tue, 12 Sep 2017 11:22:29 -0700 (PDT) Received: from localhost ([::1]:37992 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drppI-0002lj-Dg for importer@patchew.org; Tue, 12 Sep 2017 14:22:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43453) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph3-0003T5-GZ for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph2-0006S6-1y for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:53 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37310) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drpgy-0006PL-Mt; Tue, 12 Sep 2017 14:13:48 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgx-000180-Mu; Tue, 12 Sep 2017 19:13:47 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:13:59 +0100 Message-Id: <1505240046-11454-13-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 12/19] nvic: In escalation to HardFault, support HF not being priority -1 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" When escalating to HardFault, we must go into Lockup if we can't take the synchronous HardFault because the current execution priority is already at or below the priority of HardFault. In v7M HF is always priority -1 so a simple < 0 comparison sufficed; in v8M the priority of HardFault can vary depending on whether it is a Secure or NonSecure HardFault, so we must check against the priority of the HardFault exception vector we're about to use. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 3361a28..c4670f7 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -487,18 +487,8 @@ void armv7m_nvic_set_pending(void *opaque, int irq, bo= ol secure) } =20 if (escalate) { - if (running < 0) { - /* We want to escalate to HardFault but we can't take a - * synchronous HardFault at this point either. This is a - * Lockup condition due to a guest bug. We don't model - * Lockup, so report via cpu_abort() instead. - */ - cpu_abort(&s->cpu->parent_obj, - "Lockup: can't escalate %d to HardFault " - "(current priority %d)\n", irq, running); - } =20 - /* We can do the escalation, so we take HardFault instead. + /* We need to escalate this exception to a synchronous HardFau= lt. * If BFHFNMINS is set then we escalate to the banked HF for * the target security state of the original exception; otherw= ise * we take a Secure HardFault. @@ -511,6 +501,17 @@ void armv7m_nvic_set_pending(void *opaque, int irq, bo= ol secure) } else { vec =3D &s->vectors[irq]; } + if (running <=3D vec->prio) { + /* We want to escalate to HardFault but we can't take the + * synchronous HardFault at this point either. This is a + * Lockup condition due to a guest bug. We don't model + * Lockup, so report via cpu_abort() instead. + */ + cpu_abort(&s->cpu->parent_obj, + "Lockup: can't escalate %d to HardFault " + "(current priority %d)\n", irq, running); + } + /* HF may be banked but there is only one shared HFSR */ s->cpu->env.v7m.hfsr |=3D R_V7M_HFSR_FORCED_MASK; } --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505241000541933.188148099449; Tue, 12 Sep 2017 11:30:00 -0700 (PDT) Received: from localhost ([::1]:38029 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpwd-0002Wf-G4 for importer@patchew.org; Tue, 12 Sep 2017 14:29:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43576) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph6-0003X3-5f for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph4-0006UU-JY for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:56 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37316) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drph1-0006QF-4q; Tue, 12 Sep 2017 14:13:51 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgy-00018i-Ao; Tue, 12 Sep 2017 19:13:48 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:14:00 +0100 Message-Id: <1505240046-11454-14-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 13/19] nvic: Implement v8M changes to fixed priority exceptions 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" In v7M, the fixed-priority exceptions are: Reset: -3 NMI: -2 HardFault: -1 In v8M, this changes because Secure HardFault may need to be prioritised above NMI: Reset: -4 Secure HardFault if AIRCR.BFHFNMINS =3D=3D 1: -3 NMI: -2 Secure HardFault if AIRCR.BFHFNMINS =3D=3D 0: -1 NonSecure HardFault: -1 Make these changes, including support for changing the priority of Secure HardFault as AIRCR.BFHFNMINS changes. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index c4670f7..db2f170 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -937,6 +937,12 @@ static void nvic_writel(NVICState *s, uint32_t offset,= uint32_t value, (R_V7M_AIRCR_SYSRESETREQS_MASK | R_V7M_AIRCR_BFHFNMINS_MASK | R_V7M_AIRCR_PRIS_MASK); + /* BFHFNMINS changes the priority of Secure HardFault */ + if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) { + s->sec_vectors[ARMV7M_EXCP_HARD].prio =3D -3; + } else { + s->sec_vectors[ARMV7M_EXCP_HARD].prio =3D -1; + } } nvic_irq_update(s); } @@ -1452,9 +1458,12 @@ static int nvic_post_load(void *opaque, int version_= id) { NVICState *s =3D opaque; unsigned i; + int resetprio; =20 /* Check for out of range priority settings */ - if (s->vectors[ARMV7M_EXCP_RESET].prio !=3D -3 || + resetprio =3D arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3; + + if (s->vectors[ARMV7M_EXCP_RESET].prio !=3D resetprio || s->vectors[ARMV7M_EXCP_NMI].prio !=3D -2 || s->vectors[ARMV7M_EXCP_HARD].prio !=3D -1) { return 1; @@ -1497,7 +1506,12 @@ static int nvic_security_post_load(void *opaque, int= version_id) int i; =20 /* Check for out of range priority settings */ - if (s->sec_vectors[ARMV7M_EXCP_HARD].prio !=3D -1) { + if (s->sec_vectors[ARMV7M_EXCP_HARD].prio !=3D -1 + && s->sec_vectors[ARMV7M_EXCP_HARD].prio !=3D -3) { + /* We can't cross-check against AIRCR.BFHFNMINS as we don't know + * if the CPU state has been migrated yet; a mismatch won't + * cause the emulation to blow up, though. + */ return 1; } for (i =3D ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) { @@ -1544,6 +1558,7 @@ static Property props_nvic[] =3D { =20 static void armv7m_nvic_reset(DeviceState *dev) { + int resetprio; NVICState *s =3D NVIC(dev); =20 s->vectors[ARMV7M_EXCP_NMI].enabled =3D 1; @@ -1556,7 +1571,8 @@ static void armv7m_nvic_reset(DeviceState *dev) s->vectors[ARMV7M_EXCP_PENDSV].enabled =3D 1; s->vectors[ARMV7M_EXCP_SYSTICK].enabled =3D 1; =20 - s->vectors[ARMV7M_EXCP_RESET].prio =3D -3; + resetprio =3D arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3; + s->vectors[ARMV7M_EXCP_RESET].prio =3D resetprio; s->vectors[ARMV7M_EXCP_NMI].prio =3D -2; s->vectors[ARMV7M_EXCP_HARD].prio =3D -1; =20 --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240339598285.1704380985018; Tue, 12 Sep 2017 11:18:59 -0700 (PDT) Received: from localhost ([::1]:37968 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drply-0007rm-30 for importer@patchew.org; Tue, 12 Sep 2017 14:18:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43498) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph4-0003UT-EM for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph2-0006Sc-Lh for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:54 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37316) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drph0-0006QF-2W; Tue, 12 Sep 2017 14:13:50 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgz-00019A-1C; Tue, 12 Sep 2017 19:13:49 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:14:01 +0100 Message-Id: <1505240046-11454-15-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 14/19] nvic: Disable the non-secure HardFault if AIRCR.BFHFNMINS is clear 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" If AIRCR.BFHFNMINS is clear, then although NonSecure HardFault can still be pended via SHCSR.HARDFAULTPENDED it mustn't actually preempt execution. The simple way to achieve this is to clear the enable bit for it, since the enable bit isn't guest visible. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index db2f170..91d2f33 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -937,11 +937,16 @@ static void nvic_writel(NVICState *s, uint32_t offset= , uint32_t value, (R_V7M_AIRCR_SYSRESETREQS_MASK | R_V7M_AIRCR_BFHFNMINS_MASK | R_V7M_AIRCR_PRIS_MASK); - /* BFHFNMINS changes the priority of Secure HardFault */ + /* BFHFNMINS changes the priority of Secure HardFault, and + * allows a pending Non-secure HardFault to preempt (which + * we implement by marking it enabled). + */ if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) { s->sec_vectors[ARMV7M_EXCP_HARD].prio =3D -3; + s->vectors[ARMV7M_EXCP_HARD].enabled =3D 1; } else { s->sec_vectors[ARMV7M_EXCP_HARD].prio =3D -1; + s->vectors[ARMV7M_EXCP_HARD].enabled =3D 0; } } nvic_irq_update(s); @@ -1562,7 +1567,6 @@ static void armv7m_nvic_reset(DeviceState *dev) NVICState *s =3D NVIC(dev); =20 s->vectors[ARMV7M_EXCP_NMI].enabled =3D 1; - s->vectors[ARMV7M_EXCP_HARD].enabled =3D 1; /* MEM, BUS, and USAGE are enabled through * the System Handler Control register */ @@ -1584,6 +1588,10 @@ static void armv7m_nvic_reset(DeviceState *dev) =20 /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC= ) */ s->sec_vectors[ARMV7M_EXCP_HARD].prio =3D -1; + /* If AIRCR.BFHFNMINS is 0 then NS HF is (effectively) disabled */ + s->vectors[ARMV7M_EXCP_HARD].enabled =3D 0; + } else { + s->vectors[ARMV7M_EXCP_HARD].enabled =3D 1; } =20 /* Strictly speaking the reset handler should be enabled. --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505241159859912.1403715570821; Tue, 12 Sep 2017 11:32:39 -0700 (PDT) Received: from localhost ([::1]:38046 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpzD-0005Nl-0b for importer@patchew.org; Tue, 12 Sep 2017 14:32:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43595) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph6-0003Xk-R8 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph5-0006VV-TH for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:56 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37316) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drph2-0006QF-5A; Tue, 12 Sep 2017 14:13:52 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drpgz-00019p-Lp; Tue, 12 Sep 2017 19:13:49 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:14:02 +0100 Message-Id: <1505240046-11454-16-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 15/19] nvic: Handle v8M changes in nvic_exec_prio() 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Update nvic_exec_prio() to support the v8M changes: * BASEPRI, FAULTMASK and PRIMASK are all banked * AIRCR.PRIS can affect NS priorities * AIRCR.BFHFNMINS affects FAULTMASK behaviour These changes mean that it's no longer possible to definitely say that if FAULTMASK is set it overrides PRIMASK, and if PRIMASK is set it overrides BASEPRI (since if PRIMASK_NS is set and AIRCR.PRIS is set then whether that 0x80 priority should take effect or the priority in BASEPRI_S depends on the value of BASEPRI_S, for instance). So we switch to the same approach used by the pseudocode of working through BASEPRI, PRIMASK and FAULTMASK and overriding the previous values if needed. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 51 ++++++++++++++++++++++++++++++++++++++++++-----= ---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 91d2f33..b13327d 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -319,18 +319,51 @@ static void nvic_recompute_state(NVICState *s) static inline int nvic_exec_prio(NVICState *s) { CPUARMState *env =3D &s->cpu->env; - int running; + int running =3D NVIC_NOEXC_PRIO; =20 - if (env->v7m.faultmask[env->v7m.secure]) { - running =3D -1; - } else if (env->v7m.primask[env->v7m.secure]) { + if (env->v7m.basepri[M_REG_NS] > 0) { + running =3D exc_group_prio(s, env->v7m.basepri[M_REG_NS], M_REG_NS= ); + } + + if (env->v7m.basepri[M_REG_S] > 0) { + int basepri =3D exc_group_prio(s, env->v7m.basepri[M_REG_S], M_REG= _S); + if (running > basepri) { + running =3D basepri; + } + } + + if (env->v7m.primask[M_REG_NS]) { + if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) { + if (running > NVIC_NS_PRIO_LIMIT) { + running =3D NVIC_NS_PRIO_LIMIT; + } + } else { + running =3D 0; + } + } + + if (env->v7m.primask[M_REG_S]) { running =3D 0; - } else if (env->v7m.basepri[env->v7m.secure] > 0) { - running =3D env->v7m.basepri[env->v7m.secure] & - nvic_gprio_mask(s, env->v7m.secure); - } else { - running =3D NVIC_NOEXC_PRIO; /* lower than any possible priority */ } + + if (env->v7m.faultmask[M_REG_NS]) { + if (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) { + running =3D -1; + } else { + if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) { + if (running > NVIC_NS_PRIO_LIMIT) { + running =3D NVIC_NS_PRIO_LIMIT; + } + } else { + running =3D 0; + } + } + } + + if (env->v7m.faultmask[M_REG_S]) { + running =3D (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) ? -3 : -= 1; + } + /* consider priority of active handler */ return MIN(running, s->exception_prio); } --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240508980134.6551224654877; Tue, 12 Sep 2017 11:21:48 -0700 (PDT) Received: from localhost ([::1]:37990 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpoi-00027w-0H for importer@patchew.org; Tue, 12 Sep 2017 14:21:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43572) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph6-0003Wv-4D for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph4-0006Ue-Ro for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:56 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37324) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drph1-0006R3-Cj; Tue, 12 Sep 2017 14:13:51 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drph0-0001A4-BP; Tue, 12 Sep 2017 19:13:50 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:14:03 +0100 Message-Id: <1505240046-11454-17-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 16/19] target/arm: Handle banking in negative-execution-priority check in cpu_mmu_index() 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Now that we have a banked FAULTMASK register and banked exceptions, we can implement the correct check in cpu_mmu_index() for whether the MPU_CTRL.HFNMIENA bit's effect should apply. This bit causes handlers which have requested a negative execution priority to run with the MPU disabled. In v8M the test has to check this for the current security state and so takes account of banking. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/cpu.h | 21 ++++++++++++++++----- hw/intc/armv7m_nvic.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 7a93354..02be3ca 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1498,6 +1498,21 @@ int armv7m_nvic_complete_irq(void *opaque, int irq); * (v8M ARM ARM I_PKLD.) */ int armv7m_nvic_raw_execution_priority(void *opaque); +/** + * armv7m_nvic_neg_prio_requested: return true if the requested execution + * priority is negative for the specified security state. + * @opaque: the NVIC + * @secure: the security state to test + * This corresponds to the pseudocode IsReqExecPriNeg(). + */ +#ifndef CONFIG_USER_ONLY +bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure); +#else +static inline bool armv7m_nvic_neg_prio_requested(void *opaque, bool secur= e) +{ + return false; +} +#endif =20 /* Interface for defining coprocessor registers. * Registers are defined in tables of arm_cp_reginfo structs @@ -2280,11 +2295,7 @@ static inline int cpu_mmu_index(CPUARMState *env, bo= ol ifetch) if (arm_feature(env, ARM_FEATURE_M)) { ARMMMUIdx mmu_idx =3D el =3D=3D 0 ? ARMMMUIdx_MUser : ARMMMUIdx_MP= riv; =20 - /* Execution priority is negative if FAULTMASK is set or - * we're in a HardFault or NMI handler. - */ - if ((env->v7m.exception > 0 && env->v7m.exception <=3D 3) - || env->v7m.faultmask[env->v7m.secure]) { + if (armv7m_nvic_neg_prio_requested(env->nvic, env->v7m.secure)) { mmu_idx =3D ARMMMUIdx_MNegPri; } =20 diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index b13327d..5e5aecd 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -368,6 +368,35 @@ static inline int nvic_exec_prio(NVICState *s) return MIN(running, s->exception_prio); } =20 +bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure) +{ + /* Return true if the requested execution priority is negative + * for the specified security state, ie that security state + * has an active NMI or HardFault or has set its FAULTMASK. + * Note that this is not the same as whether the execution + * priority is actually negative (for instance AIRCR.PRIS may + * mean we don't allow FAULTMASK_NS to actually make the execution + * priority negative). Compare pseudocode IsReqExcPriNeg(). + */ + NVICState *s =3D opaque; + + if (s->cpu->env.v7m.faultmask[secure]) { + return true; + } + + if (secure ? s->sec_vectors[ARMV7M_EXCP_HARD].active : + s->vectors[ARMV7M_EXCP_HARD].active) { + return true; + } + + if (s->vectors[ARMV7M_EXCP_NMI].active && + exc_targets_secure(s, ARMV7M_EXCP_NMI) =3D=3D secure) { + return true; + } + + return false; +} + bool armv7m_nvic_can_take_pending_exception(void *opaque) { NVICState *s =3D opaque; --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505241275090906.4315519142159; Tue, 12 Sep 2017 11:34:35 -0700 (PDT) Received: from localhost ([::1]:38054 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drq14-0006o2-EY for importer@patchew.org; Tue, 12 Sep 2017 14:34:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43622) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph7-0003Yu-Lg for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph6-0006Vs-Fq for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:57 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37316) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drph3-0006QF-7O; Tue, 12 Sep 2017 14:13:53 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drph1-0001AY-7j; Tue, 12 Sep 2017 19:13:51 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:14:04 +0100 Message-Id: <1505240046-11454-18-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 17/19] nvic: Make ICSR banked for v8M 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The ICSR NVIC register is banked for v8M. This doesn't require any new state, but it does mean that some bits are controlled by BFHNFNMINS and some bits must work with the correct banked exception. There is also a new in v8M PENDNMICLR bit. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 5e5aecd..21fd199 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -703,7 +703,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offse= t, MemTxAttrs attrs) } case 0xd00: /* CPUID Base. */ return cpu->midr; - case 0xd04: /* Interrupt Control State. */ + case 0xd04: /* Interrupt Control State (ICSR) */ /* VECTACTIVE */ val =3D cpu->env.v7m.exception; /* VECTPENDING */ @@ -716,19 +716,32 @@ static uint32_t nvic_readl(NVICState *s, uint32_t off= set, MemTxAttrs attrs) if (nvic_rettobase(s)) { val |=3D (1 << 11); } - /* PENDSTSET */ - if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) { - val |=3D (1 << 26); - } - /* PENDSVSET */ - if (s->vectors[ARMV7M_EXCP_PENDSV].pending) { - val |=3D (1 << 28); + if (attrs.secure) { + /* PENDSTSET */ + if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].pending) { + val |=3D (1 << 26); + } + /* PENDSVSET */ + if (s->sec_vectors[ARMV7M_EXCP_PENDSV].pending) { + val |=3D (1 << 28); + } + } else { + /* PENDSTSET */ + if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) { + val |=3D (1 << 26); + } + /* PENDSVSET */ + if (s->vectors[ARMV7M_EXCP_PENDSV].pending) { + val |=3D (1 << 28); + } } /* NMIPENDSET */ - if (s->vectors[ARMV7M_EXCP_NMI].pending) { + if ((cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) && + s->vectors[ARMV7M_EXCP_NMI].pending) { val |=3D (1 << 31); } - /* ISRPREEMPT not implemented */ + /* ISRPREEMPT: RES0 when halting debug not implemented */ + /* STTNS: RES0 for the Main Extension */ return val; case 0xd08: /* Vector Table Offset. */ return cpu->env.v7m.vecbase[attrs.secure]; @@ -953,9 +966,15 @@ static void nvic_writel(NVICState *s, uint32_t offset,= uint32_t value, nvic_irq_update(s); break; } - case 0xd04: /* Interrupt Control State. */ - if (value & (1 << 31)) { - armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false); + case 0xd04: /* Interrupt Control State (ICSR) */ + if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) { + if (value & (1 << 31)) { + armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false); + } else if (value & (1 << 30) && + arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* PENDNMICLR didn't exist in v7M */ + armv7m_nvic_clear_pending(s, ARMV7M_EXCP_NMI, false); + } } if (value & (1 << 28)) { armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure); --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240808930165.59765332952304; Tue, 12 Sep 2017 11:26:48 -0700 (PDT) Received: from localhost ([::1]:38015 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drptY-0007Uz-6k for importer@patchew.org; Tue, 12 Sep 2017 14:26:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43658) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph9-0003ba-H0 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:14:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph7-0006WS-Ky for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:59 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37328) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drph2-0006SF-SW; Tue, 12 Sep 2017 14:13:53 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drph1-0001B2-S7; Tue, 12 Sep 2017 19:13:51 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:14:05 +0100 Message-Id: <1505240046-11454-19-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 18/19] nvic: Make SHCSR banked for v8M 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Handle banking of SHCSR: some register bits are banked between Secure and Non-Secure, and some are only accessible to Secure. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 221 ++++++++++++++++++++++++++++++++++++++--------= ---- 1 file changed, 169 insertions(+), 52 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 21fd199..9613990 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -770,50 +770,117 @@ static uint32_t nvic_readl(NVICState *s, uint32_t of= fset, MemTxAttrs attrs) val =3D cpu->env.v7m.ccr[attrs.secure]; val |=3D cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK; return val; - case 0xd24: /* System Handler Status. */ + case 0xd24: /* System Handler Control and State (SHCSR) */ val =3D 0; - if (s->vectors[ARMV7M_EXCP_MEM].active) { - val |=3D (1 << 0); - } - if (s->vectors[ARMV7M_EXCP_BUS].active) { - val |=3D (1 << 1); - } - if (s->vectors[ARMV7M_EXCP_USAGE].active) { - val |=3D (1 << 3); + if (attrs.secure) { + if (s->sec_vectors[ARMV7M_EXCP_MEM].active) { + val |=3D (1 << 0); + } + if (s->sec_vectors[ARMV7M_EXCP_HARD].active) { + val |=3D (1 << 2); + } + if (s->sec_vectors[ARMV7M_EXCP_USAGE].active) { + val |=3D (1 << 3); + } + if (s->sec_vectors[ARMV7M_EXCP_SVC].active) { + val |=3D (1 << 7); + } + if (s->sec_vectors[ARMV7M_EXCP_PENDSV].active) { + val |=3D (1 << 10); + } + if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].active) { + val |=3D (1 << 11); + } + if (s->sec_vectors[ARMV7M_EXCP_USAGE].pending) { + val |=3D (1 << 12); + } + if (s->sec_vectors[ARMV7M_EXCP_MEM].pending) { + val |=3D (1 << 13); + } + if (s->sec_vectors[ARMV7M_EXCP_SVC].pending) { + val |=3D (1 << 15); + } + if (s->sec_vectors[ARMV7M_EXCP_MEM].enabled) { + val |=3D (1 << 16); + } + if (s->sec_vectors[ARMV7M_EXCP_USAGE].enabled) { + val |=3D (1 << 18); + } + if (s->sec_vectors[ARMV7M_EXCP_HARD].pending) { + val |=3D (1 << 21); + } + /* SecureFault is not banked but is always RAZ/WI to NS */ + if (s->vectors[ARMV7M_EXCP_SECURE].active) { + val |=3D (1 << 4); + } + if (s->vectors[ARMV7M_EXCP_SECURE].enabled) { + val |=3D (1 << 19); + } + if (s->vectors[ARMV7M_EXCP_SECURE].pending) { + val |=3D (1 << 20); + } + } else { + if (s->vectors[ARMV7M_EXCP_MEM].active) { + val |=3D (1 << 0); + } + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* HARDFAULTACT, HARDFAULTPENDED not present in v7M */ + if (s->vectors[ARMV7M_EXCP_HARD].active) { + val |=3D (1 << 2); + } + if (s->vectors[ARMV7M_EXCP_HARD].pending) { + val |=3D (1 << 21); + } + } + if (s->vectors[ARMV7M_EXCP_USAGE].active) { + val |=3D (1 << 3); + } + if (s->vectors[ARMV7M_EXCP_SVC].active) { + val |=3D (1 << 7); + } + if (s->vectors[ARMV7M_EXCP_PENDSV].active) { + val |=3D (1 << 10); + } + if (s->vectors[ARMV7M_EXCP_SYSTICK].active) { + val |=3D (1 << 11); + } + if (s->vectors[ARMV7M_EXCP_USAGE].pending) { + val |=3D (1 << 12); + } + if (s->vectors[ARMV7M_EXCP_MEM].pending) { + val |=3D (1 << 13); + } + if (s->vectors[ARMV7M_EXCP_SVC].pending) { + val |=3D (1 << 15); + } + if (s->vectors[ARMV7M_EXCP_MEM].enabled) { + val |=3D (1 << 16); + } + if (s->vectors[ARMV7M_EXCP_USAGE].enabled) { + val |=3D (1 << 18); + } } - if (s->vectors[ARMV7M_EXCP_SVC].active) { - val |=3D (1 << 7); + if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MA= SK)) { + if (s->vectors[ARMV7M_EXCP_BUS].active) { + val |=3D (1 << 1); + } + if (s->vectors[ARMV7M_EXCP_BUS].pending) { + val |=3D (1 << 14); + } + if (s->vectors[ARMV7M_EXCP_BUS].enabled) { + val |=3D (1 << 17); + } + if (arm_feature(&cpu->env, ARM_FEATURE_V8) && + s->vectors[ARMV7M_EXCP_NMI].active) { + /* NMIACT is not present in v7M */ + val |=3D (1 << 5); + } } + + /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */ if (s->vectors[ARMV7M_EXCP_DEBUG].active) { val |=3D (1 << 8); } - if (s->vectors[ARMV7M_EXCP_PENDSV].active) { - val |=3D (1 << 10); - } - if (s->vectors[ARMV7M_EXCP_SYSTICK].active) { - val |=3D (1 << 11); - } - if (s->vectors[ARMV7M_EXCP_USAGE].pending) { - val |=3D (1 << 12); - } - if (s->vectors[ARMV7M_EXCP_MEM].pending) { - val |=3D (1 << 13); - } - if (s->vectors[ARMV7M_EXCP_BUS].pending) { - val |=3D (1 << 14); - } - if (s->vectors[ARMV7M_EXCP_SVC].pending) { - val |=3D (1 << 15); - } - if (s->vectors[ARMV7M_EXCP_MEM].enabled) { - val |=3D (1 << 16); - } - if (s->vectors[ARMV7M_EXCP_BUS].enabled) { - val |=3D (1 << 17); - } - if (s->vectors[ARMV7M_EXCP_USAGE].enabled) { - val |=3D (1 << 18); - } return val; case 0xd28: /* Configurable Fault Status. */ /* The BFSR bits [15:8] are shared between security states @@ -1061,21 +1128,71 @@ static void nvic_writel(NVICState *s, uint32_t offs= et, uint32_t value, =20 cpu->env.v7m.ccr[attrs.secure] =3D value; break; - case 0xd24: /* System Handler Control. */ - s->vectors[ARMV7M_EXCP_MEM].active =3D (value & (1 << 0)) !=3D 0; - s->vectors[ARMV7M_EXCP_BUS].active =3D (value & (1 << 1)) !=3D 0; - s->vectors[ARMV7M_EXCP_USAGE].active =3D (value & (1 << 3)) !=3D 0; - s->vectors[ARMV7M_EXCP_SVC].active =3D (value & (1 << 7)) !=3D 0; + case 0xd24: /* System Handler Control and State (SHCSR) */ + if (attrs.secure) { + s->sec_vectors[ARMV7M_EXCP_MEM].active =3D (value & (1 << 0)) = !=3D 0; + /* Secure HardFault active bit cannot be written */ + s->sec_vectors[ARMV7M_EXCP_USAGE].active =3D (value & (1 << 3)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_SVC].active =3D (value & (1 << 7)) = !=3D 0; + s->sec_vectors[ARMV7M_EXCP_PENDSV].active =3D + (value & (1 << 10)) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_SYSTICK].active =3D + (value & (1 << 11)) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_USAGE].pending =3D + (value & (1 << 12)) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_MEM].pending =3D (value & (1 << 13)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_SVC].pending =3D (value & (1 << 15)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_MEM].enabled =3D (value & (1 << 16)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_BUS].enabled =3D (value & (1 << 17)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_USAGE].enabled =3D + (value & (1 << 18)) !=3D 0; + /* SecureFault not banked, but RAZ/WI to NS */ + s->vectors[ARMV7M_EXCP_SECURE].active =3D (value & (1 << 4)) != =3D 0; + s->vectors[ARMV7M_EXCP_SECURE].enabled =3D (value & (1 << 19))= !=3D 0; + s->vectors[ARMV7M_EXCP_SECURE].pending =3D (value & (1 << 20))= !=3D 0; + } else { + s->vectors[ARMV7M_EXCP_MEM].active =3D (value & (1 << 0)) !=3D= 0; + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* HARDFAULTPENDED is not present in v7M */ + s->vectors[ARMV7M_EXCP_HARD].pending =3D (value & (1 << 21= )) !=3D 0; + } + s->vectors[ARMV7M_EXCP_USAGE].active =3D (value & (1 << 3)) != =3D 0; + s->vectors[ARMV7M_EXCP_SVC].active =3D (value & (1 << 7)) !=3D= 0; + s->vectors[ARMV7M_EXCP_PENDSV].active =3D (value & (1 << 10)) = !=3D 0; + s->vectors[ARMV7M_EXCP_SYSTICK].active =3D (value & (1 << 11))= !=3D 0; + s->vectors[ARMV7M_EXCP_USAGE].pending =3D (value & (1 << 12)) = !=3D 0; + s->vectors[ARMV7M_EXCP_MEM].pending =3D (value & (1 << 13)) != =3D 0; + s->vectors[ARMV7M_EXCP_SVC].pending =3D (value & (1 << 15)) != =3D 0; + s->vectors[ARMV7M_EXCP_MEM].enabled =3D (value & (1 << 16)) != =3D 0; + s->vectors[ARMV7M_EXCP_USAGE].enabled =3D (value & (1 << 18)) = !=3D 0; + } + if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MA= SK)) { + s->vectors[ARMV7M_EXCP_BUS].active =3D (value & (1 << 1)) !=3D= 0; + s->vectors[ARMV7M_EXCP_BUS].pending =3D (value & (1 << 14)) != =3D 0; + s->vectors[ARMV7M_EXCP_BUS].enabled =3D (value & (1 << 17)) != =3D 0; + } + /* NMIACT can only be written if the write is of a zero, with + * BFHFNMINS 1, and by the CPU in secure state via the NS alias. + */ + if (!attrs.secure && cpu->env.v7m.secure && + (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) && + (value & (1 << 5)) =3D=3D 0) { + s->vectors[ARMV7M_EXCP_NMI].active =3D 0; + } + /* HARDFAULTACT can only be written if the write is of a zero + * to the non-secure HardFault state by the CPU in secure state. + * The only case where we can be targeting the non-secure HF state + * when in secure state is if this is a write via the NS alias + * and BFHFNMINS is 1. + */ + if (!attrs.secure && cpu->env.v7m.secure && + (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) && + (value & (1 << 2)) =3D=3D 0) { + s->vectors[ARMV7M_EXCP_HARD].active =3D 0; + } + + /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */ s->vectors[ARMV7M_EXCP_DEBUG].active =3D (value & (1 << 8)) !=3D 0; - s->vectors[ARMV7M_EXCP_PENDSV].active =3D (value & (1 << 10)) !=3D= 0; - s->vectors[ARMV7M_EXCP_SYSTICK].active =3D (value & (1 << 11)) != =3D 0; - s->vectors[ARMV7M_EXCP_USAGE].pending =3D (value & (1 << 12)) !=3D= 0; - s->vectors[ARMV7M_EXCP_MEM].pending =3D (value & (1 << 13)) !=3D 0; - s->vectors[ARMV7M_EXCP_BUS].pending =3D (value & (1 << 14)) !=3D 0; - s->vectors[ARMV7M_EXCP_SVC].pending =3D (value & (1 << 15)) !=3D 0; - s->vectors[ARMV7M_EXCP_MEM].enabled =3D (value & (1 << 16)) !=3D 0; - s->vectors[ARMV7M_EXCP_BUS].enabled =3D (value & (1 << 17)) !=3D 0; - s->vectors[ARMV7M_EXCP_USAGE].enabled =3D (value & (1 << 18)) !=3D= 0; nvic_irq_update(s); break; case 0xd28: /* Configurable Fault Status. */ --=20 2.7.4 From nobody Mon Feb 9 06:45:39 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240530506799.9490653292537; Tue, 12 Sep 2017 11:22:10 -0700 (PDT) Received: from localhost ([::1]:37991 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drpp3-0002UB-Ch for importer@patchew.org; Tue, 12 Sep 2017 14:22:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43661) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph9-0003bn-Jz for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:14:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph8-0006Wg-54 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:59 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37316) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drph4-0006QF-4d; Tue, 12 Sep 2017 14:13:54 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drph2-0001BU-I3; Tue, 12 Sep 2017 19:13:52 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:14:06 +0100 Message-Id: <1505240046-11454-20-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-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] [PATCH 19/19] nvic: Support banked exceptions in acknowledge and complete 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: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Update armv7m_nvic_acknowledge_irq() and armv7m_nvic_complete_irq() to handle banked exceptions: * acknowledge needs to use the correct vector, which may be in sec_vectors[] * acknowledge needs to return to its caller whether the exception should be taken to secure or non-secure state * complete needs its caller to tell it whether the exception being completed is a secure one or not Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/cpu.h | 15 +++++++++++++-- hw/intc/armv7m_nvic.c | 26 ++++++++++++++++++++------ target/arm/helper.c | 8 +++++--- hw/intc/trace-events | 4 ++-- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 02be3ca..9c336bc 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1476,18 +1476,29 @@ static inline bool armv7m_nvic_can_take_pending_exc= eption(void *opaque) * of architecturally banked exceptions. */ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure); -void armv7m_nvic_acknowledge_irq(void *opaque); +/** + * armv7m_nvic_acknowledge_irq: make highest priority pending exception ac= tive + * @opaque: the NVIC + * + * Move the current highest priority pending exception from the pending + * state to the active state, and update v7m.exception to indicate that + * it is the exception currently being handled. + * + * Returns: true if exception should be taken to Secure state, false for NS + */ +bool armv7m_nvic_acknowledge_irq(void *opaque); /** * armv7m_nvic_complete_irq: complete specified interrupt or exception * @opaque: the NVIC * @irq: the exception number to complete + * @secure: true if this exception was secure * * Returns: -1 if the irq was not active * 1 if completing this irq brought us back to base (no active i= rqs) * 0 if there is still an irq active after this one was completed * (Ignoring -1, this is the same as the RETTOBASE value before completion= .) */ -int armv7m_nvic_complete_irq(void *opaque, int irq); +int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure); /** * armv7m_nvic_raw_execution_priority: return the raw execution priority * @opaque: the NVIC diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 9613990..078532a 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -586,24 +586,32 @@ void armv7m_nvic_set_pending(void *opaque, int irq, b= ool secure) } =20 /* Make pending IRQ active. */ -void armv7m_nvic_acknowledge_irq(void *opaque) +bool armv7m_nvic_acknowledge_irq(void *opaque) { NVICState *s =3D (NVICState *)opaque; CPUARMState *env =3D &s->cpu->env; const int pending =3D s->vectpending; const int running =3D nvic_exec_prio(s); VecInfo *vec; + bool targets_secure; =20 assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); =20 - vec =3D &s->vectors[pending]; + if (s->vectpending_is_s_banked) { + vec =3D &s->sec_vectors[pending]; + targets_secure =3D true; + } else { + vec =3D &s->vectors[pending]; + targets_secure =3D !exc_is_banked(s->vectpending) && + exc_targets_secure(s, s->vectpending); + } =20 assert(vec->enabled); assert(vec->pending); =20 assert(s->vectpending_prio < running); =20 - trace_nvic_acknowledge_irq(pending, s->vectpending_prio); + trace_nvic_acknowledge_irq(pending, s->vectpending_prio, targets_secur= e); =20 vec->active =3D 1; vec->pending =3D 0; @@ -611,9 +619,11 @@ void armv7m_nvic_acknowledge_irq(void *opaque) env->v7m.exception =3D s->vectpending; =20 nvic_irq_update(s); + + return targets_secure; } =20 -int armv7m_nvic_complete_irq(void *opaque, int irq) +int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure) { NVICState *s =3D (NVICState *)opaque; VecInfo *vec; @@ -621,9 +631,13 @@ int armv7m_nvic_complete_irq(void *opaque, int irq) =20 assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); =20 - vec =3D &s->vectors[irq]; + if (secure && exc_is_banked(irq)) { + vec =3D &s->sec_vectors[irq]; + } else { + vec =3D &s->vectors[irq]; + } =20 - trace_nvic_complete_irq(irq); + trace_nvic_complete_irq(irq, secure); =20 if (!vec->active) { /* Tell the caller this was an illegal exception return */ diff --git a/target/arm/helper.c b/target/arm/helper.c index b64acd8..8be78ea 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6218,6 +6218,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) bool return_to_sp_process =3D false; bool return_to_handler =3D false; bool rettobase =3D false; + bool exc_secure =3D false; =20 /* We can only get here from an EXCP_EXCEPTION_EXIT, and * gen_bx_excret() enforces the architectural rule @@ -6256,16 +6257,17 @@ static void do_v7m_exception_exit(ARMCPU *cpu) * which security state's faultmask to clear. (v8M ARM ARM R_KBNF.) */ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { - int es =3D excret & R_V7M_EXCRET_ES_MASK; + exc_secure =3D excret & R_V7M_EXCRET_ES_MASK; if (armv7m_nvic_raw_execution_priority(env->nvic) >=3D 0) { - env->v7m.faultmask[es] =3D 0; + env->v7m.faultmask[exc_secure] =3D 0; } } else { env->v7m.faultmask[M_REG_NS] =3D 0; } } =20 - switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception)) { + switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception, + exc_secure)) { case -1: /* attempt to exit an exception that isn't active */ ufault =3D true; diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 29bd308..b86f242 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -176,8 +176,8 @@ nvic_escalate_disabled(int irq) "NVIC escalating irq %d= to HardFault: disabled" nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending= irq %d secure-bank %d (enabled: %d priority %d)" nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pen= ding irq %d secure-bank %d (enabled: %d priority %d)" nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than= vectpending: setting irq line to 1" -nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now acti= ve (prio %d)" -nvic_complete_irq(int irq) "NVIC complete IRQ %d" +nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowl= edge IRQ: %d now active (prio %d targets_secure %d)" +nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)" nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to = %d" nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysre= g read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysr= eg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" --=20 2.7.4