From patchwork Wed Oct 10 20:37:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982095 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="fSIrR3BJ"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmFs3F78z9s9J for ; Thu, 11 Oct 2018 07:40:49 +1100 (AEDT) Received: from localhost ([::1]:59035 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALHj-00041Y-3N for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:40:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39572) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFa-0002qP-MV for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFZ-0002Ts-Im for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:34 -0400 Received: from mail-yw1-xc35.google.com ([2607:f8b0:4864:20::c35]:37548) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFR-0002Mx-C7; Wed, 10 Oct 2018 16:38:26 -0400 Received: by mail-yw1-xc35.google.com with SMTP id y14-v6so2726189ywa.4; Wed, 10 Oct 2018 13:38:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=O/InNUI5zywfTNAUJd/dlvGPiQLYFT0XunI5ik12f+Q=; b=fSIrR3BJUdLlvCiF4r84EIzOvBhwC0Ra29+k1UE8+wx2mKhaawzXVUYl77q1jcaxQX Dlc/F4K109cboP5GbTwFYNnDSEUDb0+a1uOFws8PWClmSFuMuVtAyIvq4pFvtETV6/xS FbhIj4qNZUo0FprXdfW3O6rAtT763qlaSIr/SkHAO/20JnGEAq9HHcYF8rSEi6hyvP/S 0mjJoZyl9qMxvqk6OMUV9EEVZ9EvEXaHxgJ+jJbWT3qpVr4TWjS2SbElNsmvXV/eY3wg +UJrz8HyjY2y5UTaBmUraStl7hNO1sSqIMX4It4zr6YTO4FlqCPTt35GPZKxWmKIeMr6 ECZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=O/InNUI5zywfTNAUJd/dlvGPiQLYFT0XunI5ik12f+Q=; b=NlFc1wIQ38Sz+euS2tqak7esGOgGuX/aJ4Lm3+E+P/viLXiwD/wJ9cfywZhWIvkHS7 nm4fOokqwJvUBikRh1ZKWuPloCp89yl4KPBX+lGkmv154zLK68q7RXvod7TJBNLVKkl8 u3pP3qB36c/ZHFyIucYZYovrHmlqTIswymy2VNuDJIMKVEnC0RlGBUm1PjlQAGPvauqZ n2L5fZP6z0dvh1gT8BOTuWoz63pR2llH+tecAS0efNeyX29yrSqlRsZLa+bkNL23awft s+h92MeWb/YiSh0Gk/LGRrx2VnvuDjDiiO8EvcryiMYYqb4Wyi+J7egm2x1rrStaCFOQ czDg== X-Gm-Message-State: ABuFfohN2OCxgz3M2tLm4Z/+CY7AYVikLnHoi3Uwv4t5lg3xabmJZcft tY9miYX0ceb9Ewz73gLDe4HS7TtN X-Google-Smtp-Source: ACcGV600UHwZFrRy1AscU55CMaN3247OhgZv3c4H3+7LJ6cBelsufQZPl5hwPfJfQ7H1BiV/htuwKA== X-Received: by 2002:a81:3e0d:: with SMTP id l13-v6mr15862823ywa.380.1539203904226; Wed, 10 Oct 2018 13:38:24 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:23 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:22 -0400 Message-Id: <20181010203735.27918-2-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c35 Subject: [Qemu-devel] [PATCH v6 01/14] target/arm: Mark PMINTENCLR and PMINTENCLR_EL1 accesses as possibly doing IO 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" I previously fixed this for PMINTENSET_EL1, but missed these. Signed-off-by: Aaron Lindsay Signed-off-by: Aaron Lindsay Reviewed-by: Richard Henderson --- target/arm/helper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index c83f7c1109..52c76b7444 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1423,12 +1423,14 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .writefn = pmintenset_write, .raw_writefn = raw_write, .resetvalue = 0x0 }, { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 2, - .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS, + .access = PL1_RW, .accessfn = access_tpm, + .type = ARM_CP_ALIAS | ARM_CP_IO, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), .writefn = pmintenclr_write, }, { .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2, - .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS, + .access = PL1_RW, .accessfn = access_tpm, + .type = ARM_CP_ALIAS | ARM_CP_IO, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), .writefn = pmintenclr_write }, { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH, From patchwork Wed Oct 10 20:37:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982099 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="oUS9Coit"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmKQ5wNBz9s9h for ; Thu, 11 Oct 2018 07:43:54 +1100 (AEDT) Received: from localhost ([::1]:59057 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALKi-0006g2-AR for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:43:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39612) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFb-0002rS-Ng for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFa-0002Ue-ET for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:35 -0400 Received: from mail-yb1-xb41.google.com ([2607:f8b0:4864:20::b41]:36965) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFS-0002NZ-Sy; Wed, 10 Oct 2018 16:38:27 -0400 Received: by mail-yb1-xb41.google.com with SMTP id h1-v6so2762019ybm.4; Wed, 10 Oct 2018 13:38:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=epJp5s2jRMOo1Q26kIc83hFAj7hWogQkg7AnaFDhYiQ=; b=oUS9CoitPfGxjrjrRb8uW1vZvWziB8rf+tBxmwKBwh7Uc6rCdthdGj9uqgk6MvyAJq sb92Rvj00hwLAP2NaIqkfHzMD7ao7fCYorilrQb15ADcgzcnYiJHQWU+79R7HgaTwoge DJETvFxHdBtU8o4Lir5Tmv+hLtC/2u7R1nzU5goZLR+MxcreRt3nFrRBLkIn0J4kioS3 LkpcaBzPINRUwiHpTACXOKndKtnzNbvHSXoPStvw3W3KNjqJJHtPqxVX/1ef/fTAinlg 7n+AUFvK1qEGhmJIAxi/3LaQiIaJRVHUYz43dIb/vWX9Spoh5Ccun25VTHiB557uOPmd 2SIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=epJp5s2jRMOo1Q26kIc83hFAj7hWogQkg7AnaFDhYiQ=; b=TIjsNZXBygklpTklG6sA7g12y9DGVpq7vTdmpFdi/9txkz5XfnJGuqOMnty65XQxWY AzBJHyQ/qP3O5tkNE6b0SJaigkEAlu8lMsIoEOd9GNYH+aEqvGwZzVGOuw4sBwtxwrr/ BoSsh9MUt9K91eEbSaJjO/wHMrPO+iDA7qz7sVk3V8P4enSY3ncsBqXVC2JpNBNK0ewe Nvt4/guTNZiJqOUyOlyd/wzF6uUcqeAYPFErY98Rc8qnMNtz3JJAfxe8QTlYnH/0bXs5 x1qKx8z3gOLSjIaHT5LdPe68CbpcZibmqmeC1Dpv6/daG8GfzdzLQtkTCkxzfmp6rXqM XB8Q== X-Gm-Message-State: ABuFfogg7Vd4Zmb2ksP6cmEaZnyX+1CraZBVQzGED9HYzCeXXmsP04Wa kBp2ppdPL2lckDntL0XBWTLh0Sv1 X-Google-Smtp-Source: ACcGV60liFklIf++ip0JKb0u5eNdwG/wAKE18GQ/ZxDaDUd3JvsyYVMgVpdgLkKdXRlACHG6XGigbw== X-Received: by 2002:a25:4246:: with SMTP id p67-v6mr19978771yba.178.1539203905140; Wed, 10 Oct 2018 13:38:25 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:24 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:23 -0400 Message-Id: <20181010203735.27918-3-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::b41 Subject: [Qemu-devel] [PATCH v6 02/14] target/arm: Mask PMOVSR writes based on supported counters 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This is an amendment to my earlier patch: commit 7ece99b17e832065236c07a158dfac62619ef99b Author: Aaron Lindsay Date: Thu Apr 26 11:04:39 2018 +0100 target/arm: Mask PMU register writes based on PMCR_EL0.N Signed-off-by: Aaron Lindsay Reviewed-by: Richard Henderson --- target/arm/helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/target/arm/helper.c b/target/arm/helper.c index 52c76b7444..8ca4d30797 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1179,6 +1179,7 @@ static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { + value &= pmu_counter_mask(env); env->cp15.c9_pmovsr &= ~value; } From patchwork Wed Oct 10 20:37:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982102 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="A2zugbyK"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmNX4sddz9s9J for ; Thu, 11 Oct 2018 07:46:36 +1100 (AEDT) Received: from localhost ([::1]:59076 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALNK-0000TM-8y for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:46:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39618) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFb-0002rn-Sz for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFa-0002V0-P3 for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:35 -0400 Received: from mail-yb1-xb42.google.com ([2607:f8b0:4864:20::b42]:41873) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFV-0002Np-M1; Wed, 10 Oct 2018 16:38:29 -0400 Received: by mail-yb1-xb42.google.com with SMTP id e16-v6so2754152ybk.8; Wed, 10 Oct 2018 13:38:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lcqRW3+QlXEvaODHcyzMa2/tXsQVITsUxvIKVHTwHag=; b=A2zugbyKfkLhrC/EK5ZhMoWjJnaJrlgHaeZd6PlTL/4Wfpqlk35eVT0Ri0+NabE12a 3ScegIXeHBb2pCiV+WRni46R1Qg0uNFCv8oGkgc0bEZgXX5Sk7pdL6gDlJ8wCLcvG8r2 iEpRk4cY5qvg2yWyuLkCnPquraDTaLeeI7EWx27QCg6/jFlM+jdCRPDBUjKofbOzHHWv 6gn0EQa1JAl5Az9/jlODtZNGJwxK0sS7OzqnVU/umBfqxujqV5AQR+gDNw7Q8rLWqs/9 ZZeArpyc8nlKSXpD2bj2F0rLwuZZIkiw7iWuuxZfPmODFUAfx6iSsMpdTpvfG1H+kvB+ ktzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lcqRW3+QlXEvaODHcyzMa2/tXsQVITsUxvIKVHTwHag=; b=WzINA1mYZ1+bK6bAOcI4MvOoMAkpfgwfnBT8vAAmlGLi1R7Jkqx6t3v5nGOO+1PKDN oeWKuVN/LALkBrfZOxD7zRRrSCpyLsf8PAiX7ctcm4qXcfASMP0GJJsJWgZW+OEbMtFF YEEDdsjZJidtuE1asbZTIjuHOhcyCll6dK+ATVWBRN8Kf9xAFLi62GW4gS6n2ELRWiXv L+TUL9yULGPP5mATMTxoCoeYYmpfBGQtXxtYLfc0lMAHECoGAWB2EqFmHyszeCDXpOt2 IAHr8Jj1XHZ7nqqLwsuR8r2O9oj5znRTa+jewqO7SGluu94BDSGXfyd6aQnlWJkLtsX9 RHZQ== X-Gm-Message-State: ABuFfoiJP5MT1VEWni0kiSeY2o3NBYGEXi584qMf7McOxfCsDBFmWTDY HFYhh6OtaKH1yLr/co7v1KqwNt8j X-Google-Smtp-Source: ACcGV62G8A8xLq164W9roei0Yrn8VOJzAqkRuQcDjcRKYZhJKhLKsmvevsqAjtZ8a9ZOcZGn4X314g== X-Received: by 2002:a25:ace2:: with SMTP id x34-v6mr19272250ybd.161.1539203905994; Wed, 10 Oct 2018 13:38:25 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:25 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:24 -0400 Message-Id: <20181010203735.27918-4-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::b42 Subject: [Qemu-devel] [PATCH v6 03/14] migration: Add post_save function to VMStateDescription 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" In some cases it may be helpful to modify state before saving it for migration, and then modify the state back after it has been saved. The existing pre_save function provides half of this functionality. This patch adds a post_save function to provide the second half. Signed-off-by: Aaron Lindsay --- docs/devel/migration.rst | 9 +++++++-- include/migration/vmstate.h | 1 + migration/vmstate.c | 10 +++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst index 687570754d..2a2533c9b3 100644 --- a/docs/devel/migration.rst +++ b/docs/devel/migration.rst @@ -419,8 +419,13 @@ The functions to do that are inside a vmstate definition, and are called: This function is called before we save the state of one device. -Example: You can look at hpet.c, that uses the three function to -massage the state that is transferred. +- ``void (*post_save)(void *opaque);`` + + This function is called after we save the state of one device + (even upon failure, unless the call to pre_save returned and error). + +Example: You can look at hpet.c, that uses the first three functions +to massage the state that is transferred. The ``VMSTATE_WITH_TMP`` macro may be useful when the migration data doesn't match the stored device data well; it allows an diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 2b501d0466..f6053b94e4 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -185,6 +185,7 @@ struct VMStateDescription { int (*pre_load)(void *opaque); int (*post_load)(void *opaque, int version_id); int (*pre_save)(void *opaque); + void (*post_save)(void *opaque); bool (*needed)(void *opaque); VMStateField *fields; const VMStateDescription **subsections; diff --git a/migration/vmstate.c b/migration/vmstate.c index 0bc240a317..9afc9298f3 100644 --- a/migration/vmstate.c +++ b/migration/vmstate.c @@ -387,6 +387,9 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, if (ret) { error_report("Save of field %s/%s failed", vmsd->name, field->name); + if (vmsd->post_save) { + vmsd->post_save(opaque); + } return ret; } @@ -412,7 +415,12 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, json_end_array(vmdesc); } - return vmstate_subsection_save(f, vmsd, opaque, vmdesc); + ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc); + + if (vmsd->post_save) { + vmsd->post_save(opaque); + } + return ret; } static const VMStateDescription * From patchwork Wed Oct 10 20:37:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982093 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ju6/xA8C"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmDf2XnCz9s9J for ; Thu, 11 Oct 2018 07:39:46 +1100 (AEDT) Received: from localhost ([::1]:59028 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALGi-0003EW-2N for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:39:44 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39606) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFb-0002rP-KS for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFa-0002UU-Bn for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:35 -0400 Received: from mail-yw1-xc33.google.com ([2607:f8b0:4864:20::c33]:45351) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFV-0002O7-Oo; Wed, 10 Oct 2018 16:38:29 -0400 Received: by mail-yw1-xc33.google.com with SMTP id v198-v6so2715262ywg.12; Wed, 10 Oct 2018 13:38:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9LgMESnU90CXq7QaCFmtET89r/Lwth2hK4KRVmXI3YQ=; b=Ju6/xA8C9yJyiCZuTmnLcJ4OZKtdNDzE9YRLLA+rXYkI3wdOd/hz2qcOxIXrnT6POg 8kGxyJLYnhJS6SrNbwEbQa5Un+SU/GQr/SylwfgARXU/Ow99ewpmwrJqyQ4DLgJkSNQ/ tViL+wfFAdGey6++jC/IkeQaXYg0sFJh4p5t95K5306ETE2MA+HOtu8WFt/8MqJK9le0 EqL6mgmt6mICogDd7lQrqshOyi4AnW5VoorlHPRuthdXNkAm00dCeJkYOwvEjdUczPPT dHxeLg6nnHfaMGgJ/jKQpMUpljws9GrdUz7whcJ8nw55Gkt9YuhAL1BmLY7IuTWh3Jgg YOYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9LgMESnU90CXq7QaCFmtET89r/Lwth2hK4KRVmXI3YQ=; b=lmcp+jEbX0FR8MpQ5DGPtiH/DHi/ksD4i0x6ksHlT7Pe4LjxBQy7hpjQdF7D7ZrMox yA+Uizt2vW/OAqeaLT7VBf5iSPjM9YzS+bxiDic8SZ3//RyLNAFEfv4D7gOmNq5BRkwW o4iZkQUngmnNNWw4wNJD2ARzuA1tydlEQ2y/1Y9s+q5FhCWC8kHjToJIMcMALGmOrwtw FHCGTNqPiMKz1dlRZxrOmRRgj/CMiMfJR63hvMEll5035KOOmFc0I576/ZOoCRC9ahwz wX32dEN+VednbEbWLqaZwkwzVsi0DDBHDyxWHMH1ImylzUArMU++X2sbRp5KqRqXp4K/ gKVw== X-Gm-Message-State: ABuFfogWtDWvgyRTjMLOBeBCeoGp7YWuvR5+goX91A47bWl6ZOZeWtil DckAuCEgfnXvlouy80SriBdMoil4 X-Google-Smtp-Source: ACcGV63xP9jMaTunod9SIuggcCOe8p/gtC79UTmdzgxGPSIcP3T6NkaosWJdrhC+3oniF0JsTA9wkw== X-Received: by 2002:a81:af0d:: with SMTP id n13-v6mr19874371ywh.243.1539203906871; Wed, 10 Oct 2018 13:38:26 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:26 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:25 -0400 Message-Id: <20181010203735.27918-5-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c33 Subject: [Qemu-devel] [PATCH v6 04/14] target/arm: Swap PMU values before/after migrations 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Because of the PMU's design, many register accesses have side effects which are inter-related, meaning that the normal method of saving CP registers can result in inconsistent state. These side-effects are largely handled in *op_start and *op_finish functions which can be called globally once before and after the state is saved/restored. By doing this and adding raw read/write functions for the affected registers, we avoid such inconsistencies. Signed-off-by: Aaron Lindsay --- target/arm/helper.c | 6 ++++-- target/arm/machine.c | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 8ca4d30797..12c53e54e9 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1379,11 +1379,13 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0, .access = PL0_RW, .accessfn = pmreg_access_ccntr, .type = ARM_CP_IO, - .readfn = pmccntr_read, .writefn = pmccntr_write, }, + .fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt), + .readfn = pmccntr_read, .writefn = pmccntr_write, + .raw_readfn = raw_read, .raw_writefn = raw_write, }, #endif { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7, - .writefn = pmccfiltr_write, + .writefn = pmccfiltr_write, .raw_writefn = raw_write, .access = PL0_RW, .accessfn = pmreg_access, .type = ARM_CP_IO, .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0), diff --git a/target/arm/machine.c b/target/arm/machine.c index ff4ec22bf7..8139b25be5 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -584,6 +584,8 @@ static int cpu_pre_save(void *opaque) { ARMCPU *cpu = opaque; + pmccntr_sync(&cpu->env); + if (kvm_enabled()) { if (!write_kvmstate_to_list(cpu)) { /* This should never fail */ @@ -605,6 +607,19 @@ static int cpu_pre_save(void *opaque) return 0; } +static void cpu_post_save(void *opaque) +{ + ARMCPU *cpu = opaque; + pmccntr_sync(&cpu->env); +} + +static int cpu_pre_load(void *opaque) +{ + ARMCPU *cpu = opaque; + pmccntr_sync(&cpu->env); + return 0; +} + static int cpu_post_load(void *opaque, int version_id) { ARMCPU *cpu = opaque; @@ -652,6 +667,8 @@ static int cpu_post_load(void *opaque, int version_id) hw_breakpoint_update_all(cpu); hw_watchpoint_update_all(cpu); + pmccntr_sync(&cpu->env); + return 0; } @@ -660,6 +677,8 @@ const VMStateDescription vmstate_arm_cpu = { .version_id = 22, .minimum_version_id = 22, .pre_save = cpu_pre_save, + .post_save = cpu_post_save, + .pre_load = cpu_pre_load, .post_load = cpu_post_load, .fields = (VMStateField[]) { VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16), From patchwork Wed Oct 10 20:37:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982100 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="jmllguFn"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmMJ2wHxz9s9h for ; Thu, 11 Oct 2018 07:45:32 +1100 (AEDT) Received: from localhost ([::1]:59065 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALMH-00082t-Sz for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:45:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39682) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFd-0002tz-AK for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFb-0002VV-4U for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:37 -0400 Received: from mail-yb1-xb44.google.com ([2607:f8b0:4864:20::b44]:41875) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFW-0002Ot-4x; Wed, 10 Oct 2018 16:38:30 -0400 Received: by mail-yb1-xb44.google.com with SMTP id e16-v6so2754190ybk.8; Wed, 10 Oct 2018 13:38:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8o7r+L784EqpSUAfBfXajjBjgRbCBKlWPESSLsmMw6E=; b=jmllguFnOtbM8pU8ePiSF10VTY3gv7WhbbgpT+NTcI34pMGoyEIHzDtMHuWA9h4Lzk HDWykrdZ5xUjRXdJPKYSsi+J+sDusJQxx7hK9IVcXTlf5Upxw+hwB631V8iRvvFqGww3 6+fyfIbxOISLmQxyAJvKJUnmjgJLXI1/Cu2VkcJJu39z1jQA5/8EaAD5u61ytYtM1SNC KqGDQ+arzN5msi5I7X6sx4ROuDecXe7tW3tiCx95GBJjSAx50OHpLP25Bkr3GZK8ChJR Ye57JJ3Z+ul2UQYAkPx6ffRZOwFfVJsM/x+pZ7JfUY2H1yiorywjVNFJDCvnXwQA0aUl QQ/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8o7r+L784EqpSUAfBfXajjBjgRbCBKlWPESSLsmMw6E=; b=Fkkk8sxIzk8Wi2jBNuqHyCI5k/mNXaGDUy0158YakD0i+VlPUp319vK1E1mqj2ERFe O2y9A2dJgRy2STmKWXHfNh9JzQKwHrL/odVEStK2a/88OSzatHsIyvDpfQsy5nlV8NGe 24tjKc+Ms461eCUI+NV6Ey3l+qBnggc1TWXhtfWJlqLW3Lc7jEikcEzBhJZu/FxpvCx5 zAXNMJnIsOR7ACEmMK0Sa/Brsts/yy6EQrWBZSf3W2C+OHhk8YswBn9n8kEw4CWIWYSp P7/GHFAqeweLMmJzi5YOXcqjT6xao+eWqNHPkD/kqFRvuCPzve8kHTvzcKuuAQaluqAF g4Rw== X-Gm-Message-State: ABuFfohgLNwNfwPbObd3gHU3rKTHCREansthtRdbgmsm6/ImE4NMYSii Xfh0wHInbW0/9HRrS4QbWdiLJ3l9 X-Google-Smtp-Source: ACcGV63qhgeUAWhh4siozQkax7YMwHdWc+4GYRhLEg1hRSAyHnbmOe6bbnAP70oudB9qscpLm+FE0Q== X-Received: by 2002:a25:5c07:: with SMTP id q7-v6mr19811203ybb.254.1539203907921; Wed, 10 Oct 2018 13:38:27 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:27 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:26 -0400 Message-Id: <20181010203735.27918-6-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::b44 Subject: [Qemu-devel] [PATCH v6 05/14] target/arm: Reorganize PMCCNTR accesses 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" pmccntr_read and pmccntr_write contained duplicate code that was already being handled by pmccntr_sync. Consolidate the duplicated code into two functions: pmccntr_op_start and pmccntr_op_finish. Add a companion to c15_ccnt in CPUARMState so that we can simultaneously save both the architectural register value and the last underlying cycle count - this ensures time isn't lost and will also allow us to access the 'old' architectural register value in order to detect overflows in later patches. Signed-off-by: Aaron Lindsay --- target/arm/cpu.h | 26 ++++++++---- target/arm/helper.c | 96 +++++++++++++++++++++++--------------------- target/arm/machine.c | 8 ++-- 3 files changed, 73 insertions(+), 57 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 3a2aff1192..fdf672ca22 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -468,10 +468,20 @@ typedef struct CPUARMState { uint64_t oslsr_el1; /* OS Lock Status */ uint64_t mdcr_el2; uint64_t mdcr_el3; - /* If the counter is enabled, this stores the last time the counter - * was reset. Otherwise it stores the counter value + /* Stores the architectural value of the counter *the last time it was + * updated* by pmccntr_op_start. Accesses should always be surrounded + * by pmccntr_op_start/pmccntr_op_finish to guarantee the latest + * architecturally-correct value is being read/set. */ uint64_t c15_ccnt; + /* Stores the delta between the architectural value and the underlying + * cycle count during normal operation. It is used to update c15_ccnt + * to be the correct architectural value before accesses. During + * accesses, c15_ccnt_delta contains the underlying count being used + * for the access, after which it reverts to the delta value in + * pmccntr_op_finish. + */ + uint64_t c15_ccnt_delta; uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */ uint64_t vpidr_el2; /* Virtualization Processor ID Register */ uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */ @@ -937,15 +947,15 @@ int cpu_arm_signal_handler(int host_signum, void *pinfo, void *puc); /** - * pmccntr_sync + * pmccntr_op_start/finish * @env: CPUARMState * - * Synchronises the counter in the PMCCNTR. This must always be called twice, - * once before any action that might affect the timer and again afterwards. - * The function is used to swap the state of the register if required. - * This only happens when not in user mode (!CONFIG_USER_ONLY) + * Convert the counter in the PMCCNTR between its delta form (the typical mode + * when it's enabled) and the guest-visible value. These two calls must always + * surround any action which might affect the counter. */ -void pmccntr_sync(CPUARMState *env); +void pmccntr_op_start(CPUARMState *env); +void pmccntr_op_finish(CPUARMState *env); /* SCTLR bit meanings. Several bits have been reused in newer * versions of the architecture; in that case we define constants diff --git a/target/arm/helper.c b/target/arm/helper.c index 12c53e54e9..91e4e4170b 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1052,28 +1052,53 @@ static inline bool arm_ccnt_enabled(CPUARMState *env) return true; } - -void pmccntr_sync(CPUARMState *env) +/* + * Ensure c15_ccnt is the guest-visible count so that operations such as + * enabling/disabling the counter or filtering, modifying the count itself, + * etc. can be done logically. This is essentially a no-op if the counter is + * not enabled at the time of the call. + */ +void pmccntr_op_start(CPUARMState *env) { - uint64_t temp_ticks; - - temp_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + uint64_t cycles = 0; + cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - if (env->cp15.c9_pmcr & PMCRD) { - /* Increment once every 64 processor clock cycles */ - temp_ticks /= 64; + if (arm_ccnt_enabled(env)) { + uint64_t eff_cycles = cycles; + if (env->cp15.c9_pmcr & PMCRD) { + /* Increment once every 64 processor clock cycles */ + eff_cycles /= 64; + } + + env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta; } + env->cp15.c15_ccnt_delta = cycles; +} +/* + * If PMCCNTR is enabled, recalculate the delta between the clock and the + * guest-visible count. A call to pmccntr_op_finish should follow every call to + * pmccntr_op_start. + */ +void pmccntr_op_finish(CPUARMState *env) +{ if (arm_ccnt_enabled(env)) { - env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt; + uint64_t prev_cycles = env->cp15.c15_ccnt_delta; + + if (env->cp15.c9_pmcr & PMCRD) { + /* Increment once every 64 processor clock cycles */ + prev_cycles /= 64; + } + + env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt; } } static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - pmccntr_sync(env); + pmccntr_op_start(env); if (value & PMCRC) { /* The counter has been reset */ @@ -1084,26 +1109,16 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, env->cp15.c9_pmcr &= ~0x39; env->cp15.c9_pmcr |= (value & 0x39); - pmccntr_sync(env); + pmccntr_op_finish(env); } static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri) { - uint64_t total_ticks; - - if (!arm_ccnt_enabled(env)) { - /* Counter is disabled, do not change value */ - return env->cp15.c15_ccnt; - } - - total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - - if (env->cp15.c9_pmcr & PMCRD) { - /* Increment once every 64 processor clock cycles */ - total_ticks /= 64; - } - return total_ticks - env->cp15.c15_ccnt; + uint64_t ret; + pmccntr_op_start(env); + ret = env->cp15.c15_ccnt; + pmccntr_op_finish(env); + return ret; } static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1120,22 +1135,9 @@ static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri, static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - uint64_t total_ticks; - - if (!arm_ccnt_enabled(env)) { - /* Counter is disabled, set the absolute value */ - env->cp15.c15_ccnt = value; - return; - } - - total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - - if (env->cp15.c9_pmcr & PMCRD) { - /* Increment once every 64 processor clock cycles */ - total_ticks /= 64; - } - env->cp15.c15_ccnt = total_ticks - value; + pmccntr_op_start(env); + env->cp15.c15_ccnt = value; + pmccntr_op_finish(env); } static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1148,7 +1150,11 @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri, #else /* CONFIG_USER_ONLY */ -void pmccntr_sync(CPUARMState *env) +void pmccntr_op_start(CPUARMState *env) +{ +} + +void pmccntr_op_finish(CPUARMState *env) { } @@ -1157,9 +1163,9 @@ void pmccntr_sync(CPUARMState *env) static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - pmccntr_sync(env); + pmccntr_op_start(env); env->cp15.pmccfiltr_el0 = value & 0xfc000000; - pmccntr_sync(env); + pmccntr_op_finish(env); } static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri, diff --git a/target/arm/machine.c b/target/arm/machine.c index 8139b25be5..581c44cf08 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -584,7 +584,7 @@ static int cpu_pre_save(void *opaque) { ARMCPU *cpu = opaque; - pmccntr_sync(&cpu->env); + pmccntr_op_start(&cpu->env); if (kvm_enabled()) { if (!write_kvmstate_to_list(cpu)) { @@ -610,13 +610,13 @@ static int cpu_pre_save(void *opaque) static void cpu_post_save(void *opaque) { ARMCPU *cpu = opaque; - pmccntr_sync(&cpu->env); + pmccntr_op_finish(&cpu->env); } static int cpu_pre_load(void *opaque) { ARMCPU *cpu = opaque; - pmccntr_sync(&cpu->env); + pmccntr_op_start(&cpu->env); return 0; } @@ -667,7 +667,7 @@ static int cpu_post_load(void *opaque, int version_id) hw_breakpoint_update_all(cpu); hw_watchpoint_update_all(cpu); - pmccntr_sync(&cpu->env); + pmccntr_op_finish(&cpu->env); return 0; } From patchwork Wed Oct 10 20:37:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982101 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="WA75ZxfG"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmMS199vz9s9N for ; Thu, 11 Oct 2018 07:45:39 +1100 (AEDT) Received: from localhost ([::1]:59070 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALMP-0008Ax-Kd for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:45:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39687) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFd-0002uD-GJ for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFb-0002VL-2U for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:37 -0400 Received: from mail-yb1-xb44.google.com ([2607:f8b0:4864:20::b44]:36847) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFW-0002P8-0X; Wed, 10 Oct 2018 16:38:30 -0400 Received: by mail-yb1-xb44.google.com with SMTP id 5-v6so2765714ybf.3; Wed, 10 Oct 2018 13:38:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=C7A3VwZB/W6ludp/DL8ckfBITEtl4C3TThed+08i4Qg=; b=WA75ZxfGmBBd5VaK6KskJGwZnlByO0TlUTIiUolAZE+DvZ+Ijsr/yxTOIpbs3Wc5HQ 3CKLnr5k+55FLKXpzXOF+MSonIK8HWmnGhXCaeYsMr2wci1yYU/dwwZswhsrD8rSluhF NcCTx5XqtZurcVujXqRAY3XRTDgLK4JZIkZNK6Od4mLt06wYgQmevN1W4zzqgP5PlpkX ClywRIdzOElJviiuwKP+EiA53V9Ds2Dwe6WRtNUNpCmqvAQrGU7U/MXT/+kWAXCK91Vr 3YFQhnv9kD/4M2JNzUwy/+e8X9nJpgkEMTgVpEgucv5zTpZYPTQwsXm4Nh38lr0JXMO+ 8eeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=C7A3VwZB/W6ludp/DL8ckfBITEtl4C3TThed+08i4Qg=; b=Qh8QIa0AHmzU+SU78o3USBX7tJclVdpvrwLsCAhPgv1L2rcMko9UxEoFvJUMpwzjT0 3iJjtKCmHbpPm72sxjXxX2/RBIXB4CDpI2p0JRZRCh1u5rV4XUD9v1RZJGRp349KECM3 LnzJjWcNBeIyCVQY5hDk+JQDr2oM2NNbMhsmHmBf3QR+14MQydqywT3Re6zbnEplff5h hSSPTnO7pj8n+AjFAIxaJP4AJjLi7uUBfu9pZdTqm0DYIyf14eMOxtM50IetB9t4v192 CQc2E5MKj68FrO6ZyemA628fYeFK97ROeZ0e4ZhnTAxsT0xk3gByqH7dMLFImCnrRRFY WKtw== X-Gm-Message-State: ABuFfoipEi/PwX2lvwl2h0HcaPe8L2WN86DUrJWtkbDg6BrNraWLnBJ/ f9X6PzngH/S0l0KQgK+gdMBEd2wE X-Google-Smtp-Source: ACcGV62WWOM6ZR9QN6Jad1JDvbDqVIf06w/d+lOVGHyeE/o0oT02Frflxd2ms5QvAFaMFiAlld5Ckw== X-Received: by 2002:a25:6d55:: with SMTP id i82-v6mr19314287ybc.419.1539203909092; Wed, 10 Oct 2018 13:38:29 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:28 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:27 -0400 Message-Id: <20181010203735.27918-7-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::b44 Subject: [Qemu-devel] [PATCH v6 06/14] target/arm: Filter cycle counter based on PMCCFILTR_EL0 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The pmu_counter_enabled and pmu_op_start/finish functions are generic (as opposed to PMCCNTR-specific) to allow for the implementation of other events. Signed-off-by: Aaron Lindsay Reviewed-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/cpu.c | 3 ++ target/arm/cpu.h | 22 +++++++- target/arm/helper.c | 118 +++++++++++++++++++++++++++++++++++++++---- target/arm/machine.c | 8 +-- 4 files changed, 137 insertions(+), 14 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index b5e61cc177..f69addb961 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -948,6 +948,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) if (!cpu->has_pmu) { unset_feature(env, ARM_FEATURE_PMU); cpu->id_aa64dfr0 &= ~0xf00; + } else if (!kvm_enabled()) { + arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0); + arm_register_el_change_hook(cpu, &pmu_post_el_change, 0); } if (!arm_feature(env, ARM_FEATURE_EL2)) { diff --git a/target/arm/cpu.h b/target/arm/cpu.h index fdf672ca22..d9cd8dd92c 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -957,6 +957,24 @@ int cpu_arm_signal_handler(int host_signum, void *pinfo, void pmccntr_op_start(CPUARMState *env); void pmccntr_op_finish(CPUARMState *env); +/** + * pmu_op_start/finish + * @env: CPUARMState + * + * Convert all PMU counters between their delta form (the typical mode when + * they are enabled) and the guest-visible values. These two calls must + * surround any action which might affect the counters, and the return value + * from pmu_op_start must be supplied as the second argument to pmu_op_finish. + */ +void pmu_op_start(CPUARMState *env); +void pmu_op_finish(CPUARMState *env); + +/** + * Functions to register as EL change hooks for PMU mode filtering + */ +void pmu_pre_el_change(ARMCPU *cpu, void *ignored); +void pmu_post_el_change(ARMCPU *cpu, void *ignored); + /* SCTLR bit meanings. Several bits have been reused in newer * versions of the architecture; in that case we define constants * for both old and new bit meanings. Code which tests against those @@ -1018,7 +1036,8 @@ void pmccntr_op_finish(CPUARMState *env); #define MDCR_EPMAD (1U << 21) #define MDCR_EDAD (1U << 20) -#define MDCR_SPME (1U << 17) +#define MDCR_SPME (1U << 17) /* MDCR_EL3 */ +#define MDCR_HPMD (1U << 17) /* MDCR_EL2 */ #define MDCR_SDD (1U << 16) #define MDCR_SPD (3U << 14) #define MDCR_TDRA (1U << 11) @@ -1028,6 +1047,7 @@ void pmccntr_op_finish(CPUARMState *env); #define MDCR_HPME (1U << 7) #define MDCR_TPM (1U << 6) #define MDCR_TPMCR (1U << 5) +#define MDCR_HPMN (0x1fU) /* Not all of the MDCR_EL3 bits are present in the 32-bit SDCR */ #define SDCR_VALID_MASK (MDCR_EPMAD | MDCR_EDAD | MDCR_SPME | MDCR_SPD) diff --git a/target/arm/helper.c b/target/arm/helper.c index 91e4e4170b..52bd13fdde 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -943,10 +943,24 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { /* Definitions for the PMU registers */ #define PMCRN_MASK 0xf800 #define PMCRN_SHIFT 11 +#define PMCRDP 0x10 #define PMCRD 0x8 #define PMCRC 0x4 #define PMCRE 0x1 +#define PMXEVTYPER_P 0x80000000 +#define PMXEVTYPER_U 0x40000000 +#define PMXEVTYPER_NSK 0x20000000 +#define PMXEVTYPER_NSU 0x10000000 +#define PMXEVTYPER_NSH 0x08000000 +#define PMXEVTYPER_M 0x04000000 +#define PMXEVTYPER_MT 0x02000000 +#define PMXEVTYPER_EVTCOUNT 0x0000ffff +#define PMXEVTYPER_MASK (PMXEVTYPER_P | PMXEVTYPER_U | PMXEVTYPER_NSK | \ + PMXEVTYPER_NSU | PMXEVTYPER_NSH | \ + PMXEVTYPER_M | PMXEVTYPER_MT | \ + PMXEVTYPER_EVTCOUNT) + static inline uint32_t pmu_num_counters(CPUARMState *env) { return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT; @@ -1042,16 +1056,66 @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env, return pmreg_access(env, ri, isread); } -static inline bool arm_ccnt_enabled(CPUARMState *env) +/* Returns true if the counter (pass 31 for PMCCNTR) should count events using + * the current EL, security state, and register configuration. + */ +static inline bool pmu_counter_enabled(CPUARMState *env, uint8_t counter) { - /* This does not support checking PMCCFILTR_EL0 register */ + uint64_t filter; + bool e, p, u, nsk, nsu, nsh, m; + bool enabled, prohibited, filtered; + bool secure = arm_is_secure(env); + int el = arm_current_el(env); + uint8_t hpmn = env->cp15.mdcr_el2 & MDCR_HPMN; - if (!(env->cp15.c9_pmcr & PMCRE) || !(env->cp15.c9_pmcnten & (1 << 31))) { - return false; + if (!arm_feature(env, ARM_FEATURE_EL2) || + (counter < hpmn || counter == 31)) { + e = env->cp15.c9_pmcr & PMCRE; + } else { + e = env->cp15.mdcr_el2 & MDCR_HPME; } + enabled = e && (env->cp15.c9_pmcnten & (1 << counter)); - return true; + if (!secure) { + if (el == 2 && (counter < hpmn || counter == 31)) { + prohibited = env->cp15.mdcr_el2 & MDCR_HPMD; + } else { + prohibited = false; + } + } else { + prohibited = arm_feature(env, ARM_FEATURE_EL3) && + (env->cp15.mdcr_el3 & MDCR_SPME); + } + + if (prohibited && counter == 31) { + prohibited = env->cp15.c9_pmcr & PMCRDP; + } + + /* TODO Remove assert, set filter to correct PMEVTYPER */ + assert(counter == 31); + filter = env->cp15.pmccfiltr_el0; + + p = filter & PMXEVTYPER_P; + u = filter & PMXEVTYPER_U; + nsk = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSK); + nsu = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSU); + nsh = arm_feature(env, ARM_FEATURE_EL2) && (filter & PMXEVTYPER_NSH); + m = arm_el_is_aa64(env, 1) && + arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_M); + + if (el == 0) { + filtered = secure ? u : u != nsu; + } else if (el == 1) { + filtered = secure ? p : p != nsk; + } else if (el == 2) { + filtered = !nsh; + } else { /* EL3 */ + filtered = m != p; + } + + return enabled && !prohibited && !filtered; } + /* * Ensure c15_ccnt is the guest-visible count so that operations such as * enabling/disabling the counter or filtering, modifying the count itself, @@ -1064,7 +1128,7 @@ void pmccntr_op_start(CPUARMState *env) cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); - if (arm_ccnt_enabled(env)) { + if (pmu_counter_enabled(env, 31)) { uint64_t eff_cycles = cycles; if (env->cp15.c9_pmcr & PMCRD) { /* Increment once every 64 processor clock cycles */ @@ -1083,7 +1147,7 @@ void pmccntr_op_start(CPUARMState *env) */ void pmccntr_op_finish(CPUARMState *env) { - if (arm_ccnt_enabled(env)) { + if (pmu_counter_enabled(env, 31)) { uint64_t prev_cycles = env->cp15.c15_ccnt_delta; if (env->cp15.c9_pmcr & PMCRD) { @@ -1095,10 +1159,30 @@ void pmccntr_op_finish(CPUARMState *env) } } +void pmu_op_start(CPUARMState *env) +{ + pmccntr_op_start(env); +} + +void pmu_op_finish(CPUARMState *env) +{ + pmccntr_op_finish(env); +} + +void pmu_pre_el_change(ARMCPU *cpu, void *ignored) +{ + pmu_op_start(&cpu->env); +} + +void pmu_post_el_change(ARMCPU *cpu, void *ignored) +{ + pmu_op_finish(&cpu->env); +} + static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - pmccntr_op_start(env); + pmu_op_start(env); if (value & PMCRC) { /* The counter has been reset */ @@ -1109,7 +1193,7 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, env->cp15.c9_pmcr &= ~0x39; env->cp15.c9_pmcr |= (value & 0x39); - pmccntr_op_finish(env); + pmu_op_finish(env); } static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri) @@ -1158,6 +1242,22 @@ void pmccntr_op_finish(CPUARMState *env) { } +void pmu_op_start(CPUARMState *env) +{ +} + +void pmu_op_finish(CPUARMState *env) +{ +} + +void pmu_pre_el_change(ARMCPU *cpu, void *ignored) +{ +} + +void pmu_post_el_change(ARMCPU *cpu, void *ignored) +{ +} + #endif static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri, diff --git a/target/arm/machine.c b/target/arm/machine.c index 581c44cf08..bb9e47f602 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -584,7 +584,7 @@ static int cpu_pre_save(void *opaque) { ARMCPU *cpu = opaque; - pmccntr_op_start(&cpu->env); + pmu_op_start(&cpu->env); if (kvm_enabled()) { if (!write_kvmstate_to_list(cpu)) { @@ -610,13 +610,13 @@ static int cpu_pre_save(void *opaque) static void cpu_post_save(void *opaque) { ARMCPU *cpu = opaque; - pmccntr_op_finish(&cpu->env); + pmu_op_finish(&cpu->env); } static int cpu_pre_load(void *opaque) { ARMCPU *cpu = opaque; - pmccntr_op_start(&cpu->env); + pmu_op_start(&cpu->env); return 0; } @@ -667,7 +667,7 @@ static int cpu_post_load(void *opaque, int version_id) hw_breakpoint_update_all(cpu); hw_watchpoint_update_all(cpu); - pmccntr_op_finish(&cpu->env); + pmu_op_finish(&cpu->env); return 0; } From patchwork Wed Oct 10 20:37:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982096 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qZluxc2H"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmJ26ggNz9s9J for ; Thu, 11 Oct 2018 07:42:42 +1100 (AEDT) Received: from localhost ([::1]:59051 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALJY-0005bH-Fl for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:42:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39615) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFb-0002ri-Qj for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFa-0002Up-LO for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:35 -0400 Received: from mail-yw1-xc44.google.com ([2607:f8b0:4864:20::c44]:47096) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFW-0002QO-Oz; Wed, 10 Oct 2018 16:38:30 -0400 Received: by mail-yw1-xc44.google.com with SMTP id j202-v6so2710196ywa.13; Wed, 10 Oct 2018 13:38:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=AnhG0/ln6p/5gZevgYimHTnAiMxu17Lcq2p4OJVwhik=; b=qZluxc2HhKFPdM1xvKHLm3ozdP7BNmdCOknzP+UT0wv1+BTY6x3i7GMb0qqBli+1Wd djTAlJmus0o3YJhzMUM6j0YwvrO+1Kd21AkQOmdy8d+D5DmaBfohgYDqNdVss7hwbjpN PYrvpZDuHqPOaObhP/xRebxB7KRkS62n9AxPFG2yYzdD1xNuSa6Ff4MbTwmrGXCIM58b F0rjwm+UNazjNCPpdI/wEfS++fmgWxRRwENa8gHCPJqLysySwHT1Mz+q3/vsNxnRQFe8 +2XjB0sY5xfugSck+MuT+X4kLgD1GG97kQkOHKNoUHDnj2Mas9fPJ+bhe+yKLbs/Fcmh fyiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=AnhG0/ln6p/5gZevgYimHTnAiMxu17Lcq2p4OJVwhik=; b=Qq+uw1oObvgTLhRsbpZD9TIa6rpjOpBYAYkDQCogKaF5ZlDVx594i2O4eWMk1nvGSk vT+u6+rG05Bm3P2SVAfL/G2vO+B7CsO3cvAOPVupiIt3YhnDQw/PBqAAB5A1nGkYi0ku uUHsbIHhVL9+Z0FuQlW2xhbC9SYmPfkC6iDsIqkxOzH4ab3g/AEqTr/AG2qrKou5r0JC MUIFOi/frzQySCG45ErbBYk/JbWvH0SIbJer5a+6QFU1l+KbMw/bo8YVzE62GPOi3aYr CHtvo5CSzDT/r8g0DGGVtnq3IT+Z9/P4DaiAq1SBv/0KPfyXeKtBemsHTwnrkT07ajLe EtwA== X-Gm-Message-State: ABuFfojbVU+2U6ISYjJztTROHudOUBOdDcw10TZscuxs6CnbHkh+YnRD A4y5y1TF9xtOdNLk7CS2/0uL/L+X X-Google-Smtp-Source: ACcGV61M2/RftAEYV+L4Gwhi3tMlCQGez/ZiyfkDqzHtyDqwfHsPQ5IsghKFPvZNSlJchfWgvf8YBQ== X-Received: by 2002:a81:560a:: with SMTP id k10-v6mr19013985ywb.80.1539203910103; Wed, 10 Oct 2018 13:38:30 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:29 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:28 -0400 Message-Id: <20181010203735.27918-8-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c44 Subject: [Qemu-devel] [PATCH v6 07/14] target/arm: Allow AArch32 access for PMCCFILTR 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Aaron Lindsay Reviewed-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/helper.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 52bd13fdde..e804caaced 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -961,6 +961,10 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { PMXEVTYPER_M | PMXEVTYPER_MT | \ PMXEVTYPER_EVTCOUNT) +#define PMCCFILTR 0xf8000000 +#define PMCCFILTR_M PMXEVTYPER_M +#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M) + static inline uint32_t pmu_num_counters(CPUARMState *env) { return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT; @@ -1264,10 +1268,26 @@ static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { pmccntr_op_start(env); - env->cp15.pmccfiltr_el0 = value & 0xfc000000; + env->cp15.pmccfiltr_el0 = value & PMCCFILTR_EL0; + pmccntr_op_finish(env); +} + +static void pmccfiltr_write_a32(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + pmccntr_op_start(env); + /* M is not accessible from AArch32 */ + env->cp15.pmccfiltr_el0 = (env->cp15.pmccfiltr_el0 & PMCCFILTR_M) | + (value & PMCCFILTR); pmccntr_op_finish(env); } +static uint64_t pmccfiltr_read_a32(CPUARMState *env, const ARMCPRegInfo *ri) +{ + /* M is not visible in AArch32 */ + return env->cp15.pmccfiltr_el0 & PMCCFILTR; +} + static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -1489,6 +1509,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .readfn = pmccntr_read, .writefn = pmccntr_write, .raw_readfn = raw_read, .raw_writefn = raw_write, }, #endif + { .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7, + .writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS | ARM_CP_IO, + .resetvalue = 0, }, { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7, .writefn = pmccfiltr_write, .raw_writefn = raw_write, From patchwork Wed Oct 10 20:37:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982094 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Sh3HycZC"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmDv3ShZz9s9J for ; Thu, 11 Oct 2018 07:39:59 +1100 (AEDT) Received: from localhost ([::1]:59030 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALGv-0003PB-28 for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:39:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39605) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFb-0002rO-KZ for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFa-0002UZ-Cm for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:35 -0400 Received: from mail-yw1-xc32.google.com ([2607:f8b0:4864:20::c32]:33952) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFX-0002RM-P6; Wed, 10 Oct 2018 16:38:31 -0400 Received: by mail-yw1-xc32.google.com with SMTP id m129-v6so2731057ywc.1; Wed, 10 Oct 2018 13:38:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UXPD8KhgIRR+aP3UPZnC5gnhN4pMpEVIMIIDlkzVIRI=; b=Sh3HycZCpo39UHuL/cEXJzlDyI9VQAOxIim0St/ThAAFUzxnAAtYTR4PWR82MSmAJD 8qP2m56nt45/h7qIToaBeC5cTAdQ7fI6hTKwBbRRMiciyEUXkzAHhiPUDFtpxQPe+QWF e4NdZ7PZpPZdnS9ZahifS5xnCDholYifQH82b3/IqBzcRvRZDMs0piGr1B4IisiCnOvB R9Xh6vl8V546gC4kzjV3teRIUqBhXoPxisM9AHf4uOQ8TpLn14QQvJIFnMX101zLl9yQ TWSISewDBEAt9sBLdq8TFnT8GRe15/Dvyr/t5ZJBH/r3+yGw0S/zvBXggGLWGZLC9JyN TqEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UXPD8KhgIRR+aP3UPZnC5gnhN4pMpEVIMIIDlkzVIRI=; b=rX4fu8UiLAbxxxYyhrLry576dXC98GOBuA3vJdt3y8cK36ioYr5vyQPpI5viso5ALi RHCvHdCBCl1PNSJA8FPFEb+jAjerWiOSM1ZAYHIhQcWLHXi4k0sacFrU1XyAscKmku0a +q51Ss3XuaVbKWHkSpHf+tJVcywenJZPRzwp/mDlCLMA9WxTI6J5v4SVZqmt/OrC0+4j rTWlCYMqS+mRY7PXuwlTzSG3sn5oyWbwqNceuidE87Dr3e0ujcjtk6bpbPm30BkeBRAx SXraz3HKg5aEx7zSIn3/ZLxI+BVepwqQwZXQByAFiwjITTh9+c6OUBpAhT1POxGe2Lpu 8jxQ== X-Gm-Message-State: ABuFfojZ9/D7JU77H+GMF5UHrv1ZAjGATcg1d+Pr2GCtUJ4BwcZNO3O7 tdXHruUvdSkvcEU8eKG6ybysgOjY X-Google-Smtp-Source: ACcGV6050/DAYioVuLdnrxAH3evwGQT2i8fBm+XcU3iTvqPPVdKMh3D6tpACnCpGl3WkDo4WD8nW1Q== X-Received: by 2002:a81:2d54:: with SMTP id t81-v6mr19619082ywt.69.1539203911053; Wed, 10 Oct 2018 13:38:31 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:30 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:29 -0400 Message-Id: <20181010203735.27918-9-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c32 Subject: [Qemu-devel] [PATCH v6 08/14] target/arm: Implement PMOVSSET 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add an array for PMOVSSET so we only define it for v7ve+ platforms Signed-off-by: Aaron Lindsay Reviewed-by: Richard Henderson --- target/arm/helper.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/target/arm/helper.c b/target/arm/helper.c index e804caaced..f3c00c3db0 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1309,6 +1309,13 @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri, env->cp15.c9_pmovsr &= ~value; } +static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + value &= pmu_counter_mask(env); + env->cp15.c9_pmovsr |= value; +} + static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -1662,6 +1669,24 @@ static const ARMCPRegInfo v7mp_cp_reginfo[] = { REGINFO_SENTINEL }; +static const ARMCPRegInfo pmovsset_cp_reginfo[] = { + /* PMOVSSET is not implemented in v7 before v7ve */ + { .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS, + .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr), + .writefn = pmovsset_write, + .raw_writefn = raw_write }, + { .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3, + .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_ALIAS, + .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr), + .writefn = pmovsset_write, + .raw_writefn = raw_write }, + REGINFO_SENTINEL +}; + static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -5116,6 +5141,9 @@ void register_cp_regs_for_features(ARMCPU *cpu) !arm_feature(env, ARM_FEATURE_PMSA)) { define_arm_cp_regs(cpu, v7mp_cp_reginfo); } + if (arm_feature(env, ARM_FEATURE_V7VE)) { + define_arm_cp_regs(cpu, pmovsset_cp_reginfo); + } if (arm_feature(env, ARM_FEATURE_V7)) { /* v7 performance monitor control register: same implementor * field as main ID register, and we implement only the cycle From patchwork Wed Oct 10 20:37:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982098 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dUdyBBK9"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmJH6cVjz9s9N for ; Thu, 11 Oct 2018 07:42:55 +1100 (AEDT) Received: from localhost ([::1]:59054 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALJl-0005lq-Fa for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:42:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39714) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFe-0002uO-KF for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFd-0002Zv-2D for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:38 -0400 Received: from mail-yw1-xc42.google.com ([2607:f8b0:4864:20::c42]:41277) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFY-0002SI-OX; Wed, 10 Oct 2018 16:38:32 -0400 Received: by mail-yw1-xc42.google.com with SMTP id 135-v6so2716223ywo.8; Wed, 10 Oct 2018 13:38:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OO5omZne/mpRB5n5xRTpKEr+jlwMxC9ACMNSJpaNgDo=; b=dUdyBBK9XM+xY7mmR5WhrY43fUHl8hYxWZj83dB8aiEcPKHIhce3smHouFQSDZ/VjT V6SZtEvIdSe1R+nM49L25pAhe79tcrOQ8XUZNwFowsDZIAf9/CtWoikVOOYwn1wxShNm iRvijtDSLrkcbPY45YELY/89OYgP1u9VDDQytcAGhBgjUEC/dkcDeeZ56NXv3LL2V+rF Ilt7gtdlwZuxbip6oQYcd98O5ciK70yplEaRctwC5lRahaXWDBzlpGBkd5VQVFFIT10A 4hktgNZcbh9I8tJDnrw44FsaDu5AjeQs4awoOv7zc0v6LIf2KFHC8RxnM9pzEGM3h+lK XyQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OO5omZne/mpRB5n5xRTpKEr+jlwMxC9ACMNSJpaNgDo=; b=QRN3OJyJcInx9OpQw7EdxyDtzFjjg0wVdF0xbFMckDZ7SfRKHVIVQY2TxDr26C6x4/ Toz0hUREawTr1u9Z9dEqX90Hdqp8P1UMASNrxc2AL6J2g6IJmjq62AzgakJhz/ETzJrT iWwBb6qopJQeKrHJTpmQEjr1SX1m8ndKnysnH8/83RF+DA9Rc9/Lt7E3Je9ATCYIOyvs infrb/a29vCIL1rDCYAlEvIls3j2Ctxc9iilWMHY9N8cfeYUqWW0pR3P6fA9DQHYeZT5 n3mto05WxP/hThdjdQxe1GZ1Eq81bFdmdTOGMHajfq+tpCLCmn6/Al6pwscUidYn2g7/ JpZg== X-Gm-Message-State: ABuFfoiLt2wPzG3nZdmpNZpXRpPHEymWkljS7vY/N9FY4lLdL0kT0ha6 8g4PoJpgB5CXFKrSJOmrmMLN9+mD X-Google-Smtp-Source: ACcGV60B3t7e8HLYcqzOelAojh9SDsqlvUKUNQBIvp+mZ7jYPz2C7Wsl9Ef/0AdmvY6OcL/hFfBxbw== X-Received: by 2002:a0d:ec0e:: with SMTP id v14-v6mr19955778ywe.384.1539203912012; Wed, 10 Oct 2018 13:38:32 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:31 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:30 -0400 Message-Id: <20181010203735.27918-10-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c42 Subject: [Qemu-devel] [PATCH v6 09/14] target/arm: Add array for supported PMU events, generate PMCEID[01] 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This commit doesn't add any supported events, but provides the framework for adding them. We store the pm_event structs in a simple array, and provide the mapping from the event numbers to array indexes in the supported_event_map array. Because the value of PMCEID[01] depends upon which events are supported at runtime, generate it dynamically. Signed-off-by: Aaron Lindsay --- target/arm/cpu.c | 20 +++++++++++++------- target/arm/cpu.h | 10 ++++++++++ target/arm/cpu64.c | 2 -- target/arm/helper.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index f69addb961..7f39f25f51 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -948,9 +948,19 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) if (!cpu->has_pmu) { unset_feature(env, ARM_FEATURE_PMU); cpu->id_aa64dfr0 &= ~0xf00; - } else if (!kvm_enabled()) { - arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0); - arm_register_el_change_hook(cpu, &pmu_post_el_change, 0); + } + if (arm_feature(env, ARM_FEATURE_PMU)) { + uint64_t pmceid = get_pmceid(&cpu->env); + cpu->pmceid0 = pmceid & 0xffffffff; + cpu->pmceid1 = (pmceid >> 32) & 0xffffffff; + + if (!kvm_enabled()) { + arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0); + arm_register_el_change_hook(cpu, &pmu_post_el_change, 0); + } + } else { + cpu->pmceid0 = 0x00000000; + cpu->pmceid1 = 0x00000000; } if (!arm_feature(env, ARM_FEATURE_EL2)) { @@ -1583,8 +1593,6 @@ static void cortex_a7_initfn(Object *obj) cpu->id_pfr0 = 0x00001131; cpu->id_pfr1 = 0x00011011; cpu->id_dfr0 = 0x02010555; - cpu->pmceid0 = 0x00000000; - cpu->pmceid1 = 0x00000000; cpu->id_afr0 = 0x00000000; cpu->id_mmfr0 = 0x10101105; cpu->id_mmfr1 = 0x40000000; @@ -1626,8 +1634,6 @@ static void cortex_a15_initfn(Object *obj) cpu->id_pfr0 = 0x00001131; cpu->id_pfr1 = 0x00011011; cpu->id_dfr0 = 0x02010555; - cpu->pmceid0 = 0x0000000; - cpu->pmceid1 = 0x00000000; cpu->id_afr0 = 0x00000000; cpu->id_mmfr0 = 0x10201105; cpu->id_mmfr1 = 0x20000000; diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d9cd8dd92c..cc026f0b75 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -975,6 +975,16 @@ void pmu_op_finish(CPUARMState *env); void pmu_pre_el_change(ARMCPU *cpu, void *ignored); void pmu_post_el_change(ARMCPU *cpu, void *ignored); +/* + * get_pmceid + * @env: CPUARMState + * + * Return the PMCEID[01] register values corresponding to the counters which + * are supported given the current configuration (0 is low 32, 1 is high 32 + * bits) + */ +uint64_t get_pmceid(CPUARMState *env); + /* SCTLR bit meanings. Several bits have been reused in newer * versions of the architecture; in that case we define constants * for both old and new bit meanings. Code which tests against those diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index db71504cb5..440d874c17 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -143,8 +143,6 @@ static void aarch64_a57_initfn(Object *obj) cpu->id_isar6 = 0; cpu->id_aa64pfr0 = 0x00002222; cpu->id_aa64dfr0 = 0x10305106; - cpu->pmceid0 = 0x00000000; - cpu->pmceid1 = 0x00000000; cpu->id_aa64isar0 = 0x00011120; cpu->id_aa64mmfr0 = 0x00001124; cpu->dbgdidr = 0x3516d000; diff --git a/target/arm/helper.c b/target/arm/helper.c index f3c00c3db0..375b6dcda5 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -976,6 +976,48 @@ static inline uint64_t pmu_counter_mask(CPUARMState *env) return (1 << 31) | ((1 << pmu_num_counters(env)) - 1); } +typedef struct pm_event { + uint16_t number; /* PMEVTYPER.evtCount is 16 bits wide */ + /* If the event is supported on this CPU (used to generate PMCEID[01]) */ + bool (*supported)(CPUARMState *); + /* + * Retrieve the current count of the underlying event. The programmed + * counters hold a difference from the return value from this function + */ + uint64_t (*get_count)(CPUARMState *); +} pm_event; + +static const pm_event pm_events[] = { +}; +#define MAX_EVENT_ID 0x0 +#define UNSUPPORTED_EVENT UINT16_MAX +static uint16_t supported_event_map[MAX_EVENT_ID + 1]; + +/* + * Called upon initialization to build PMCEID0 (low 32 bits) and PMCEID1 (high + * 32). We also use it to build a map of ARM event numbers to indices in + * our pm_events array. + */ +uint64_t get_pmceid(CPUARMState *env) +{ + uint64_t pmceid = 0; + unsigned int i; + + for (i = 0; i <= MAX_EVENT_ID; i++) { + supported_event_map[i] = UNSUPPORTED_EVENT; + } + + for (i = 0; i < ARRAY_SIZE(pm_events); i++) { + const pm_event *cnt = &pm_events[i]; + assert(cnt->number <= MAX_EVENT_ID); + if (cnt->supported(env)) { + pmceid |= (1 << cnt->number); + supported_event_map[cnt->number] = i; + } + } + return pmceid; +} + static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { From patchwork Wed Oct 10 20:37:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982106 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="RIa5IeY1"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmWy17Hvz9s9N for ; Thu, 11 Oct 2018 07:53:02 +1100 (AEDT) Received: from localhost ([::1]:59119 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALTX-0004i9-MW for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:52:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39829) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFj-0002x5-9N for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFh-0002k0-HI for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:43 -0400 Received: from mail-yw1-xc2e.google.com ([2607:f8b0:4864:20::c2e]:37542) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFZ-0002Tw-TH; Wed, 10 Oct 2018 16:38:34 -0400 Received: by mail-yw1-xc2e.google.com with SMTP id y14-v6so2726353ywa.4; Wed, 10 Oct 2018 13:38:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0/oLOuK/SUhKNQ3tQWg3bSZl9Farv5I3v9vlbrlFe8A=; b=RIa5IeY1tTbUIci7o8u+PehHCchEVUwFTe5sL1q6rrc8/9OUJqP22QKmKfdDEnT6mZ TnyD3QcDaVTFflVmN2sE/5ZhmlcjHB67Mh2VU3rrUZiaQATpGeuRKO7LPszm0G8gJWMi XLVF33w4HDxvuyn82qFiavsrvupOaKh6909cRpebNMPGIaN3vYA4kVD9rLZTJ6ngIQsa PDXuteOChQEXqlWACVkiWT3XyIG9pIEMYKDpYbSmt4tjGRlGeAnMAIUJIW8hHlsH99R+ uKbiskwOi2oFll9MOXeSVV+Rc60crhbR7HpvwJf3HVPX+GF6xEFSyZj5lJzNtjKf8N4r zHuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0/oLOuK/SUhKNQ3tQWg3bSZl9Farv5I3v9vlbrlFe8A=; b=jhyJMEhrLUSwhIPG37NQvtrPQAd4k0VgscdOTtce0myjuW64wymIVzq2P0UwDVPMqf RfaLWEQJ1BfRFye0A98cgD5MIOrPkxINdsABabMeJcLFizDQAgcqE0qcQmn3dfN7Is6O R5UOiP939uy4mhplc0Zas22jSYq/QDgycG+CnIdW4HE2eQkxekZY0UUYm7SGg51ortRH mjPLjRekGl1f3zXuStyhx7DO+85c9XHHv42XWfTw7VZNxp1ytQYwiWZtj+XWESN9Fber tvOzMz16vwADMLhGpvVMlnAWjA6x/9dTg5CKXYA3C6fepB+EbSFHs24O0INOECaAo1KE DQpg== X-Gm-Message-State: ABuFfohf2u6iNHR9b6MNYKSTAvZK9AeMQw2S7d7JvFlO/Cw3QugwU5VU b2NpPtjPc4Ib7t2t1oXEtq2vYBJD X-Google-Smtp-Source: ACcGV639JCloH8A3p84+qYJnUORhfQ/dSiiRlHh45yGl0UerJr5dWaKsxBGUTWLua82Iiq/OScT5gg== X-Received: by 2002:a81:3088:: with SMTP id w130-v6mr19682931yww.230.1539203912984; Wed, 10 Oct 2018 13:38:32 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:32 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:31 -0400 Message-Id: <20181010203735.27918-11-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c2e Subject: [Qemu-devel] [PATCH v6 10/14] target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add arrays to hold the registers, the definitions themselves, access functions, and logic to reset counters when PMCR.P is set. Update filtering code to support counters other than PMCCNTR. Support migration with raw read/write functions. Signed-off-by: Aaron Lindsay Signed-off-by: Aaron Lindsay Reviewed-by: Richard Henderson --- target/arm/cpu.h | 3 + target/arm/helper.c | 296 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 282 insertions(+), 17 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index cc026f0b75..f4317f87c9 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -482,6 +482,9 @@ typedef struct CPUARMState { * pmccntr_op_finish. */ uint64_t c15_ccnt_delta; + uint64_t c14_pmevcntr[31]; + uint64_t c14_pmevcntr_delta[31]; + uint64_t c14_pmevtyper[31]; uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */ uint64_t vpidr_el2; /* Virtualization Processor ID Register */ uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */ diff --git a/target/arm/helper.c b/target/arm/helper.c index 375b6dcda5..f0798f7a8c 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -946,6 +946,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { #define PMCRDP 0x10 #define PMCRD 0x8 #define PMCRC 0x4 +#define PMCRP 0x2 #define PMCRE 0x1 #define PMXEVTYPER_P 0x80000000 @@ -1018,6 +1019,17 @@ uint64_t get_pmceid(CPUARMState *env) return pmceid; } +/* + * Check at runtime whether a PMU event is supported for the current machine + */ +static bool event_supported(uint16_t number) +{ + if (number > MAX_EVENT_ID) { + return false; + } + return supported_event_map[number] != UNSUPPORTED_EVENT; +} + static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { @@ -1137,9 +1149,11 @@ static inline bool pmu_counter_enabled(CPUARMState *env, uint8_t counter) prohibited = env->cp15.c9_pmcr & PMCRDP; } - /* TODO Remove assert, set filter to correct PMEVTYPER */ - assert(counter == 31); - filter = env->cp15.pmccfiltr_el0; + if (counter == 31) { + filter = env->cp15.pmccfiltr_el0; + } else { + filter = env->cp15.c14_pmevtyper[counter]; + } p = filter & PMXEVTYPER_P; u = filter & PMXEVTYPER_U; @@ -1159,6 +1173,17 @@ static inline bool pmu_counter_enabled(CPUARMState *env, uint8_t counter) filtered = m != p; } + if (counter != 31) { + /* + * If not checking PMCCNTR, ensure the counter is setup to an event we + * support + */ + uint16_t event = filter & PMXEVTYPER_EVTCOUNT; + if (!event_supported(event)) { + return false; + } + } + return enabled && !prohibited && !filtered; } @@ -1205,14 +1230,47 @@ void pmccntr_op_finish(CPUARMState *env) } } +static void pmevcntr_op_start(CPUARMState *env, uint8_t counter) +{ + + uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT; + uint64_t count = 0; + if (event_supported(event)) { + uint16_t event_idx = supported_event_map[event]; + count = pm_events[event_idx].get_count(env); + } + + if (pmu_counter_enabled(env, counter)) { + env->cp15.c14_pmevcntr[counter] = + count - env->cp15.c14_pmevcntr_delta[counter]; + } + env->cp15.c14_pmevcntr_delta[counter] = count; +} + +static void pmevcntr_op_finish(CPUARMState *env, uint8_t counter) +{ + if (pmu_counter_enabled(env, counter)) { + env->cp15.c14_pmevcntr_delta[counter] -= + env->cp15.c14_pmevcntr[counter]; + } +} + void pmu_op_start(CPUARMState *env) { + unsigned int i; pmccntr_op_start(env); + for (i = 0; i < pmu_num_counters(env); i++) { + pmevcntr_op_start(env, i); + } } void pmu_op_finish(CPUARMState *env) { + unsigned int i; pmccntr_op_finish(env); + for (i = 0; i < pmu_num_counters(env); i++) { + pmevcntr_op_finish(env, i); + } } void pmu_pre_el_change(ARMCPU *cpu, void *ignored) @@ -1235,6 +1293,13 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, env->cp15.c15_ccnt = 0; } + if (value & PMCRP) { + unsigned int i; + for (i = 0; i < pmu_num_counters(env); i++) { + env->cp15.c14_pmevcntr[i] = 0; + } + } + /* only the DP, X, D and E bits are writable */ env->cp15.c9_pmcr &= ~0x39; env->cp15.c9_pmcr |= (value & 0x39); @@ -1288,6 +1353,14 @@ void pmccntr_op_finish(CPUARMState *env) { } +void pmevcntr_op_start(CPUARMState *env, uint8_t i) +{ +} + +void pmevcntr_op_finish(CPUARMState *env, uint8_t i) +{ +} + void pmu_op_start(CPUARMState *env) { } @@ -1358,30 +1431,174 @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri, env->cp15.c9_pmovsr |= value; } -static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri, - uint64_t value) +static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value, const uint8_t counter) { + if (counter == 31) { + pmccfiltr_write(env, ri, value); + } else if (counter < pmu_num_counters(env)) { + pmevcntr_op_start(env, counter); + + /* + * If this counter's event type is changing, store the current + * underlying count for the new type in c14_pmevcntr_delta[counter] so + * pmevcntr_op_finish has the correct baseline when it converts back to + * a delta. + */ + uint16_t old_event = env->cp15.c14_pmevtyper[counter] & + PMXEVTYPER_EVTCOUNT; + uint16_t new_event = value & PMXEVTYPER_EVTCOUNT; + if (old_event != new_event) { + uint64_t count = 0; + if (event_supported(new_event)) { + uint16_t event_idx = supported_event_map[new_event]; + count = pm_events[event_idx].get_count(env); + } + env->cp15.c14_pmevcntr_delta[counter] = count; + } + + env->cp15.c14_pmevtyper[counter] = value & PMXEVTYPER_MASK; + pmevcntr_op_finish(env, counter); + } /* Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when * PMSELR value is equal to or greater than the number of implemented * counters, but not equal to 0x1f. We opt to behave as a RAZ/WI. */ - if (env->cp15.c9_pmselr == 0x1f) { - pmccfiltr_write(env, ri, value); +} + +static uint64_t pmevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri, + const uint8_t counter) +{ + if (counter == 31) { + return env->cp15.pmccfiltr_el0; + } else if (counter < pmu_num_counters(env)) { + return env->cp15.c14_pmevtyper[counter]; + } else { + /* + * We opt to behave as a RAZ/WI when attempts to access PMXEVTYPER + * are CONSTRAINED UNPREDICTABLE. See comments in pmevtyper_write(). + */ + return 0; } } +static void pmevtyper_writefn(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7); + pmevtyper_write(env, ri, value, counter); +} + +static void pmevtyper_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7); + env->cp15.c14_pmevtyper[counter] = value; + + /* + * pmevtyper_rawwrite is called between a pair of pmu_op_start and + * pmu_op_finish calls when loading saved state for a migration. Because + * we're potentially updating the type of event here, the value written to + * c14_pmevcntr_delta by the preceeding pmu_op_start call may be for a + * different counter type. Therefore, we need to set this value to the + * current count for the counter type we're writing so that pmu_op_finish + * has the correct count for its calculation. + */ + uint16_t event = value & PMXEVTYPER_EVTCOUNT; + if (event_supported(event)) { + uint16_t event_idx = supported_event_map[event]; + env->cp15.c14_pmevcntr_delta[counter] = + pm_events[event_idx].get_count(env); + } +} + +static uint64_t pmevtyper_readfn(CPUARMState *env, const ARMCPRegInfo *ri) +{ + uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7); + return pmevtyper_read(env, ri, counter); +} + +static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + pmevtyper_write(env, ri, value, env->cp15.c9_pmselr & 31); +} + static uint64_t pmxevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri) { - /* We opt to behave as a RAZ/WI when attempts to access PMXEVTYPER - * are CONSTRAINED UNPREDICTABLE. See comments in pmxevtyper_write(). + return pmevtyper_read(env, ri, env->cp15.c9_pmselr & 31); +} + +static void pmevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value, uint8_t counter) +{ + if (counter < pmu_num_counters(env)) { + pmevcntr_op_start(env, counter); + env->cp15.c14_pmevcntr[counter] = value; + pmevcntr_op_finish(env, counter); + } + /* + * We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR + * are CONSTRAINED UNPREDICTABLE. */ - if (env->cp15.c9_pmselr == 0x1f) { - return env->cp15.pmccfiltr_el0; +} + +static uint64_t pmevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri, + uint8_t counter) +{ + if (counter < pmu_num_counters(env)) { + uint64_t ret; + pmevcntr_op_start(env, counter); + ret = env->cp15.c14_pmevcntr[counter]; + pmevcntr_op_finish(env, counter); + return ret; } else { + /* We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR + * are CONSTRAINED UNPREDICTABLE. */ return 0; } } +static void pmevcntr_writefn(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7); + pmevcntr_write(env, ri, value, counter); +} + +static uint64_t pmevcntr_readfn(CPUARMState *env, const ARMCPRegInfo *ri) +{ + uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7); + return pmevcntr_read(env, ri, counter); +} + +static void pmevcntr_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7); + assert(counter < pmu_num_counters(env)); + env->cp15.c14_pmevcntr[counter] = value; + pmevcntr_write(env, ri, value, counter); +} + +static uint64_t pmevcntr_rawread(CPUARMState *env, const ARMCPRegInfo *ri) +{ + uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7); + assert(counter < pmu_num_counters(env)); + return env->cp15.c14_pmevcntr[counter]; +} + +static void pmxevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + pmevcntr_write(env, ri, value, env->cp15.c9_pmselr & 31); +} + +static uint64_t pmxevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ + return pmevcntr_read(env, ri, env->cp15.c9_pmselr & 31); +} + static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -1571,16 +1788,23 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0), .resetvalue = 0, }, { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1, - .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access, + .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = pmreg_access, .writefn = pmxevtyper_write, .readfn = pmxevtyper_read }, { .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1, - .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access, + .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = pmreg_access, .writefn = pmxevtyper_write, .readfn = pmxevtyper_read }, - /* Unimplemented, RAZ/WI. */ { .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2, - .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0, - .accessfn = pmreg_access_xevcntr }, + .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = pmreg_access_xevcntr, + .writefn = pmxevcntr_write, .readfn = pmxevcntr_read }, + { .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2, + .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO, + .accessfn = pmreg_access_xevcntr, + .writefn = pmxevcntr_write, .readfn = pmxevcntr_read }, { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0, .access = PL0_R | PL1_RW, .accessfn = access_tpm, .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmuserenr), @@ -4339,7 +4563,7 @@ static const ARMCPRegInfo el2_cp_reginfo[] = { #endif /* The only field of MDCR_EL2 that has a defined architectural reset value * is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N; but we - * don't impelment any PMU event counters, so using zero as a reset + * don't implement any PMU event counters, so using zero as a reset * value for MDCR_EL2 is okay */ { .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH, @@ -5191,6 +5415,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) * field as main ID register, and we implement only the cycle * count register. */ + unsigned int i, pmcrn = 4; #ifndef CONFIG_USER_ONLY ARMCPRegInfo pmcr = { .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0, @@ -5211,6 +5436,43 @@ void register_cp_regs_for_features(ARMCPU *cpu) }; define_one_arm_cp_reg(cpu, &pmcr); define_one_arm_cp_reg(cpu, &pmcr64); + for (i = 0; i < pmcrn; i++) { + char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i); + char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i); + char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i); + char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i); + ARMCPRegInfo pmev_regs[] = { + { .name = pmevcntr_name, .cp = 15, .crn = 15, + .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7, + .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS, + .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn, + .accessfn = pmreg_access }, + { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 8 | (3 & (i >> 3)), + .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_IO, + .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn, + .raw_readfn = pmevcntr_rawread, + .raw_writefn = pmevcntr_rawwrite }, + { .name = pmevtyper_name, .cp = 15, .crn = 15, + .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7, + .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS, + .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn, + .accessfn = pmreg_access }, + { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 12 | (3 & (i >> 3)), + .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access, + .type = ARM_CP_IO, + .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn, + .raw_writefn = pmevtyper_rawwrite }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, pmev_regs); + g_free(pmevcntr_name); + g_free(pmevcntr_el0_name); + g_free(pmevtyper_name); + g_free(pmevtyper_el0_name); + } #endif ARMCPRegInfo clidr = { .name = "CLIDR", .state = ARM_CP_STATE_BOTH, From patchwork Wed Oct 10 20:37:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982097 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="g16reVRe"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmJC1Js9z9s9J for ; Thu, 11 Oct 2018 07:42:51 +1100 (AEDT) Received: from localhost ([::1]:59052 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALJg-0005hV-Jk for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:42:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39809) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFi-0002wL-Gl for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFh-0002ju-CK for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:42 -0400 Received: from mail-yw1-xc44.google.com ([2607:f8b0:4864:20::c44]:43621) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFa-0002Uj-Oe; Wed, 10 Oct 2018 16:38:34 -0400 Received: by mail-yw1-xc44.google.com with SMTP id j75-v6so2716112ywj.10; Wed, 10 Oct 2018 13:38:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XSKOUQl9vmYg3HcpyWFwjAi/QFJzce6gGYliyVcFznE=; b=g16reVReXoKePBaxx+eU7KRtyu7j7tIvNe9sZVAWJD65TWxmtiVkmekQlZfEBlQgv+ NERx8GQ0o3ka3OOKzPoOPVaOT7yEbnBVMMc/UTZkopOgUodely24jsr8YHgbhEcVoC6m CQJdsEeICVHP+Lz8nhdsQfse8cfM/corRdfSDCktaITtP9zQaXM8X262NrEbkLn335Ch UwQAk7gx3/1b8xzgGp8kCNqzjvfg0KuP44d6LtzXroG0gEXfZBzqJHeHb69GG9xdJ3u8 kO0ida5gyuCiaee1UlCIvTweUoDqEMfBUtBGWmS01Dnml1hteCW3ydKwpDCfIobCuf69 VGyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XSKOUQl9vmYg3HcpyWFwjAi/QFJzce6gGYliyVcFznE=; b=fwnyyBXBl1W/iyF/Ofm3F/D48+a0iMsSEiZlv0f/OQAWg8IkmOdcHo3Svk+cftXOEq 8WDlSLsddE8pnioL4YgGHAe0eLIG2CKg0UBzzg9abwb/0YmVP7DBgHYb7qE0t0xG0tSv NPPK546A+j9ae0Nxsus9JupPeaKigkjBSgBJBHqWa2E1S3D37F4H0J0n4pTW9F2QBYWS AF0KPeeR6Ra34Z4L7sEPU6QxJJYa0d1aFiWG6NBgyxAFAO4crPP3h5WaZ4pkwNJiZ2/y cQLDlKWm5D2jXsCOxhfngdNwOEq8ngaPAQAuSdM2y6aWKmuCd5GUZiacUVYtIIv1cfaz I1jA== X-Gm-Message-State: ABuFfohbvsGrTS+lPFqJFiaRI/A/toD//c//r5D35kvTsJUx0pyXq6NF SbmzDSK9LbfNjJwapSYNviPaNhVB X-Google-Smtp-Source: ACcGV605J7NBmoB22gGeSW7fFpnPYdJwMFA+mxpfYKOHN0AzDOBab2M20Ale3SjNBpZCjvhxrGRmBw== X-Received: by 2002:a81:7a93:: with SMTP id v141-v6mr19516278ywc.100.1539203914004; Wed, 10 Oct 2018 13:38:34 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:33 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:32 -0400 Message-Id: <20181010203735.27918-12-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c44 Subject: [Qemu-devel] [PATCH v6 11/14] target/arm: PMU: Add instruction and cycle events 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The instruction event is only enabled when icount is used, cycles are always supported. Always defining get_cycle_count (but altering its behavior depending on CONFIG_USER_ONLY) allows us to remove some CONFIG_USER_ONLY #defines throughout the rest of the code. Signed-off-by: Aaron Lindsay Reviewed-by: Peter Maydell --- target/arm/helper.c | 90 ++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index f0798f7a8c..d6501de1ba 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -15,6 +15,7 @@ #include "arm_ldst.h" #include /* For crc32 */ #include "exec/semihost.h" +#include "sysemu/cpus.h" #include "sysemu/kvm.h" #include "fpu/softfloat.h" #include "qemu/range.h" @@ -988,9 +989,50 @@ typedef struct pm_event { uint64_t (*get_count)(CPUARMState *); } pm_event; +static bool event_always_supported(CPUARMState *env) +{ + return true; +} + +/* + * Return the underlying cycle count for the PMU cycle counters. If we're in + * usermode, simply return 0. + */ +static uint64_t cycles_get_count(CPUARMState *env) +{ +#ifndef CONFIG_USER_ONLY + return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); +#else + return 0; +#endif +} + +#ifndef CONFIG_USER_ONLY +static bool instructions_supported(CPUARMState *env) +{ + return use_icount == 1 /* Precise instruction counting */; +} + +static uint64_t instructions_get_count(CPUARMState *env) +{ + return (uint64_t)cpu_get_icount_raw(); +} +#endif + static const pm_event pm_events[] = { +#ifndef CONFIG_USER_ONLY + { .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */ + .supported = instructions_supported, + .get_count = instructions_get_count, + }, + { .number = 0x011, /* CPU_CYCLES, Cycle */ + .supported = event_always_supported, + .get_count = cycles_get_count, + } +#endif }; -#define MAX_EVENT_ID 0x0 +#define MAX_EVENT_ID 0x11 #define UNSUPPORTED_EVENT UINT16_MAX static uint16_t supported_event_map[MAX_EVENT_ID + 1]; @@ -1083,8 +1125,6 @@ static CPAccessResult pmreg_access_swinc(CPUARMState *env, return pmreg_access(env, ri, isread); } -#ifndef CONFIG_USER_ONLY - static CPAccessResult pmreg_access_selr(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) @@ -1195,9 +1235,7 @@ static inline bool pmu_counter_enabled(CPUARMState *env, uint8_t counter) */ void pmccntr_op_start(CPUARMState *env) { - uint64_t cycles = 0; - cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - ARM_CPU_FREQ, NANOSECONDS_PER_SECOND); + uint64_t cycles = cycles_get_count(env); if (pmu_counter_enabled(env, 31)) { uint64_t eff_cycles = cycles; @@ -1343,42 +1381,6 @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri, pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value)); } -#else /* CONFIG_USER_ONLY */ - -void pmccntr_op_start(CPUARMState *env) -{ -} - -void pmccntr_op_finish(CPUARMState *env) -{ -} - -void pmevcntr_op_start(CPUARMState *env, uint8_t i) -{ -} - -void pmevcntr_op_finish(CPUARMState *env, uint8_t i) -{ -} - -void pmu_op_start(CPUARMState *env) -{ -} - -void pmu_op_finish(CPUARMState *env) -{ -} - -void pmu_pre_el_change(ARMCPU *cpu, void *ignored) -{ -} - -void pmu_post_el_change(ARMCPU *cpu, void *ignored) -{ -} - -#endif - static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -1752,7 +1754,6 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { /* Unimplemented so WI. */ { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4, .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP }, -#ifndef CONFIG_USER_ONLY { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, .access = PL0_RW, .type = ARM_CP_ALIAS, .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr), @@ -1774,7 +1775,6 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt), .readfn = pmccntr_read, .writefn = pmccntr_write, .raw_readfn = raw_read, .raw_writefn = raw_write, }, -#endif { .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7, .writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32, .access = PL0_RW, .accessfn = pmreg_access, @@ -5416,7 +5416,6 @@ void register_cp_regs_for_features(ARMCPU *cpu) * count register. */ unsigned int i, pmcrn = 4; -#ifndef CONFIG_USER_ONLY ARMCPRegInfo pmcr = { .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0, .access = PL0_RW, @@ -5473,7 +5472,6 @@ void register_cp_regs_for_features(ARMCPU *cpu) g_free(pmevtyper_name); g_free(pmevtyper_el0_name); } -#endif ARMCPRegInfo clidr = { .name = "CLIDR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1, From patchwork Wed Oct 10 20:37:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982105 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Cf7/47lA"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmT76lxdz9s9N for ; Thu, 11 Oct 2018 07:50:35 +1100 (AEDT) Received: from localhost ([::1]:59102 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALRB-0003AT-JV for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:50:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39807) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFi-0002wJ-G4 for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFh-0002kD-K4 for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:42 -0400 Received: from mail-yb1-xb41.google.com ([2607:f8b0:4864:20::b41]:43086) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFb-0002Ve-Kb; Wed, 10 Oct 2018 16:38:35 -0400 Received: by mail-yb1-xb41.google.com with SMTP id w80-v6so2750414ybe.10; Wed, 10 Oct 2018 13:38:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EWF0Fr/S5CUPmbGpS8tqzvex/tP5zrxb/33cA+skGN4=; b=Cf7/47lAYIOTZaG7uIbjQGVGyyofz8AoFJ4bkLiY7cr+HyjzuzZ55u3biWAZNi+jxQ U40C7HLsK2Tw1qTjRBnaqpHRAxGmhXvVzwJX6rpCKpw3oAiG41Tip+MZACRUNEXwlm/9 IYf3wpHnEG6/hxkZEPuMnNBCnSJc953qUOYxBgDaKyLW9VcC5/DYnrTODeY/0E/1WWoz hV8uIteYdf7V/dlZl/jgiqZ8PN4bzWDO5G88P4HhJzj4SUgZzhmeKefafgbHZGl71Wlg ivqUya4+rdNqAVYweUVTIE9cr2gTUTHruk+eua0xhFyTNXo/SLAICme9Efl6y0/1OA+z ZslQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EWF0Fr/S5CUPmbGpS8tqzvex/tP5zrxb/33cA+skGN4=; b=CA3IKpn9hbJoP1ClcVAREC6zUGnGB8nPopI+rXYYxH0c0zjNUBxD1xi5Ma7Uh/HeRX wFXdX7UvtXNswC+EfSftKSwr0k6YY5Y4T4qyBWY5JsE4eu3itP2jREKOY/IBG8PgjPvF QPH9TspaPjczag3obWGCTWzxoRVK1uWe7/Mzzsl+9uDI/AJvInsUu1n5jPrC7t6h/4Py hjWFvCCk+mIakuReyKjUPWw3PT+dfGAwpEoycwhdJAG9kUh9hGLj2optJYEF5wlhaCwR ZWmkhYt4a8zEpvPIODb632Ewzf8lk9idjDhSTJjQWF7jQxW0u8oyNcMKLJRRy8zkaYFz CqqQ== X-Gm-Message-State: ABuFfojkcTaDM3SzDDGdBxNN5hBWDVvKwPUbfnwmA4jJ+b5f9nPXLbw8 2fX3sYKdE8uv6ja3TEA3DGo+g4Ur X-Google-Smtp-Source: ACcGV60CgvoECT5nEJ72eDJJUKMYbVccR5Pt32S+uCTYv0YrbaGR5OIoDKXHw6VU6p46atQpnmWnjA== X-Received: by 2002:a25:e481:: with SMTP id b123-v6mr19206298ybh.416.1539203914835; Wed, 10 Oct 2018 13:38:34 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:34 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:33 -0400 Message-Id: <20181010203735.27918-13-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::b41 Subject: [Qemu-devel] [PATCH v6 12/14] target/arm: PMU: Set PMCR.N to 4 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This both advertises that we support four counters and enables them because the pmu_num_counters() reads this value from PMCR. Signed-off-by: Aaron Lindsay --- target/arm/helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index d6501de1ba..89ceb34cb9 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -1706,7 +1706,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .access = PL1_W, .type = ARM_CP_NOP }, /* Performance monitors are implementation defined in v7, * but with an ARM recommended set of registers, which we - * follow (although we don't actually implement any counters) + * follow. * * Performance registers fall into three categories: * (a) always UNDEF in PL0, RW in PL1 (PMINTENSET, PMINTENCLR) @@ -5412,8 +5412,8 @@ void register_cp_regs_for_features(ARMCPU *cpu) } if (arm_feature(env, ARM_FEATURE_V7)) { /* v7 performance monitor control register: same implementor - * field as main ID register, and we implement only the cycle - * count register. + * field as main ID register, and we implement four counters in + * addition to the cycle count register. */ unsigned int i, pmcrn = 4; ARMCPRegInfo pmcr = { @@ -5430,7 +5430,7 @@ void register_cp_regs_for_features(ARMCPU *cpu) .access = PL0_RW, .accessfn = pmreg_access, .type = ARM_CP_IO, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr), - .resetvalue = cpu->midr & 0xff000000, + .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT), .writefn = pmcr_write, .raw_writefn = raw_write, }; define_one_arm_cp_reg(cpu, &pmcr); From patchwork Wed Oct 10 20:37:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982103 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="deB4FQOr"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmQM1Nwhz9s9h for ; Thu, 11 Oct 2018 07:48:11 +1100 (AEDT) Received: from localhost ([::1]:59084 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALOq-0001VA-PC for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:48:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39804) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFi-0002wF-CN for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFh-0002k6-IG for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:42 -0400 Received: from mail-yw1-xc29.google.com ([2607:f8b0:4864:20::c29]:44722) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFc-0002XI-Ky; Wed, 10 Oct 2018 16:38:36 -0400 Received: by mail-yw1-xc29.google.com with SMTP id s73-v6so2710425ywg.11; Wed, 10 Oct 2018 13:38:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YJ6eE9L423EKbyHgFwS2f9XgDpoJJ4DU/ssXptC2hWQ=; b=deB4FQOrIsIZ9P4Nm3RNbpVIQA8SCtTpMR5nWT7iEM4o1e+hYzwS9k2Rq5u8HN3GQk if6glw0NfW3qWblWKvMibJli3LlIQ4cb+CR9iSTXbmSrlRqGaOsGIIvj8habLV3ya3+3 H2VIZmMsYG49ImDuC4IRNmlh8hKrSrT/aC9QVUBWVEtMMmPFv1JU0A3OMLSONO7kE9Yv HkqQn16IaGM+yCpAwN7xw7ktzxWD0JX8dahndGIcoFArwmQgbsKbE/aJzxlMH3n4TbZE b2ktKD1aJ6z/M0uhjdN7Efr0dNaXKiq24bAastAWTt+Hd5wP86n2aRRVE5qvHXDYK6+o smeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YJ6eE9L423EKbyHgFwS2f9XgDpoJJ4DU/ssXptC2hWQ=; b=BxUsfiDSyI+58dOfgt68eAwUx2lgpp9Uadn2uEXgXySNjhtRayPX+C+x0trxVzLP/a fiaTtXbBuGJTIasC6qyQiIFto/irgLw3rN2FYXJXpTT9yyK5QGMV93710mzoKIqIZHdX MusjgFlazRq6ZMHaYRo5P20AElS5Tr78RbtMf4aPBQjO2naBqS2YQ755GEvhTUSRZUBS bkkhqTlfO/rOVmUQkHyG+nz7TxpD8upu63CWXnIITQqqeaBhQL33H31B9oomXeVySwV1 7j2Ja0nkttD7jzXWbV2v4fsPCaPnhB2pdjvGejgdO7oB+iiJF2kqGppUkBHjAB1m/af8 4ijw== X-Gm-Message-State: ABuFfojQxJcKEkLPsGGJj3FXz0q7o/IWLo9Rfv8C109zvGfTzWr+QCYu rhIPSlLqOphg9pZSP/lxgOWGeu4h X-Google-Smtp-Source: ACcGV600kDey8m+gsjc3xXGpoRsWt45aFdxWU6YkOI7QANBTaw2yk1UzSy8sKpb4Ywcv8mU7xXYJIQ== X-Received: by 2002:a81:764b:: with SMTP id j11-v6mr19476632ywk.137.1539203915885; Wed, 10 Oct 2018 13:38:35 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:35 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:34 -0400 Message-Id: <20181010203735.27918-14-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c29 Subject: [Qemu-devel] [PATCH v6 13/14] target/arm: Implement PMSWINC 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Aaron Lindsay Reviewed-by: Richard Henderson --- target/arm/helper.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index 89ceb34cb9..6c2a899009 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -994,6 +994,15 @@ static bool event_always_supported(CPUARMState *env) return true; } +static uint64_t swinc_get_count(CPUARMState *env) +{ + /* + * SW_INCR events are written directly to the pmevcntr's by writes to + * PMSWINC, so there is no underlying count maintained by the PMU itself + */ + return 0; +} + /* * Return the underlying cycle count for the PMU cycle counters. If we're in * usermode, simply return 0. @@ -1021,6 +1030,10 @@ static uint64_t instructions_get_count(CPUARMState *env) #endif static const pm_event pm_events[] = { + { .number = 0x000, /* SW_INCR */ + .supported = event_always_supported, + .get_count = swinc_get_count, + }, #ifndef CONFIG_USER_ONLY { .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */ .supported = instructions_supported, @@ -1345,6 +1358,24 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, pmu_op_finish(env); } +static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ + unsigned int i; + for (i = 0; i < pmu_num_counters(env); i++) { + /* Increment a counter's count iff: */ + if ((value & (1 << i)) && /* counter's bit is set */ + /* counter is enabled and not filtered */ + pmu_counter_enabled(env, i) && + /* counter is SW_INCR */ + (env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) { + pmevcntr_op_start(env, i); + env->cp15.c14_pmevcntr[i]++; + pmevcntr_op_finish(env, i); + } + } +} + static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri) { uint64_t ret; @@ -1751,9 +1782,13 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr), .writefn = pmovsr_write, .raw_writefn = raw_write }, - /* Unimplemented so WI. */ { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4, - .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP }, + .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW, + .writefn = pmswinc_write }, + { .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4, + .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW, + .writefn = pmswinc_write }, { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5, .access = PL0_RW, .type = ARM_CP_ALIAS, .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr), From patchwork Wed Oct 10 20:37:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Lindsay X-Patchwork-Id: 982104 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="HmC3uQ4R"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42VmRy0cv6z9s9J for ; Thu, 11 Oct 2018 07:49:34 +1100 (AEDT) Received: from localhost ([::1]:59094 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALQB-0002WA-6l for incoming@patchwork.ozlabs.org; Wed, 10 Oct 2018 16:49:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39842) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gALFk-0002z9-Ln for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gALFj-0002lJ-5p for qemu-devel@nongnu.org; Wed, 10 Oct 2018 16:38:44 -0400 Received: from mail-yw1-xc44.google.com ([2607:f8b0:4864:20::c44]:34685) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gALFd-0002av-Oy; Wed, 10 Oct 2018 16:38:37 -0400 Received: by mail-yw1-xc44.google.com with SMTP id m129-v6so2731187ywc.1; Wed, 10 Oct 2018 13:38:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RgwX8cXGv99sl4bIbEoKxd7822+OZEtz9oMUx2BxVpA=; b=HmC3uQ4R4MghIqItEsYc2a21Uk9ZOrk4h3m4yBsvuEPv0lMGzcEkCh1WO3lxuy27bU hCbQeBIwd9X+vCxh3mp99z8nHAuJ/14+IwaHP8mSiIxGrSALufq0Q+zDAM0ijUPf3C/+ ZGBg4ATuyPHO8GCfYv1kdCa9w9vY61F8TObPHhsD/4Zo2PE0e5+4Ga/lCnx53dULCKA6 KyjlyXh/2MpiQdnafZGDQpTCd/Ffv+2qCYVfxI/aQLkQzDQLbdrD/wJI/W5LI5EKedKA QhHY/9aMqzkDUFSQjUcLRW0JCX7mclcNnCT9zdnJXL3yCrAAm3r0aof4+tvFkYB9iTLl F1jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RgwX8cXGv99sl4bIbEoKxd7822+OZEtz9oMUx2BxVpA=; b=fhYKdZsQqR4jtFI6F5HGL2ZUbTVhx9GXCforFKUczof6/nJbeQTwccs1dKsfq14knA 6a+uprexadRIcV4qQWhUdxMbJudkwZbnclUA4KMa1HHOhayqd3MDFEynaxrt58ukXdvp DLlIoPEWMChddt4K7pLg+RYBD7jpktwMEtXJc7pdmpy5o5pksSZz4QX2S+b5K69RNMXm 8b/3LfhKAEJGbkZfveCakgc/NHzVV+bFyTokJV98ybAQOz8e4nXXQ7Y7KoMbp78FEaWg lDNpMJF4pbT9nJBnK6U+E3hncw1yQOeWyXrUBsheq5/HOaE3UkkeG5np/5og5U/J6NWP 87Dw== X-Gm-Message-State: ABuFfoifRyAGmoLmtzIsyjq+UXWhOdEO7xlIXGNaZGvVGt+Y+zRFVOCH ojJhr2NmOqRWFHgMbM4npk11teqh X-Google-Smtp-Source: ACcGV60v2KBY01iCcfz8D9y5ofy7wFb1G8DFWVYjdUocG5ILW15fR9UXK/BY/WXyUcsnGctn/yypRw== X-Received: by 2002:a81:9345:: with SMTP id k66-v6mr19804401ywg.507.1539203916810; Wed, 10 Oct 2018 13:38:36 -0700 (PDT) Received: from quinoa.localdomain ([216.85.170.153]) by smtp.gmail.com with ESMTPSA id u131-v6sm15170728ywf.13.2018.10.10.13.38.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Oct 2018 13:38:36 -0700 (PDT) From: Aaron Lindsay To: qemu-arm@nongnu.org, Peter Maydell , Alistair Francis , Wei Huang , Peter Crosthwaite Date: Wed, 10 Oct 2018 16:37:35 -0400 Message-Id: <20181010203735.27918-15-aclindsa@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181010203735.27918-1-aclindsa@gmail.com> References: <20181010203735.27918-1-aclindsa@gmail.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::c44 Subject: [Qemu-devel] [PATCH v6 14/14] target/arm: Send interrupts on PMU counter overflow 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: , Cc: Aaron Lindsay , Michael Spradling , qemu-devel@nongnu.org, Digant Desai Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Setup a QEMUTimer to get a callback when we expect counters to next overflow and trigger an interrupt at that time. Signed-off-by: Aaron Lindsay --- target/arm/cpu.c | 11 ++++ target/arm/cpu.h | 7 +++ target/arm/helper.c | 126 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 138 insertions(+), 6 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 7f39f25f51..c89c7c776c 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -764,6 +764,12 @@ static void arm_cpu_finalizefn(Object *obj) QLIST_REMOVE(hook, node); g_free(hook); } +#ifndef CONFIG_USER_ONLY + if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) { + timer_deinit(cpu->pmu_timer); + timer_free(cpu->pmu_timer); + } +#endif } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) @@ -958,6 +964,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0); arm_register_el_change_hook(cpu, &pmu_post_el_change, 0); } + +#ifndef CONFIG_USER_ONLY + cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, arm_pmu_timer_cb, + cpu); +#endif } else { cpu->pmceid0 = 0x00000000; cpu->pmceid1 = 0x00000000; diff --git a/target/arm/cpu.h b/target/arm/cpu.h index f4317f87c9..a27481658c 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -721,6 +721,8 @@ struct ARMCPU { /* Timers used by the generic (architected) timer */ QEMUTimer *gt_timer[NUM_GTIMERS]; + /* Timer used by the PMU */ + QEMUTimer *pmu_timer; /* GPIO outputs for generic timer */ qemu_irq gt_timer_outputs[NUM_GTIMERS]; /* GPIO output for GICv3 maintenance interrupt signal */ @@ -972,6 +974,11 @@ void pmccntr_op_finish(CPUARMState *env); void pmu_op_start(CPUARMState *env); void pmu_op_finish(CPUARMState *env); +/** + * Called when a PMU counter is due to overflow + */ +void arm_pmu_timer_cb(void *opaque); + /** * Functions to register as EL change hooks for PMU mode filtering */ diff --git a/target/arm/helper.c b/target/arm/helper.c index 6c2a899009..9699e43f0c 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -944,6 +944,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { /* Definitions for the PMU registers */ #define PMCRN_MASK 0xf800 #define PMCRN_SHIFT 11 +#define PMCRLC 0x40 #define PMCRDP 0x10 #define PMCRD 0x8 #define PMCRC 0x4 @@ -963,6 +964,8 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { PMXEVTYPER_M | PMXEVTYPER_MT | \ PMXEVTYPER_EVTCOUNT) +#define PMEVCNTR_OVERFLOW_MASK ((uint64_t)1 << 31) + #define PMCCFILTR 0xf8000000 #define PMCCFILTR_M PMXEVTYPER_M #define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M) @@ -987,6 +990,11 @@ typedef struct pm_event { * counters hold a difference from the return value from this function */ uint64_t (*get_count)(CPUARMState *); + /* Return how many nanoseconds it will take (at a minimum) for count events + * to occur. A negative value indicates the counter will never overflow, or + * that the counter has otherwise arranged for the overflow bit to be set + * and the PMU interrupt to be raised on overflow. */ + int64_t (*ns_per_count)(uint64_t); } pm_event; static bool event_always_supported(CPUARMState *env) @@ -1003,6 +1011,11 @@ static uint64_t swinc_get_count(CPUARMState *env) return 0; } +static int64_t swinc_ns_per(uint64_t ignored) +{ + return -1; +} + /* * Return the underlying cycle count for the PMU cycle counters. If we're in * usermode, simply return 0. @@ -1018,6 +1031,11 @@ static uint64_t cycles_get_count(CPUARMState *env) } #ifndef CONFIG_USER_ONLY +static int64_t cycles_ns_per(uint64_t cycles) +{ + return (ARM_CPU_FREQ / NANOSECONDS_PER_SECOND) * cycles; +} + static bool instructions_supported(CPUARMState *env) { return use_icount == 1 /* Precise instruction counting */; @@ -1027,21 +1045,29 @@ static uint64_t instructions_get_count(CPUARMState *env) { return (uint64_t)cpu_get_icount_raw(); } + +static int64_t instructions_ns_per(uint64_t icount) +{ + return cpu_icount_to_ns((int64_t)icount); +} #endif static const pm_event pm_events[] = { { .number = 0x000, /* SW_INCR */ .supported = event_always_supported, .get_count = swinc_get_count, + .ns_per_count = swinc_ns_per, }, #ifndef CONFIG_USER_ONLY { .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */ .supported = instructions_supported, .get_count = instructions_get_count, + .ns_per_count = instructions_ns_per, }, { .number = 0x011, /* CPU_CYCLES, Cycle */ .supported = event_always_supported, .get_count = cycles_get_count, + .ns_per_count = cycles_ns_per, } #endif }; @@ -1240,6 +1266,13 @@ static inline bool pmu_counter_enabled(CPUARMState *env, uint8_t counter) return enabled && !prohibited && !filtered; } +static void pmu_update_irq(CPUARMState *env) +{ + ARMCPU *cpu = arm_env_get_cpu(env); + qemu_set_irq(cpu->pmu_interrupt, (env->cp15.c9_pmcr & PMCRE) && + (env->cp15.c9_pminten & env->cp15.c9_pmovsr)); +} + /* * Ensure c15_ccnt is the guest-visible count so that operations such as * enabling/disabling the counter or filtering, modifying the count itself, @@ -1257,7 +1290,18 @@ void pmccntr_op_start(CPUARMState *env) eff_cycles /= 64; } - env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta; + uint64_t new_pmccntr = eff_cycles - env->cp15.c15_ccnt_delta; + + unsigned int overflow_bit = (env->cp15.c9_pmcr & PMCRLC) ? 63 : 31; + uint64_t overflow_mask = (uint64_t)1 << overflow_bit; + if (!(new_pmccntr & overflow_mask) && + (env->cp15.c15_ccnt & overflow_mask)) { + env->cp15.c9_pmovsr |= (1 << 31); + new_pmccntr &= ~overflow_mask; + pmu_update_irq(env); + } + + env->cp15.c15_ccnt = new_pmccntr; } env->cp15.c15_ccnt_delta = cycles; } @@ -1270,13 +1314,28 @@ void pmccntr_op_start(CPUARMState *env) void pmccntr_op_finish(CPUARMState *env) { if (pmu_counter_enabled(env, 31)) { - uint64_t prev_cycles = env->cp15.c15_ccnt_delta; +#ifndef CONFIG_USER_ONLY + uint64_t delta; + if (env->cp15.c9_pmcr & PMCRLC) { + delta = UINT64_MAX - env->cp15.c15_ccnt + 1; + } else { + delta = UINT32_MAX - (uint32_t)env->cp15.c15_ccnt + 1; + } + int64_t overflow_in = cycles_ns_per(delta); + + if (overflow_in > 0) { + int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + overflow_in; + ARMCPU *cpu = arm_env_get_cpu(env); + timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at); + } +#endif + uint64_t prev_cycles = env->cp15.c15_ccnt_delta; if (env->cp15.c9_pmcr & PMCRD) { /* Increment once every 64 processor clock cycles */ prev_cycles /= 64; } - env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt; } } @@ -1292,8 +1351,15 @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t counter) } if (pmu_counter_enabled(env, counter)) { - env->cp15.c14_pmevcntr[counter] = - count - env->cp15.c14_pmevcntr_delta[counter]; + uint64_t new_pmevcntr = count - env->cp15.c14_pmevcntr_delta[counter]; + + if (!(new_pmevcntr & PMEVCNTR_OVERFLOW_MASK) && + (env->cp15.c14_pmevcntr[counter] & PMEVCNTR_OVERFLOW_MASK)) { + env->cp15.c9_pmovsr |= (1 << counter); + new_pmevcntr &= ~PMEVCNTR_OVERFLOW_MASK; + pmu_update_irq(env); + } + env->cp15.c14_pmevcntr[counter] = new_pmevcntr; } env->cp15.c14_pmevcntr_delta[counter] = count; } @@ -1301,6 +1367,21 @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t counter) static void pmevcntr_op_finish(CPUARMState *env, uint8_t counter) { if (pmu_counter_enabled(env, counter)) { +#ifndef CONFIG_USER_ONLY + uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT; + uint16_t event_idx = supported_event_map[event]; + uint64_t delta = UINT32_MAX - + (uint32_t)env->cp15.c14_pmevcntr[counter] + 1; + int64_t overflow_in = pm_events[event_idx].ns_per_count(delta); + + if (overflow_in > 0) { + int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + overflow_in; + ARMCPU *cpu = arm_env_get_cpu(env); + timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at); + } +#endif + env->cp15.c14_pmevcntr_delta[counter] -= env->cp15.c14_pmevcntr[counter]; } @@ -1334,6 +1415,19 @@ void pmu_post_el_change(ARMCPU *cpu, void *ignored) pmu_op_finish(&cpu->env); } +void arm_pmu_timer_cb(void *opaque) +{ + ARMCPU *cpu = opaque; + + /* Update all the counter values based on the current underlying counts, + * triggering interrupts to be raised, if necessary. pmu_op_finish() also + * has the effect of setting the cpu->pmu_timer to the next earliest time a + * counter may expire. + */ + pmu_op_start(&cpu->env); + pmu_op_finish(&cpu->env); +} + static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -1370,7 +1464,21 @@ static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri, /* counter is SW_INCR */ (env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) { pmevcntr_op_start(env, i); - env->cp15.c14_pmevcntr[i]++; + + /* Detect if this write causes an overflow since we can't predict + * PMSWINC overflows like we can for other events + */ + uint64_t new_pmswinc = env->cp15.c14_pmevcntr[i] + 1; + + if (!(new_pmswinc & PMEVCNTR_OVERFLOW_MASK) && + (env->cp15.c14_pmevcntr[i] & PMEVCNTR_OVERFLOW_MASK)) { + env->cp15.c9_pmovsr |= (1 << i); + new_pmswinc &= ~PMEVCNTR_OVERFLOW_MASK; + pmu_update_irq(env); + } + + env->cp15.c14_pmevcntr[i] = new_pmswinc; + pmevcntr_op_finish(env, i); } } @@ -1441,6 +1549,7 @@ static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri, { value &= pmu_counter_mask(env); env->cp15.c9_pmcnten |= value; + pmu_update_irq(env); } static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1448,6 +1557,7 @@ static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, { value &= pmu_counter_mask(env); env->cp15.c9_pmcnten &= ~value; + pmu_update_irq(env); } static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1455,6 +1565,7 @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri, { value &= pmu_counter_mask(env); env->cp15.c9_pmovsr &= ~value; + pmu_update_irq(env); } static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1462,6 +1573,7 @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri, { value &= pmu_counter_mask(env); env->cp15.c9_pmovsr |= value; + pmu_update_irq(env); } static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1648,6 +1760,7 @@ static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri, /* We have no event counters so only the C bit can be changed */ value &= pmu_counter_mask(env); env->cp15.c9_pminten |= value; + pmu_update_irq(env); } static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, @@ -1655,6 +1768,7 @@ static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri, { value &= pmu_counter_mask(env); env->cp15.c9_pminten &= ~value; + pmu_update_irq(env); } static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,