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);