From patchwork Thu Sep 7 13:28:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 111918 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp93930qge; Thu, 7 Sep 2017 06:29:05 -0700 (PDT) X-Google-Smtp-Source: ADKCNb5YiQKAzdu9qHVC8ORZTHNDaVscCpAuTlA8VyP6Tl1+V8fn1QkY72k2CC1/H2uSPAcQ2S/v X-Received: by 10.55.92.7 with SMTP id q7mr3420210qkb.236.1504790945824; Thu, 07 Sep 2017 06:29:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504790945; cv=none; d=google.com; s=arc-20160816; b=JqckQRFtqkud9lvy/ISZXYUZy83AhtrILta0pFcnpvUUvMFiiD/5+GePeagwtkrAgz oyYQhKtEoQDW+HQ0yXP7cupFvzDHu3HIFmKXoZeksFHn8zgb2BHUvOyLpiid1eqVcu2R fJv/g/NMjF+02A5O5PKhbHaaxd7x4M0Jtlr+/jvebmm3d/8d6qmUpb8F2hHPhHFJGV5y 53Sjfm6CwnR0/aTNuyf+0lxaDAhaV5UMDsKCf0XOLy0z1laqII9IBpQR36WErfHBaPNZ SbVQTW07fAeNt6brtNGAGc2bx4wVibYVdPI8aYcfOM8DM30FUJx1TfMAqESHc9/xLYub zQ5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:arc-authentication-results; bh=3pFNWJlTC73f7TWvYKwdt0KrMuvUah0K3NzbWYuwiFI=; b=VzDFVJdr/FMEyQdVyblp1pbMsKUOov//oejmvn7oC/HYdJvIFz5KZZMd3V3iX4HaLV 4igtbLNF9F9g+frj29/iXhlz85jPhF7VOVYZ0x2wHQONYIJCZWubEFgvIGFNbIA5D9s6 +9an5onLX+faqQMqb2/0qEOlVypofqHcyNhzmbhWm9Ly/Q508eybeD383tA/vwqc6aXF tqXhnKfo8sFHX//XsKQM1VMzQHDK7S85c2oOdQX9q0F5ag8BHmW3dDjjYyv7xNhulFa+ BNW9sNnoOto1setLkrHD9oBeOTTMWChJqk9ZrZCDXP3sVXz/7z2je7ZlZrMroz85PzN+ +57w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id s2si2843825qti.449.2017.09.07.06.29.05 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 07 Sep 2017 06:29:05 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:40497 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpwrf-0001FB-JY for patch@linaro.org; Thu, 07 Sep 2017 09:29:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56494) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpwr6-00011k-Rf for qemu-devel@nongnu.org; Thu, 07 Sep 2017 09:28:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpwqy-0007ej-NZ for qemu-devel@nongnu.org; Thu, 07 Sep 2017 09:28:28 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37196) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dpwqy-0007dn-DX for qemu-devel@nongnu.org; Thu, 07 Sep 2017 09:28:20 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1dpwqx-0001ek-E9 for qemu-devel@nongnu.org; Thu, 07 Sep 2017 14:28:19 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 7 Sep 2017 14:28:16 +0100 Message-Id: <1504790904-17018-24-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1504790904-17018-1-git-send-email-peter.maydell@linaro.org> References: <1504790904-17018-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 23/31] target/arm: Make CCR register 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: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Make the CCR register banked if v8M security extensions are enabled. This is slightly more complicated than the other "add banking" patches because there is one bit in the register which is not banked. We keep the live data in the NS copy of the register, and adjust it on register reads and writes. (Since we don't currently implement the behaviour that the bit controls, there is nowhere else that needs to care.) This patch includes the enforcement of the bits which are newly RES1 in ARMv8M. Signed-off-by: Peter Maydell Message-id: 1503414539-28762-17-git-send-email-peter.maydell@linaro.org --- target/arm/cpu.h | 2 +- hw/intc/armv7m_nvic.c | 33 +++++++++++++++++++++++++++------ target/arm/cpu.c | 12 +++++++++--- target/arm/helper.c | 5 +++-- target/arm/machine.c | 3 ++- 5 files changed, 42 insertions(+), 13 deletions(-) -- 2.7.4 diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 29ffb26..d223446 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -423,7 +423,7 @@ typedef struct CPUARMState { uint32_t vecbase[2]; uint32_t basepri[2]; uint32_t control[2]; - uint32_t ccr; /* Configuration and Control */ + uint32_t ccr[2]; /* Configuration and Control */ uint32_t cfsr; /* Configurable Fault Status */ uint32_t hfsr; /* HardFault Status */ uint32_t dfsr; /* Debug Fault Status Register */ diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index a4c298f..a889397 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -448,7 +448,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) /* TODO: Implement SLEEPONEXIT. */ return 0; case 0xd14: /* Configuration Control. */ - return cpu->env.v7m.ccr; + /* The BFHFNMIGN bit is the only non-banked bit; we + * keep it in the non-secure copy of the register. + */ + 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. */ val = 0; if (s->vectors[ARMV7M_EXCP_MEM].active) { @@ -673,7 +678,20 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, R_V7M_CCR_USERSETMPEND_MASK | R_V7M_CCR_NONBASETHRDENA_MASK); - cpu->env.v7m.ccr = value; + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* v8M makes NONBASETHRDENA and STKALIGN be RES1 */ + value |= R_V7M_CCR_NONBASETHRDENA_MASK + | R_V7M_CCR_STKALIGN_MASK; + } + if (attrs.secure) { + /* the BFHFNMIGN bit is not banked; keep that in the NS copy */ + cpu->env.v7m.ccr[M_REG_NS] = + (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK) + | (value & R_V7M_CCR_BFHFNMIGN_MASK); + value &= ~R_V7M_CCR_BFHFNMIGN_MASK; + } + + cpu->env.v7m.ccr[attrs.secure] = value; break; case 0xd24: /* System Handler Control. */ s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0; @@ -860,12 +878,15 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, } } -static bool nvic_user_access_ok(NVICState *s, hwaddr offset) +static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs) { /* Return true if unprivileged access to this register is permitted. */ switch (offset) { case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */ - return s->cpu->env.v7m.ccr & R_V7M_CCR_USERSETMPEND_MASK; + /* For access via STIR_NS it is the NS CCR.USERSETMPEND that + * controls access even though the CPU is in Secure state (I_QDKX). + */ + return s->cpu->env.v7m.ccr[attrs.secure] & R_V7M_CCR_USERSETMPEND_MASK; default: /* All other user accesses cause a BusFault unconditionally */ return false; @@ -881,7 +902,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, unsigned i, startvec, end; uint32_t val; - if (attrs.user && !nvic_user_access_ok(s, addr)) { + if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) { /* Generate BusFault for unprivileged accesses */ return MEMTX_ERROR; } @@ -971,7 +992,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, trace_nvic_sysreg_write(addr, value, size); - if (attrs.user && !nvic_user_access_ok(s, addr)) { + if (attrs.user && !nvic_user_access_ok(s, addr, attrs)) { /* Generate BusFault for unprivileged accesses */ return MEMTX_ERROR; } diff --git a/target/arm/cpu.c b/target/arm/cpu.c index b7f5ec2..116b567 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -189,11 +189,17 @@ static void arm_cpu_reset(CPUState *s) env->v7m.secure = true; } - /* The reset value of this bit is IMPDEF, but ARM recommends + /* In v7M the reset value of this bit is IMPDEF, but ARM recommends * that it resets to 1, so QEMU always does that rather than making - * it dependent on CPU model. + * it dependent on CPU model. In v8M it is RES1. */ - env->v7m.ccr = R_V7M_CCR_STKALIGN_MASK; + env->v7m.ccr[M_REG_NS] = R_V7M_CCR_STKALIGN_MASK; + env->v7m.ccr[M_REG_S] = R_V7M_CCR_STKALIGN_MASK; + if (arm_feature(env, ARM_FEATURE_V8)) { + /* in v8M the NONBASETHRDENA bit [0] is RES1 */ + env->v7m.ccr[M_REG_NS] |= R_V7M_CCR_NONBASETHRDENA_MASK; + env->v7m.ccr[M_REG_S] |= R_V7M_CCR_NONBASETHRDENA_MASK; + } /* Unlike A/R profile, M profile defines the reset LR value */ env->regs[14] = 0xffffffff; diff --git a/target/arm/helper.c b/target/arm/helper.c index cc68688..2fe1662 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6113,7 +6113,8 @@ static void v7m_push_stack(ARMCPU *cpu) uint32_t xpsr = xpsr_read(env); /* Align stack pointer if the guest wants that */ - if ((env->regs[13] & 4) && (env->v7m.ccr & R_V7M_CCR_STKALIGN_MASK)) { + if ((env->regs[13] & 4) && + (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKALIGN_MASK)) { env->regs[13] -= 4; xpsr |= XPSR_SPREALIGN; } @@ -6211,7 +6212,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) /* fall through */ case 9: /* Return to Thread using Main stack */ if (!rettobase && - !(env->v7m.ccr & R_V7M_CCR_NONBASETHRDENA_MASK)) { + !(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_NONBASETHRDENA_MASK)) { ufault = true; } break; diff --git a/target/arm/machine.c b/target/arm/machine.c index 666655d..d740e83 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -117,7 +117,7 @@ static const VMStateDescription vmstate_m = { VMSTATE_UINT32(env.v7m.vecbase[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU), - VMSTATE_UINT32(env.v7m.ccr, ARMCPU), + VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.cfsr, ARMCPU), VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), VMSTATE_UINT32(env.v7m.dfsr, ARMCPU), @@ -271,6 +271,7 @@ static const VMStateDescription vmstate_m_security = { VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU), VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate), VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU), + VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU), VMSTATE_END_OF_LIST() } };