From patchwork Fri Feb 9 16:58:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 127868 Delivered-To: patches@linaro.org Received: by 10.46.124.24 with SMTP id x24csp802177ljc; Fri, 9 Feb 2018 08:58:17 -0800 (PST) X-Google-Smtp-Source: AH8x22491ZZNIt0h70vyWg7jK0gaNgWGGxecLTbxp6VQpevJEC/6KTa43SvlPmtfKjIc/PgZ9k1l X-Received: by 10.28.105.80 with SMTP id e77mr2734161wmc.123.1518195497112; Fri, 09 Feb 2018 08:58:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518195497; cv=none; d=google.com; s=arc-20160816; b=Ec0OwnmccIDW2HEW7OwRwqB6Q94LqE7OW+LsKDUdWEJDqqWCeQIdosv1T1eRNlBN6n pRlbmVjfajfOfKLFuAwAu3CBtBQFY3eelfY4xxz800flAuXOQC2f67i6KFH/EOyLzBGA IlnSm8i43DJfSPwTVhpF78qhRHpseKdVQDbe8nwep8O7J7Cy3AlZu7jv6ZkmPrkfTOJ8 nVVL0+q97n5xGutpWxA0dZssbHh0uL1g8u08ZUYAcIlmSjIWFejc8H76rKdPHzhI9Exu TRvs65uBL68btPXqsR1gRxDCGj27tHyF0PR2kEIAhT9vqjrfLz7JL90KcrNMVCV0w8AF 0pAw== 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=oilZFdbngdoZgrErTwbIFe/9tviyhfuHlkhAqjSzA50=; b=YOTkjptMKYZSI8rQaxV7b0Lya82gvQDFNhcUT4FJ66iQA6LlTtnPI2Rh2eNjbSOMez VDMe87ihJpQYzhKs/uflfiXCZWVC+PKUNhwT4XV+Q/KbMklfDFbXpE5VuLxEY7xzOwU+ +2AXOvTJhnAD2y/wKEwvgQp9EienrzJ8lcXojrs1d/ufK6J8zhZPWjuZx99ics14Ogkl si5ZpJXdIvJ4g3xIdGBcTFFoUHAY4MQY6sgm5xrhV3u9radbneGn74gilll0IWQuHsjl kCZ2h1azryR/sKCZNFDpK4xQ4o1OPuiIfPCIo7GK+XDRL9mTWI459AjVS3u1CYfY97Q2 9tKg== 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 d30si2129838wra.341.2018.02.09.08.58.16 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 09 Feb 2018 08:58:17 -0800 (PST) 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 1ekC08-00030O-K7; Fri, 09 Feb 2018 16:58:16 +0000 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH v2 05/11] hw/intc/armv7m_nvic: Implement cache ID registers Date: Fri, 9 Feb 2018 16:58:04 +0000 Message-Id: <20180209165810.6668-6-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180209165810.6668-1-peter.maydell@linaro.org> References: <20180209165810.6668-1-peter.maydell@linaro.org> M profile cores have a similar setup for cache ID registers to A profile: * Cache Level ID Register (CLIDR) is a fixed value * Cache Type Register (CTR) is a fixed value * Cache Size ID Registers (CCSIDR) are a bank of registers; which one you see is selected by the Cache Size Selection Register (CSSELR) The only difference is that they're in the NVIC memory mapped register space rather than being coprocessor registers. Implement the M profile view of them. Since neither Cortex-M3 nor Cortex-M4 implement caches, we don't need to update their init functions and can leave the ctr/clidr/ccsidr[] fields in their ARMCPU structs at zero. Newer cores (like the Cortex-M33) will want to be able to set these ID registers to non-zero values, though. Signed-off-by: Peter Maydell --- v1->v2 changes: use FIELD() to define some constants; add compile-time assert that we won't index outside cssidr[] --- target/arm/cpu.h | 26 ++++++++++++++++++++++++++ hw/intc/armv7m_nvic.c | 16 ++++++++++++++++ target/arm/machine.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) -- 2.16.1 Reviewed-by: Richard Henderson diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 521444a5a1..4c1b9e9814 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -496,6 +496,7 @@ typedef struct CPUARMState { uint32_t faultmask[M_REG_NUM_BANKS]; uint32_t aircr; /* only holds r/w state if security extn implemented */ uint32_t secure; /* Is CPU in Secure state? (not guest visible) */ + uint32_t csselr[M_REG_NUM_BANKS]; } v7m; /* Information associated with an exception about to be taken: @@ -1325,6 +1326,23 @@ FIELD(V7M_MPU_CTRL, ENABLE, 0, 1) FIELD(V7M_MPU_CTRL, HFNMIENA, 1, 1) FIELD(V7M_MPU_CTRL, PRIVDEFENA, 2, 1) +/* v7M CLIDR bits */ +FIELD(V7M_CLIDR, CTYPE_ALL, 0, 21) +FIELD(V7M_CLIDR, LOUIS, 21, 3) +FIELD(V7M_CLIDR, LOC, 24, 3) +FIELD(V7M_CLIDR, LOUU, 27, 3) +FIELD(V7M_CLIDR, ICB, 30, 2) + +FIELD(V7M_CSSELR, IND, 0, 1) +FIELD(V7M_CSSELR, LEVEL, 1, 3) +/* We use the combination of InD and Level to index into cpu->ccsidr[]; + * define a mask for this and check that it doesn't permit running off + * the end of the array. + */ +FIELD(V7M_CSSELR, INDEX, 0, 4) + +QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK); + /* If adding a feature bit which corresponds to a Linux ELF * HWCAP bit, remember to update the feature-bit-to-hwcap * mapping in linux-user/elfload.c:get_elf_hwcap(). @@ -2485,6 +2503,14 @@ static inline int arm_debug_target_el(CPUARMState *env) } } +static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu) +{ + /* If all the CLIDR.Ctypem bits are 0 there are no caches, and + * CSSELR is RAZ/WI. + */ + return (cpu->clidr & R_V7M_CLIDR_CTYPE_ALL_MASK) != 0; +} + static inline bool aa64_generate_debug_exceptions(CPUARMState *env) { if (arm_is_secure(env)) { diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index eb49fd77c7..040f3380ec 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -1025,6 +1025,17 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) return cpu->id_isar4; case 0xd74: /* ISAR5. */ return cpu->id_isar5; + case 0xd78: /* CLIDR */ + return cpu->clidr; + case 0xd7c: /* CTR */ + return cpu->ctr; + case 0xd80: /* CSSIDR */ + { + int idx = cpu->env.v7m.csselr[attrs.secure] & R_V7M_CSSELR_INDEX_MASK; + return cpu->ccsidr[idx]; + } + case 0xd84: /* CSSELR */ + return cpu->env.v7m.csselr[attrs.secure]; /* TODO: Implement debug registers. */ case 0xd90: /* MPU_TYPE */ /* Unified MPU; if the MPU is not present this value is zero */ @@ -1385,6 +1396,11 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, qemu_log_mask(LOG_UNIMP, "NVIC: Aux fault status registers unimplemented\n"); break; + case 0xd84: /* CSSELR */ + if (!arm_v7m_csselr_razwi(cpu)) { + cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK; + } + break; case 0xd90: /* MPU_TYPE */ return; /* RO */ case 0xd94: /* MPU_CTRL */ diff --git a/target/arm/machine.c b/target/arm/machine.c index 2c8b43062f..cae63c2f98 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -191,6 +191,41 @@ static const VMStateDescription vmstate_m_faultmask_primask = { } }; +/* CSSELR is in a subsection because we didn't implement it previously. + * Migration from an old implementation will leave it at zero, which + * is OK since the only CPUs in the old implementation make the + * register RAZ/WI. + * Since there was no version of QEMU which implemented the CSSELR for + * just non-secure, we transfer both banks here rather than putting + * the secure banked version in the m-security subsection. + */ +static bool csselr_vmstate_validate(void *opaque, int version_id) +{ + ARMCPU *cpu = opaque; + + return cpu->env.v7m.csselr[M_REG_NS] <= R_V7M_CSSELR_INDEX_MASK + && cpu->env.v7m.csselr[M_REG_S] <= R_V7M_CSSELR_INDEX_MASK; +} + +static bool m_csselr_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + + return !arm_v7m_csselr_razwi(cpu); +} + +static const VMStateDescription vmstate_m_csselr = { + .name = "cpu/m/csselr", + .version_id = 1, + .minimum_version_id = 1, + .needed = m_csselr_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(env.v7m.csselr, ARMCPU, M_REG_NUM_BANKS), + VMSTATE_VALIDATE("CSSELR is valid", csselr_vmstate_validate), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_m = { .name = "cpu/m", .version_id = 4, @@ -212,6 +247,7 @@ static const VMStateDescription vmstate_m = { }, .subsections = (const VMStateDescription*[]) { &vmstate_m_faultmask_primask, + &vmstate_m_csselr, NULL } };