From patchwork Mon Apr 29 17:00:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 163086 Delivered-To: patch@linaro.org Received: by 2002:a92:7e86:0:0:0:0:0 with SMTP id q6csp2173868ill; Mon, 29 Apr 2019 10:39:43 -0700 (PDT) X-Google-Smtp-Source: APXvYqwJVNDhFrzBWsyzpEfIvNMxlYdMuzOqsUVW/Tt4CRvCOv9OPR4cS0/Jl8DNEZ1e8LJzPHQI X-Received: by 2002:a05:6000:12c9:: with SMTP id l9mr939603wrx.302.1556559583370; Mon, 29 Apr 2019 10:39:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556559583; cv=none; d=google.com; s=arc-20160816; b=ZPOs8YWtZzJ+Byx7r1ppzbZAJQflc1sFmns7hnxAuttQf7Ac9o/WuDHUFzzIm7E43q RREmFgnO22boETpidcWlT32xgeqYuD3wx0ituOUYM3vHZWcaDv16X68lwr6NfxOwvsNQ 0LR60572zPBpk/0IGfnRu26kp4jTrh88J/awBRU3Wbo0wwVJlpiTJTLsOiTMpRI705bj 4qDdi61GW8mbesw9EFcBS+r26nwqvHmRIn4lGGzRoeODifaCkBprmKGw5oRujh19dCWG eoSiBjCvamXtAio4ja/D5lsC1s/h9KRRM60gAi5RbRWRHzGlOPetcDGdrEn8+hyddOhi ccxA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=LmOE0d83u1c72HUQ4AcSpNQ+fi+rYfjt+t1Pykdp+Yo=; b=un/jAiBfoS/WK8N/yG4ce6hfpJjUFzIpZ7lMd+s+bcSTCMcss67WTpzi6U2Z3JmC0z ASj030+RpBOuS31DPKhQ4bZ7+5XKSK4+U5zHZETjqWECYeCqi0pldwM0WByhcBe3PyLE N0JvRUFak1eoNPYB63T8nJ2e71x1iLULuvIYbY0ZB8Qzp52szod4D9pk2pw9X/uF8jm6 oLqfStp6TTtigdAgA7s2WlcvOHoQhldyV6T2TWfNJV8KPIFCcpgTJT3J0XeY1N+7R2EF m5Whpj7/tO8y1Q/npeWcRYWO7jBburW8qZobfz+NHsruzYVXqfWq1PB98xINrbSCsmeg sTOw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=CoXh3v0u; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id x15si2407886wrm.448.2019.04.29.10.39.43 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 29 Apr 2019 10:39:43 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=CoXh3v0u; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1]:32934 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hLAFi-00050g-9i for patch@linaro.org; Mon, 29 Apr 2019 13:39:42 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34753) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hL9fQ-0005WJ-Af for qemu-devel@nongnu.org; Mon, 29 Apr 2019 13:02:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hL9fO-00075Y-7T for qemu-devel@nongnu.org; Mon, 29 Apr 2019 13:02:12 -0400 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]:51179) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hL9fM-0006PQ-6O for qemu-devel@nongnu.org; Mon, 29 Apr 2019 13:02:10 -0400 Received: by mail-wm1-x332.google.com with SMTP id p21so186668wmc.0 for ; Mon, 29 Apr 2019 10:00:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=LmOE0d83u1c72HUQ4AcSpNQ+fi+rYfjt+t1Pykdp+Yo=; b=CoXh3v0u54eB+WuoQABFjvZjmpV/EtdHOWWc4XjhWBOL5dBoRC8JUOfZknyMN1QkqN dknBKPP8/C+92gk6Ytm44WW3THGOBxy2nHsB42cuNG4LSlQnm63EDLvBTQCQxmLv4z60 +OIxq18cXPuXFwFdG8+omYEYJybd2dc3F8UbGZzMXcPT5GpAxXfXDFvoM4tBK+GtDw+/ ZSMd3m2N3nCjlXsF4cSUOHDBLwqzlAvTIxqZOHMVEAg+QyU1lH5gJJJ4XcbpIybaTToT HwS1IL0GUcG0meGpxYVq1GKsmwOw+YMLTrH01suKSQ8jfHCWVfsyyhkBYu4dxWmysYoR XEyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LmOE0d83u1c72HUQ4AcSpNQ+fi+rYfjt+t1Pykdp+Yo=; b=PH8uvSWr5ft+ohRzxD4Peg4m/+WWe4Pbu9rOak68kEfSBgI57NxB3+S+KEKU+ulbM0 RlB6QiHg8lgDoiervq6/HUNHwbwOFLjleSrT6KLDVaoZl5HUOsVdGZvNHdlcdsLtDlLK hHAb74oJ2OmacEGOEvESjWAiicJhWkwaPK/3sjnHy9wXyhnRjM9Hcjjbsz4/c8gzArtW JPj+BvVYSwzR+06uDAvVSuOOQCY4nwKCN/tuXivBOcYZlt7H1z2pNMSqAlkWfoFka252 o19NtKk09adU0Sx1CdbmoNYSBtbO3tc9LT9K0vXpl7lnYB2RcWCG8nQ/ucea7CLi9pHU o9pA== X-Gm-Message-State: APjAAAUsmVjy6ZBez92LEVm21pkD4gKXJ2f1FktjcQt0Xz2Awyzln2al p3ox3K78a8skjCyg7YVJ207IMe7juWA= X-Received: by 2002:a1c:f702:: with SMTP id v2mr67290wmh.0.1556557250374; Mon, 29 Apr 2019 10:00:50 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id a13sm36896wmj.39.2019.04.29.10.00.49 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Apr 2019 10:00:49 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 29 Apr 2019 18:00:02 +0100 Message-Id: <20190429170030.11323-15-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190429170030.11323-1-peter.maydell@linaro.org> References: <20190429170030.11323-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::332 Subject: [Qemu-devel] [PULL 14/42] target/arm: Implement v7m_update_fpccr() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Implement the code which updates the FPCCR register on an exception entry where we are going to use lazy FP stacking. We have to defer to the NVIC to determine whether the various exceptions are currently ready or not. Signed-off-by: Peter Maydell Message-id: 20190416125744.27770-12-peter.maydell@linaro.org --- target/arm/cpu.h | 14 +++++++++ hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++ target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 114 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 67e4e95d440..eb989d773af 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2044,6 +2044,20 @@ 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, bool secure); +/** + * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure) + * @opaque: the NVIC + * @irq: the exception number to mark pending + * @secure: false for non-banked exceptions or for the nonsecure + * version of a banked exception, true for the secure version of a banked + * exception. + * + * Return whether an exception is "ready", i.e. whether the exception is + * enabled and is configured at a priority which would allow it to + * interrupt the current execution priority. This controls whether the + * RDY bit for it in the FPCCR is set. + */ +bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure); /** * armv7m_nvic_raw_execution_priority: return the raw execution priority * @opaque: the NVIC diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 5eb438f5409..53b4631dace 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -746,6 +746,40 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure) return ret; } +bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure) +{ + /* + * Return whether an exception is "ready", i.e. it is enabled and is + * configured at a priority which would allow it to interrupt the + * current execution priority. + * + * irq and secure have the same semantics as for armv7m_nvic_set_pending(): + * for non-banked exceptions secure is always false; for banked exceptions + * it indicates which of the exceptions is required. + */ + NVICState *s = (NVICState *)opaque; + bool banked = exc_is_banked(irq); + VecInfo *vec; + int running = nvic_exec_prio(s); + + assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq); + assert(!secure || banked); + + /* + * HardFault is an odd special case: we always check against -1, + * even if we're secure and HardFault has priority -3; we never + * need to check for enabled state. + */ + if (irq == ARMV7M_EXCP_HARD) { + return running > -1; + } + + vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq]; + + return vec->enabled && + exc_group_prio(s, vec->prio, secure) < running; +} + /* callback when external interrupt line is changed */ static void set_irq_level(void *opaque, int n, int level) { diff --git a/target/arm/helper.c b/target/arm/helper.c index 6e55da5c482..547898581a2 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8177,6 +8177,71 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain, env->thumb = addr & 1; } +static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr, + bool apply_splim) +{ + /* + * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR + * that we will need later in order to do lazy FP reg stacking. + */ + bool is_secure = env->v7m.secure; + void *nvic = env->nvic; + /* + * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits + * are banked and we want to update the bit in the bank for the + * current security state; and in one case we want to specifically + * update the NS banked version of a bit even if we are secure. + */ + uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S]; + uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS]; + uint32_t *fpccr = &env->v7m.fpccr[is_secure]; + bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy; + + env->v7m.fpcar[is_secure] = frameptr & ~0x7; + + if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) { + bool splimviol; + uint32_t splim = v7m_sp_limit(env); + bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) && + (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK); + + splimviol = !ign && frameptr < splim; + *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol); + } + + *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1); + + *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure); + + *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0); + + *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD, + !arm_v7m_is_handler_mode(env)); + + hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false); + *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy); + + bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false); + *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy); + + mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure); + *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy); + + ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false); + *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy); + + monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false); + *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy); + + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true); + *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy); + + sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false); + *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy); + } +} + static bool v7m_push_stack(ARMCPU *cpu) { /* Do the "set up stack frame" part of exception entry, @@ -8324,7 +8389,7 @@ static bool v7m_push_stack(ARMCPU *cpu) } } else { /* Lazy stacking enabled, save necessary info to stack later */ - /* TODO : equivalent of UpdateFPCCR() pseudocode */ + v7m_update_fpccr(env, frameptr + 0x20, true); } } }