From patchwork Fri Oct 6 15:59:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 115100 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp2002288qgn; Fri, 6 Oct 2017 09:48:43 -0700 (PDT) X-Google-Smtp-Source: AOwi7QCPPJdwB4ENIZW6HnBdqNQMsou3tPnVLlSeNBB90/uJHwdUwISBdjZeWTs2+m9820UQoDAu X-Received: by 10.55.43.75 with SMTP id r72mr34155759qkh.307.1507308523649; Fri, 06 Oct 2017 09:48:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507308523; cv=none; d=google.com; s=arc-20160816; b=GWCEsyrXhBUCEImAlgwV0yadwYkc6juFYb5sgQR9lmj5p+0crdeSoc5fdSBPXJNWi2 0YOq/ljipzVSa4Tl1HmFtmfG9G+lWGRjSDYZwBp90/9dwS/J7tW1DQPt1XuvsDR1rxZo +2ESubjWrHDHgNUY7Jl/G1is/IxgD3dRC/3w/pHcOPYaMvm9AMghme9EF4WAbSeh59Yb dbDWwj1fJW1f33mzLkLWVV9qA/ByZUogNaIycZUV2bfCB4rqEyxmw0raCAANdsTdnrX9 OVB09/KSCiSP7J/+j4fkz18/3/QpTX9Z+nXkBT4VSTbJVyKr0F9mN6pX1LdkdTKYvztH 6y/A== 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=lpCBaVWRGHLjWuaTWN5z5zxEGeFgHNJjg/Yv7ASafBg=; b=rJNvTh5xBgwwG/quXH0SFsUGkVIS32syiccYa1zdURHD4pASMK/u1iawiTO1IrPkMd MEGC/tjoR7m+vqK1cadfBLrItO/Zl7E4W4Ubhk7QVhF1HvqbR+miy1Qxb7Sz2TFCV9Ew NBSt0Mp9SE357ZeLUfvhVV4N44E0jrI9xEwHg4xV5NtVIcxi2oROgUlbTG6pKxoYtQvq Q22gmvFJqEOMAfsG8f0TVPKND16q8R5UgrK5fEOn71wEHDWydPVyVmWxL+Vqe9MtzGKj quFurOBLPro52UWSQVDcUQNukaprG+hA92FP2PC0P7JO5jh3JC/ZnMGNnm1o3cz3+0gD hbgA== 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 i66si1519619qkd.378.2017.10.06.09.48.43 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 06 Oct 2017 09:48:43 -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]:45945 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e0Vnn-0005WJ-5r for patch@linaro.org; Fri, 06 Oct 2017 12:48:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58061) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e0V1j-0004AU-Qp for qemu-devel@nongnu.org; Fri, 06 Oct 2017 11:59:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e0V1i-0007me-Gn for qemu-devel@nongnu.org; Fri, 06 Oct 2017 11:59:03 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37716) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e0V1i-0007kt-6P for qemu-devel@nongnu.org; Fri, 06 Oct 2017 11:59:02 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1e0V1h-0002xs-3E for qemu-devel@nongnu.org; Fri, 06 Oct 2017 16:59:01 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 6 Oct 2017 16:59:41 +0100 Message-Id: <1507305585-20608-17-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1507305585-20608-1-git-send-email-peter.maydell@linaro.org> References: <1507305585-20608-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 16/20] nvic: Implement Security Attribution Unit registers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Implement the register interface for the SAU: SAU_CTRL, SAU_TYPE, SAU_RNR, SAU_RBAR and SAU_RLAR. None of the actual behaviour is implemented here; registers just read back as written. When the CPU definition for Cortex-M33 is eventually added, its initfn will set cpu->sau_sregion, in the same way that we currently set cpu->pmsav7_dregion for the M3 and M4. Number of SAU regions is typically a configurable CPU parameter, but this patch doesn't provide a QEMU CPU property for it. We can easily add one when we have a board that requires it. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 1506092407-26985-14-git-send-email-peter.maydell@linaro.org --- target/arm/cpu.h | 10 +++++ hw/intc/armv7m_nvic.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ target/arm/cpu.c | 27 ++++++++++++ target/arm/machine.c | 14 ++++++ 4 files changed, 167 insertions(+) -- 2.7.4 diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 9e3a16d..441e584 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -568,6 +568,14 @@ typedef struct CPUARMState { uint32_t mair1[M_REG_NUM_BANKS]; } pmsav8; + /* v8M SAU */ + struct { + uint32_t *rbar; + uint32_t *rlar; + uint32_t rnr; + uint32_t ctrl; + } sau; + void *nvic; const struct arm_boot_info *boot_info; /* Store GICv3CPUState to access from this struct */ @@ -663,6 +671,8 @@ struct ARMCPU { bool has_mpu; /* PMSAv7 MPU number of supported regions */ uint32_t pmsav7_dregion; + /* v8M SAU number of supported regions */ + uint32_t sau_sregion; /* PSCI conduit used to invoke PSCI methods * 0 - disabled, 1 - smc, 2 - hvc diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index deea637..bd1d5d3 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -1017,6 +1017,60 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) goto bad_offset; } return cpu->env.pmsav8.mair1[attrs.secure]; + case 0xdd0: /* SAU_CTRL */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return 0; + } + return cpu->env.sau.ctrl; + case 0xdd4: /* SAU_TYPE */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return 0; + } + return cpu->sau_sregion; + case 0xdd8: /* SAU_RNR */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return 0; + } + return cpu->env.sau.rnr; + case 0xddc: /* SAU_RBAR */ + { + int region = cpu->env.sau.rnr; + + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return 0; + } + if (region >= cpu->sau_sregion) { + return 0; + } + return cpu->env.sau.rbar[region]; + } + case 0xde0: /* SAU_RLAR */ + { + int region = cpu->env.sau.rnr; + + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return 0; + } + if (region >= cpu->sau_sregion) { + return 0; + } + return cpu->env.sau.rlar[region]; + } case 0xde4: /* SFSR */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; @@ -1384,6 +1438,68 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, * only affect cacheability, and we don't implement caching. */ break; + case 0xdd0: /* SAU_CTRL */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return; + } + cpu->env.sau.ctrl = value & 3; + case 0xdd4: /* SAU_TYPE */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + break; + case 0xdd8: /* SAU_RNR */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return; + } + if (value >= cpu->sau_sregion) { + qemu_log_mask(LOG_GUEST_ERROR, "SAU region out of range %" + PRIu32 "/%" PRIu32 "\n", + value, cpu->sau_sregion); + } else { + cpu->env.sau.rnr = value; + } + break; + case 0xddc: /* SAU_RBAR */ + { + int region = cpu->env.sau.rnr; + + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return; + } + if (region >= cpu->sau_sregion) { + return; + } + cpu->env.sau.rbar[region] = value & ~0x1f; + tlb_flush(CPU(cpu)); + break; + } + case 0xde0: /* SAU_RLAR */ + { + int region = cpu->env.sau.rnr; + + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (!attrs.secure) { + return; + } + if (region >= cpu->sau_sregion) { + return; + } + cpu->env.sau.rlar[region] = value & ~0x1c; + tlb_flush(CPU(cpu)); + break; + } case 0xde4: /* SFSR */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 4300de6..f4f601f 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -285,6 +285,18 @@ static void arm_cpu_reset(CPUState *s) env->pmsav8.mair1[M_REG_S] = 0; } + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + if (cpu->sau_sregion > 0) { + memset(env->sau.rbar, 0, sizeof(*env->sau.rbar) * cpu->sau_sregion); + memset(env->sau.rlar, 0, sizeof(*env->sau.rlar) * cpu->sau_sregion); + } + env->sau.rnr = 0; + /* SAU_CTRL reset value is IMPDEF; we choose 0, which is what + * the Cortex-M33 does. + */ + env->sau.ctrl = 0; + } + set_flush_to_zero(1, &env->vfp.standard_fp_status); set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); set_default_nan_mode(1, &env->vfp.standard_fp_status); @@ -873,6 +885,20 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } } + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + uint32_t nr = cpu->sau_sregion; + + if (nr > 0xff) { + error_setg(errp, "v8M SAU #regions invalid %" PRIu32, nr); + return; + } + + if (nr) { + env->sau.rbar = g_new0(uint32_t, nr); + env->sau.rlar = g_new0(uint32_t, nr); + } + } + if (arm_feature(env, ARM_FEATURE_EL3)) { set_feature(env, ARM_FEATURE_VBAR); } @@ -1141,6 +1167,7 @@ static void cortex_m4_initfn(Object *obj) cpu->midr = 0x410fc240; /* r0p0 */ cpu->pmsav7_dregion = 8; } + static void arm_v7m_class_init(ObjectClass *oc, void *data) { CPUClass *cc = CPU_CLASS(oc); diff --git a/target/arm/machine.c b/target/arm/machine.c index a0d7ed8..1762746 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -242,6 +242,13 @@ static bool s_rnr_vmstate_validate(void *opaque, int version_id) return cpu->env.pmsav7.rnr[M_REG_S] < cpu->pmsav7_dregion; } +static bool sau_rnr_vmstate_validate(void *opaque, int version_id) +{ + ARMCPU *cpu = opaque; + + return cpu->env.sau.rnr < cpu->sau_sregion; +} + static bool m_security_needed(void *opaque) { ARMCPU *cpu = opaque; @@ -278,6 +285,13 @@ static const VMStateDescription vmstate_m_security = { VMSTATE_UINT32(env.v7m.cfsr[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.sfsr, ARMCPU), VMSTATE_UINT32(env.v7m.sfar, ARMCPU), + VMSTATE_VARRAY_UINT32(env.sau.rbar, ARMCPU, sau_sregion, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(env.sau.rlar, ARMCPU, sau_sregion, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_UINT32(env.sau.rnr, ARMCPU), + VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate), + VMSTATE_UINT32(env.sau.ctrl, ARMCPU), VMSTATE_END_OF_LIST() } };