From nobody Mon Feb 9 11:29:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1555419992; cv=none; d=zoho.com; s=zohoarc; b=ARMQGW3NzsHSaWKwOfh/37WNqzP9LbJLmlFQyFSatpxYW/QRW/fF5+Xjbu5A+MIYiSvuHB/AGg4M9eDDuCuF9mV9KdQ/SgiOnoJADFsJ/LY+UCTFTLeTTDuBTsXsdncpDSMrDaJ1VsRXWQhCgzoXyM5u5AL5wiu/J7SkXF38FB4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1555419992; h=Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=4RdrN7GA3r8yy/LIQmPOrXRIGWZZCxjf6XHcNWaC7So=; b=gseQd+ffQopnTjuWMEOoUMj+aMkrgqyWp4aa4XMaM+T46v/EXbVYPdoNpU8GuPTP287IApycJGNkEm5tg5HKkgCaaI0qKzWLKYvhOi1XO7HupOAXbReArk/sAQbG4Vh/vgmmVP65f4891wYgdxZMvvrnw3B8xdMY12CEKVUW8RA= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1555419992514328.15327582803775; Tue, 16 Apr 2019 06:06:32 -0700 (PDT) Received: from localhost ([127.0.0.1]:36391 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hGNnA-0002mv-Bd for importer@patchew.org; Tue, 16 Apr 2019 09:06:28 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34611) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hGNfF-0004nE-Rp for qemu-devel@nongnu.org; Tue, 16 Apr 2019 08:58:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hGNfE-0001Hj-1K for qemu-devel@nongnu.org; Tue, 16 Apr 2019 08:58:17 -0400 Received: from mail-wr1-x444.google.com ([2a00:1450:4864:20::444]:41751) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hGNfC-0001FV-3r for qemu-devel@nongnu.org; Tue, 16 Apr 2019 08:58:15 -0400 Received: by mail-wr1-x444.google.com with SMTP id r4so26906579wrq.8 for ; Tue, 16 Apr 2019 05:58:12 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id v184sm39476572wma.6.2019.04.16.05.58.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Apr 2019 05:58:10 -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=4RdrN7GA3r8yy/LIQmPOrXRIGWZZCxjf6XHcNWaC7So=; b=ovd5Dugtc5ym8g6PNqfZgcpHhg8AICVBnHu06SPNW74TVUkJqXw7Q4dL2WbUQG8tQZ ey30lUhD6FnhOshEJLjR+ADKuMrQy49kitMImXJbkN4U6dsZdhwmUkqYvbwxfwipKGr9 oQpK9l1yyRGBFNw6+PqqT+qbu/mDqUd8wBOKHvCayvRZwnHvqAmFlf/NYNQ42//3x36a pwUwDjv412D4HLSlZWrK3pZacVLYvmMOzHw026Oby6qbAfP0NOwsRIx0lcFoqofJSTkY ByjyOLhfTi7QQDLF0f8CZ5dPHZTgUfNXC96EagTi2wUz6ipuCanJWh7+XemBUGWrGsT+ 1Thw== 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=4RdrN7GA3r8yy/LIQmPOrXRIGWZZCxjf6XHcNWaC7So=; b=JgcYV2DHE+R/59fo43cXb5CLuMP3Rl/v+uAJ5+2Ltqs/du6avzQEYJNZLro1lw8zBh RZZGYR90jK521K5S9dtB2fpXYUDkNk60M/e4I4DbISI5UrsoefzWQyLkAGhXqa8NAS1v iHZ05A+1kDKW7onhCtSrMz5pOqvQatiEjWganaTSVfnj7x3WY79Xuv/3wruiVyiXgVTS V/tWvWqw+4JvfBv3qCWe6L+/XRCZkBcmMXeI+GzFeIYLBm+nzUJ7Dl8Fg3eHv32xyxSe tkwdKZxkpG4DHRPVlHzJJ9czahlsvaGRVTrMTSLRUpzjz4oE7zbpVbPBmNjAovXgBNmP f+kA== X-Gm-Message-State: APjAAAVuXUHxJqJ/J6QyA9dyZvb3THzZAa2nF0P31ndYF84UEHBa0L4+ XoDMZn6Oa5yJm0e/KJLd5GeCkA== X-Google-Smtp-Source: APXvYqxXrryAM+9Mf6N9ZqhYorAGtC0xnGFAQDrlTehf6yI2CVMmAyw8TajpxRB0nkB17yWN1YHB+w== X-Received: by 2002:a5d:448b:: with SMTP id j11mr18983611wrq.218.1555419491605; Tue, 16 Apr 2019 05:58:11 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 16 Apr 2019 13:57:29 +0100 Message-Id: <20190416125744.27770-12-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190416125744.27770-1-peter.maydell@linaro.org> References: <20190416125744.27770-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::444 Subject: [Qemu-devel] [PATCH 11/26] 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Type: text/plain; charset="utf-8" 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 --- target/arm/cpu.h | 14 +++++++++ hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++ target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index c8d78bd5b52..0e0cb6b2271 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -2045,6 +2045,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, bo= ol secure) return ret; } =20 +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_pendi= ng(): + * for non-banked exceptions secure is always false; for banked except= ions + * it indicates which of the exceptions is required. + */ + NVICState *s =3D (NVICState *)opaque; + bool banked =3D exc_is_banked(irq); + VecInfo *vec; + int running =3D 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 =3D=3D ARMV7M_EXCP_HARD) { + return running > -1; + } + + vec =3D (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 7b2174a5e61..7298f9de735 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8182,6 +8182,71 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_= t lr, bool dotailchain, env->thumb =3D addr & 1; } =20 +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 =3D env->v7m.secure; + void *nvic =3D 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 =3D &env->v7m.fpccr[M_REG_S]; + uint32_t *fpccr_ns =3D &env->v7m.fpccr[M_REG_NS]; + uint32_t *fpccr =3D &env->v7m.fpccr[is_secure]; + bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy; + + env->v7m.fpcar[is_secure] =3D frameptr & ~0x7; + + if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) { + bool splimviol; + uint32_t splim =3D v7m_sp_limit(env); + bool ign =3D armv7m_nvic_neg_prio_requested(nvic, is_secure) && + (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK); + + splimviol =3D !ign && frameptr < splim; + *fpccr =3D FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol); + } + + *fpccr =3D FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1); + + *fpccr_s =3D FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure); + + *fpccr =3D FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) =3D= =3D 0); + + *fpccr =3D FIELD_DP32(*fpccr, V7M_FPCCR, THREAD, + !arm_v7m_is_handler_mode(env)); + + hfrdy =3D armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false); + *fpccr_s =3D FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy); + + bfrdy =3D armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false); + *fpccr_s =3D FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy); + + mmrdy =3D armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secur= e); + *fpccr =3D FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy); + + ns_ufrdy =3D armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, fal= se); + *fpccr_ns =3D FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy); + + monrdy =3D armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false= ); + *fpccr_s =3D FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy); + + if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { + s_ufrdy =3D armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, = true); + *fpccr_s =3D FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy); + + sfrdy =3D armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, f= alse); + *fpccr_s =3D 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, @@ -8329,7 +8394,7 @@ static bool v7m_push_stack(ARMCPU *cpu) } } else { /* Lazy stacking enabled, save necessary info to stack lat= er */ - /* TODO : equivalent of UpdateFPCCR() pseudocode */ + v7m_update_fpccr(env, frameptr + 0x20, true); } } } --=20 2.20.1