From nobody Tue Nov 4 06:39:53 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505240808930165.59765332952304; Tue, 12 Sep 2017 11:26:48 -0700 (PDT) Received: from localhost ([::1]:38015 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drptY-0007Uz-6k for importer@patchew.org; Tue, 12 Sep 2017 14:26:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43658) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drph9-0003ba-H0 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:14:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drph7-0006WS-Ky for qemu-devel@nongnu.org; Tue, 12 Sep 2017 14:13:59 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37328) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1drph2-0006SF-SW; Tue, 12 Sep 2017 14:13:53 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1drph1-0001B2-S7; Tue, 12 Sep 2017 19:13:51 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 12 Sep 2017 19:14:05 +0100 Message-Id: <1505240046-11454-19-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 18/19] nvic: Make SHCSR banked for v8M X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: patches@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Handle banking of SHCSR: some register bits are banked between Secure and Non-Secure, and some are only accessible to Secure. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- hw/intc/armv7m_nvic.c | 221 ++++++++++++++++++++++++++++++++++++++--------= ---- 1 file changed, 169 insertions(+), 52 deletions(-) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 21fd199..9613990 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -770,50 +770,117 @@ static uint32_t nvic_readl(NVICState *s, uint32_t of= fset, MemTxAttrs attrs) val =3D cpu->env.v7m.ccr[attrs.secure]; val |=3D cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK; return val; - case 0xd24: /* System Handler Status. */ + case 0xd24: /* System Handler Control and State (SHCSR) */ val =3D 0; - if (s->vectors[ARMV7M_EXCP_MEM].active) { - val |=3D (1 << 0); - } - if (s->vectors[ARMV7M_EXCP_BUS].active) { - val |=3D (1 << 1); - } - if (s->vectors[ARMV7M_EXCP_USAGE].active) { - val |=3D (1 << 3); + if (attrs.secure) { + if (s->sec_vectors[ARMV7M_EXCP_MEM].active) { + val |=3D (1 << 0); + } + if (s->sec_vectors[ARMV7M_EXCP_HARD].active) { + val |=3D (1 << 2); + } + if (s->sec_vectors[ARMV7M_EXCP_USAGE].active) { + val |=3D (1 << 3); + } + if (s->sec_vectors[ARMV7M_EXCP_SVC].active) { + val |=3D (1 << 7); + } + if (s->sec_vectors[ARMV7M_EXCP_PENDSV].active) { + val |=3D (1 << 10); + } + if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].active) { + val |=3D (1 << 11); + } + if (s->sec_vectors[ARMV7M_EXCP_USAGE].pending) { + val |=3D (1 << 12); + } + if (s->sec_vectors[ARMV7M_EXCP_MEM].pending) { + val |=3D (1 << 13); + } + if (s->sec_vectors[ARMV7M_EXCP_SVC].pending) { + val |=3D (1 << 15); + } + if (s->sec_vectors[ARMV7M_EXCP_MEM].enabled) { + val |=3D (1 << 16); + } + if (s->sec_vectors[ARMV7M_EXCP_USAGE].enabled) { + val |=3D (1 << 18); + } + if (s->sec_vectors[ARMV7M_EXCP_HARD].pending) { + val |=3D (1 << 21); + } + /* SecureFault is not banked but is always RAZ/WI to NS */ + if (s->vectors[ARMV7M_EXCP_SECURE].active) { + val |=3D (1 << 4); + } + if (s->vectors[ARMV7M_EXCP_SECURE].enabled) { + val |=3D (1 << 19); + } + if (s->vectors[ARMV7M_EXCP_SECURE].pending) { + val |=3D (1 << 20); + } + } else { + if (s->vectors[ARMV7M_EXCP_MEM].active) { + val |=3D (1 << 0); + } + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* HARDFAULTACT, HARDFAULTPENDED not present in v7M */ + if (s->vectors[ARMV7M_EXCP_HARD].active) { + val |=3D (1 << 2); + } + if (s->vectors[ARMV7M_EXCP_HARD].pending) { + val |=3D (1 << 21); + } + } + if (s->vectors[ARMV7M_EXCP_USAGE].active) { + val |=3D (1 << 3); + } + if (s->vectors[ARMV7M_EXCP_SVC].active) { + val |=3D (1 << 7); + } + if (s->vectors[ARMV7M_EXCP_PENDSV].active) { + val |=3D (1 << 10); + } + if (s->vectors[ARMV7M_EXCP_SYSTICK].active) { + val |=3D (1 << 11); + } + if (s->vectors[ARMV7M_EXCP_USAGE].pending) { + val |=3D (1 << 12); + } + if (s->vectors[ARMV7M_EXCP_MEM].pending) { + val |=3D (1 << 13); + } + if (s->vectors[ARMV7M_EXCP_SVC].pending) { + val |=3D (1 << 15); + } + if (s->vectors[ARMV7M_EXCP_MEM].enabled) { + val |=3D (1 << 16); + } + if (s->vectors[ARMV7M_EXCP_USAGE].enabled) { + val |=3D (1 << 18); + } } - if (s->vectors[ARMV7M_EXCP_SVC].active) { - val |=3D (1 << 7); + if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MA= SK)) { + if (s->vectors[ARMV7M_EXCP_BUS].active) { + val |=3D (1 << 1); + } + if (s->vectors[ARMV7M_EXCP_BUS].pending) { + val |=3D (1 << 14); + } + if (s->vectors[ARMV7M_EXCP_BUS].enabled) { + val |=3D (1 << 17); + } + if (arm_feature(&cpu->env, ARM_FEATURE_V8) && + s->vectors[ARMV7M_EXCP_NMI].active) { + /* NMIACT is not present in v7M */ + val |=3D (1 << 5); + } } + + /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */ if (s->vectors[ARMV7M_EXCP_DEBUG].active) { val |=3D (1 << 8); } - if (s->vectors[ARMV7M_EXCP_PENDSV].active) { - val |=3D (1 << 10); - } - if (s->vectors[ARMV7M_EXCP_SYSTICK].active) { - val |=3D (1 << 11); - } - if (s->vectors[ARMV7M_EXCP_USAGE].pending) { - val |=3D (1 << 12); - } - if (s->vectors[ARMV7M_EXCP_MEM].pending) { - val |=3D (1 << 13); - } - if (s->vectors[ARMV7M_EXCP_BUS].pending) { - val |=3D (1 << 14); - } - if (s->vectors[ARMV7M_EXCP_SVC].pending) { - val |=3D (1 << 15); - } - if (s->vectors[ARMV7M_EXCP_MEM].enabled) { - val |=3D (1 << 16); - } - if (s->vectors[ARMV7M_EXCP_BUS].enabled) { - val |=3D (1 << 17); - } - if (s->vectors[ARMV7M_EXCP_USAGE].enabled) { - val |=3D (1 << 18); - } return val; case 0xd28: /* Configurable Fault Status. */ /* The BFSR bits [15:8] are shared between security states @@ -1061,21 +1128,71 @@ static void nvic_writel(NVICState *s, uint32_t offs= et, uint32_t value, =20 cpu->env.v7m.ccr[attrs.secure] =3D value; break; - case 0xd24: /* System Handler Control. */ - s->vectors[ARMV7M_EXCP_MEM].active =3D (value & (1 << 0)) !=3D 0; - s->vectors[ARMV7M_EXCP_BUS].active =3D (value & (1 << 1)) !=3D 0; - s->vectors[ARMV7M_EXCP_USAGE].active =3D (value & (1 << 3)) !=3D 0; - s->vectors[ARMV7M_EXCP_SVC].active =3D (value & (1 << 7)) !=3D 0; + case 0xd24: /* System Handler Control and State (SHCSR) */ + if (attrs.secure) { + s->sec_vectors[ARMV7M_EXCP_MEM].active =3D (value & (1 << 0)) = !=3D 0; + /* Secure HardFault active bit cannot be written */ + s->sec_vectors[ARMV7M_EXCP_USAGE].active =3D (value & (1 << 3)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_SVC].active =3D (value & (1 << 7)) = !=3D 0; + s->sec_vectors[ARMV7M_EXCP_PENDSV].active =3D + (value & (1 << 10)) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_SYSTICK].active =3D + (value & (1 << 11)) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_USAGE].pending =3D + (value & (1 << 12)) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_MEM].pending =3D (value & (1 << 13)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_SVC].pending =3D (value & (1 << 15)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_MEM].enabled =3D (value & (1 << 16)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_BUS].enabled =3D (value & (1 << 17)= ) !=3D 0; + s->sec_vectors[ARMV7M_EXCP_USAGE].enabled =3D + (value & (1 << 18)) !=3D 0; + /* SecureFault not banked, but RAZ/WI to NS */ + s->vectors[ARMV7M_EXCP_SECURE].active =3D (value & (1 << 4)) != =3D 0; + s->vectors[ARMV7M_EXCP_SECURE].enabled =3D (value & (1 << 19))= !=3D 0; + s->vectors[ARMV7M_EXCP_SECURE].pending =3D (value & (1 << 20))= !=3D 0; + } else { + s->vectors[ARMV7M_EXCP_MEM].active =3D (value & (1 << 0)) !=3D= 0; + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* HARDFAULTPENDED is not present in v7M */ + s->vectors[ARMV7M_EXCP_HARD].pending =3D (value & (1 << 21= )) !=3D 0; + } + s->vectors[ARMV7M_EXCP_USAGE].active =3D (value & (1 << 3)) != =3D 0; + s->vectors[ARMV7M_EXCP_SVC].active =3D (value & (1 << 7)) !=3D= 0; + s->vectors[ARMV7M_EXCP_PENDSV].active =3D (value & (1 << 10)) = !=3D 0; + s->vectors[ARMV7M_EXCP_SYSTICK].active =3D (value & (1 << 11))= !=3D 0; + s->vectors[ARMV7M_EXCP_USAGE].pending =3D (value & (1 << 12)) = !=3D 0; + s->vectors[ARMV7M_EXCP_MEM].pending =3D (value & (1 << 13)) != =3D 0; + s->vectors[ARMV7M_EXCP_SVC].pending =3D (value & (1 << 15)) != =3D 0; + s->vectors[ARMV7M_EXCP_MEM].enabled =3D (value & (1 << 16)) != =3D 0; + s->vectors[ARMV7M_EXCP_USAGE].enabled =3D (value & (1 << 18)) = !=3D 0; + } + if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MA= SK)) { + s->vectors[ARMV7M_EXCP_BUS].active =3D (value & (1 << 1)) !=3D= 0; + s->vectors[ARMV7M_EXCP_BUS].pending =3D (value & (1 << 14)) != =3D 0; + s->vectors[ARMV7M_EXCP_BUS].enabled =3D (value & (1 << 17)) != =3D 0; + } + /* NMIACT can only be written if the write is of a zero, with + * BFHFNMINS 1, and by the CPU in secure state via the NS alias. + */ + if (!attrs.secure && cpu->env.v7m.secure && + (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) && + (value & (1 << 5)) =3D=3D 0) { + s->vectors[ARMV7M_EXCP_NMI].active =3D 0; + } + /* HARDFAULTACT can only be written if the write is of a zero + * to the non-secure HardFault state by the CPU in secure state. + * The only case where we can be targeting the non-secure HF state + * when in secure state is if this is a write via the NS alias + * and BFHFNMINS is 1. + */ + if (!attrs.secure && cpu->env.v7m.secure && + (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) && + (value & (1 << 2)) =3D=3D 0) { + s->vectors[ARMV7M_EXCP_HARD].active =3D 0; + } + + /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */ s->vectors[ARMV7M_EXCP_DEBUG].active =3D (value & (1 << 8)) !=3D 0; - s->vectors[ARMV7M_EXCP_PENDSV].active =3D (value & (1 << 10)) !=3D= 0; - s->vectors[ARMV7M_EXCP_SYSTICK].active =3D (value & (1 << 11)) != =3D 0; - s->vectors[ARMV7M_EXCP_USAGE].pending =3D (value & (1 << 12)) !=3D= 0; - s->vectors[ARMV7M_EXCP_MEM].pending =3D (value & (1 << 13)) !=3D 0; - s->vectors[ARMV7M_EXCP_BUS].pending =3D (value & (1 << 14)) !=3D 0; - s->vectors[ARMV7M_EXCP_SVC].pending =3D (value & (1 << 15)) !=3D 0; - s->vectors[ARMV7M_EXCP_MEM].enabled =3D (value & (1 << 16)) !=3D 0; - s->vectors[ARMV7M_EXCP_BUS].enabled =3D (value & (1 << 17)) !=3D 0; - s->vectors[ARMV7M_EXCP_USAGE].enabled =3D (value & (1 << 18)) !=3D= 0; nvic_irq_update(s); break; case 0xd28: /* Configurable Fault Status. */ --=20 2.7.4