From nobody Mon Feb 9 11:29:39 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=1555419903; cv=none; d=zoho.com; s=zohoarc; b=ogdlKkPdRuR8N308XU7atEYNVob06cGlYV8lt6h/GQjWBtTJpe+FwLQ5KL1uo6xmpUQFWnZqUlDa00hhuytXQhBVLSYp5oF+KqwztTtjCvHM4hAHqtcNcA1YK+EKE8dmjNku9w3Ming/244RZCLBPXHR3TsGsvlXRjeuVQQXTCk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1555419903; 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=o6hagmVvoqqJ0XtX75gSSLbFcTrXtyoSJl24uehJGoY=; b=fximRreHvj0hrB6ulZyQahBWkyAlGGEEXiWNkCfRrN74qiWRRzAeP7trIrxJjiFWnuAarpIuaLVRt4ZxVPZo/GJujb8enWKIY4g2P9V56aEpaE/VyZkQEwwQmMauz3TYtIaIkJjcSxQWXOnTCv0wfi/zZunW8cLqIV2iHYhYuMc= 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 1555419903283100.40487642801861; Tue, 16 Apr 2019 06:05:03 -0700 (PDT) Received: from localhost ([127.0.0.1]:36351 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hGNli-0001UE-FB for importer@patchew.org; Tue, 16 Apr 2019 09:04:58 -0400 Received: from eggs.gnu.org ([209.51.188.92]:34521) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hGNf9-0004dN-5P for qemu-devel@nongnu.org; Tue, 16 Apr 2019 08:58:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hGNf7-0001C6-2s for qemu-devel@nongnu.org; Tue, 16 Apr 2019 08:58:11 -0400 Received: from mail-wm1-x341.google.com ([2a00:1450:4864:20::341]:40152) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hGNf6-0001Ai-O7 for qemu-devel@nongnu.org; Tue, 16 Apr 2019 08:58:08 -0400 Received: by mail-wm1-x341.google.com with SMTP id z24so25491371wmi.5 for ; Tue, 16 Apr 2019 05:58:08 -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.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 Apr 2019 05:58:06 -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=o6hagmVvoqqJ0XtX75gSSLbFcTrXtyoSJl24uehJGoY=; b=nM9l7XCc7gjhpeHvgu+2rSd3D+u1riAjplh5a0iOHP1PF007LI+WLvRwY2g7z2JUrw EgbRnZbmJaWmMx/k/vFPLnT0CCI7kSKVBeMcPEuJ8opB5qFaVPSmYxgQbOlfrlwsrR5o adwoCgte+R+1OuS6q2y8e3OGXHHMU+iMxftRXHir0iyeOm7UeYXhZ8EPkhTEcVQWpdQ5 Wh+oFGTqvUd2nPBjMez4HFcFihu0DmMtRbmFKxCrd/dWT6FhEb56FpjPMcd9Yc+bKrbc 1Dogx5jksBuBMT6v5U4xqUmIE4VsnYoUJCMMBMR5wV2T/agNgkeK8NxtOH4G/nKkqo7T X3pA== 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=o6hagmVvoqqJ0XtX75gSSLbFcTrXtyoSJl24uehJGoY=; b=J+MXuGDapQy18T14kTx/NIGlEIU7zc25r96ybWKKhn1JmF+KCLQ4InPep4zMiM9OKg x4uqvnfgIAWUHxFgVorr02i2UC+X3pYrsXYVl6qaCFVhQ/BAZu36Vnra8J435whQczmj TSOfyqTJqHv5fKY9JQkzQLL0/VvBQPWubG0GG6zmxZWvXkLYPRZYjX2dGxeeta5boDdT O+80CqJX1TWBdcVDr4QXKw7557Z3ozezRnKN/ZmWlY3w7TU6ACQlrGKybd82mSd5aWJf aHWoGWRkyXQHoN0kdxqqbWYOGEV/2Hx8suIHdJRCHfg//psEBoiL3NyekEFBb7jZNwiz 7zLA== X-Gm-Message-State: APjAAAWBQMTcYO2595791lcYcITk1BO+XAIfNMCp3O71U1MOe+vT6bNa 1RZ7PcXnyxDllUOKrMYtQaDggg== X-Google-Smtp-Source: APXvYqwuK/toMq2uHlf7IyhOlZ2Fnyz4B5Gf2gTS5ejcFd51fMLXplVndsNzOIbdUV/DgYqYARu6/w== X-Received: by 2002:a1c:804c:: with SMTP id b73mr25470401wmd.116.1555419487425; Tue, 16 Apr 2019 05:58:07 -0700 (PDT) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Date: Tue, 16 Apr 2019 13:57:28 +0100 Message-Id: <20190416125744.27770-11-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::341 Subject: [Qemu-devel] [PATCH 10/26] target/arm: Handle floating point registers in exception entry 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" Handle floating point registers in exception entry. This corresponds to the FP-specific parts of the pseudocode functions ActivateException() and PushStack(). We defer the code corresponding to UpdateFPCCR() to a later patch. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index a2222f84803..7b2174a5e61 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -8172,6 +8172,9 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t= lr, bool dotailchain, switch_v7m_security_state(env, targets_secure); write_v7m_control_spsel(env, 0); arm_clear_exclusive(env); + /* Clear SFPA and FPCA (has no effect if no FPU) */ + env->v7m.control[M_REG_S] &=3D + ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK); /* Clear IT bits */ env->condexec_bits =3D 0; env->regs[14] =3D lr; @@ -8192,6 +8195,20 @@ static bool v7m_push_stack(ARMCPU *cpu) uint32_t xpsr =3D xpsr_read(env); uint32_t frameptr =3D env->regs[13]; ARMMMUIdx mmu_idx =3D arm_mmu_idx(env); + uint32_t framesize; + bool nsacr_cp10 =3D extract32(env->v7m.nsacr, 10, 1); + + if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) && + (env->v7m.secure || nsacr_cp10)) { + if (env->v7m.secure && + env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) { + framesize =3D 0xa8; + } else { + framesize =3D 0x68; + } + } else { + framesize =3D 0x20; + } =20 /* Align stack pointer if the guest wants that */ if ((frameptr & 4) && @@ -8200,7 +8217,13 @@ static bool v7m_push_stack(ARMCPU *cpu) xpsr |=3D XPSR_SPREALIGN; } =20 - frameptr -=3D 0x20; + xpsr &=3D ~XPSR_SFPA; + if (env->v7m.secure && + (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) { + xpsr |=3D XPSR_SFPA; + } + + frameptr -=3D framesize; =20 if (arm_feature(env, ARM_FEATURE_V8)) { uint32_t limit =3D v7m_sp_limit(env); @@ -8244,6 +8267,73 @@ static bool v7m_push_stack(ARMCPU *cpu) v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false)= && v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false); =20 + if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) { + /* FPU is active, try to save its registers */ + bool fpccr_s =3D env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK; + bool lspact =3D env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK; + + if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) { + qemu_log_mask(CPU_LOG_INT, + "...SecureFault because LSPACT and FPCA both set= \n"); + env->v7m.sfsr |=3D R_V7M_SFSR_LSERR_MASK; + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false); + } else if (!env->v7m.secure && !nsacr_cp10) { + qemu_log_mask(CPU_LOG_INT, + "...Secure UsageFault with CFSR.NOCP because " + "NSACR.CP10 prevents stacking FP regs\n"); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S); + env->v7m.cfsr[M_REG_S] |=3D R_V7M_CFSR_NOCP_MASK; + } else { + if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) { + /* Lazy stacking disabled, save registers now */ + int i; + bool cpacr_pass =3D v7m_cpacr_pass(env, env->v7m.secure, + arm_current_el(env) !=3D = 0); + + if (stacked_ok && !cpacr_pass) { + /* + * Take UsageFault if CPACR forbids access. The pseudo= code + * here does a full CheckCPEnabled() but we know the N= SACR + * check can never fail as we have already handled tha= t. + */ + qemu_log_mask(CPU_LOG_INT, + "...UsageFault with CFSR.NOCP because " + "CPACR.CP10 prevents stacking FP regs\n"= ); + armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, + env->v7m.secure); + env->v7m.cfsr[env->v7m.secure] |=3D R_V7M_CFSR_NOCP_MA= SK; + stacked_ok =3D false; + } + + for (i =3D 0; i < ((framesize =3D=3D 0xa8) ? 32 : 16); i += =3D 2) { + uint64_t dn =3D *aa32_vfp_dreg(env, i / 2); + uint32_t faddr =3D frameptr + 0x20 + 4 * i; + uint32_t slo =3D extract64(dn, 0, 32); + uint32_t shi =3D extract64(dn, 32, 32); + + if (i >=3D 16) { + faddr +=3D 8; /* skip the slot for the FPSCR */ + } + stacked_ok =3D stacked_ok && + v7m_stack_write(cpu, faddr, slo, mmu_idx, false) && + v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, fals= e); + } + stacked_ok =3D stacked_ok && + v7m_stack_write(cpu, frameptr + 0x60, + vfp_get_fpscr(env), mmu_idx, false); + if (cpacr_pass) { + for (i =3D 0; i < ((framesize =3D=3D 0xa8) ? 32 : 16);= i +=3D 2) { + *aa32_vfp_dreg(env, i / 2) =3D 0; + } + vfp_set_fpscr(env, 0); + } + } else { + /* Lazy stacking enabled, save necessary info to stack lat= er */ + /* TODO : equivalent of UpdateFPCCR() pseudocode */ + } + } + } + /* * If we broke a stack limit then SP was already updated earlier; * otherwise we update SP regardless of whether any of the stack @@ -9004,8 +9094,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) =20 if (arm_feature(env, ARM_FEATURE_V8)) { lr =3D R_V7M_EXCRET_RES1_MASK | - R_V7M_EXCRET_DCRS_MASK | - R_V7M_EXCRET_FTYPE_MASK; + R_V7M_EXCRET_DCRS_MASK; /* The S bit indicates whether we should return to Secure * or NonSecure (ie our current state). * The ES bit indicates whether we're taking this exception @@ -9020,6 +9109,9 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) if (env->v7m.secure) { lr |=3D R_V7M_EXCRET_S_MASK; } + if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) { + lr |=3D R_V7M_EXCRET_FTYPE_MASK; + } } else { lr =3D R_V7M_EXCRET_RES1_MASK | R_V7M_EXCRET_S_MASK | --=20 2.20.1