Linux-RISC-V Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support
@ 2025-09-11 12:44 cp0613
  2025-09-11 12:44 ` [RFC PATCH 1/4] dt-bindings: riscv: Add trace components description cp0613
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: cp0613 @ 2025-09-11 12:44 UTC (permalink / raw)
  To: paul.walmsley, palmer, aou, alex, guoren
  Cc: linux-riscv, linux-kernel, Chen Pei

From: Chen Pei <cp0613@linux.alibaba.com>

The RISC-V Trace Specification defines a standardized framework for
capturing and analyzing the execution of RISC-V processors. Its main
uses include: instruction and data tracing, real-time debugging, etc.
Similar to Intel-PT and ARM-CoreSight.

According to the RISC-V Trace Control Interface specification [1].
There are two standard RISC-V trace protocols which will utilize
this RISC-V Trace Control Interface:
- RISC-V N-Trace (Nexus-based Trace) Specification
- Efficient Trace for RISC-V Specification
So, this is a complete guideline for any standard RISC-V trace
implementation.

This series of patches is mainly used to start related work and
communication. It completes the following tasks:
1. dt-bindings completes the basic definition of riscv trace
   component properties, but is still incomplete.
2. Implemented the basic RISC-V Trace PMU driver, including
   support for the aux buffer.
3. Implemented basic support for AUXTRACE integration with perf
   tools.

There's still more work to be done, such as:
1. Complete RISC-V Trace PMU implementation.
2. The perf.data generation and parsing including AUXTRACE events.
3. Taking RISC-V N-Trace as an example, implement the parsing of
   Nexus Trace data format, including support for perf report and
   perf script commands.
We are still sorting out.

Any comments or suggestions are welcome.

[1] https://github.com/riscv-non-isa/tg-nexus-trace.git

Chen Pei (4):
  dt-bindings: riscv: Add trace components description
  riscv: event: Initial riscv trace driver support
  tools: perf: Support perf record with aux buffer for riscv trace
  riscv: trace: Support sink using dma buffer

 .../riscv/trace/riscv,trace,encoder.yaml      |  41 +++
 .../riscv/trace/riscv,trace,funnel.yaml       |  46 ++++
 .../riscv/trace/riscv,trace,sink.yaml         |  37 +++
 arch/riscv/Kbuild                             |   1 +
 arch/riscv/Kconfig                            |   2 +
 arch/riscv/events/Kconfig                     |  11 +
 arch/riscv/events/Makefile                    |   3 +
 arch/riscv/events/riscv_trace.c               | 253 ++++++++++++++++++
 arch/riscv/events/riscv_trace.h               | 133 +++++++++
 arch/riscv/events/riscv_trace_encoder.c       | 109 ++++++++
 arch/riscv/events/riscv_trace_funnel.c        | 160 +++++++++++
 arch/riscv/events/riscv_trace_sink.c          | 100 +++++++
 tools/perf/arch/riscv/util/Build              |   3 +
 tools/perf/arch/riscv/util/auxtrace.c         |  33 +++
 tools/perf/arch/riscv/util/pmu.c              |  18 ++
 tools/perf/arch/riscv/util/riscv-trace.c      | 183 +++++++++++++
 tools/perf/arch/riscv/util/tsc.c              |  15 ++
 tools/perf/util/Build                         |   1 +
 tools/perf/util/auxtrace.c                    |   4 +
 tools/perf/util/auxtrace.h                    |   1 +
 tools/perf/util/riscv-trace.c                 | 162 +++++++++++
 tools/perf/util/riscv-trace.h                 |  18 ++
 22 files changed, 1334 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,encoder.yaml
 create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,funnel.yaml
 create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,sink.yaml
 create mode 100644 arch/riscv/events/Kconfig
 create mode 100644 arch/riscv/events/Makefile
 create mode 100644 arch/riscv/events/riscv_trace.c
 create mode 100644 arch/riscv/events/riscv_trace.h
 create mode 100644 arch/riscv/events/riscv_trace_encoder.c
 create mode 100644 arch/riscv/events/riscv_trace_funnel.c
 create mode 100644 arch/riscv/events/riscv_trace_sink.c
 create mode 100644 tools/perf/arch/riscv/util/auxtrace.c
 create mode 100644 tools/perf/arch/riscv/util/pmu.c
 create mode 100644 tools/perf/arch/riscv/util/riscv-trace.c
 create mode 100644 tools/perf/arch/riscv/util/tsc.c
 create mode 100644 tools/perf/util/riscv-trace.c
 create mode 100644 tools/perf/util/riscv-trace.h

-- 
2.49.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RFC PATCH 1/4] dt-bindings: riscv: Add trace components description
  2025-09-11 12:44 [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support cp0613
@ 2025-09-11 12:44 ` cp0613
  2025-09-11 17:24   ` Krzysztof Kozlowski
  2025-09-11 12:44 ` [RFC PATCH 2/4] riscv: event: Initial riscv trace driver support cp0613
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: cp0613 @ 2025-09-11 12:44 UTC (permalink / raw)
  To: paul.walmsley, palmer, aou, alex, guoren
  Cc: linux-riscv, linux-kernel, Chen Pei

From: Chen Pei <cp0613@linux.alibaba.com>

This patch has added property definitions related to the riscv
trace component, providing a foundation for subsequent driver
implementations.

The RISC-V Trace Control Interface can be found in [1].
Some principles are as follows:
1. Trace has three types of components:
1.1 Encoder: Collects CPU execution information through the
    Ingress Port and generates Trace Messages.
1.2 Funnel: Used to integrate multiple trace sources.
1.3 Sink: Used to store trace data.
2. Each hart requires one trace encoder.
3. When there are multiple trace sources, a trace funnel component
   is needed to integrate them. One trace funnel is required for
   each cluster.
4. When multiple trace funnels are fed into a single trace sink,
   multiple levels of trace funnels are required.
5. If there is only one cluster, the trace funnel (Level 0) can be
   connected directly to the trace sink.

Taking [cpu0]-->[encoder0]-->[funnel0]-->[sink0] as an example,
the DTS configuration is as follows:

    encoder0: trace_encoder@26001000 {
        compatible = "riscv_trace,encoder-controller";
        reg = <0x0 0x26001000 0x0 0x1000>;
        cpu = <&cpu0>;
        output_port {
            port0 {
                endpoint = <&funnel0>;
            };
        };
    };

    funnel0: trace_funnel@26404000 {
        compatible = "riscv_trace,funnel-controller";
        reg = <0x0 0x26404000 0x0 0x1000>;
        level = <1>;
        input_port {
            port0 {
                endpoint = <&encoder0>;
            };
        };
        output_port {
            port0 {
                endpoint = <&sink0>;
            };
        };
    };

    sink0: trace_sink@26401000 {
        compatible = "riscv_trace,sink-controller";
        reg = <0x0 0x26401000 0x0 0x1000>;
        input_port {
            port0 {
                endpoint = <&funnel0>;
            };
        };
    };

Note: The detailed property definition of each component will be
provided in the subsequent series of patches.

[1] https://github.com/riscv-non-isa/tg-nexus-trace.git

Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
 .../riscv/trace/riscv,trace,encoder.yaml      | 41 +++++++++++++++++
 .../riscv/trace/riscv,trace,funnel.yaml       | 46 +++++++++++++++++++
 .../riscv/trace/riscv,trace,sink.yaml         | 37 +++++++++++++++
 3 files changed, 124 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,encoder.yaml
 create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,funnel.yaml
 create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,sink.yaml

