From patchwork Tue Sep 12 18:13:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112354 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5548995qgf; Tue, 12 Sep 2017 11:13:45 -0700 (PDT) X-Google-Smtp-Source: ADKCNb4dntSFgSN2v7cWKOOnWz7OL3GJdWHm5lQCDylJsCACOT76XmwlQWSZTpUmZyabuqQhDXqL X-Received: by 10.99.176.14 with SMTP id h14mr15820430pgf.358.1505240025325; Tue, 12 Sep 2017 11:13:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240025; cv=none; d=google.com; s=arc-20160816; b=jxxvdcv33o6AP5iJvWoHbqqLsyexrmnZLgIUc/ulesNzA3JYjLSvbeWgEnpGbbdHYz ipb1Y93DMKL78KTTFc9bF45osmTuv/TXggGnsRl0WkawhcBdbQoZAt5pMcgVKx11FNeJ E2j7+VmCwoi/1p3mCsU5OpH7EY8z89yVY+WMVWfdR1jInjlju2h/p8nw7O3Glcy03k2A qOI0ic0hZXbOmPwn6qRJTvBfdquoekiMUZDBhKaELurIA0HXakTDJsQsFWNxBZYHfcZQ bBG9PNvSF1o+XMD0JC324hDFB6++QPZhqqH66ZL0TUxNkuJ6uk0opp7ao1Oy3VU5wgf2 RDJw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=kQsJmKLqlo0zU/tVNsuqSlH51deGiBgTiRR53dwMu9M=; b=S14WQypYqjcTb7ruA1YjMTi4vVJ/Greg1tjUUHDqK6JRewqzCfFtytLLH766T3ELLJ w4v/eHy92nh9wA53ds+HA3C3bHpob2suCb5v0wkm07f8BwOO0CrLBAGxKcrxW3+0QYvD veHZ0jZP2nc3kto3aFJMoo0LzH8X/cCVOkoy/PjuWc5ZUUE1TpA0RQI1Od47zxvVOY31 tSTk6OAL1qrlQmUkeBeDgOBurpw6C9UzZQccQZsRqIZwhjWn3SJwXY6/WC5ersCnxoAG NEtJaZuo5Q7Ty0G/O11YnZ1GXt7oDpd76M7/6hlYYUv+UtG3ZnmbAfM9ykuCfhMy5kck LzBA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id g6si9111044pll.236.2017.09.12.11.13.44 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 01/19] target/arm: Implement MSR/MRS access to NS banked registers 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> 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 --- target/arm/helper.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) -- 2.7.4 Reviewed-by: Richard Henderson 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]; } if (el == 0) { return 0; /* unprivileged reads others as zero */ } + 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.SPSEL. + */ + bool spsel = env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_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_MASK) ? @@ -8936,6 +8992,60 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) return; } + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + switch (reg) { + case 0x88: /* MSP_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.other_ss_msp = val; + return; + case 0x89: /* PSP_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.other_ss_psp = val; + return; + case 0x90: /* PRIMASK_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.primask[M_REG_NS] = val & 1; + return; + case 0x91: /* BASEPRI_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.basepri[M_REG_NS] = val & 0xff; + return; + case 0x93: /* FAULTMASK_NS */ + if (!env->v7m.secure) { + return; + } + env->v7m.faultmask[M_REG_NS] = 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.SPSEL. + */ + bool spsel = env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_MASK; + + if (!env->v7m.secure) { + return; + } + if (!arm_v7m_is_handler_mode(env) && spsel) { + env->v7m.other_ss_psp = val; + } else { + env->v7m.other_ss_msp = val; + } + return; + } + default: + break; + } + } + switch (reg) { case 0 ... 7: /* xPSR sub-fields */ /* only APSR is actually writable */ From patchwork Tue Sep 12 18:13:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112348 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5548909qgf; Tue, 12 Sep 2017 11:13:41 -0700 (PDT) X-Google-Smtp-Source: ADKCNb65qowww6soKKWsw+Mp+jyLbIFH70cgNiRlUGzLlzQLHBssfbv8UkwB9YC7rrBtLHBD06P1 X-Received: by 10.223.195.108 with SMTP id e41mr12596829wrg.51.1505240021739; Tue, 12 Sep 2017 11:13:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240021; cv=none; d=google.com; s=arc-20160816; b=Omd75nscoB7CsiOkpqJsbZPHUt0sRCz9FcgI5PWxMHkqbqTLPKwN/STpNP3sRsPYAL RGvxxf/9LxsgXsmVYUJLETfD3pMqTGixYrvlKvHs84Jq8rporRIIx5R3V0qGkG2t2dke xeIEXJnYxpz94kf8PAAzB6xlhQSVOvjJQzE7QjEuQqK6Nyj4hxmZjV4PpsCHlspRevTU l3qopGpgawERDMdG++H9lcy/lUk+fy56OJ0n0r8lEiWi5suTa1FjQ0uBVJa1soCssxpK JxKsDlrqxSWNgkYqULpbd6SRAiFLC3L/vHQWb8vYXtVXT08PhQ7PxusDxv95UPl9XDqS vw4g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=bpESvZ/5OmlheuZ1ANsRLM3u0F8HOEBbwg6I+XzDjuU=; b=D9XftrHVhhiq6eVGoFsN3La7qo1Mpen9UFgdbTLlkYXPOEhXWLITpCU/oXKthbk3BS RM1wbcvj7hYvRwYPzgjB+b8Yo98HozFG0mjtKFmxLu9M4gz1zsVri8zAnLghU9qN763S q+z+5k0Vbkaj1+8ntlnKGwv/43ZgN0hbitq1I2qWHeUhNbTiEFrg5i362s4/K7NYBoNR n80ADOltFV4CeVeYecgHLHoA8N54AXsMi9Pc0QFxZiASoRL304VLeNvKD0wsYqjkolf0 mTx1R1A4uPHbucjoJ8u1YkWk125n99iOhsbgYgCh3QWGdsn8T1dVo6XrQ/2bZlIMzQhR M+iw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id b9si9492025wrh.36.2017.09.12.11.13.41 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 02/19] nvic: Add banked exception states 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> 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 --- include/hw/intc/armv7m_nvic.h | 14 +++++++++++++ hw/intc/armv7m_nvic.c | 49 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 @@ /* Highest permitted number of exceptions (architectural limit) */ #define NVIC_MAX_VECTORS 512 +/* Number of internal exceptions */ +#define NVIC_INTERNAL_VECTORS 16 typedef struct VecInfo { /* Exception priorities can range from -3 to 255; only the unmodifiable @@ -41,6 +43,18 @@ typedef struct NVICState { ARMCPU *cpu; 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, though + * 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 exceptions + * like SecureFault that unconditionally target Secure state). + * Entries in sec_vectors[] for non-banked exception numbers are unused. + */ + VecInfo sec_vectors[NVIC_INTERNAL_VECTORS]; uint32_t prigroup; /* 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) /* Effective running priority of the CPU when no exception is active @@ -1158,6 +1158,43 @@ static const VMStateDescription vmstate_VecInfo = { } }; +static bool nvic_security_needed(void *opaque) +{ + NVICState *s = opaque; + + return arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY); +} + +static int nvic_security_post_load(void *opaque, int version_id) +{ + NVICState *s = opaque; + int i; + + /* Check for out of range priority settings */ + if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1) { + return 1; + } + for (i = 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 = { + .name = "nvic/m-security", + .version_id = 1, + .minimum_version_id = 1, + .needed = nvic_security_needed, + .post_load = &nvic_security_post_load, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS, 1, + vmstate_VecInfo, VecInfo), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_nvic = { .name = "armv7m_nvic", .version_id = 4, @@ -1195,6 +1232,16 @@ static void armv7m_nvic_reset(DeviceState *dev) s->vectors[ARMV7M_EXCP_NMI].prio = -2; s->vectors[ARMV7M_EXCP_HARD].prio = -1; + if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { + s->sec_vectors[ARMV7M_EXCP_HARD].enabled = 1; + s->sec_vectors[ARMV7M_EXCP_SVC].enabled = 1; + s->sec_vectors[ARMV7M_EXCP_PENDSV].enabled = 1; + s->sec_vectors[ARMV7M_EXCP_SYSTICK].enabled = 1; + + /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */ + s->sec_vectors[ARMV7M_EXCP_HARD].prio = -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. From patchwork Tue Sep 12 18:13:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112349 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5548941qgf; Tue, 12 Sep 2017 11:13:42 -0700 (PDT) X-Google-Smtp-Source: AOwi7QAqjexoB2FMCX/oUGt+FASgpmaRbWTTTbSL/kjXfjqLby0nm21I5FwWjclEh3QIuXS9GO/Y X-Received: by 10.46.23.25 with SMTP id l25mr2746460lje.178.1505240022818; Tue, 12 Sep 2017 11:13:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240022; cv=none; d=google.com; s=arc-20160816; b=gUAo5ecFjDK66n+rOVJhcePie1NBRx83Hu4vaXivknOgJzt7+TC093/4CEoLyYv06R 9WVfcMgsTvRUE1LT8JCN8zKTjfO8lsFiqRdf5DuPCDG1vs2W3DNBOvNR5Js5ghWGxa1m vSg08Pyg26Fa2DFwUVhqciKR4EFenyryqIAFCDHm/9TRyPNHXbfbuErDO+MldmzdnUFh Fc/BbAEI8JjCPy9yysZIP0LyGYdCUWWVm0E+/h9eSiR+zLoNpNPoBvrOOq3Htatcpp3Q s+quAX5/4aqHNF9UQfo5h1ke1KTR1PqstzdR63ASHCUZbrENLzyguLl45w36PMbD2XJE P9Yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=0RdA84HwaRVq1HY6y6uO6ARE7wTHWisiKDdMt0RMmtc=; b=uqCLjKdWKz6/CBDAdtaBtxIDBkP8fkYvw7/Af3jWpIFJf4vnSDJtkGuQkys8xia2I8 d8bVNgmkb3Os9qksjydfZHj5POmGf3BVo2NPK21gvZpTGA6xXlxSPs9y5wWPwUnoJb9f UAaTA3zgkb5Uwb3oucPoJTqmNxPH78yZyD6964JPF5Ky73yI4lUnAgofG0LeZs6krJpg 2txGkfHgbIh7qd9yu2AuSfWlPRxQ9O7FriNeIBQ35vKdC2DehH6maL8BntpaybbSGj9H rHmw0YSnpqRl8MN4ZIdKVxBami4ZnsLsM4WfIqP763+AO6erotHIjOl/VmlLo3XslYep 5mhw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id m141si4479533lfg.617.2017.09.12.11.13.42 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 03/19] nvic: Add cached vectpending_is_s_banked state 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> 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(-) -- 2.7.4 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; - /* 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 */ 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) s->exception_prio = NVIC_NOEXC_PRIO; s->vectpending = 0; + s->vectpending_is_s_banked = false; } static void nvic_systick_trigger(void *opaque, int n, int level) From patchwork Tue Sep 12 18:13:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112350 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5548944qgf; Tue, 12 Sep 2017 11:13:43 -0700 (PDT) X-Google-Smtp-Source: AOwi7QCRrQ5vUg1TYnXe7oYBFCfXkU6Pr4Gs6+1v1EeZEoQ0wkQiVR/OH3JCbar+RHStC6MrcLst X-Received: by 10.28.74.144 with SMTP id n16mr363659wmi.151.1505240023029; Tue, 12 Sep 2017 11:13:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240023; cv=none; d=google.com; s=arc-20160816; b=aSNwB3sMQj/X1lxG8GB/a1u4Wvgy8Zaz8ULFSpaccIZjAdKFQzCif4EVYBTdR+Me8a y7Hm8j6J/D1RLlGXwYXlcpSY3FFVaO2Ov0cKQ/DEwOZzvTS2wjBXRtgYIZq2SKca+4ms XOw/YMNkm5QOVXQ4bOA7cU2caNPA63VLPxlX/p1ShhsclGGO9PtPRwbqMEcJrGXk1DnJ PQfHBZQ6P9eD4EvQHp3Rf9L6nAkYY4bTLnmqAV/nxntKdzR1V7AEw003F+hV8vtIaj3T 8GgaC1o3Wow09H6+hJgh3mc/2UTOgIsEMw4IiODv+ML8C5xhZ9B5CR2oaT4EnONBeVMs ExsA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=SJLISZy0Y2yXJJx7XEJ/sXNFvSm2YfyZNNF2xFwHRMc=; b=B3A631ZeeuCUDV5HcNq+fCMFolvkl/oN52/9aw3M5OBfw9Ye0rzXVzbbWWAUqyY0fC U1YR0g9qwCB2t+wHcZctSsKZjP5X28GIasPYUwIJ/2dtjUUs1+AsfcxgvzEg8HzAMBRQ wydUjZaUlSe7ZjIB1WPzpUUnGdRK5GKPXsXQVTzrqPCCljYmuW0msg0GCJ6CIifXxq2A rQ6f31Ccu+4dL+emSqLZHysAeZ9hjLpgYRBqJd/7vkvkV8llCw14Bz7aokbb3MY3Z9Bi HaBxZs7rqojlH4Ml1k3EPrvzjEY9GdW9vhuwaVUvwOdUW1O9tS/Av/k/d8SJvRAnLsxW mKjQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 199si9225857wme.0.2017.09.12.11.13.42 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 04/19] nvic: Add cached vectpending_prio state 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> 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 --- 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(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 */ 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[] = { 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_PRIO; + return s->vectpending_prio; } /* Return the value of the ISCR RETTOBASE bit: @@ -156,10 +156,17 @@ static void nvic_recompute_state(NVICState *s) active_prio &= nvic_gprio_mask(s); } + if (pend_prio > 0) { + pend_prio &= nvic_gprio_mask(s); + } + s->vectpending = pend_irq; + s->vectpending_prio = pend_prio; s->exception_prio = active_prio; - trace_nvic_recompute_state(s->vectpending, s->exception_prio); + trace_nvic_recompute_state(s->vectpending, + s->vectpending_prio, + s->exception_prio); } /* Return the current execution priority of the CPU @@ -323,7 +330,6 @@ void armv7m_nvic_acknowledge_irq(void *opaque) CPUARMState *env = &s->cpu->env; const int pending = s->vectpending; const int running = nvic_exec_prio(s); - int pendgroupprio; VecInfo *vec; 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); - pendgroupprio = vec->prio; - if (pendgroupprio > 0) { - pendgroupprio &= nvic_gprio_mask(s); - } - assert(pendgroupprio < running); + assert(s->vectpending_prio < running); - trace_nvic_acknowledge_irq(pending, vec->prio); + trace_nvic_acknowledge_irq(pending, s->vectpending_prio); vec->active = 1; vec->pending = 0; @@ -1251,6 +1253,7 @@ static void armv7m_nvic_reset(DeviceState *dev) s->exception_prio = NVIC_NOEXC_PRIO; s->vectpending = 0; s->vectpending_is_s_banked = false; + s->vectpending_prio = NVIC_NOEXC_PRIO; } 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 pending SGI %d" # hw/intc/armv7m_nvic.c -nvic_recompute_state(int vectpending, int exception_prio) "NVIC state recomputed: 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 level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d" From patchwork Tue Sep 12 18:13:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112351 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5548960qgf; Tue, 12 Sep 2017 11:13:44 -0700 (PDT) X-Google-Smtp-Source: AOwi7QBoQOQyqGPUC6J12qNnSsfL9GEzIFEL4+C6hDEDvWyOfIkButJ5FR7gwIJP2Z0EswsgDPo+ X-Received: by 10.25.215.38 with SMTP id o38mr4759898lfg.124.1505240024107; Tue, 12 Sep 2017 11:13:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240024; cv=none; d=google.com; s=arc-20160816; b=r/Yl1c0/myMBdJWsDU1Y/UKN18WMHzhfuq6VxfwnHu9h9fzIm1jANJmcWs9L/Jk4wN 1t4ItbQ8LSuuWULZvhgpZrvtCdWqRMM29XecghTG47iS45OgWH4Vl0fNhSYhUMC8mQHf jF0DEkzqXcMf7XMGsTxyIRYdEWGE+9iVfyyxPM9ZaaNAd3Aijlf5c2TCTSbaKlsEyvp4 1Dn/n+/XIR+x/yRYwGvS4h0oQBjPmBqYcuwT0HecYx4bNt3SbO8qHyzeqAa1UjuJZZMc +nInuvhU0wuB1he/nlBuRMwjYIYilvizU5UWqtWJ/TnGUsk2Dyt1fkad9C8mFDtypvio XszQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=S4xRoR+aki4pDlDeeX3neR3B7CUCg/JnQcDHI9nYI54=; b=kZf/wuDumWUh0Ze7DCrG3clSChEX/7X915u9kLywLbZDLYmeU+Ozz/PC+CShZ/Odig EibvGGBJQxxnsbtIFYvmbBJhk/OzS4F8Xmeh6rhFjQaMzYQbuDuG3tkmar1K7LIETe1Q sMnPST7MibF3Hd+YsZd/sIlsy3tlLhV+pGtGk5wpLKzess9S9k6wVHPKLwshJ38LFjUb EADRJqgU6ANZy+Q2BwzHmUn6ByEOTyO2MNApLRUjXPcs5B3ILker+T1KobX42vsSACdR bpXeDc7JUptnZRg4j2orSVJ6XTMwCN7Ae1tOwFfQ3Z9zKP8CxLkxXXlJd/BkghArRKuK KN2g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id a2si4797562ljb.393.2017.09.12.11.13.43 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:43 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 05/19] nvic: Implement AIRCR changes for v8M 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> 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 --- 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(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 unused. */ VecInfo sec_vectors[NVIC_INTERNAL_VECTORS]; - uint32_t prigroup; + /* The PRIGROUP field in AIRCR is banked */ + uint32_t prigroup[M_REG_NUM_BANKS]; /* 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 implemented */ uint32_t secure; /* Is CPU in Secure state? (not guest visible) */ } v7m; @@ -1200,6 +1201,17 @@ FIELD(V7M_CCR, STKALIGN, 9, 1) FIELD(V7M_CCR, DC, 16, 1) FIELD(V7M_CCR, IC, 17, 1) +/* 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); } /* Recompute vectpending and exception_prio */ @@ -451,8 +451,21 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, 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 = 0xfa050000 | (s->prigroup[attrs.secure] << 8); + if (attrs.secure) { + /* s->aircr stores PRIS, BFHFNMINS, SYSRESETREQS */ + val |= 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 |= 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] = value & 0xffffff80; break; - case 0xd0c: /* Application Interrupt/Reset Control. */ - if ((value >> 16) == 0x05fa) { - if (value & 4) { - qemu_irq_pulse(s->sysresetreq); + case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */ + if ((value >> R_V7M_AIRCR_VECTKEY_SHIFT) == 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 mode " "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 = extract32(value, 8, 3); + s->prigroup[attrs.secure] = extract32(value, + R_V7M_AIRCR_PRIGROUP_SHIFT, + R_V7M_AIRCR_PRIGROUP_LENGTH); + if (attrs.secure) { + /* These bits are only writable by secure */ + cpu->env.v7m.aircr = 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 = { .fields = (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 = { .fields = (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) if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { env->v7m.secure = 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 = R_V7M_AIRCR_BFHFNMINS_MASK; } /* In v7M the reset value of this bit is IMPDEF, but ARM recommends From patchwork Tue Sep 12 18:13:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112352 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5548961qgf; Tue, 12 Sep 2017 11:13:44 -0700 (PDT) X-Google-Smtp-Source: AOwi7QCBIYevW93XVwR09mAVkEqn35QQ4+yCHsloZxXXRdQXNDPSZFltWJj3z/UJdJ6vTIFsf2CX X-Received: by 10.28.97.11 with SMTP id v11mr325818wmb.45.1505240024156; Tue, 12 Sep 2017 11:13:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240024; cv=none; d=google.com; s=arc-20160816; b=LLFvbSLOujnWzTU+k+ulO8fSWxj+Fa4LJUg0VxciMMh/jX+IfQHTSfHgUi05fGNoVG c/iNZJ2ey4nyIfdx4TDzSiyzRi18JgAMWvWru950rVk+MZioOsWUbVaT2jTElpXPWQLj pRqz3pDYDpN4Z8Wz/NU86jpjqAsDAAhDRF6LOSiI3qRt2IAGtSyp/6buceTpWfm/dgOk 9eKLu3dS+3CCjYTxk8InB6i8qaTosWqvWZP/lJDRiiV/q1FWiLLxCMqxQIVNTNrNI2yT Bc9uH4xAnxLDhsTDxt9fXlLZj4cv3ZgHdrCaQu6+VBiZbHA+ZXuF+gzeW2hqlIyyAGEG VxBw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=stY5Ps6HXs3obf3PcYxE3USHO9aFc13HjVy0YFrAprw=; b=Go/miWArE6HcHLIKLdo2Klueo65KROOI7/0KzG4+o8gl/d/5/8AioIZ8+PRz+zo2Dh 2QW9j3Ra+jHpJmoh0MowJfqvQ8o/rD7DMWxwYDnVx0yidtD5HiIbmA///WMNTe6xIcne vcmp30ldLyzCRIO9Ycb7vq2Xm0oJWuFMTlrTtKzF5eWnbSEMzkNols5xAkr4Y1jjPWeA QzfiY6kD8LTgyEdaouqRR5A5uFdTyeJGkNor1WNBVnxzdm20ixH+cJneQmBQnZ5PgKDs CmVtHQMJSCnHMLy0UZqHIuMrs9rcNQllj7hwvAFUEgplfqu7NQ+t91RskVXeuD1yKc+0 tH9Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id b26si9452243wrc.383.2017.09.12.11.13.43 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 06/19] nvic: Make ICSR.RETTOBASE handle banked exceptions 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> 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 --- hw/intc/armv7m_nvic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 = 0; + bool check_sec = arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY); for (irq = 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 == 2) { return 0; From patchwork Tue Sep 12 18:13:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112353 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5548984qgf; Tue, 12 Sep 2017 11:13:44 -0700 (PDT) X-Google-Smtp-Source: AOwi7QA8jOJ8zumw6KyHj9E85QHYyIEs/JefQRWroJoNYHOJohFEL0q3Q6ZcejbLV/2avuyW2iZK X-Received: by 10.28.107.17 with SMTP id g17mr400837wmc.58.1505240024853; Tue, 12 Sep 2017 11:13:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240024; cv=none; d=google.com; s=arc-20160816; b=OX2/tEN/xNcY+Fe9Glo4BkONUri9rsHK/I29fsdWuzJAxIymz6vjtyTcb265h86I4G EA8LSZCH3Fp8K75FUZztX7q9zy0Ls379n7Ds2SnI6WyTjCxLSk4obwAY5B5Pih4A3/bs XP+6GtFduMbC/TIV9HLbtaKsdBu6a7DQp/aWNHIrfZftXg2Ov+hVlOqH02GNdSA1zfkH 9CTj9q54LUG3GJiLSitV1NMao6NnD4hvxfl7/OsMMb8isyma4Lclp2L2sUF+fE3Frlyh BI1UsPTQwaw1vHqxl3MpKpQr5qLNqXILMlPic4neki3aUR4Os5qZGFRdKLaPgk9LGhT5 65NQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=TZqISnWS8crTyERgwclvfQOkiQpXDa7RbssLPTTV9vg=; b=aV3AaF+4ZbVZZj1qF7nPK8l478ZmlPVn5XOo00HcZDs8GlANHz/k75NUKlO/REeulC 8ejatfXXcnV5SpDFSPQpMcnHi+x0D3C/wuCyT6/x2PP7+N6r/HzeGyUpAYpeYqcFPMf0 217HYurZHk9SGTdwMv1D1efbDqJ5uq0JZil3J9on0v+FnO+K0Cn1WSbYGKdeaKUhHwJ/ M+9GvPmT65eVIddl4tt2aIVWrp2dY/Cn9bWdq9WvXwIKQ5gmijD/UbbldKAHTcM7ZW0L JxP+IqN1DFJoBLZUWUfLITuWvP+78lEevvn2cYwVp+18CF62udes3hazefhYYDc2GADs E1uw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id i131si8904412wmf.240.2017.09.12.11.13.44 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:44 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 07/19] nvic: Implement NVIC_ITNS registers 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> 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 --- include/hw/intc/armv7m_nvic.h | 3 ++ hw/intc/armv7m_nvic.c | 74 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 7 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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]; + /* 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 offset, 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 = 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 = 0; + for (i = 0; i < 32 && startvec + i < s->num_irq; i++) { + if (s->itns[startvec + i]) { + val |= (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 = s->cpu; switch (offset) { + case 0x380 ... 0x3bf: /* NVIC_ITNS */ + { + int startvec = 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 = 0; i < 32 && startvec + i < s->num_irq; i++) { + s->itns[startvec + i] = 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, hwaddr addr, startvec = offset - 0x180 + NVIC_FIRST_IRQ; /* vector # */ for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { - if (s->vectors[startvec + i].enabled) { + if (s->vectors[startvec + i].enabled && + (attrs.secure || s->itns[startvec + i])) { val |= (1 << i); } } @@ -978,7 +1015,8 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, val = 0; startvec = offset - 0x280 + NVIC_FIRST_IRQ; /* vector # */ for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { - if (s->vectors[startvec + i].pending) { + if (s->vectors[startvec + i].pending && + (attrs.secure || s->itns[startvec + i])) { val |= (1 << i); } } @@ -988,7 +1026,8 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, startvec = offset - 0x300 + NVIC_FIRST_IRQ; /* vector # */ for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { - if (s->vectors[startvec + i].active) { + if (s->vectors[startvec + i].active && + (attrs.secure || s->itns[startvec + i])) { val |= (1 << i); } } @@ -998,7 +1037,9 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, startvec = offset - 0x400 + NVIC_FIRST_IRQ; /* vector # */ for (i = 0; i < size && startvec + i < s->num_irq; i++) { - val |= s->vectors[startvec + i].prio << (8 * i); + if (attrs.secure || s->itns[startvec + i]) { + val |= 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, hwaddr addr, startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ; for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { - if (value & (1 << i)) { + if (value & (1 << i) && + (attrs.secure || s->itns[startvec + i])) { s->vectors[startvec + i].enabled = setval; } } @@ -1072,7 +1114,8 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */ for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { - if (value & (1 << i)) { + if (value & (1 << i) && + (attrs.secure || s->itns[startvec + i])) { s->vectors[startvec + i].pending = setval; } } @@ -1084,7 +1127,9 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, startvec = 8 * (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */ for (i = 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 = { 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 = 0; s->vectpending_is_s_banked = false; s->vectpending_prio = 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-security + * 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 = NVIC_FIRST_IRQ; i < ARRAY_SIZE(s->itns); i++) { + s->itns[i] = true; + } + } } static void nvic_systick_trigger(void *opaque, int n, int level) From patchwork Tue Sep 12 18:13:55 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112355 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549003qgf; Tue, 12 Sep 2017 11:13:46 -0700 (PDT) X-Google-Smtp-Source: AOwi7QBuJlo1WhKWhaJLG39914PdpuQGzYTvPDaKjlm1hKENuMZ6XG5+/ObtjGWsQtt3DJUT80Pq X-Received: by 10.28.109.142 with SMTP id b14mr296613wmi.65.1505240025672; Tue, 12 Sep 2017 11:13:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240025; cv=none; d=google.com; s=arc-20160816; b=C27lcwkAEH4AUFOoABFwFCLZWi7VoV7XwRTBh5Lyj85kDhI781AWv00KJEIEBkVqvd +GkEdAW5LmT46ZpiYCK1wwpbv0Gvn1GUILZpf2lNpSSE7bWP4Dr4AtFZfRT7nTlWBPhx K0rH/RmxxSq4J7g4YRCwA1ubDFf6JPAyi6l6f6hLd1WsMOt1pNQD3WsmYbQHVIwbbCKs +RscdlnN9+BBVBO12XX9xhMM6ffx0oC4DA6fIaD4gZ/zvy5wFOW+z7oWBdpZMX7lnqm+ mr5O0O/DJgTM5N+GG9qd+9hpsMKdAKzqpYIeg/0GBbmZSvTezn60ZUYdZmAItugA685L JKpA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=gKAMgogRWVRHLL2+573F/4t+0MGLZHPfN0Gkx/z5T8c=; b=DAf/zuwxST54SOsSd6hsn0lH/ttkKzfpdeG/Arns0wMWIHvLxq0l+cgYzUQBXDKzTG nJMpVqCA9kcBkCCbdFrErYy61G6noiYUB8qLYD9uvD8wA+baxhlFdk7ZHLjMP4ivX2d8 2f+yHhlSIqcSjRlB9mN/qPgY8wjCyj6XGO+YGP98dtH5xTiNBPro5DRLP8z7AMXtJBJj 3aNAjoYWETZ9P0iigMhS3u514HttqBz2y01VOCm5wifTc5U1jldVnF6spA8MKWIQykKg RnBdlixJ7AlhBuUBaYpx7Qd9zOPaDUwSg2A7wM5hlqIYN+rWIOXU1ZBsZGO1IrncU97W G7tA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id w18si9557719wra.107.2017.09.12.11.13.45 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:45 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 08/19] nvic: Handle banked exceptions in nvic_recompute_state() 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> 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 --- hw/intc/armv7m_nvic.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++-- hw/intc/trace-events | 1 + 2 files changed, 147 insertions(+), 5 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 static const uint8_t nvic_id[] = { 0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1 @@ -126,13 +128,139 @@ static bool nvic_isrpending(NVICState *s) return false; } +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 == ARMV7M_EXCP_HARD || + exc == ARMV7M_EXCP_MEM || + exc == ARMV7M_EXCP_USAGE || + exc == ARMV7M_EXCP_SVC || + exc == ARMV7M_EXCP_PENDSV || + exc == 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 >= 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 &= 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 = (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 = NVIC_NOEXC_PRIO; + int active_prio = NVIC_NOEXC_PRIO; + int pend_irq = 0; + bool pending_is_s_banked = 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 = 1; i < s->num_irq; i++) { + for (bank = M_REG_S; bank >= M_REG_NS; bank--) { + VecInfo *vec; + int prio; + bool targets_secure; + + if (bank == M_REG_S) { + if (!exc_is_banked(i)) { + continue; + } + vec = &s->sec_vectors[i]; + targets_secure = true; + } else { + vec = &s->vectors[i]; + targets_secure = !exc_is_banked(i) && exc_targets_secure(s, i); + } + + prio = exc_group_prio(s, vec->prio, targets_secure); + if (vec->enabled && vec->pending && prio < pend_prio) { + pend_prio = prio; + pend_irq = i; + pending_is_s_banked = (bank == M_REG_S); + } + if (vec->active && prio < active_prio) { + active_prio = prio; + } + } + } + + s->vectpending_is_s_banked = pending_is_s_banked; + s->vectpending = pend_irq; + s->vectpending_prio = pend_prio; + s->exception_prio = active_prio; + + trace_nvic_recompute_state_secure(s->vectpending, + s->vectpending_is_s_banked, + s->vectpending_prio, + s->exception_prio); } /* Recompute vectpending and exception_prio */ @@ -143,6 +271,18 @@ static void nvic_recompute_state(NVICState *s) int active_prio = NVIC_NOEXC_PRIO; int pend_irq = 0; + /* 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 = 1; i < s->num_irq; i++) { VecInfo *vec = &s->vectors[i]; @@ -156,11 +296,11 @@ static void nvic_recompute_state(NVICState *s) } if (active_prio > 0) { - active_prio &= nvic_gprio_mask(s); + active_prio &= nvic_gprio_mask(s, false); } if (pend_prio > 0) { - pend_prio &= nvic_gprio_mask(s); + pend_prio &= nvic_gprio_mask(s, false); } s->vectpending = pend_irq; @@ -186,7 +326,8 @@ static inline int nvic_exec_prio(NVICState *s) } else if (env->v7m.primask[env->v7m.secure]) { running = 0; } else if (env->v7m.basepri[env->v7m.secure] > 0) { - running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s); + running = env->v7m.basepri[env->v7m.secure] & + nvic_gprio_mask(s, env->v7m.secure); } else { running = 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 redistributor 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: vectpending %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 level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d" From patchwork Tue Sep 12 18:13:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112356 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549012qgf; Tue, 12 Sep 2017 11:13:46 -0700 (PDT) X-Google-Smtp-Source: ADKCNb6L3XIksSm9r/HQmmF67lMEEYFkg2nfnZhRSH5IaKDA+pn2shLIaDFyVdj0hnrH92KTd1nB X-Received: by 10.223.179.200 with SMTP id x8mr7071833wrd.274.1505240026374; Tue, 12 Sep 2017 11:13:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240026; cv=none; d=google.com; s=arc-20160816; b=LoQTYW2KcxTMpkgfsteKZzZXWfUKE0xU/YgofgsZmj+rQDQTfr3jVWJ/J3ft5txgZY M/XtISsDPg4xXPk1JoB9P3txpDOwyMXcdXB+Oo9rRgWvymfy5NHu2x5fkinCvn+eMC4a ZXyTRWMX/C9pIe7diMyK3ULui34jxwJRyqzwUgvo/RPoAjkpR5Mnl4TUy27P65ZYzHwc PtSVhK5N60CdWygcsw4dq5ELb70fAbbtyqAmfVjbTebetILBI7Ppda2hc1TsfTDck/z2 EomPR25xUgZk/2Fa+QOarPCVqSV0Li5yVuNc+/mZYa8Ya1q4S/lsl+QgtMwqOuR7c5AI TCOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=lRui77mQTgIOUl2zVzmVfe1z7G/5MV9+Dju3llF35Yw=; b=spxMruxEZiHpLG6qZwygRY3VgM2Vq2PatPFxMAmkI773MfjhJ96cq/ONZpXy6+IDWV oKICzWODSSOajE1jv2oimDBCD30lEDEQT0BmwzjkitdblSLDWv6ceIfkFZWuWorkdGZ4 fCqnuNfv4VE8/SC18p/a5nVylFlikg0JPMRvMKhSG788nCYYiR3R6Stx9RykbTueKA/i elglAHJF/EIv7ykN4RUngnnur16asJ5k3N60/+6W2MrbQOWFR+rBHBIldOQiF9k9G+Ox yXhMZ3e7PP46Wuc27rwintcXy21zZlYYHvIImgj7lcNYm+6Imtz9XcpBEVZ3ZCyYgsKS 9Q2A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id e2si9564198wrc.294.2017.09.12.11.13.46 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 09/19] nvic: Make set_pending and clear_pending take a secure parameter 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> 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 --- 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(-) -- 2.7.4 Reviewed-by: Richard Henderson 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_exception(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); } -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 = (NVICState *)opaque; VecInfo *vec; assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); - vec = &s->vectors[irq]; - trace_nvic_clear_pending(irq, vec->enabled, vec->prio); + if (secure) { + assert(exc_is_banked(irq)); + vec = &s->sec_vectors[irq]; + } else { + vec = &s->vectors[irq]; + } + trace_nvic_clear_pending(irq, secure, vec->enabled, vec->prio); if (vec->pending) { vec->pending = 0; nvic_irq_update(s); } } -void armv7m_nvic_set_pending(void *opaque, int irq) +void armv7m_nvic_set_pending(void *opaque, int irq, bool secure) { NVICState *s = (NVICState *)opaque; + bool banked = exc_is_banked(irq); VecInfo *vec; assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); + assert(!secure || banked); - vec = &s->vectors[irq]; - trace_nvic_set_pending(irq, vec->enabled, vec->prio); + vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq]; + trace_nvic_set_pending(irq, secure, vec->enabled, vec->prio); if (irq >= 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); } - /* 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; otherwise + * we take a Secure HardFault. + */ irq = ARMV7M_EXCP_HARD; - vec = &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 = &s->sec_vectors[irq]; + } else { + vec = &s->vectors[irq]; + } + /* HF may be banked but there is only one shared HFSR */ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK; } } @@ -551,7 +581,7 @@ static void set_irq_level(void *opaque, int n, int level) if (level != vec->level) { vec->level = 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 = (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); } } 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] |= 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.secure); 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 != 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] |= 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.secure); env->v7m.cfsr[env->v7m.secure] |= 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.secure); env->v7m.cfsr[env->v7m.secure] |= 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.secure); env->v7m.cfsr[env->v7m.secure] |= 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.secure); 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 priority %d" nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d" nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled" -nvic_set_pending(int irq, int en, int prio) "NVIC set pending irq %d (enabled: %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 pending 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 active (prio %d)" nvic_complete_irq(int irq) "NVIC complete IRQ %d" From patchwork Tue Sep 12 18:13:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112357 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549023qgf; Tue, 12 Sep 2017 11:13:47 -0700 (PDT) X-Google-Smtp-Source: ADKCNb7mfB/fYp2RBmux5jsGkxigmUnAy+VfT1ftPNsXNSJ+6FdoiHKGBtBS2K/hUFmwjFlXJs5t X-Received: by 10.223.147.166 with SMTP id 35mr15141196wrp.90.1505240027064; Tue, 12 Sep 2017 11:13:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240027; cv=none; d=google.com; s=arc-20160816; b=f1HHv0Ep7uwh2ejScBsY2iPxmxEsgV9OnwycPuAd7byG3VU3OxAquFxsDe3eSwlpDw fYGnh5hNFJ/1eSVFDncXeCBTpNz6kotK0ezfINXMEXdN7MAWHe1hElVaoSlXW0DRnKwO NSdRct7H+tuaF7gMrFwZx9a0F8bifvJCJ3+IjPyTHL9irjEW3y2A8KPOQsmMHGT3ClTC gheIgdAdxiQ9s3M9VzGWtSU7RixgnlEDRGO3HiApt3mEb7ho5m+eKAkgTZjm2vc0V6XK nqWyGs0+LUcLXLl+EdFzSKpP/ruVmQ2lxAP29jDD1kByB9jtjpFTKRtuLL9PT3e8Qq7a kDsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=FlUItbsz+RUazJQkPcG53M0KyOhORaDuFAIsj/CPBRk=; b=x0eLTgG9HMcQtfXxGElxmWytIaFcsWqSrxodcdcC4WZ5RRpErhB06CmxiQa7l5vzWP xmgT5y46cXCjYOBkdk5Rj/6VXDHUAlTarBOljR7+FwvPoARRYNN3yo+bk27M8G+uOVIv iHkjo57kqL+Ngxkx+noXnx39q9d5JIpz99QNX278Dde6+iow6p0Ok/oxOV7fkuGdTyoU dJPUcvanUYKvwNeeHGQmLON6oT6ov3hPZumiLQQ4VKqBgVdQ64kO7jlo5vkSZv5hfJJc 8Lx0HJqVLLyF2d2qsrIUC13UO0WzS0dXeJ61BvFXIPXLLFAZJeA7eU4957XQNUBRVZZH yplg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 32si9776453wra.155.2017.09.12.11.13.46 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 10/19] nvic: Make SHPR registers banked 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> 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 --- hw/intc/armv7m_nvic.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++----- hw/intc/trace-events | 2 +- 2 files changed, 88 insertions(+), 10 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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; } -/* 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=true 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); - s->vectors[irq].prio = prio; + if (secure) { + assert(exc_is_banked(irq)); + s->sec_vectors[irq].prio = prio; + } else { + s->vectors[irq].prio = 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=true 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); - 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; + } } /* Recompute state and assert irq line accordingly. @@ -1149,6 +1174,47 @@ static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs) } } +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, hwaddr addr, } } break; - case 0xd18 ... 0xd23: /* System Handler Priority. */ + case 0xd18 ... 0xd23: /* System Handler Priority (SHPR1, SHPR2, SHPR3) */ val = 0; for (i = 0; i < size; i++) { - val |= s->vectors[(offset - 0xd14) + i].prio << (i * 8); + unsigned hdlidx = (offset - 0xd14) + i; + int sbank = shpr_bank(s, hdlidx, attrs); + + if (sbank < 0) { + continue; + } + val = 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, for (i = 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 = 0; i < size; i++) { unsigned hdlidx = (offset - 0xd14) + i; - set_prio(s, hdlidx, (value >> (i * 8)) & 0xff); + int newprio = extract32(value, i * 8, 8); + int sbank = 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 redistributor 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: vectpending %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 level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d" nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled" From patchwork Tue Sep 12 18:13:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112358 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549031qgf; Tue, 12 Sep 2017 11:13:47 -0700 (PDT) X-Google-Smtp-Source: AOwi7QCi4ToYpLr52FY8fhcXPOYTm0d1D6KsRhLG1rkaq5C+hsIuToBCKbEdIQQCF8t+LwFb0NW4 X-Received: by 10.223.156.17 with SMTP id f17mr14372258wrc.203.1505240027610; Tue, 12 Sep 2017 11:13:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240027; cv=none; d=google.com; s=arc-20160816; b=WLmJhW2zeF1axTOp0tjAVynBFHySPebIeaUty1FEgFI5qbldD7xK5w2ikZ/zoOARgs eoB6zo7u8G5FW3HsI8sfxjnAJOKUv2ggM7RoXoWkfCyVmbTM5oZljnKcvZom/wALwEW4 g0swiBHbz9ixcD70xVTaoBkV3fpEudQk+1at/6RizM2SPgqXntxWCz6ce0e9q86EWIgB DIHGnE4njRCK223GP6bveJSZfNT1QQm1FaDWTnmlgy/bw8Lb4yBjF/Mv3iZJr2pDJcbk lBaJm8Qdwmla4vAE1f1fmZOOBhmps5Aj4QN8qFzRQfrSVjHu98VpSSCeK7TK4zUgnNm4 GDYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=KfqOr5c3D/TPnaY2YCNcC7WzwcmuUVPVB4jjexCkhwQ=; b=lHNU/lwoASsuXS3yIhwKuefiZdJpxuDXCGdhV5WCzzKOrscAq1VSx6ZPLslVGrGT47 N+Wu7MXNY9wHgrpyi8rPVXhPP89Xb3gcxb6FpHYYbemNmPG3owf/zCR/9Chrn9aKuXKW r21sRQgPPQSvYlpxUqMQeFCEdnozesA3UdfKIBpz4WwOGA5YLDgQkG8xTgOY1Ps9KDGA KKxUIZUNAogKMgntmxpy2J9Dx8OtHHbdQeSm8bY6HTK6IUiDcwQXF+QKHzsNcQeLJicg XPcfUdV/bCeny1K88AmxYIEPRcWhBQhc51CaB2Votwo/XbPRoEUxsny9fnIC5o+qzI5I iJ9w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id b79si9370494wmi.228.2017.09.12.11.13.47 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:47 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 11/19] nvic: Compare group priority for escalation to HF 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> 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 --- hw/intc/armv7m_nvic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -- 2.7.4 Reviewed-by: Richard Henderson 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, bool secure) int running = nvic_exec_prio(s); bool escalate = false; - if (vec->prio >= running) { + if (exc_group_prio(s, vec->prio, secure) >= running) { trace_nvic_escalate_prio(irq, vec->prio, running); escalate = true; } else if (!vec->enabled) { From patchwork Tue Sep 12 18:13:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112359 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549045qgf; Tue, 12 Sep 2017 11:13:48 -0700 (PDT) X-Google-Smtp-Source: AOwi7QBDbq44d5aXC34XScJJG4FBSdUh7AO4/rrp3+ZipnR9f5EEz1p2ADaXSqsAPG7fME4bFgIe X-Received: by 10.28.232.138 with SMTP id f10mr335900wmi.130.1505240028370; Tue, 12 Sep 2017 11:13:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240028; cv=none; d=google.com; s=arc-20160816; b=XBRyh8KuuV6dchN5ub4jGPjO6DdOnA8dH4Z38zzcmxao6nMUMUiZki0OZSZX2pdJIN zoyzZmRyUbUNe6SofqfVG3DUb8W3SE++Gome5+BueT8wYSj2tVGtSj4b/KTw9eHDsjDG ++81+xWVafyJlG02CzP8p0zJP6t43IwRVf5u6rIB6ECm1V1VILCr/1bdhWVhihMWbTdG NGo/aRJESgX9c3Hpfx/xlMdEcjns/seo3+Vh1cipexSI5bUnVFrPzrxezMAGmrQ6CCyK W7qXkqOKOl7jynQ0KgxkM2M8kek4SVL+AxRvPhOXWTTz2yzq+spqjJgiiZe9ds1uvPdu uvpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=Hi4KEYkOeqiZNTWr9KA2PYqFwLBCrciDgI8JaNsGQn4=; b=LVAJSvePBtk2gZ796E+Ain5dpZI7gm9jZ3FguTCotSArgYfS8W063/5TgTOv8+XpHh JcTtwL0giY9gx1GpW6U/u7JM907Uq/hWFE5+qP0Dmb2CI8R/2CyoCgH7visWXVnik056 E59qcNfBrIIAr2ctTVO05IX1B6aUjmeQWH8pjqYew37e3JyfjCZyyZHcTAFsf90UjvdB 92JVPXKA2zEHpbtGIzNz+Ka60BVR8dynhnVDRynhkd1c9eATQGePvcJOgwAJZIFOgq+6 k5YddhFe8aGmQNSrgfy+IHaQo6xg59F2G7Hw6fahSr3lxWaYnySxxorMlUkAG7qFmuA7 T7Yw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 2si8982485wms.238.2017.09.12.11.13.48 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 12/19] nvic: In escalation to HardFault, support HF not being priority -1 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> 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 --- hw/intc/armv7m_nvic.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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, bool secure) } 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); - } - /* We can do the escalation, so we take HardFault instead. + /* We need to escalate this exception to a synchronous HardFault. * If BFHFNMINS is set then we escalate to the banked HF for * the target security state of the original exception; otherwise * we take a Secure HardFault. @@ -511,6 +501,17 @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure) } else { vec = &s->vectors[irq]; } + if (running <= 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 |= R_V7M_HFSR_FORCED_MASK; } From patchwork Tue Sep 12 18:14:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112360 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549053qgf; Tue, 12 Sep 2017 11:13:49 -0700 (PDT) X-Google-Smtp-Source: AOwi7QBAX1KIdHJh+lz9ZN6FKX6qoMxkioHV9aRtPh0O/FJ3vHx/v8AbRmWI/f49CEV/gDbWcmXj X-Received: by 10.28.10.142 with SMTP id 136mr303134wmk.92.1505240028890; Tue, 12 Sep 2017 11:13:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240028; cv=none; d=google.com; s=arc-20160816; b=n7enjmerh66DnV35uxtfsiXH0XFXLHND64QreopJ1Sq+lWUltN+V5/2xtcuPNThQaZ yuOsdLg2nj0g+OKAtTVjEyQvPOqLedFRMVUDDSaqWMsnmVTT7ZgfMPsRkw1fJz0S6Y5C NB7Ps8WQXnY6MHBy/Q2l0kuMCv5iNskxHozU2wavUmg/Mq0gwexurM2DSiHhNCWUnXVr a5ZbXl49FIR+FNH9tMFQv2LKUtXZHKCpRafZg/RFLE/CWE6f4IGS1LrjWWfCvbzTXaBi nx5ZdBi8UU+PjWRYyP+QZCRpRIP/LVMh9YAyu+2PNoqZz2N+8KBjM+ubwilKD0DxVfuS jDkg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=mg2A4zX2ZTvB3uLwahEsHqpOEORmmkpaaPSUzV5IF8w=; b=W9FBGR0TdzVefDD1XruqL/z8rfJ/5X8E5oRfdCNVeIz5jcAUjD6Hwr/5TnVq74VEtW fVNJOAt5ajn6d9wpjkULLzznwwWfswjJ3oh+anqjpizlJ4JA7dPKtwM0uQxKX8EFAOaN bVEd6nJH2EZWf15uQrEk7nJw6Nv58PwxP4pS2wxgDwIhPXMjlONmWgUfMHRuLYGPKO4n 6cvpTX1WLTxNiYw4Jj7KAA9cfvXQ1BEzUWIDTkbYGGsFx1ybCdDhq6L1HybNSBDVfEvf sC8LZmojCbaidWZahJCM1L06EEdTYjGoEKbvUVJEIA/T3+vGOmhJWqMGXhua3Eu4QfJD CE+w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id p103si9515275wrc.149.2017.09.12.11.13.48 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 13/19] nvic: Implement v8M changes to fixed priority exceptions 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> 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 == 1: -3 NMI: -2 Secure HardFault if AIRCR.BFHFNMINS == 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 --- hw/intc/armv7m_nvic.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 = -3; + } else { + s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1; + } } nvic_irq_update(s); } @@ -1452,9 +1458,12 @@ static int nvic_post_load(void *opaque, int version_id) { NVICState *s = opaque; unsigned i; + int resetprio; /* Check for out of range priority settings */ - if (s->vectors[ARMV7M_EXCP_RESET].prio != -3 || + resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3; + + if (s->vectors[ARMV7M_EXCP_RESET].prio != resetprio || s->vectors[ARMV7M_EXCP_NMI].prio != -2 || s->vectors[ARMV7M_EXCP_HARD].prio != -1) { return 1; @@ -1497,7 +1506,12 @@ static int nvic_security_post_load(void *opaque, int version_id) int i; /* Check for out of range priority settings */ - if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1) { + if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1 + && s->sec_vectors[ARMV7M_EXCP_HARD].prio != -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 = ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) { @@ -1544,6 +1558,7 @@ static Property props_nvic[] = { static void armv7m_nvic_reset(DeviceState *dev) { + int resetprio; NVICState *s = NVIC(dev); s->vectors[ARMV7M_EXCP_NMI].enabled = 1; @@ -1556,7 +1571,8 @@ static void armv7m_nvic_reset(DeviceState *dev) s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1; s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1; - s->vectors[ARMV7M_EXCP_RESET].prio = -3; + resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3; + s->vectors[ARMV7M_EXCP_RESET].prio = resetprio; s->vectors[ARMV7M_EXCP_NMI].prio = -2; s->vectors[ARMV7M_EXCP_HARD].prio = -1; From patchwork Tue Sep 12 18:14:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112361 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549066qgf; Tue, 12 Sep 2017 11:13:49 -0700 (PDT) X-Google-Smtp-Source: AOwi7QDGJKf19sfDMVeOC+BngeRSK63AsCgsrSTfLIFyLRSAOyyeS/PiLDRnRPinzYb11l2Dkdhs X-Received: by 10.28.137.208 with SMTP id l199mr302786wmd.123.1505240029588; Tue, 12 Sep 2017 11:13:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240029; cv=none; d=google.com; s=arc-20160816; b=RUNTqBJnVKcCN4ee+NYYVJzyWilE3UYgyuOCZeSERIkDq/BqJ9Ax4Tyg5iTmrNwzMr cvlznPw9rmc4f9vZdlVTa6hPLNZ9qEjzD20frAq7IC6f+ZIM+zqlQ7ZCbuSa/0Byo7Nw gseLQUVAYMz5MH10+VS8hLL93toZ4ETFzdBDizLACClvAb5SM3d5SAQs40zVBAitLLp1 vRzRdFKT4BA///XbMYOthpNEIuPhmOPU5anvOhjQHkPIb1pGynBocoyvKVxYZhtM254N GjdO9qA6hOs5OntaqYw6AJAiQA552GW+cff4gTeX+MqYMCrl8Hn+g5nRH3W09DQD84dk Nuhw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=1HELrp4XudSVWHWja2ay6iZ9jVuM5OnXb4hNo6vMgOI=; b=ness1FsansuHMO6RwPFgsG8rvFek4UcA8rQhm6KXJ5XcLaNSA/8ygBNPWaxUnD9Apu Z0x47hb+Ul4pM79lTUpoCRSd30sthHBWRUcYNmuq5kqzx2oJ+a8tz2aJZkiDQ64RSsCf Nk3Q5mAgtrlJDzYSj6RvfJV6BS1Dr+c90E7RCKiCtzCoY/uyzvbLGWQ0K/+cAcwLwNzX QhTRh7KAKFGIhVO24UnE87/IrazA8bC1mRF8x9sY7uzhXouIRyFQclPsLqd+J8zMQmXH dIV9xRvzNj6fQzy0nvmJ/QVLh61TZc6VJHgrIJjt66LVpCV3SJerRfMNw4clL+/NxON5 zxfQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id z80si513276wmd.264.2017.09.12.11.13.49 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 14/19] nvic: Disable the non-secure HardFault if AIRCR.BFHFNMINS is clear 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> 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 --- hw/intc/armv7m_nvic.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 = -3; + s->vectors[ARMV7M_EXCP_HARD].enabled = 1; } else { s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1; + s->vectors[ARMV7M_EXCP_HARD].enabled = 0; } } nvic_irq_update(s); @@ -1562,7 +1567,6 @@ static void armv7m_nvic_reset(DeviceState *dev) NVICState *s = NVIC(dev); s->vectors[ARMV7M_EXCP_NMI].enabled = 1; - s->vectors[ARMV7M_EXCP_HARD].enabled = 1; /* MEM, BUS, and USAGE are enabled through * the System Handler Control register */ @@ -1584,6 +1588,10 @@ static void armv7m_nvic_reset(DeviceState *dev) /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */ s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1; + /* If AIRCR.BFHFNMINS is 0 then NS HF is (effectively) disabled */ + s->vectors[ARMV7M_EXCP_HARD].enabled = 0; + } else { + s->vectors[ARMV7M_EXCP_HARD].enabled = 1; } /* Strictly speaking the reset handler should be enabled. From patchwork Tue Sep 12 18:14:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112362 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549082qgf; Tue, 12 Sep 2017 11:13:50 -0700 (PDT) X-Google-Smtp-Source: AOwi7QAazoH1EGmNbL/OURZdQ29IPkhVBDCRCVG8Iy+UHAPY7CoN94Jdn3EZbKrYthnVIfV5Yf9l X-Received: by 10.28.238.73 with SMTP id m70mr323235wmh.112.1505240030364; Tue, 12 Sep 2017 11:13:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240030; cv=none; d=google.com; s=arc-20160816; b=HG2PXhrjZdmR5R+wJ07FlvpoT/jtcPPURgFHhXZblueKqiuVttA0ULYP4VPK1xY0TN 6IGAVYt5uz+lyVSotxS/9kin4TXXh7vbzMqjPWYGdpIm6uzvjPVw86I3WPU+bDLG7Y7e SEnIJ/SnQz6kOJ34ohSXavky2c1P0LLv1H0/RYBtT3QfNAUDF/LBUMra9FvoHiRu+8QA IsIv5gZyH/loXvWLcqaWnXDAYPJwwdTKd2aYyIAVgwPSnfDlWqOWqsnSR4TuBRJRZcP1 0V1BolNZ6NcJWYefRXS4gSnUCKzLJBp6bCgPZKf4BsdglBWEPpwqYGadt8CvWOaxfuQo LPZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=CWTZ9IjpiVNvRzH5AMM1MnhqcHS+7K9fqJGB01gIA7w=; b=BJuetU/8U9gR7wkSItNgEQ0lf9H1Ump4HafAloaSqQxrVb5khb4hyL8e2Pm9gnx1Be WKmxyno3PO1wDIc11aMwIiENbFH1tixu8/M40UdlrUeTZwBZToLtYHQrHQCrzbQg6aGk 4cx3WhzQ0T1PGPb4L8DHopOvZzryPxlfFQ3SO28CswJylpgYTwenwhxmOVd0FbXRFcNf boPBrGJ4KIEsb6+fRhs1H+mYXoIWaI4GikI4NBHT9OxWHiOXwZ4onGUeTXcF8feXjxVv ipjAYuz0s16kGnhEIbrm3TYiUq7c+eq23VMZFG3fmxgWZqBuRW5OdKhXgw+A+t8fVfjl NSHQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id i131si9406443wmd.100.2017.09.12.11.13.50 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 15/19] nvic: Handle v8M changes in nvic_exec_prio() 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> 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 --- hw/intc/armv7m_nvic.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 = &s->cpu->env; - int running; + int running = NVIC_NOEXC_PRIO; - if (env->v7m.faultmask[env->v7m.secure]) { - running = -1; - } else if (env->v7m.primask[env->v7m.secure]) { + if (env->v7m.basepri[M_REG_NS] > 0) { + running = exc_group_prio(s, env->v7m.basepri[M_REG_NS], M_REG_NS); + } + + if (env->v7m.basepri[M_REG_S] > 0) { + int basepri = exc_group_prio(s, env->v7m.basepri[M_REG_S], M_REG_S); + if (running > basepri) { + running = basepri; + } + } + + if (env->v7m.primask[M_REG_NS]) { + if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) { + if (running > NVIC_NS_PRIO_LIMIT) { + running = NVIC_NS_PRIO_LIMIT; + } + } else { + running = 0; + } + } + + if (env->v7m.primask[M_REG_S]) { running = 0; - } else if (env->v7m.basepri[env->v7m.secure] > 0) { - running = env->v7m.basepri[env->v7m.secure] & - nvic_gprio_mask(s, env->v7m.secure); - } else { - running = 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 = -1; + } else { + if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) { + if (running > NVIC_NS_PRIO_LIMIT) { + running = NVIC_NS_PRIO_LIMIT; + } + } else { + running = 0; + } + } + } + + if (env->v7m.faultmask[M_REG_S]) { + running = (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) ? -3 : -1; + } + /* consider priority of active handler */ return MIN(running, s->exception_prio); } From patchwork Tue Sep 12 18:14:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112363 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549093qgf; Tue, 12 Sep 2017 11:13:51 -0700 (PDT) X-Google-Smtp-Source: ADKCNb70rWsjDwx0WIUWdf7/NleUYwgX/7GPJFzXCCoMdK+EQpqZEVAcwqr7t29Ac5aGixqpAgst X-Received: by 10.223.171.21 with SMTP id q21mr13003325wrc.125.1505240030973; Tue, 12 Sep 2017 11:13:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240030; cv=none; d=google.com; s=arc-20160816; b=PBzWov9Db9Wd5BlLbPMeHkE8hu0c50KcWTFrCT2gq02QAcB2JaAW8IQL515cupp53g ygjIkNfxM3vZHXfUyp+R/t1Qnb6lON16tHfnf+yW+SDbTmWbqs+7KWnobck5+ZWFhp+y cDA07sH8nH6MhmKo914A3dNKC6GluaRrGNhJLdQMS1C0Cvuqri1jpoqz8dnNm+jgXulY L8hXy4rVybcCQkGa/gWtk91ZqzUEs79zUQhNCJ0l6OS348gH2tfab8qqmkDAqHNhE+Tw c8z10WEqgODpx5/u8RIlHy1m+RVHTc0rkXKcXMxMQWiiWa1kLFYZRAG2hkRZbzAWRVjL wh+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=KZ8pI30d7RlPgjW/BmNZTegucgHmwQZlWm+4BUcmTI0=; b=SvZHqnt7WRdi+Qar/DvxzCgnAZyYx4Cbf/Evbc3Efd5FYJfVZSkxLDsuubR2kqXgi9 RkLhSiifUpMPrFaowXIgJhMNKfb4WTJfMpdkpCu+PfJKFP0irksoYLxYILMQxtt0HC1E jvZAciPxgv9llTcX4+ZgqvFqTwYpQwfcBJai0NZOg27ukNenJiuWdGNgp7ftCo9ZQp0H zUAtuh/uTArFX008gJQZ+oIfBwDkz969jY8ajC0fhv/egYbSSABHKH11C5wnLx4DSXJ9 zq2u/uzrMDEDdNhspK+VObtQfhs4xmMz/iQChc+TDQUxOiktbDY3bgjB3CZC6q+Lfw7G YZDw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id s22si4221417wra.348.2017.09.12.11.13.50 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 16/19] target/arm: Handle banking in negative-execution-priority check in cpu_mmu_index() 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> 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 --- target/arm/cpu.h | 21 ++++++++++++++++----- hw/intc/armv7m_nvic.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 secure) +{ + return false; +} +#endif /* 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, bool ifetch) if (arm_feature(env, ARM_FEATURE_M)) { ARMMMUIdx mmu_idx = el == 0 ? ARMMMUIdx_MUser : ARMMMUIdx_MPriv; - /* 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 <= 3) - || env->v7m.faultmask[env->v7m.secure]) { + if (armv7m_nvic_neg_prio_requested(env->nvic, env->v7m.secure)) { mmu_idx = ARMMMUIdx_MNegPri; } 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); } +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 = 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) == secure) { + return true; + } + + return false; +} + bool armv7m_nvic_can_take_pending_exception(void *opaque) { NVICState *s = opaque; From patchwork Tue Sep 12 18:14:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112364 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549108qgf; Tue, 12 Sep 2017 11:13:51 -0700 (PDT) X-Google-Smtp-Source: AOwi7QDxLKHCSqvBMksMhltAAqqABo+CnX8S/Z5IWLfQ4BdlqfjArjuqm4S8L0Ht9V7vL/0LQLLu X-Received: by 10.28.52.132 with SMTP id b126mr338325wma.144.1505240031860; Tue, 12 Sep 2017 11:13:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240031; cv=none; d=google.com; s=arc-20160816; b=OPssCJkXSlqsT75lPl4fQgE9s0+cP7Of8wxQ9Kh9cn5/39Xij1dT3Oy56llBxoyMHT b65SaMzeLXorWIkZHfC/Pwxs5ipSxsAUFEuAup6zQOn1QLyAKbSvS/8jY5haN6e67dS9 1KcclKyIig2Z1EeSBGEOLxnA4Ki6Y615qv06s+ynYRTcXcT0xxkn73n38GzxkX7H7CgF IcGL2x1bQfG9rMkb7LRRzS9k5v69U/J6g5svPLkI9+0UF2+F4Obxt0j9mA13LZdg/4wX gg13gKfVvDBVjhByIalA6DSxoB9HqnwlZz9rLDS94+LpVMGQNqtMJ3+qKT2aGTbVn0zS ACCg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=01dh5BWCFYErQ39khmrp+Y96B3+LsFoIqLF8Q0CFSD0=; b=awjPw+6GDotZ0FE8/bdFgnpAWDaG3Xm66rW0DJy1zYILLwuaLnnBOAVVrKQYLa6f21 NmHk/3laFZ2UbpFqWDDjdcQIHidz2nEBwCWmOGlz/JetAqXYeWbiQssSbb/SF312+F8C G/jlgjUqSFgTDU/st8pd1paBCtMgMNC3UtFkGPDQisi2SUbJOUZ+l5P5WcEf1YMsCjfX Qm9zXGBlKFmrQ/kdKm2LCVl5s2BXvLDjqdOwUv13YZ4VEV1YdbK6DzjwB/02NEHAe3O0 CbZDsTxmt45WpAKnVJZE4ulBIeIy0BegLOnChrN+LjZmS37Jcnhja+uUST7yZ344SRSr r+zA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id q30si9352383wra.109.2017.09.12.11.13.51 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:51 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 17/19] nvic: Make ICSR banked for v8M 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> 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 --- hw/intc/armv7m_nvic.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 offset, MemTxAttrs attrs) } case 0xd00: /* CPUID Base. */ return cpu->midr; - case 0xd04: /* Interrupt Control State. */ + case 0xd04: /* Interrupt Control State (ICSR) */ /* VECTACTIVE */ val = cpu->env.v7m.exception; /* VECTPENDING */ @@ -716,19 +716,32 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (nvic_rettobase(s)) { val |= (1 << 11); } - /* PENDSTSET */ - if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) { - val |= (1 << 26); - } - /* PENDSVSET */ - if (s->vectors[ARMV7M_EXCP_PENDSV].pending) { - val |= (1 << 28); + if (attrs.secure) { + /* PENDSTSET */ + if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].pending) { + val |= (1 << 26); + } + /* PENDSVSET */ + if (s->sec_vectors[ARMV7M_EXCP_PENDSV].pending) { + val |= (1 << 28); + } + } else { + /* PENDSTSET */ + if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) { + val |= (1 << 26); + } + /* PENDSVSET */ + if (s->vectors[ARMV7M_EXCP_PENDSV].pending) { + val |= (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 |= (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); From patchwork Tue Sep 12 18:14:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112366 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549122qgf; Tue, 12 Sep 2017 11:13:52 -0700 (PDT) X-Google-Smtp-Source: AOwi7QDnyWYFyfPW1z4rs5Sirc9xqfpwBmx3qLjaBC0Dsze2js479SFsCh0rPTHO4bb3qlHTFkK4 X-Received: by 10.28.211.78 with SMTP id k75mr375061wmg.94.1505240032529; Tue, 12 Sep 2017 11:13:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240032; cv=none; d=google.com; s=arc-20160816; b=Ya9qulrCVFy8QPM+IHDzArpl6auSlx/wHRdp0/sm6XRfkv20tmNygJJydAj04tniNO EVx4ia1cS0dT/k3cl33twgkClIXQQ/4pxV9En6a4F8VXsePO2Q4TY5DAuouIu0IAkYOH xv7UGNl8Eg21Gqc9Pci0+jkIEBbcvMcimQjbJd3/xL3U1YWxOL2TKisodDWzTOhcH/AY cG4aWNnQa2hUlS2USZzscbLkv/2gwaVdxJJfJ0JBFqNtJ8z2hkVNmnqXT8GE1itI8Wrf tm/dVoACS6tBds4L4p1AhD5jXSSB32ppfU70v17Jqn/RY2jqIbfjybw5p9scQzydWVGT Z9bA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=nTbDyN9N2Yh0NEpf4+ZjdVOMY5X1S+o/w/lviJGfRoo=; b=md5z+UuiESsDGOKCa6+2Z8q1jtAa1sPOFLKEEY8P2Rq65NRkmlyidgtaXokothpvku O3aqIPs2SsM3PTKe4Jh2pYey7rZdoJE/rzGMaw6HwQicmkOxjFb7lw5pATqIZgdN+7AI btZuPupJTra1pQcjmRxbGuXPYSDq8JtnIxW1Icb/f+FPmFDQwkAoTOX4OMChgA8/9dln WVhzy0JKjEubWWhAVQ9VpMhWhU5pbaZCEPO6V05JgjxffuegrPMTXbxAa2Yfw/DvyWlq oZVwKwUYzv6jnP81Hna09lGgVU7kD3edxLGXnz92bDHg7BqIGHEeax41xPYsn0dHqZQo q6bA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id k52si9685459wrf.83.2017.09.12.11.13.52 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:52 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 18/19] nvic: Make SHCSR banked for v8M 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> 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 --- hw/intc/armv7m_nvic.c | 221 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 169 insertions(+), 52 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson 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 offset, MemTxAttrs attrs) val = cpu->env.v7m.ccr[attrs.secure]; val |= 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 = 0; - if (s->vectors[ARMV7M_EXCP_MEM].active) { - val |= (1 << 0); - } - if (s->vectors[ARMV7M_EXCP_BUS].active) { - val |= (1 << 1); - } - if (s->vectors[ARMV7M_EXCP_USAGE].active) { - val |= (1 << 3); + if (attrs.secure) { + if (s->sec_vectors[ARMV7M_EXCP_MEM].active) { + val |= (1 << 0); + } + if (s->sec_vectors[ARMV7M_EXCP_HARD].active) { + val |= (1 << 2); + } + if (s->sec_vectors[ARMV7M_EXCP_USAGE].active) { + val |= (1 << 3); + } + if (s->sec_vectors[ARMV7M_EXCP_SVC].active) { + val |= (1 << 7); + } + if (s->sec_vectors[ARMV7M_EXCP_PENDSV].active) { + val |= (1 << 10); + } + if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].active) { + val |= (1 << 11); + } + if (s->sec_vectors[ARMV7M_EXCP_USAGE].pending) { + val |= (1 << 12); + } + if (s->sec_vectors[ARMV7M_EXCP_MEM].pending) { + val |= (1 << 13); + } + if (s->sec_vectors[ARMV7M_EXCP_SVC].pending) { + val |= (1 << 15); + } + if (s->sec_vectors[ARMV7M_EXCP_MEM].enabled) { + val |= (1 << 16); + } + if (s->sec_vectors[ARMV7M_EXCP_USAGE].enabled) { + val |= (1 << 18); + } + if (s->sec_vectors[ARMV7M_EXCP_HARD].pending) { + val |= (1 << 21); + } + /* SecureFault is not banked but is always RAZ/WI to NS */ + if (s->vectors[ARMV7M_EXCP_SECURE].active) { + val |= (1 << 4); + } + if (s->vectors[ARMV7M_EXCP_SECURE].enabled) { + val |= (1 << 19); + } + if (s->vectors[ARMV7M_EXCP_SECURE].pending) { + val |= (1 << 20); + } + } else { + if (s->vectors[ARMV7M_EXCP_MEM].active) { + val |= (1 << 0); + } + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* HARDFAULTACT, HARDFAULTPENDED not present in v7M */ + if (s->vectors[ARMV7M_EXCP_HARD].active) { + val |= (1 << 2); + } + if (s->vectors[ARMV7M_EXCP_HARD].pending) { + val |= (1 << 21); + } + } + if (s->vectors[ARMV7M_EXCP_USAGE].active) { + val |= (1 << 3); + } + if (s->vectors[ARMV7M_EXCP_SVC].active) { + val |= (1 << 7); + } + if (s->vectors[ARMV7M_EXCP_PENDSV].active) { + val |= (1 << 10); + } + if (s->vectors[ARMV7M_EXCP_SYSTICK].active) { + val |= (1 << 11); + } + if (s->vectors[ARMV7M_EXCP_USAGE].pending) { + val |= (1 << 12); + } + if (s->vectors[ARMV7M_EXCP_MEM].pending) { + val |= (1 << 13); + } + if (s->vectors[ARMV7M_EXCP_SVC].pending) { + val |= (1 << 15); + } + if (s->vectors[ARMV7M_EXCP_MEM].enabled) { + val |= (1 << 16); + } + if (s->vectors[ARMV7M_EXCP_USAGE].enabled) { + val |= (1 << 18); + } } - if (s->vectors[ARMV7M_EXCP_SVC].active) { - val |= (1 << 7); + if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { + if (s->vectors[ARMV7M_EXCP_BUS].active) { + val |= (1 << 1); + } + if (s->vectors[ARMV7M_EXCP_BUS].pending) { + val |= (1 << 14); + } + if (s->vectors[ARMV7M_EXCP_BUS].enabled) { + val |= (1 << 17); + } + if (arm_feature(&cpu->env, ARM_FEATURE_V8) && + s->vectors[ARMV7M_EXCP_NMI].active) { + /* NMIACT is not present in v7M */ + val |= (1 << 5); + } } + + /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */ if (s->vectors[ARMV7M_EXCP_DEBUG].active) { val |= (1 << 8); } - if (s->vectors[ARMV7M_EXCP_PENDSV].active) { - val |= (1 << 10); - } - if (s->vectors[ARMV7M_EXCP_SYSTICK].active) { - val |= (1 << 11); - } - if (s->vectors[ARMV7M_EXCP_USAGE].pending) { - val |= (1 << 12); - } - if (s->vectors[ARMV7M_EXCP_MEM].pending) { - val |= (1 << 13); - } - if (s->vectors[ARMV7M_EXCP_BUS].pending) { - val |= (1 << 14); - } - if (s->vectors[ARMV7M_EXCP_SVC].pending) { - val |= (1 << 15); - } - if (s->vectors[ARMV7M_EXCP_MEM].enabled) { - val |= (1 << 16); - } - if (s->vectors[ARMV7M_EXCP_BUS].enabled) { - val |= (1 << 17); - } - if (s->vectors[ARMV7M_EXCP_USAGE].enabled) { - val |= (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 offset, uint32_t value, cpu->env.v7m.ccr[attrs.secure] = value; break; - case 0xd24: /* System Handler Control. */ - s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0; - s->vectors[ARMV7M_EXCP_BUS].active = (value & (1 << 1)) != 0; - s->vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0; - s->vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0; + case 0xd24: /* System Handler Control and State (SHCSR) */ + if (attrs.secure) { + s->sec_vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0; + /* Secure HardFault active bit cannot be written */ + s->sec_vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0; + s->sec_vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0; + s->sec_vectors[ARMV7M_EXCP_PENDSV].active = + (value & (1 << 10)) != 0; + s->sec_vectors[ARMV7M_EXCP_SYSTICK].active = + (value & (1 << 11)) != 0; + s->sec_vectors[ARMV7M_EXCP_USAGE].pending = + (value & (1 << 12)) != 0; + s->sec_vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0; + s->sec_vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0; + s->sec_vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0; + s->sec_vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0; + s->sec_vectors[ARMV7M_EXCP_USAGE].enabled = + (value & (1 << 18)) != 0; + /* SecureFault not banked, but RAZ/WI to NS */ + s->vectors[ARMV7M_EXCP_SECURE].active = (value & (1 << 4)) != 0; + s->vectors[ARMV7M_EXCP_SECURE].enabled = (value & (1 << 19)) != 0; + s->vectors[ARMV7M_EXCP_SECURE].pending = (value & (1 << 20)) != 0; + } else { + s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0; + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* HARDFAULTPENDED is not present in v7M */ + s->vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0; + } + s->vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0; + s->vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0; + s->vectors[ARMV7M_EXCP_PENDSV].active = (value & (1 << 10)) != 0; + s->vectors[ARMV7M_EXCP_SYSTICK].active = (value & (1 << 11)) != 0; + s->vectors[ARMV7M_EXCP_USAGE].pending = (value & (1 << 12)) != 0; + s->vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0; + s->vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0; + s->vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0; + s->vectors[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0; + } + if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { + s->vectors[ARMV7M_EXCP_BUS].active = (value & (1 << 1)) != 0; + s->vectors[ARMV7M_EXCP_BUS].pending = (value & (1 << 14)) != 0; + s->vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 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)) == 0) { + s->vectors[ARMV7M_EXCP_NMI].active = 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)) == 0) { + s->vectors[ARMV7M_EXCP_HARD].active = 0; + } + + /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */ s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0; - s->vectors[ARMV7M_EXCP_PENDSV].active = (value & (1 << 10)) != 0; - s->vectors[ARMV7M_EXCP_SYSTICK].active = (value & (1 << 11)) != 0; - s->vectors[ARMV7M_EXCP_USAGE].pending = (value & (1 << 12)) != 0; - s->vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0; - s->vectors[ARMV7M_EXCP_BUS].pending = (value & (1 << 14)) != 0; - s->vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0; - s->vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0; - s->vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0; - s->vectors[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0; nvic_irq_update(s); break; case 0xd28: /* Configurable Fault Status. */ From patchwork Tue Sep 12 18:14:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112365 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5549144qgf; Tue, 12 Sep 2017 11:13:53 -0700 (PDT) X-Google-Smtp-Source: AOwi7QDeasdY2vFlIyDohfOtex6huBwBkVpbMCNrkLolGJuEGfxUnWxLei5d8WwP2mihkWw0k3eb X-Received: by 10.28.128.19 with SMTP id b19mr336310wmd.136.1505240033177; Tue, 12 Sep 2017 11:13:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240033; cv=none; d=google.com; s=arc-20160816; b=GCZKyyInc0wlnuNDhY1dEnmfCvYgFn1TQehBbkFownpJh8uOXAqXXB7VaidQYHX/uC tocGZOxm0VFO1r0wq/FihzVa+j63e2GxeI8gdIakWaZ+ysCfosSxQvjgeWPKp72VdDc2 LTz4wo2vTBfaCZgpu7cIOl7Tss4PcLww5nE6zJV52CwK8VXLWUlRtUMAqLH6fyqBCgJN E7c+R9Bs65qn0UzTep7PfixJ+XqKpmF/Pc96kmNwXAns7q4s2tuhwwwN+dtuL+CMLyC4 ek6i/BY2R20DHuCKHdIlJ2g43znLdhq1jDZR4mAAN/5aVUiFtL96Ljhsm34Pxd3IeZqN B8BA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=RKpSyzQZdHXWVgtdJGt8eOQ5grI4KKp31zubjUL7bZc=; b=L66YSWOQz8bbGOZa7ODUhSMdbdhzDwO1gSz2o05XKxq7wg/HYn88pI+hz4sTxTt5r+ X+B/x5L7j7kR1VvNG71M6Nh5jSuwpbkxjM0fzdEdfH3NY+e3ciFACkQPGffDr67q4mPS mtCQiq3WCdph83FbLtmFiU6g/3ixwk06Zxc3+1k4Mq1h2FmYkc6YMMIJo/u+a8zSmuS0 eG5zFze18ShZW7/E/xFOUiQbimnWPGllU8YpR70RFEwuDL5TNVOv5jhc1PrbWJ6RtlKj MZSkNa45h/QqGBnJtwY0pZhbNkwWIBKxl3SevaHFfyElvLZ7bXDFE6pT+j+wqyFjpWuO S4Ug== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 62si9414123wmb.162.2017.09.12.11.13.52 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org 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 Cc: patches@linaro.org Subject: [PATCH 19/19] nvic: Support banked exceptions in acknowledge and complete 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> 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 --- 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(-) -- 2.7.4 Reviewed-by: Richard Henderson 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_exception(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 active + * @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 irqs) * 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, bool secure) } /* Make pending IRQ active. */ -void armv7m_nvic_acknowledge_irq(void *opaque) +bool armv7m_nvic_acknowledge_irq(void *opaque) { NVICState *s = (NVICState *)opaque; CPUARMState *env = &s->cpu->env; const int pending = s->vectpending; const int running = nvic_exec_prio(s); VecInfo *vec; + bool targets_secure; assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); - vec = &s->vectors[pending]; + if (s->vectpending_is_s_banked) { + vec = &s->sec_vectors[pending]; + targets_secure = true; + } else { + vec = &s->vectors[pending]; + targets_secure = !exc_is_banked(s->vectpending) && + exc_targets_secure(s, s->vectpending); + } assert(vec->enabled); assert(vec->pending); assert(s->vectpending_prio < running); - trace_nvic_acknowledge_irq(pending, s->vectpending_prio); + trace_nvic_acknowledge_irq(pending, s->vectpending_prio, targets_secure); vec->active = 1; vec->pending = 0; @@ -611,9 +619,11 @@ void armv7m_nvic_acknowledge_irq(void *opaque) env->v7m.exception = s->vectpending; nvic_irq_update(s); + + return targets_secure; } -int armv7m_nvic_complete_irq(void *opaque, int irq) +int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure) { NVICState *s = (NVICState *)opaque; VecInfo *vec; @@ -621,9 +631,13 @@ int armv7m_nvic_complete_irq(void *opaque, int irq) assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); - vec = &s->vectors[irq]; + if (secure && exc_is_banked(irq)) { + vec = &s->sec_vectors[irq]; + } else { + vec = &s->vectors[irq]; + } - trace_nvic_complete_irq(irq); + trace_nvic_complete_irq(irq, secure); 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 = false; bool return_to_handler = false; bool rettobase = false; + bool exc_secure = false; /* 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 = excret & R_V7M_EXCRET_ES_MASK; + exc_secure = excret & R_V7M_EXCRET_ES_MASK; if (armv7m_nvic_raw_execution_priority(env->nvic) >= 0) { - env->v7m.faultmask[es] = 0; + env->v7m.faultmask[exc_secure] = 0; } } else { env->v7m.faultmask[M_REG_NS] = 0; } } - 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 = 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 pending 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 active (prio %d)" -nvic_complete_irq(int irq) "NVIC complete IRQ %d" +nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge 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 sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"