From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B378FA59 for ; Sat, 1 Nov 2025 15:43:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011792; cv=none; b=jT1C+u5aEWkp35Lk1L5b8G9f/Bvuy4XfRxODMAi4+qKO1WQBXcb5ZFzqcUJ30xLz+F0aYa8A/rjRRR8sKdWBEc+BtE9Q3daOWc2nZVAgnrl6MpuUsgM3aEp00Wx6kgXfXlRrpARgpdiE/hhXRFTvZ4c8p0zPpMmG/XvHRHABwE0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011792; c=relaxed/simple; bh=OtVnZzUaYjn1Rh1BXslqcE/Vnsj4xtT0TKYxOcVoPh8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gW+igTeD1F9QAGiENnIlcb8XK/2HhoywhlDOuukbwKvfZ6OB8054MlarIC9frEhNtXehNFE5O6NMVKZ3E/zo0c5D+vFw0zSvIVWxmwuhLHPg+VSfwJV/Qi1JUKEhlNz0iwI4oc43vyaZFbMdfHtZ0WtrUqYedXWR2smD4g5u/h4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=jmeIqfut; arc=none smtp.client-ip=209.85.214.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="jmeIqfut" Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-29524abfba3so16639955ad.1 for ; Sat, 01 Nov 2025 08:43:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011790; x=1762616590; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CcA70PVwTnb4/jopyJB8UMf+ejoU1/qkR5vDiv7mLZA=; b=jmeIqfutEVbpoLhFhr7JP+IAJV/HOGBGz08zMpvD7h/SVmFgFQxhCclHdOpkahSOwg X9uJt/r/U5nPfi0Xp1YZXsx5JlwEy2JZfFmSGZFtwsJcdJKn7QcPOtAGxQY17LFvyijf kvQFUy1TUDM9FOOcxiYFwxCiTyjsBQCnR1Obkj3pKL6e1St6E7V3bLpoKpr+gRMDaBGm eiszvbI7EuPZBZMUZGD65Wwa4woL0Q7ilpO+3weEFUYvxRzAWYaiVO7Xi5GQdoe1ki7c /Ac4ftMZZfq6AOgT6y/AUA0+RnTqXHXQpTVRLScKWQgVmkSLK9T+68L/Ugq3q1fNzuSQ 2xRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011790; x=1762616590; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CcA70PVwTnb4/jopyJB8UMf+ejoU1/qkR5vDiv7mLZA=; b=f8uJIBYcDE2xUAJRzQ3WMNMiq4LzklxsktwtHAu7jotHyvLq+XPMOC7NuNA/kYda+M 3CgVXSYh24XFgi6zx+w5jBJGU1gM+DsbbasWBoI05CqrO1IkkgI1/fzrBjhjmDW/02WT vjgw6N60uEco/74P4o3899cct6UcLVerGgSpRuIR5gFrkRHPHqbKB1cP53giQ9saF3MO tMw+OwBWHUOId9g8H08xrRk5qtKDFKhBGbW3r0eo91i7en4Qw8OWbZKjJ7qjc07aRG+J qyOdXrqtaKaYSqGBQHNxqlwwf0+96kaNMN6FmvVUN+MCGBjF+O7kuNr4yApRnznqseCl DBjQ== X-Forwarded-Encrypted: i=1; AJvYcCUUduN4jYrRH7B22p3pbgiDnQnp3Qk7X1Y7Ih3duR/+L70ndcZCwGzk/VDZr2utlnUfhb4cdTKsucU+jKM=@vger.kernel.org X-Gm-Message-State: AOJu0YypdTxFnVDJdd9mD5dMCJ6RDygFes4dzANCM3T73gCHow/41RWb 1tCklxKUm0GVYAYXzaGfC8CEwAPJDVIJOw/BzsYKTCP/q30nWLZSbJhdBsacv4Mhu4AoyAupLia s634uDQQ= X-Gm-Gg: ASbGncsNRd5YutyiSuhA3HuPGq9jv5t2py6kLvfIcLyy4cE2qYybziPUaESOSwOC9cs b/D7hJr+YmfJK7t9ewpkXRxL6QHMYdIDc0/2XlG+/p3OCpdMECPKDbNT6n4aRekgtC7QzVjPZBb 4FFgvbZWpxFMRrHUyxnDbngprRpvqblHlda2sX7GPPmwyJCraR3FBsoiQWepPd9ysxRgGyFdP7u ZWi0dpoOyBYzsMthoXV0dex2o0RvsO3ukxBrUaqXRlFoRp1xXHC5+iuySG39Msc5D2ZjiRnlodD sRcF3vM2NdckuEmQDdY3gQcoeevmsbLwnjwl4jAQST/BKDC4wsWj5oIfrljDdpIALlf/1+yexn1 XUmFbSopM5ySkUalpoRvEclW/acYk/QoarljW2FshjPqrIzgX0nb2KJIp/Kf0pm7iwRafaBz8Qc QXg1PllBFB1+JMhFRBDHFGP2W8o60sBnUUosFZUyPpPg== X-Google-Smtp-Source: AGHT+IGpRBEwhgyZU04oRdc2JtlV77rsk0jCZD7dlM8oXxEemL+4JiYFTNnpMduG0pla8WCCicoqeg== X-Received: by 2002:a17:903:38c7:b0:295:62d:503c with SMTP id d9443c01a7336-2951a3d281bmr96116035ad.16.1762011789776; Sat, 01 Nov 2025 08:43:09 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.43.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:43:09 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Anup Patel Subject: [PATCH v2 01/12] dt-bindings: Add RISC-V trace component bindings Date: Sat, 1 Nov 2025 21:12:34 +0530 Message-ID: <20251101154245.162492-2-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add device tree bindings for the memory mapped RISC-V trace components which support both the RISC-V efficient trace (E-trace) protocol and the RISC-V Nexus-based trace (N-trace) protocol. The RISC-V trace components are defined by the RISC-V trace control interface specification. Signed-off-by: Anup Patel --- .../bindings/riscv/riscv,trace-component.yaml | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 Documentation/devicetree/bindings/riscv/riscv,trace-com= ponent.yaml diff --git a/Documentation/devicetree/bindings/riscv/riscv,trace-component.= yaml b/Documentation/devicetree/bindings/riscv/riscv,trace-component.yaml new file mode 100644 index 000000000000..7979af3d4174 --- /dev/null +++ b/Documentation/devicetree/bindings/riscv/riscv,trace-component.yaml @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/riscv/riscv,trace-component.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RISC-V Trace Component + +maintainers: + - Anup Patel + +description: + The RISC-V trace control interface specification standard memory mapped + components (or devices) which support both the RISC-V efficient trace + (E-trace) protocol and the RISC-V Nexus-based trace (N-trace) protocol. + The RISC-V trace components have implementation specific directed acyclic + graph style interdependency where output of one component serves as input + to another component and certain components (such as funnel) can take in= puts + from multiple components. The type and version of a RISC-V trace compone= nt + can be discovered from it's IMPL memory mapped register hence component + specific compatible strings are not needed. + +properties: + compatible: + items: + - enum: + - qemu,trace-component + - const: riscv,trace-component + + reg: + maxItems: 1 + + cpus: + maxItems: 1 + description: + phandle to the cpu to which the RISC-V trace component is bound. + + in-ports: + $ref: /schemas/graph.yaml#/properties/ports + patternProperties: + '^port(@[0-7])?$': + description: Input connections from RISC-V trace component + $ref: /schemas/graph.yaml#/properties/port + + out-ports: + $ref: /schemas/graph.yaml#/properties/ports + patternProperties: + '^port(@[0-7])?$': + description: Output connections from RISC-V trace component + $ref: /schemas/graph.yaml#/properties/port + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + // Example 1 (Per-hart encoder and ramsink components): + + encoder@c000000 { + compatible =3D "qemu,trace-component", "riscv,trace-component"; + reg =3D <0xc000000 0x1000>; + cpus =3D <&CPU0>; + out-ports { + port { + CPU0_ENCODER_OUTPUT: endpoint { + remote-endpoint =3D <&CPU0_RAMSINK_INPUT>; + }; + }; + }; + }; + + ramsink@c001000 { + compatible =3D "qemu,trace-component", "riscv,trace-component"; + reg =3D <0xc001000 0x1000>; + cpus =3D <&CPU0>; + in-ports { + port { + CPU0_RAMSINK_INPUT: endpoint { + }; + }; + }; + }; + + encoder@c002000 { + compatible =3D "qemu,trace-component", "riscv,trace-component"; + reg =3D <0xc002000 0x1000>; + cpus =3D <&CPU1>; + out-ports { + port { + CPU1_ENCODER_OUTPUT: endpoint { + remote-endpoint =3D <&CPU1_RAMSINK_INPUT>; + }; + }; + }; + }; + + ramsink@c003000 { + compatible =3D "qemu,trace-component", "riscv,trace-component"; + reg =3D <0xc003000 0x1000>; + cpus =3D <&CPU1>; + in-ports { + port { + CPU1_RAMSINK_INPUT: endpoint { + }; + }; + }; + }; + +... --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E0022F7AB4 for ; Sat, 1 Nov 2025 15:43:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011801; cv=none; b=gCnD+1lW/11U4PNTQzdW8Fc0ZGFtguqxC9uwH+anCoRau/CEK2K2GBswryqxFxmu3IveeLIdNVf2JTu9W6TV8GHQh/c1H+Be2GgVGun8zaOIpjjb59+wANfMP9TjnnNy46M4XW9qsEROk4zvuVAQ8po6ONmKMm/zRTR6N2PMklM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011801; c=relaxed/simple; bh=VVec7viv6uqUlzWdJG3sfe+ksYGDSOzFQvzqCdjqLjA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TiMVoHMVqz7OUFiXDkESlAN+PAncTXLE/86UA1CPFpMed15azg2pkf9WAU6CKS5XryfwXWxm7ZBDPa6ArhBjaAqAcA7eVNxhqjMWYGx9IcP3HittHxrAPigaMFivr+gaeI/luP9uI02j8YXVVFqKn8/+qVxqq9q25DDUWhtrhPk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=KdDASeTE; arc=none smtp.client-ip=209.85.215.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="KdDASeTE" Received: by mail-pg1-f170.google.com with SMTP id 41be03b00d2f7-b550eff972eso2245991a12.3 for ; Sat, 01 Nov 2025 08:43:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011798; x=1762616598; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lJutO7OK9RvRlu7Ga6ZLaugpxZbKoUMzueQ1pJ0IpGo=; b=KdDASeTE5sZtP+gpx8bh6YRUgchvvllcT3QQPGuc5U//xpv/h1y9UaCxurj1KxHRY6 JUm3wvtpHD8hYFpDs4Oompq3wsTSchni57kPql+DrJ+tPfmWkMMUUaio/ExA3sEj78a9 u3Y3sEBRTUFjPqx7KHeIDbPzZZan8oMpBPuWDNFT/JgSpccvKuZKlYZ8MKSSRZgNwepg vyEUtCFdT75ewkCQl7CkjBZ8brJg0ME2z3vvlz3URiapBi9ZpjHrUptIum9oZuRNGPJu lvRHmDlgvTc0BD4Ba4PQtKLhf960fKqgVn6zj6FFL4J4zUFHjpG+W8GOaOKHp4DdX2gq rKtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011798; x=1762616598; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lJutO7OK9RvRlu7Ga6ZLaugpxZbKoUMzueQ1pJ0IpGo=; b=hm2kYtZMGJHv3yn7nlQ96ff4Qjl8c9hMGNY5Fdh5lS+bHQ8CMXjh9hX/mPJjQVkU7Y u3engzOmbMwbr/ioPKs/37M7UqFM0QnLH0gmR/FbCzbr5TJd21Pnk6yvO8RJzoIn0jKN 1Ngm1kR3JE5kvpQKkYJzSNjnx2YJo/sDarrgCotTQmLtgjZlmcVcPJ65TM3oh1Bn06y5 11hAlVImsz0pCuYeuzNiNdb/fj0CsS7SsJIJHmHqXc5OpvaQi6esBePgCoP2YzfVH8rO 9ZZrAxfkRBGEQV+UHJ7ehxDcceSXJ6+x74zl6UkYNcJLbeIDeMZZ21oZkiRMPJ6HdScQ ncpQ== X-Forwarded-Encrypted: i=1; AJvYcCUdW/M9R9/KeRw8ZRuaRSHya7Fjg4q59Aj7tomj2spE9NF7nQ7iEQCNLegcULk3e3P9FSg/KptbOR6llL0=@vger.kernel.org X-Gm-Message-State: AOJu0Yz4SAGiBzYvoHq2lWK5vf1SEchyHo8lvv79/nhK6tNruKt3yWXn mx9xG2CCJPUBhY4I+aQaTia0vHtT9cp6WqXoW9F1IX4T99HdjZOoI6di/cXBvQlX5Mc= X-Gm-Gg: ASbGncu1rep1M29x9HdxfIMYbtV5giyk8k8fs5wF7QDivnj4sD0x791E9NFeNnDOdD2 7HKogDTk2vhzMWVl7Wd39dT1LLabkmwJ9cWYMEX3PBv1etEdfCqvD2JAWZrDUKX9PCuD2QRz8Yy r6CRUUc2eI2XpSlipfXFEv1MJge3h4ncvk3CWfF0PTWcY/ps72pdwwSNhfpR1Ikx5UH9iqcY/bM maJze0O6WRni94KlG/ThAbUHlkNfSkHfcyYJ3ZQCaTIm1VQCGBdIZvTzkeQNSXAU4bgxe9v9FsR vPoeCXNpjsJa9v3QbiUkB74L6Qe5R1P8KcdYv+K+7SETriw6BGoKld/6JFZVOOfroo8IUGO5fF7 fdYYvf6I3vCdqiQkUdDFt7dRhvSGsEp14Z/uwwfnNhz/Uo93ktlLslny8NU3LuOEJy34JAj9g+O QEFh8jNTkhjhiElTlQWKSCh6zcxC0Wdqg= X-Google-Smtp-Source: AGHT+IE2XueFF/NWd5tWURFURLGzGW+djmc65AMR7kYjFoOZDR5tZf/oLe7GOVs+zg5c5Ifn+DnVYg== X-Received: by 2002:a17:902:f70e:b0:295:7453:b580 with SMTP id d9443c01a7336-2957453b734mr10911815ad.58.1762011798310; Sat, 01 Nov 2025 08:43:18 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.43.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:43:17 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Anup Patel , Mayuresh Chitale Subject: [PATCH v2 02/12] rvtrace: Initial implementation of driver framework Date: Sat, 1 Nov 2025 21:12:35 +0530 Message-ID: <20251101154245.162492-3-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The RISC-V Trace Control Interface Specification [1] defines a standard way of implementing RISC-V trace related modular components irrespective to underlying trace format (E-trace or N-trace). These RISC-V trace components are organized in a graph-like topology where each RISC-V hart has its own RISC-V trace encoder component. Implement a basic driver framework for RISC-V trace where RISC-V trace components are instantiated by a common platform driver and a separate RISC-V trace driver for each type of RISC-V trace component. [1] https://github.com/riscv-non-isa/tg-nexus-trace/releases/download/1.0_R= atified/RISC-V-Trace-Control-Interface.pdf Co-developed-by: Mayuresh Chitale Signed-off-by: Mayuresh Chitale Signed-off-by: Anup Patel --- drivers/Makefile | 1 + drivers/hwtracing/Kconfig | 2 + drivers/hwtracing/rvtrace/Kconfig | 16 + drivers/hwtracing/rvtrace/Makefile | 4 + drivers/hwtracing/rvtrace/rvtrace-core.c | 501 +++++++++++++++++++ drivers/hwtracing/rvtrace/rvtrace-platform.c | 192 +++++++ include/linux/rvtrace.h | 280 +++++++++++ 7 files changed, 996 insertions(+) create mode 100644 drivers/hwtracing/rvtrace/Kconfig create mode 100644 drivers/hwtracing/rvtrace/Makefile create mode 100644 drivers/hwtracing/rvtrace/rvtrace-core.c create mode 100644 drivers/hwtracing/rvtrace/rvtrace-platform.c create mode 100644 include/linux/rvtrace.h diff --git a/drivers/Makefile b/drivers/Makefile index 8e1ffa4358d5..3c0c3bd40a89 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -178,6 +178,7 @@ obj-$(CONFIG_CORESIGHT) +=3D hwtracing/coresight/ obj-y +=3D hwtracing/intel_th/ obj-$(CONFIG_STM) +=3D hwtracing/stm/ obj-$(CONFIG_HISI_PTT) +=3D hwtracing/ptt/ +obj-$(CONFIG_RVTRACE) +=3D hwtracing/rvtrace/ obj-y +=3D android/ obj-$(CONFIG_NVMEM) +=3D nvmem/ obj-$(CONFIG_FPGA) +=3D fpga/ diff --git a/drivers/hwtracing/Kconfig b/drivers/hwtracing/Kconfig index 911ee977103c..daeb38fe332d 100644 --- a/drivers/hwtracing/Kconfig +++ b/drivers/hwtracing/Kconfig @@ -7,4 +7,6 @@ source "drivers/hwtracing/intel_th/Kconfig" =20 source "drivers/hwtracing/ptt/Kconfig" =20 +source "drivers/hwtracing/rvtrace/Kconfig" + endmenu diff --git a/drivers/hwtracing/rvtrace/Kconfig b/drivers/hwtracing/rvtrace/= Kconfig new file mode 100644 index 000000000000..f8f6feea1953 --- /dev/null +++ b/drivers/hwtracing/rvtrace/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only + +menuconfig RVTRACE + tristate "RISC-V Trace Support" + depends on RISCV + depends on OF + default RISCV + help + This framework provides a kernel interface for the RISC-V trace + drivers (including both e-trace and n-trace). It's intended to + build a topological view of the RISC-V trace components and + configure the right series of components when trace is enabled + on a CPU. + + To compile this driver as a module, choose M here: the module + will be called rvtrace. diff --git a/drivers/hwtracing/rvtrace/Makefile b/drivers/hwtracing/rvtrace= /Makefile new file mode 100644 index 000000000000..988525a379cf --- /dev/null +++ b/drivers/hwtracing/rvtrace/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_RVTRACE) +=3D rvtrace.o +rvtrace-y :=3D rvtrace-core.o rvtrace-platform.o diff --git a/drivers/hwtracing/rvtrace/rvtrace-core.c b/drivers/hwtracing/r= vtrace/rvtrace-core.c new file mode 100644 index 000000000000..32fda1647b39 --- /dev/null +++ b/drivers/hwtracing/rvtrace/rvtrace-core.c @@ -0,0 +1,501 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Ventana Micro Systems Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Mutex to serialize component registration/unregistration */ +static DEFINE_MUTEX(rvtrace_mutex); + +/* Per-CPU encoder instances */ +static DEFINE_PER_CPU(struct rvtrace_component *, rvtrace_cpu_encoder); + +/* Component type based id generator */ +struct rvtrace_type_idx { + /* Lock to protect the type ID generator */ + struct mutex lock; + struct idr idr; +}; + +/* Array of component type based id generator */ +static struct rvtrace_type_idx rvtrace_type_idx_array[RVTRACE_COMPONENT_TY= PE_MAX]; + +static int rvtrace_alloc_type_idx(struct rvtrace_component *comp) +{ + struct rvtrace_type_idx *rvidx =3D &rvtrace_type_idx_array[comp->id.type]; + int idx; + + mutex_lock(&rvidx->lock); + idx =3D idr_alloc(&rvidx->idr, comp, 0, 0, GFP_KERNEL); + mutex_unlock(&rvidx->lock); + if (idx < 0) + return idx; + + comp->type_idx =3D idx; + return 0; +} + +static void rvtrace_free_type_idx(struct rvtrace_component *comp) +{ + struct rvtrace_type_idx *rvidx =3D &rvtrace_type_idx_array[comp->id.type]; + + mutex_lock(&rvidx->lock); + idr_remove(&rvidx->idr, comp->type_idx); + mutex_unlock(&rvidx->lock); +} + +static void __init rvtrace_init_type_idx(void) +{ + struct rvtrace_type_idx *rvidx; + int i; + + for (i =3D 0; i < RVTRACE_COMPONENT_TYPE_MAX; i++) { + rvidx =3D &rvtrace_type_idx_array[i]; + mutex_init(&rvidx->lock); + idr_init(&rvidx->idr); + } +} + +const struct rvtrace_component_id *rvtrace_match_id(struct rvtrace_compone= nt *comp, + const struct rvtrace_component_id *ids) +{ + u32 comp_maj, comp_min, id_maj, id_min; + const struct rvtrace_component_id *id; + + for (id =3D ids; id->version && id->type; id++) { + if (comp->id.type !=3D id->type) + return NULL; + + id_maj =3D rvtrace_component_version_major(id->version); + id_min =3D rvtrace_component_version_minor(id->version); + comp_maj =3D rvtrace_component_version_major(comp->id.version); + comp_min =3D rvtrace_component_version_minor(comp->id.version); + if (comp_maj > id_maj) + continue; + + /* Refer to Ch. 5 'Versioning of components of the Trace Control spec. */ + if (comp_maj < id_maj) + dev_warn(&comp->dev, "Older component with major version %d\n", comp_ma= j); + if (comp_min =3D=3D 15) + dev_warn(&comp->dev, "Experimental component\n"); + else if (comp_min > id_min) + dev_warn(&comp->dev, "Newer component with minor version %d\n", comp_mi= n); + + return id; + } + + return NULL; +} +EXPORT_SYMBOL_GPL(rvtrace_match_id); + +static int rvtrace_match_device(struct device *dev, const struct device_dr= iver *drv) +{ + const struct rvtrace_driver *rtdrv =3D to_rvtrace_driver(drv); + struct rvtrace_component *comp =3D to_rvtrace_component(dev); + + return rvtrace_match_id(comp, rtdrv->id_table) ? 1 : 0; +} + +static int rvtrace_probe(struct device *dev) +{ + const struct rvtrace_driver *rtdrv =3D to_rvtrace_driver(dev->driver); + struct rvtrace_component *comp =3D to_rvtrace_component(dev); + int ret =3D -ENODEV; + + if (!rtdrv->probe) + return ret; + + ret =3D rtdrv->probe(comp); + if (!ret) + comp->ready =3D true; + + return ret; +} + +static void rvtrace_remove(struct device *dev) +{ + const struct rvtrace_driver *rtdrv =3D to_rvtrace_driver(dev->driver); + struct rvtrace_component *comp =3D to_rvtrace_component(dev); + + comp->ready =3D false; + if (rtdrv->remove) + rtdrv->remove(comp); +} + +const struct bus_type rvtrace_bustype =3D { + .name =3D "rvtrace", + .match =3D rvtrace_match_device, + .probe =3D rvtrace_probe, + .remove =3D rvtrace_remove, +}; + +struct rvtrace_fwnode_match_data { + struct fwnode_handle *fwnode; + struct rvtrace_component *match; +}; + +static int rvtrace_match_fwnode(struct device *dev, void *data) +{ + struct rvtrace_component *comp =3D to_rvtrace_component(dev); + struct rvtrace_fwnode_match_data *d =3D data; + + if (device_match_fwnode(&comp->dev, d->fwnode)) { + d->match =3D comp; + return 1; + } + + return 0; +} + +struct rvtrace_component *rvtrace_find_by_fwnode(struct fwnode_handle *fwn= ode) +{ + struct rvtrace_fwnode_match_data d =3D { .fwnode =3D fwnode, .match =3D N= ULL }; + int ret; + + ret =3D bus_for_each_dev(&rvtrace_bustype, NULL, &d, rvtrace_match_fwnode= ); + if (ret < 0) + return ERR_PTR(ret); + + return d.match; +} +EXPORT_SYMBOL_GPL(rvtrace_find_by_fwnode); + +int rvtrace_poll_bit(struct rvtrace_platform_data *pdata, int offset, + int bit, int bitval, int timeout) +{ + int i =3D 10; + u32 val; + + while (i--) { + val =3D rvtrace_read32(pdata, offset); + if (((val >> bit) & 0x1) =3D=3D bitval) + break; + udelay(timeout); + } + + return (i < 0) ? -ETIMEDOUT : 0; +} +EXPORT_SYMBOL_GPL(rvtrace_poll_bit); + +int rvtrace_enable_component(struct rvtrace_component *comp) +{ + u32 val; + + val =3D rvtrace_read32(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET); + val |=3D BIT(RVTRACE_COMPONENT_CTRL_ENABLE_SHIFT); + rvtrace_write32(comp->pdata, val, RVTRACE_COMPONENT_CTRL_OFFSET); + return rvtrace_poll_bit(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET, + RVTRACE_COMPONENT_CTRL_ENABLE_SHIFT, 1, + comp->pdata->control_poll_timeout_usecs); +} +EXPORT_SYMBOL_GPL(rvtrace_enable_component); + +int rvtrace_disable_component(struct rvtrace_component *comp) +{ + u32 val; + + val =3D rvtrace_read32(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET); + val &=3D ~BIT(RVTRACE_COMPONENT_CTRL_ENABLE_SHIFT); + rvtrace_write32(comp->pdata, val, RVTRACE_COMPONENT_CTRL_OFFSET); + return rvtrace_poll_bit(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET, + RVTRACE_COMPONENT_CTRL_ENABLE_SHIFT, 0, + comp->pdata->control_poll_timeout_usecs); +} +EXPORT_SYMBOL_GPL(rvtrace_disable_component); + +struct rvtrace_component *rvtrace_cpu_source(unsigned int cpu) +{ + if (!cpu_present(cpu)) + return NULL; + + return per_cpu(rvtrace_cpu_encoder, cpu); +} +EXPORT_SYMBOL_GPL(rvtrace_cpu_source); + +static int rvtrace_cleanup_inconn(struct device *dev, void *data) +{ + struct rvtrace_component *comp =3D to_rvtrace_component(dev); + struct rvtrace_platform_data *pdata =3D comp->pdata; + struct rvtrace_connection *conn =3D data; + int i; + + if (device_match_fwnode(&comp->dev, conn->dest_fwnode)) { + for (i =3D 0; i < pdata->nr_inconns; i++) { + if (pdata->inconns[i] !=3D conn) + continue; + pdata->inconns[i] =3D NULL; + return 1; + } + } + + return 0; +} + +static void rvtrace_cleanup_inconns_from_outconns(struct rvtrace_component= *comp) +{ + struct rvtrace_platform_data *pdata =3D comp->pdata; + struct rvtrace_connection *conn; + int i; + + lockdep_assert_held(&rvtrace_mutex); + + for (i =3D 0; i < pdata->nr_outconns; i++) { + conn =3D pdata->outconns[i]; + bus_for_each_dev(&rvtrace_bustype, NULL, conn, rvtrace_cleanup_inconn); + } +} + +static int rvtrace_setup_inconn(struct device *dev, void *data) +{ + struct rvtrace_component *comp =3D to_rvtrace_component(dev); + struct rvtrace_platform_data *pdata =3D comp->pdata; + struct rvtrace_connection *conn =3D data; + int i; + + if (device_match_fwnode(&comp->dev, conn->dest_fwnode)) { + for (i =3D 0; i < pdata->nr_inconns; i++) { + if (pdata->inconns[i]) + continue; + pdata->inconns[i] =3D conn; + return 1; + } + } + + return 0; +} + +static int rvtrace_setup_inconns_from_outconns(struct rvtrace_component *c= omp) +{ + struct rvtrace_platform_data *pdata =3D comp->pdata; + struct rvtrace_connection *conn; + int i, ret; + + lockdep_assert_held(&rvtrace_mutex); + + for (i =3D 0; i < pdata->nr_outconns; i++) { + conn =3D pdata->outconns[i]; + ret =3D bus_for_each_dev(&rvtrace_bustype, NULL, conn, rvtrace_setup_inc= onn); + if (ret < 0) { + rvtrace_cleanup_inconns_from_outconns(comp); + return ret; + } + } + + return 0; +} + +static void rvtrace_component_release(struct device *dev) +{ + struct rvtrace_component *comp =3D to_rvtrace_component(dev); + + fwnode_handle_put(comp->dev.fwnode); + rvtrace_free_type_idx(comp); + kfree(comp); +} + +static int rvtrace_component_reset(struct rvtrace_platform_data *pdata) +{ + int ret; + + rvtrace_write32(pdata, 0, RVTRACE_COMPONENT_CTRL_OFFSET); + ret =3D rvtrace_poll_bit(pdata, RVTRACE_COMPONENT_CTRL_OFFSET, + RVTRACE_COMPONENT_CTRL_ACTIVE_SHIFT, 0, + pdata->control_poll_timeout_usecs); + if (ret) + return ret; + + rvtrace_write32(pdata, RVTRACE_COMPONENT_CTRL_ACTIVE_MASK, + RVTRACE_COMPONENT_CTRL_OFFSET); + return rvtrace_poll_bit(pdata, RVTRACE_COMPONENT_CTRL_OFFSET, + RVTRACE_COMPONENT_CTRL_ACTIVE_SHIFT, 1, + pdata->control_poll_timeout_usecs); +} + +struct rvtrace_component *rvtrace_register_component(struct rvtrace_platfo= rm_data *pdata) +{ + struct rvtrace_connection *conn; + struct rvtrace_component *comp; + u32 impl, type, major, minor; + int i, ret =3D 0; + + if (!pdata || !pdata->dev) { + ret =3D -EINVAL; + goto err_out; + } + + for (i =3D 0; i < pdata->nr_inconns; i++) { + if (pdata->inconns[i]) { + ret =3D -EINVAL; + goto err_out; + } + } + + for (i =3D 0; i < pdata->nr_outconns; i++) { + conn =3D pdata->outconns[i]; + if (!conn || conn->src_port < 0 || conn->src_comp || + !device_match_fwnode(pdata->dev, conn->src_fwnode) || + conn->dest_port < 0 || !conn->dest_fwnode || !conn->dest_comp) { + ret =3D -EINVAL; + goto err_out; + } + } + + ret =3D rvtrace_component_reset(pdata); + if (ret) + goto err_out; + + impl =3D rvtrace_read32(pdata, RVTRACE_COMPONENT_IMPL_OFFSET); + type =3D (impl >> RVTRACE_COMPONENT_IMPL_TYPE_SHIFT) & + RVTRACE_COMPONENT_IMPL_TYPE_MASK; + major =3D (impl >> RVTRACE_COMPONENT_IMPL_VERMAJOR_SHIFT) & + RVTRACE_COMPONENT_IMPL_VERMAJOR_MASK; + minor =3D (impl >> RVTRACE_COMPONENT_IMPL_VERMINOR_SHIFT) & + RVTRACE_COMPONENT_IMPL_VERMINOR_MASK; + + if (pdata->bound_cpu >=3D 0 && !cpu_present(pdata->bound_cpu)) { + ret =3D -EINVAL; + goto err_out; + } + if (type =3D=3D RVTRACE_COMPONENT_TYPE_ENCODER && pdata->bound_cpu < 0) { + ret =3D -EINVAL; + goto err_out; + } + + comp =3D kzalloc(sizeof(*comp), GFP_KERNEL); + if (!comp) { + ret =3D -ENOMEM; + goto err_out; + } + comp->pdata =3D pdata; + comp->id.type =3D type; + comp->id.version =3D rvtrace_component_mkversion(major, minor); + ret =3D rvtrace_alloc_type_idx(comp); + if (ret) { + kfree(comp); + goto err_out; + } + + comp->dev.parent =3D pdata->dev; + comp->dev.coherent_dma_mask =3D pdata->dev->coherent_dma_mask; + comp->dev.release =3D rvtrace_component_release; + comp->dev.bus =3D &rvtrace_bustype; + comp->dev.fwnode =3D fwnode_handle_get(dev_fwnode(pdata->dev)); + switch (comp->id.type) { + case RVTRACE_COMPONENT_TYPE_ENCODER: + dev_set_name(&comp->dev, "encoder-%d", comp->type_idx); + break; + case RVTRACE_COMPONENT_TYPE_FUNNEL: + dev_set_name(&comp->dev, "funnel-%d", comp->type_idx); + break; + case RVTRACE_COMPONENT_TYPE_RAMSINK: + dev_set_name(&comp->dev, "ramsink-%d", comp->type_idx); + break; + case RVTRACE_COMPONENT_TYPE_PIBSINK: + dev_set_name(&comp->dev, "pibsink-%d", comp->type_idx); + break; + case RVTRACE_COMPONENT_TYPE_ATBBRIDGE: + dev_set_name(&comp->dev, "atbbridge-%d", comp->type_idx); + break; + default: + dev_set_name(&comp->dev, "type%d-%d", comp->id.type, comp->type_idx); + break; + } + + mutex_lock(&rvtrace_mutex); + + ret =3D device_register(&comp->dev); + if (ret) { + put_device(&comp->dev); + goto err_out_unlock; + } + + for (i =3D 0; i < pdata->nr_outconns; i++) { + conn =3D pdata->outconns[i]; + conn->src_comp =3D comp; + } + + ret =3D rvtrace_setup_inconns_from_outconns(comp); + if (ret < 0) { + device_unregister(&comp->dev); + goto err_out_unlock; + } + + if (comp->id.type =3D=3D RVTRACE_COMPONENT_TYPE_ENCODER) { + rvtrace_get_component(comp); + per_cpu(rvtrace_cpu_encoder, comp->pdata->bound_cpu) =3D comp; + } + + mutex_unlock(&rvtrace_mutex); + + return comp; + +err_out_unlock: + mutex_unlock(&rvtrace_mutex); +err_out: + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(rvtrace_register_component); + +void rvtrace_unregister_component(struct rvtrace_component *comp) +{ + struct rvtrace_component *c; + + mutex_lock(&rvtrace_mutex); + + if (comp->id.type =3D=3D RVTRACE_COMPONENT_TYPE_ENCODER) { + c =3D per_cpu(rvtrace_cpu_encoder, comp->pdata->bound_cpu); + per_cpu(rvtrace_cpu_encoder, comp->pdata->bound_cpu) =3D NULL; + rvtrace_put_component(c); + } + + rvtrace_cleanup_inconns_from_outconns(comp); + device_unregister(&comp->dev); + + mutex_unlock(&rvtrace_mutex); +} +EXPORT_SYMBOL_GPL(rvtrace_unregister_component); + +int __rvtrace_register_driver(struct module *owner, struct rvtrace_driver = *rtdrv) +{ + rtdrv->driver.owner =3D owner; + rtdrv->driver.bus =3D &rvtrace_bustype; + + return driver_register(&rtdrv->driver); +} +EXPORT_SYMBOL_GPL(__rvtrace_register_driver); + +static int __init rvtrace_init(void) +{ + int ret; + + rvtrace_init_type_idx(); + + ret =3D bus_register(&rvtrace_bustype); + if (ret) + return ret; + + ret =3D platform_driver_register(&rvtrace_platform_driver); + if (ret) { + bus_unregister(&rvtrace_bustype); + return ret; + } + + return 0; +} + +static void __exit rvtrace_exit(void) +{ + platform_driver_unregister(&rvtrace_platform_driver); + bus_unregister(&rvtrace_bustype); +} + +module_init(rvtrace_init); +module_exit(rvtrace_exit); diff --git a/drivers/hwtracing/rvtrace/rvtrace-platform.c b/drivers/hwtraci= ng/rvtrace/rvtrace-platform.c new file mode 100644 index 000000000000..6eb362880e5c --- /dev/null +++ b/drivers/hwtracing/rvtrace/rvtrace-platform.c @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Ventana Micro Systems Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int rvtrace_of_parse_outconns(struct rvtrace_platform_data *pdata) +{ + struct device_node *parent, *ep_node, *rep_node, *rdev_node; + struct rvtrace_connection *conn; + struct of_endpoint ep, rep; + int ret =3D 0, i =3D 0; + + parent =3D of_get_child_by_name(dev_of_node(pdata->dev), "out-ports"); + if (!parent) + return 0; + + pdata->nr_outconns =3D of_graph_get_endpoint_count(parent); + pdata->outconns =3D devm_kcalloc(pdata->dev, pdata->nr_outconns, + sizeof(*pdata->outconns), GFP_KERNEL); + if (!pdata->outconns) { + ret =3D -ENOMEM; + goto done; + } + + for_each_endpoint_of_node(parent, ep_node) { + conn =3D devm_kzalloc(pdata->dev, sizeof(*conn), GFP_KERNEL); + if (!conn) { + of_node_put(ep_node); + ret =3D -ENOMEM; + break; + } + + ret =3D of_graph_parse_endpoint(ep_node, &ep); + if (ret) { + of_node_put(ep_node); + break; + } + + rep_node =3D of_graph_get_remote_endpoint(ep_node); + if (!rep_node) { + ret =3D -ENODEV; + of_node_put(ep_node); + break; + } + rdev_node =3D of_graph_get_port_parent(rep_node); + + ret =3D of_graph_parse_endpoint(rep_node, &rep); + if (ret) { + of_node_put(ep_node); + break; + } + + conn->src_port =3D ep.port; + conn->src_fwnode =3D dev_fwnode(pdata->dev); + /* The 'src_comp' is set by rvtrace_register_component() */ + conn->src_comp =3D NULL; + conn->dest_port =3D rep.port; + conn->dest_fwnode =3D of_fwnode_handle(rdev_node); + fwnode_handle_get(conn->dest_fwnode); + conn->dest_comp =3D rvtrace_find_by_fwnode(conn->dest_fwnode); + if (!conn->dest_comp) { + ret =3D -EPROBE_DEFER; + of_node_put(ep_node); + break; + } + + pdata->outconns[i] =3D conn; + i++; + } + +done: + if (ret) { + for (i =3D 0; i < pdata->nr_outconns; i++) { + conn =3D pdata->outconns[i]; + if (conn && conn->dest_fwnode) + fwnode_handle_put(conn->dest_fwnode); + } + } + of_node_put(parent); + return ret; +} + +static int rvtrace_of_parse_inconns(struct rvtrace_platform_data *pdata) +{ + struct device_node *parent; + int ret =3D 0; + + parent =3D of_get_child_by_name(dev_of_node(pdata->dev), "in-ports"); + if (!parent) + return 0; + + pdata->nr_inconns =3D of_graph_get_endpoint_count(parent); + pdata->inconns =3D devm_kcalloc(pdata->dev, pdata->nr_inconns, + sizeof(*pdata->inconns), GFP_KERNEL); + if (!pdata->inconns) + ret =3D -ENOMEM; + + of_node_put(parent); + return ret; +} + +static int rvtrace_platform_probe(struct platform_device *pdev) +{ + struct rvtrace_platform_data *pdata; + struct device *dev =3D &pdev->dev; + struct rvtrace_component *comp; + struct device_node *node; + struct resource *res; + int ret; + + pdata =3D devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + pdata->dev =3D dev; + pdata->impid =3D RVTRACE_COMPONENT_IMPID_UNKNOWN; + + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + pdata->io_mem =3D true; + pdata->base =3D devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!pdata->base) + return dev_err_probe(dev, -ENOMEM, "failed to ioremap %pR\n", res); + + pdata->bound_cpu =3D -1; + node =3D of_parse_phandle(dev_of_node(dev), "cpus", 0); + if (node) { + ret =3D of_cpu_node_to_id(node); + of_node_put(node); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get CPU id for %pOF\n", node); + pdata->bound_cpu =3D ret; + } + + /* Default control poll timeout */ + pdata->control_poll_timeout_usecs =3D 10; + + ret =3D rvtrace_of_parse_outconns(pdata); + if (ret) + return dev_err_probe(dev, ret, "failed to parse output connections\n"); + + ret =3D rvtrace_of_parse_inconns(pdata); + if (ret) + return dev_err_probe(dev, ret, "failed to parse input connections\n"); + + comp =3D rvtrace_register_component(pdata); + if (IS_ERR(comp)) + return PTR_ERR(comp); + + platform_set_drvdata(pdev, comp); + return 0; +} + +static void rvtrace_platform_remove(struct platform_device *pdev) +{ + struct rvtrace_component *comp =3D platform_get_drvdata(pdev); + struct rvtrace_platform_data *pdata =3D comp->pdata; + struct rvtrace_connection *conn; + int i; + + for (i =3D 0; i < pdata->nr_outconns; i++) { + conn =3D pdata->outconns[i]; + if (conn && conn->dest_fwnode) + fwnode_handle_put(conn->dest_fwnode); + } + + rvtrace_unregister_component(comp); +} + +static const struct of_device_id rvtrace_platform_match[] =3D { + { .compatible =3D "riscv,trace-component" }, + {} +}; + +struct platform_driver rvtrace_platform_driver =3D { + .driver =3D { + .name =3D "rvtrace", + .of_match_table =3D rvtrace_platform_match, + }, + .probe =3D rvtrace_platform_probe, + .remove =3D rvtrace_platform_remove, +}; diff --git a/include/linux/rvtrace.h b/include/linux/rvtrace.h new file mode 100644 index 000000000000..e8e055ad6583 --- /dev/null +++ b/include/linux/rvtrace.h @@ -0,0 +1,280 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2025 Ventana Micro Systems Inc. + */ + +#ifndef __LINUX_RVTRACE_H__ +#define __LINUX_RVTRACE_H__ + +#include +#include +#include +#include +#include + +/* Control register common across all RISC-V trace components */ +#define RVTRACE_COMPONENT_CTRL_OFFSET 0x000 +#define RVTRACE_COMPONENT_CTRL_ACTIVE_MASK 0x1 +#define RVTRACE_COMPONENT_CTRL_ACTIVE_SHIFT 0 +#define RVTRACE_COMPONENT_CTRL_ENABLE_MASK 0x1 +#define RVTRACE_COMPONENT_CTRL_ENABLE_SHIFT 1 +#define RVTRACE_COMPONENT_CTRL_EMPTY_SHIFT 3 + +/* Implementation register common across all RISC-V trace components */ +#define RVTRACE_COMPONENT_IMPL_OFFSET 0x004 +#define RVTRACE_COMPONENT_IMPL_VERMAJOR_MASK 0xf +#define RVTRACE_COMPONENT_IMPL_VERMAJOR_SHIFT 0 +#define RVTRACE_COMPONENT_IMPL_VERMINOR_MASK 0xf +#define RVTRACE_COMPONENT_IMPL_VERMINOR_SHIFT 4 +#define RVTRACE_COMPONENT_IMPL_TYPE_MASK 0xf +#define RVTRACE_COMPONENT_IMPL_TYPE_SHIFT 8 + +/* Possible component types defined by the RISC-V Trace Control Interface = */ +enum rvtrace_component_type { + RVTRACE_COMPONENT_TYPE_RESV0, + RVTRACE_COMPONENT_TYPE_ENCODER, /* 0x1 */ + RVTRACE_COMPONENT_TYPE_RESV2, + RVTRACE_COMPONENT_TYPE_RESV3, + RVTRACE_COMPONENT_TYPE_RESV4, + RVTRACE_COMPONENT_TYPE_RESV5, + RVTRACE_COMPONENT_TYPE_RESV6, + RVTRACE_COMPONENT_TYPE_RESV7, + RVTRACE_COMPONENT_TYPE_FUNNEL, /* 0x8 */ + RVTRACE_COMPONENT_TYPE_RAMSINK, /* 0x9 */ + RVTRACE_COMPONENT_TYPE_PIBSINK, /* 0xA */ + RVTRACE_COMPONENT_TYPE_RESV11, + RVTRACE_COMPONENT_TYPE_RESV12, + RVTRACE_COMPONENT_TYPE_RESV13, + RVTRACE_COMPONENT_TYPE_ATBBRIDGE, /* 0xE */ + RVTRACE_COMPONENT_TYPE_RESV15, + RVTRACE_COMPONENT_TYPE_MAX +}; + +/* Encoding/decoding macros for RISC-V trace component version */ +#define rvtrace_component_version_major(__version) \ + (((__version) >> 16) & 0xffff) +#define rvtrace_component_version_minor(__version) \ + ((__version) & 0xffff) +#define rvtrace_component_mkversion(__major, __minor) \ + ((((__major) & 0xffff) << 16) | ((__minor) & 0xffff)) + +/* + * Possible component implementation IDs discovered from DT or ACPI + * shared across the RISC-V trace drivers to infer trace parameters, + * quirks, and work-arounds. These component implementation IDs are + * internal to Linux and must not be exposed to user-space. + * + * The component implementation ID should be named as follows: + * RVTRACE_COMPONENT_IMPID__ + */ +enum rvtrace_component_impid { + RVTRACE_COMPONENT_IMPID_UNKNOWN, + RVTRACE_COMPONENT_IMPID_MAX +}; + +/** + * struct rvtrace_connection - Representation of a physical connection bet= ween + * two RISC-V trace components. + * @src_port: A connection's source port number. + * @src_fwnode: Source component's fwnode handle.. + * @src_comp: Source component's pointer. + * @dest_port: A connection's destination port number. + * @dest_fwnode: Destination component's fwnode handle. + * @dest_comp: Destination component's pointer. + */ +struct rvtrace_connection { + int src_port; + struct fwnode_handle *src_fwnode; + int dest_port; + struct fwnode_handle *dest_fwnode; + struct rvtrace_component *src_comp; + struct rvtrace_component *dest_comp; +}; + +/** + * struct rvtrace_platform_data - Platform-level data for a RISC-V trace c= omponent + * discovered from DT or ACPI. + * @dev: Parent device. + * @impid: Component implementation ID + * @io_mem: Flag showing whether component registers are memory mappe= d. + * @base: If io_mem =3D=3D true then base address of the memory map= ped registers. + * @read: If io_mem =3D=3D false then read register from the given = "offset". + * @write: If io_mem =3D=3D false then write register to the given "= offset". + * @bound_cpu: CPU to which the component is bound. This should be -1 if + * the component is not bound to any CPU. For encoder compon= ent + * type this must not be -1. + * @nr_inconns: Number of input connections. + * @inconns: Array of pointers to input connections. + * @nr_outconns: Number of output connections. + * @outconns: Array of pointers to output connections. + */ +struct rvtrace_platform_data { + struct device *dev; + + enum rvtrace_component_impid impid; + + bool io_mem; + union { + void __iomem *base; + struct { + u32 (*read)(struct rvtrace_platform_data *pdata, + u32 offset, bool relaxed); + void (*write)(struct rvtrace_platform_data *pdata, + u32 val, u32 offset, bool relaxed); + }; + }; + + int bound_cpu; + + /* Delay in microseconds when polling control register bits */ + int control_poll_timeout_usecs; + + /* + * Platform driver must only populate empty pointer array without + * any actual input connections. + */ + unsigned int nr_inconns; + struct rvtrace_connection **inconns; + + /* + * Platform driver must fully populate pointer array with individual + * array elements pointing to actual output connections. The src_comp + * of each output connection is automatically updated at the time of + * registering component. + */ + unsigned int nr_outconns; + struct rvtrace_connection **outconns; +}; + +static inline u32 rvtrace_read32(struct rvtrace_platform_data *pdata, u32 = offset) +{ + if (likely(pdata->io_mem)) + return readl(pdata->base + offset); + + return pdata->read(pdata, offset, false); +} + +static inline u32 rvtrace_relaxed_read32(struct rvtrace_platform_data *pda= ta, u32 offset) +{ + if (likely(pdata->io_mem)) + return readl_relaxed(pdata->base + offset); + + return pdata->read(pdata, offset, true); +} + +static inline void rvtrace_write32(struct rvtrace_platform_data *pdata, u3= 2 val, u32 offset) +{ + if (likely(pdata->io_mem)) + writel(val, pdata->base + offset); + else + pdata->write(pdata, val, offset, false); +} + +static inline void rvtrace_relaxed_write32(struct rvtrace_platform_data *p= data, + u32 val, u32 offset) +{ + if (likely(pdata->io_mem)) + writel_relaxed(val, pdata->base + offset); + else + pdata->write(pdata, val, offset, true); +} + +static inline bool rvtrace_is_source(struct rvtrace_platform_data *pdata) +{ + return !pdata->nr_inconns ? true : false; +} + +static inline bool rvtrace_is_sink(struct rvtrace_platform_data *pdata) +{ + return !pdata->nr_outconns ? true : false; +} + +/** + * struct rvtrace_component_id - Details to identify or match a RISC-V tra= ce component + * @type: Type of the component + * @version: Version of the component + * @data: Data pointer for driver use + */ +struct rvtrace_component_id { + enum rvtrace_component_type type; + u32 version; + void *data; +}; + +/** + * struct rvtrace_component - Representation of a RISC-V trace component + * pdata: Pointer to underlying platform data + * id: Details to match the component + * type_idx: Unique number based on component type + * dev: Device instance + * ready: Flag showing whether RISC-V trace driver was probed successfu= lly + */ +struct rvtrace_component { + struct rvtrace_platform_data *pdata; + struct rvtrace_component_id id; + u32 type_idx; + struct device dev; + bool ready; +}; + +#define to_rvtrace_component(__dev) container_of_const(__dev, struct rvtra= ce_component, dev) + +static inline void rvtrace_get_component(struct rvtrace_component *comp) +{ + get_device(&comp->dev); +} + +static inline void rvtrace_put_component(struct rvtrace_component *comp) +{ + put_device(&comp->dev); +} + +const struct rvtrace_component_id *rvtrace_match_id(struct rvtrace_compone= nt *comp, + const struct rvtrace_component_id *ids); +struct rvtrace_component *rvtrace_find_by_fwnode(struct fwnode_handle *fwn= ode); + +int rvtrace_poll_bit(struct rvtrace_platform_data *pdata, int offset, + int bit, int bitval, int timeout); +int rvtrace_enable_component(struct rvtrace_component *comp); +int rvtrace_disable_component(struct rvtrace_component *comp); + +struct rvtrace_component *rvtrace_cpu_source(unsigned int cpu); + +struct rvtrace_component *rvtrace_register_component(struct rvtrace_platfo= rm_data *pdata); +void rvtrace_unregister_component(struct rvtrace_component *comp); + +/** + * struct rvtrace_driver - Representation of a RISC-V trace driver + * id_table: Table to match components handled by the driver + * probe: Driver probe() function + * remove: Driver remove() function + * driver: Device driver instance + */ +struct rvtrace_driver { + const struct rvtrace_component_id *id_table; + int (*probe)(struct rvtrace_component *comp); + void (*remove)(struct rvtrace_component *comp); + struct device_driver driver; +}; + +#define to_rvtrace_driver(__drv) \ + ((__drv) ? container_of_const((__drv), struct rvtrace_driver, driver) : N= ULL) + +extern struct platform_driver rvtrace_platform_driver; + +int __rvtrace_register_driver(struct module *owner, struct rvtrace_driver = *rtdrv); +#define rvtrace_register_driver(driver) __rvtrace_register_driver(THIS_MOD= ULE, driver) +static inline void rvtrace_unregister_driver(struct rvtrace_driver *rtdrv) +{ + if (rtdrv) + driver_unregister(&rtdrv->driver); +} + +static inline int rvtrace_comp_is_empty(struct rvtrace_component *comp) +{ + return rvtrace_poll_bit(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET, + RVTRACE_COMPONENT_CTRL_EMPTY_SHIFT, 1, + comp->pdata->control_poll_timeout_usecs); +} + +#endif --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pg1-f169.google.com (mail-pg1-f169.google.com [209.85.215.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CCAE02F9D83 for ; Sat, 1 Nov 2025 15:43:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011809; cv=none; b=p49XTYMb8PI7lZ6jOtGit9x60QKsEG3hkUBig6cEOGl6a4jbQHOha+aV0RUOoiHsap9RiA6ATxKzx135/RhVWO1mw3ZwGBTUxtQCRWPBr5ReZVhYR45qucYUYOQe75mTxhLEu4Bpi5DZHI+xfJit/EoG0J6KxvmAdvZXHdQGFh0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011809; c=relaxed/simple; bh=BvBD0Z9+XjSQERc0S1HJVRiFVdEPJieSXUF2h1D9pgU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SIDK3Uw+0fD3caw7RUHWf04iswEOW7UF9nuOcXrrTTCwDwlP3dyaqaXpcz7g4oKr+DEawufq9WwFLWGFjQQpnPXbq6FRyKf/BtNq75xb+FLSUNNFLAQTkflz53EWSaapvRmsxdHfZiKvY9CYd+kyX7LUMAhBpZJRwB4rCKmylRE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=ioDoXFBw; arc=none smtp.client-ip=209.85.215.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="ioDoXFBw" Received: by mail-pg1-f169.google.com with SMTP id 41be03b00d2f7-b98e6ff9071so113293a12.0 for ; Sat, 01 Nov 2025 08:43:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011807; x=1762616607; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kOvY7+y3+k/BpOCCJeQtfZUneWdciA55AKvg4KUFkXw=; b=ioDoXFBwA8ZOnkRIz/m1RZ1T6qHrTZBye8CD323znd8X8DdztmjfxKtECI8/4QMYZW pjpdhassZDBVWEdMG5mXzXajrh9ZayncN1oY2+RrBrQjMidyXUoM+j8DI9SD4zqYCo25 YK9ysOzdsEgUhTPBVPJAqDVszhNCwMxhH88zHRzIAOZRiqyP228BD5vd2ehgsEXHn4Tj TSpcTmO5KDK04JfROR2cee3cdHmid4PgsfTAS90acZFTMWpTE/0Qi5N5xL44Ka05J/59 5S5tPZKC6uKx0t78wY9oV6+h2yfD5LQmkfRnZ4xWnVb+jULllf5cQc0oWFmrSS6h7tkk 1fog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011807; x=1762616607; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kOvY7+y3+k/BpOCCJeQtfZUneWdciA55AKvg4KUFkXw=; b=ntoh6H/Bv0eRU5EwsQ/TRB+HAXZyXRKr8g0CESL3YAtgqndmTKxF/s3rcUAFdKQqrc zldlcLDUGbGMma6MVxp9kmjzjA3N2B4eUukZMMLDXE9Uke4xo2y6v2ZuPXugRvV0hUQO Fk01Pl7oKAY8L1V3HpoTCkV9AZKbpmkI9ldgqq/Ow6CtSo1giorXD37ZINnLiOHcsBPx nvZs05kpbCZz8yx6NYhI+OCrRqVowEhVxPkpu74/uy3UrLrrHGZyNU3qjURDWvm2nfH/ Uzi1w7i6cSJjw2InQ/sAn+yLjMazwB220Iyr3Bbrfs2hzbqK2tw5Rm5F00VZcLKN853E zmXQ== X-Forwarded-Encrypted: i=1; AJvYcCXBvOFnYqeLqoSbuTkiTPpXxaGkZ6OVWyRcWuaiR6DS0mdj5ghvIGgOX/DUO1nkk6V4/aKkbUBQSnRxelM=@vger.kernel.org X-Gm-Message-State: AOJu0YwbmW8bWmK4NrD5sLyum71R5sguImP4o0IdgOaaUbibw+qvr1dE xWXMcVuXs7OwPU4xjVpusAinJREgATCXhHt0+3XT3Z2ZxnAYZf/oAlIbNoKIK6hkPkY= X-Gm-Gg: ASbGncsk4ROmUeAvg51nVXgIPAvwVlmMFhtYy0YfANPxWgw2N7QpJ8fFn/hR/dClrsa 8tk8EtzZiTR2DlD4DXzhTiXjtW79byjFXHqm4RwlMU1QhdfG6q+4X59983bv7CIqSsucUXdxTrw eBRCzlFZj/LETCJ838dzcaoEw3Ko9oD/BvO5YIDMZX6CNwb7/CURQFtFQOKZZTNg/aOHN2jUaN7 cozQFrAgafIRNZEfNpwYSd0bsSu5Ssd4pSB2x5SgXaPfjcxzU9W2f83U73frlANgzLBHCI/KZCe pxvWihBY9Wpg7ock5FjPX1jZVoGTNuRbhw9r9DC25M6P+MMSTOP7IMX82oMgdzhsskeQWzDVMJ9 naGmmstfZ60QQArSRWJ/tXuffLV3yFX3udODJSwkqnNMUsMATZdm+gEr5j4XPYt7KCmc/bsgGav jM9eg4hjn9phFfyd0ThulhUdf2s9bjqTvDN+xcQXlIx+ss6H4fS5KQ X-Google-Smtp-Source: AGHT+IEfN3sDw4+c9kAcEeOlETsmvroTxjtc7mSSvF7SLOSV5F4wykTjDG1l/xLBcJfYOVZ8mhA2wg== X-Received: by 2002:a17:903:41ce:b0:295:82d0:9baa with SMTP id d9443c01a7336-29582d0a17cmr2501135ad.17.1762011806967; Sat, 01 Nov 2025 08:43:26 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.43.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:43:26 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Anup Patel , Mayuresh Chitale Subject: [PATCH v2 03/12] rvtrace: Add functions to create/destroy a trace component path Date: Sat, 1 Nov 2025 21:12:36 +0530 Message-ID: <20251101154245.162492-4-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Trace needs to be configured on a chain of trace components which are connected to each other. These chain of components is also referred to as trace component path. Add functions to create/destroy a trace component path which will be later used by RISC-V trace perf support. Co-developed-by: Mayuresh Chitale Signed-off-by: Mayuresh Chitale Signed-off-by: Anup Patel --- drivers/hwtracing/rvtrace/rvtrace-core.c | 223 +++++++++++++++++++++++ include/linux/rvtrace.h | 43 ++++- 2 files changed, 264 insertions(+), 2 deletions(-) diff --git a/drivers/hwtracing/rvtrace/rvtrace-core.c b/drivers/hwtracing/r= vtrace/rvtrace-core.c index 32fda1647b39..7006a4469d62 100644 --- a/drivers/hwtracing/rvtrace/rvtrace-core.c +++ b/drivers/hwtracing/rvtrace/rvtrace-core.c @@ -211,6 +211,53 @@ int rvtrace_disable_component(struct rvtrace_component= *comp) } EXPORT_SYMBOL_GPL(rvtrace_disable_component); =20 +static int __rvtrace_walk_output_components(struct rvtrace_component *comp, + bool *stop, void *priv, + int (*fn)(struct rvtrace_component *comp, bool *stop, + struct rvtrace_connection *stop_conn, + void *priv)) +{ + struct rvtrace_connection *conn, *stop_conn =3D NULL; + struct rvtrace_platform_data *pdata =3D comp->pdata; + int i, ret; + + for (i =3D 0; i < pdata->nr_outconns; i++) { + conn =3D pdata->outconns[i]; + ret =3D __rvtrace_walk_output_components(conn->dest_comp, stop, priv, fn= ); + if (ret) + return ret; + if (*stop) { + stop_conn =3D conn; + break; + } + } + + ret =3D fn(comp, stop, stop_conn, priv); + if (ret) + return ret; + + return 0; +} + +int rvtrace_walk_output_components(struct rvtrace_component *comp, void *p= riv, + int (*fn)(struct rvtrace_component *comp, bool *stop, + struct rvtrace_connection *stop_conn, + void *priv)) +{ + bool stop =3D false; + int ret; + + if (!comp || !fn) + return -EINVAL; + + mutex_lock(&rvtrace_mutex); + ret =3D __rvtrace_walk_output_components(comp, &stop, priv, fn); + mutex_unlock(&rvtrace_mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(rvtrace_walk_output_components); + struct rvtrace_component *rvtrace_cpu_source(unsigned int cpu) { if (!cpu_present(cpu)) @@ -463,6 +510,182 @@ void rvtrace_unregister_component(struct rvtrace_comp= onent *comp) } EXPORT_SYMBOL_GPL(rvtrace_unregister_component); =20 +struct rvtrace_path_node { + struct list_head head; + struct rvtrace_component *comp; + struct rvtrace_connection *conn; +}; + +struct rvtrace_component *rvtrace_path_source(struct rvtrace_path *path) +{ + struct rvtrace_path_node *node; + + node =3D list_first_entry(&path->comp_list, struct rvtrace_path_node, hea= d); + return node->comp; +} +EXPORT_SYMBOL_GPL(rvtrace_path_source); + +struct rvtrace_component *rvtrace_path_sink(struct rvtrace_path *path) +{ + struct rvtrace_path_node *node; + + node =3D list_last_entry(&path->comp_list, struct rvtrace_path_node, head= ); + return node->comp; +} +EXPORT_SYMBOL_GPL(rvtrace_path_sink); + +static int rvtrace_assign_trace_id(struct rvtrace_path *path) +{ + const struct rvtrace_driver *rtdrv; + struct rvtrace_component *comp; + struct rvtrace_path_node *node; + int trace_id; + + list_for_each_entry(node, &path->comp_list, head) { + comp =3D node->comp; + rtdrv =3D to_rvtrace_driver(comp->dev.driver); + + if (!rtdrv->get_trace_id) + continue; + + trace_id =3D rtdrv->get_trace_id(comp, path->mode); + if (trace_id > 0) { + path->trace_id =3D trace_id; + return 0; + } else if (trace_id < 0) { + return trace_id; + } + } + + return 0; +} + +static void rvtrace_unassign_trace_id(struct rvtrace_path *path) +{ + const struct rvtrace_driver *rtdrv; + struct rvtrace_component *comp; + struct rvtrace_path_node *node; + + list_for_each_entry(node, &path->comp_list, head) { + comp =3D node->comp; + rtdrv =3D to_rvtrace_driver(comp->dev.driver); + + if (!rtdrv->put_trace_id) + continue; + + rtdrv->put_trace_id(comp, path->mode, path->trace_id); + } +} + +static bool rvtrace_path_ready(struct rvtrace_path *path) +{ + struct rvtrace_path_node *node; + + list_for_each_entry(node, &path->comp_list, head) { + if (!node->comp->ready) + return false; + } + + return true; +} + +struct build_path_walk_priv { + struct rvtrace_path *path; + struct rvtrace_component *sink; +}; + +static int build_path_walk_fn(struct rvtrace_component *comp, bool *stop, + struct rvtrace_connection *stop_conn, + void *priv) +{ + struct build_path_walk_priv *ppriv =3D priv; + struct rvtrace_path *path =3D ppriv->path; + struct rvtrace_path_node *node; + + if ((!ppriv->sink && rvtrace_is_sink(comp->pdata)) || + (ppriv->sink && ppriv->sink =3D=3D comp)) + *stop =3D true; + + if (*stop) { + node =3D kzalloc(sizeof(*node), GFP_KERNEL); + if (!path) + return -ENOMEM; + INIT_LIST_HEAD(&node->head); + rvtrace_get_component(comp); + node->comp =3D comp; + node->conn =3D stop_conn; + list_add(&node->head, &path->comp_list); + } + + return 0; +} + +static void rvtrace_release_path_nodes(struct rvtrace_path *path) +{ + struct rvtrace_path_node *node, *node1; + + list_for_each_entry_safe(node, node1, &path->comp_list, head) { + list_del(&node->head); + rvtrace_put_component(node->comp); + kfree(node); + } +} + +struct rvtrace_path *rvtrace_create_path(struct rvtrace_component *source, + struct rvtrace_component *sink, + enum rvtrace_component_mode mode) +{ + struct build_path_walk_priv priv; + struct rvtrace_path *path; + int ret =3D 0; + + if (!source || mode >=3D RVTRACE_COMPONENT_MODE_MAX) { + ret =3D -EINVAL; + goto err_out; + } + + path =3D kzalloc(sizeof(*path), GFP_KERNEL); + if (!path) { + ret =3D -ENOMEM; + goto err_out; + } + INIT_LIST_HEAD(&path->comp_list); + path->mode =3D mode; + path->trace_id =3D RVTRACE_INVALID_TRACE_ID; + + priv.path =3D path; + priv.sink =3D sink; + ret =3D rvtrace_walk_output_components(source, &priv, build_path_walk_fn); + if (ret < 0) + goto err_release_path_nodes; + + if (!rvtrace_path_ready(path)) { + ret =3D -EOPNOTSUPP; + goto err_release_path_nodes; + } + + ret =3D rvtrace_assign_trace_id(path); + if (ret < 0) + goto err_release_path_nodes; + + return path; + +err_release_path_nodes: + rvtrace_release_path_nodes(path); + kfree(path); +err_out: + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(rvtrace_create_path); + +void rvtrace_destroy_path(struct rvtrace_path *path) +{ + rvtrace_unassign_trace_id(path); + rvtrace_release_path_nodes(path); + kfree(path); +} +EXPORT_SYMBOL_GPL(rvtrace_destroy_path); + int __rvtrace_register_driver(struct module *owner, struct rvtrace_driver = *rtdrv) { rtdrv->driver.owner =3D owner; diff --git a/include/linux/rvtrace.h b/include/linux/rvtrace.h index e8e055ad6583..4b31ab96e721 100644 --- a/include/linux/rvtrace.h +++ b/include/linux/rvtrace.h @@ -8,6 +8,8 @@ =20 #include #include +#include +#include #include #include #include @@ -72,6 +74,12 @@ enum rvtrace_component_impid { RVTRACE_COMPONENT_IMPID_MAX }; =20 +/* Supported usage modes for RISC-V trace components */ +enum rvtrace_component_mode { + RVTRACE_COMPONENT_MODE_PERF, + RVTRACE_COMPONENT_MODE_MAX +}; + /** * struct rvtrace_connection - Representation of a physical connection bet= ween * two RISC-V trace components. @@ -238,22 +246,53 @@ int rvtrace_poll_bit(struct rvtrace_platform_data *pd= ata, int offset, int rvtrace_enable_component(struct rvtrace_component *comp); int rvtrace_disable_component(struct rvtrace_component *comp); =20 +int rvtrace_walk_output_components(struct rvtrace_component *comp, void *p= riv, + int (*fn)(struct rvtrace_component *comp, bool *stop, + struct rvtrace_connection *stop_conn, + void *priv)); struct rvtrace_component *rvtrace_cpu_source(unsigned int cpu); =20 struct rvtrace_component *rvtrace_register_component(struct rvtrace_platfo= rm_data *pdata); void rvtrace_unregister_component(struct rvtrace_component *comp); =20 +/** + * struct rvtrace_path - Representation of a RISC-V trace path from source= to sink + * @comp_list: List of RISC-V trace components in the path + * @mode: Usage mode for RISC-V trace components + * @trace_id: ID of the trace source (typically hart id) + */ +struct rvtrace_path { + struct list_head comp_list; + enum rvtrace_component_mode mode; + u32 trace_id; +#define RVTRACE_INVALID_TRACE_ID 0 +}; + +struct rvtrace_component *rvtrace_path_source(struct rvtrace_path *path); +struct rvtrace_component *rvtrace_path_sink(struct rvtrace_path *path); +struct rvtrace_path *rvtrace_create_path(struct rvtrace_component *source, + struct rvtrace_component *sink, + enum rvtrace_component_mode mode); +void rvtrace_destroy_path(struct rvtrace_path *path); + /** * struct rvtrace_driver - Representation of a RISC-V trace driver * id_table: Table to match components handled by the driver - * probe: Driver probe() function - * remove: Driver remove() function + * probe: Driver probe() function + * remove: Driver remove() function + * get_trace_id: Get/allocate a trace ID + * put_trace_id: Put/free a trace ID * driver: Device driver instance */ struct rvtrace_driver { const struct rvtrace_component_id *id_table; int (*probe)(struct rvtrace_component *comp); void (*remove)(struct rvtrace_component *comp); + int (*get_trace_id)(struct rvtrace_component *comp, + enum rvtrace_component_mode mode); + void (*put_trace_id)(struct rvtrace_component *comp, + enum rvtrace_component_mode mode, + u32 trace_id); struct device_driver driver; }; =20 --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 52A512F83CC for ; Sat, 1 Nov 2025 15:43:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011817; cv=none; b=a0T3yEUJJAJZuMgngSTl3C6yiLiHXad+oSQ0ARxefU94dYwCe5ux8fSfXyA1UpPtzDeavc3HizOCpH//rBrCdsc5MX2gVCkHB8CYr6gj8P0FTtTnidOlfIvgdLmEOKACjXN0dMERucYDJ04+nGUYIoT5RvE0SZoY4+BGeKDcrj4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011817; c=relaxed/simple; bh=/B8Y/5QX6tFLftY6wKUyS0+gWGKDmzQfDNzD5G0vJ0s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BibQ8XC1UOiyX3nCIyZZ15dR7ytk6wnULR9/W/fvcZ8f/nOoSg6LhXLbwQPonVetSR1VRcNdUEx05yi/EUugSJjqZ4qjDJ6Vx1B565scKlEaI3oJlyiXfiyMzAs93nRXWPAFW96Xh+wKkLle6rJ3N7/+GunkOfEoG+SwLjyrAPg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=lA8Raf54; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="lA8Raf54" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-26a0a694ea8so24279495ad.3 for ; Sat, 01 Nov 2025 08:43:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011816; x=1762616616; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nfEP9PIU9MbWencudNocKuygkeJ/OR2b1cy84VkwN7s=; b=lA8Raf541lNlrj10Km9ucFx3K0m933YJP23P/cPyGjVsDZO6nuhKp+CqGTpiYZumYt zwlOWdGxopQ+DMMT3Tdvsj6jJ3pKEKkZtq8SfVn5WsXCQvWye7/xW+3YYXEly/Qb98jA fKOWJgXgxh+gzQrdmNkM5DWyUE8uwFHfjxVMbhHpVyFZ78NXG3nsVBiiERC1sL8+6Fp7 om+CR41O2CUV+VmoH5kgQwKZ/z3XfaLdPYpW23EZCHuEyM+6IAzv8dMgQgB+lbHNooFx 9gLr3Bxu/tOj2CVmo0vosyea3yVw7+txMMCQiA/L7Kyyz7wAFTsErEOAIe8ch0uhL6zr erJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011816; x=1762616616; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nfEP9PIU9MbWencudNocKuygkeJ/OR2b1cy84VkwN7s=; b=PnmN3SnGBOxcg33MxKDhUXAzHNzPTQZVNK6b/aROJylwu6vFW87AyoRTCVtkQDTrEM p6PhByvLtb3RkcBFNQgJuQgShQJjohCQzYqOHlHGn3F4omv1PmxGmTKig8gm3fZo0x/m 1gjhHBCCDLVe/4Q9AM/rSpTE0g7G1dgv8l2HqSWdjX7dQl4/ijwNH7sFC8It7RKeXSGD xr/tIwktrarLufOZDlwjP0bSXRTkr8XVubTF0wIO+QtJrZsDfJLK+jyuBp9OQRlUP1ta wg2S1wASks2vOsn55JE7xNVQaHD5Ac3X882Mzv3HK6IhGXdAsnX11EaUZZsBGjdWVFlU /d3w== X-Forwarded-Encrypted: i=1; AJvYcCVQVBzzNWV9Rzp7aqoNlGQRHk66cJCHh3GaDtEKUqzXnOgvnSeHMl8t/8QzooCMh0x/gr5zYz5A2D/sZJI=@vger.kernel.org X-Gm-Message-State: AOJu0YwVgU8G+APDn/trE3GqG4IHiRqCCllx7kYtE0IXBMmP7/cU3bXI x59DIqT9eFYFa9gxz86FKMpqcAirhvyEmUWvqaP9fH0FB+jB09CSfEy/tgc+SM4wcBs= X-Gm-Gg: ASbGncveBQ2kyOvbsPBQ/BcvQAGK8r12/PCmBWe+5CphuLkDLN+qeqIJY/1D+astdO/ 0w54LyA5Ver+ehPJTjCxRJGYzMqBqAKQ9kSt7dFRHKPLmBO5D9S3PwKD7aTwOKaYKY0VWPq/Cwy qdaAQATM5esWpXTHFdKrW5lWVn3UAJTF42++7yG7T4nVgdBodIKmEMeLG5O+9JoetojIftbe4+l Sx7hZwejoHLINUXw+Of3Czmp7Dz/xTs9mwhYxMeeFgouHRlUt2N91oE28GY2PYPYt9yk6LKWM0L 3PpGylgy/4dV+pq7GhkUkNzBG7h4lLthseOd7wG6dXXJlfJ8kNtgKInZCTa4x+Z+CJL9HDpLdoW yKOrtJxT9lyeiG11z24aLzeuwpCyzTeaLsD0hnVt/XrtID6rJHHzpsj8EVeKv+VsdXwttLCSQx2 DUOuLNriUnkoSFaQJ4i7TsBQ/KyGUfiNtjB+48IcjJWw== X-Google-Smtp-Source: AGHT+IE3shkEkgNOrmF/SQpIoxDdNl0ITxKDPFu9uZQNBFl+V+HOFkfpCYl/Xzoqo1IWNRiPw24eiA== X-Received: by 2002:a17:903:2285:b0:264:70e9:dcb1 with SMTP id d9443c01a7336-2951a4bf845mr83133985ad.56.1762011815528; Sat, 01 Nov 2025 08:43:35 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.43.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:43:34 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Mayuresh Chitale , Anup Patel Subject: [PATCH v2 04/12] rvtrace: Add functions to start/stop tracing on a component path Date: Sat, 1 Nov 2025 21:12:37 +0530 Message-ID: <20251101154245.162492-5-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mayuresh Chitale The perf driver framework needs to be able to start / stop all components in a trace component path during its operation. Add rvtrace_path_start() and rvtrace_path_stop() functions for this purpose. Co-developed-by: Anup Patel Signed-off-by: Anup Patel Signed-off-by: Mayuresh Chitale --- drivers/hwtracing/rvtrace/rvtrace-core.c | 44 ++++++++++++++++++++++++ include/linux/rvtrace.h | 6 ++++ 2 files changed, 50 insertions(+) diff --git a/drivers/hwtracing/rvtrace/rvtrace-core.c b/drivers/hwtracing/r= vtrace/rvtrace-core.c index 7006a4469d62..35bd77d6880a 100644 --- a/drivers/hwtracing/rvtrace/rvtrace-core.c +++ b/drivers/hwtracing/rvtrace/rvtrace-core.c @@ -631,6 +631,50 @@ static void rvtrace_release_path_nodes(struct rvtrace_= path *path) } } =20 +int rvtrace_path_start(struct rvtrace_path *path) +{ + const struct rvtrace_driver *rtdrv; + struct rvtrace_component *comp; + struct rvtrace_path_node *node; + int ret; + + list_for_each_entry(node, &path->comp_list, head) { + comp =3D node->comp; + rtdrv =3D to_rvtrace_driver(comp->dev.driver); + if (!rtdrv->start) + continue; + + ret =3D rtdrv->start(comp); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(rvtrace_path_start); + +int rvtrace_path_stop(struct rvtrace_path *path) +{ + const struct rvtrace_driver *rtdrv; + struct rvtrace_component *comp; + struct rvtrace_path_node *node; + int ret; + + list_for_each_entry(node, &path->comp_list, head) { + comp =3D node->comp; + rtdrv =3D to_rvtrace_driver(comp->dev.driver); + if (!rtdrv->stop) + continue; + + ret =3D rtdrv->stop(comp); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(rvtrace_path_stop); + struct rvtrace_path *rvtrace_create_path(struct rvtrace_component *source, struct rvtrace_component *sink, enum rvtrace_component_mode mode) diff --git a/include/linux/rvtrace.h b/include/linux/rvtrace.h index 4b31ab96e721..e2842e8728d4 100644 --- a/include/linux/rvtrace.h +++ b/include/linux/rvtrace.h @@ -274,10 +274,14 @@ struct rvtrace_path *rvtrace_create_path(struct rvtra= ce_component *source, struct rvtrace_component *sink, enum rvtrace_component_mode mode); void rvtrace_destroy_path(struct rvtrace_path *path); +int rvtrace_path_start(struct rvtrace_path *path); +int rvtrace_path_stop(struct rvtrace_path *path); =20 /** * struct rvtrace_driver - Representation of a RISC-V trace driver * id_table: Table to match components handled by the driver + * start: Callback to start tracing + * stop: Callback to stop tracing * probe: Driver probe() function * remove: Driver remove() function * get_trace_id: Get/allocate a trace ID @@ -286,6 +290,8 @@ void rvtrace_destroy_path(struct rvtrace_path *path); */ struct rvtrace_driver { const struct rvtrace_component_id *id_table; + int (*start)(struct rvtrace_component *comp); + int (*stop)(struct rvtrace_component *comp); int (*probe)(struct rvtrace_component *comp); void (*remove)(struct rvtrace_component *comp); int (*get_trace_id)(struct rvtrace_component *comp, --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pl1-f181.google.com (mail-pl1-f181.google.com [209.85.214.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 14862A59 for ; Sat, 1 Nov 2025 15:43:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011825; cv=none; b=FebWSJv15fN2Rld3h//18YXegVPRFg3YMufdyS98RKiQtulkQOUVIrSVg8Zk1VG1hpUQZeLEOTlgoWi1IpvOfMlrwLmmhKHt7yPm709Woe1DUfAfsfFV/nY9UmzcCgh1wllDiss7QT/eogFixA7F5DIDj44Almg1Q/SrKaikf1M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011825; c=relaxed/simple; bh=MebY2Kn6y2LU2xMPrHuRiqWl4Ev7U4wWsZxdN5aqQsE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jMre8IC/6oLyqL4NsRT2jD+UI8BEvdAveXcDENXUsM0BE3nCDrob1+8Qj3j+n81tcuWo/nwbpQFZ91kl6tG2GCz6Zo5Yaak0M7IYhUglSMZ/qsPCiTgoaFTErR1HZlItzrHxQmMcqIbEIGGd17k79XkqXlyPMJCyMJ1LSqEJBv8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=WeZpp3N0; arc=none smtp.client-ip=209.85.214.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="WeZpp3N0" Received: by mail-pl1-f181.google.com with SMTP id d9443c01a7336-29555b384acso6098815ad.1 for ; Sat, 01 Nov 2025 08:43:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011823; x=1762616623; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=VKOoQPMUVsEmi6hMo7Uy8Fdi9yV1PxzBRenc/eHTo9c=; b=WeZpp3N0Hr110Jpi0AkhuiWRuKAhsXfOsEY2eAHyo3fit9fo4TDKmQ9T3L58XzXuyZ NQwWHPy0tRB9lbQR0ZHGeLmB9843eKBKpYgenlQSvMf7Y+O5YVWPpfKgKrQK2I8LCoGX lRKqHXQRVt+UxVvWeFOvhKmn27l+Yxe6OQIlx1XZB3g9P8M1j+baqdBXCS6JaUtq+3M8 xB4EYI/NtamEnG4KcB2SJbzCDD+HAieUMSn97g6xo+zbKJq5tXrbpLH+jToeDId4r84z uDuOM0zarZ3VbYCzbYgwzbr6LmzsaSJsDk0gz+s8gZJgGpnnJzswhtGhasoR5hDO36S/ xyqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011823; x=1762616623; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VKOoQPMUVsEmi6hMo7Uy8Fdi9yV1PxzBRenc/eHTo9c=; b=YdgEYrCjiPW+JSAVfHLzLg4w6weKxadXHPFgZsWeADIo1CGtJVgB6pYyh39Gd0X58v qW6thimEZTjgGHjK+gJBY3R7/xbemwOsvPkU5AukIHLwy4qnDY77agm3RgnhboBASqnA Kr23W2Ya3P/uqBNPwWVTKXkU4/1Ry43q/tzi5w5lTQY+7YQJSpfiPo9Is9s6Y+zDcvkx al0BTLgqLZZW83yc05KNdmUY7lo+xHMd7COprsZdVTXY+WdFcKW0rRSSqnZKUwSPOFBC MPyM65Jj8O7dvJyy2NctABSusnApUKvwGUNtes83rT9SJp9NVQV2jjbvjmpVc64htg7C YI/Q== X-Forwarded-Encrypted: i=1; AJvYcCWfjy4fESsRg8ZKKk1EnG+J+MbQk1zWoqlPy+9BqXtoretcMKeFRAYBfmsq9lHwLDd2BBnjCmuWW8HsN/g=@vger.kernel.org X-Gm-Message-State: AOJu0YwTf64XCLFLVgWzjSGYDgfnUU8xrF+CEUlR2Vt8Y4ZPzyhBPniC /Hn2c2LTd2E5fmMvBo8dq8OcLZ2LGCSPGUnDgvuX+qYPSO1RX19UuQLiM+cOL3m3HYs= X-Gm-Gg: ASbGncvlAVrnRn2ql10oQhGETia7tJeFgBPeJ7TF3bRVOFmUy3Ky6dlMcanCs7q6KyC Bk/3dRwHJTf2Ab6zKHS0TUzrNgvjaj/r4dY7aIQWW+htB3l3a6OcsE0ii1qoTAugO8KBp9NdN1U rePnl9nfCukIocruKs1Ozy4tVxjt0t9OSiC3VRHEs3tQfvMzTay7uJ6NJQOb6W5LznHPgVJd/aj lsw3WRFGEOWDP9zizlyayMtsDQyWCU9CttVq81E3vAMV5VRV8OPN9DMsE/220OGeBCtDhP9AGFB sZOkfv/r8CDUfrM1ha8w374taPesEKzmxHKIYx/xv4ylQ3jbTdoidsuuIpWCvUAFl5ZbiJw5Mna PVaNJgM7D+cUEIUmTiHVdfrb2veCdqxXjbuc+JYuh8C/FQhstItWXUhWmTes5GgTgp86GoAN/Im m1Nc/RfgMxY/0moqm1JJ25bB/jRPJXqO7MSHmUAPA37JCdFr6sKjU9 X-Google-Smtp-Source: AGHT+IFJbHT4F5pXbCNLO8qvOGYbikUZ+tUCbxIpYKWdYciUFwFGUUJMQoZvXRQKkQTGN7eTPXehmg== X-Received: by 2002:a17:903:2441:b0:295:20c5:5453 with SMTP id d9443c01a7336-29520c5565dmr98352145ad.29.1762011823274; Sat, 01 Nov 2025 08:43:43 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.43.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:43:42 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Mayuresh Chitale , Anup Patel Subject: [PATCH v2 05/12] rvtrace: Add trace encoder driver Date: Sat, 1 Nov 2025 21:12:38 +0530 Message-ID: <20251101154245.162492-6-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mayuresh Chitale Add initial implementation of RISC-V trace encoder driver. The encoder is defined in the RISC-V Trace Control Interface specification. Co-developed-by: Anup Patel Signed-off-by: Anup Patel Signed-off-by: Mayuresh Chitale --- drivers/hwtracing/rvtrace/Kconfig | 7 ++ drivers/hwtracing/rvtrace/Makefile | 1 + drivers/hwtracing/rvtrace/rvtrace-encoder.c | 107 ++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 drivers/hwtracing/rvtrace/rvtrace-encoder.c diff --git a/drivers/hwtracing/rvtrace/Kconfig b/drivers/hwtracing/rvtrace/= Kconfig index f8f6feea1953..ba35c05f3f54 100644 --- a/drivers/hwtracing/rvtrace/Kconfig +++ b/drivers/hwtracing/rvtrace/Kconfig @@ -14,3 +14,10 @@ menuconfig RVTRACE =20 To compile this driver as a module, choose M here: the module will be called rvtrace. + +config RVTRACE_ENCODER + tristate "RISC-V Trace Encoder driver" + depends on RVTRACE + default y + help + This driver provides support for RISC-V Trace Encoder component. diff --git a/drivers/hwtracing/rvtrace/Makefile b/drivers/hwtracing/rvtrace= /Makefile index 988525a379cf..f320693a1fc5 100644 --- a/drivers/hwtracing/rvtrace/Makefile +++ b/drivers/hwtracing/rvtrace/Makefile @@ -2,3 +2,4 @@ =20 obj-$(CONFIG_RVTRACE) +=3D rvtrace.o rvtrace-y :=3D rvtrace-core.o rvtrace-platform.o +obj-$(CONFIG_RVTRACE_ENCODER) +=3D rvtrace-encoder.o diff --git a/drivers/hwtracing/rvtrace/rvtrace-encoder.c b/drivers/hwtracin= g/rvtrace/rvtrace-encoder.c new file mode 100644 index 000000000000..69ceb5821709 --- /dev/null +++ b/drivers/hwtracing/rvtrace/rvtrace-encoder.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Ventana Micro Systems Inc. + */ + +#include +#include +#include + +#define RVTRACE_COMPONENT_CTRL_ITRACE_SHIFT 2 +#define RVTRACE_COMPONENT_CTRL_INSTMODE_SHIFT 4 + +static int rvtrace_encoder_start(struct rvtrace_component *comp) +{ + u32 val; + + val =3D rvtrace_read32(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET); + val |=3D BIT(RVTRACE_COMPONENT_CTRL_ITRACE_SHIFT); + rvtrace_write32(comp->pdata, val, RVTRACE_COMPONENT_CTRL_OFFSET); + return rvtrace_poll_bit(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET, + RVTRACE_COMPONENT_CTRL_ITRACE_SHIFT, 1, + comp->pdata->control_poll_timeout_usecs); +} + +static int rvtrace_encoder_stop(struct rvtrace_component *comp) +{ + int ret; + u32 val; + + val =3D rvtrace_read32(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET); + val &=3D ~BIT(RVTRACE_COMPONENT_CTRL_ITRACE_SHIFT); + rvtrace_write32(comp->pdata, val, RVTRACE_COMPONENT_CTRL_OFFSET); + ret =3D rvtrace_poll_bit(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET, + RVTRACE_COMPONENT_CTRL_ITRACE_SHIFT, 0, + comp->pdata->control_poll_timeout_usecs); + if (ret) { + dev_err(&comp->dev, "failed to stop tracing.\n"); + return ret; + } + + return rvtrace_comp_is_empty(comp); +} + +static void rvtrace_encoder_setmode(struct rvtrace_component *comp, u32 mo= de) +{ + u32 val; + + val =3D rvtrace_read32(comp->pdata, RVTRACE_COMPONENT_CTRL_OFFSET); + val |=3D (mode << RVTRACE_COMPONENT_CTRL_INSTMODE_SHIFT); + rvtrace_write32(comp->pdata, val, RVTRACE_COMPONENT_CTRL_OFFSET); +} + +static int rvtrace_encoder_probe(struct rvtrace_component *comp) +{ + int ret; + + rvtrace_encoder_setmode(comp, 0x6); + ret =3D rvtrace_enable_component(comp); + if (ret) + return dev_err_probe(&comp->dev, ret, "failed to enable encoder.\n"); + + return 0; +} + +static void rvtrace_encoder_remove(struct rvtrace_component *comp) +{ + int ret; + + ret =3D rvtrace_disable_component(comp); + if (ret) + dev_err(&comp->dev, "failed to disable encoder.\n"); +} + +static struct rvtrace_component_id rvtrace_encoder_ids[] =3D { + { .type =3D RVTRACE_COMPONENT_TYPE_ENCODER, + .version =3D rvtrace_component_mkversion(1, 0), }, + {}, +}; + +static struct rvtrace_driver rvtrace_encoder_driver =3D { + .id_table =3D rvtrace_encoder_ids, + .start =3D rvtrace_encoder_start, + .stop =3D rvtrace_encoder_stop, + .probe =3D rvtrace_encoder_probe, + .remove =3D rvtrace_encoder_remove, + .driver =3D { + .name =3D "rvtrace-encoder", + }, +}; + +static int __init rvtrace_encoder_init(void) +{ + return rvtrace_register_driver(&rvtrace_encoder_driver); +} + +static void __exit rvtrace_encoder_exit(void) +{ + rvtrace_unregister_driver(&rvtrace_encoder_driver); +} + +module_init(rvtrace_encoder_init); +module_exit(rvtrace_encoder_exit); + +/* Module information */ +MODULE_AUTHOR("Mayuresh Chitale "); +MODULE_DESCRIPTION("RISC-V Trace Encoder Driver"); +MODULE_LICENSE("GPL"); --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E4972FABFF for ; Sat, 1 Nov 2025 15:43:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011833; cv=none; b=pDfw/J/accrN9TlJbdY+SLEeZf88Z9ptXrilW8vpadYBTQiZ/8V/uZuAw4DmRRSFU3951mndPjq6ebfPs8TrQ6otp6Fbs9HIYgzG9bhEAPcLgE4UaIZePvruSjGf+G7aVfO9Qg4teK48cWPiiaiV5jzYSa529k9nIIiX5BUulzI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011833; c=relaxed/simple; bh=1/PSRddxMss1ZLh6BKodL70umd3EchlKrwrkzcSbhDI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XYXEK5HQprHSUkEv9N4ILWnYX1VhQfr/41pYbBpZ8BCgxgBCtyChR/33XXtDIEBvi9haFAuOkb2pLTaYdFMyZF/9X04imbAtUULA/WfWfamn/w73PWrjFAUo//HPGY8Q6mZuEGwcMK9OyN9RGO/r1/Bn4yrO6C0mYp0cFrXvrHw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=ltAGTjVa; arc=none smtp.client-ip=209.85.215.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="ltAGTjVa" Received: by mail-pg1-f179.google.com with SMTP id 41be03b00d2f7-b6ce696c18bso2808672a12.1 for ; Sat, 01 Nov 2025 08:43:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011832; x=1762616632; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/cNRcLxuGh85qOUhHhakMZrIP7xVwXKqva0C/jWYbVA=; b=ltAGTjVaEoEzdubkUW6z1KjhT+VCJk2eVIiIKTvA0I0dNXfkFFUROtNIMBXAyiX1pQ GojLX/x3ZtanzUdvgzN67TzWzfOqtWajWp7qfWYfuS30I8TKzvNAOSSNgVPNLD4NRuZP 7I6okhqzjmfNYLIqzofVeVTrLZp2Ts2atef4EFJIADidwecG7oO1bHwfAFIjwwyUBq6J jk/PC+AaJ0QtUifY7zSUgywmAqiYYW3yVV+GtTUcXa70crSiRFilq+prym4rLQbw9s6U YzM3xUJIkqheeaP24Hz6yv5JGWve0VnZr8hyRP7YUxW0azlBppsr3MElydrubXwKkAIB y9rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011832; x=1762616632; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/cNRcLxuGh85qOUhHhakMZrIP7xVwXKqva0C/jWYbVA=; b=AEsCJ4fJ2rDZCwwlQNLGHfJwhDq0JtgFwvhlkUVZJjkWjoT8plaz2XsTJUdqBKJy7w 5JnXcI/Vq9kLbB6TrBq2cp/59a3iYysv3Xqipm/nJYrX855PN0IDdBfSXVpQZgj67TYd EEM0InqWL35l3ybJY/CiihWHhfHpCfHKNUYkJe5vZOBsIogpTyrXNeq+moOvYWxVxm/7 L602ztz3GJV7t6SRgsjBNErdd7QzKtt8O6WLU7fKsyy6K2FlY0+q0rEK/6FhvpG88kOV nOJLNXMAIfV8CYoWS/wOomjQNL0TGCvNzcOwYw0AAb/OmqTxiWuUBUBy3E0Ly8UzZ0zN 28oA== X-Forwarded-Encrypted: i=1; AJvYcCWB77GgLMjF2BhHaH6A25yZbV5S7ssKVcCsNQI5MwlYX99CxxbOl1IvveY/j6DQDLCSqP++rtKNV9VXvPk=@vger.kernel.org X-Gm-Message-State: AOJu0YznlY3pYnKRI81ojdWmfqtQKEZoWnX3SQppBEEpoyTDqhSUWDwy KbyNBLmPapBHJsYaz6UEVKg/JPSc10UrtJ0Z0xvgGZV7Q0juvc1wjpKKfGKX5Dvechs= X-Gm-Gg: ASbGnct1kUHsoNfYbPZiKYN+jYTHKzinfADBHkQ0MDeTEus1IFFVnKGgG+5T84bDhYH IaI8jH39BQDZVR4/DGCYG41EaBROewYGRw0vhlYy/8Q2YYyywPqk9o0z5fMmaAmafWCnwYmA+a+ bzYNq5AbPwaulO42ZWc2xdCyrBie5Ts033Qnoy4lr5YrsM8WPo4aoqLfYna9skToi2GJx9BTxY2 85oOnS08TkEfO/2cx579ldLrvndqIRk/M/SaCJWvbvXCqLEZcKGQqWfnqcAGi3eo2h630fs3T4S TLM9Al0bL7QGbMoJIE3rQOTD1gBUZUGGF2lOeobGw0GENs+PY0PRQrtijGc4I0Fj7rD9Jrp8gt7 kBPPS7KRdyMv2kW85uU7oNGllrScPsFYVjSdp56dg3AxR7DSSeebjR9db2PrbkUpEO5vyXUyfFA 8ymNNMUV0ZeGnDz7SOD2OUnKrkXCV+2l4= X-Google-Smtp-Source: AGHT+IE9dgmddcRbzfRQuPturLe2P+J6B0ktYW7UkJ98oGijMhfJoMmqTs3LZbQLk6Eea6Hsg8gvAw== X-Received: by 2002:a17:902:d505:b0:290:c0ed:de42 with SMTP id d9443c01a7336-2951a4dfc4fmr100179015ad.36.1762011831758; Sat, 01 Nov 2025 08:43:51 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.43.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:43:51 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Anup Patel , Mayuresh Chitale Subject: [PATCH v2 06/12] rvtrace: Add function to copy into perf AUX buffer Date: Sat, 1 Nov 2025 21:12:39 +0530 Message-ID: <20251101154245.162492-7-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The RISC-V trace ramsink will need a mechanism to copy trace data into the perf AUX buffer. Add rvtrace_path_copyto_auxbuf() function and corresponding trace driver callback copyto_auxbuf() for this purpose. Co-developed-by: Mayuresh Chitale Signed-off-by: Mayuresh Chitale Signed-off-by: Anup Patel --- drivers/hwtracing/rvtrace/rvtrace-core.c | 22 ++++++++++++++++++++++ include/linux/rvtrace.h | 21 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/drivers/hwtracing/rvtrace/rvtrace-core.c b/drivers/hwtracing/r= vtrace/rvtrace-core.c index 35bd77d6880a..b955e5f3b048 100644 --- a/drivers/hwtracing/rvtrace/rvtrace-core.c +++ b/drivers/hwtracing/rvtrace/rvtrace-core.c @@ -675,6 +675,28 @@ int rvtrace_path_stop(struct rvtrace_path *path) } EXPORT_SYMBOL_GPL(rvtrace_path_stop); =20 +int rvtrace_path_copyto_auxbuf(struct rvtrace_path *path, + struct rvtrace_perf_auxbuf *buf, + size_t *bytes_copied) +{ + const struct rvtrace_driver *rtdrv; + struct rvtrace_component *comp; + struct rvtrace_path_node *node; + + list_for_each_entry(node, &path->comp_list, head) { + comp =3D node->comp; + rtdrv =3D to_rvtrace_driver(comp->dev.driver); + if (!rtdrv->copyto_auxbuf) + continue; + + *bytes_copied =3D rtdrv->copyto_auxbuf(comp, buf); + return 0; + } + + return -EOPNOTSUPP; +} +EXPORT_SYMBOL_GPL(rvtrace_path_copyto_auxbuf); + struct rvtrace_path *rvtrace_create_path(struct rvtrace_component *source, struct rvtrace_component *sink, enum rvtrace_component_mode mode) diff --git a/include/linux/rvtrace.h b/include/linux/rvtrace.h index e2842e8728d4..cecf6c153ca6 100644 --- a/include/linux/rvtrace.h +++ b/include/linux/rvtrace.h @@ -277,9 +277,28 @@ void rvtrace_destroy_path(struct rvtrace_path *path); int rvtrace_path_start(struct rvtrace_path *path); int rvtrace_path_stop(struct rvtrace_path *path); =20 +/** + * struct rvtrace_perf_auxbuf - Representation of the perf AUX buffer + * @length: size of the AUX buffer + * @nr_pages: number of pages of the AUX buffer + * @base: start address of AUX buffer + * @pos: position in the AUX buffer to commit traced data + */ +struct rvtrace_perf_auxbuf { + size_t length; + int nr_pages; + void *base; + long pos; +}; + +int rvtrace_path_copyto_auxbuf(struct rvtrace_path *path, + struct rvtrace_perf_auxbuf *buf, + size_t *bytes_copied); + /** * struct rvtrace_driver - Representation of a RISC-V trace driver * id_table: Table to match components handled by the driver + * copyto_auxbuf:Callback to copy data into perf AUX buffer * start: Callback to start tracing * stop: Callback to stop tracing * probe: Driver probe() function @@ -290,6 +309,8 @@ int rvtrace_path_stop(struct rvtrace_path *path); */ struct rvtrace_driver { const struct rvtrace_component_id *id_table; + size_t (*copyto_auxbuf)(struct rvtrace_component *comp, + struct rvtrace_perf_auxbuf *buf); int (*start)(struct rvtrace_component *comp); int (*stop)(struct rvtrace_component *comp); int (*probe)(struct rvtrace_component *comp); --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pg1-f176.google.com (mail-pg1-f176.google.com [209.85.215.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C58652F2915 for ; Sat, 1 Nov 2025 15:44:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011842; cv=none; b=TDT5kHEkKjKe2qisv6GLehX3lk0GLiJ86nWP8xe6MoI/Z8DoXs+UoliRU1xeEovEjaXy/9HKl6PQV0Z5MKmLb8M4hLj24i3u70RjX2qDMT7e0t16GosdcorpX9hLVECG6zHdFPHwKbofWPCGIzym9U6pMQu0pDGSu8Bm02tkmgI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011842; c=relaxed/simple; bh=zo5YKif/sbpHnYA1aiIFPZB6QxT8hmW+j1PaV42UeZg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h/7hekcdbKY6vatvqEoGQB9jze0sVUA2M/7rufXF94tuoaWeM9Ss5h2HlZx7qGC9kgLgABHrsh9/2iY52LQE59fhzP0f/rynrGwElm0xEjM8zDCuIAV2tA2mjpsTtrI74GvdxDyH801yZIuKgvSuRCp7+yPlT1f4MZkwFGT7AYY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=IqvtGgrd; arc=none smtp.client-ip=209.85.215.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="IqvtGgrd" Received: by mail-pg1-f176.google.com with SMTP id 41be03b00d2f7-b67ae7e76abso2366228a12.3 for ; Sat, 01 Nov 2025 08:44:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011840; x=1762616640; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ae2lirZMEyfHKsluDGqvTk55hOG0uMkmu2dMvKUo7Mg=; b=IqvtGgrdZZnAyKksWUU4nsyUqgKCZ9HtpJyjyOVjddp3JaK5FspjtglxF6ZErGXkib P3dTb4BFyDOlJCmqIjH1z4TTLkeuIEi2R3u/ATWEn+uTRFIXuCsHisBtZlJ2HNcM61ms m8EropCew07VG2qBjbE/bgeZJkPfwJmf7f9thF4Y+v81gq9ofPzZQm9gX7Bm6xlrGaOZ H5KL/Asc104aCwQD/1RvscrK5Hbe9+t+JfeHVw7xbXmNUbQleUy370bqt6eG8PM8mJM/ B56KpmPWJ3wcrM5cMJA0m+MfnWMoIhHvkrNf7nDKpsEvTP7Oyjxpk39kFPnJwz636RcT mUag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011840; x=1762616640; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ae2lirZMEyfHKsluDGqvTk55hOG0uMkmu2dMvKUo7Mg=; b=kKPGO/zl8iIjcm1kg96xwSU5Ugvbv2HetvLEIfEjtlKMaD9iYUgdgaYov1G9inwQjj OXZhKHV3oft6OUKSJaxDpv3vcfKFd5H2CZ3EIlwzlHGOXtAH98PCSnb+G4vy6RjEMQiH Cg8V/aXTTm9gfRKREbES7+D9OFCAclGDXCqFX9FgEwfQKeA0HSbe46pGFkLQX8DtI/Gk H3a/uMwPMkWcvU2hYVKmoFCy5aJqycJIeb8nk1FwF4kNt1U0XrjL870D6OK8oC4szR/c A4EngvrxkSuK+Tq8Uk8dJU6oJ9EzZOtc6JQ1+43Rbh9oeyGDiJolX/kN1WzW0oH80/D3 zM8Q== X-Forwarded-Encrypted: i=1; AJvYcCXmxCNeXah7POnimy3Rn9AOGT9k6x8yvG4YIJSApgPFcklh1fy4mDfhUl0s8ZQhgxsfDIkkPBFOC77i1fM=@vger.kernel.org X-Gm-Message-State: AOJu0YzQqvj1S1UlKodvSVV6g0d3gkNV0GV5/RkA/svA6zLR0rpQLHWN l4si3IylL4ikotoFlxeDM05nU5Nh6I1HVcAjWlIqMhdN1GSegnTqnyTjM8UPv/SP+bs= X-Gm-Gg: ASbGnctUBlZXZHRhgllgKlSFggx0c738WqM6wpgjNcQBHtqbmLd0Pwx05F22F/Veihu oTaiDOXvizU0f945C7Fe8InexBP0zZywEUQVCV/RwYk2ba3Ee78rG40Ck0/Hrzbw2ZimFMYKzVR 2Zq62PwF+yvfjsmQz2HBfJSJXt8xC/qOwODoj4Asyu2h4p42XiJBa74BfPYhdeDF5NcgI0MlPgM o0QGn2OJ360E+kaDvI/T0gszUjQoH6ddEpCWDXi4T8i/Xlfmk0jkn8EuWHuxt0Smn5wr2WQlcko O4/74Q2tCYgNheF2hncddRRTp4Kay33QjcupEG4/cA8dBkI1xc6XR1tlXyNKwSy/k9YDAgZlUwM TG1EUuXxnyNNLhYjIRMFvTWulF3ZFBDSUP89v7YDTpSNpyPg4c3xFFqRp4vazp4JmvI3utYlfmF /e1lTTbfEqC6BTwcjdp8McDV1Vm5zhlYU= X-Google-Smtp-Source: AGHT+IHnu/LkNJmWubjJ09gAWYh0sS09HDl6f2CIH0+AtetQ53djcWevN3kIT2bI6ucVlf4vDM7MeQ== X-Received: by 2002:a17:902:ea04:b0:295:511d:537 with SMTP id d9443c01a7336-295511d12femr48219465ad.44.1762011840123; Sat, 01 Nov 2025 08:44:00 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.43.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:43:59 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Mayuresh Chitale , Anup Patel Subject: [PATCH v2 07/12] rvtrace: Add trace ramsink driver Date: Sat, 1 Nov 2025 21:12:40 +0530 Message-ID: <20251101154245.162492-8-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mayuresh Chitale Add initial implementation of RISC-V trace ramsink driver. The ramsink is defined in the RISC-V Trace Control Interface specification. Co-developed-by: Anup Patel Signed-off-by: Anup Patel Signed-off-by: Mayuresh Chitale --- drivers/hwtracing/rvtrace/Kconfig | 9 + drivers/hwtracing/rvtrace/Makefile | 1 + drivers/hwtracing/rvtrace/rvtrace-ramsink.c | 262 ++++++++++++++++++++ 3 files changed, 272 insertions(+) create mode 100644 drivers/hwtracing/rvtrace/rvtrace-ramsink.c diff --git a/drivers/hwtracing/rvtrace/Kconfig b/drivers/hwtracing/rvtrace/= Kconfig index ba35c05f3f54..0577f9acb858 100644 --- a/drivers/hwtracing/rvtrace/Kconfig +++ b/drivers/hwtracing/rvtrace/Kconfig @@ -21,3 +21,12 @@ config RVTRACE_ENCODER default y help This driver provides support for RISC-V Trace Encoder component. + +config RVTRACE_RAMSINK + tristate "RISC-V Trace Ramsink driver" + depends on RVTRACE + select DMA_SHARED_BUFFER + default y + help + This driver provides support for Risc-V E-Trace Ramsink + component. diff --git a/drivers/hwtracing/rvtrace/Makefile b/drivers/hwtracing/rvtrace= /Makefile index f320693a1fc5..122e575da9fb 100644 --- a/drivers/hwtracing/rvtrace/Makefile +++ b/drivers/hwtracing/rvtrace/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_RVTRACE) +=3D rvtrace.o rvtrace-y :=3D rvtrace-core.o rvtrace-platform.o obj-$(CONFIG_RVTRACE_ENCODER) +=3D rvtrace-encoder.o +obj-$(CONFIG_RVTRACE_RAMSINK) +=3D rvtrace-ramsink.o diff --git a/drivers/hwtracing/rvtrace/rvtrace-ramsink.c b/drivers/hwtracin= g/rvtrace/rvtrace-ramsink.c new file mode 100644 index 000000000000..676344c9387c --- /dev/null +++ b/drivers/hwtracing/rvtrace/rvtrace-ramsink.c @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Ventana Micro Systems Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define RVTRACE_RAMSINK_STARTLOW_OFF 0x010 +#define RVTRACE_RAMSINK_STARTHIGH_OFF 0x014 +#define RVTRACE_RAMSINK_LIMITLOW_OFF 0x018 +#define RVTRACE_RAMSINK_LIMITHIGH_OFF 0x01c +#define RVTRACE_RAMSINK_WPLOW_OFF 0x020 +#define RVTRACE_RAMSINK_WPLOW_WRAP 0x1 +#define RVTRACE_RAMSINK_WPHIGH_OFF 0x024 +#define RVTRACE_RAMSINK_RPLOW_OFF 0x028 +#define RVTRACE_RAMSINK_RPHIGH_OFF 0x02c + +struct rvtrace_ramsink_priv { + size_t size; + void *va; + dma_addr_t start; + dma_addr_t end; + /* WP from prev iteration */ + dma_addr_t prev_head; +}; + +struct trace_buf { + void *base; + size_t size; + long cur; + size_t len; +}; + +static int rvtrace_ramsink_stop(struct rvtrace_component *comp) +{ + return rvtrace_comp_is_empty(comp); +} + +static void tbuf_to_pbuf_copy(struct trace_buf *src, struct trace_buf *dst) +{ + int bytes_dst, bytes_src, bytes; + void *dst_addr, *src_addr; + + while (src->size) { + src_addr =3D src->base + src->cur; + dst_addr =3D dst->base + dst->cur; + + if (dst->len - dst->cur < src->size) + bytes_dst =3D dst->len - dst->cur; + else + bytes_dst =3D src->size; + if (src->len - src->cur < src->size) + bytes_src =3D src->len - src->cur; + else + bytes_src =3D src->size; + bytes =3D bytes_dst < bytes_src ? bytes_dst : bytes_src; + memcpy(dst_addr, src_addr, bytes); + dst->cur =3D (dst->cur + bytes) % dst->len; + src->cur =3D (src->cur + bytes) % src->len; + src->size -=3D bytes; + } +} + +static size_t rvtrace_ramsink_copyto_auxbuf(struct rvtrace_component *comp, + struct rvtrace_perf_auxbuf *buf) +{ + struct rvtrace_ramsink_priv *priv =3D dev_get_drvdata(&comp->dev); + struct trace_buf src, dst; + u32 wp_low, wp_high; + u64 buf_cur_head; + size_t size; + + wp_low =3D rvtrace_read32(comp->pdata, RVTRACE_RAMSINK_WPLOW_OFF); + wp_high =3D rvtrace_read32(comp->pdata, RVTRACE_RAMSINK_WPHIGH_OFF); + buf_cur_head =3D (u64)(wp_high) << 32 | (wp_low & ~RVTRACE_RAMSINK_WPLOW_= WRAP); + + if (buf_cur_head =3D=3D priv->prev_head) + return 0; + + dst.base =3D buf->base; + dst.len =3D buf->length; + dst.cur =3D buf->pos; + + src.base =3D priv->va; + src.len =3D priv->end - priv->start; + if (buf_cur_head > priv->prev_head) { + src.size =3D buf_cur_head - priv->prev_head; + } else { + src.size =3D priv->end - priv->prev_head; + src.size +=3D buf_cur_head - priv->start; + } + + src.cur =3D buf_cur_head - priv->start; + size =3D src.size; + tbuf_to_pbuf_copy(&src, &dst); + buf->pos =3D dst.cur; + priv->prev_head =3D buf_cur_head; + + return size; +} + +static int rvtrace_ramsink_setup_buf(struct rvtrace_component *comp) +{ + struct rvtrace_ramsink_priv *priv =3D dev_get_drvdata(&comp->dev); + u64 start_min, limit_max, end; + u32 low, high; + + /* Probe min and max values for start and limit registers */ + rvtrace_write32(comp->pdata, 0, RVTRACE_RAMSINK_STARTLOW_OFF); + rvtrace_write32(comp->pdata, 0, RVTRACE_RAMSINK_STARTHIGH_OFF); + low =3D rvtrace_read32(comp->pdata, RVTRACE_RAMSINK_STARTLOW_OFF); + high =3D rvtrace_read32(comp->pdata, RVTRACE_RAMSINK_STARTHIGH_OFF); + start_min =3D (u64)(high) << 32 | low; + + rvtrace_write32(comp->pdata, 0xffffffff, RVTRACE_RAMSINK_LIMITLOW_OFF); + rvtrace_write32(comp->pdata, 0xffffffff, RVTRACE_RAMSINK_LIMITHIGH_OFF); + low =3D rvtrace_read32(comp->pdata, RVTRACE_RAMSINK_LIMITLOW_OFF); + high =3D rvtrace_read32(comp->pdata, RVTRACE_RAMSINK_LIMITHIGH_OFF); + limit_max =3D (u64)(high) << 32 | low; + + if (priv->end < start_min) { + dev_err(&comp->dev, "DMA memory not addressable by device\n"); + return -EINVAL; + } + + /* Setup ram sink start addresses */ + if (priv->start < start_min) { + dev_warn(&comp->dev, "Ramsink start address updated from %llx to %llx\n", + priv->start, start_min); + priv->va +=3D start_min - priv->start; + priv->start =3D start_min; + } + + priv->prev_head =3D priv->start; + priv->end =3D priv->start + priv->size; + rvtrace_write32(comp->pdata, lower_32_bits(priv->start), RVTRACE_RAMSINK_= STARTLOW_OFF); + rvtrace_write32(comp->pdata, upper_32_bits(priv->start), RVTRACE_RAMSINK_= STARTHIGH_OFF); + rvtrace_write32(comp->pdata, lower_32_bits(priv->start), RVTRACE_RAMSINK_= WPLOW_OFF); + rvtrace_write32(comp->pdata, upper_32_bits(priv->start), RVTRACE_RAMSINK_= WPHIGH_OFF); + /* Setup ram sink limit addresses */ + if (priv->end > limit_max) { + dev_warn(&comp->dev, "Ramsink limit address updated from %llx to %llx\n"= , priv->end, + limit_max); + priv->end =3D limit_max; + priv->size =3D priv->end - priv->start; + } + + /* Limit address needs to be set to end - 4 to avoid overflow */ + end =3D priv->end - 4; + rvtrace_write32(comp->pdata, lower_32_bits(end), RVTRACE_RAMSINK_LIMITLOW= _OFF); + rvtrace_write32(comp->pdata, upper_32_bits(end), RVTRACE_RAMSINK_LIMITHIG= H_OFF); + low =3D rvtrace_read32(comp->pdata, RVTRACE_RAMSINK_LIMITLOW_OFF); + high =3D rvtrace_read32(comp->pdata, RVTRACE_RAMSINK_LIMITHIGH_OFF); + end =3D (u64)(high) << 32 | low; + if (end !=3D (priv->end - 4)) { + dev_warn(&comp->dev, "Ramsink limit address updated from %llx to %llx\n"= , priv->end, + end); + priv->end =3D end; + priv->size =3D priv->end - priv->start; + } + + return 0; +} + +static int rvtrace_ramsink_setup(struct rvtrace_component *comp) +{ + struct device *pdev =3D comp->pdata->dev; + struct rvtrace_ramsink_priv *priv; + + priv =3D devm_kzalloc(&comp->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev_set_drvdata(&comp->dev, priv); + + /* Derive RAM sink memory size based on component implementation ID */ + switch (comp->pdata->impid) { + default: + priv->size =3D SZ_1M; + break; + } + + priv->va =3D dma_alloc_coherent(pdev, priv->size, &priv->start, GFP_KERNE= L); + if (!priv->va) + return -ENOMEM; + + return rvtrace_ramsink_setup_buf(comp); +} + +static void rvtrace_ramsink_cleanup(struct rvtrace_component *comp) +{ + struct rvtrace_ramsink_priv *priv =3D dev_get_drvdata(&comp->dev); + + dma_free_coherent(&comp->dev, priv->size, priv->va, priv->start); +} + +static int rvtrace_ramsink_probe(struct rvtrace_component *comp) +{ + int ret; + + ret =3D rvtrace_ramsink_setup(comp); + if (ret) + return dev_err_probe(&comp->dev, ret, "failed to setup ramsink.\n"); + + ret =3D rvtrace_enable_component(comp); + if (ret) + return dev_err_probe(&comp->dev, ret, "failed to enable ramsink.\n"); + + return ret; +} + +static void rvtrace_ramsink_remove(struct rvtrace_component *comp) +{ + int ret; + + ret =3D rvtrace_disable_component(comp); + if (ret) + dev_err(&comp->dev, "failed to disable ramsink.\n"); + + rvtrace_ramsink_cleanup(comp); +} + +static struct rvtrace_component_id rvtrace_ramsink_ids[] =3D { + { .type =3D RVTRACE_COMPONENT_TYPE_RAMSINK, + .version =3D rvtrace_component_mkversion(1, 0), }, + {}, +}; + +static struct rvtrace_driver rvtrace_ramsink_driver =3D { + .id_table =3D rvtrace_ramsink_ids, + .copyto_auxbuf =3D rvtrace_ramsink_copyto_auxbuf, + .stop =3D rvtrace_ramsink_stop, + .probe =3D rvtrace_ramsink_probe, + .remove =3D rvtrace_ramsink_remove, + .driver =3D { + .name =3D "rvtrace-ramsink", + }, +}; + +static int __init rvtrace_ramsink_init(void) +{ + return rvtrace_register_driver(&rvtrace_ramsink_driver); +} + +static void __exit rvtrace_ramsink_exit(void) +{ + rvtrace_unregister_driver(&rvtrace_ramsink_driver); +} + +module_init(rvtrace_ramsink_init); +module_exit(rvtrace_ramsink_exit); + +/* Module information */ +MODULE_AUTHOR("Mayuresh Chitale "); +MODULE_DESCRIPTION("RISC-V Trace Ramsink Driver"); +MODULE_LICENSE("GPL"); --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 68E562FB601 for ; Sat, 1 Nov 2025 15:44:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011850; cv=none; b=kqR4CPpiBKC7NbQOgilYnCREQemQCiOvBbNdltDJ1JdDIOzl5f5I9s1SQP1JstYBOhnAatqjZfKSAxcbEVmnFWG7YsIhWtO42A9XA/kJOhZJy7Dl5oP/VDW6XJvr9/8R9U+Ag4+zmKUVwE/xJM1nN1f2r3pWz4++5n1eMKucjLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011850; c=relaxed/simple; bh=25h2zSA984OKtQmRh9EqfuGp/YR9+0RmE5X6wuvM7LU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Hu1RyjKANq15CPAviUP4ZmuE6KOiLHVqlzKZkG51cyJLnESMxZmKon4fIlHHAY/j3FCl3THbtOS5y6NsQ0Ogn/ld3+ayaDBj18PI8M4CV+oXFEhFRPWYr1rhi6gdxqscybCKsFL0z7WYWQ5QFGrOE1QOmqhvXZslGtZrIYMA4zg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=MO+QIsd8; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="MO+QIsd8" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-2957850c63bso1466865ad.0 for ; Sat, 01 Nov 2025 08:44:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011849; x=1762616649; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=x2XwcEWhGPqe4YWn8OiU0EgUYXN4uylgwxXcr7hecLU=; b=MO+QIsd8rzwC+6fGbbHdHtttAcm/z4thyOIljW0sP8tnYxLqk+JehlOZUrJGMhnHvd NYQ1yggIB+3gPNH0EtsfQ9f0mbUMGWZmHkmib0YMipc4TUJJGMdU2yJTX2zXCan46sci DyA6Kks1qZ27SUOCUGWkZBIM2emfnATdBkMnZl6JRI+NjQsxssUUe/F7CBNJcUb8uwvU yLRNIzbb5vBaUEJAf7fdxZU0WATnw/vckiPN3urFBewXkxgGe/OC4WXGDdzMcZmg3M7Z fpNO3xxOPXdlJpopwWrvlnzxIeNQmGF8wSEdql5k3+79t84y9PNS2wKkk8FBrwMrGaFf MAWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011849; x=1762616649; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=x2XwcEWhGPqe4YWn8OiU0EgUYXN4uylgwxXcr7hecLU=; b=vbdbWR1GYqsymZKEje5nmZ+W4zYIQlUJsD7Zqx9nnczIj9XSVGXc2yqcsLnyRXzexE 8Ep+aZzgJXk2pV5Dnaf6ZRnGGSxAwaSFD5+dR+SO9jVd6GN9lKAKywPcJGSJcq0hX3dO W9LRBKLprqAsClc133jD2d0H3yJwlqF0yWYmpH31sZAHTQx12lG+sIbGtW7Zr5VLZdb0 fS4Mx4MWmnHlGLqC4SYs+sLgsTEr6zx0/6bHDB2JvNpB+hEp9O7ph50zwCvQ/2AE+h5q NB+A8CNvM4dydwO3vF3n9TcGWja5ZMnS4NZxdaOrDUjDoOd1a7bSdzpd/HK6ouRMiJdb otSA== X-Forwarded-Encrypted: i=1; AJvYcCXT5XVZc340yjxuzh0ggFqC+XjjxT4lutNg7T0s+ivVr1klY3XsWuIsWRyuiDxLqqu46vwuNZC+Cx4LOng=@vger.kernel.org X-Gm-Message-State: AOJu0YwSyjeecHaRGHP/R2ZGpkcvhmmOg77ed4HN6RO7zHysM3z6vxFr oNe5aWf/pgWzY3vkICQ2+REP4tKB++fe0PXki0loZpYcYw4ULy6P/GHK2GtL4RcR00U= X-Gm-Gg: ASbGncur3VJ/SmY8LmCQxfom+H1NdFutJPMFhC26KZW33A5VY3/URMbJwcjYvMHRw+S VSgcx1u6Ae8V4Io9EcK9HzEtfL1Qwirwa+rmsgWw9oyL23pnopIfjiuDYCUGGXVUN+6ZOOhk/x9 cHn3Ni9lICpiqIv9uyxlhrwgGjqvyVOYZ3ThPgGjtwlVbC/Soo4r3tDVOZPTKpikAUTJBn6rsQa VYNizkW0Ep1yvbdLO1Ad9Wi0sR4ENuZqQQq4ClQzoYeJ6VLUJHYIyCnNCwp9GomHCTQlk8K8jjp +aIZEB1TKiSTc5ukinbb1PUyowvwFx6HMIYvHacI1v6e7SqvUTEE6p8kGyGQms9B9VE8g574yfb 1MXRhEFvT4GjBiqxyeQU/afDx0S3igImjcL0yxt9gwz8RJX6bbbaCKPtIyniuhcXGpH94+PjddW 1PtjLIkTZprziri4kSA7sUTcu3zV9ZPi8= X-Google-Smtp-Source: AGHT+IFLXAEw3tjU/Pr/6wioFbhUuNkqtSYjBkNNCIo72pud4xy2at7NIHMIFUUJC02TK+9WqwH1GA== X-Received: by 2002:a17:902:cece:b0:295:5898:ff5c with SMTP id d9443c01a7336-295589900b9mr26809925ad.16.1762011848203; Sat, 01 Nov 2025 08:44:08 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.44.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:44:07 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Anup Patel Subject: [PATCH v2 08/12] riscv: Enable DMA_RESTRICTED_POOL in defconfig Date: Sat, 1 Nov 2025 21:12:41 +0530 Message-ID: <20251101154245.162492-9-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The RISC-V ramsink trace component may have implementation specific restrictions such that the component can only write trace data in particular parts of DRAM. Enable DMA_RESTRICTED_POOL in the defconfig so that dma_alloc_*() and dma_free_*() APIs work for devices with DMA address restrictions. Signed-off-by: Anup Patel --- arch/riscv/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig index d2c1ea2a866c..4e870b8f2220 100644 --- a/arch/riscv/configs/defconfig +++ b/arch/riscv/configs/defconfig @@ -305,6 +305,7 @@ CONFIG_SECURITY_APPARMOR=3Dy CONFIG_DEFAULT_SECURITY_DAC=3Dy CONFIG_CRYPTO_USER_API_HASH=3Dy CONFIG_CRYPTO_DEV_VIRTIO=3Dy +CONFIG_DMA_RESTRICTED_POOL=3Dy CONFIG_PRINTK_TIME=3Dy CONFIG_DEBUG_KERNEL=3Dy CONFIG_DEBUG_FS=3Dy --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pl1-f173.google.com (mail-pl1-f173.google.com [209.85.214.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 939782F9DBC for ; Sat, 1 Nov 2025 15:44:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011859; cv=none; b=F0t6DGATzNejblNYfclVJFTpw/2y1FUb6crnTvzE0XmIOnXmnAN+db8jyjz3QBl5Rtic/IpfaOLcjA+cQ/BISm0xqt2WT+qTQJZMkPH26Y3/FJShUG9rrNgaUsK4yY9jgUMeyji5NwIERblAy+KlgnGV2ElumktfHZqJYrAdPVE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011859; c=relaxed/simple; bh=g5rD55j0ewpWZwtP4iDepKmEh3GBb5aXjxdfchIjUts=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oO5Oiv77L3j0QUPFJQYVLAzP7bC3OMEYd8qkr/gDOYk+EA+9HTw7JzoszZh6sQUGkFlMci5u5J1Wpx3AX5kJo+wh5jbVBf/eefYwalCBiRyVHvHehPUUzChOOFfs9ObXnz+Z82T1Vl23+jOApTQ+zYgXRriFQaMfmX9rlnX/qAE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=a5AW46dE; arc=none smtp.client-ip=209.85.214.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="a5AW46dE" Received: by mail-pl1-f173.google.com with SMTP id d9443c01a7336-29524c38f4fso22196795ad.2 for ; Sat, 01 Nov 2025 08:44:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011857; x=1762616657; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uw3xX0lWv0Z5caNa0HF905Jm6Ibav/ckH29ZGZIeYG0=; b=a5AW46dE9IHdzZ2nYC0qH8ODDdmsqR+6Y5n1zCnveKYYe1S4+O+NJQ91GXTDd3DkzC u5hB9wAed6gSMZiOSOp4e8Ju8rTJRgIiJCuXOiDWJqQSH87GlHDXYEYUmkTGLF9KZYsh gA/aPg6FPvHDnw+9sNdeUHxmWE2ItUUxwcMR8DwxOxmn4Qbn84HetDuyrjmjcxAJxm/N YwyjI6Ar9E6xl3s84Ci5K3PiCqslGb5LILN70/vAa1sWFkBaxIDVdYvidGF6y8A0CQLg MgFw421qgdy4wvIiRyznOGfC/CdnubBuGEM0uT+EOGSvmrBC+OihDvMmaxNrrN/hjQTI x9Mw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011857; x=1762616657; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uw3xX0lWv0Z5caNa0HF905Jm6Ibav/ckH29ZGZIeYG0=; b=tRRPP8KoYmKJ5h1dgc09TJx2yf4E3dGBKdAnNoOGOVXYWk0e6Dg13LSJluRczdDxo4 eoWvVQz7lBxwcjWEGaQ69IIL1G4GU/VrOhWHfCO8gU3DtQ3gcTDIleMUqxusiIAO3kDX Qmvv83s7kN++xY8/kK5P9L/l5OMddlN023XUPHjusDEUuC8SDJHO9tNzlM3QHQVA/Nrk By0MQbZuA8npzRvy1STgaXh0t6ILXhQ9NxZ1JHhKuwtiEuSPi78Adgit2AjdVLn7Myvd yDacb1Hv57eYG2H6JC8hrTIa6Dz5hZyynzIjGLfZGGf5KcDDqnKX1asADzGLkXPVXO8M i1wg== X-Forwarded-Encrypted: i=1; AJvYcCXTPbCU5CSE4VMFuS0ug7AR2Jc2fO7HZ4XZfOCeDLwmk4ioWx9rclhATwGFD1p3ATQxqORgxP3TJ691/Xg=@vger.kernel.org X-Gm-Message-State: AOJu0Yzog9waXygI22NtK/csYtlnz6E8FkkdLUtcNNquuNBcjy/23ITq dZJtnG7Xi2esCImX4noxOC0mHxwmu2aCuQxdkAeN5thFRQUNXRWM6ttrqbQT9QvG71c= X-Gm-Gg: ASbGncs38qczYrrE9QIfxUv2ZwvMfiV8BmegZXcYszzCmd8tjgJgEeDH8omuikmvddk B4K6elJw92bx3WRNJE3O1vRObDOkux0FNhgwinQI0pgGjD2o+6HUWchxxE2BCV245u1N8BKh+fp 6EYUGlKGNfV75EBeIp5Wr/iZbmvEI8QFNGCqnOd1WsTMzsI8IBYWsIhfaIYi9oZ3wO7ZbNwUw+O 5PSw8xTCBgQqro9ePVJ/65oa+buZ5u1Nob2po4Z6fHVcAWyLC1YO/dZ2mna189OiyXtbkeER/ZJ fMDcRZy8c73M9gyg/grD31nM4ywTzFTKXcq+7vCqGCee3eRSMOW24vLZz2N7HVzHnEq5YjEu5PA ooM/AHGwGAYILQEMgZknxC+YK0WTObHOk/G/h+sjqSbEHhN2VZYTZvybkN+tOPMCnzS0qseuLXH EaTuIxhbUtuwWswehWc+pMiZ/vuya+62o= X-Google-Smtp-Source: AGHT+IFFWL85T9HhS0difffMIWTRJBYYSad8o6w2jHo37Nk+CHybhhZtaAfAEVq3uYrHD502FqqzfA== X-Received: by 2002:a17:902:ea0d:b0:295:7bbd:52fa with SMTP id d9443c01a7336-2957bbd5b0dmr6783025ad.56.1762011856866; Sat, 01 Nov 2025 08:44:16 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.44.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:44:16 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Mayuresh Chitale , Anup Patel Subject: [PATCH v2 09/12] rvtrace: Add perf driver for tracing using perf tool Date: Sat, 1 Nov 2025 21:12:42 +0530 Message-ID: <20251101154245.162492-10-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mayuresh Chitale Add perf driver for RISC-V tracing similar to ARM Coresight and Hisilicon PTT drivers. The driver adds 'rvtrace' event descriptor which can be used by the perf tool to record the RISC-V trace data. Co-developed-by: Anup Patel Signed-off-by: Anup Patel Signed-off-by: Mayuresh Chitale --- drivers/hwtracing/rvtrace/Kconfig | 1 + drivers/hwtracing/rvtrace/Makefile | 2 +- drivers/hwtracing/rvtrace/rvtrace-core.c | 8 + drivers/hwtracing/rvtrace/rvtrace-perf.c | 343 +++++++++++++++++++++++ include/linux/rvtrace.h | 3 + 5 files changed, 356 insertions(+), 1 deletion(-) create mode 100644 drivers/hwtracing/rvtrace/rvtrace-perf.c diff --git a/drivers/hwtracing/rvtrace/Kconfig b/drivers/hwtracing/rvtrace/= Kconfig index 0577f9acb858..ba11acf1117d 100644 --- a/drivers/hwtracing/rvtrace/Kconfig +++ b/drivers/hwtracing/rvtrace/Kconfig @@ -4,6 +4,7 @@ menuconfig RVTRACE tristate "RISC-V Trace Support" depends on RISCV depends on OF + select PERF_EVENTS default RISCV help This framework provides a kernel interface for the RISC-V trace diff --git a/drivers/hwtracing/rvtrace/Makefile b/drivers/hwtracing/rvtrace= /Makefile index 122e575da9fb..07403f4d94e3 100644 --- a/drivers/hwtracing/rvtrace/Makefile +++ b/drivers/hwtracing/rvtrace/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 =20 obj-$(CONFIG_RVTRACE) +=3D rvtrace.o -rvtrace-y :=3D rvtrace-core.o rvtrace-platform.o +rvtrace-y :=3D rvtrace-core.o rvtrace-platform.o rvtrace-perf.o obj-$(CONFIG_RVTRACE_ENCODER) +=3D rvtrace-encoder.o obj-$(CONFIG_RVTRACE_RAMSINK) +=3D rvtrace-ramsink.o diff --git a/drivers/hwtracing/rvtrace/rvtrace-core.c b/drivers/hwtracing/r= vtrace/rvtrace-core.c index b955e5f3b048..bbe39aaf930d 100644 --- a/drivers/hwtracing/rvtrace/rvtrace-core.c +++ b/drivers/hwtracing/rvtrace/rvtrace-core.c @@ -777,11 +777,19 @@ static int __init rvtrace_init(void) return ret; } =20 + ret =3D rvtrace_perf_init(); + if (ret) { + platform_driver_unregister(&rvtrace_platform_driver); + bus_unregister(&rvtrace_bustype); + return ret; + } + return 0; } =20 static void __exit rvtrace_exit(void) { + rvtrace_perf_exit(); platform_driver_unregister(&rvtrace_platform_driver); bus_unregister(&rvtrace_bustype); } diff --git a/drivers/hwtracing/rvtrace/rvtrace-perf.c b/drivers/hwtracing/r= vtrace/rvtrace-perf.c new file mode 100644 index 000000000000..2d3039f8b681 --- /dev/null +++ b/drivers/hwtracing/rvtrace/rvtrace-perf.c @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(C) 2025 Ventanamicro Limited. All rights reserved. + * Author: Mayuresh Chitale + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RVTRACE_PMU_NAME "rvtrace" +#define RVTRACE_BUF_LEN (4 * 1024 * 1024) + +static struct pmu rvtrace_pmu; +static DEFINE_SPINLOCK(perf_buf_lock); + +/** + * struct rvtrace_event_data - RISC-V trace specific perf event data + * @work: Handle to free allocated memory outside IRQ context. + * @mask: Hold the CPU(s) this event was set for. + * @aux_hwid_done: Whether a CPU has emitted the TraceID packet or not. + * @path: An array of path, each slot for one CPU. + * @buf: Aux buffer / pages allocated by perf framework. + */ +struct rvtrace_event_data { + struct work_struct work; + cpumask_t mask; + cpumask_t aux_hwid_done; + struct rvtrace_path * __percpu *path; + struct rvtrace_perf_auxbuf buf; +}; + +struct rvtrace_ctxt { + struct perf_output_handle handle; + struct rvtrace_event_data *event_data; +}; + +static DEFINE_PER_CPU(struct rvtrace_ctxt, rvtrace_ctxt); + +static void *alloc_event_data(int cpu) +{ + struct rvtrace_event_data *event_data; + cpumask_t *mask; + + event_data =3D kzalloc(sizeof(*event_data), GFP_KERNEL); + if (!event_data) + return NULL; + + /* Update mask as per selected CPUs */ + mask =3D &event_data->mask; + if (cpu !=3D -1) + cpumask_set_cpu(cpu, mask); + else + cpumask_copy(mask, cpu_present_mask); + + event_data->path =3D alloc_percpu(struct rvtrace_path *); + return event_data; +} + +static void rvtrace_free_aux(void *data) +{ + struct rvtrace_event_data *event_data =3D data; + + schedule_work(&event_data->work); +} + +static struct rvtrace_path **rvtrace_event_cpu_path_ptr(struct rvtrace_eve= nt_data *data, + int cpu) +{ + return per_cpu_ptr(data->path, cpu); +} + +static void free_event_data(struct work_struct *work) +{ + struct rvtrace_event_data *event_data; + struct rvtrace_path *path; + cpumask_t *mask; + int cpu; + + event_data =3D container_of(work, struct rvtrace_event_data, work); + mask =3D &event_data->mask; + for_each_cpu(cpu, mask) { + path =3D *rvtrace_event_cpu_path_ptr(event_data, cpu); + rvtrace_destroy_path(path); + } + free_percpu(event_data->path); + kfree(event_data); +} + +static void *rvtrace_setup_aux(struct perf_event *event, void **pages, + int nr_pages, bool overwrite) +{ + struct rvtrace_event_data *event_data =3D NULL; + struct page **pagelist; + int cpu =3D event->cpu, i; + cpumask_t *mask; + + event_data =3D alloc_event_data(cpu); + if (!event_data) + return NULL; + + INIT_WORK(&event_data->work, free_event_data); + mask =3D &event_data->mask; + /* + * Create the path for each CPU in the mask. In case of any failure skip = the CPU + */ + for_each_cpu(cpu, mask) { + struct rvtrace_component *src; + struct rvtrace_path *path; + + src =3D rvtrace_cpu_source(cpu); + if (!src) + continue; + + path =3D rvtrace_create_path(src, NULL, RVTRACE_COMPONENT_MODE_PERF); + if (!path) + continue; + + *rvtrace_event_cpu_path_ptr(event_data, cpu) =3D path; + } + + /* If we don't have any CPUs ready for tracing, abort */ + cpu =3D cpumask_first(&event_data->mask); + if (cpu >=3D nr_cpu_ids) + goto err; + + pagelist =3D kcalloc(nr_pages, sizeof(*pagelist), GFP_KERNEL); + if (!pagelist) + goto err; + + for (i =3D 0; i < nr_pages; i++) + pagelist[i] =3D virt_to_page(pages[i]); + + event_data->buf.base =3D vmap(pagelist, nr_pages, VM_MAP, PAGE_KERNEL); + if (!event_data->buf.base) { + kfree(pagelist); + goto err; + } + + event_data->buf.nr_pages =3D nr_pages; + event_data->buf.length =3D nr_pages * PAGE_SIZE; + event_data->buf.pos =3D 0; + return event_data; +err: + rvtrace_free_aux(event_data); + return NULL; +} + +static void rvtrace_event_read(struct perf_event *event) +{ +} + +static void rvtrace_event_destroy(struct perf_event *event) +{ +} + +static int rvtrace_event_init(struct perf_event *event) +{ + if (event->attr.type !=3D rvtrace_pmu.type) + return -EINVAL; + + event->destroy =3D rvtrace_event_destroy; + return 0; +} + +static void rvtrace_event_start(struct perf_event *event, int flags) +{ + struct rvtrace_ctxt *ctxt =3D this_cpu_ptr(&rvtrace_ctxt); + struct perf_output_handle *handle =3D &ctxt->handle; + struct rvtrace_event_data *event_data; + int cpu =3D smp_processor_id(); + struct rvtrace_path *path; + + if (WARN_ON(ctxt->event_data)) + goto fail; + + /* + * Deal with the ring buffer API and get a handle on the + * session's information. + */ + event_data =3D perf_aux_output_begin(handle, event); + if (!event_data) + goto fail; + + if (!cpumask_test_cpu(cpu, &event_data->mask)) + goto out; + + event_data->buf.pos =3D handle->head % event_data->buf.length; + path =3D *rvtrace_event_cpu_path_ptr(event_data, cpu); + if (!path) { + pr_err("Error. Path not found\n"); + return; + } + + if (rvtrace_path_start(path)) { + pr_err("Error. Tracing not started\n"); + return; + } + + /* + * output cpu / trace ID in perf record, once for the lifetime + * of the event. + */ + if (!cpumask_test_cpu(cpu, &event_data->aux_hwid_done)) { + cpumask_set_cpu(cpu, &event_data->aux_hwid_done); + perf_report_aux_output_id(event, cpu); + } + +out: + /* Tell the perf core the event is alive */ + event->hw.state =3D 0; + ctxt->event_data =3D event_data; + return; +fail: + event->hw.state =3D PERF_HES_STOPPED; +} + +static void rvtrace_event_stop(struct perf_event *event, int mode) +{ + struct rvtrace_ctxt *ctxt =3D this_cpu_ptr(&rvtrace_ctxt); + struct perf_output_handle *handle =3D &ctxt->handle; + struct rvtrace_event_data *event_data; + int ret, cpu =3D smp_processor_id(); + struct rvtrace_path *path; + size_t size; + + if (event->hw.state =3D=3D PERF_HES_STOPPED) + return; + + if (handle->event && + WARN_ON(perf_get_aux(handle) !=3D ctxt->event_data)) + return; + + event_data =3D ctxt->event_data; + ctxt->event_data =3D NULL; + + if (WARN_ON(!event_data)) + return; + + if (handle->event && (mode & PERF_EF_UPDATE) && !cpumask_test_cpu(cpu, &e= vent_data->mask)) { + event->hw.state =3D PERF_HES_STOPPED; + perf_aux_output_end(handle, 0); + return; + } + + /* stop tracing */ + path =3D *rvtrace_event_cpu_path_ptr(event_data, cpu); + if (!path) { + pr_err("Error. Path not found\n"); + return; + } + + if (rvtrace_path_stop(path)) { + pr_err("Error. Tracing not stopped\n"); + return; + } + + event->hw.state =3D PERF_HES_STOPPED; + if (handle->event && (mode & PERF_EF_UPDATE)) { + if (WARN_ON_ONCE(handle->event !=3D event)) + return; + spin_lock(&perf_buf_lock); + ret =3D rvtrace_path_copyto_auxbuf(path, &event_data->buf, &size); + spin_unlock(&perf_buf_lock); + WARN_ON_ONCE(ret); + if (READ_ONCE(handle->event)) + perf_aux_output_end(handle, size); + else + WARN_ON(size); + } +} + +static int rvtrace_event_add(struct perf_event *event, int mode) +{ + struct hw_perf_event *hwc =3D &event->hw; + int ret =3D 0; + + if (mode & PERF_EF_START) { + rvtrace_event_start(event, 0); + if (hwc->state & PERF_HES_STOPPED) + ret =3D -EINVAL; + } else { + hwc->state =3D PERF_HES_STOPPED; + } + + return ret; +} + +static void rvtrace_event_del(struct perf_event *event, int mode) +{ + rvtrace_event_stop(event, PERF_EF_UPDATE); +} + +PMU_FORMAT_ATTR(event, "config:0-0"); + +static struct attribute *rvtrace_pmu_formats_attr[] =3D { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group rvtrace_pmu_format_group =3D { + .name =3D "format", + .attrs =3D rvtrace_pmu_formats_attr, +}; + +static const struct attribute_group *rvtrace_pmu_attr_groups[] =3D { + &rvtrace_pmu_format_group, + NULL, +}; + +int __init rvtrace_perf_init(void) +{ + rvtrace_pmu.capabilities =3D (PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRAC= E); + rvtrace_pmu.attr_groups =3D rvtrace_pmu_attr_groups; + rvtrace_pmu.task_ctx_nr =3D perf_sw_context; + rvtrace_pmu.read =3D rvtrace_event_read; + rvtrace_pmu.event_init =3D rvtrace_event_init; + rvtrace_pmu.setup_aux =3D rvtrace_setup_aux; + rvtrace_pmu.free_aux =3D rvtrace_free_aux; + rvtrace_pmu.start =3D rvtrace_event_start; + rvtrace_pmu.stop =3D rvtrace_event_stop; + rvtrace_pmu.add =3D rvtrace_event_add; + rvtrace_pmu.del =3D rvtrace_event_del; + rvtrace_pmu.module =3D THIS_MODULE; + + return perf_pmu_register(&rvtrace_pmu, RVTRACE_PMU_NAME, -1); +} + +void __exit rvtrace_perf_exit(void) +{ + perf_pmu_unregister(&rvtrace_pmu); +} diff --git a/include/linux/rvtrace.h b/include/linux/rvtrace.h index cecf6c153ca6..d5f782ac132f 100644 --- a/include/linux/rvtrace.h +++ b/include/linux/rvtrace.h @@ -343,4 +343,7 @@ static inline int rvtrace_comp_is_empty(struct rvtrace_= component *comp) comp->pdata->control_poll_timeout_usecs); } =20 +int rvtrace_perf_init(void); +void rvtrace_perf_exit(void); + #endif --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 430352F9DBC for ; Sat, 1 Nov 2025 15:44:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011868; cv=none; b=QtznIyIPEnlMQ2amnnTNH+7p/1Fmm6yFilTKuSfJ9AH94AzUpCRi8hhYMpd2S3aiKDViTC0UPnX+DK0Ttx2SNHEhWpLzhg60SJuLqZYcIiyEoSMKslXdUhgCykirKUMoAHDRNcfRHj6aOUIxZOu32Hs7VzV7QzsToc5AFNaifLQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011868; c=relaxed/simple; bh=pizzB9cRq+aT3hF9bgrZeiXgsMsAyZQ2bUTDm+uBFMU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Sc9qLqkH0k4tKfehxIVojsyYifq18XpEimIcOORzpoQt2nT4U9tgj/+hyPD5TyWgUO89bDQAojNV0KZLK7ruxG11zD/+YicZME2tLigUoeFEgQuCm3tep0LyOVGRxUNGb7cARqdWz3/syDrANPUHmXn+vJRbsOFnQj6ReuTYULc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=WbzOGzR7; arc=none smtp.client-ip=209.85.214.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="WbzOGzR7" Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-27d3540a43fso32333875ad.3 for ; Sat, 01 Nov 2025 08:44:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011866; x=1762616666; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7XnFRCS+sTtRhexwba7Np0dAUXiR2aGYN+xgEcH1cxk=; b=WbzOGzR7EZ21EGYkpi0SW/jclvIB1HG8csrLqC1mRo0HY8eGThmgPdfegsN3CZPStP dZOXcxzI4B3MTU3HO7Ru/4RbSgLXfKlYs55OlATdvJEtdXWungTXcBY8cjxL8+HexJzZ ONoPNKzxoF4mw6C9cagi6GsPGyfxaBbdbws2Uqk83vnA+CwoJi9YCg7OFDSaADc8Re7w cMFb660Fds0jx0xII8jcmOZ55EN8IAU0DCRAksEPRuqAMqIRpwgi2XOxyGuHUqH+BLig 7toWKtSImkOPJa3ysw72x06wXuIdUS0QFEgySN0kd6QFPSSXflljnNqkfX9PQywu7mm3 E9xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011866; x=1762616666; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7XnFRCS+sTtRhexwba7Np0dAUXiR2aGYN+xgEcH1cxk=; b=GrTYP70Skb4cZqmpdC+tQa8fqGk6un79xTnEKRD1PQfAZqSq41bsUss8ttUySXbOIe sc7q5bFKRxApoYRrMyG8jsKHnkWSqdnHLCr4lZxElJ30cZn/JpxfKRWsKD2vNmTu9r7Y xUpwRegPAtGHflXgC2TRzYtfrPyQJ6rOcGpaC5yUwb0CVDvh/p0D4m0Oq7iI8FMDbW1n kImUdoPwMDxiJg8pvZswj0csOQQgg/iiPOgpxRdgB/GLNS0yNhKM77OzNp2rAYcWhWXI YuX6+lOqpboaBf1tpSih4psH4k9YRxOB64s+RJTQ6zahZJzHgRUK6jw6SEcETNGwpaOW rQ5A== X-Forwarded-Encrypted: i=1; AJvYcCVnYtmsHG+GHzBRYvjkvLv5Tgq0T57CUuj5NOZO2rr7L1BzLsWPc1h0QJEbzsxhZSc6pbElzA3QTTQPL8w=@vger.kernel.org X-Gm-Message-State: AOJu0YwwRsml/TYWGW7+SUJLYOtf5jw6mnkQUHZUrdxRXU7sJcTcUOm3 vgnkg8CUnXSTBIYYb1+B7hqDOcYadmpfr7epHEzokkzetGOHND9jTWKJmZCXNR3Masg= X-Gm-Gg: ASbGncuZ4TKR7NlGE2LU9blEdobcMVqjEJMNLThskl5uGAYVkUMSDatcuyBFa/DfyiH j9fNlM6487rUdEQScqgFSp2uB/P753W7/2vEuR0krlu+8LhJW/acCJP19lsCpimMQY0REni+8Sv ktJ0PAuZEaAMhMha1a91ZK+hDlyNibZ20owSDaiJSMW36mnVekMIH7b+m87t/8pxUgQv/2WN1Tb kGprpC+k8mtTCj+A64SPNVVBNQRuj+68uBBXAV7ZJ2NBTnNa257F6FBdICev7xWY4IsCzRFhxgX /27dN58FeB1gvV+caJiq211bRz7PQj64ehOid5TZtxS0/a4NWVyQv4L8iMSY3PdyehT8krNKlwO Sz/dhiiLVoTL2FCXF8memMbbwx7FKhHhT/fUpfGVfIFENaAhBWGtJ9jfVM8NeU3RaS/Vz/OHoGv 6rx2twj5ilIG0BoeDK3KPkYV11mGPwZPr5oaFEHK6h9w== X-Google-Smtp-Source: AGHT+IHqSK+MBUN/GAqGdH+BeccrIifT4o6CYolTjikOEjgbWEPinm6+JP4k2LJ8ohbiCjztsZFCQA== X-Received: by 2002:a17:902:ce81:b0:295:5945:2930 with SMTP id d9443c01a7336-29559452c6emr26600735ad.2.1762011866181; Sat, 01 Nov 2025 08:44:26 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.44.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:44:25 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Mayuresh Chitale , Anup Patel Subject: [PATCH v2 10/12] perf tools: Add RISC-V trace PMU record capabilities Date: Sat, 1 Nov 2025 21:12:43 +0530 Message-ID: <20251101154245.162492-11-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mayuresh Chitale Introduce the required auxiliary API functions allowing the perf core to interact with RISC-V trace perf driver. Co-developed-by: Anup Patel Signed-off-by: Anup Patel Signed-off-by: Mayuresh Chitale --- tools/perf/arch/riscv/util/Build | 1 + tools/perf/arch/riscv/util/auxtrace.c | 218 ++++++++++++++++++++++++++ tools/perf/util/auxtrace.c | 1 + tools/perf/util/auxtrace.h | 1 + tools/perf/util/rvtrace.h | 18 +++ 5 files changed, 239 insertions(+) create mode 100644 tools/perf/arch/riscv/util/auxtrace.c create mode 100644 tools/perf/util/rvtrace.h diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/= Build index 58a672246024..2ba1fb98a0ad 100644 --- a/tools/perf/arch/riscv/util/Build +++ b/tools/perf/arch/riscv/util/Build @@ -3,3 +3,4 @@ perf-util-y +=3D header.o =20 perf-util-$(CONFIG_LIBTRACEEVENT) +=3D kvm-stat.o perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) +=3D unwind-libdw.o +perf-util-$(CONFIG_AUXTRACE) +=3D auxtrace.o diff --git a/tools/perf/arch/riscv/util/auxtrace.c b/tools/perf/arch/riscv/= util/auxtrace.c new file mode 100644 index 000000000000..adc86bd38998 --- /dev/null +++ b/tools/perf/arch/riscv/util/auxtrace.c @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Risc-V E-Trace support + */ + +#include +#include +#include +#include +#include +#include + +#include // page_size +#include "../../../util/auxtrace.h" +#include "../../../util/cpumap.h" +#include "../../../util/debug.h" +#include "../../../util/event.h" +#include "../../../util/evlist.h" +#include "../../../util/evsel.h" +#include "../../../util/rvtrace.h" +#include "../../../util/pmu.h" +#include "../../../util/record.h" +#include "../../../util/session.h" +#include "../../../util/tsc.h" + +#define RVTRACE_PMU_NAME "rvtrace" +#define KiB(x) ((x) * 1024) +#define MiB(x) ((x) * 1024 * 1024) + +struct rvtrace_recording { + struct auxtrace_record itr; + struct perf_pmu *rvtrace_pmu; + struct evlist *evlist; +}; + +static size_t rvtrace_info_priv_size(struct auxtrace_record *itr __maybe_u= nused, + struct evlist *evlist __maybe_unused) +{ + return RVTRACE_AUXTRACE_PRIV_SIZE; +} + +static int rvtrace_info_fill(struct auxtrace_record *itr, struct perf_sess= ion *session, + struct perf_record_auxtrace_info *auxtrace_info, size_t priv_size) +{ + struct rvtrace_recording *ptr =3D container_of(itr, struct rvtrace_record= ing, itr); + struct perf_pmu *rvtrace_pmu =3D ptr->rvtrace_pmu; + + if (priv_size !=3D RVTRACE_AUXTRACE_PRIV_SIZE) + return -EINVAL; + + if (!session->evlist->core.nr_mmaps) + return -EINVAL; + + auxtrace_info->type =3D PERF_AUXTRACE_RISCV_TRACE; + auxtrace_info->priv[0] =3D rvtrace_pmu->type; + + return 0; +} + +static int rvtrace_set_auxtrace_mmap_page(struct record_opts *opts) +{ + bool privileged =3D perf_event_paranoid_check(-1); + + if (!opts->full_auxtrace) + return 0; + + if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) { + if (privileged) { + opts->auxtrace_mmap_pages =3D MiB(16) / page_size; + } else { + opts->auxtrace_mmap_pages =3D KiB(128) / page_size; + if (opts->mmap_pages =3D=3D UINT_MAX) + opts->mmap_pages =3D KiB(256) / page_size; + } + } + + /* Validate auxtrace_mmap_pages */ + if (opts->auxtrace_mmap_pages) { + size_t sz =3D opts->auxtrace_mmap_pages * (size_t)page_size; + size_t min_sz =3D KiB(8); + + if (sz < min_sz || !is_power_of_2(sz)) { + pr_err("Invalid mmap size : must be at least %zuKiB and a power of 2\n", + min_sz / 1024); + return -EINVAL; + } + } + + return 0; +} + +static int rvtrace_recording_options(struct auxtrace_record *itr, struct e= vlist *evlist, + struct record_opts *opts) +{ + struct rvtrace_recording *ptr =3D container_of(itr, struct rvtrace_record= ing, itr); + struct perf_pmu *rvtrace_pmu =3D ptr->rvtrace_pmu; + struct evsel *evsel, *rvtrace_evsel =3D NULL; + struct evsel *tracking_evsel; + int err; + + ptr->evlist =3D evlist; + evlist__for_each_entry(evlist, evsel) { + if (evsel->core.attr.type =3D=3D rvtrace_pmu->type) { + if (rvtrace_evsel) { + pr_err("There may be only one " RVTRACE_PMU_NAME "x event\n"); + return -EINVAL; + } + evsel->core.attr.freq =3D 0; + evsel->core.attr.sample_period =3D 1; + evsel->needs_auxtrace_mmap =3D true; + rvtrace_evsel =3D evsel; + opts->full_auxtrace =3D true; + } + } + + err =3D rvtrace_set_auxtrace_mmap_page(opts); + if (err) + return err; + /* + * To obtain the auxtrace buffer file descriptor, the auxtrace event + * must come first. + */ + evlist__to_front(evlist, rvtrace_evsel); + evsel__set_sample_bit(rvtrace_evsel, TIME); + + /* Add dummy event to keep tracking */ + err =3D parse_event(evlist, "dummy:u"); + if (err) + return err; + + tracking_evsel =3D evlist__last(evlist); + evlist__set_tracking_event(evlist, tracking_evsel); + + tracking_evsel->core.attr.freq =3D 0; + tracking_evsel->core.attr.sample_period =3D 1; + evsel__set_sample_bit(tracking_evsel, TIME); + + return 0; +} + +static u64 rvtrace_reference(struct auxtrace_record *itr __maybe_unused) +{ + return rdtsc(); +} + +static void rvtrace_recording_free(struct auxtrace_record *itr) +{ + struct rvtrace_recording *ptr =3D + container_of(itr, struct rvtrace_recording, itr); + + free(ptr); +} + +static struct auxtrace_record *rvtrace_recording_init(int *err, struct per= f_pmu *rvtrace_pmu) +{ + struct rvtrace_recording *ptr; + + if (!rvtrace_pmu) { + *err =3D -ENODEV; + return NULL; + } + + ptr =3D zalloc(sizeof(*ptr)); + if (!ptr) { + *err =3D -ENOMEM; + return NULL; + } + + ptr->rvtrace_pmu =3D rvtrace_pmu; + ptr->itr.recording_options =3D rvtrace_recording_options; + ptr->itr.info_priv_size =3D rvtrace_info_priv_size; + ptr->itr.info_fill =3D rvtrace_info_fill; + ptr->itr.free =3D rvtrace_recording_free; + ptr->itr.reference =3D rvtrace_reference; + ptr->itr.read_finish =3D auxtrace_record__read_finish; + ptr->itr.alignment =3D 0; + + *err =3D 0; + return &ptr->itr; +} + +static struct perf_pmu *find_pmu_for_event(struct perf_pmu **pmus, + int pmu_nr, struct evsel *evsel) +{ + int i; + + if (!pmus) + return NULL; + + for (i =3D 0; i < pmu_nr; i++) { + if (evsel->core.attr.type =3D=3D pmus[i]->type) + return pmus[i]; + } + + return NULL; +} + +struct auxtrace_record *auxtrace_record__init(struct evlist *evlist, int *= err) +{ + struct perf_pmu *rvtrace_pmu =3D NULL; + struct perf_pmu *found_etm =3D NULL; + struct evsel *evsel; + + if (!evlist) + return NULL; + + rvtrace_pmu =3D perf_pmus__find(RVTRACE_PMU_NAME); + evlist__for_each_entry(evlist, evsel) { + if (rvtrace_pmu && !found_etm) + found_etm =3D find_pmu_for_event(&rvtrace_pmu, 1, evsel); + } + + if (found_etm) + return rvtrace_recording_init(err, rvtrace_pmu); + + *err =3D 0; + return NULL; +} diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index 1539c1dc823c..c905563e0d8a 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -1394,6 +1394,7 @@ int perf_event__process_auxtrace_info(struct perf_ses= sion *session, case PERF_AUXTRACE_VPA_DTL: err =3D powerpc_vpadtl_process_auxtrace_info(event, session); break; + case PERF_AUXTRACE_RISCV_TRACE: case PERF_AUXTRACE_UNKNOWN: default: return -EINVAL; diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h index e0a5b39fed12..1c89a281a06c 100644 --- a/tools/perf/util/auxtrace.h +++ b/tools/perf/util/auxtrace.h @@ -51,6 +51,7 @@ enum auxtrace_type { PERF_AUXTRACE_S390_CPUMSF, PERF_AUXTRACE_HISI_PTT, PERF_AUXTRACE_VPA_DTL, + PERF_AUXTRACE_RISCV_TRACE, }; =20 enum itrace_period_type { diff --git a/tools/perf/util/rvtrace.h b/tools/perf/util/rvtrace.h new file mode 100644 index 000000000000..93c041db8660 --- /dev/null +++ b/tools/perf/util/rvtrace.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright(C) 2015 Linaro Limited. All rights reserved. + * Author: Mathieu Poirier + */ + +#ifndef INCLUDE__UTIL_PERF_RVTRACE_H__ +#define INCLUDE__UTIL_PERF_RVTRACE_H__ + +#include "debug.h" +#include "auxtrace.h" +#include "util/event.h" +#include "util/session.h" +#include + +#define RVTRACE_AUXTRACE_PRIV_SIZE sizeof(u64) + +#endif --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ED78F2FCBE5 for ; Sat, 1 Nov 2025 15:44:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011877; cv=none; b=NIQ1Dg0dnRZv7m0q3Y44bICwQXY90qlE9uIloe0wwn4O/cAOsCxIbUg3QO9VFHnfUCMVk5jAHnp8kkN0ZABKj5hQwzBqQRkbeb3E8iVdvIMzuCjkk1CNTfOnTphAwi3iLVjnlTW2cZhjjDZucDNn7AP5uDWgAU76sVYZ7HqFeYA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011877; c=relaxed/simple; bh=9VZ5oZne9mpX5H3+7yVk994ciSqlhPNHkVeF7hnMOrA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=O8A6FJMWAhetSrVfL2kNlQf8OVNHvwyOsZIeAJSUtHYnGKnh4ewnOrOIAnuQXf+Zrid3QEcTna/sDqpACHIfPiSVJSuw5cW4QEjSwpjy49SucGg2f08s/YZpplwAcwicZJDaZ5sxDZ4pkx1oUeKoEqFUlLwFapv2FKSUJGqvSZc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=MIghZK2/; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="MIghZK2/" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-27d3540a43fso32334515ad.3 for ; Sat, 01 Nov 2025 08:44:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011875; x=1762616675; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/d8QkW3fcCXd7CklfrCHDzxbpDgi3QraTb9WZel9ANQ=; b=MIghZK2/LOZaiXHm+DRglXQV/aljwaYCj5HAfo2Aaf0d1kfa0H4RJtQ/b+3PEfCiux TlY7vAGRQx5Gk86Xo9Xe7LjBdn9p/OCQmZuKJtZRO6iLt+Wq8GIXttL/U08pFkbBvP2/ jRyRCHJjepat2kJBIPKk8901JsaYsZmbyaGGYaRW/adc/oCepnF7asQ5eWBv9nNhQTMV RTw6ttoR6D1/vfkBJbbzcZkWlVfB6+6UQpItr/1Gl4JdogNzH//1U5J73ZaN3JGUkMRm XQ42N7DmVV2Hy6lC7m1UEv9zx2DvIwDLMWqTLMCekPhbwCmA8GbchGjAg1D+fO3Irwt5 e52A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011875; x=1762616675; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/d8QkW3fcCXd7CklfrCHDzxbpDgi3QraTb9WZel9ANQ=; b=F3GTkhqXTeG7vYqRm/ck8xa87cUfdz3nLPztCDa7X43SniQsy6PjC7JGysnEOvGkQQ NSIYuO9Ik3J9YZNk4tHQl9yJogmN7344U1k+xR/0xAMLEhNZOMKPcD2RuSUWVMtL4AXs /LMyOM/4QgzWFSzkG+Tjb2sVz2XPidSP48Me2RMlgy+PtvaxJ6Y4K42GEATkDSslevG2 7dV7D3uIuy8BXIpl4DQh3AdJwFW4bCBBLPypPHaX7q5XRzIFqh9W9U+wBJzqzytuv+t/ bwFdQDcutfnMqhAKzSHGX27TGs/vn42R0sh2PPZJlRzmsKckpXZgMaWiI20csZz5qbnK oFxA== X-Forwarded-Encrypted: i=1; AJvYcCXnQL+swMouIHVrM2nk8JLtz+QIP2lhA4/yrSt0kVxflMeNpaFM/tMWV7I6/HQkAZZepNKnAsDLhls5KUc=@vger.kernel.org X-Gm-Message-State: AOJu0YyunXBL3dJTJDfjFIrUAEprEjfbKk0JWeBGGwNj6mF6MU3fFX3D ohsUyw+ucXPz/kzCDrqSZbF2G4JsTjKwEm0VElGL3rqFSapPlunHFBbCdsJjXb76Uos= X-Gm-Gg: ASbGnctyLJ9qMufIEuT7Si34cXQdGGsLEZytIL79DdGxj71jbyqX0+sdTRKcBYOtEyq zsRut41gf4TAPGrSnbv0h856OZp9rncbQVn5SuYctNKlcneRbRvHgr4sSpoPyPsSOfxUkUvdQ5U eSs8ASsBR1c7f106/HNfWwMl28OoePUvQbCh7pX4e9fkNZEuk8eHl5pWrT3BQSApgFq8PekjlxI lO5r66fs7auWoNO8QDDAhLlhNK7Bd42Jp8IhFsu3ORt2cqvS130s9CpYs9rlAogUgxhhCTXZplF aioR6BsXNYGzdcRRY14mRc1svbcBDrvI3N9drveZBGGqRA9vIz66ohmtTF0ofSlZtEc8QSudvGR 2DzR1OIDKLVg6jhszd2loUNke56TMyTJI2qMMRyHkokOLYJSqY1o/h3nKuCWubABPTIQcQcOHdu 2R5Ip4TUmhn9ZP64lCz56L++3SuSyAA7bIHK71BGhasw== X-Google-Smtp-Source: AGHT+IGqcfZVcMgWLUG0d9hDZlQu23GscfETgA3I9ETT6Ty8Q0IVDNoUtgE/qtgar49rN37Arqj0Gw== X-Received: by 2002:a17:902:e552:b0:294:f1fa:9097 with SMTP id d9443c01a7336-2951a55b71emr107166325ad.34.1762011875095; Sat, 01 Nov 2025 08:44:35 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.44.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:44:34 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Mayuresh Chitale , Anup Patel Subject: [PATCH v2 11/12] perf tools: Initial support for RISC-V trace decoder Date: Sat, 1 Nov 2025 21:12:44 +0530 Message-ID: <20251101154245.162492-12-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mayuresh Chitale Add bare bones support for RISC-V trace decoder so that the data received from the hardware by the RISC-V trace perf driver can be written to the perf record output file. Co-developed-by: Anup Patel Signed-off-by: Anup Patel Signed-off-by: Mayuresh Chitale --- tools/perf/util/Build | 1 + tools/perf/util/auxtrace.c | 3 + tools/perf/util/rvtrace-decoder.c | 91 +++++++++++++++++++++++++++++++ tools/perf/util/rvtrace.h | 2 + 4 files changed, 97 insertions(+) create mode 100644 tools/perf/util/rvtrace-decoder.c diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 4be313cd115a..f736cea51fd8 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -145,6 +145,7 @@ perf-util-$(CONFIG_AUXTRACE) +=3D cs-etm.o perf-util-$(CONFIG_AUXTRACE) +=3D cs-etm-decoder/ endif perf-util-$(CONFIG_AUXTRACE) +=3D cs-etm-base.o +perf-util-$(CONFIG_AUXTRACE) +=3D rvtrace-decoder.o =20 perf-util-y +=3D parse-branch-options.o perf-util-y +=3D dump-insn.o diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c index c905563e0d8a..299991d5d305 100644 --- a/tools/perf/util/auxtrace.c +++ b/tools/perf/util/auxtrace.c @@ -54,6 +54,7 @@ #include "arm-spe.h" #include "hisi-ptt.h" #include "s390-cpumsf.h" +#include "rvtrace.h" #include "util/mmap.h" #include "powerpc-vpadtl.h" =20 @@ -1395,6 +1396,8 @@ int perf_event__process_auxtrace_info(struct perf_ses= sion *session, err =3D powerpc_vpadtl_process_auxtrace_info(event, session); break; case PERF_AUXTRACE_RISCV_TRACE: + err =3D rvtrace__process_auxtrace_info(event, session); + break; case PERF_AUXTRACE_UNKNOWN: default: return -EINVAL; diff --git a/tools/perf/util/rvtrace-decoder.c b/tools/perf/util/rvtrace-de= coder.c new file mode 100644 index 000000000000..58db5ca62c1a --- /dev/null +++ b/tools/perf/util/rvtrace-decoder.c @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RISC-V trace Decoder + */ + +#include +#include +#include "evlist.h" +#include +#include "rvtrace.h" + +struct rvtrace_decoder { + struct auxtrace auxtrace; + u32 auxtrace_type; + struct perf_session *session; + struct machine *machine; + u32 pmu_type; +}; + +static int rvtrace_process_event(struct perf_session *session __maybe_unus= ed, + union perf_event *event __maybe_unused, + struct perf_sample *sample __maybe_unused, + const struct perf_tool *tool __maybe_unused) +{ + return 0; +} + +static int rvtrace_process_auxtrace_event(struct perf_session *session __m= aybe_unused, + union perf_event *event __maybe_unused, + const struct perf_tool *tool __maybe_unused) +{ + return 0; +} + +static int rvtrace_flush(struct perf_session *session __maybe_unused, + const struct perf_tool *tool __maybe_unused) +{ + return 0; +} + +static void rvtrace_free_events(struct perf_session *session __maybe_unuse= d) +{ +} + +static void rvtrace_free(struct perf_session *session) +{ + struct rvtrace_decoder *ptr =3D container_of(session->auxtrace, struct rv= trace_decoder, + auxtrace); + + session->auxtrace =3D NULL; + free(ptr); +} + +static bool rvtrace_evsel_is_auxtrace(struct perf_session *session, + struct evsel *evsel) +{ + struct rvtrace_decoder *ptr =3D container_of(session->auxtrace, + struct rvtrace_decoder, auxtrace); + + return evsel->core.attr.type =3D=3D ptr->pmu_type; +} + +int rvtrace__process_auxtrace_info(union perf_event *event, + struct perf_session *session) +{ + struct perf_record_auxtrace_info *auxtrace_info =3D &event->auxtrace_info; + struct rvtrace_decoder *ptr; + + if (auxtrace_info->header.size < RVTRACE_AUXTRACE_PRIV_SIZE + + sizeof(struct perf_record_auxtrace_info)) + return -EINVAL; + + ptr =3D zalloc(sizeof(*ptr)); + if (!ptr) + return -ENOMEM; + + ptr->session =3D session; + ptr->machine =3D &session->machines.host; + ptr->auxtrace_type =3D auxtrace_info->type; + ptr->pmu_type =3D auxtrace_info->priv[0]; + + ptr->auxtrace.process_event =3D rvtrace_process_event; + ptr->auxtrace.process_auxtrace_event =3D rvtrace_process_auxtrace_event; + ptr->auxtrace.flush_events =3D rvtrace_flush; + ptr->auxtrace.free_events =3D rvtrace_free_events; + ptr->auxtrace.free =3D rvtrace_free; + ptr->auxtrace.evsel_is_auxtrace =3D rvtrace_evsel_is_auxtrace; + session->auxtrace =3D &ptr->auxtrace; + + return 0; +} diff --git a/tools/perf/util/rvtrace.h b/tools/perf/util/rvtrace.h index 93c041db8660..fdf2e5866c85 100644 --- a/tools/perf/util/rvtrace.h +++ b/tools/perf/util/rvtrace.h @@ -15,4 +15,6 @@ =20 #define RVTRACE_AUXTRACE_PRIV_SIZE sizeof(u64) =20 +int rvtrace__process_auxtrace_info(union perf_event *event, struct perf_se= ssion *session); +struct auxtrace_record *rvtrace_record_init(int *err); #endif --=20 2.43.0 From nobody Wed Dec 17 16:32:01 2025 Received: from mail-pg1-f178.google.com (mail-pg1-f178.google.com [209.85.215.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF5E02F7AB4 for ; Sat, 1 Nov 2025 15:44:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011885; cv=none; b=Q+2p6j3btVsWLWVwpjF74EPyBdp7qQ0Bs/xKEYCuXdNE+FYrjCiSQoXGNkpKnN7Uc/CPy+wusFSFRaUUrI+FWrjC+j/PRXzuYlxXCuHgD0fqrSuvbMjgOBPqUXFHfWevz5fK3sWb2YroNRbmvSfkT+bpS5st5l4xAGAPE/W6Y5M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762011885; c=relaxed/simple; bh=HAo7tAo9pz07C0eWiSeGo7gw9TyyhoVzDLUpVnhm81I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PzRF0sOnXm8+P5LLJqoqMBMhNufkwxu/epBsoCQOCAL6LKS+d8AibVLHR95NSbxs+XZSYnmNND953geime9uX+XyrBtqfQsYqLF+257PJEyS+VdHn5N7JAXjYfPfgO1lWjgu2g1FEQgCzb0zQyO6ThR15AJ1wqayd4ZXq2nIcrc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=JbgOwaAM; arc=none smtp.client-ip=209.85.215.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="JbgOwaAM" Received: by mail-pg1-f178.google.com with SMTP id 41be03b00d2f7-b67684e2904so2220250a12.2 for ; Sat, 01 Nov 2025 08:44:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1762011883; x=1762616683; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5DZT80TGVVkLsDEh8uIzxjLsAC/KruYN21Qem0m8wUw=; b=JbgOwaAMxo5b9DwOyWFIeRyJX35y0Ee7GbJNmaFzFl7XF4Nd21ZDmUkHnDuAoLy6pY Xf4iT8RXoToM/oVcUBfMyTcYPUuEkzeCJKtGQnKB3rcSyDXu2S/2aFqQ8ozCpF2ylqLq y3DKb5eIEWJ+LxktDcgCOmg/9n0jxvnT0tMsSYLuI8vZhAES+7vacrXD8/7VNU3Yjtv1 9VwdETVDpQoXwNoC5kyxjQilUuOd54hLmW9O+kygCnxp+EU6aijhpT5/2ItGL2gZGXWB gK8kFTRtNUICgiHm6rGng5KYDluWbvzjvyePnRx+X5svfMQ7yA2RW42myKAQWnULu/72 w2iA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762011883; x=1762616683; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5DZT80TGVVkLsDEh8uIzxjLsAC/KruYN21Qem0m8wUw=; b=LVWrXRRPbcA3G3pmBlVcuhwGga16Im3JCiS22X1EFcGUB8j6S/om2gDJaRBqlhbWlb uCzooKE8THDzhpNOres/+lvRyChCh9fODU/G74ksaxW71JdfQ1GtAhf21Ed5VFSzhsMh Tbo+PuH9Cu2ZBHPhPBOvPfP/efrLDuVEzVmC6Ji7EBpN4gX9Ge7EYjfpL61MkZFc4sbS hhXyzgZ1M17GNCOUywBdfjgKszDghPBnHqgpgSrEMRwkpYzrZNnEVs7B12rnwFMpbu4v GGo2HFfDTVonQJHX9iSDwwRzQFKxLmwz86WSlhj3DIaUGOofFtYuB5ZgrGy/j3yNwKyo 5zDQ== X-Forwarded-Encrypted: i=1; AJvYcCXZgHyKfP1BS24hSnoMZNbRx2lssnt0HJEMh+Oi01dLaCXqHU/whpHaBtieO5X77A5Hm7RpeacatS65OL8=@vger.kernel.org X-Gm-Message-State: AOJu0YzwfV+cBdK4Njg3VIzia3jP8TaPlUzyF/9MfuDBiBwjde7ArB8I XbH4F2MH3LJ14s1pIOgj5W4hblMlcAnLNlwFKDagXSVksey9K93BV1vNqct7KC+BZlk= X-Gm-Gg: ASbGncv1NWLCb3c25t9dkNEzoG+7tYIGsg5zT6wjyA8k59CvFoeC/AhMOfEVIkZTLIR eiqEZrJ0Z9RmF0bpQgQb2W7Argyqadx4yVkv8urnNbuKWRXfcayFMbtAEbMvFkmSdgoHhVoywyO gi2sPy2qDzK8z0E9mim+/b1M3/YqFE5M8PQfm1PaNAiYHAFYOA+rTNZKbfwwOKhvc09WYYa1jdn F+v//W65rBs31tigrtbQTnaeKdT6Mf125bAPM6fGwFnA5SoTTWk022BPgzQ0Fv3xAa9kS/y/mcu 4aVbL5xMdvPVBxMXIrjqSl/XVW4Mf2X1f1HsT0pg3YvadLoKpi+Oe49Bwi1isRZVu7OSSpO24T/ 6HWuNrdC66s2P2LeyJoVVd0tKjmEV5uLNM5Z+SKkP8FaKo6cDq9ymVO8ooaZGVDBAvfxYxUAClP AsyYmF+u1TXVsCEpdwvs+ucxdjplLK4Cmatvdth9VrFw== X-Google-Smtp-Source: AGHT+IFkhzb/ZLe6YUds3l2xBBPyiwCVMl/rVpbi6jYMxJtBM8rfwpjbkYfn40FDvEOmymUfcjZpEQ== X-Received: by 2002:a17:902:ec86:b0:268:15f:8358 with SMTP id d9443c01a7336-2951a51e6b1mr86346225ad.42.1762011883058; Sat, 01 Nov 2025 08:44:43 -0700 (PDT) Received: from localhost.localdomain ([122.171.20.36]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-295269bd2fesm59990105ad.105.2025.11.01.08.44.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Nov 2025 08:44:42 -0700 (PDT) From: Anup Patel To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Paul Walmsley , Palmer Dabbelt , Greg KH , Alexander Shishkin , Ian Rogers Cc: Alexandre Ghiti , Peter Zijlstra , Ingo Molnar , Namhyung Kim , Mark Rutland , Jiri Olsa , Adrian Hunter , Liang Kan , Mayuresh Chitale , Anup Patel , Atish Patra , Andrew Jones , Sunil V L , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Anup Patel Subject: [PATCH v2 12/12] MAINTAINERS: Add entry for RISC-V trace framework and drivers Date: Sat, 1 Nov 2025 21:12:45 +0530 Message-ID: <20251101154245.162492-13-apatel@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251101154245.162492-1-apatel@ventanamicro.com> References: <20251101154245.162492-1-apatel@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add Mayuresh and myself as maintainers for RISC-V trace framework and drive= rs. Signed-off-by: Anup Patel --- MAINTAINERS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 29e94a94aa0a..45718190cf44 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22228,6 +22228,17 @@ F: include/dt-bindings/power/thead,th1520-power.h F: include/dt-bindings/reset/thead,th1520-reset.h F: include/linux/firmware/thead/thead,th1520-aon.h =20 +RISC-V TRACE FRAMEWORK AND DRIVERS +M: Mayuresh Chitale +M: Anup Patel +L: linux-riscv@lists.infradead.org +S: Maintained +F: Documentation/devicetree/bindings/riscv/riscv,trace-component.yaml +F: drivers/hwtracing/rvtrace/* +F: include/linux/rvtrace* +F: tools/perf/arch/riscv/util/auxtrace.c +F: tools/perf/util/rvtrace* + RNBD BLOCK DRIVERS M: Md. Haris Iqbal M: Jack Wang --=20 2.43.0