diff --git a/Documentation/devicetree/bindings/riscv/trace/riscv,trace,encoder.yaml b/Documentation/devicetree/bindings/riscv/trace/riscv,trace,encoder.yaml
new file mode 100644
index 000000000000..e2ec3ce514b2
--- /dev/null
+++ b/Documentation/devicetree/bindings/riscv/trace/riscv,trace,encoder.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/riscv/trace/riscv,trace,encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Trace Encoder Controller
+
+description: |
+  riscv trace encoder controller description.
+
+maintainers:
+  - Chen Pei <cp0613@linux.alibaba.com>
+
+properties:
+  compatible:
+    items:
+      - const: riscv_trace,encoder-controller
+  reg:
+    description: A memory region containing registers for encoder controller
+
+  cpu:
+    description: CPU identifier associated with this encoder
+
+  ports:
+    description: Output port definitions
+
+additionalProperties: true
+
+examples:
+  - |
+    encoder0: trace_encoder@26001000 {
+        compatible = "riscv_trace,encoder-controller";
+        reg = <0x0 0x26001000 0x0 0x1000>;
+        cpu = <&cpu0>;
+        output_port {
+            port0 {
+                endpoint = <&funnel0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/riscv/trace/riscv,trace,funnel.yaml b/Documentation/devicetree/bindings/riscv/trace/riscv,trace,funnel.yaml
new file mode 100644
index 000000000000..5da836997355
--- /dev/null
+++ b/Documentation/devicetree/bindings/riscv/trace/riscv,trace,funnel.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/riscv/trace/riscv,trace,funnel.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Trace Funnel Controller
+
+description: |
+  riscv trace funnel controller description.
+
+maintainers:
+  - Chen Pei <cp0613@linux.alibaba.com>
+
+properties:
+  compatible:
+    items:
+      - const: riscv_trace,funnel-controller
+  reg:
+    description: A memory region containing registers for funnel controller
+
+  ports:
+    description: Input/Output port definitions
+
+  level:
+    description: Level of the funnel (e.g., 1 means close to the encoder)
+
+additionalProperties: true
+
+examples:
+  - |
+    funnel0: trace_funnel@26404000 {
+        compatible = "riscv_trace,funnel-controller";
+        reg = <0x0 0x26404000 0x0 0x1000>;
+        level = <1>;
+        input_port {
+            port0 {
+                endpoint = <&encoder0>;
+            };
+        };
+        output_port {
+            port0 {
+                endpoint = <&sink0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/riscv/trace/riscv,trace,sink.yaml b/Documentation/devicetree/bindings/riscv/trace/riscv,trace,sink.yaml
new file mode 100644
index 000000000000..b42e65988f31
--- /dev/null
+++ b/Documentation/devicetree/bindings/riscv/trace/riscv,trace,sink.yaml
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/riscv/trace/riscv,trace,sink.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RISC-V Trace Sink Controller
+
+description: |
+  riscv trace sink controller description.
+
+maintainers:
+  - Chen Pei <cp0613@linux.alibaba.com>
+
+properties:
+  compatible:
+    items:
+      - const: riscv_trace,sink-controller
+  reg:
+    description: A memory region containing registers for sink controller
+
+  ports:
+    description: Input port definitions
+
+additionalProperties: true
+
+examples:
+  - |
+    sink0: trace_sink@26401000 {
+        compatible = "riscv_trace,sink-controller";
+        reg = <0x0 0x26401000 0x0 0x1000>;
+        input_port {
+            port0 {
+                endpoint = <&funnel0>;
+            };
+        };
+    };
-- 
2.49.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 2/4] riscv: event: Initial riscv trace driver support
  2025-09-11 12:44 [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support cp0613
  2025-09-11 12:44 ` [RFC PATCH 1/4] dt-bindings: riscv: Add trace components description cp0613
@ 2025-09-11 12:44 ` cp0613
  2025-09-11 12:44 ` [RFC PATCH 3/4] tools: perf: Support perf record with aux buffer for riscv trace cp0613
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: cp0613 @ 2025-09-11 12:44 UTC (permalink / raw)
  To: paul.walmsley, palmer, aou, alex, guoren
  Cc: linux-riscv, linux-kernel, Chen Pei

From: Chen Pei <cp0613@linux.alibaba.com>

This patch implements the riscv trace perf driver. It's suitable
for RISC-V processors that implement the trace specification
(N-Trace or E-Trace). Users can specify the riscv_trace driver
through the perf program.

The driver adds two format attributes, start_addr and stop_addr,
to specify the valid instruction range for tracing. It also
supports specifying the priv_mode (user and kernel) to specify
the valid privilege mode for tracing.

The reference commands are as follows:

  cat /sys/bus/event_source/devices/riscv_trace/format/*
  perf record -e riscv_trace// ls
  perf record -e riscv_trace/start_addr=0x1234,stop_addr=0x5678/ ls
  perf record -e riscv_trace/start_addr=0x1234,stop_addr=0x5678/k ls
  perf report -D

Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
 arch/riscv/Kbuild                       |   1 +
 arch/riscv/Kconfig                      |   2 +
 arch/riscv/events/Kconfig               |  11 ++
 arch/riscv/events/Makefile              |   3 +
 arch/riscv/events/riscv_trace.c         | 145 +++++++++++++++++++++
 arch/riscv/events/riscv_trace.h         | 123 ++++++++++++++++++
 arch/riscv/events/riscv_trace_encoder.c | 109 ++++++++++++++++
 arch/riscv/events/riscv_trace_funnel.c  | 160 ++++++++++++++++++++++++
 arch/riscv/events/riscv_trace_sink.c    | 100 +++++++++++++++
 9 files changed, 654 insertions(+)
 create mode 100644 arch/riscv/events/Kconfig
 create mode 100644 arch/riscv/events/Makefile
 create mode 100644 arch/riscv/events/riscv_trace.c
 create mode 100644 arch/riscv/events/riscv_trace.h
 create mode 100644 arch/riscv/events/riscv_trace_encoder.c
 create mode 100644 arch/riscv/events/riscv_trace_funnel.c
 create mode 100644 arch/riscv/events/riscv_trace_sink.c

diff --git a/arch/riscv/Kbuild b/arch/riscv/Kbuild
index 126fb738fc44..8107a614c428 100644
--- a/arch/riscv/Kbuild
+++ b/arch/riscv/Kbuild
@@ -4,6 +4,7 @@ obj-y += kernel/ mm/ net/
 obj-$(CONFIG_CRYPTO) += crypto/
 obj-y += errata/
 obj-$(CONFIG_KVM) += kvm/
+obj-$(CONFIG_PERF_EVENTS) += events/
 
 obj-$(CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY) += purgatory/
 
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 51dcd8eaa243..145d3424651b 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -1374,3 +1374,5 @@ endmenu # "CPU Power Management"
 source "arch/riscv/kvm/Kconfig"
 
 source "drivers/acpi/Kconfig"
+
+source "arch/riscv/events/Kconfig"
diff --git a/arch/riscv/events/Kconfig b/arch/riscv/events/Kconfig
new file mode 100644
index 000000000000..c6fb073b29b1
--- /dev/null
+++ b/arch/riscv/events/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+menu "Performance monitoring"
+
+config PERF_EVENTS_RISCV_TRACE
+	tristate "RISCV TRACE events"
+	depends on PERF_EVENTS && RISCV
+	default m
+	help
+	  Include support for riscv trace events.
+
+endmenu
diff --git a/arch/riscv/events/Makefile b/arch/riscv/events/Makefile
new file mode 100644
index 000000000000..5014de2847df
--- /dev/null
+++ b/arch/riscv/events/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PERF_EVENTS_RISCV_TRACE) += riscv_trace_pmu.o
+riscv_trace_pmu-objs := riscv_trace.o riscv_trace_encoder.o riscv_trace_funnel.o riscv_trace_sink.o
diff --git a/arch/riscv/events/riscv_trace.c b/arch/riscv/events/riscv_trace.c
new file mode 100644
index 000000000000..e408d9a4034a
--- /dev/null
+++ b/arch/riscv/events/riscv_trace.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt
+
+#include <linux/types.h>
+#include <linux/bits.h>
+#include <linux/limits.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/perf_event.h>
+
+#include "riscv_trace.h"
+
+LIST_HEAD(riscv_trace_controllers);
+static struct riscv_trace_pmu riscv_trace_pmu;
+
+PMU_FORMAT_ATTR(start_addr, "config:0-63");
+PMU_FORMAT_ATTR(stop_addr,  "config1:0-63");
+
+static struct attribute *riscv_trace_filter_attrs[] = {
+	&format_attr_start_addr.attr,
+	&format_attr_stop_addr.attr,
+	NULL,
+};
+
+static struct attribute_group riscv_trace_filter_attr_group = {
+	.name = "format",
+	.attrs = riscv_trace_filter_attrs,
+};
+
+static const struct attribute_group *riscv_trace_attr_groups[] = {
+	&riscv_trace_filter_attr_group,
+	NULL
+};
+
+static void riscv_trace_init_filter_attrs(struct perf_event *event)
+{
+	riscv_trace_pmu.filter_attr.start_addr = event->attr.config;
+	riscv_trace_pmu.filter_attr.stop_addr  = event->attr.config1;
+
+	if (event->attr.exclude_kernel)
+		riscv_trace_pmu.filter_attr.priv_mode =
+		    RISCV_TRACE_PRIV_MODE_EXCL_KERN;
+	else if (event->attr.exclude_user)
+		riscv_trace_pmu.filter_attr.priv_mode =
+		    RISCV_TRACE_PRIV_MODE_EXCL_USER;
+	else
+		riscv_trace_pmu.filter_attr.priv_mode =
+		    RISCV_TRACE_PRIV_MODE_EXCL_NONE;
+
+	pr_info("start_addr=0x%llx stop_addr=0x%llx priv_mode=%d\n",
+		riscv_trace_pmu.filter_attr.start_addr,
+		riscv_trace_pmu.filter_attr.stop_addr,
+		riscv_trace_pmu.filter_attr.priv_mode);
+}
+
+static int riscv_trace_event_init(struct perf_event *event)
+{
+	if (event->attr.type != riscv_trace_pmu.pmu.type)
+		return -ENOENT;
+
+	riscv_trace_init_filter_attrs(event);
+
+	return 0;
+}
+
+static int riscv_trace_event_add(struct perf_event *event, int flags)
+{
+	pr_info("%s:%d\n", __func__, __LINE__);
+	// TODO: Configuring the trace component
+	return 0;
+}
+
+static void riscv_trace_event_del(struct perf_event *event, int flags)
+{
+	// TODO: Reset the trace component
+	pr_info("%s:%d\n", __func__, __LINE__);
+}
+
+static void riscv_trace_event_start(struct perf_event *event, int flags)
+{
+	pr_info("%s:%d on_cpu=%d cpu=%d\n", __func__, __LINE__,
+		event->oncpu, event->cpu);
+	// TODO: Enable the trace component
+}
+
+static void riscv_trace_event_stop(struct perf_event *event, int flags)
+{
+	pr_info("%s:%d on_cpu=%d cpu=%d\n", __func__, __LINE__,
+		event->oncpu, event->cpu);
+	// TODO: Disable the trace component
+}
+
+static int __init riscv_trace_init(void)
+{
+	struct riscv_trace_component *component;
+
+	riscv_trace_encoder_init();
+	riscv_trace_funnel_init();
+	riscv_trace_sink_init();
+
+	if (get_list_count(&riscv_trace_controllers) == 0)
+		return -ENXIO;
+
+	list_for_each_entry(component, &riscv_trace_controllers, list) {
+		pr_info("type=%s in_num=%d out_num=%d\n",
+			riscv_trace_type2str(component->type),
+			component->in_num, component->out_num);
+		for (int i = 0; i < component->in_num; i++) {
+			pr_info("\t in[%d] type=%s base_addr=0x%llx\n", i,
+				riscv_trace_type2str(component->in[i]->type),
+				component->in[i]->base_addr);
+		}
+		for (int j = 0; j < component->out_num; j++) {
+			pr_info("\t out[%d] type=%s base_addr=0x%llx\n", j,
+				riscv_trace_type2str(component->out[j]->type),
+				component->out[j]->base_addr);
+		}
+	}
+
+	riscv_trace_pmu.pmu.module       = THIS_MODULE,
+	riscv_trace_pmu.pmu.name         = "riscv_trace",
+	riscv_trace_pmu.pmu.capabilities = PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE;
+	riscv_trace_pmu.pmu.attr_groups  = riscv_trace_attr_groups;
+	riscv_trace_pmu.pmu.task_ctx_nr  = perf_sw_context,
+	riscv_trace_pmu.pmu.event_init   = riscv_trace_event_init;
+	riscv_trace_pmu.pmu.add          = riscv_trace_event_add;
+	riscv_trace_pmu.pmu.del          = riscv_trace_event_del;
+	riscv_trace_pmu.pmu.start        = riscv_trace_event_start;
+	riscv_trace_pmu.pmu.stop         = riscv_trace_event_stop;
+
+	return perf_pmu_register(&riscv_trace_pmu.pmu, "riscv_trace", -1);
+}
+
+static void __exit riscv_trace_exit(void)
+{
+	perf_pmu_unregister(&riscv_trace_pmu.pmu);
+}
+
+module_init(riscv_trace_init);
+module_exit(riscv_trace_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Chen Pei <cp0613@linux.alibaba.com>");
+MODULE_DESCRIPTION("Driver for RISC-V Trace Device");
diff --git a/arch/riscv/events/riscv_trace.h b/arch/riscv/events/riscv_trace.h
new file mode 100644
index 000000000000..ef0af0d0b2ee
--- /dev/null
+++ b/arch/riscv/events/riscv_trace.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __RISCV_TRACE_H__
+#define __RISCV_TRACE_H__
+
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/types.h>
+#include <linux/perf_event.h>
+
+#define RISCV_TRACE_ADDR_MASK GENMASK(63, 0)
+
+enum RISCV_TRACE_COMPONENT_TYPE {
+	RISCV_TRACE_ENCODER = 0,
+	RISCV_TRACE_FUNNEL,
+	RISCV_TRACE_SINK,
+};
+
+enum RISCV_TRACE_FUNNEL_LEVEL {
+	LEVEL1_FUNNEL = 1,
+	LEVEL2_FUNNEL = 2,
+};
+
+enum RISCV_TRACE_PRIV_MODE_TYPE {
+	RISCV_TRACE_PRIV_MODE_EXCL_NONE = 0,
+	RISCV_TRACE_PRIV_MODE_EXCL_KERN,
+	RISCV_TRACE_PRIV_MODE_EXCL_USER,
+};
+
+struct riscv_trace_filter_attr {
+	u64 start_addr;
+	u64 stop_addr;
+	u32 priv_mode;		// user&kernel
+};
+
+struct riscv_io_port {
+	bool is_input;		// input=1, output=0
+	u32 endpoint_num;
+	enum RISCV_TRACE_COMPONENT_TYPE type;
+	u64 base_addr;
+};
+
+struct riscv_trace_encoder {
+	u32 cpu;
+};
+
+struct riscv_trace_funnel {
+	enum RISCV_TRACE_FUNNEL_LEVEL level;
+};
+
+struct riscv_trace_sink {
+	;
+};
+
+struct riscv_trace_component {
+	enum RISCV_TRACE_COMPONENT_TYPE type;
+	u64 reg_base;
+	u64 reg_size;
+	struct list_head list;
+
+	union {
+		struct riscv_trace_encoder encoder;
+		struct riscv_trace_funnel funnel;
+		struct riscv_trace_sink sink;
+	};
+
+	u32 in_num;
+	u32 out_num;
+	struct riscv_io_port **in;
+	struct riscv_io_port **out;
+};
+
+extern struct list_head riscv_trace_controllers;
+
+struct riscv_trace_pmu {
+	struct pmu pmu;
+	struct riscv_trace_filter_attr filter_attr;
+};
+
+static inline const char *riscv_trace_type2str(enum RISCV_TRACE_COMPONENT_TYPE
+					       type)
+{
+	switch (type) {
+	case RISCV_TRACE_ENCODER:
+		return "encoder";
+	case RISCV_TRACE_FUNNEL:
+		return "funnel";
+	case RISCV_TRACE_SINK:
+		return "sink";
+	default:
+		return "none";
+	}
+}
+
+static inline int count_device_node_child(struct device_node *parent)
+{
+	struct device_node *child;
+	int count = 0;
+
+	for_each_child_of_node(parent, child) {
+		count++;
+	}
+
+	return count;
+}
+
+static inline int get_list_count(struct list_head *head)
+{
+	u32 count = 0;
+	struct list_head *pos;
+
+	list_for_each(pos, head) {
+		count++;
+	}
+
+	return count;
+}
+
+int riscv_trace_encoder_init(void);
+int riscv_trace_funnel_init(void);
+int riscv_trace_sink_init(void);
+
+#endif /* __RISCV_TRACE_H__ */
diff --git a/arch/riscv/events/riscv_trace_encoder.c b/arch/riscv/events/riscv_trace_encoder.c
new file mode 100644
index 000000000000..fb2c37c3561a
--- /dev/null
+++ b/arch/riscv/events/riscv_trace_encoder.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt
+
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
+
+#include "riscv_trace.h"
+
+static const struct of_device_id riscv_trace_encoder_of_match[] = {
+	{.compatible = "riscv_trace,encoder-controller", },
+	{ },
+};
+
+int riscv_trace_encoder_init(void)
+{
+	struct riscv_trace_component *component;
+	struct device_node *node, *child_node, *port_node;
+	struct riscv_io_port *io_port;
+	resource_size_t base, size;
+	u32 reg[4];
+	int port_nr;
+	int ret;
+
+	for_each_matching_node(node, riscv_trace_encoder_of_match) {
+		if (!of_device_is_available(node)) {
+			of_node_put(node);
+			continue;
+		}
+
+		component = kzalloc(sizeof(*component), GFP_KERNEL);
+		if (!component)
+			return -ENOMEM;
+		component->type = RISCV_TRACE_ENCODER;
+
+		ret = of_property_read_u32_array(node, "reg", &reg[0], 4);
+		if (ret) {
+			pr_err("Failed to read 'reg'\n");
+			of_node_put(node);
+			return ret;
+		}
+		base = ((resource_size_t) reg[0] << 32) | reg[1];
+		size = ((resource_size_t) reg[2] << 32) | reg[3];
+		pr_info("base=0x%llx size=0x%llx\n", base, size);
+		component->reg_base = (u64)ioremap(base, size);
+		component->reg_size = size;
+		pr_info("reg_base=0x%llx reg_size=0x%llx\n",
+			component->reg_base, component->reg_size);
+
+		ret =
+		    of_property_read_u32(node, "cpu", &component->encoder.cpu);
+		if (ret) {
+			pr_err("Failed to read 'cpu'\n");
+			of_node_put(node);
+			return ret;
+		}
+		pr_info("cpu=%d\n", component->encoder.cpu);
+
+		child_node = of_get_child_by_name(node, "output_port");
+		if (!child_node) {
+			pr_err("Failed to find 'output_port'\n");
+			of_node_put(node);
+			return -ENODEV;
+		}
+		component->out_num = count_device_node_child(child_node);
+		if (component->out_num) {
+			component->out =
+			    krealloc_array(component->out, component->out_num,
+					   sizeof(*component->out), GFP_KERNEL);
+			if (!component->out)
+				return -ENOMEM;
+			port_nr = 0;
+
+			for_each_child_of_node(child_node, port_node) {
+				if (!of_device_is_available(port_node)) {
+					of_node_put(child_node);
+					continue;
+				}
+				pr_info("Found output_port: %pOF\n", port_node);
+				const struct device_node *endpoint_node =
+				    of_parse_phandle(port_node, "endpoint", 0);
+				pr_info("\t endpoint: %pOF\n", endpoint_node);
+
+				of_property_read_u32_array((struct device_node
+							    *)endpoint_node,
+							   "reg", &reg[0], 4);
+
+				io_port =
+				    kmalloc(sizeof(struct riscv_io_port),
+					    GFP_KERNEL);
+				io_port->is_input = false;
+				io_port->endpoint_num = port_nr;
+				io_port->type = RISCV_TRACE_FUNNEL;
+				io_port->base_addr =
+				    ((u64) reg[0] << 32) | reg[1];
+				component->out[port_nr] = io_port;
+				port_nr++;
+			}
+		}
+
+		INIT_LIST_HEAD(&component->list);
+		list_add_tail(&component->list, &riscv_trace_controllers);
+	}
+
+	return ret;
+}
diff --git a/arch/riscv/events/riscv_trace_funnel.c b/arch/riscv/events/riscv_trace_funnel.c
new file mode 100644
index 000000000000..c6d412fd1f90
--- /dev/null
+++ b/arch/riscv/events/riscv_trace_funnel.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt
+
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
+
+#include "riscv_trace.h"
+
+static const struct of_device_id riscv_trace_funnel_of_match[] = {
+	{.compatible = "riscv_trace,funnel-controller", },
+	{ },
+};
+
+int riscv_trace_funnel_init(void)
+{
+	struct riscv_trace_component *component;
+	struct device_node *node, *child_node, *port_node;
+	struct riscv_io_port *io_port;
+	resource_size_t base, size;
+	u32 reg[4];
+	int port_nr;
+	int ret;
+
+	for_each_matching_node(node, riscv_trace_funnel_of_match) {
+		if (!of_device_is_available(node)) {
+			of_node_put(node);
+			continue;
+		}
+
+		component = kzalloc(sizeof(*component), GFP_KERNEL);
+		if (!component)
+			return -ENOMEM;
+		component->type = RISCV_TRACE_FUNNEL;
+
+		ret = of_property_read_u32_array(node, "reg", &reg[0], 4);
+		if (ret) {
+			pr_err("Failed to read 'reg'\n");
+			of_node_put(node);
+			return ret;
+		}
+		base = ((resource_size_t) reg[0] << 32) | reg[1];
+		size = ((resource_size_t) reg[2] << 32) | reg[3];
+		pr_info("base=0x%llx size=0x%llx\n", base, size);
+		component->reg_base = (u64)ioremap(base, size);
+		component->reg_size = size;
+		pr_info("reg_base=0x%llx reg_size=0x%llx\n",
+			component->reg_base, component->reg_size);
+
+		ret =
+		    of_property_read_u32(node, "level",
+					 &component->funnel.level);
+		if (ret)
+			component->funnel.level = LEVEL1_FUNNEL;
+		pr_info("funnel level=%d\n", component->funnel.level);
+
+		child_node = of_get_child_by_name(node, "input_port");
+		if (!child_node) {
+			pr_err("Failed to find 'input_port'\n");
+			of_node_put(node);
+			return -ENODEV;
+		}
+		component->in_num = count_device_node_child(child_node);
+		if (component->in_num) {
+			component->in =
+			    krealloc_array(component->in, component->in_num,
+					   sizeof(*component->in), GFP_KERNEL);
+			if (!component->in)
+				return -ENOMEM;
+			port_nr = 0;
+
+			for_each_child_of_node(child_node, port_node) {
+				if (!of_device_is_available(port_node)) {
+					of_node_put(child_node);
+					continue;
+				}
+				pr_info("Found input_port: %pOF\n", port_node);
+				const struct device_node *endpoint_node =
+				    of_parse_phandle(port_node, "endpoint", 0);
+				pr_info("\t endpoint: %pOF\n", endpoint_node);
+
+				of_property_read_u32_array((struct device_node
+							    *)endpoint_node,
+							   "reg", &reg[0], 4);
+
+				io_port =
+				    kmalloc(sizeof(struct riscv_io_port),
+					    GFP_KERNEL);
+				io_port->is_input = true;
+				io_port->endpoint_num = port_nr;
+				io_port->type = RISCV_TRACE_ENCODER;
+				io_port->base_addr =
+				    ((u64) reg[0] << 32) | reg[1];
+				component->in[port_nr] = io_port;
+				port_nr++;
+			}
+		}
+
+		child_node = of_get_child_by_name(node, "output_port");
+		if (!child_node) {
+			pr_err("Failed to find 'output_port'\n");
+			of_node_put(node);
+			return -ENODEV;
+		}
+		component->out_num = count_device_node_child(child_node);
+		if (component->out_num) {
+			component->out =
+			    krealloc_array(component->out, component->out_num,
+					   sizeof(*component->out), GFP_KERNEL);
+			if (!component->out)
+				return -ENOMEM;
+			port_nr = 0;
+
+			for_each_child_of_node(child_node, port_node) {
+				if (!of_device_is_available(port_node)) {
+					of_node_put(child_node);
+					continue;
+				}
+				pr_info("Found output_port: %pOF\n", port_node);
+				const struct device_node *endpoint_node =
+				    of_parse_phandle(port_node, "endpoint", 0);
+				pr_info("\t endpoint: %pOF\n", endpoint_node);
+
+				of_property_read_u32_array((struct device_node
+							    *)endpoint_node,
+							   "reg", &reg[0], 4);
+
+				io_port =
+				    kmalloc(sizeof(struct riscv_io_port),
+					    GFP_KERNEL);
+				io_port->is_input = false;
+				io_port->endpoint_num = port_nr;
+				io_port->type = RISCV_TRACE_SINK;
+				io_port->base_addr =
+				    ((u64) reg[0] << 32) | reg[1];
+				component->out[port_nr] = io_port;
+				port_nr++;
+			}
+		}
+
+		for (int i = 0; i < component->in_num; i++) {
+			pr_info("\t in[%d]is_input=%d endpoint_num=%d\n", i,
+				component->in[i]->is_input,
+				component->in[i]->endpoint_num);
+		}
+		for (int j = 0; j < component->out_num; j++) {
+			pr_info("\t out[%d]is_input=%d endpoint_num=%d\n", j,
+				component->out[j]->is_input,
+				component->out[j]->endpoint_num);
+		}
+
+		INIT_LIST_HEAD(&component->list);
+		list_add_tail(&component->list, &riscv_trace_controllers);
+	}
+
+	return ret;
+}
diff --git a/arch/riscv/events/riscv_trace_sink.c b/arch/riscv/events/riscv_trace_sink.c
new file mode 100644
index 000000000000..dbdc153d798c
--- /dev/null
+++ b/arch/riscv/events/riscv_trace_sink.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) KBUILD_BASENAME ": " fmt
+
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
+
+#include "riscv_trace.h"
+
+static const struct of_device_id riscv_trace_sink_of_match[] = {
+	{.compatible = "riscv_trace,sink-controller", },
+	{ },
+};
+
+int riscv_trace_sink_init(void)
+{
+	struct riscv_trace_component *component;
+	struct device_node *node, *child_node, *port_node;
+	struct riscv_io_port *io_port;
+	resource_size_t base, size;
+	u32 reg[4];
+	int port_nr;
+	int ret;
+
+	for_each_matching_node(node, riscv_trace_sink_of_match) {
+		if (!of_device_is_available(node)) {
+			of_node_put(node);
+			continue;
+		}
+
+		component = kzalloc(sizeof(*component), GFP_KERNEL);
+		if (!component)
+			return -ENOMEM;
+		component->type = RISCV_TRACE_SINK;
+
+		ret = of_property_read_u32_array(node, "reg", &reg[0], 4);
+		if (ret) {
+			pr_err("Failed to read 'reg'\n");
+			of_node_put(node);
+			return ret;
+		}
+		base = ((resource_size_t) reg[0] << 32) | reg[1];
+		size = ((resource_size_t) reg[2] << 32) | reg[3];
+		pr_info("base=0x%llx size=0x%llx\n", base, size);
+		component->reg_base = (u64)ioremap(base, size);
+		component->reg_size = size;
+		pr_info("reg_base=0x%llx reg_size=0x%llx\n",
+			component->reg_base, component->reg_size);
+
+		child_node = of_get_child_by_name(node, "input_port");
+		if (!child_node) {
+			pr_err("Failed to find 'input_port'\n");
+			of_node_put(node);
+			return -ENODEV;
+		}
+		component->in_num = count_device_node_child(child_node);
+		if (component->in_num) {
+			component->in =
+			    krealloc_array(component->in, component->in_num,
+					   sizeof(*component->in), GFP_KERNEL);
+			if (!component->in)
+				return -ENOMEM;
+			port_nr = 0;
+
+			for_each_child_of_node(child_node, port_node) {
+				if (!of_device_is_available(port_node)) {
+					of_node_put(child_node);
+					continue;
+				}
+				pr_info("Found input_port: %pOF\n", port_node);
+				const struct device_node *endpoint_node =
+				    of_parse_phandle(port_node, "endpoint", 0);
+				pr_info("\t endpoint: %pOF\n", endpoint_node);
+
+				of_property_read_u32_array((struct device_node
+							    *)endpoint_node,
+							   "reg", &reg[0], 4);
+
+				io_port =
+				    kmalloc(sizeof(struct riscv_io_port),
+					    GFP_KERNEL);
+				io_port->is_input = true;
+				io_port->endpoint_num = port_nr;
+				io_port->type = RISCV_TRACE_FUNNEL;
+				io_port->base_addr =
+				    ((u64) reg[0] << 32) | reg[1];
+				component->in[port_nr] = io_port;
+				port_nr++;
+			}
+		}
+
+		INIT_LIST_HEAD(&component->list);
+		list_add_tail(&component->list, &riscv_trace_controllers);
+	}
+
+	return ret;
+}
-- 
2.49.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 3/4] tools: perf: Support perf record with aux buffer for riscv trace
  2025-09-11 12:44 [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support cp0613
  2025-09-11 12:44 ` [RFC PATCH 1/4] dt-bindings: riscv: Add trace components description cp0613
  2025-09-11 12:44 ` [RFC PATCH 2/4] riscv: event: Initial riscv trace driver support cp0613
@ 2025-09-11 12:44 ` cp0613
  2025-09-11 12:44 ` [RFC PATCH 4/4] riscv: trace: Support sink using dma buffer cp0613
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: cp0613 @ 2025-09-11 12:44 UTC (permalink / raw)
  To: paul.walmsley, palmer, aou, alex, guoren
  Cc: linux-riscv, linux-kernel, Chen Pei

From: Chen Pei <cp0613@linux.alibaba.com>

This patch implements AUXTRACE support for RISC-V Trace. The
corresponding driver needs to implement the setup_aux and free_aux
PMU driver ops.

The aux buffer is a type of ring buffer used in trace scenarios,
and RISC-V Trace should also reuse this capability.

Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
 arch/riscv/events/riscv_trace.c          |  61 ++++++++
 arch/riscv/events/riscv_trace.h          |   8 +
 tools/perf/arch/riscv/util/Build         |   3 +
 tools/perf/arch/riscv/util/auxtrace.c    |  33 ++++
 tools/perf/arch/riscv/util/pmu.c         |  18 +++
 tools/perf/arch/riscv/util/riscv-trace.c | 183 +++++++++++++++++++++++
 tools/perf/arch/riscv/util/tsc.c         |  15 ++
 tools/perf/util/Build                    |   1 +
 tools/perf/util/auxtrace.c               |   4 +
 tools/perf/util/auxtrace.h               |   1 +
 tools/perf/util/riscv-trace.c            | 162 ++++++++++++++++++++
 tools/perf/util/riscv-trace.h            |  18 +++
 12 files changed, 507 insertions(+)
 create mode 100644 tools/perf/arch/riscv/util/auxtrace.c
 create mode 100644 tools/perf/arch/riscv/util/pmu.c
 create mode 100644 tools/perf/arch/riscv/util/riscv-trace.c
 create mode 100644 tools/perf/arch/riscv/util/tsc.c
 create mode 100644 tools/perf/util/riscv-trace.c
 create mode 100644 tools/perf/util/riscv-trace.h

diff --git a/arch/riscv/events/riscv_trace.c b/arch/riscv/events/riscv_trace.c
index e408d9a4034a..3ac4a3be5d3e 100644
--- a/arch/riscv/events/riscv_trace.c
+++ b/arch/riscv/events/riscv_trace.c
@@ -8,6 +8,7 @@
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/perf_event.h>
+#include <linux/vmalloc.h>
 
 #include "riscv_trace.h"
 
@@ -81,6 +82,9 @@ static void riscv_trace_event_start(struct perf_event *event, int flags)
 {
 	pr_info("%s:%d on_cpu=%d cpu=%d\n", __func__, __LINE__,
 		event->oncpu, event->cpu);
+	// TODO: Begin aux buffer
+	// struct xuantie_ntrace_aux_buf *buf;
+	// buf = perf_aux_output_begin(&riscv_trace_pmu.handle, event);
 	// TODO: Enable the trace component
 }
 
@@ -89,6 +93,61 @@ static void riscv_trace_event_stop(struct perf_event *event, int flags)
 	pr_info("%s:%d on_cpu=%d cpu=%d\n", __func__, __LINE__,
 		event->oncpu, event->cpu);
 	// TODO: Disable the trace component
+	// TODO: End aux buffer
+	// struct xuantie_ntrace_aux_buf *buf;
+	// buf = perf_get_aux(&riscv_trace_pmu.handle);
+	// Fill aux buffer
+	// perf_aux_output_end(&riscv_trace_pmu.handle, size);
+}
+
+static void *riscv_trace_buffer_setup_aux(struct perf_event *event, void **pages,
+					 int nr_pages, bool overwrite)
+{
+	struct riscv_trace_aux_buf *buf;
+	struct page **pagelist;
+	int i;
+
+	if (overwrite) {
+		pr_warn("Overwrite mode is not supported\n");
+		return NULL;
+	}
+
+	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		return NULL;
+
+	pagelist = kcalloc(nr_pages, sizeof(*pagelist), GFP_KERNEL);
+	if (!pagelist)
+		goto err;
+
+	for (i = 0; i < nr_pages; i++)
+		pagelist[i] = virt_to_page(pages[i]);
+
+	buf->base = vmap(pagelist, nr_pages, VM_MAP, PAGE_KERNEL);
+	if (!buf->base) {
+		kfree(pagelist);
+		goto err;
+	}
+
+	buf->nr_pages = nr_pages;
+	buf->length = nr_pages * PAGE_SIZE;
+	buf->pos = 0;
+
+	pr_info("nr_pages=%d length=%d\n", buf->nr_pages, buf->length);
+
+	kfree(pagelist);
+	return buf;
+err:
+	kfree(buf);
+	return NULL;
+}
+
+static void riscv_trace_buffer_free_aux(void *aux)
+{
+	struct riscv_trace_aux_buf *buf = aux;
+
+	vunmap(buf->base);
+	kfree(buf);
 }
 
 static int __init riscv_trace_init(void)
@@ -128,6 +187,8 @@ static int __init riscv_trace_init(void)
 	riscv_trace_pmu.pmu.del          = riscv_trace_event_del;
 	riscv_trace_pmu.pmu.start        = riscv_trace_event_start;
 	riscv_trace_pmu.pmu.stop         = riscv_trace_event_stop;
+	riscv_trace_pmu.pmu.setup_aux    = riscv_trace_buffer_setup_aux;
+	riscv_trace_pmu.pmu.free_aux     = riscv_trace_buffer_free_aux;
 
 	return perf_pmu_register(&riscv_trace_pmu.pmu, "riscv_trace", -1);
 }
diff --git a/arch/riscv/events/riscv_trace.h b/arch/riscv/events/riscv_trace.h
index ef0af0d0b2ee..c28216227006 100644
--- a/arch/riscv/events/riscv_trace.h
+++ b/arch/riscv/events/riscv_trace.h
@@ -75,6 +75,14 @@ extern struct list_head riscv_trace_controllers;
 struct riscv_trace_pmu {
 	struct pmu pmu;
 	struct riscv_trace_filter_attr filter_attr;
+	struct perf_output_handle handle;
+};
+
+struct riscv_trace_aux_buf {
+	u32 length;
+	u32 nr_pages;
+	void *base;
+	u32 pos;
 };
 
 static inline const char *riscv_trace_type2str(enum RISCV_TRACE_COMPONENT_TYPE
diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
index 58a672246024..d1599b70ef2f 100644
--- a/tools/perf/arch/riscv/util/Build
+++ b/tools/perf/arch/riscv/util/Build
@@ -1,5 +1,8 @@
 perf-util-y += perf_regs.o
 perf-util-y += header.o
+perf-util-y += tsc.o
 
 perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o
 perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
+
+perf-util-$(CONFIG_AUXTRACE) += pmu.o auxtrace.o riscv-trace.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..51c8dac5ff61
--- /dev/null
+++ b/tools/perf/arch/riscv/util/auxtrace.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dirent.h>
+#include <stdbool.h>
+#include <linux/zalloc.h>
+#include <api/fs/fs.h>
+
+#include "../../../util/auxtrace.h"
+#include "../../../util/debug.h"
+#include "../../../util/evlist.h"
+#include "../../../util/pmu.h"
+#include "../../../util/pmus.h"
+#include "riscv-trace.h"
+
+struct auxtrace_record
+*auxtrace_record__init(struct evlist *evlist, int *err)
+{
+	struct perf_pmu	*riscv_trace_pmu = NULL;
+	struct evsel *evsel;
+	bool found_riscv_trace = false;
+
+	riscv_trace_pmu = perf_pmus__find(RISCV_TRACE_PMU_NAME);
+
+	evlist__for_each_entry(evlist, evsel) {
+		if (riscv_trace_pmu && evsel->core.attr.type == riscv_trace_pmu->type)
+			found_riscv_trace = true;
+	}
+
+	if (found_riscv_trace)
+		return riscv_trace_recording_init(err, riscv_trace_pmu);
+
+	return NULL;
+}
diff --git a/tools/perf/arch/riscv/util/pmu.c b/tools/perf/arch/riscv/util/pmu.c
new file mode 100644
index 000000000000..921b083c4f6b
--- /dev/null
+++ b/tools/perf/arch/riscv/util/pmu.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <string.h>
+#include <linux/perf_event.h>
+#include <linux/string.h>
+
+#include "riscv-trace.h"
+#include "../../../util/pmu.h"
+
+void perf_pmu__arch_init(struct perf_pmu *pmu)
+{
+#ifdef HAVE_AUXTRACE_SUPPORT
+	if (!strcmp(pmu->name, RISCV_TRACE_PMU_NAME)) {
+		pmu->auxtrace = true;
+		pmu->selectable = true;
+	}
+#endif
+}
diff --git a/tools/perf/arch/riscv/util/riscv-trace.c b/tools/perf/arch/riscv/util/riscv-trace.c
new file mode 100644
index 000000000000..0632f1f43c15
--- /dev/null
+++ b/tools/perf/arch/riscv/util/riscv-trace.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/log2.h>
+#include <linux/zalloc.h>
+#include <time.h>
+
+#include <internal/lib.h> // 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/pmu.h"
+#include "../../../util/record.h"
+#include "../../../util/session.h"
+#include "../../../util/tsc.h"
+#include "../../../util/riscv-trace.h"
+
+#define KiB(x) ((x) * 1024)
+#define MiB(x) ((x) * 1024 * 1024)
+
+struct riscv_trace_recording {
+	struct auxtrace_record	itr;
+	struct perf_pmu *riscv_trace_pmu;
+	struct evlist *evlist;
+};
+
+static size_t
+riscv_trace_info_priv_size(struct auxtrace_record *itr __maybe_unused,
+			struct evlist *evlist __maybe_unused)
+{
+	return RISCV_TRACE_AUXTRACE_PRIV_SIZE;
+}
+
+static int riscv_trace_info_fill(struct auxtrace_record *itr,
+			      struct perf_session *session,
+			      struct perf_record_auxtrace_info *auxtrace_info,
+			      size_t priv_size)
+{
+	struct riscv_trace_recording *pttr =
+			container_of(itr, struct riscv_trace_recording, itr);
+	struct perf_pmu *riscv_trace_pmu = pttr->riscv_trace_pmu;
+
+	if (priv_size != RISCV_TRACE_AUXTRACE_PRIV_SIZE)
+		return -EINVAL;
+
+	if (!session->evlist->core.nr_mmaps)
+		return -EINVAL;
+
+	auxtrace_info->type = PERF_AUXTRACE_RISCV_TRACE;
+	auxtrace_info->priv[0] = riscv_trace_pmu->type;
+
+	return 0;
+}
+
+static int riscv_trace_set_auxtrace_mmap_page(struct record_opts *opts)
+{
+	bool privileged = 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 = MiB(16) / page_size;
+		} else {
+			opts->auxtrace_mmap_pages = KiB(128) / page_size;
+			if (opts->mmap_pages == UINT_MAX)
+				opts->mmap_pages = KiB(256) / page_size;
+		}
+	}
+
+	/* Validate auxtrace_mmap_pages */
+	if (opts->auxtrace_mmap_pages) {
+		size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
+		size_t min_sz = KiB(8);
+
+		if (sz < min_sz || !is_power_of_2(sz)) {
+			pr_err("Invalid mmap size for riscv trace: must be at least %zuKiB and a power of 2\n",
+			       min_sz / 1024);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int riscv_trace_recording_options(struct auxtrace_record *itr,
+				      struct evlist *evlist,
+				      struct record_opts *opts)
+{
+	struct riscv_trace_recording *pttr =
+			container_of(itr, struct riscv_trace_recording, itr);
+	struct perf_pmu *riscv_trace_pmu = pttr->riscv_trace_pmu;
+	struct evsel *evsel, *riscv_trace_evsel = NULL;
+	struct evsel *tracking_evsel;
+	int err;
+
+	pttr->evlist = evlist;
+	evlist__for_each_entry(evlist, evsel) {
+		if (evsel->core.attr.type == riscv_trace_pmu->type) {
+			if (riscv_trace_evsel) {
+				pr_err("There may be only one " RISCV_TRACE_PMU_NAME "x event\n");
+				return -EINVAL;
+			}
+			evsel->core.attr.freq = 0;
+			evsel->core.attr.sample_period = 1;
+			evsel->needs_auxtrace_mmap = true;
+			riscv_trace_evsel = evsel;
+			opts->full_auxtrace = true;
+		}
+	}
+
+	err = riscv_trace_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, riscv_trace_evsel);
+	evsel__set_sample_bit(riscv_trace_evsel, TIME);
+
+	/* Add dummy event to keep tracking */
+	err = parse_event(evlist, "dummy:u");
+	if (err)
+		return err;
+
+	tracking_evsel = evlist__last(evlist);
+	evlist__set_tracking_event(evlist, tracking_evsel);
+
+	tracking_evsel->core.attr.freq = 0;
+	tracking_evsel->core.attr.sample_period = 1;
+	evsel__set_sample_bit(tracking_evsel, TIME);
+
+	return 0;
+}
+
+static u64 riscv_trace_reference(struct auxtrace_record *itr __maybe_unused)
+{
+	return rdtsc();
+}
+
+static void riscv_trace_recording_free(struct auxtrace_record *itr)
+{
+	struct riscv_trace_recording *pttr =
+			container_of(itr, struct riscv_trace_recording, itr);
+
+	free(pttr);
+}
+
+struct auxtrace_record *riscv_trace_recording_init(int *err,
+						struct perf_pmu *riscv_trace_pmu)
+{
+	struct riscv_trace_recording *pttr;
+
+	if (!riscv_trace_pmu) {
+		*err = -ENODEV;
+		return NULL;
+	}
+
+	pttr = zalloc(sizeof(*pttr));
+	if (!pttr) {
+		*err = -ENOMEM;
+		return NULL;
+	}
+
+	pttr->riscv_trace_pmu = riscv_trace_pmu;
+	pttr->itr.recording_options = riscv_trace_recording_options;
+	pttr->itr.info_priv_size = riscv_trace_info_priv_size;
+	pttr->itr.info_fill = riscv_trace_info_fill;
+	pttr->itr.free = riscv_trace_recording_free;
+	pttr->itr.reference = riscv_trace_reference;
+	pttr->itr.read_finish = auxtrace_record__read_finish;
+	pttr->itr.alignment = 0;
+
+	*err = 0;
+	return &pttr->itr;
+}
diff --git a/tools/perf/arch/riscv/util/tsc.c b/tools/perf/arch/riscv/util/tsc.c
new file mode 100644
index 000000000000..cf021e423f79
--- /dev/null
+++ b/tools/perf/arch/riscv/util/tsc.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/types.h>
+
+#include "../../../util/tsc.h"
+
+u64 rdtsc(void)
+{
+	u64 val;
+
+	// https://lore.kernel.org/all/YxIzgYP3MujXdqwj@aurel32.net/T/
+	asm volatile("rdtime %0" : "=r"(val));
+
+	return val;
+}
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 4959e7a990e4..4726a100a156 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -136,6 +136,7 @@ perf-util-$(CONFIG_AUXTRACE) += arm-spe-decoder/
 perf-util-$(CONFIG_AUXTRACE) += hisi-ptt.o
 perf-util-$(CONFIG_AUXTRACE) += hisi-ptt-decoder/
 perf-util-$(CONFIG_AUXTRACE) += s390-cpumsf.o
+perf-util-$(CONFIG_AUXTRACE) += riscv-trace.o
 
 ifdef CONFIG_LIBOPENCSD
 perf-util-$(CONFIG_AUXTRACE) += cs-etm.o
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index ebd32f1b8f12..b4d8f3c5ebb1 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 "riscv-trace.h"
 #include "util/mmap.h"
 
 #include <linux/ctype.h>
@@ -1393,6 +1394,9 @@ int perf_event__process_auxtrace_info(struct perf_session *session,
 	case PERF_AUXTRACE_HISI_PTT:
 		err = hisi_ptt_process_auxtrace_info(event, session);
 		break;
+	case PERF_AUXTRACE_RISCV_TRACE:
+		err = riscv_trace_process_auxtrace_info(event, session);
+		break;
 	case PERF_AUXTRACE_UNKNOWN:
 	default:
 		return -EINVAL;
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index f001cbb68f8e..5b7ce4a99709 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -50,6 +50,7 @@ enum auxtrace_type {
 	PERF_AUXTRACE_ARM_SPE,
 	PERF_AUXTRACE_S390_CPUMSF,
 	PERF_AUXTRACE_HISI_PTT,
+	PERF_AUXTRACE_RISCV_TRACE,
 };
 
 enum itrace_period_type {
diff --git a/tools/perf/util/riscv-trace.c b/tools/perf/util/riscv-trace.c
new file mode 100644
index 000000000000..c9bc3f6a7857
--- /dev/null
+++ b/tools/perf/util/riscv-trace.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/log2.h>
+#include <linux/types.h>
+#include <linux/zalloc.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "auxtrace.h"
+#include "color.h"
+#include "debug.h"
+#include "evsel.h"
+#include "riscv-trace.h"
+#include "machine.h"
+#include "session.h"
+#include "tool.h"
+#include <internal/lib.h>
+
+struct riscv_trace {
+	struct auxtrace auxtrace;
+	u32 auxtrace_type;
+	struct perf_session *session;
+	struct machine *machine;
+	u32 pmu_type;
+};
+
+static void riscv_trace_dump(struct riscv_trace *trace __maybe_unused,
+			  unsigned char *buf, size_t len)
+{
+
+	const char *color = PERF_COLOR_BLUE;
+
+	color_fprintf(stdout, color, ". ... %s: buf=%p len=%zubytes\n", __func__, buf, len);
+	for (size_t i = 0; i < len; i++)
+		printf("%02x ", buf[i]);
+}
+
+static void riscv_trace_dump_event(struct riscv_trace *trace, unsigned char *buf,
+				size_t len)
+{
+	printf(".\n");
+
+	riscv_trace_dump(trace, buf, len);
+}
+
+static int riscv_trace_process_event(struct perf_session *session __maybe_unused,
+				  union perf_event *event __maybe_unused,
+				  struct perf_sample *sample __maybe_unused,
+				  const struct perf_tool *tool __maybe_unused)
+{
+	return 0;
+}
+
+static int riscv_trace_process_auxtrace_event(struct perf_session *session,
+					   union perf_event *event,
+					   const struct perf_tool *tool __maybe_unused)
+{
+	struct riscv_trace *trace = container_of(session->auxtrace, struct riscv_trace,
+					    auxtrace);
+	int fd = perf_data__fd(session->data);
+	int size = event->auxtrace.size;
+	void *data = malloc(size);
+	off_t data_offset;
+	int err;
+
+	if (!data)
+		return -errno;
+
+	if (perf_data__is_pipe(session->data)) {
+		data_offset = 0;
+	} else {
+		data_offset = lseek(fd, 0, SEEK_CUR);
+		if (data_offset == -1) {
+			free(data);
+			return -errno;
+		}
+	}
+
+	err = readn(fd, data, size);
+	if (err != (ssize_t)size) {
+		free(data);
+		return -errno;
+	}
+
+	if (dump_trace)
+		riscv_trace_dump_event(trace, data, size);
+
+	free(data);
+	return 0;
+}
+
+static int riscv_trace_flush(struct perf_session *session __maybe_unused,
+			  const struct perf_tool *tool __maybe_unused)
+{
+	return 0;
+}
+
+static void riscv_trace_free_events(struct perf_session *session __maybe_unused)
+{
+}
+
+static void riscv_trace_free(struct perf_session *session)
+{
+	struct riscv_trace *trace = container_of(session->auxtrace, struct riscv_trace,
+					    auxtrace);
+
+	session->auxtrace = NULL;
+	free(trace);
+}
+
+static bool riscv_trace_evsel_is_auxtrace(struct perf_session *session,
+				       struct evsel *evsel)
+{
+	struct riscv_trace *trace = container_of(session->auxtrace, struct riscv_trace, auxtrace);
+
+	return evsel->core.attr.type == trace->pmu_type;
+}
+
+static void riscv_trace_print_info(__u64 type)
+{
+	if (!dump_trace)
+		return;
+
+	fprintf(stdout, "  PMU Type           %" PRId64 "\n", (s64) type);
+}
+
+int riscv_trace_process_auxtrace_info(union perf_event *event,
+				   struct perf_session *session)
+{
+	struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
+	struct riscv_trace *trace;
+
+	if (auxtrace_info->header.size < RISCV_TRACE_AUXTRACE_PRIV_SIZE +
+				sizeof(struct perf_record_auxtrace_info))
+		return -EINVAL;
+
+	trace = zalloc(sizeof(*trace));
+	if (!trace)
+		return -ENOMEM;
+
+	trace->session = session;
+	trace->machine = &session->machines.host; /* No kvm support */
+	trace->auxtrace_type = auxtrace_info->type;
+	trace->pmu_type = auxtrace_info->priv[0];
+
+	trace->auxtrace.process_event = riscv_trace_process_event;
+	trace->auxtrace.process_auxtrace_event = riscv_trace_process_auxtrace_event;
+	trace->auxtrace.flush_events = riscv_trace_flush;
+	trace->auxtrace.free_events = riscv_trace_free_events;
+	trace->auxtrace.free = riscv_trace_free;
+	trace->auxtrace.evsel_is_auxtrace = riscv_trace_evsel_is_auxtrace;
+	session->auxtrace = &trace->auxtrace;
+
+	riscv_trace_print_info(auxtrace_info->priv[0]);
+
+	return 0;
+}
diff --git a/tools/perf/util/riscv-trace.h b/tools/perf/util/riscv-trace.h
new file mode 100644
index 000000000000..4901ea323b77
--- /dev/null
+++ b/tools/perf/util/riscv-trace.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef INCLUDE__PERF_RISCV_TRACE_H__
+#define INCLUDE__PERF_RISCV_TRACE_H__
+
+#define RISCV_TRACE_PMU_NAME		"riscv_trace"
+#define RISCV_TRACE_AUXTRACE_PRIV_SIZE	sizeof(u64)
+
+union perf_event;
+struct perf_session;
+struct perf_pmu;
+
+struct auxtrace_record *riscv_trace_recording_init(int *err,
+						struct perf_pmu *riscv_ntrace_pmu);
+
+int riscv_trace_process_auxtrace_info(union perf_event *event,
+				   struct perf_session *session);
+
+#endif
-- 
2.49.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFC PATCH 4/4] riscv: trace: Support sink using dma buffer
  2025-09-11 12:44 [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support cp0613
                   ` (2 preceding siblings ...)
  2025-09-11 12:44 ` [RFC PATCH 3/4] tools: perf: Support perf record with aux buffer for riscv trace cp0613
@ 2025-09-11 12:44 ` cp0613
  2025-09-17  7:27 ` [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support Bo Gan
  2025-10-13  4:22 ` Anup Patel
  5 siblings, 0 replies; 11+ messages in thread
From: cp0613 @ 2025-09-11 12:44 UTC (permalink / raw)
  To: paul.walmsley, palmer, aou, alex, guoren
  Cc: linux-riscv, linux-kernel, Chen Pei

From: Chen Pei <cp0613@linux.alibaba.com>

In common SoC systems, the trace data by the sink is usually
written to the memory, and the memory needs to be a large block.

We have two methods to achieve this. One is based on reserved
memory. This method requires pre-isolation of memory and is not
flexible enough. Therefore, we chose the second method, which is
based on IOMMU to map non-contiguous memory to continuous. When
implementing the driver, only the DMA alloc related APIs are needed.

Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
 arch/riscv/events/riscv_trace.c | 49 ++++++++++++++++++++++++++++++++-
 arch/riscv/events/riscv_trace.h |  4 ++-
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/events/riscv_trace.c b/arch/riscv/events/riscv_trace.c
index 3ac4a3be5d3e..e8deaefa0180 100644
--- a/arch/riscv/events/riscv_trace.c
+++ b/arch/riscv/events/riscv_trace.c
@@ -9,6 +9,7 @@
 #include <linux/device.h>
 #include <linux/perf_event.h>
 #include <linux/vmalloc.h>
+#include <linux/dma-mapping.h>
 
 #include "riscv_trace.h"
 
@@ -55,6 +56,44 @@ static void riscv_trace_init_filter_attrs(struct perf_event *event)
 		riscv_trace_pmu.filter_attr.priv_mode);
 }
 
+static int riscv_trace_sink_dma_alloc(unsigned long size)
+{
+	struct riscv_trace_component *component;
+	dma_addr_t dma_addr;
+
+	list_for_each_entry(component, &riscv_trace_controllers, list) {
+		if (component->type == RISCV_TRACE_SINK) {
+			component->sink.vaddr =
+			    dma_alloc_coherent(riscv_trace_pmu.pmu.dev, size,
+					       &dma_addr, GFP_KERNEL);
+			if (component->sink.vaddr) {
+				component->sink.start_addr = dma_addr;
+				component->sink.limit_addr = dma_addr + size;
+				continue;
+			} else {
+				pr_err("dma_alloc_coherent failed\n");
+				return -ENOMEM;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void riscv_trace_sink_dma_free(void)
+{
+	struct riscv_trace_component *component;
+
+	list_for_each_entry(component, &riscv_trace_controllers, list) {
+		if (component->type == RISCV_TRACE_SINK) {
+			if (component->sink.vaddr)
+				dma_free_coherent(riscv_trace_pmu.pmu.dev,
+					component->sink.limit_addr - component->sink.start_addr,
+					component->sink.vaddr, component->sink.start_addr);
+		}
+	}
+}
+
 static int riscv_trace_event_init(struct perf_event *event)
 {
 	if (event->attr.type != riscv_trace_pmu.pmu.type)
@@ -105,7 +144,7 @@ static void *riscv_trace_buffer_setup_aux(struct perf_event *event, void **pages
 {
 	struct riscv_trace_aux_buf *buf;
 	struct page **pagelist;
-	int i;
+	int i, ret;
 
 	if (overwrite) {
 		pr_warn("Overwrite mode is not supported\n");
@@ -135,6 +174,12 @@ static void *riscv_trace_buffer_setup_aux(struct perf_event *event, void **pages
 
 	pr_info("nr_pages=%d length=%d\n", buf->nr_pages, buf->length);
 
+	ret = riscv_trace_sink_dma_alloc(buf->length);
+	if (ret) {
+		kfree(pagelist);
+		goto err;
+	}
+
 	kfree(pagelist);
 	return buf;
 err:
@@ -148,6 +193,8 @@ static void riscv_trace_buffer_free_aux(void *aux)
 
 	vunmap(buf->base);
 	kfree(buf);
+
+	riscv_trace_sink_dma_free();
 }
 
 static int __init riscv_trace_init(void)
diff --git a/arch/riscv/events/riscv_trace.h b/arch/riscv/events/riscv_trace.h
index c28216227006..7819fbeace1f 100644
--- a/arch/riscv/events/riscv_trace.h
+++ b/arch/riscv/events/riscv_trace.h
@@ -49,7 +49,9 @@ struct riscv_trace_funnel {
 };
 
 struct riscv_trace_sink {
-	;
+	u64 start_addr;
+	u64 limit_addr;
+	void __iomem *vaddr;
 };
 
 struct riscv_trace_component {
-- 
2.49.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 1/4] dt-bindings: riscv: Add trace components description
  2025-09-11 12:44 ` [RFC PATCH 1/4] dt-bindings: riscv: Add trace components description cp0613
@ 2025-09-11 17:24   ` Krzysztof Kozlowski
  2025-09-15  2:39     ` cp0613
  0 siblings, 1 reply; 11+ messages in thread
From: Krzysztof Kozlowski @ 2025-09-11 17:24 UTC (permalink / raw)
  To: cp0613, paul.walmsley, palmer, aou, alex, guoren
  Cc: linux-riscv, linux-kernel

On 11/09/2025 14:44, cp0613@linux.alibaba.com wrote:
> From: Chen Pei <cp0613@linux.alibaba.com>
> 
> This patch has added property definitions related to the riscv

Please do not use "This commit/patch/change", but imperative mood. See
longer explanation here:
https://elixir.bootlin.com/linux/v6.16/source/Documentation/process/submitting-patches.rst#L94

<form letter>
Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC. It might happen, that command when run on an older
kernel, gives you outdated entries. Therefore please be sure you base
your patches on recent Linux kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.

You missed at least devicetree list (maybe more), so this won't be
tested by automated tooling. Performing review on untested code might be
a waste of time.

Please kindly resend and include all necessary To/Cc entries.
</form letter>


> trace component, providing a foundation for subsequent driver
> implementations.
> 


...

> +$id: http://devicetree.org/schemas/riscv/trace/riscv,trace,funnel.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: RISC-V Trace Funnel Controller
> +
> +description: |
> +  riscv trace funnel controller description.
> +
> +maintainers:
> +  - Chen Pei <cp0613@linux.alibaba.com>
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: riscv_trace,funnel-controller

You need to start following DTS coding style.



> +  reg:
> +    description: A memory region containing registers for funnel controller
> +
> +  ports:
> +    description: Input/Output port definitions
> +
> +  level:
> +    description: Level of the funnel (e.g., 1 means close to the encoder)
> +
> +additionalProperties: true

No clue from where you got this, but that's not how DT bindings are
written. Maybe you used some AI tools for that - in that case, it would
be strong grumpy NAK. :( You just waste community time with such approach.

Please start from scratch from example-schema or known good bindings.

Best regards,
Krzysztof

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 1/4] dt-bindings: riscv: Add trace components description
  2025-09-11 17:24   ` Krzysztof Kozlowski
@ 2025-09-15  2:39     ` cp0613
  0 siblings, 0 replies; 11+ messages in thread
From: cp0613 @ 2025-09-15  2:39 UTC (permalink / raw)
  To: krzk
  Cc: alex, aou, cp0613, guoren, linux-kernel, linux-riscv, palmer,
	paul.walmsley

On Thu, 11 Sep 2025 19:24:39 +0200, krzk@kernel.org wrote:

> > This patch has added property definitions related to the riscv> 

> Please do not use "This commit/patch/change", but imperative mood. See
> longer explanation here:
> https://elixir.bootlin.com/linux/v6.16/source/Documentation/process/submitting-patches.rst#L94> 

> <form letter>
> Please use scripts/get_maintainers.pl to get a list of necessary people
> and lists to CC. It might happen, that command when run on an older
> kernel, gives you outdated entries. Therefore please be sure you base
> your patches on recent Linux kernel.> 

> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> people, so fix your workflow. Tools might also fail if you work on some
> ancient tree (don't, instead use mainline) or work on fork of kernel
> (don't, instead use mainline). Just use b4 and everything should be
> fine, although remember about `b4 prep --auto-to-cc` if you added new
> patches to the patchset.> 

> You missed at least devicetree list (maybe more), so this won't be
> tested by automated tooling. Performing review on untested code might be
> a waste of time.> 

> Please kindly resend and include all necessary To/Cc entries.
> </form letter>> 
> 

> > trace component, providing a foundation for subsequent driver
> > implementations.

Thank you very much for your review.
My next resend will include all necessary To/Cc entries.


>> +    items:
>> +      - const: riscv_trace,funnel-controller>

>You need to start following DTS coding style.>
>
>

>> +  reg:
>> +    description: A memory region containing registers for funnel controller

Indeed, the current dt-bindings are very primitive and may contain some
errors. I should improve and check them before sending them out. I will
pay attention to it next time.

Thank you,
Pei

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support
  2025-09-11 12:44 [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support cp0613
                   ` (3 preceding siblings ...)
  2025-09-11 12:44 ` [RFC PATCH 4/4] riscv: trace: Support sink using dma buffer cp0613
@ 2025-09-17  7:27 ` Bo Gan
  2025-09-18  6:19   ` cp0613
  2025-10-13  4:22 ` Anup Patel
  5 siblings, 1 reply; 11+ messages in thread
From: Bo Gan @ 2025-09-17  7:27 UTC (permalink / raw)
  To: cp0613, paul.walmsley, palmer, aou, alex, guoren
  Cc: linux-riscv, linux-kernel

On 9/11/25 05:44, cp0613@linux.alibaba.com wrote:
> From: Chen Pei <cp0613@linux.alibaba.com>
> 
> The RISC-V Trace Specification defines a standardized framework for
> capturing and analyzing the execution of RISC-V processors. Its main
> uses include: instruction and data tracing, real-time debugging, etc.
> Similar to Intel-PT and ARM-CoreSight.
> 
> According to the RISC-V Trace Control Interface specification [1].
> There are two standard RISC-V trace protocols which will utilize
> this RISC-V Trace Control Interface:
> - RISC-V N-Trace (Nexus-based Trace) Specification
> - Efficient Trace for RISC-V Specification
> So, this is a complete guideline for any standard RISC-V trace
> implementation.
> 
> This series of patches is mainly used to start related work and
> communication. It completes the following tasks:
> 1. dt-bindings completes the basic definition of riscv trace
>     component properties, but is still incomplete.
> 2. Implemented the basic RISC-V Trace PMU driver, including
>     support for the aux buffer.
> 3. Implemented basic support for AUXTRACE integration with perf
>     tools.
> 
> There's still more work to be done, such as:
> 1. Complete RISC-V Trace PMU implementation.
> 2. The perf.data generation and parsing including AUXTRACE events.
> 3. Taking RISC-V N-Trace as an example, implement the parsing of
>     Nexus Trace data format, including support for perf report and
>     perf script commands.
> We are still sorting out.
> 
> Any comments or suggestions are welcome.
> 
> [1] https://github.com/riscv-non-isa/tg-nexus-trace.git
> 

Hi Chen, thanks for starting this series. I have done a N-trace driver
in user space: https://github.com/ganboing/riscv-trace-umd, and I'd love
to see someone finally taking the effort to try a proper kernel driver.

My overall suggestions:

1. We need a way to expose proper topology to user-space like coresight.
    Thus, I'm thinking of using similar logic in coresight to export the
    topology through sysfs. Potentially we can abstract some logic out of
    coresight and make it a common core path that can be reused by riscv
    trace driver. Thus, we don't reinvent the wheel. This also helps
    debugging trace driver issues if anything goes wrong.

2. IMO, The driver should be moved to drivers/hwtracing/. It's not tightly
    coupled with arch, and there are many platform related logic where it
    doesn't belong to arch/riscv/. Having said that, I do believe we'll need
    something in arch/riscv/ eventually for trace once the self-hosted trace
    spec is finalized. Self-hosted trace behaves more like Intel PT, where
    the control will be done through some CSR(s), and it doesn't need those
    funnel/sink topology, and can emit trace stream to virtual memory directly.
    It's a per-hart thing with LAMBI and all that. I'd imagine that eventually
    riscv trace will be two parts. One is more coresight-alike, where you have
    encoders/funnel/sink/bridge that are described through DT and controlled by
    MMIO. The other part is more PT-alike, where the feature is described by
    ISA-string (I guess?), and it's much easier to program. For the time being,
    IMO, a coresight-alike driver, e.g., drivers/hwtracing/rvtrace, is more
    suited for existing platforms implementing N-trace or E-trace. Also, don't
    assume the memory sink is available. People using this "coresight-alike"
    driver can very-well be HW engineers who's collecting traces using external
    probes, so again I think we may want to abstract out part of coresight's
    logic and reuse then in riscv.

3. I've already implemented a N-trace decoder:
    https://github.com/ganboing/libnexus-rv
    It can decode N-trace on real HW (ESWIN EIC7700/Sifive P550). I'll try to
    see if I have the time to code up N-trace decoding in perf tool, once the
    driver and the perf trace collection part is stabilized. If not, I will be
    happy to review yours. Please include me in future series.

BTW, perhaps you want to also CC riscv Task Groups such as
   - Sig-Debug-Trace-Perf-Mon (DTPM)
   - Tech-Self-Hosted-Trace

to keep people like Beeman/Robert/Bruce/Iain/Greg posted. Robert mentioned
they tried to contact Sifive to see if they had similar driver upstreaming
effort just like yours, but there were no reply. Keep them posted anyway to
avoid duplicate work. We should also discuss this during riscv NA summit if
you or Guo's attending.

> Chen Pei (4):
>    dt-bindings: riscv: Add trace components description
>    riscv: event: Initial riscv trace driver support
>    tools: perf: Support perf record with aux buffer for riscv trace
>    riscv: trace: Support sink using dma buffer
> 
>   .../riscv/trace/riscv,trace,encoder.yaml      |  41 +++
>   .../riscv/trace/riscv,trace,funnel.yaml       |  46 ++++
>   .../riscv/trace/riscv,trace,sink.yaml         |  37 +++
>   arch/riscv/Kbuild                             |   1 +
>   arch/riscv/Kconfig                            |   2 +
>   arch/riscv/events/Kconfig                     |  11 +
>   arch/riscv/events/Makefile                    |   3 +
>   arch/riscv/events/riscv_trace.c               | 253 ++++++++++++++++++
>   arch/riscv/events/riscv_trace.h               | 133 +++++++++
>   arch/riscv/events/riscv_trace_encoder.c       | 109 ++++++++
>   arch/riscv/events/riscv_trace_funnel.c        | 160 +++++++++++
>   arch/riscv/events/riscv_trace_sink.c          | 100 +++++++
>   tools/perf/arch/riscv/util/Build              |   3 +
>   tools/perf/arch/riscv/util/auxtrace.c         |  33 +++
>   tools/perf/arch/riscv/util/pmu.c              |  18 ++
>   tools/perf/arch/riscv/util/riscv-trace.c      | 183 +++++++++++++
>   tools/perf/arch/riscv/util/tsc.c              |  15 ++
>   tools/perf/util/Build                         |   1 +
>   tools/perf/util/auxtrace.c                    |   4 +
>   tools/perf/util/auxtrace.h                    |   1 +
>   tools/perf/util/riscv-trace.c                 | 162 +++++++++++
>   tools/perf/util/riscv-trace.h                 |  18 ++
>   22 files changed, 1334 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,encoder.yaml
>   create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,funnel.yaml
>   create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,sink.yaml
>   create mode 100644 arch/riscv/events/Kconfig
>   create mode 100644 arch/riscv/events/Makefile
>   create mode 100644 arch/riscv/events/riscv_trace.c
>   create mode 100644 arch/riscv/events/riscv_trace.h
>   create mode 100644 arch/riscv/events/riscv_trace_encoder.c
>   create mode 100644 arch/riscv/events/riscv_trace_funnel.c
>   create mode 100644 arch/riscv/events/riscv_trace_sink.c
>   create mode 100644 tools/perf/arch/riscv/util/auxtrace.c
>   create mode 100644 tools/perf/arch/riscv/util/pmu.c
>   create mode 100644 tools/perf/arch/riscv/util/riscv-trace.c
>   create mode 100644 tools/perf/arch/riscv/util/tsc.c
>   create mode 100644 tools/perf/util/riscv-trace.c
>   create mode 100644 tools/perf/util/riscv-trace.h
> 
Bo

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support
  2025-09-17  7:27 ` [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support Bo Gan
@ 2025-09-18  6:19   ` cp0613
  0 siblings, 0 replies; 11+ messages in thread
From: cp0613 @ 2025-09-18  6:19 UTC (permalink / raw)
  To: ganboing
  Cc: alex, aou, cp0613, guoren, linux-kernel, linux-riscv, palmer,
	paul.walmsley

On Wed, 17 Sep 2025 00:27:43 -0700, ganboing@gmail.com:

> > Any comments or suggestions are welcome.
> > 
> > [1] https://github.com/riscv-non-isa/tg-nexus-trace.git
> > > 

> Hi Chen, thanks for starting this series. I have done a N-trace driver
> in user space: https://github.com/ganboing/riscv-trace-umd, and I'd love
> to see someone finally taking the effort to try a proper kernel driver.> 

> My overall suggestions:> 

> 1. We need a way to expose proper topology to user-space like coresight.
>     Thus, I'm thinking of using similar logic in coresight to export the
>     topology through sysfs. Potentially we can abstract some logic out of
>     coresight and make it a common core path that can be reused by riscv
>     trace driver. Thus, we don't reinvent the wheel. This also helps
>     debugging trace driver issues if anything goes wrong.> 

> 2. IMO, The driver should be moved to drivers/hwtracing/. It's not tightly
>     coupled with arch, and there are many platform related logic where it
>     doesn't belong to arch/riscv/. Having said that, I do believe we'll need
>     something in arch/riscv/ eventually for trace once the self-hosted trace
>     spec is finalized. Self-hosted trace behaves more like Intel PT, where
>     the control will be done through some CSR(s), and it doesn't need those
>     funnel/sink topology, and can emit trace stream to virtual memory directly.
>     It's a per-hart thing with LAMBI and all that. I'd imagine that eventually
>     riscv trace will be two parts. One is more coresight-alike, where you have
>     encoders/funnel/sink/bridge that are described through DT and controlled by
>     MMIO. The other part is more PT-alike, where the feature is described by
>     ISA-string (I guess?), and it's much easier to program. For the time being,
>     IMO, a coresight-alike driver, e.g., drivers/hwtracing/rvtrace, is more
>     suited for existing platforms implementing N-trace or E-trace. Also, don't
>     assume the memory sink is available. People using this "coresight-alike"
>     driver can very-well be HW engineers who's collecting traces using external
>     probes, so again I think we may want to abstract out part of coresight's
>     logic and reuse then in riscv.> 

> 3. I've already implemented a N-trace decoder:
>     https://github.com/ganboing/libnexus-rv
>     It can decode N-trace on real HW (ESWIN EIC7700/Sifive P550). I'll try to
>     see if I have the time to code up N-trace decoding in perf tool, once the
>     driver and the perf trace collection part is stabilized. If not, I will be
>     happy to review yours. Please include me in future series.> 

> BTW, perhaps you want to also CC riscv Task Groups such as
>    - Sig-Debug-Trace-Perf-Mon (DTPM)
>    - Tech-Self-Hosted-Trace> 

> to keep people like Beeman/Robert/Bruce/Iain/Greg posted. Robert mentioned
> they tried to contact Sifive to see if they had similar driver upstreaming
> effort just like yours, but there were no reply. Keep them posted anyway to
> avoid duplicate work. We should also discuss this during riscv NA summit if
> you or Guo's attending.> 

> > Chen Pei (4):
> >    dt-bindings: riscv: Add trace components description
> >    riscv: event: Initial riscv trace driver support
> >    tools: perf: Support perf record with aux buffer for riscv trace
> >    riscv: trace: Support sink using dma buffer

Thank you very much for your review. Every suggestion and existing work is
valuable, and I will carefully evaluate it.

1. I will further investigate the technical details you mentioned in
   CoreSight, reusing existing design and code as much as possible.

2. Moving the driver to drivers/hwtracing/ is a good suggestion, and I've
   considered it before.

3. We've noticed that there are many types of sinks, such as the Lauterbach's
   Debug Probe, as you mentioned. The current code does not reflect this, I
   will consider compatibility later.

4. Your implementation of the N-trace decoder is very useful as a reference.
   I will study it carefully. We also have an internal implementation, which
   I will compare and provide feedback to you later.

5. The RISC-V Task Groups should indeed be cc'd. Thanks for the reminder.

Thank you,
Pei

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support
  2025-09-11 12:44 [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support cp0613
                   ` (4 preceding siblings ...)
  2025-09-17  7:27 ` [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support Bo Gan
@ 2025-10-13  4:22 ` Anup Patel
  2025-10-14  2:54   ` Guo Ren
  5 siblings, 1 reply; 11+ messages in thread
From: Anup Patel @ 2025-10-13  4:22 UTC (permalink / raw)
  To: guoren; +Cc: paul.walmsley, palmer, aou, alex, linux-riscv, linux-kernel,
	cp0613

Hi Guo,

On Thu, Sep 11, 2025 at 6:15 PM <cp0613@linux.alibaba.com> wrote:
>
> From: Chen Pei <cp0613@linux.alibaba.com>
>
> The RISC-V Trace Specification defines a standardized framework for
> capturing and analyzing the execution of RISC-V processors. Its main
> uses include: instruction and data tracing, real-time debugging, etc.
> Similar to Intel-PT and ARM-CoreSight.
>
> According to the RISC-V Trace Control Interface specification [1].
> There are two standard RISC-V trace protocols which will utilize
> this RISC-V Trace Control Interface:
> - RISC-V N-Trace (Nexus-based Trace) Specification
> - Efficient Trace for RISC-V Specification
> So, this is a complete guideline for any standard RISC-V trace
> implementation.
>
> This series of patches is mainly used to start related work and
> communication. It completes the following tasks:
> 1. dt-bindings completes the basic definition of riscv trace
>    component properties, but is still incomplete.
> 2. Implemented the basic RISC-V Trace PMU driver, including
>    support for the aux buffer.
> 3. Implemented basic support for AUXTRACE integration with perf
>    tools.
>
> There's still more work to be done, such as:
> 1. Complete RISC-V Trace PMU implementation.
> 2. The perf.data generation and parsing including AUXTRACE events.
> 3. Taking RISC-V N-Trace as an example, implement the parsing of
>    Nexus Trace data format, including support for perf report and
>    perf script commands.
> We are still sorting out.
>
> Any comments or suggestions are welcome.
>
> [1] https://github.com/riscv-non-isa/tg-nexus-trace.git
>
> Chen Pei (4):
>   dt-bindings: riscv: Add trace components description
>   riscv: event: Initial riscv trace driver support
>   tools: perf: Support perf record with aux buffer for riscv trace
>   riscv: trace: Support sink using dma buffer
>
>  .../riscv/trace/riscv,trace,encoder.yaml      |  41 +++
>  .../riscv/trace/riscv,trace,funnel.yaml       |  46 ++++
>  .../riscv/trace/riscv,trace,sink.yaml         |  37 +++
>  arch/riscv/Kbuild                             |   1 +
>  arch/riscv/Kconfig                            |   2 +
>  arch/riscv/events/Kconfig                     |  11 +
>  arch/riscv/events/Makefile                    |   3 +
>  arch/riscv/events/riscv_trace.c               | 253 ++++++++++++++++++
>  arch/riscv/events/riscv_trace.h               | 133 +++++++++
>  arch/riscv/events/riscv_trace_encoder.c       | 109 ++++++++
>  arch/riscv/events/riscv_trace_funnel.c        | 160 +++++++++++
>  arch/riscv/events/riscv_trace_sink.c          | 100 +++++++
>  tools/perf/arch/riscv/util/Build              |   3 +
>  tools/perf/arch/riscv/util/auxtrace.c         |  33 +++
>  tools/perf/arch/riscv/util/pmu.c              |  18 ++
>  tools/perf/arch/riscv/util/riscv-trace.c      | 183 +++++++++++++
>  tools/perf/arch/riscv/util/tsc.c              |  15 ++
>  tools/perf/util/Build                         |   1 +
>  tools/perf/util/auxtrace.c                    |   4 +
>  tools/perf/util/auxtrace.h                    |   1 +
>  tools/perf/util/riscv-trace.c                 | 162 +++++++++++
>  tools/perf/util/riscv-trace.h                 |  18 ++
>  22 files changed, 1334 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,encoder.yaml
>  create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,funnel.yaml
>  create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,sink.yaml
>  create mode 100644 arch/riscv/events/Kconfig
>  create mode 100644 arch/riscv/events/Makefile
>  create mode 100644 arch/riscv/events/riscv_trace.c
>  create mode 100644 arch/riscv/events/riscv_trace.h
>  create mode 100644 arch/riscv/events/riscv_trace_encoder.c
>  create mode 100644 arch/riscv/events/riscv_trace_funnel.c
>  create mode 100644 arch/riscv/events/riscv_trace_sink.c
>  create mode 100644 tools/perf/arch/riscv/util/auxtrace.c
>  create mode 100644 tools/perf/arch/riscv/util/pmu.c
>  create mode 100644 tools/perf/arch/riscv/util/riscv-trace.c
>  create mode 100644 tools/perf/arch/riscv/util/tsc.c
>  create mode 100644 tools/perf/util/riscv-trace.c
>  create mode 100644 tools/perf/util/riscv-trace.h
>
> --

Few months back we (Ventana) had informed everyone
within RVI (particularly self-hosted trace TG) that we are
working on Linux trace framework and drivers for the RISC-V
community [1]. There are also publicly accessible RISE
project pages already available for the trace efforts [2].

This is yet another instance where ongoing efforts were
totally ignored.

--
Anup

[1] https://lists.riscv.org/g/sig-hypervisors/message/648
[2] https://lf-rise.atlassian.net/wiki/spaces/HOME/pages/8591251/2025+-+Kernel+and+Virtualization+Priorities

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support
  2025-10-13  4:22 ` Anup Patel
@ 2025-10-14  2:54   ` Guo Ren
  0 siblings, 0 replies; 11+ messages in thread
From: Guo Ren @ 2025-10-14  2:54 UTC (permalink / raw)
  To: Anup Patel
  Cc: paul.walmsley, palmer, aou, alex, linux-riscv, linux-kernel,
	cp0613

On Mon, Oct 13, 2025 at 12:22 PM Anup Patel <apatel@ventanamicro.com> wrote:
>
> Hi Guo,
>
> On Thu, Sep 11, 2025 at 6:15 PM <cp0613@linux.alibaba.com> wrote:
> >
> > From: Chen Pei <cp0613@linux.alibaba.com>
> >
> > The RISC-V Trace Specification defines a standardized framework for
> > capturing and analyzing the execution of RISC-V processors. Its main
> > uses include: instruction and data tracing, real-time debugging, etc.
> > Similar to Intel-PT and ARM-CoreSight.
> >
> > According to the RISC-V Trace Control Interface specification [1].
> > There are two standard RISC-V trace protocols which will utilize
> > this RISC-V Trace Control Interface:
> > - RISC-V N-Trace (Nexus-based Trace) Specification
> > - Efficient Trace for RISC-V Specification
> > So, this is a complete guideline for any standard RISC-V trace
> > implementation.
> >
> > This series of patches is mainly used to start related work and
> > communication. It completes the following tasks:
> > 1. dt-bindings completes the basic definition of riscv trace
> >    component properties, but is still incomplete.
> > 2. Implemented the basic RISC-V Trace PMU driver, including
> >    support for the aux buffer.
> > 3. Implemented basic support for AUXTRACE integration with perf
> >    tools.
> >
> > There's still more work to be done, such as:
> > 1. Complete RISC-V Trace PMU implementation.
> > 2. The perf.data generation and parsing including AUXTRACE events.
> > 3. Taking RISC-V N-Trace as an example, implement the parsing of
> >    Nexus Trace data format, including support for perf report and
> >    perf script commands.
> > We are still sorting out.
> >
> > Any comments or suggestions are welcome.
> >
> > [1] https://github.com/riscv-non-isa/tg-nexus-trace.git
> >
> > Chen Pei (4):
> >   dt-bindings: riscv: Add trace components description
> >   riscv: event: Initial riscv trace driver support
> >   tools: perf: Support perf record with aux buffer for riscv trace
> >   riscv: trace: Support sink using dma buffer
> >
> >  .../riscv/trace/riscv,trace,encoder.yaml      |  41 +++
> >  .../riscv/trace/riscv,trace,funnel.yaml       |  46 ++++
> >  .../riscv/trace/riscv,trace,sink.yaml         |  37 +++
> >  arch/riscv/Kbuild                             |   1 +
> >  arch/riscv/Kconfig                            |   2 +
> >  arch/riscv/events/Kconfig                     |  11 +
> >  arch/riscv/events/Makefile                    |   3 +
> >  arch/riscv/events/riscv_trace.c               | 253 ++++++++++++++++++
> >  arch/riscv/events/riscv_trace.h               | 133 +++++++++
> >  arch/riscv/events/riscv_trace_encoder.c       | 109 ++++++++
> >  arch/riscv/events/riscv_trace_funnel.c        | 160 +++++++++++
> >  arch/riscv/events/riscv_trace_sink.c          | 100 +++++++
> >  tools/perf/arch/riscv/util/Build              |   3 +
> >  tools/perf/arch/riscv/util/auxtrace.c         |  33 +++
> >  tools/perf/arch/riscv/util/pmu.c              |  18 ++
> >  tools/perf/arch/riscv/util/riscv-trace.c      | 183 +++++++++++++
> >  tools/perf/arch/riscv/util/tsc.c              |  15 ++
> >  tools/perf/util/Build                         |   1 +
> >  tools/perf/util/auxtrace.c                    |   4 +
> >  tools/perf/util/auxtrace.h                    |   1 +
> >  tools/perf/util/riscv-trace.c                 | 162 +++++++++++
> >  tools/perf/util/riscv-trace.h                 |  18 ++
> >  22 files changed, 1334 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,encoder.yaml
> >  create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,funnel.yaml
> >  create mode 100644 Documentation/devicetree/bindings/riscv/trace/riscv,trace,sink.yaml
> >  create mode 100644 arch/riscv/events/Kconfig
> >  create mode 100644 arch/riscv/events/Makefile
> >  create mode 100644 arch/riscv/events/riscv_trace.c
> >  create mode 100644 arch/riscv/events/riscv_trace.h
> >  create mode 100644 arch/riscv/events/riscv_trace_encoder.c
> >  create mode 100644 arch/riscv/events/riscv_trace_funnel.c
> >  create mode 100644 arch/riscv/events/riscv_trace_sink.c
> >  create mode 100644 tools/perf/arch/riscv/util/auxtrace.c
> >  create mode 100644 tools/perf/arch/riscv/util/pmu.c
> >  create mode 100644 tools/perf/arch/riscv/util/riscv-trace.c
> >  create mode 100644 tools/perf/arch/riscv/util/tsc.c
> >  create mode 100644 tools/perf/util/riscv-trace.c
> >  create mode 100644 tools/perf/util/riscv-trace.h
> >
> > --
>
> Few months back we (Ventana) had informed everyone
> within RVI (particularly self-hosted trace TG) that we are
> working on Linux trace framework and drivers for the RISC-V
> community [1]. There are also publicly accessible RISE
> project pages already available for the trace efforts [2].\
Thx for reminding, I would reply on [1].

>
> This is yet another instance where ongoing efforts were
> totally ignored.
>
> --
> Anup
>
> [1] https://lists.riscv.org/g/sig-hypervisors/message/648
> [2] https://lf-rise.atlassian.net/wiki/spaces/HOME/pages/8591251/2025+-+Kernel+and+Virtualization+Priorities



-- 
Best Regards
 Guo Ren

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2025-10-14  2:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-11 12:44 [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support cp0613
2025-09-11 12:44 ` [RFC PATCH 1/4] dt-bindings: riscv: Add trace components description cp0613
2025-09-11 17:24   ` Krzysztof Kozlowski
2025-09-15  2:39     ` cp0613
2025-09-11 12:44 ` [RFC PATCH 2/4] riscv: event: Initial riscv trace driver support cp0613
2025-09-11 12:44 ` [RFC PATCH 3/4] tools: perf: Support perf record with aux buffer for riscv trace cp0613
2025-09-11 12:44 ` [RFC PATCH 4/4] riscv: trace: Support sink using dma buffer cp0613
2025-09-17  7:27 ` [RFC PATCH 0/4] riscv: tarce: Implement riscv trace pmu driver and perf support Bo Gan
2025-09-18  6:19   ` cp0613
2025-10-13  4:22 ` Anup Patel
2025-10-14  2:54   ` Guo Ren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox