From patchwork Tue Aug 22 15:08:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110673 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816075qge; Tue, 22 Aug 2017 08:09:03 -0700 (PDT) X-Received: by 10.99.16.65 with SMTP id 1mr1050398pgq.208.1503414543353; Tue, 22 Aug 2017 08:09:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414543; cv=none; d=google.com; s=arc-20160816; b=QfUooYPdtXRFGPwINCUKUtyobtos2EqXH70gLBoqZsKIJst2aN7E9/niEkIhBHRLod CsxEhdmm5Q9f8/ElL7NKYCFHPJXQ5Z7tyBrYb7cv8wwnmXG6oAvvl+56W/TOfGHzEiQG j3s3uDwF+uBKRjIakVqeFY7gREI8Ev//H0S3r831Og3YKxGKViL1oeYRauseaNvQiiyu 5Q/7Z8xc9PdmNeAy6+bhuMF7d6XbMnYO3VmppHeMdkAB88TPFaz+nP+s25jRQ33rHH0n HjATeZb2qeXuwZsiMEJ579jo/XO/eEx/3udCfiI/QVR8g9DGgtuaFnZRRtqVECt41u/H kSTQ== 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=vSDF9LNQpcrXG1qsbB7ov2NemUYa/LcUX8iOIVw+8Os=; b=W19UVkjr8/CbLOS0fZyTOKCE0ZgEwi8zEbQrq2NChYcEbfg/WFUGSPh0TqBWueiF9j PrQJC3ykNScDZj/gKg29JcvYzwQNg0mHKgrmS8E9u+MEOwssHPYTmkm8wzZcyCUucETI g7QmffJyrdmr9zac4NxbotW4XPATq6gYGKjbB9QyTGF2+VZ75BQuikwStqzxQFoS+z79 Z+wCxJHyV170tMlbGf/IhTOK3knF6wtgnMbraUf+cQh0LIGCRHiVLhQLfqo/tHJdWNel 3tcs5R1+IV3/AtJL1ElIH37gVg8fYtw4dpsB7S1qy8GZrDDmEM/71rvMWSxa93V8bNiN DzfA== 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 c76si9036448pfl.693.2017.08.22.08.09.01 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:02 -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 1dkAnZ-0004dj-QG; Tue, 22 Aug 2017 16:08:57 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 01/20] target/arm: Implement ARMv8M's PMSAv8 registers Date: Tue, 22 Aug 2017 16:08:40 +0100 Message-Id: <1503414539-28762-2-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> As part of ARMv8M, we need to add support for the PMSAv8 MPU architecture. PMSAv8 differs from PMSAv7 both in register/data layout (for instance using base and limit registers rather than base and size) and also in behaviour (for example it does not have subregions); rather than trying to wedge it into the existing PMSAv7 code and data structures, we define separate ones. This commit adds the data structures which hold the state for a PMSAv8 MPU and the register interface to it. The implementation of the MPU behaviour will be added in a subsequent commit. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 13 ++++++ hw/intc/armv7m_nvic.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++---- target/arm/cpu.c | 36 ++++++++++----- target/arm/machine.c | 28 +++++++++++- 4 files changed, 179 insertions(+), 20 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/target/arm/cpu.h b/target/arm/cpu.h index fe6edb7..b6bb78a 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -522,6 +522,19 @@ typedef struct CPUARMState { uint32_t rnr; } pmsav7; + /* PMSAv8 MPU */ + struct { + /* The PMSAv8 implementation also shares some PMSAv7 config + * and state: + * pmsav7.rnr (region number register) + * pmsav7_dregion (number of configured regions) + */ + uint32_t *rbar; + uint32_t *rlar; + uint32_t mair0; + uint32_t mair1; + } pmsav8; + void *nvic; const struct arm_boot_info *boot_info; /* Store GICv3CPUState to access from this struct */ diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index bbfe2d5..c0dbbad 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -544,25 +544,67 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset) { int region = cpu->env.pmsav7.rnr; + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* PMSAv8M handling of the aliases is different from v7M: + * aliases A1, A2, A3 override the low two bits of the region + * number in MPU_RNR, and there is no 'region' field in the + * RBAR register. + */ + int aliasno = (offset - 0xd9c) / 8; /* 0..3 */ + if (aliasno) { + region = deposit32(region, 0, 2, aliasno); + } + if (region >= cpu->pmsav7_dregion) { + return 0; + } + return cpu->env.pmsav8.rbar[region]; + } + if (region >= cpu->pmsav7_dregion) { return 0; } return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf); } - case 0xda0: /* MPU_RASR */ - case 0xda8: /* MPU_RASR_A1 */ - case 0xdb0: /* MPU_RASR_A2 */ - case 0xdb8: /* MPU_RASR_A3 */ + case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */ + case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */ + case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */ + case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */ { int region = cpu->env.pmsav7.rnr; + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* PMSAv8M handling of the aliases is different from v7M: + * aliases A1, A2, A3 override the low two bits of the region + * number in MPU_RNR. + */ + int aliasno = (offset - 0xda0) / 8; /* 0..3 */ + if (aliasno) { + region = deposit32(region, 0, 2, aliasno); + } + if (region >= cpu->pmsav7_dregion) { + return 0; + } + return cpu->env.pmsav8.rlar[region]; + } + if (region >= cpu->pmsav7_dregion) { return 0; } return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) | (cpu->env.pmsav7.drsr[region] & 0xffff); } + case 0xdc0: /* MPU_MAIR0 */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + return cpu->env.pmsav8.mair0; + case 0xdc4: /* MPU_MAIR1 */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + return cpu->env.pmsav8.mair1; default: + bad_offset: qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset); return 0; } @@ -691,6 +733,26 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) { int region; + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* PMSAv8M handling of the aliases is different from v7M: + * aliases A1, A2, A3 override the low two bits of the region + * number in MPU_RNR, and there is no 'region' field in the + * RBAR register. + */ + int aliasno = (offset - 0xd9c) / 8; /* 0..3 */ + + region = cpu->env.pmsav7.rnr; + if (aliasno) { + region = deposit32(region, 0, 2, aliasno); + } + if (region >= cpu->pmsav7_dregion) { + return; + } + cpu->env.pmsav8.rbar[region] = value; + tlb_flush(CPU(cpu)); + return; + } + if (value & (1 << 4)) { /* VALID bit means use the region number specified in this * value and also update MPU_RNR.REGION with that value. @@ -715,13 +777,32 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) tlb_flush(CPU(cpu)); break; } - case 0xda0: /* MPU_RASR */ - case 0xda8: /* MPU_RASR_A1 */ - case 0xdb0: /* MPU_RASR_A2 */ - case 0xdb8: /* MPU_RASR_A3 */ + case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */ + case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */ + case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */ + case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */ { int region = cpu->env.pmsav7.rnr; + if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { + /* PMSAv8M handling of the aliases is different from v7M: + * aliases A1, A2, A3 override the low two bits of the region + * number in MPU_RNR. + */ + int aliasno = (offset - 0xd9c) / 8; /* 0..3 */ + + region = cpu->env.pmsav7.rnr; + if (aliasno) { + region = deposit32(region, 0, 2, aliasno); + } + if (region >= cpu->pmsav7_dregion) { + return; + } + cpu->env.pmsav8.rlar[region] = value; + tlb_flush(CPU(cpu)); + return; + } + if (region >= cpu->pmsav7_dregion) { return; } @@ -731,6 +812,30 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) tlb_flush(CPU(cpu)); break; } + case 0xdc0: /* MPU_MAIR0 */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (cpu->pmsav7_dregion) { + /* Register is RES0 if no MPU regions are implemented */ + cpu->env.pmsav8.mair0 = value; + } + /* We don't need to do anything else because memory attributes + * only affect cacheability, and we don't implement caching. + */ + break; + case 0xdc4: /* MPU_MAIR1 */ + if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { + goto bad_offset; + } + if (cpu->pmsav7_dregion) { + /* Register is RES0 if no MPU regions are implemented */ + cpu->env.pmsav8.mair1 = value; + } + /* We don't need to do anything else because memory attributes + * only affect cacheability, and we don't implement caching. + */ + break; case 0xf00: /* Software Triggered Interrupt Register */ { int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ; @@ -740,6 +845,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) break; } default: + bad_offset: qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad write offset 0x%x\n", offset); } diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 41ae6ba..8b610de 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -228,17 +228,25 @@ static void arm_cpu_reset(CPUState *s) env->vfp.xregs[ARM_VFP_FPEXC] = 0; #endif - if (arm_feature(env, ARM_FEATURE_PMSA) && - arm_feature(env, ARM_FEATURE_V7)) { + if (arm_feature(env, ARM_FEATURE_PMSA)) { if (cpu->pmsav7_dregion > 0) { - memset(env->pmsav7.drbar, 0, - sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); - memset(env->pmsav7.drsr, 0, - sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion); - memset(env->pmsav7.dracr, 0, - sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion); + if (arm_feature(env, ARM_FEATURE_V8)) { + memset(env->pmsav8.rbar, 0, + sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion); + memset(env->pmsav8.rlar, 0, + sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion); + } else if (arm_feature(env, ARM_FEATURE_V7)) { + memset(env->pmsav7.drbar, 0, + sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); + memset(env->pmsav7.drsr, 0, + sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion); + memset(env->pmsav7.dracr, 0, + sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion); + } } env->pmsav7.rnr = 0; + env->pmsav8.mair0 = 0; + env->pmsav8.mair1 = 0; } set_flush_to_zero(1, &env->vfp.standard_fp_status); @@ -809,9 +817,15 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } if (nr) { - env->pmsav7.drbar = g_new0(uint32_t, nr); - env->pmsav7.drsr = g_new0(uint32_t, nr); - env->pmsav7.dracr = g_new0(uint32_t, nr); + if (arm_feature(env, ARM_FEATURE_V8)) { + /* PMSAv8 */ + env->pmsav8.rbar = g_new0(uint32_t, nr); + env->pmsav8.rlar = g_new0(uint32_t, nr); + } else { + env->pmsav7.drbar = g_new0(uint32_t, nr); + env->pmsav7.drsr = g_new0(uint32_t, nr); + env->pmsav7.dracr = g_new0(uint32_t, nr); + } } } diff --git a/target/arm/machine.c b/target/arm/machine.c index 3193b00..05e2909 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -159,7 +159,8 @@ static bool pmsav7_needed(void *opaque) CPUARMState *env = &cpu->env; return arm_feature(env, ARM_FEATURE_PMSA) && - arm_feature(env, ARM_FEATURE_V7); + arm_feature(env, ARM_FEATURE_V7) && + !arm_feature(env, ARM_FEATURE_V8); } static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) @@ -209,6 +210,31 @@ static const VMStateDescription vmstate_pmsav7_rnr = { } }; +static bool pmsav8_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + return arm_feature(env, ARM_FEATURE_PMSA) && + arm_feature(env, ARM_FEATURE_V8); +} + +static const VMStateDescription vmstate_pmsav8 = { + .name = "cpu/pmsav8", + .version_id = 1, + .minimum_version_id = 1, + .needed = pmsav8_needed, + .fields = (VMStateField[]) { + VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0, + vmstate_info_uint32, uint32_t), + VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU), + VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU), + VMSTATE_END_OF_LIST() + } +}; + static int get_cpsr(QEMUFile *f, void *opaque, size_t size, VMStateField *field) { From patchwork Tue Aug 22 15:08: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: 110666 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2815972qge; Tue, 22 Aug 2017 08:09:00 -0700 (PDT) X-Received: by 10.25.21.151 with SMTP id 23mr352500lfv.230.1503414540155; Tue, 22 Aug 2017 08:09:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414540; cv=none; d=google.com; s=arc-20160816; b=A+uNvIACHc1bFJTy2ukZkGNmXYICDa9bqYXhv8wzTh31S5U+jlluTyJ/w0cfHwylL5 sqO1yoh0HhQSWhjBeQ2uLVYxJhn1UTY1/jH/JHphTNHVfYwfBlH7korZyPY9wCbBmS/r P6pPibdIn80BWb5kWtNUvNW54Gtm+xHa0mnCaovT3+L3Tm2Pcf0qvdarArQWQERk+evG KUlyUSePcd/FZWvcArvdAr6qPqCsBc/Zb3og1HdvzE+vZ8fGayVvyFJ+pj1ABsczyQ9a lfahVEt1R8hxprdKZSbkjVxsiR/y6ppLvTz1HqmYreTlII77R8zMjTZPk26QbV8gnEUO cy6w== 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=gHamKw8ebS/pJEu33NEifzEJ0aDK3iltO7a9dgTgqwU=; b=hdoSbz7H401DzoEzrC0y1NVMQDQudTikmGRvTnd+Njvq73rbPLIb+t6TFQg/2wKFm9 YI1cFzMAUMyLHaJlbq9pIiLJ/TgwLMkaUDwVWWX0xZvXv6me08fObE77oNHtbKiP+DQp JPa0mOuUvvIOrx6KXYJournZmmXyBUsL46/c6dLoOYmXvHQiYtZyZaRwc18bzgy6aujP 2HCgPH7DsLpVrgS3qF2Q8Y88MRtVRpIEFNOtv9xLgMWpvss69vgLV/qAPNwy6Ij5aElj ZUtHDtKLJNgZ1SQZFAgwZDoGCKRfcVDetO17NRUnFtqZiwKDlGsXh8fPHCc5uVwo3jy8 IScA== 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 y24si5794512ljd.153.2017.08.22.08.08.59 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:08:59 -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 1dkAna-0004e0-Gg; Tue, 22 Aug 2017 16:08:58 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 02/20] target/arm: Implement new PMSAv8 behaviour Date: Tue, 22 Aug 2017 16:08:41 +0100 Message-Id: <1503414539-28762-3-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Implement the behavioural side of the new PMSAv8 specification. Signed-off-by: Peter Maydell --- target/arm/helper.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/target/arm/helper.c b/target/arm/helper.c index 7920153..887490a 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8416,6 +8416,111 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, return !(*prot & (1 << access_type)); } +static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address, + MMUAccessType access_type, ARMMMUIdx mmu_idx, + hwaddr *phys_ptr, int *prot, uint32_t *fsr) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + bool is_user = regime_is_user(env, mmu_idx); + int n; + int matchregion = -1; + bool hit = false; + + *phys_ptr = address; + *prot = 0; + + /* Unlike the ARM ARM pseudocode, we don't need to check whether this + * was an exception vector read from the vector table (which is always + * done using the default system address map), because those accesses + * are done in arm_v7m_load_vector(), which always does a direct + * read using address_space_ldl(), rather than going via this function. + */ + if (regime_translation_disabled(env, mmu_idx)) { /* MPU disabled */ + hit = true; + } else if (m_is_ppb_region(env, address)) { + hit = true; + } else if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) { + hit = true; + } else { + for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) { + /* region search */ + /* Note that the base address is bits [31:5] from the register + * with bits [4:0] all zeroes, but the limit address is bits + * [31:5] from the register with bits [4:0] all ones. + */ + uint32_t base = env->pmsav8.rbar[n] & ~0x1f; + uint32_t limit = env->pmsav8.rlar[n] | 0x1f; + + if (!(env->pmsav8.rlar[n] & 0x1)) { + /* Region disabled */ + continue; + } + + if (address < base || address > limit) { + continue; + } + + if (hit) { + /* Multiple regions match -- always a failure (unlike + * PMSAv7 where highest-numbered-region wins) + */ + *fsr = 0x00d; /* permission fault */ + return true; + } + + matchregion = n; + hit = true; + + if (base & ~TARGET_PAGE_MASK) { + qemu_log_mask(LOG_UNIMP, + "MPU_RBAR[%d]: No support for MPU region base" + "address of 0x%" PRIx32 ". Minimum alignment is " + "%d\n", + n, base, TARGET_PAGE_BITS); + continue; + } + if ((limit + 1) & ~TARGET_PAGE_MASK) { + qemu_log_mask(LOG_UNIMP, + "MPU_RBAR[%d]: No support for MPU region limit" + "address of 0x%" PRIx32 ". Minimum alignment is " + "%d\n", + n, limit, TARGET_PAGE_BITS); + continue; + } + } + } + + if (!hit) { + /* background fault */ + *fsr = 0; + return true; + } + + if (matchregion == -1) { + /* hit using the background region */ + get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); + } else { + uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2); + uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1); + + if (m_is_system_region(env, address)) { + /* System space is always execute never */ + xn = 1; + } + + *prot = simple_ap_to_rw_prot(env, mmu_idx, ap); + if (*prot && !xn) { + *prot |= PAGE_EXEC; + } + /* We don't need to look the attribute up in the MAIR0/MAIR1 + * registers because that only tells us about cacheability. + */ + } + + *fsr = 0x00d; /* Permission fault */ + return !(*prot & (1 << access_type)); +} + static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, MMUAccessType access_type, ARMMMUIdx mmu_idx, hwaddr *phys_ptr, int *prot, uint32_t *fsr) @@ -8585,7 +8690,11 @@ static bool get_phys_addr(CPUARMState *env, target_ulong address, bool ret; *page_size = TARGET_PAGE_SIZE; - if (arm_feature(env, ARM_FEATURE_V7)) { + if (arm_feature(env, ARM_FEATURE_V8)) { + /* PMSAv8 */ + ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx, + phys_ptr, prot, fsr); + } else if (arm_feature(env, ARM_FEATURE_V7)) { /* PMSAv7 */ ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx, phys_ptr, prot, fsr); From patchwork Tue Aug 22 15:08:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110667 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2815971qge; Tue, 22 Aug 2017 08:09:00 -0700 (PDT) X-Received: by 10.28.6.212 with SMTP id 203mr604235wmg.126.1503414540119; Tue, 22 Aug 2017 08:09:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414540; cv=none; d=google.com; s=arc-20160816; b=egzyksgqAwYx9/QEh4yNEO8qStaWtfdoUifJqs8brwoEP7VXkvvTfLfQ75lxtci3AI q2xqt6PAR7Al77muvdgaSMYSiM5Vxp/wVq42CS3tG6UxOmvXCHXi5smDeIrRaLTWsUjR RTffHSLtXOQS67BV4dVHgCjlW6HnxtUfZRowUnD51G/MR6QthIApv+fbmLjJoZVreIic ZHmv8jYARC/fY+HyaTTaar6hk7RI28/M+uLsQSU21K2zyO6qyJ3NJ6Yv7nMsXzUwnpGX lWnNEN/8bPHXFjADrHmWnbmIgOzDu7540OIj6ciTA2+njib84+6dUdAuUtva/l95oGAd 5B4g== 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=5nzO7zo8161xQHIbcIVqfq8W0ywj5SWr6gWM8Cdjp2E=; b=0i65Q57omXls8YGea6jaAZ3OGmdIguEbdQMvQHPlSuLGK30mSaKoOtEOwug5/RjA1n oBsX5Qm5uKbvI9FOS6sQqTSvmbT7IqzIc45Y9PMNOuM2bRYOk7G9x+V+KWo142l1XAWA zQxtDxoD5mKeaxhedBKELvVcg/ohOlH14xYybh7U1NvcfH+MV5grvRP5Kb37h142foGa ciIOZHKe5b7EQGiJ5APCfADIdJ2tqlJappPPmo9Ia6bzPNPNzxlH/gpWoZznODdNiaAF bf2KREqdcAdia6YKK5rwyLKaemLA+DPtykB4i6up0ORgooZUZhbcq2sxMbcUZpuTKYnH O+FA== 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 x42si11577263wrb.449.2017.08.22.08.08.59 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:00 -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 1dkAnb-0004eF-6B; Tue, 22 Aug 2017 16:08:59 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 03/20] target/arm: Add state field, feature bit and migration for v8M secure state Date: Tue, 22 Aug 2017 16:08:42 +0100 Message-Id: <1503414539-28762-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> As the first step in implementing ARM v8M's security extension: * add a new feature bit ARM_FEATURE_M_SECURITY * add the CPU state field that indicates whether the CPU is currently in the secure state * add a migration subsection for this new state (we will add the Secure copies of banked register state to this subsection in later patches) * add a #define for the one new-in-v8M exception type * make the CPU debug log print S/NS status Signed-off-by: Peter Maydell --- target/arm/cpu.h | 3 +++ target/arm/cpu.c | 4 ++++ target/arm/machine.c | 20 ++++++++++++++++++++ target/arm/translate.c | 8 +++++++- 4 files changed, 34 insertions(+), 1 deletion(-) -- 2.7.4 Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/cpu.h b/target/arm/cpu.h index b6bb78a..24666baa 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -66,6 +66,7 @@ #define ARMV7M_EXCP_MEM 4 #define ARMV7M_EXCP_BUS 5 #define ARMV7M_EXCP_USAGE 6 +#define ARMV7M_EXCP_SECURE 7 #define ARMV7M_EXCP_SVC 11 #define ARMV7M_EXCP_DEBUG 12 #define ARMV7M_EXCP_PENDSV 14 @@ -420,6 +421,7 @@ typedef struct CPUARMState { int exception; uint32_t primask; uint32_t faultmask; + uint32_t secure; /* Is CPU in Secure state? (not guest visible) */ } v7m; /* Information associated with an exception about to be taken: @@ -1264,6 +1266,7 @@ enum arm_features { ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */ ARM_FEATURE_PMU, /* has PMU support */ ARM_FEATURE_VBAR, /* has cp15 VBAR */ + ARM_FEATURE_M_SECURITY, /* M profile Security Extension */ }; static inline int arm_feature(CPUARMState *env, int feature) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 8b610de..f32317e 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -185,6 +185,10 @@ static void arm_cpu_reset(CPUState *s) uint32_t initial_pc; /* Loaded from 0x4 */ uint8_t *rom; + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + env->v7m.secure = true; + } + /* 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. diff --git a/target/arm/machine.c b/target/arm/machine.c index 05e2909..745adae 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -235,6 +235,25 @@ static const VMStateDescription vmstate_pmsav8 = { } }; +static bool m_security_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + return arm_feature(env, ARM_FEATURE_M_SECURITY); +} + +static const VMStateDescription vmstate_m_security = { + .name = "cpu/m-security", + .version_id = 1, + .minimum_version_id = 1, + .needed = m_security_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32(env.v7m.secure, ARMCPU), + VMSTATE_END_OF_LIST() + } +}; + static int get_cpsr(QEMUFile *f, void *opaque, size_t size, VMStateField *field) { @@ -484,6 +503,7 @@ const VMStateDescription vmstate_arm_cpu = { */ &vmstate_pmsav7_rnr, &vmstate_pmsav7, + &vmstate_m_security, NULL } }; diff --git a/target/arm/translate.c b/target/arm/translate.c index e52a6d7..dea0a6f 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -12232,6 +12232,11 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, if (arm_feature(env, ARM_FEATURE_M)) { uint32_t xpsr = xpsr_read(env); const char *mode; + const char *ns_status = ""; + + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + ns_status = env->v7m.secure ? "S " : "NS "; + } if (xpsr & XPSR_EXCP) { mode = "handler"; @@ -12243,13 +12248,14 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, } } - cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s\n", + cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n", xpsr, xpsr & XPSR_N ? 'N' : '-', xpsr & XPSR_Z ? 'Z' : '-', xpsr & XPSR_C ? 'C' : '-', xpsr & XPSR_V ? 'V' : '-', xpsr & XPSR_T ? 'T' : 'A', + ns_status, mode); } else { uint32_t psr = cpsr_read(env); From patchwork Tue Aug 22 15:08:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110668 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816011qge; Tue, 22 Aug 2017 08:09:01 -0700 (PDT) X-Received: by 10.28.99.138 with SMTP id x132mr8821wmb.58.1503414541175; Tue, 22 Aug 2017 08:09:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414541; cv=none; d=google.com; s=arc-20160816; b=usaGl4Kj6NX2Z654PRz6e6R93cAgQqy501iRATy2Zk2TOAfPoPXJJJgqtxRNACqNEq EY2EbKly6wLRcvgqEARk6zQ+kKXedkbLjsESew38ZAx/Yfy5VUkJ9G6jxUAoTdiSEq1U hbbXhZV8h52dctnnUMv//Nb8fjWGu7mVGbXq42ayWiEe8Sz3DeCxvbsnp4Mi+iMUHyBu jvKTZ5wCxPWD1Kkv4HncUIPTvqzxW7GMYEgYgZst3eQx3iwIKdgEhipMPJK96yplB1kU sLzH+gneK+fBhhpVGK8G6GB2lN/eRDdnfoli94e4Vkr3N8Gm4WeoiYyNZ1ywO8/XjGjb Xs2A== 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=2wRUDHW6BYy8nSk4IUjGsZPqQgyPdoimScGQ2jae2Yk=; b=puCG11doeshzKDFv9KHEvTODDms6rQTHIyWt2G1DU0hgIy2Wzu5rzrnpAu5zgcd6rr 8MUzHJvWD9GsTY+mBblxVCY9wIILjPA3n2ojY26Umc1LVq1OlBqg7EsQpaRNh/92W9qi oLIYVm0FdQUjBrBabtNKFDvRLdTe/ROgmafZ+K6i1/vDpzRPj6yySzrAOfvpuHSfb2eg BIvy2qF3RY8vD//V569zsL7Ab98atOyLluGDRu3rCroYQ4xfc+o0a3viA42ncHuHm3QB q1teABq2B15+/23bCEpAnVo/4vRXU6tzcXvxElY0e5SAKderNHVGL681C8Xwa6dtYvKg WVsA== 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 k184si57075wme.87.2017.08.22.08.09.00 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:01 -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 1dkAnc-0004eU-4e; Tue, 22 Aug 2017 16:09:00 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 04/20] target/arm: Register second AddressSpace for secure v8M CPUs Date: Tue, 22 Aug 2017 16:08:43 +0100 Message-Id: <1503414539-28762-5-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> If a v8M CPU supports the security extension then we need to give it two AddressSpaces, the same way we do already for an A profile core with EL3. Signed-off-by: Peter Maydell --- target/arm/cpu.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/target/arm/cpu.c b/target/arm/cpu.c index f32317e..ae866be 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -843,22 +843,21 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) init_cpreg_list(cpu); #ifndef CONFIG_USER_ONLY - if (cpu->has_el3) { - cs->num_ases = 2; - } else { - cs->num_ases = 1; - } - - if (cpu->has_el3) { + if (cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY)) { AddressSpace *as; + cs->num_ases = 2; + if (!cpu->secure_memory) { cpu->secure_memory = cs->memory; } as = address_space_init_shareable(cpu->secure_memory, "cpu-secure-memory"); cpu_address_space_init(cs, as, ARMASIdx_S); + } else { + cs->num_ases = 1; } + cpu_address_space_init(cs, address_space_init_shareable(cs->memory, "cpu-memory"), From patchwork Tue Aug 22 15:08:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110669 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816036qge; Tue, 22 Aug 2017 08:09:02 -0700 (PDT) X-Received: by 10.46.7.65 with SMTP id i1mr471135ljd.170.1503414542028; Tue, 22 Aug 2017 08:09:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414542; cv=none; d=google.com; s=arc-20160816; b=zUrOt894W3MOnEMCK0472Kp3p7KnkbjWYjhVRyCKjocu7ITglGqa9hW96gyzJFNrVJ ZIr/ViiP+U23A4MJxf2ARwimbqJeahtjt4Cbm1lAjcPtPjJkixmQ0oFxojLJYbB74Jmw GmnGrJLIIqGha0goQGZpi7EPNVZLkYUrCmjP64HFSfCpHGpWMzLQultlRRch35kwqj9p m6iEr1OOWfWWPDRpfHWr5kil1deSqhzjjy2ztQTKtMtgKEfEqfkEqvn4yw9j8t2vrMj6 5Tm75Iw8dOkzcWipuBcPnxxdEbpENKjaPvYKGx8tPWkyl2IhTzf17t0xvyhRCiXAF0e1 Cmww== 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=l/YvvVFTwLMlIyHgBdBo3E+YymElFbZynGjTEMD1rN8=; b=TsVzS/xA5mOYJDIhnGpicJhGc/Tnez213TkX6evBIl9vB83/bep09Wgb0E9hsCXbIc a3i/Zqq409VuUEvO0bGRgkmTlraZZY27TorC6JePUz6bk1CDt4VUWZoxgYc7clegvh6A +jmDiGYq64kBFA+ijt2tqbYVApGDzatOTLoyYNmqBOxPm+aTjLL9TR8Jb3HFnxrKEPu2 HP/QtwCjfyvGUnOgvd+SoCesfrCY2BnvOcQPvvfwoQx2JQ46NHNxv4Nyc36UCzuEs5XP 4NxTCkhTeZiuNgZ1I01vIZlQcQ0Tuuz6j/sGmQxHeNVqf3DJjtZmmWKetyjOSiKAPIsa f5Bw== 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 a70si6233726ljb.202.2017.08.22.08.09.01 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:02 -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 1dkAnc-0004fF-RV; Tue, 22 Aug 2017 16:09:00 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 05/20] target/arm: Add MMU indexes for secure v8M Date: Tue, 22 Aug 2017 16:08:44 +0100 Message-Id: <1503414539-28762-6-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Now that MPU lookups can return different results for v8M when the CPU is in secure vs non-secure state, we need to have separate MMU indexes; add the secure counterparts to the existing three M profile MMU indexes. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 19 +++++++++++++++++-- target/arm/helper.c | 9 ++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 24666baa..436ca0d 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2104,6 +2104,10 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, * Execution priority negative (this is like privileged, but the * MPU HFNMIENA bit means that it may have different access permission * check results to normal privileged code, so can't share a TLB). + * If the CPU supports the v8M Security Extension then there are also: + * Secure User + * Secure Privileged + * Secure, execution priority negative * * The ARMMMUIdx and the mmu index value used by the core QEMU TLB code * are not quite the same -- different CPU types (most notably M profile @@ -2141,6 +2145,9 @@ typedef enum ARMMMUIdx { ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M, ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M, ARMMMUIdx_MNegPri = 2 | ARM_MMU_IDX_M, + ARMMMUIdx_MSUser = 3 | ARM_MMU_IDX_M, + ARMMMUIdx_MSPriv = 4 | ARM_MMU_IDX_M, + ARMMMUIdx_MSNegPri = 5 | ARM_MMU_IDX_M, /* Indexes below here don't have TLBs and are used only for AT system * instructions or for the first stage of an S12 page table walk. */ @@ -2162,6 +2169,9 @@ typedef enum ARMMMUIdxBit { ARMMMUIdxBit_MUser = 1 << 0, ARMMMUIdxBit_MPriv = 1 << 1, ARMMMUIdxBit_MNegPri = 1 << 2, + ARMMMUIdxBit_MSUser = 1 << 3, + ARMMMUIdxBit_MSPriv = 1 << 4, + ARMMMUIdxBit_MSNegPri = 1 << 5, } ARMMMUIdxBit; #define MMU_USER_IDX 0 @@ -2187,7 +2197,8 @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx) case ARM_MMU_IDX_A: return mmu_idx & 3; case ARM_MMU_IDX_M: - return mmu_idx == ARMMMUIdx_MUser ? 0 : 1; + return (mmu_idx == ARMMMUIdx_MUser || mmu_idx == ARMMMUIdx_MSUser) + ? 0 : 1; default: g_assert_not_reached(); } @@ -2206,7 +2217,11 @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch) */ if ((env->v7m.exception > 0 && env->v7m.exception <= 3) || env->v7m.faultmask) { - return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri); + mmu_idx = ARMMMUIdx_MNegPri; + } + + if (env->v7m.secure) { + mmu_idx += ARMMMUIdx_MSUser; } return arm_to_core_mmu_idx(mmu_idx); diff --git a/target/arm/helper.c b/target/arm/helper.c index 887490a..1debebc 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -7037,6 +7037,9 @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) case ARMMMUIdx_MPriv: case ARMMMUIdx_MNegPri: case ARMMMUIdx_MUser: + case ARMMMUIdx_MSPriv: + case ARMMMUIdx_MSNegPri: + case ARMMMUIdx_MSUser: return 1; default: g_assert_not_reached(); @@ -7060,6 +7063,9 @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) case ARMMMUIdx_S1E3: case ARMMMUIdx_S1SE0: case ARMMMUIdx_S1SE1: + case ARMMMUIdx_MSPriv: + case ARMMMUIdx_MSNegPri: + case ARMMMUIdx_MSUser: return true; default: g_assert_not_reached(); @@ -7081,7 +7087,8 @@ static inline bool regime_translation_disabled(CPUARMState *env, (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) { case R_V7M_MPU_CTRL_ENABLE_MASK: /* Enabled, but not for HardFault and NMI */ - return mmu_idx == ARMMMUIdx_MNegPri; + return mmu_idx == ARMMMUIdx_MNegPri || + mmu_idx == ARMMMUIdx_MSNegPri; case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK: /* Enabled for all cases */ return false; From patchwork Tue Aug 22 15:08:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110670 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816052qge; Tue, 22 Aug 2017 08:09:02 -0700 (PDT) X-Received: by 10.223.179.211 with SMTP id x19mr683652wrd.7.1503414542650; Tue, 22 Aug 2017 08:09:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414542; cv=none; d=google.com; s=arc-20160816; b=NQLm4/5iqtJ4V7cOFoRL+tYgoGdmu+SejaLfJiz+kbG8Mf25zMR5uAJeb9bX3WmjPz Ef2ciJctyHhCrv8gg4lFVCS313em81QbQIk/6+INkb57ZzT+kZ+HRwpWsm8FfmeWaulN y10zMLcJfnpmTCL1jMCkZc1SQDUwz6VDdhIcGsj51q14KBdFV9d09W7zSfGFOp+ZK15P zfk3/f+0DftHU9a51ZdgLvDxTxg/niG7kJQTTauc7lOmE/EcJ3m1/0TLH5HdBSSRdsQi GoxwSzrHJVPq7R0PSA11VH4bBFgw4DKK2QxdgPgX/EzovT9TzJ4GTo0mn0+ZdsXDWlwm XWAA== 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=NNboBZotAIAVMSi6x36KmTEDEdhY00C2VbUCH+AYSQk=; b=X34X5lDqj/sWOWTO1BpLq2plWbPmOPPByhpIYJIcVBquFwgWP33HN3gKE6oolAhlp6 5kwlYmUOCkBuZQuXAP2ly9XWkcxDZT/VTn7Hplr/zOlJGZgurWQ2cpPgZcdEKngQCERl Mbteqf7pCqN2bDXaEgNr49Ro2iS6pU6C77AG850hVPFzyIuE0zCqsOKhtqeql06PIDJL 6xof6qN1AwWTp6ZirhYcl5BuOXPHNfcBE5Q3cn2ze6vSVUON3C5eIuRPGcZujTAiVyqF lTXanZnsx/qCuhv/GrZWEdQIYX6Sql09NlGAQ5lPw6XoE9P8oZ79fskrkz6ctLIyivvs 4SlA== 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 i192si81126wme.24.2017.08.22.08.09.02 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:02 -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 1dkAnd-0004fk-J2; Tue, 22 Aug 2017 16:09:01 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 06/20] target/arm: Make BASEPRI register banked for v8M Date: Tue, 22 Aug 2017 16:08:45 +0100 Message-Id: <1503414539-28762-7-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the BASEPRI register banked if v8M security extensions are enabled. Note that we do not yet implement the functionality of the new AIRCR.PRIS bit (which allows the effect of the NS copy of BASEPRI to be restricted). Signed-off-by: Peter Maydell --- target/arm/cpu.h | 14 +++++++++++++- hw/intc/armv7m_nvic.c | 4 ++-- target/arm/helper.c | 10 ++++++---- target/arm/machine.c | 3 ++- 4 files changed, 23 insertions(+), 8 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 436ca0d..0c28dfd 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -72,6 +72,18 @@ #define ARMV7M_EXCP_PENDSV 14 #define ARMV7M_EXCP_SYSTICK 15 +/* For M profile, some registers are banked secure vs non-secure; + * these are represented as a 2-element array where the first element + * is the non-secure copy and the second is the secure copy. + * When the CPU does not have implement the security extension then + * only the first element is used. + * This means that the copy for the current security state can be + * accessed via env->registerfield[env->v7m.secure] (whether the security + * extension is implemented or not). + */ +#define M_REG_NS 0 +#define M_REG_S 1 + /* ARM-specific interrupt pending bits. */ #define CPU_INTERRUPT_FIQ CPU_INTERRUPT_TGT_EXT_1 #define CPU_INTERRUPT_VIRQ CPU_INTERRUPT_TGT_EXT_2 @@ -409,7 +421,7 @@ typedef struct CPUARMState { struct { uint32_t other_sp; uint32_t vecbase; - uint32_t basepri; + uint32_t basepri[2]; uint32_t control; uint32_t ccr; /* Configuration and Control */ uint32_t cfsr; /* Configurable Fault Status */ diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index c0dbbad..2a41e5d 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -171,8 +171,8 @@ static inline int nvic_exec_prio(NVICState *s) running = -1; } else if (env->v7m.primask) { running = 0; - } else if (env->v7m.basepri > 0) { - running = env->v7m.basepri & nvic_gprio_mask(s); + } else if (env->v7m.basepri[env->v7m.secure] > 0) { + running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s); } else { running = NVIC_NOEXC_PRIO; /* lower than any possible priority */ } diff --git a/target/arm/helper.c b/target/arm/helper.c index 1debebc..1087f19 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8838,7 +8838,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) return env->v7m.primask; case 17: /* BASEPRI */ case 18: /* BASEPRI_MAX */ - return env->v7m.basepri; + return env->v7m.basepri[env->v7m.secure]; case 19: /* FAULTMASK */ return env->v7m.faultmask; default: @@ -8898,12 +8898,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) env->v7m.primask = val & 1; break; case 17: /* BASEPRI */ - env->v7m.basepri = val & 0xff; + env->v7m.basepri[env->v7m.secure] = val & 0xff; break; case 18: /* BASEPRI_MAX */ val &= 0xff; - if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0)) - env->v7m.basepri = val; + if (val != 0 && (val < env->v7m.basepri[env->v7m.secure] + || env->v7m.basepri[env->v7m.secure] == 0)) { + env->v7m.basepri[env->v7m.secure] = val; + } break; case 19: /* FAULTMASK */ env->v7m.faultmask = val & 1; diff --git a/target/arm/machine.c b/target/arm/machine.c index 745adae..8476efd 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -115,7 +115,7 @@ static const VMStateDescription vmstate_m = { .needed = m_needed, .fields = (VMStateField[]) { VMSTATE_UINT32(env.v7m.vecbase, ARMCPU), - VMSTATE_UINT32(env.v7m.basepri, ARMCPU), + VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.control, ARMCPU), VMSTATE_UINT32(env.v7m.ccr, ARMCPU), VMSTATE_UINT32(env.v7m.cfsr, ARMCPU), @@ -250,6 +250,7 @@ static const VMStateDescription vmstate_m_security = { .needed = m_security_needed, .fields = (VMStateField[]) { VMSTATE_UINT32(env.v7m.secure, ARMCPU), + VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU), VMSTATE_END_OF_LIST() } }; From patchwork Tue Aug 22 15:08:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110671 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816076qge; Tue, 22 Aug 2017 08:09:03 -0700 (PDT) X-Received: by 10.25.215.104 with SMTP id o101mr365957lfg.24.1503414543417; Tue, 22 Aug 2017 08:09:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414543; cv=none; d=google.com; s=arc-20160816; b=AJJTdabVuoDFPIBeCl1EPl4eg7pyraujSryUIbnFlaQhl5UbaJuLDbb5ok01cfOxlm C2ccCBvVBmE+P9Xo0NwARJl1Oc5ci1USn0cLAwJADAAyww0yqunAUnT6y7OPN7pJBqAR /PaG9Uv03liUYsyb587w++uWvJw3yDS6Eg0ahmWzAcSJppdipHwsAu9wIq/nLiOLqMZp v9qsXfBwFD41U1Amip/NKIuwpShCrxSqZ7lTQ0FWFJJeyJ3CEU/MmG0D8shbLYn4qy8+ sT0yw29ivL0gUChhIXOQjUFxJOMs2Ls94wOiBIu6sWdXFc0d/poIC6FulFNwhafXTC6F lyvg== 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=i35px/cVwmZI7aAmHE1o6idhO6qXvbvULgKf75+1LEk=; b=nIBx7Ab7L0K0zSBvm2GHhvIpe4tQNbnu/nI+60TvHKYymPkykWW0/dSrdnlRZFotyt rs8PAXMin30w3P543T2S3FjpcBGKGcUXfZmpXoqPBFmK0dApxmlSRlV6IpycPKQ61n9l EXImgOTPI3Bys0LR1DGBX1D93L5bKS9vSLKgHMEwUdj2GUeBj/9C7qd9+8xqLl3wSngT wZ9oovUugtxtO7h9FrT3lTIXZPexrPgeuq/MiGnfh1wTKuemkrwIIVJ8cFsaPYZjmdkn w0+5xJ6BkwZuukvcEePBYtoh1rshUIUDtj8eiJWmcwbvI+EEFXyDjNokskOD1JjG5wlc iiiA== 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 u8si6071440ljd.174.2017.08.22.08.09.03 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:03 -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 1dkAne-0004fz-9a; Tue, 22 Aug 2017 16:09:02 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 07/20] target/arm: Make PRIMASK register banked for v8M Date: Tue, 22 Aug 2017 16:08:46 +0100 Message-Id: <1503414539-28762-8-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the PRIMASK register banked if v8M security extensions are enabled. Note that we do not yet implement the functionality of the new AIRCR.PRIS bit (which allows the effect of the NS copy of PRIMASK to be restricted). Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 +- hw/intc/armv7m_nvic.c | 2 +- target/arm/helper.c | 4 ++-- target/arm/machine.c | 9 +++++++-- 4 files changed, 11 insertions(+), 6 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 0c28dfd..fee337b 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -431,7 +431,7 @@ typedef struct CPUARMState { uint32_t bfar; /* BusFault Address */ unsigned mpu_ctrl; /* MPU_CTRL */ int exception; - uint32_t primask; + uint32_t primask[2]; uint32_t faultmask; uint32_t secure; /* Is CPU in Secure state? (not guest visible) */ } v7m; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 2a41e5d..a654792 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -169,7 +169,7 @@ static inline int nvic_exec_prio(NVICState *s) if (env->v7m.faultmask) { running = -1; - } else if (env->v7m.primask) { + } 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); diff --git a/target/arm/helper.c b/target/arm/helper.c index 1087f19..c0a6dbd 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8835,7 +8835,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ? env->regs[13] : env->v7m.other_sp; case 16: /* PRIMASK */ - return env->v7m.primask; + return env->v7m.primask[env->v7m.secure]; case 17: /* BASEPRI */ case 18: /* BASEPRI_MAX */ return env->v7m.basepri[env->v7m.secure]; @@ -8895,7 +8895,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) } break; case 16: /* PRIMASK */ - env->v7m.primask = val & 1; + env->v7m.primask[env->v7m.secure] = val & 1; break; case 17: /* BASEPRI */ env->v7m.basepri[env->v7m.secure] = val & 0xff; diff --git a/target/arm/machine.c b/target/arm/machine.c index 8476efd..6f0f6c9 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -103,7 +103,7 @@ static const VMStateDescription vmstate_m_faultmask_primask = { .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_UINT32(env.v7m.faultmask, ARMCPU), - VMSTATE_UINT32(env.v7m.primask, ARMCPU), + VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU), VMSTATE_END_OF_LIST() } }; @@ -251,6 +251,7 @@ static const VMStateDescription vmstate_m_security = { .fields = (VMStateField[]) { VMSTATE_UINT32(env.v7m.secure, ARMCPU), VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU), + VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU), VMSTATE_END_OF_LIST() } }; @@ -271,9 +272,13 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size, * differences are that the T bit is not in the same place, the * primask/faultmask info may be in the CPSR I and F bits, and * we do not want the mode bits. + * We know that this cleanup happened before v8M, so there + * is no complication with banked primask/faultmask. */ uint32_t newval = val; + assert(!arm_feature(env, ARM_FEATURE_M_SECURITY)); + newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE); if (val & CPSR_T) { newval |= XPSR_T; @@ -287,7 +292,7 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size, env->v7m.faultmask = 1; } if (val & CPSR_I) { - env->v7m.primask = 1; + env->v7m.primask[M_REG_NS] = 1; } val = newval; } From patchwork Tue Aug 22 15:08:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110672 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816084qge; Tue, 22 Aug 2017 08:09:04 -0700 (PDT) X-Received: by 10.223.175.8 with SMTP id z8mr760606wrc.16.1503414544012; Tue, 22 Aug 2017 08:09:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414544; cv=none; d=google.com; s=arc-20160816; b=q9HLEGIB+Q6u8NhmOZnrVTt501bnQGFIaduJ4l7ByhicyMjLjgViSUEdmJUdC2MS28 sw63hLwi77+iZkCqRqgKNt9CECq3TLHD4ohIyMnWpD70+x46wTs0H2BEviedEo+Av94B hs7FvfrM9cB7aWXY45c3UxT7ozYUAinOTrJIODfgpZbAd6R0Vu9XCTcI8yYaKboFCAkG luaQrc4/kCK9uoErYeFELJWvSg7pY2IWsItWU1m+ODXYVn4OrC0rI/mUF7VozTYOlo9L Zv51w6EiacmFOs/GR0BEg1tdnJzuYHKfL8U0FjOdxkekFoDybKUWs/dikOa+jh9W25iE M+ig== 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=JimyCQvoa7E6JwMzt2RYVcOPVmWADuz+2q+QxWl3IKA=; b=aQK3IV/X3P+hA7jlANqbX+5UXtwt3VGVD2fiyAl/66HC1BY0QamQQIq5rJtsZL08t3 31PcgHRYjddUHfWQUtAvBEvHgiHtT5cFNBVhLS9xnCfis42XBDvo08I0G06F1qLcPq4R 8jIGJPHLVqqec/ID9aNCjCUGSditr3mu5QEi4T5E9vlaH5YYBOrHg2Lp0phfPOz+OJFb GlqUZ5JuTL+pX0c66bo43wmxb9wSNZJBuvjNSYyO2g0265WQGfATbnoJESzOD/+zrMLO zqY/fVUZBTFw3vQvcpfHdB64p7TSIeEzjqWxOYe5d5lb3OQiG5EV+B22Mt7ikwLf5WLh bsHQ== 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 k72si54639wmh.193.2017.08.22.08.09.03 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:04 -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 1dkAnf-0004gf-2e; Tue, 22 Aug 2017 16:09:03 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 08/20] target/arm: Make FAULTMASK register banked for v8M Date: Tue, 22 Aug 2017 16:08:47 +0100 Message-Id: <1503414539-28762-9-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the FAULTMASK register banked if v8M security extensions are enabled. Note that we do not yet implement the functionality of the new AIRCR.PRIS bit (which allows the effect of the NS copy of FAULTMASK to be restricted). This patch includes the code to determine for v8M which copy of FAULTMASK should be updated on exception exit; further changes will be required to the exception exit code in general to support v8M, so this is just a small piece of that. The v8M ARM ARM introduces a notation where individual paragraphs are labelled with R (for rule) or I (for information) followed by a random group of subscript letters. In comments where we want to refer to a particular part of the manual we use this convention, which should be more stable across document revisions than using section or page numbers. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 14 ++++++++++++-- hw/intc/armv7m_nvic.c | 9 ++++++++- target/arm/helper.c | 20 ++++++++++++++++---- target/arm/machine.c | 5 +++-- 4 files changed, 39 insertions(+), 9 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/target/arm/cpu.h b/target/arm/cpu.h index fee337b..edd4c9e 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -432,7 +432,7 @@ typedef struct CPUARMState { unsigned mpu_ctrl; /* MPU_CTRL */ int exception; uint32_t primask[2]; - uint32_t faultmask; + uint32_t faultmask[2]; uint32_t secure; /* Is CPU in Secure state? (not guest visible) */ } v7m; @@ -1443,6 +1443,16 @@ void armv7m_nvic_acknowledge_irq(void *opaque); * (Ignoring -1, this is the same as the RETTOBASE value before completion.) */ int armv7m_nvic_complete_irq(void *opaque, int irq); +/** + * armv7m_nvic_raw_execution_priority: return the raw execution priority + * @opaque: the NVIC + * + * Returns: the raw execution priority as defined by the v8M architecture. + * This is the execution priority minus the effects of AIRCR.PRIS, + * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting. + * (v8M ARM ARM I_PKLD.) + */ +int armv7m_nvic_raw_execution_priority(void *opaque); /* Interface for defining coprocessor registers. * Registers are defined in tables of arm_cp_reginfo structs @@ -2228,7 +2238,7 @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch) * we're in a HardFault or NMI handler. */ if ((env->v7m.exception > 0 && env->v7m.exception <= 3) - || env->v7m.faultmask) { + || env->v7m.faultmask[env->v7m.secure]) { mmu_idx = ARMMMUIdx_MNegPri; } diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index a654792..babdc3b 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -167,7 +167,7 @@ static inline int nvic_exec_prio(NVICState *s) CPUARMState *env = &s->cpu->env; int running; - if (env->v7m.faultmask) { + if (env->v7m.faultmask[env->v7m.secure]) { running = -1; } else if (env->v7m.primask[env->v7m.secure]) { running = 0; @@ -187,6 +187,13 @@ bool armv7m_nvic_can_take_pending_exception(void *opaque) return nvic_exec_prio(s) > nvic_pending_prio(s); } +int armv7m_nvic_raw_execution_priority(void *opaque) +{ + NVICState *s = opaque; + + return s->exception_prio; +} + /* caller must call nvic_irq_update() after this */ static void set_prio(NVICState *s, unsigned irq, uint8_t prio) { diff --git a/target/arm/helper.c b/target/arm/helper.c index c0a6dbd..b8f3b23 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6171,8 +6171,20 @@ static void do_v7m_exception_exit(ARMCPU *cpu) } if (env->v7m.exception != ARMV7M_EXCP_NMI) { - /* Auto-clear FAULTMASK on return from other than NMI */ - env->v7m.faultmask = 0; + /* Auto-clear FAULTMASK on return from other than NMI. + * If the security extension is implemented then this only + * happens if the raw execution priority is >= 0; the + * value of the ES bit in the exception return value indicates + * which security state's faultmask to clear. (v8M ARM ARM R_KBNF.) + */ + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + int es = type & 1; + if (armv7m_nvic_raw_execution_priority(env->nvic) >= 0) { + env->v7m.faultmask[es] = 0; + } + } else { + env->v7m.faultmask[M_REG_NS] = 0; + } } switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception)) { @@ -8840,7 +8852,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) case 18: /* BASEPRI_MAX */ return env->v7m.basepri[env->v7m.secure]; case 19: /* FAULTMASK */ - return env->v7m.faultmask; + return env->v7m.faultmask[env->v7m.secure]; default: qemu_log_mask(LOG_GUEST_ERROR, "Attempt to read unknown special" " register %d\n", reg); @@ -8908,7 +8920,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) } break; case 19: /* FAULTMASK */ - env->v7m.faultmask = val & 1; + env->v7m.faultmask[env->v7m.secure] = val & 1; break; case 20: /* CONTROL */ /* Writing to the SPSEL bit only has an effect if we are in diff --git a/target/arm/machine.c b/target/arm/machine.c index 6f0f6c9..bd7aba1 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -102,7 +102,7 @@ static const VMStateDescription vmstate_m_faultmask_primask = { .version_id = 1, .minimum_version_id = 1, .fields = (VMStateField[]) { - VMSTATE_UINT32(env.v7m.faultmask, ARMCPU), + VMSTATE_UINT32(env.v7m.faultmask[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU), VMSTATE_END_OF_LIST() } @@ -252,6 +252,7 @@ static const VMStateDescription vmstate_m_security = { VMSTATE_UINT32(env.v7m.secure, ARMCPU), VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU), + VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU), VMSTATE_END_OF_LIST() } }; @@ -289,7 +290,7 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size, * transferred using the vmstate_m_faultmask_primask subsection. */ if (val & CPSR_F) { - env->v7m.faultmask = 1; + env->v7m.faultmask[M_REG_NS] = 1; } if (val & CPSR_I) { env->v7m.primask[M_REG_NS] = 1; From patchwork Tue Aug 22 15:08:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110674 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816104qge; Tue, 22 Aug 2017 08:09:05 -0700 (PDT) X-Received: by 10.46.4.27 with SMTP id 27mr424397lje.113.1503414545339; Tue, 22 Aug 2017 08:09:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414545; cv=none; d=google.com; s=arc-20160816; b=uvVXcYpTGMXb0mn43EPcZi64V7zqcLvIyxl4ngfgtIjzxgMWOPGsyNSQa/Y+/StheE +LQeC5xO9iDb0CoZNU3kWdKQYx97iZ4n786Dja2PVWg0bmWXMC5T9dZ09ftDvAfANifQ Tx3XDsUsOfRYe43Ozk4SqUZNO016S5ky4KAxI1TiMGlTVjZw8ItUSaK7Qa/Yhntn6IXD mcemWSbD4oFM6tuaXa/dPAWejbIhiO4x6AmBwpa0JQzBpGXw+ScR7en0lu0ABiTsWQYd N6u1jZpETuaKagh+mczsZXTL0ncNb2WZqZtk1Xgeadc7FhDEAiVJX1r+BkCCRLxsVpT9 T5xw== 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=3Y4ypGZJ2YHu+je89n0kOunR4qXIJZnjZaL0J37nNvU=; b=0gs6EYx6kLJ/8OllE92oWMCm2XGYj8hHANYsv7mIIwURubqr3H2HwACKxoWnFSmlqe /0bN1HvAgFquKuwUR1+26SgwEGLO6AjAdJim3S4ADkFlxRU1BKELBVf8lHnHs8l4ErMh ED2vf4GLBJxO8bpBD6FPmsjfr2QyrtxiNb5pO1I04Bb1slG9fsccG48VVWtZbsBZhin9 9mZZuF93fPHzA4YrT5egOojd3rUB2d9hsfZUOj+ZKRr+h9pE2GRPwck89ccwjINoBnQ2 ojmXaJTWx6mctzhfqaumJmB4H4VlbgzN8WEPuLeH4vWSI7Mq3jsernDtUwsf1kqh58HO ExRQ== 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 p19si6086733lfj.286.2017.08.22.08.09.04 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:05 -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 1dkAnf-0004h9-Q5; Tue, 22 Aug 2017 16:09:03 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 09/20] target/arm: Make CONTROL register banked for v8M Date: Tue, 22 Aug 2017 16:08:48 +0100 Message-Id: <1503414539-28762-10-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the CONTROL register banked if v8M security extensions are enabled. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 5 +++-- target/arm/helper.c | 21 +++++++++++---------- target/arm/machine.c | 3 ++- target/arm/translate.c | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/cpu.h b/target/arm/cpu.h index edd4c9e..e922d1f 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -422,7 +422,7 @@ typedef struct CPUARMState { uint32_t other_sp; uint32_t vecbase; uint32_t basepri[2]; - uint32_t control; + uint32_t control[2]; uint32_t ccr; /* Configuration and Control */ uint32_t cfsr; /* Configurable Fault Status */ uint32_t hfsr; /* HardFault Status */ @@ -1682,7 +1682,8 @@ static inline bool arm_v7m_is_handler_mode(CPUARMState *env) static inline int arm_current_el(CPUARMState *env) { if (arm_feature(env, ARM_FEATURE_M)) { - return arm_v7m_is_handler_mode(env) || !(env->v7m.control & 1); + return arm_v7m_is_handler_mode(env) || + !(env->v7m.control[env->v7m.secure] & 1); } if (is_a64(env)) { diff --git a/target/arm/helper.c b/target/arm/helper.c index b8f3b23..8e74b10 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6053,14 +6053,15 @@ static uint32_t v7m_pop(CPUARMState *env) static void switch_v7m_sp(CPUARMState *env, bool new_spsel) { uint32_t tmp; - bool old_spsel = env->v7m.control & R_V7M_CONTROL_SPSEL_MASK; + uint32_t old_control = env->v7m.control[env->v7m.secure]; + bool old_spsel = old_control & R_V7M_CONTROL_SPSEL_MASK; if (old_spsel != new_spsel) { tmp = env->v7m.other_sp; env->v7m.other_sp = env->regs[13]; env->regs[13] = tmp; - env->v7m.control = deposit32(env->v7m.control, + env->v7m.control[env->v7m.secure] = deposit32(old_control, R_V7M_CONTROL_SPSEL_SHIFT, R_V7M_CONTROL_SPSEL_LENGTH, new_spsel); } @@ -6414,7 +6415,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) } lr = 0xfffffff1; - if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) { + if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) { lr |= 4; } if (!arm_v7m_is_handler_mode(env)) { @@ -8832,7 +8833,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) return xpsr_read(env) & mask; break; case 20: /* CONTROL */ - return env->v7m.control; + return env->v7m.control[env->v7m.secure]; } if (el == 0) { @@ -8841,10 +8842,10 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) switch (reg) { case 8: /* MSP */ - return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ? + return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ? env->v7m.other_sp : env->regs[13]; case 9: /* PSP */ - return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ? + return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ? env->regs[13] : env->v7m.other_sp; case 16: /* PRIMASK */ return env->v7m.primask[env->v7m.secure]; @@ -8893,14 +8894,14 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) } break; case 8: /* MSP */ - if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) { + if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) { env->v7m.other_sp = val; } else { env->regs[13] = val; } break; case 9: /* PSP */ - if (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) { + if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) { env->regs[13] = val; } else { env->v7m.other_sp = val; @@ -8931,8 +8932,8 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val) if (!arm_v7m_is_handler_mode(env)) { switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0); } - env->v7m.control &= ~R_V7M_CONTROL_NPRIV_MASK; - env->v7m.control |= val & R_V7M_CONTROL_NPRIV_MASK; + env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK; + env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK; break; default: qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special" diff --git a/target/arm/machine.c b/target/arm/machine.c index bd7aba1..2cd64c5 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -116,7 +116,7 @@ static const VMStateDescription vmstate_m = { .fields = (VMStateField[]) { VMSTATE_UINT32(env.v7m.vecbase, ARMCPU), VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU), - VMSTATE_UINT32(env.v7m.control, ARMCPU), + VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.ccr, ARMCPU), VMSTATE_UINT32(env.v7m.cfsr, ARMCPU), VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), @@ -253,6 +253,7 @@ static const VMStateDescription vmstate_m_security = { VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU), + VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU), VMSTATE_END_OF_LIST() } }; diff --git a/target/arm/translate.c b/target/arm/translate.c index dea0a6f..6aa2d7c 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -12241,7 +12241,7 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, if (xpsr & XPSR_EXCP) { mode = "handler"; } else { - if (env->v7m.control & R_V7M_CONTROL_NPRIV_MASK) { + if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) { mode = "unpriv-thread"; } else { mode = "priv-thread"; From patchwork Tue Aug 22 15:08: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: 110675 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816115qge; Tue, 22 Aug 2017 08:09:05 -0700 (PDT) X-Received: by 10.28.101.5 with SMTP id z5mr681022wmb.136.1503414545504; Tue, 22 Aug 2017 08:09:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414545; cv=none; d=google.com; s=arc-20160816; b=r5vkj/rcyFqJuD9EFkbiqYiCrjPXLn3rtgoCnVm+mjrvk2/KfvEtEeEBI2l3fRMAIb DvU1dN59ZD18Q3DHPnJAOT1zm7kVJnGx9QPRVVIHkOFEUG1j3KxQqlt5HRigF8hGQ9V0 GMRjacoPEl9oMG+OctlzUNmE71RQ+fxgZEzrpkNn1JeaRvI8qvwPf3ibuxqwe5KmxeSI Hazi5iNcHA5mvClov/afIRiJraS0mFL1sQ4Pe/799swAr+kURhKyPnOY4/BjYZ0pFr0K StXthINxWQMLauIuRV3lhZZN75oJM+i3c+N6xQzmrVvu8Mei79ax8mhxpJH9HnUK7N4V uHYQ== 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=NVR8daCllQZEGcqq9pMnjnFCUcSOnndLSUTX08xOwWw=; b=ZH8pTHpXp+DsVZZYjnePWfCIaoXR1OeG3FP9B75K5gXyiCeG1Ta9DF+3a5h1/O68QN bGawNCbBu993fBkQKhNH6EjqjzW+VwE8AbjozRpqzzwVUz6Y1YWkSV67aIfHK9GT3C/L 3jm/iEu6KJn5VO2k9rCc0EsUr0OPbpr9PvEJfCPUpAvu+NFlGcCI02DwLnA7SSRErza4 +lnz7OGTxjwBNpAG4zazeAmB8XYCBFNM90adB9GishaAIFzxOs4vjKgFSyzn7ZhxW3bj JTGJb887L3GFHu6PeuT2VSzBwjFojHC7ddtKMGF3tRg9Zqw1zMx4LNLGuojdW19XQPEi tDMQ== 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 78si65966wmp.183.2017.08.22.08.09.05 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:05 -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 1dkAng-0004ho-IY; Tue, 22 Aug 2017 16:09:04 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 10/20] nvic: Add NS alias SCS region Date: Tue, 22 Aug 2017 16:08:49 +0100 Message-Id: <1503414539-28762-11-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> For v8M the range 0xe002e000..0xe002efff is an alias region which for secure accesses behaves like a NonSecure access to the main SCS region. (For nonsecure accesses including when the security extension is not implemented, it is RAZ/WI.) Signed-off-by: Peter Maydell --- include/hw/intc/armv7m_nvic.h | 1 + hw/intc/armv7m_nvic.c | 66 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) -- 2.7.4 diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h index 1d145fb..1a4cce7 100644 --- a/include/hw/intc/armv7m_nvic.h +++ b/include/hw/intc/armv7m_nvic.h @@ -50,6 +50,7 @@ typedef struct NVICState { int exception_prio; /* group prio of the highest prio active exception */ MemoryRegion sysregmem; + MemoryRegion sysreg_ns_mem; MemoryRegion container; uint32_t num_irq; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index babdc3b..2b0b328 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -1040,6 +1040,47 @@ static const MemoryRegionOps nvic_sysreg_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size, + MemTxAttrs attrs) +{ + if (attrs.secure) { + /* S accesses to the alias act like NS accesses to the real region */ + attrs.secure = 0; + return nvic_sysreg_write(opaque, addr, value, size, attrs); + } else { + /* NS attrs are RAZ/WI for privileged, and BusFault for user */ + if (attrs.user) { + return MEMTX_ERROR; + } + return MEMTX_OK; + } +} + +static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr, + uint64_t *data, unsigned size, + MemTxAttrs attrs) +{ + if (attrs.secure) { + /* S accesses to the alias act like NS accesses to the real region */ + attrs.secure = 0; + return nvic_sysreg_read(opaque, addr, data, size, attrs); + } else { + /* NS attrs are RAZ/WI for privileged, and BusFault for user */ + if (attrs.user) { + return MEMTX_ERROR; + } + *data = 0; + return MEMTX_OK; + } +} + +static const MemoryRegionOps nvic_sysreg_ns_ops = { + .read_with_attrs = nvic_sysreg_ns_read, + .write_with_attrs = nvic_sysreg_ns_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + static int nvic_post_load(void *opaque, int version_id) { NVICState *s = opaque; @@ -1141,6 +1182,7 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp) NVICState *s = NVIC(dev); SysBusDevice *systick_sbd; Error *err = NULL; + int regionlen; s->cpu = ARM_CPU(qemu_get_cpu(0)); assert(s->cpu); @@ -1173,8 +1215,23 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp) * 0xd00..0xd3c - SCS registers * 0xd40..0xeff - Reserved or Not implemented * 0xf00 - STIR + * + * Some registers within this space are banked between security states. + * In v8M there is a second range 0xe002e000..0xe002efff which is the + * NonSecure alias SCS; secure accesses to this behave like NS accesses + * to the main SCS range, and non-secure accesses (including when + * the security extension is not implemented) are RAZ/WI. + * Note that both the main SCS range and the alias range are defined + * to be exempt from memory attribution (R_BLJT) and so the memory + * transaction attribute always matches the current CPU security + * state (attrs.secure == env->v7m.secure). In the nvic_sysreg_ns_ops + * wrappers we change attrs.secure to indicate the NS access; so + * generally code determining which banked register to use should + * use attrs.secure; code determining actual behaviour of the system + * should use env->v7m.secure. */ - memory_region_init(&s->container, OBJECT(s), "nvic", 0x1000); + regionlen = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? 0x21000 : 0x1000; + memory_region_init(&s->container, OBJECT(s), "nvic", regionlen); /* The system register region goes at the bottom of the priority * stack as it covers the whole page. */ @@ -1185,6 +1242,13 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp) sysbus_mmio_get_region(systick_sbd, 0), 1); + if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) { + memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s), + &nvic_sysreg_ns_ops, s, + "nvic_sysregs_ns", 0x1000); + memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem); + } + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container); } From patchwork Tue Aug 22 15:08:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110676 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816152qge; Tue, 22 Aug 2017 08:09:06 -0700 (PDT) X-Received: by 10.28.109.27 with SMTP id i27mr556025wmc.173.1503414546538; Tue, 22 Aug 2017 08:09:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414546; cv=none; d=google.com; s=arc-20160816; b=0wW2Evps6hUY4P4NVTMJkYC+JwvaF/BW8ZS1zarTE/Gbi/axqX3kS0hCBycilpAIfw YGerPPHPwYFNw4/5OA5sizRSzqSCAvLmn0D7WW3HxEtlLcr50lHYOA+NDdPWon+TDXQ/ xotUNP4r9/BlXAT8i0jFenPXmfY6T7wnMdsB7LRdp5hGgZ/8SVxq3KY07qrhuke+LgTc 8MPNAvXwBALJ4iSEmcgDMHs+c4S4GlNYt3RGLLyu0aWRs36O+Ytnj3HgXnKI5/J12eX4 jYmUMimCnAR9ceiSdeCKKNFQCyhFp5QP4qy7ukZI39dkOWwoEo/ZVYy6f5fW+DSRfCZq JuIA== 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=VnE4ZWZJUHQ3b/HKyV0FCKWJeqQj1GV90M8zC48TM6U=; b=BQuY//92cdjcmAQ1DR7IbOE1mHUm1RX/jZFe8YY1wG0hrqcvKCexLBDyTar9G0/0MG qO0GVHRTTJ9icFRgREJzNyao1vdyASGDj+vO6fMK3sRrwBLDbbs96I9WltwvEtdYwLud qchq5CgeRQaHd2yYNG9MK8G54R2VoBeMdJ9rlNtJSLBeupqCm2I5U65749dxy5A2z33s 39d3dpwB8H39uQ8suf+fBAxpajgHWjSBPjQDPW3zQPakHjSfmWpfDlnMo27s/OP4oQJq 19amQBRAXCYgD+eZPQLE9roMnrQxVLqTch/Dfm6zAP3eSpgZzUG1YSgl9kwIk0Hd7wGD Ky5Q== 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 w77si66465wmd.204.2017.08.22.08.09.06 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:06 -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 1dkAnh-0004i6-H2; Tue, 22 Aug 2017 16:09:05 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 11/20] target/arm: Make VTOR register banked for v8M Date: Tue, 22 Aug 2017 16:08:50 +0100 Message-Id: <1503414539-28762-12-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the VTOR register banked if v8M security extensions are enabled. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 +- hw/intc/armv7m_nvic.c | 13 +++++++------ target/arm/helper.c | 2 +- target/arm/machine.c | 3 ++- 4 files changed, 11 insertions(+), 9 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/cpu.h b/target/arm/cpu.h index e922d1f..d0b0936 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -420,7 +420,7 @@ typedef struct CPUARMState { struct { uint32_t other_sp; - uint32_t vecbase; + uint32_t vecbase[2]; uint32_t basepri[2]; uint32_t control[2]; uint32_t ccr; /* Configuration and Control */ diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 2b0b328..3a1f02d 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -403,7 +403,7 @@ static void set_irq_level(void *opaque, int n, int level) } } -static uint32_t nvic_readl(NVICState *s, uint32_t offset) +static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) { ARMCPU *cpu = s->cpu; uint32_t val; @@ -441,7 +441,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset) /* ISRPREEMPT not implemented */ return val; case 0xd08: /* Vector Table Offset. */ - return cpu->env.v7m.vecbase; + return cpu->env.v7m.vecbase[attrs.secure]; case 0xd0c: /* Application Interrupt/Reset Control. */ return 0xfa050000 | (s->prigroup << 8); case 0xd10: /* System Control. */ @@ -617,7 +617,8 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset) } } -static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) +static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, + MemTxAttrs attrs) { ARMCPU *cpu = s->cpu; @@ -638,7 +639,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value) } break; case 0xd08: /* Vector Table Offset. */ - cpu->env.v7m.vecbase = value & 0xffffff80; + cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80; break; case 0xd0c: /* Application Interrupt/Reset Control. */ if ((value >> 16) == 0x05fa) { @@ -944,7 +945,7 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, break; default: if (size == 4) { - val = nvic_readl(s, offset); + val = nvic_readl(s, offset, attrs); } else { qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read of size %d at offset 0x%x\n", @@ -1025,7 +1026,7 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, return MEMTX_OK; } if (size == 4) { - nvic_writel(s, offset, value); + nvic_writel(s, offset, value, attrs); return MEMTX_OK; } qemu_log_mask(LOG_GUEST_ERROR, diff --git a/target/arm/helper.c b/target/arm/helper.c index 8e74b10..b1bb507 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6072,7 +6072,7 @@ static uint32_t arm_v7m_load_vector(ARMCPU *cpu) CPUState *cs = CPU(cpu); CPUARMState *env = &cpu->env; MemTxResult result; - hwaddr vec = env->v7m.vecbase + env->v7m.exception * 4; + hwaddr vec = env->v7m.vecbase[env->v7m.secure] + env->v7m.exception * 4; uint32_t addr; addr = address_space_ldl(cs->as, vec, diff --git a/target/arm/machine.c b/target/arm/machine.c index 2cd64c5..cd6b6af 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -114,7 +114,7 @@ static const VMStateDescription vmstate_m = { .minimum_version_id = 4, .needed = m_needed, .fields = (VMStateField[]) { - VMSTATE_UINT32(env.v7m.vecbase, ARMCPU), + 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), @@ -254,6 +254,7 @@ static const VMStateDescription vmstate_m_security = { VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU), + VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU), VMSTATE_END_OF_LIST() } }; From patchwork Tue Aug 22 15:08:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110677 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816177qge; Tue, 22 Aug 2017 08:09:07 -0700 (PDT) X-Received: by 10.25.161.209 with SMTP id k200mr454834lfe.132.1503414547469; Tue, 22 Aug 2017 08:09:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414547; cv=none; d=google.com; s=arc-20160816; b=MBnnd5c6e77w27YZw8JuKM/tQnpr6CvKEpjdXC95WT0tWQ2nYxJQbvnRgaDs/gaJWh +qXCMokxDrglZW9F2RppT6+E9GYuleyNdg1fjkJHLLBOVql/1zlZlpYBQOKBF9q4APUD Ww8e6wmaRLZrgXaI6kpQ4R0UpL59/iw/zy47m66J1m+GhUcgDf+4KD4REz9dJNROB7pp E7cwUQ/UP3dBAD4TrtZz1rMfqtcBi1EXJXkB5KgMWbiTTypj29rwMVFINEvrD8CS2Gps RelJujABez27lv3yoMCtHNP5UyWWusWrvibxemTvsFa/rdhqZpMKKoa4D7ozXSqLCHOw DtKQ== 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=n2uaVqbqUq5OlMflr5hz4owWhpu67v/nqAMNitJz9KA=; b=KWtlsAoCo6KbC3Hkga9odAMCBVkup1rFcRze6UWvZEYS9wNspH13XZIX+FjIWnMeev 3KXFxPIeurST9S5issmm7jqnjKuGliqAASP4gFEQPolZxu8YcKi1+3tIECjXwQnSq6xw +M1lpk3JjgqZxNmwCTHOHvDbBDZq3/0dq2lCN5m3fspXipvK6wgSHjhQeGajkSTvD4+d /MqK8w8peOccrqjlbFHsEDat8Bh7GLbGk9f4PUawcPQtaVJM4oEQEWTG8j42H4ixA1JB doU9/lXlD2Q6oTu+y+wpckb1aNNPwA0/itklJrVBXCQWC8wbQb2cUURxSfWW7FnotGRn 5WNA== 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 o10si1982944lfc.55.2017.08.22.08.09.07 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:07 -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 1dkAni-0004in-99; Tue, 22 Aug 2017 16:09:06 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 12/20] target/arm: Make MPU_MAIR0, MPU_MAIR1 registers banked for v8M Date: Tue, 22 Aug 2017 16:08:51 +0100 Message-Id: <1503414539-28762-13-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security extensions are enabled. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 4 ++-- hw/intc/armv7m_nvic.c | 8 ++++---- target/arm/cpu.c | 4 ++-- target/arm/machine.c | 6 ++++-- 4 files changed, 12 insertions(+), 10 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d0b0936..2f59828 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -545,8 +545,8 @@ typedef struct CPUARMState { */ uint32_t *rbar; uint32_t *rlar; - uint32_t mair0; - uint32_t mair1; + uint32_t mair0[2]; + uint32_t mair1[2]; } pmsav8; void *nvic; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 3a1f02d..e98eb95 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -604,12 +604,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } - return cpu->env.pmsav8.mair0; + return cpu->env.pmsav8.mair0[attrs.secure]; case 0xdc4: /* MPU_MAIR1 */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } - return cpu->env.pmsav8.mair1; + return cpu->env.pmsav8.mair1[attrs.secure]; default: bad_offset: qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset); @@ -826,7 +826,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, } if (cpu->pmsav7_dregion) { /* Register is RES0 if no MPU regions are implemented */ - cpu->env.pmsav8.mair0 = value; + cpu->env.pmsav8.mair0[attrs.secure] = value; } /* We don't need to do anything else because memory attributes * only affect cacheability, and we don't implement caching. @@ -838,7 +838,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, } if (cpu->pmsav7_dregion) { /* Register is RES0 if no MPU regions are implemented */ - cpu->env.pmsav8.mair1 = value; + cpu->env.pmsav8.mair1[attrs.secure] = value; } /* We don't need to do anything else because memory attributes * only affect cacheability, and we don't implement caching. diff --git a/target/arm/cpu.c b/target/arm/cpu.c index ae866be..ae8af19 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -249,8 +249,8 @@ static void arm_cpu_reset(CPUState *s) } } env->pmsav7.rnr = 0; - env->pmsav8.mair0 = 0; - env->pmsav8.mair1 = 0; + memset(env->pmsav8.mair0, 0, sizeof(env->pmsav8.mair0)); + memset(env->pmsav8.mair1, 0, sizeof(env->pmsav8.mair1)); } set_flush_to_zero(1, &env->vfp.standard_fp_status); diff --git a/target/arm/machine.c b/target/arm/machine.c index cd6b6af..414a879 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -229,8 +229,8 @@ static const VMStateDescription vmstate_pmsav8 = { vmstate_info_uint32, uint32_t), VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0, vmstate_info_uint32, uint32_t), - VMSTATE_UINT32(env.pmsav8.mair0, ARMCPU), - VMSTATE_UINT32(env.pmsav8.mair1, ARMCPU), + VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU), + VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU), VMSTATE_END_OF_LIST() } }; @@ -255,6 +255,8 @@ static const VMStateDescription vmstate_m_security = { VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU), + VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU), + VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU), VMSTATE_END_OF_LIST() } }; From patchwork Tue Aug 22 15:08:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110678 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816195qge; Tue, 22 Aug 2017 08:09:08 -0700 (PDT) X-Received: by 10.223.170.136 with SMTP id h8mr725096wrc.49.1503414548220; Tue, 22 Aug 2017 08:09:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414548; cv=none; d=google.com; s=arc-20160816; b=h/lW/qtUZEe4wzKr2RVzsaP81ErlmZtwcHyGDn0djMlkLReUoimM3oSscxStXGd1AE KCttrsLf6OhOKPj/byURee4nWVYy8+W7YHd0G6UB8FwYkHeRGH/oaO/3FJHwWr3AjGfc 2srDcLW3zI7zKIMiazTTW3xK8E5jmhXiLy43CWkdrwtsyPGs+BKKyaczM5z4YY/RXVJp mKLgm3BbCf75EwjiN0xZ2T5NDMKikdHlxvHIk58qHLCZApupl7YqFl7Y5nhzbQPqAA4l 2Jmoypt7GnBpkskGoYJJf5NFyIihV441Q3ueUUaD+mkQOaLvxdlFLchw977RHPCDwbQ/ q4kg== 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=RiLW8AiQpZF6iGJrbmrjYOdePG5Q8A6d2/D4E66B4xE=; b=V4FWGkw45rs8DV6K/aqx2n0mTDhjz0bBAEUd69R3m/yLg0wBRtg7sgD5OcY0dNaUyQ mXCrAZE4Q83xBhqtlKVvJ+ep4+txX5v2u2W70BGcosxisNy7Aut+lJ91mX3E6mnBNega Ib2w/VgRaBwClQNJQGkzagUsnMLiYfbMdbAVz9Zsw1ug/6eWAQNEmFRa5PIGoKdJDH/J cZR/j8NZI93C9ySdWfae9pUJGasUR+6HrQ2K4d53Pwjj4XYGirlssYk8LJoOEjItsTe9 dUAbAZmVb2FvuNY5LFLfNeaEdexIXMIkUh1cE1lZ7GrdkrdrFWndaSCjLASa2xZ9KmXx tbeA== 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 k34si7548078wrf.93.2017.08.22.08.09.07 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:08 -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 1dkAnj-0004j5-52; Tue, 22 Aug 2017 16:09:07 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 13/20] target/arm: Make MPU_RBAR, MPU_RLAR banked for v8M Date: Tue, 22 Aug 2017 16:08:52 +0100 Message-Id: <1503414539-28762-14-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the MPU registers MPU_MAIR0 and MPU_MAIR1 banked if v8M security extensions are enabled. We can freely add more items to vmstate_m_security without breaking migration compatibility, because no CPU currently has the ARM_FEATURE_M_SECURITY bit enabled and so this subsection is not yet used by anything. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 4 ++-- hw/intc/armv7m_nvic.c | 8 ++++---- target/arm/cpu.c | 26 ++++++++++++++++++++------ target/arm/helper.c | 11 ++++++----- target/arm/machine.c | 12 ++++++++---- 5 files changed, 40 insertions(+), 21 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 2f59828..12fa95e 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -543,8 +543,8 @@ typedef struct CPUARMState { * pmsav7.rnr (region number register) * pmsav7_dregion (number of configured regions) */ - uint32_t *rbar; - uint32_t *rlar; + uint32_t *rbar[2]; + uint32_t *rlar[2]; uint32_t mair0[2]; uint32_t mair1[2]; } pmsav8; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index e98eb95..9ced7af 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -564,7 +564,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (region >= cpu->pmsav7_dregion) { return 0; } - return cpu->env.pmsav8.rbar[region]; + return cpu->env.pmsav8.rbar[attrs.secure][region]; } if (region >= cpu->pmsav7_dregion) { @@ -591,7 +591,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (region >= cpu->pmsav7_dregion) { return 0; } - return cpu->env.pmsav8.rlar[region]; + return cpu->env.pmsav8.rlar[attrs.secure][region]; } if (region >= cpu->pmsav7_dregion) { @@ -756,7 +756,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, if (region >= cpu->pmsav7_dregion) { return; } - cpu->env.pmsav8.rbar[region] = value; + cpu->env.pmsav8.rbar[attrs.secure][region] = value; tlb_flush(CPU(cpu)); return; } @@ -806,7 +806,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, if (region >= cpu->pmsav7_dregion) { return; } - cpu->env.pmsav8.rlar[region] = value; + cpu->env.pmsav8.rlar[attrs.secure][region] = value; tlb_flush(CPU(cpu)); return; } diff --git a/target/arm/cpu.c b/target/arm/cpu.c index ae8af19..333029c 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -235,10 +235,20 @@ static void arm_cpu_reset(CPUState *s) if (arm_feature(env, ARM_FEATURE_PMSA)) { if (cpu->pmsav7_dregion > 0) { if (arm_feature(env, ARM_FEATURE_V8)) { - memset(env->pmsav8.rbar, 0, - sizeof(*env->pmsav8.rbar) * cpu->pmsav7_dregion); - memset(env->pmsav8.rlar, 0, - sizeof(*env->pmsav8.rlar) * cpu->pmsav7_dregion); + memset(env->pmsav8.rbar[M_REG_NS], 0, + sizeof(*env->pmsav8.rbar[M_REG_NS]) + * cpu->pmsav7_dregion); + memset(env->pmsav8.rlar[M_REG_NS], 0, + sizeof(*env->pmsav8.rlar[M_REG_NS]) + * cpu->pmsav7_dregion); + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + memset(env->pmsav8.rbar[M_REG_S], 0, + sizeof(*env->pmsav8.rbar[M_REG_S]) + * cpu->pmsav7_dregion); + memset(env->pmsav8.rlar[M_REG_S], 0, + sizeof(*env->pmsav8.rlar[M_REG_S]) + * cpu->pmsav7_dregion); + } } else if (arm_feature(env, ARM_FEATURE_V7)) { memset(env->pmsav7.drbar, 0, sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion); @@ -823,8 +833,12 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) if (nr) { if (arm_feature(env, ARM_FEATURE_V8)) { /* PMSAv8 */ - env->pmsav8.rbar = g_new0(uint32_t, nr); - env->pmsav8.rlar = g_new0(uint32_t, nr); + env->pmsav8.rbar[M_REG_NS] = g_new0(uint32_t, nr); + env->pmsav8.rlar[M_REG_NS] = g_new0(uint32_t, nr); + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + env->pmsav8.rbar[M_REG_S] = g_new0(uint32_t, nr); + env->pmsav8.rlar[M_REG_S] = g_new0(uint32_t, nr); + } } else { env->pmsav7.drbar = g_new0(uint32_t, nr); env->pmsav7.drsr = g_new0(uint32_t, nr); diff --git a/target/arm/helper.c b/target/arm/helper.c index b1bb507..5394cef 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8442,6 +8442,7 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address, { ARMCPU *cpu = arm_env_get_cpu(env); bool is_user = regime_is_user(env, mmu_idx); + uint32_t secure = regime_is_secure(env, mmu_idx); int n; int matchregion = -1; bool hit = false; @@ -8468,10 +8469,10 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address, * with bits [4:0] all zeroes, but the limit address is bits * [31:5] from the register with bits [4:0] all ones. */ - uint32_t base = env->pmsav8.rbar[n] & ~0x1f; - uint32_t limit = env->pmsav8.rlar[n] | 0x1f; + uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f; + uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f; - if (!(env->pmsav8.rlar[n] & 0x1)) { + if (!(env->pmsav8.rlar[secure][n] & 0x1)) { /* Region disabled */ continue; } @@ -8520,8 +8521,8 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address, /* hit using the background region */ get_phys_addr_pmsav7_default(env, mmu_idx, address, prot); } else { - uint32_t ap = extract32(env->pmsav8.rbar[matchregion], 1, 2); - uint32_t xn = extract32(env->pmsav8.rbar[matchregion], 0, 1); + uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2); + uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1); if (m_is_system_region(env, address)) { /* System space is always execute never */ diff --git a/target/arm/machine.c b/target/arm/machine.c index 414a879..05c6c7a 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -225,10 +225,10 @@ static const VMStateDescription vmstate_pmsav8 = { .minimum_version_id = 1, .needed = pmsav8_needed, .fields = (VMStateField[]) { - VMSTATE_VARRAY_UINT32(env.pmsav8.rbar, ARMCPU, pmsav7_dregion, 0, - vmstate_info_uint32, uint32_t), - VMSTATE_VARRAY_UINT32(env.pmsav8.rlar, ARMCPU, pmsav7_dregion, 0, - vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_NS], ARMCPU, pmsav7_dregion, + 0, vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_NS], ARMCPU, pmsav7_dregion, + 0, vmstate_info_uint32, uint32_t), VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU), VMSTATE_END_OF_LIST() @@ -257,6 +257,10 @@ static const VMStateDescription vmstate_m_security = { VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU), VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU), VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU), + VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_S], ARMCPU, pmsav7_dregion, + 0, vmstate_info_uint32, uint32_t), + VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion, + 0, vmstate_info_uint32, uint32_t), VMSTATE_END_OF_LIST() } }; From patchwork Tue Aug 22 15:08: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: 110684 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816305qge; Tue, 22 Aug 2017 08:09:12 -0700 (PDT) X-Received: by 10.99.2.197 with SMTP id 188mr1034877pgc.307.1503414552843; Tue, 22 Aug 2017 08:09:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414552; cv=none; d=google.com; s=arc-20160816; b=mDEYgofA1UntlxTeMzn/vdql9VQsJ+ZuXmH0KAMn0slwA7EY+cQyXAkOtO9P9tbBy5 btEM7dMvUZ5z8nNZCJojb/ndyFO2aHPhH7klvAR2KmNAcSRyHGpcnZIq1aea8rvItHkT p7squ58RVFyZfwl8v5Wn+O+Y8JT4BTfeZRl+L/ytOXkCc3/MSLUWkdUITKlKzNcB6644 nVGsiORjD/Rq+Oh3trZqQYx05eh8MCFRiGkELhRDXDEZA1kalv7BCy7POpZV5etRSRKq Uo25G0xryagxn+a3PHzVvStn17TuB9mZJAOpkkXIIEnzF7CMqDM56nrqf1v6qyiuSw67 hG2w== 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=zcHCso0qwP8Gomk1oDVTljCuaixwSTQNVeLeuOsPeYA=; b=tAp8HomTJ6iXQ9lK669B53PQTfd6eUveoB8RmQrp4l2D7r9Fe+3XTPvKJL92o4sCmZ JJqQYGZSUhDSLLC8e/8hewqsgow/r+95ZNZ47EdwztEBilek1PnZJEK8/k8VECWP3E2i +Rfw0vYZGoddqaznResyRGTe7jRf3bS+LCz6jYFl+uW9tVhp/fQZ/7tuHfrdegUYpJGi Q8VWEjb6KDZD6aFGRQ/l6tK0802Eu9AbaXoTNhcvjFPwKQUHsNdV0m+6LVHfjbwibqQl EKEIyqPms0CJJnBnwMcnQ/IDu4nOdecmTj1GucQkzoLROI5qXvZgjQkTZSyh+1W1HPjV joSA== 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 b9si2264261pli.875.2017.08.22.08.09.12 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:12 -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 1dkAnj-0004jb-UZ; Tue, 22 Aug 2017 16:09:07 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 14/20] target/arm: Make MPU_RNR register banked for v8M Date: Tue, 22 Aug 2017 16:08:53 +0100 Message-Id: <1503414539-28762-15-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the MPU_RNR register banked if v8M security extensions are enabled. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 +- hw/intc/armv7m_nvic.c | 18 +++++++++--------- target/arm/cpu.c | 3 ++- target/arm/helper.c | 6 +++--- target/arm/machine.c | 13 +++++++++++-- 5 files changed, 26 insertions(+), 16 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 12fa95e..43d36d6 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -533,7 +533,7 @@ typedef struct CPUARMState { uint32_t *drbar; uint32_t *drsr; uint32_t *dracr; - uint32_t rnr; + uint32_t rnr[2]; } pmsav7; /* PMSAv8 MPU */ diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 9ced7af..c3c214c 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -543,13 +543,13 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) case 0xd94: /* MPU_CTRL */ return cpu->env.v7m.mpu_ctrl; case 0xd98: /* MPU_RNR */ - return cpu->env.pmsav7.rnr; + return cpu->env.pmsav7.rnr[attrs.secure]; case 0xd9c: /* MPU_RBAR */ case 0xda4: /* MPU_RBAR_A1 */ case 0xdac: /* MPU_RBAR_A2 */ case 0xdb4: /* MPU_RBAR_A3 */ { - int region = cpu->env.pmsav7.rnr; + int region = cpu->env.pmsav7.rnr[attrs.secure]; if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { /* PMSAv8M handling of the aliases is different from v7M: @@ -577,7 +577,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */ case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */ { - int region = cpu->env.pmsav7.rnr; + int region = cpu->env.pmsav7.rnr[attrs.secure]; if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { /* PMSAv8M handling of the aliases is different from v7M: @@ -731,7 +731,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, PRIu32 "/%" PRIu32 "\n", value, cpu->pmsav7_dregion); } else { - cpu->env.pmsav7.rnr = value; + cpu->env.pmsav7.rnr[attrs.secure] = value; } break; case 0xd9c: /* MPU_RBAR */ @@ -749,7 +749,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, */ int aliasno = (offset - 0xd9c) / 8; /* 0..3 */ - region = cpu->env.pmsav7.rnr; + region = cpu->env.pmsav7.rnr[attrs.secure]; if (aliasno) { region = deposit32(region, 0, 2, aliasno); } @@ -772,9 +772,9 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, region, cpu->pmsav7_dregion); return; } - cpu->env.pmsav7.rnr = region; + cpu->env.pmsav7.rnr[attrs.secure] = region; } else { - region = cpu->env.pmsav7.rnr; + region = cpu->env.pmsav7.rnr[attrs.secure]; } if (region >= cpu->pmsav7_dregion) { @@ -790,7 +790,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */ case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */ { - int region = cpu->env.pmsav7.rnr; + int region = cpu->env.pmsav7.rnr[attrs.secure]; if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { /* PMSAv8M handling of the aliases is different from v7M: @@ -799,7 +799,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, */ int aliasno = (offset - 0xd9c) / 8; /* 0..3 */ - region = cpu->env.pmsav7.rnr; + region = cpu->env.pmsav7.rnr[attrs.secure]; if (aliasno) { region = deposit32(region, 0, 2, aliasno); } diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 333029c..11038b8 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -258,7 +258,8 @@ static void arm_cpu_reset(CPUState *s) sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion); } } - env->pmsav7.rnr = 0; + env->pmsav7.rnr[M_REG_NS] = 0; + env->pmsav7.rnr[M_REG_S] = 0; memset(env->pmsav8.mair0, 0, sizeof(env->pmsav8.mair0)); memset(env->pmsav8.mair1, 0, sizeof(env->pmsav8.mair1)); } diff --git a/target/arm/helper.c b/target/arm/helper.c index 5394cef..48e0fc6 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -2385,7 +2385,7 @@ static uint64_t pmsav7_read(CPUARMState *env, const ARMCPRegInfo *ri) return 0; } - u32p += env->pmsav7.rnr; + u32p += env->pmsav7.rnr[M_REG_NS]; return *u32p; } @@ -2399,7 +2399,7 @@ static void pmsav7_write(CPUARMState *env, const ARMCPRegInfo *ri, return; } - u32p += env->pmsav7.rnr; + u32p += env->pmsav7.rnr[M_REG_NS]; tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */ *u32p = value; } @@ -2442,7 +2442,7 @@ static const ARMCPRegInfo pmsav7_cp_reginfo[] = { .resetfn = arm_cp_reset_ignore }, { .name = "RGNR", .cp = 15, .crn = 6, .opc1 = 0, .crm = 2, .opc2 = 0, .access = PL1_RW, - .fieldoffset = offsetof(CPUARMState, pmsav7.rnr), + .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]), .writefn = pmsav7_rgnr_write, .resetfn = arm_cp_reset_ignore }, REGINFO_SENTINEL diff --git a/target/arm/machine.c b/target/arm/machine.c index 05c6c7a..6941e35 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -167,7 +167,7 @@ static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) { ARMCPU *cpu = opaque; - return cpu->env.pmsav7.rnr < cpu->pmsav7_dregion; + return cpu->env.pmsav7.rnr[M_REG_NS] < cpu->pmsav7_dregion; } static const VMStateDescription vmstate_pmsav7 = { @@ -205,7 +205,7 @@ static const VMStateDescription vmstate_pmsav7_rnr = { .minimum_version_id = 1, .needed = pmsav7_rnr_needed, .fields = (VMStateField[]) { - VMSTATE_UINT32(env.pmsav7.rnr, ARMCPU), + VMSTATE_UINT32(env.pmsav7.rnr[M_REG_NS], ARMCPU), VMSTATE_END_OF_LIST() } }; @@ -235,6 +235,13 @@ static const VMStateDescription vmstate_pmsav8 = { } }; +static bool s_rnr_vmstate_validate(void *opaque, int version_id) +{ + ARMCPU *cpu = opaque; + + return cpu->env.pmsav7.rnr[M_REG_S] < cpu->pmsav7_dregion; +} + static bool m_security_needed(void *opaque) { ARMCPU *cpu = opaque; @@ -261,6 +268,8 @@ static const VMStateDescription vmstate_m_security = { 0, vmstate_info_uint32, uint32_t), VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion, 0, vmstate_info_uint32, uint32_t), + VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU), + VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate), VMSTATE_END_OF_LIST() } }; From patchwork Tue Aug 22 15:08: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: 110679 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816235qge; Tue, 22 Aug 2017 08:09:09 -0700 (PDT) X-Received: by 10.28.170.67 with SMTP id t64mr586897wme.107.1503414549582; Tue, 22 Aug 2017 08:09:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414549; cv=none; d=google.com; s=arc-20160816; b=nbua0MbbwPQzhWzLbS/wtxuWca5OpTLv+OoZidhM1li84fAbamoUDBSWIIs9+h4Oo6 K4s3wBflDZS9qxVYPAiacwaKtEjZuHtwrorauIEwSKOskiYbEVEDUNWFaLa1O6rlUrYF SRxRcFCqKjz/S0SL6GXp5IbE25ADyqw39EbW47tl1y6/t3LNo+klO9vMS6oJgR+PiTWc xNOWsdKVU+CaXUqqQT6shQMAVOzECZ6vRkporiHkYOC3yE4e/l/OmLHCd2y1kO2mCcBU amt0TF/k/8aSepGREaqcx/hfX9NO521WYpB38yJVPW2MboZZBeVCSJYWEaAA8yQvibdR RU1Q== 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=YYRZSpsj3uNdOjUDvWjsGfuIWksSEvd8H/jt3PO9sNE=; b=rQFtJmG2BM4E6XYolxJbqt1r7GqHN1xiQDtb/0A1xKNpswy7okDlgyC//Lo2NsMUEx 8jS4vwVY+X7y4bWiF+XYzndyr7kf0HJPnLaVm1bj5usXg3I8bqA30g1BWZpIj/TjYt59 p3g33jD9RlE/c/9LeUGoQkrnGBAIgaW2HhB0nO59OmkSufSFZcyoVG0IxgnWt9++SYr8 XiutWnWmbZiJpqyu6FnoA+r9i81jkwBApWaDj83yQldHDtFpMdK2T2mByX6v02IUocYL jQ6Vqxhzi3wiJRf48choBoO73bEEOYF0WkPAlX56gT2wCQxmde3MSo77jyqT0VOhEJA3 S/zg== 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 m136si75378wmd.6.2017.08.22.08.09.09 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:09 -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 1dkAnk-0004jy-Mk; Tue, 22 Aug 2017 16:09:08 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 15/20] target/arm: Make MPU_CTRL register banked for v8M Date: Tue, 22 Aug 2017 16:08:54 +0100 Message-Id: <1503414539-28762-16-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the MPU_CTRL register banked if v8M security extensions are enabled. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 +- hw/intc/armv7m_nvic.c | 9 +++++---- target/arm/helper.c | 5 +++-- target/arm/machine.c | 3 ++- 4 files changed, 11 insertions(+), 8 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 43d36d6..78cd3f0 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -429,7 +429,7 @@ typedef struct CPUARMState { uint32_t dfsr; /* Debug Fault Status Register */ uint32_t mmfar; /* MemManage Fault Address */ uint32_t bfar; /* BusFault Address */ - unsigned mpu_ctrl; /* MPU_CTRL */ + unsigned mpu_ctrl[2]; /* MPU_CTRL */ int exception; uint32_t primask[2]; uint32_t faultmask[2]; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index c3c214c..a4c298f 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -541,7 +541,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) return cpu->pmsav7_dregion << 8; break; case 0xd94: /* MPU_CTRL */ - return cpu->env.v7m.mpu_ctrl; + return cpu->env.v7m.mpu_ctrl[attrs.secure]; case 0xd98: /* MPU_RNR */ return cpu->env.pmsav7.rnr[attrs.secure]; case 0xd9c: /* MPU_RBAR */ @@ -720,9 +720,10 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is " "UNPREDICTABLE\n"); } - cpu->env.v7m.mpu_ctrl = value & (R_V7M_MPU_CTRL_ENABLE_MASK | - R_V7M_MPU_CTRL_HFNMIENA_MASK | - R_V7M_MPU_CTRL_PRIVDEFENA_MASK); + cpu->env.v7m.mpu_ctrl[attrs.secure] + = value & (R_V7M_MPU_CTRL_ENABLE_MASK | + R_V7M_MPU_CTRL_HFNMIENA_MASK | + R_V7M_MPU_CTRL_PRIVDEFENA_MASK); tlb_flush(CPU(cpu)); break; case 0xd98: /* MPU_RNR */ diff --git a/target/arm/helper.c b/target/arm/helper.c index 48e0fc6..4a2148c 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -7096,7 +7096,7 @@ static inline bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx) { if (arm_feature(env, ARM_FEATURE_M)) { - switch (env->v7m.mpu_ctrl & + switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] & (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) { case R_V7M_MPU_CTRL_ENABLE_MASK: /* Enabled, but not for HardFault and NMI */ @@ -8256,7 +8256,8 @@ static bool pmsav7_use_background_region(ARMCPU *cpu, } if (arm_feature(env, ARM_FEATURE_M)) { - return env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_PRIVDEFENA_MASK; + return env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] + & R_V7M_MPU_CTRL_PRIVDEFENA_MASK; } else { return regime_sctlr(env, mmu_idx) & SCTLR_BR; } diff --git a/target/arm/machine.c b/target/arm/machine.c index 6941e35..5cc95e8 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -123,7 +123,7 @@ static const VMStateDescription vmstate_m = { VMSTATE_UINT32(env.v7m.dfsr, ARMCPU), VMSTATE_UINT32(env.v7m.mmfar, ARMCPU), VMSTATE_UINT32(env.v7m.bfar, ARMCPU), - VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU), + VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU), VMSTATE_INT32(env.v7m.exception, ARMCPU), VMSTATE_END_OF_LIST() }, @@ -270,6 +270,7 @@ static const VMStateDescription vmstate_m_security = { 0, vmstate_info_uint32, uint32_t), 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_END_OF_LIST() } }; From patchwork Tue Aug 22 15:08: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: 110680 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816261qge; Tue, 22 Aug 2017 08:09:10 -0700 (PDT) X-Received: by 10.46.13.18 with SMTP id 18mr452301ljn.128.1503414550826; Tue, 22 Aug 2017 08:09:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414550; cv=none; d=google.com; s=arc-20160816; b=lf/8GsRdZQvRejeAIMy3orIzVJDeWW8NIQLK1/CuyYCjVV9al6EqP94B6AEfJa9Lqq F41JF/Ul5b5G558FvxUgMxCAXApPaukSVmlBx6KeL7z8/zOAcVAl1c6RrRFXU2Nf/oZ8 KSv4jcaNmyxvYpd6abiF1shvrn8YQmauCJ4TeX61ZUZvhVQLy3NrUAmUEK3DPpBk8TXk hGYqeLWxGzt7nEkicStlsqBcudHTSa58m4Q+Oqlt1D+jhRqjhe92GiPySvyYn/C4EDle lpSsYUFD99xZDpA+KoKlkxzNDxxI79Xd/45LFUIN6AT1cd0AkGlhJpBqQ3s+Q/yEk4tp csxw== 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=N/nwW7vSeZL2WgKVODgBVHZCQgOvw6DxnbDWYkbuprA=; b=S0A7IYt5skE28gjlbHCfcNV1x3gwmLnHwW7tVjvYNEYGcnJP0I2nUwErZOOtLIA7JX JzypTd5R6kbhMbI20jRsYagrD1kkoSibM/HJzwOWJQxQBLuLI9TO07FuiZ6Rw4gioCRE KsGktUWui8Aqo1MDuamZWx+mDFDIZQa1XxrsyeRZiPnZli5idgca/517vChOw5MoXRuI NFXucYJsnsVYjXzzpiC/wzkl1bfcfx3iN21jwjmlwwOlzb3pYzWQuiRhj1VXa/QXepYX j1UuslvGgL4Xl8cdVb7cQAbZ2YGTIK1WGL/dcRVd7iJQOKhw6Hpy1FmEv+2dOopYRqLT aCYg== 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 h22si5792907ljb.262.2017.08.22.08.09.10 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:10 -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 1dkAnl-0004kK-Cw; Tue, 22 Aug 2017 16:09:09 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 16/20] target/arm: Make CCR register banked for v8M Date: Tue, 22 Aug 2017 16:08:55 +0100 Message-Id: <1503414539-28762-17-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> 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 --- target/arm/cpu.h | 2 +- hw/intc/armv7m_nvic.c | 36 ++++++++++++++++++++++++++++++------ target/arm/cpu.c | 12 +++++++++--- target/arm/helper.c | 5 +++-- target/arm/machine.c | 3 ++- 5 files changed, 45 insertions(+), 13 deletions(-) -- 2.7.4 diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 78cd3f0..25ebf9e 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..f071649 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,23 @@ 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 */ + int new_bfhnmign = !!(value & R_V7M_CCR_BFHFNMIGN_MASK); + + cpu->env.v7m.ccr[M_REG_NS] = deposit32(cpu->env.v7m.ccr[M_REG_NS], + R_V7M_CCR_BFHFNMIGN_SHIFT, + R_V7M_CCR_BFHFNMIGN_LENGTH, + new_bfhnmign); + 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 +881,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 +905,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 +995,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 11038b8..3c2ff11 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 4a2148c..28b3d6c 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6118,7 +6118,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; } @@ -6216,7 +6217,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 5cc95e8..4457ec6 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() } }; From patchwork Tue Aug 22 15:08:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110681 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816273qge; Tue, 22 Aug 2017 08:09:11 -0700 (PDT) X-Received: by 10.28.153.14 with SMTP id b14mr577222wme.131.1503414551274; Tue, 22 Aug 2017 08:09:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414551; cv=none; d=google.com; s=arc-20160816; b=O4qpmxqWIA14WB+/ghJqNZdUjX5uQk2S8GKbdBSqny5WVp3LjkqLgwLR7MWnadUSFW fQ42lH2I2fFyFjhSFGnXxiAMC1qOlRo7dfJGjHS5tye18sAO/GYalpSChNbvxda3YDxJ 8Ukb4JpW27oG/9HyYoRWalxjFgUr2w6F5Unoi+6m3HX+SBLhYcKltHG+xNZIMQT2s9w7 m7/lG+aTA+nXwH4vUIE1DpLZimsGnIy2FUO9M7bLHkWvj3eDlWae5wbMS6d0aGptVBLc CaF+Jq0Ds8mPItIf1EjjTZuB6VOmTsn9x/ZAIBwDCiSha9+um6TJmPB5/P8JymA4srdx E/Yw== 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=kE6xWZi2IMg4sT8d0R+McIWwziPSQ44v6M9kDzQFZN8=; b=m/e3oRQRWHFOGFSjFtXHnDOMw5pyRI60i+wtkKoBavXVTp/hmVtJ6ac7LdMQ0ONo0X Rcc+L7g/+hrU/DFL+As747UICm+ZjsyaEs6REXpFjRZdXsIPnctYJS6eyLkTy7qWOvz4 viWpgvCLo97ZMQAC6N/6zB47X6mwSrsx51IJ/T5QZ1N8jWs/0FYOiawSWLH/Le842o8W hGQ0IJzuvstb5woX6trOvPoGL+5emi11tBsLGHHI8nEwTtLK3mwCQDAm3QmkXfaPNkBa /vOEOE6SV/B59hGkfYegBiT7aXrR2G4BPgcYr8q3AAqIunkYzT/5gaSk6hNyWhZkVL7s YCmQ== 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 b25si11316575wrc.374.2017.08.22.08.09.11 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:11 -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 1dkAnm-0004l3-5h; Tue, 22 Aug 2017 16:09:10 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 17/20] target/arm: Make MMFAR banked for v8M Date: Tue, 22 Aug 2017 16:08:56 +0100 Message-Id: <1503414539-28762-18-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the MMFAR register banked if v8M security extensions are enabled. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 2 +- hw/intc/armv7m_nvic.c | 4 ++-- target/arm/helper.c | 4 ++-- target/arm/machine.c | 3 ++- 4 files changed, 7 insertions(+), 6 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 25ebf9e..21c68d7 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -427,7 +427,7 @@ typedef struct CPUARMState { uint32_t cfsr; /* Configurable Fault Status */ uint32_t hfsr; /* HardFault Status */ uint32_t dfsr; /* Debug Fault Status Register */ - uint32_t mmfar; /* MemManage Fault Address */ + uint32_t mmfar[2]; /* MemManage Fault Address */ uint32_t bfar; /* BusFault Address */ unsigned mpu_ctrl[2]; /* MPU_CTRL */ int exception; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index f071649..99b62ac 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -506,7 +506,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) case 0xd30: /* Debug Fault Status. */ return cpu->env.v7m.dfsr; case 0xd34: /* MMFAR MemManage Fault Address */ - return cpu->env.v7m.mmfar; + return cpu->env.v7m.mmfar[attrs.secure]; case 0xd38: /* Bus Fault Address. */ return cpu->env.v7m.bfar; case 0xd3c: /* Aux Fault Status. */ @@ -723,7 +723,7 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, cpu->env.v7m.dfsr &= ~value; /* W1C */ break; case 0xd34: /* Mem Manage Address. */ - cpu->env.v7m.mmfar = value; + cpu->env.v7m.mmfar[attrs.secure] = value; return; case 0xd38: /* Bus Fault Address. */ cpu->env.v7m.bfar = value; diff --git a/target/arm/helper.c b/target/arm/helper.c index 28b3d6c..e587e85 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6380,10 +6380,10 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) case EXCP_DATA_ABORT: env->v7m.cfsr |= (R_V7M_CFSR_DACCVIOL_MASK | R_V7M_CFSR_MMARVALID_MASK); - env->v7m.mmfar = env->exception.vaddress; + env->v7m.mmfar[env->v7m.secure] = env->exception.vaddress; qemu_log_mask(CPU_LOG_INT, "...with CFSR.DACCVIOL and MMFAR 0x%x\n", - env->v7m.mmfar); + env->v7m.mmfar[env->v7m.secure]); break; } armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM); diff --git a/target/arm/machine.c b/target/arm/machine.c index 4457ec6..5122e58 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -121,7 +121,7 @@ static const VMStateDescription vmstate_m = { VMSTATE_UINT32(env.v7m.cfsr, ARMCPU), VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), VMSTATE_UINT32(env.v7m.dfsr, ARMCPU), - VMSTATE_UINT32(env.v7m.mmfar, ARMCPU), + VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.bfar, ARMCPU), VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU), VMSTATE_INT32(env.v7m.exception, ARMCPU), @@ -272,6 +272,7 @@ static const VMStateDescription vmstate_m_security = { 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_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU), VMSTATE_END_OF_LIST() } }; From patchwork Tue Aug 22 15:08: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: 110683 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816295qge; Tue, 22 Aug 2017 08:09:12 -0700 (PDT) X-Received: by 10.25.18.200 with SMTP id 69mr387820lfs.176.1503414552321; Tue, 22 Aug 2017 08:09:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414552; cv=none; d=google.com; s=arc-20160816; b=kwZdQ203OHyCfxJaxuv/uBMGOygRes0k8rcNhUQRVPaz/bXfc3JGlBgDZsKojgUT2u R2XUtFlaDfxWi0dupFzSeOdxXIPfiV/zAMBHB/rzJQNZQcVIGmVD7jtxRhY3AoG/MVd/ sbNagV3Z9rCfCYS7s4hYUGofihsq1iTTVf5u5Hdq2v+42TTewj0FTyQ7PdCxoUPNK3Z7 VxSPIx3LPeAqG5UQkXD8edjSxQzDBpOYc5UHgVifrSHK9k8AsjhwhpN2B+bHU7mjhukh K2Cww2Tw57CAx5G/kqkiMZROmaCBqXOWMYTOs9tBhBN4tV56dHt9CYlRuCSDNfa+8ie2 rPoA== 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=JyU0DYomgjAN4R4XYcA2L0EnrWl0Osvx4RYV470Cvj4=; b=UiW7be5Je6D7HEXUXxevSqnmPecSop8yHzOimKW6QN+kQxKG09dft2yFZG/CWQ1xbA PRTbE0FlRmAa5t9omHx4MclnEnALkfpJmZQCi8cmOSdbo2cCAkEthrPQDkkGqm6JW8tm VqNh1du/pB5v0TAmR9KW3YRMD2L9xLC5uAlUwuhs1LxG3BcZpC5CtuGE3BBUvSAokl1O BmMcoLjINMSkhwfTjSlasJGrT51R6SYoX/o/3/JSe66Ku9JqxpKSGegw239kPtGFUGKV 86aadmBtsamYZz05pNsUtvh9ExrOCl8Pmx59uQFlGfukhlu1+0UUadaEoG8aFnrDaMO+ UshA== 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 y21si5972250ljd.247.2017.08.22.08.09.12 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:12 -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 1dkAnn-0004lV-1q; Tue, 22 Aug 2017 16:09:11 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 18/20] target/arm: Make CFSR register banked for v8M Date: Tue, 22 Aug 2017 16:08:57 +0100 Message-Id: <1503414539-28762-19-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Make the CFSR register banked if v8M security extensions are enabled. Not all the bits in this register are banked: the BFSR bits [15:8] are shared between S and NS, and we store them in the NS copy of the register. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 7 ++++++- hw/intc/armv7m_nvic.c | 15 +++++++++++++-- target/arm/helper.c | 18 +++++++++--------- target/arm/machine.c | 3 ++- 4 files changed, 30 insertions(+), 13 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 21c68d7..3683537 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -424,7 +424,7 @@ typedef struct CPUARMState { uint32_t basepri[2]; uint32_t control[2]; uint32_t ccr[2]; /* Configuration and Control */ - uint32_t cfsr; /* Configurable Fault Status */ + uint32_t cfsr[2]; /* Configurable Fault Status */ uint32_t hfsr; /* HardFault Status */ uint32_t dfsr; /* Debug Fault Status Register */ uint32_t mmfar[2]; /* MemManage Fault Address */ @@ -1210,6 +1210,11 @@ FIELD(V7M_CFSR, NOCP, 16 + 3, 1) FIELD(V7M_CFSR, UNALIGNED, 16 + 8, 1) FIELD(V7M_CFSR, DIVBYZERO, 16 + 9, 1) +/* V7M CFSR bit masks covering all of the subregister bits */ +FIELD(V7M_CFSR, MMFSR, 0, 8) +FIELD(V7M_CFSR, BFSR, 8, 8) +FIELD(V7M_CFSR, UFSR, 16, 16) + /* V7M HFSR bits */ FIELD(V7M_HFSR, VECTTBL, 1, 1) FIELD(V7M_HFSR, FORCED, 30, 1) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 99b62ac..3c14cc8 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -500,7 +500,12 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) } return val; case 0xd28: /* Configurable Fault Status. */ - return cpu->env.v7m.cfsr; + /* The BFSR bits [15:8] are shared between security states + * and we store them in the NS copy + */ + val = cpu->env.v7m.cfsr[attrs.secure]; + val |= cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK; + return val; case 0xd2c: /* Hard Fault Status. */ return cpu->env.v7m.hfsr; case 0xd30: /* Debug Fault Status. */ @@ -714,7 +719,13 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, nvic_irq_update(s); break; case 0xd28: /* Configurable Fault Status. */ - cpu->env.v7m.cfsr &= ~value; /* W1C */ + cpu->env.v7m.cfsr[attrs.secure] &= ~value; /* W1C */ + if (attrs.secure) { + /* The BFSR bits [15:8] are shared between security states + * and we store them in the NS copy. + */ + cpu->env.v7m.cfsr[M_REG_NS] &= ~(value & R_V7M_CFSR_BFSR_MASK); + } break; case 0xd2c: /* Hard Fault Status. */ cpu->env.v7m.hfsr &= ~value; /* W1C */ diff --git a/target/arm/helper.c b/target/arm/helper.c index e587e85..67b3874 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -6229,7 +6229,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) /* Bad exception return: instead of popping the exception * stack, directly take a usage fault on the current stack. */ - env->v7m.cfsr |= R_V7M_CFSR_INVPC_MASK; + env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK; armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); v7m_exception_taken(cpu, type | 0xf0000000); qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing " @@ -6271,7 +6271,7 @@ static void do_v7m_exception_exit(ARMCPU *cpu) 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); - env->v7m.cfsr |= R_V7M_CFSR_INVPC_MASK; + env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK; v7m_push_stack(cpu); v7m_exception_taken(cpu, type | 0xf0000000); qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on new stackframe: " @@ -6330,15 +6330,15 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) switch (cs->exception_index) { case EXCP_UDEF: armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); - env->v7m.cfsr |= R_V7M_CFSR_UNDEFINSTR_MASK; + env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK; break; case EXCP_NOCP: armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); - env->v7m.cfsr |= R_V7M_CFSR_NOCP_MASK; + env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK; break; case EXCP_INVSTATE: armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); - env->v7m.cfsr |= R_V7M_CFSR_INVSTATE_MASK; + env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK; break; case EXCP_SWI: /* The PC already points to the next instruction. */ @@ -6354,11 +6354,11 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) case 0x8: /* External Abort */ switch (cs->exception_index) { case EXCP_PREFETCH_ABORT: - env->v7m.cfsr |= R_V7M_CFSR_PRECISERR_MASK; + env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_PRECISERR_MASK; qemu_log_mask(CPU_LOG_INT, "...with CFSR.PRECISERR\n"); break; case EXCP_DATA_ABORT: - env->v7m.cfsr |= + env->v7m.cfsr[M_REG_NS] |= (R_V7M_CFSR_IBUSERR_MASK | R_V7M_CFSR_BFARVALID_MASK); env->v7m.bfar = env->exception.vaddress; qemu_log_mask(CPU_LOG_INT, @@ -6374,11 +6374,11 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) */ switch (cs->exception_index) { case EXCP_PREFETCH_ABORT: - env->v7m.cfsr |= R_V7M_CFSR_IACCVIOL_MASK; + env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK; qemu_log_mask(CPU_LOG_INT, "...with CFSR.IACCVIOL\n"); break; case EXCP_DATA_ABORT: - env->v7m.cfsr |= + env->v7m.cfsr[env->v7m.secure] |= (R_V7M_CFSR_DACCVIOL_MASK | R_V7M_CFSR_MMARVALID_MASK); env->v7m.mmfar[env->v7m.secure] = env->exception.vaddress; qemu_log_mask(CPU_LOG_INT, diff --git a/target/arm/machine.c b/target/arm/machine.c index 5122e58..3cc94b4 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -118,7 +118,7 @@ static const VMStateDescription vmstate_m = { VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU), - VMSTATE_UINT32(env.v7m.cfsr, ARMCPU), + VMSTATE_UINT32(env.v7m.cfsr[M_REG_NS], ARMCPU), VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), VMSTATE_UINT32(env.v7m.dfsr, ARMCPU), VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU), @@ -273,6 +273,7 @@ static const VMStateDescription vmstate_m_security = { VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU), + VMSTATE_UINT32(env.v7m.cfsr[M_REG_S], ARMCPU), VMSTATE_END_OF_LIST() } }; From patchwork Tue Aug 22 15:08:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 110682 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816301qge; Tue, 22 Aug 2017 08:09:12 -0700 (PDT) X-Received: by 10.223.141.230 with SMTP id o93mr681648wrb.110.1503414552735; Tue, 22 Aug 2017 08:09:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414552; cv=none; d=google.com; s=arc-20160816; b=x7QcPzNzqr/pSJSgVwEaVsFOD1I20WsPGo3NnrG9BX+StJGh56y4VKmMjRvWydMWz9 D4jR5he4SlKAY4Ux/4jur/aAE6EKbgpIlJ1Ch8M/9gcsvKI5OQiLf0yZaxaY8mODHnJ+ j59SSJ545H4jrGvv08vrX6SyvFXoaeWUumeSz28FyIzPgzOvIGIqefzSkl46F8UxH8UU cusTfWZB7/+GnrjZWefyCiWvyWYxVn1h2CWAfMmHOWUbUSKIkEWzlgGOYBtolMUIR6VY 8qev+yEa89fl3DKY75D8xp+R885I+NcUflL65cr7eRFDI3uL4p0d91eU0gOTHR+xzgTP jzug== 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=sZxHIQ0uWucKo+x7Wygy7dwH0CR+l8l/OL+PUZTpbcs=; b=Pex9io9RpSpLZO5MmBeWsFvI73+uykwFp5Q/tfL0micpweZWpZrvxBkieZHqI1So4S /0+p3JBtsj/f0a8mAo690JrWXPnShzS8I+ktc5rW5u+0C1gc7xn+Vbab8DhhqIZBngmv u0FDGM/lrp8XYMPSUouz4oLnsVuT9bNGVO+P6dyNeoRRJqF0YpLAlXCCJGR63r++Hkv8 vYZ/qiMc93MRwe7V22iVxvCI6hsmx4oHbCuGeVa4+OZoEI1CoLu71ciAOzZ1s2vGfeDz 69WdvMFofaaMocTPOEl7LOD3DzGWjdsdS15zvd7dQeqksLnSLY5RROsBQVUa10ux6qjf hdvg== 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 137si42270wmk.261.2017.08.22.08.09.12 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:12 -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 1dkAnn-0004m0-Pn; Tue, 22 Aug 2017 16:09:11 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 19/20] target/arm: Move regime_is_secure() to target/arm/internals.h Date: Tue, 22 Aug 2017 16:08:58 +0100 Message-Id: <1503414539-28762-20-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Move the regime_is_secure() utility function to internals.h; we are going to want to call it from translate.c. Signed-off-by: Peter Maydell --- target/arm/internals.h | 26 ++++++++++++++++++++++++++ target/arm/helper.c | 26 -------------------------- 2 files changed, 26 insertions(+), 26 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/internals.h b/target/arm/internals.h index bb06946..eb171b1 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -478,4 +478,30 @@ static inline void arm_call_el_change_hook(ARMCPU *cpu) } } +/* Return true if this address translation regime is secure */ +static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) +{ + switch (mmu_idx) { + case ARMMMUIdx_S12NSE0: + case ARMMMUIdx_S12NSE1: + case ARMMMUIdx_S1NSE0: + case ARMMMUIdx_S1NSE1: + case ARMMMUIdx_S1E2: + case ARMMMUIdx_S2NS: + case ARMMMUIdx_MPriv: + case ARMMMUIdx_MNegPri: + case ARMMMUIdx_MUser: + return false; + case ARMMMUIdx_S1E3: + case ARMMMUIdx_S1SE0: + case ARMMMUIdx_S1SE1: + case ARMMMUIdx_MSPriv: + case ARMMMUIdx_MSNegPri: + case ARMMMUIdx_MSUser: + return true; + default: + g_assert_not_reached(); + } +} + #endif diff --git a/target/arm/helper.c b/target/arm/helper.c index 67b3874..b1ae73c 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -7060,32 +7060,6 @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx) } } -/* Return true if this address translation regime is secure */ -static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx) -{ - switch (mmu_idx) { - case ARMMMUIdx_S12NSE0: - case ARMMMUIdx_S12NSE1: - case ARMMMUIdx_S1NSE0: - case ARMMMUIdx_S1NSE1: - case ARMMMUIdx_S1E2: - case ARMMMUIdx_S2NS: - case ARMMMUIdx_MPriv: - case ARMMMUIdx_MNegPri: - case ARMMMUIdx_MUser: - return false; - case ARMMMUIdx_S1E3: - case ARMMMUIdx_S1SE0: - case ARMMMUIdx_S1SE1: - case ARMMMUIdx_MSPriv: - case ARMMMUIdx_MSNegPri: - case ARMMMUIdx_MSUser: - return true; - default: - g_assert_not_reached(); - } -} - /* Return the SCTLR value which controls this address translation regime */ static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx) { From patchwork Tue Aug 22 15:08: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: 110685 Delivered-To: patches@linaro.org Received: by 10.140.95.78 with SMTP id h72csp2816333qge; Tue, 22 Aug 2017 08:09:14 -0700 (PDT) X-Received: by 10.25.208.17 with SMTP id h17mr350876lfg.150.1503414553867; Tue, 22 Aug 2017 08:09:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1503414553; cv=none; d=google.com; s=arc-20160816; b=t6MqynfBC2VUl60eZIRWGDQKv5tbJqMd55fQ/30IM8RG6DhigmzvofJlzJvZHzFx7V mFk01u9gI87brebuv2esTbbElFCffRl7G/XqXYAFxOL5vCojblq3oFN9a5eL5hhFN0ES C5UhgRdhtO7pmNfsPq8mickv75PEv5ICwtEpdqU+QMLTTSGsv260Ipotkj0XaUGTGaFB 12HPSv1ztQVK2+u1LJh8BHHfrm9P2inAGIpf9Z1kDM5hRyeI0x0iiymwPyD3f0tDNlPH GyPSJuZIoep7j+5eQ5l4+s38b7FKTWsJULbijtblctzy4g+cKDaBuj+5ML3dPAIig1Yb 793g== 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=fVOfcJdPdldiaFhC1Ifq+k8dD++CxupDyz2GFBgDA0M=; b=U4TLv1N5veJ91E8cbQ/jqBeuLRr+iTfVyhNvmYcwUFcvdrQPjqDFpHxbaQlurusCJT YPC3myNIy/IoTcOAqJ28HolYLvs/q0zw8y9FGnWPnJIg85iv3vvzN+uebmlRFItgI8dJ s/Y0Oo6xlnBokcWPbbO9UMU4uJXLtfVutjadO3+tv8npwuuOgPOrU6JxblW1Ygj1mRgL NXJFzUvK624l0V0iWR29n1ui0yaIJ4INLW3Kkpg9wGQrcgeWd6Gp3kFnebIGOb7vbhk4 aGAmVbvs/fFJKMY6Sl6OoExDonoQjDU6G54/XMlIjOiCLpknVje3D3vvG1ZZ3r6Ag8QN EP0A== 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 s29si6150951lfk.252.2017.08.22.08.09.13 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 22 Aug 2017 08:09:13 -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 1dkAno-0004mp-Ir; Tue, 22 Aug 2017 16:09:12 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 20/20] target/arm: Implement BXNS, and banked stack pointers Date: Tue, 22 Aug 2017 16:08:59 +0100 Message-Id: <1503414539-28762-21-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> References: <1503414539-28762-1-git-send-email-peter.maydell@linaro.org> Implement the BXNS v8M instruction, which is like BX but will do a jump-and-switch-to-NonSecure if the branch target address has bit 0 clear. This is the first piece of code which implements "switch to the other security state", so the commit also includes the code to switch the stack pointers around, which is the only complicated part of switching security state. BLXNS is more complicated than just "BXNS but set the link register", so we leave it for a separate commit. Signed-off-by: Peter Maydell --- target/arm/cpu.h | 13 +++++++++ target/arm/helper.h | 2 ++ target/arm/translate.h | 1 + target/arm/helper.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ target/arm/machine.c | 2 ++ target/arm/translate.c | 42 ++++++++++++++++++++++++++- 6 files changed, 138 insertions(+), 1 deletion(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 3683537..5e7b68b 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -419,7 +419,20 @@ typedef struct CPUARMState { } cp15; struct { + /* M profile has up to 4 stack pointers: + * a Main Stack Pointer and a Process Stack Pointer for each + * of the Secure and Non-Secure states. (If the CPU doesn't support + * the security extension then it has only two SPs.) + * In QEMU we always store the currently active SP in regs[13], + * and the non-active SP for the current security state in + * v7m.other_sp. The stack pointers for the inactive security state + * are stored in other_ss_msp and other_ss_psp. + * switch_v7m_security_state() is responsible for rearranging them + * when we change security state. + */ uint32_t other_sp; + uint32_t other_ss_msp; + uint32_t other_ss_psp; uint32_t vecbase[2]; uint32_t basepri[2]; uint32_t control[2]; diff --git a/target/arm/helper.h b/target/arm/helper.h index df86bf7..64afbac 100644 --- a/target/arm/helper.h +++ b/target/arm/helper.h @@ -63,6 +63,8 @@ DEF_HELPER_1(cpsr_read, i32, env) DEF_HELPER_3(v7m_msr, void, env, i32, i32) DEF_HELPER_2(v7m_mrs, i32, env, i32) +DEF_HELPER_2(v7m_bxns, void, env, i32) + DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32) DEF_HELPER_3(set_cp_reg, void, env, ptr, i32) DEF_HELPER_2(get_cp_reg, i32, env, ptr) diff --git a/target/arm/translate.h b/target/arm/translate.h index 2fe144b..ef625ad 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -32,6 +32,7 @@ typedef struct DisasContext { int vec_len; int vec_stride; bool v7m_handler_mode; + bool v8m_secure; /* true if v8M and we're in Secure mode */ /* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI * so that top level loop can generate correct syndrome information. */ diff --git a/target/arm/helper.c b/target/arm/helper.c index b1ae73c..4489bbd 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -5875,6 +5875,12 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg) return 0; } +void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest) +{ + /* translate.c should never generate calls here in user-only mode */ + g_assert_not_reached(); +} + void switch_mode(CPUARMState *env, int mode) { ARMCPU *cpu = arm_env_get_cpu(env); @@ -6049,6 +6055,18 @@ static uint32_t v7m_pop(CPUARMState *env) return val; } +/* Return true if we're using the process stack pointer (not the MSP) */ +static bool v7m_using_psp(CPUARMState *env) +{ + /* Handler mode always uses the main stack; for thread mode + * the CONTROL.SPSEL bit determines the answer. + * Note that in v7M it is not possible to be in Handler mode with + * CONTROL.SPSEL non-zero, but in v8M it is, so we must check both. + */ + return !arm_v7m_is_handler_mode(env) && + env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK; +} + /* Switch to V7M main or process stack pointer. */ static void switch_v7m_sp(CPUARMState *env, bool new_spsel) { @@ -6067,6 +6085,67 @@ static void switch_v7m_sp(CPUARMState *env, bool new_spsel) } } +/* Switch M profile security state between NS and S */ +static void switch_v7m_security_state(CPUARMState *env, bool new_secstate) +{ + uint32_t new_ss_msp, new_ss_psp; + + if (env->v7m.secure == new_secstate) { + return; + } + + /* All the banked state is accessed by looking at env->v7m.secure + * except for the stack pointer; rearrange the SP appropriately. + */ + new_ss_msp = env->v7m.other_ss_msp; + new_ss_psp = env->v7m.other_ss_psp; + + if (v7m_using_psp(env)) { + env->v7m.other_ss_psp = env->regs[13]; + env->v7m.other_ss_msp = env->v7m.other_sp; + } else { + env->v7m.other_ss_msp = env->regs[13]; + env->v7m.other_ss_psp = env->v7m.other_sp; + } + + env->v7m.secure = new_secstate; + + if (v7m_using_psp(env)) { + env->regs[13] = new_ss_psp; + env->v7m.other_sp = new_ss_msp; + } else { + env->regs[13] = new_ss_msp; + env->v7m.other_sp = new_ss_psp; + } +} + +void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest) +{ + /* Handle v7M BXNS: + * - if the return value is a magic value, do exception return (like BX) + * - otherwise bit 0 of the return value is the target security state + */ + if (dest >= 0xff000000) { + /* This is an exception return magic value; put it where + * do_v7m_exception_exit() expects and raise EXCEPTION_EXIT. + * Note that if we ever add gen_ss_advance() singlestep support to + * M profile this should count as an "instruction execution complete" + * event (compare gen_bx_excret_final_code()). + */ + env->regs[15] = dest & ~1; + env->thumb = dest & 1; + HELPER(exception_internal)(env, EXCP_EXCEPTION_EXIT); + /* notreached */ + } + + /* translate.c should have made BXNS UNDEF unless we're secure */ + assert(env->v7m.secure); + + switch_v7m_security_state(env, dest & 1); + env->thumb = 1; + env->regs[15] = dest & ~1; +} + static uint32_t arm_v7m_load_vector(ARMCPU *cpu) { CPUState *cs = CPU(cpu); diff --git a/target/arm/machine.c b/target/arm/machine.c index 3cc94b4..1aca40d 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -257,6 +257,8 @@ static const VMStateDescription vmstate_m_security = { .needed = m_security_needed, .fields = (VMStateField[]) { VMSTATE_UINT32(env.v7m.secure, ARMCPU), + VMSTATE_UINT32(env.v7m.other_ss_msp, ARMCPU), + VMSTATE_UINT32(env.v7m.other_ss_psp, ARMCPU), VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU), VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU), diff --git a/target/arm/translate.c b/target/arm/translate.c index 6aa2d7c..e7966e2 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -994,6 +994,25 @@ static inline void gen_bx_excret_final_code(DisasContext *s) gen_exception_internal(EXCP_EXCEPTION_EXIT); } +static inline void gen_bxns(DisasContext *s, int rm) +{ + TCGv_i32 var = load_reg(s, rm); + + /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory + * we need to sync state before calling it, but: + * - we don't need to do gen_set_pc_im() because the bxns helper will + * always set the PC itself + * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE + * unless it's outside an IT block or the last insn in an IT block, + * so we know that condexec == 0 (already set at the top of the TB) + * is correct in the non-UNPREDICTABLE cases, and we can choose + * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise. + */ + gen_helper_v7m_bxns(cpu_env, var); + tcg_temp_free_i32(var); + s->is_jmp = DISAS_EXIT; +} + /* Variant of store_reg which uses branch&exchange logic when storing to r15 in ARM architecture v7 and above. The source must be a temporary and will be marked as dead. */ @@ -11185,12 +11204,31 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) */ bool link = insn & (1 << 7); - if (insn & 7) { + if (insn & 3) { goto undef; } if (link) { ARCH(5); } + if ((insn & 4)) { + /* BXNS/BLXNS: only exists for v8M with the + * security extensions, and always UNDEF if NonSecure. + * We don't implement these in the user-only mode + * either (in theory you can use them from Secure User + * mode but they are too tied in to system emulation.) + */ + if (!s->v8m_secure || IS_USER_ONLY) { + goto undef; + } + if (link) { + /* BLXNS: not yet implemented */ + goto undef; + } else { + gen_bxns(s, rm); + } + break; + } + /* BLX/BX */ tmp = load_reg(s, rm); if (link) { val = (uint32_t)s->pc | 1; @@ -11878,6 +11916,8 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags); dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags); dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(tb->flags); + dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) && + regime_is_secure(env, dc->mmu_idx); dc->cp_regs = cpu->cp_regs; dc->features = env->features;