drivers/hwtracing/Kconfig | 2 + drivers/hwtracing/coresight/Kconfig | 46 +- drivers/hwtracing/coresight/Makefile | 6 + drivers/hwtracing/coresight/coresight-core.c | 8 + .../hwtracing/coresight/coresight-etm-perf.c | 1 - .../hwtracing/coresight/coresight-etm-perf.h | 21 + .../hwtracing/coresight/coresight-platform.c | 1 - .../hwtracing/coresight/coresight-tmc-etf.c | 4 + .../hwtracing/coresight/coresight-tmc-etr.c | 4 + .../hwtracing/coresight/rvtrace-atbbridge.c | 239 +++ drivers/hwtracing/coresight/rvtrace-core.c | 135 ++ .../coresight/rvtrace-encoder-core.c | 562 +++++++ .../coresight/rvtrace-encoder-sysfs.c | 363 +++++ drivers/hwtracing/coresight/rvtrace-encoder.h | 151 ++ drivers/hwtracing/coresight/rvtrace-funnel.c | 337 ++++ drivers/hwtracing/coresight/rvtrace-funnel.h | 39 + .../hwtracing/coresight/rvtrace-timestamp.c | 278 ++++ .../hwtracing/coresight/rvtrace-timestamp.h | 64 + include/linux/coresight-pmu.h | 4 + include/linux/rvtrace.h | 116 ++ tools/arch/riscv/include/asm/insn.h | 645 ++++++++ tools/perf/arch/riscv/util/Build | 2 + tools/perf/arch/riscv/util/auxtrace.c | 490 ++++++ tools/perf/arch/riscv/util/pmu.c | 20 + tools/perf/util/Build | 3 + tools/perf/util/auxtrace.c | 4 + tools/perf/util/auxtrace.h | 1 + tools/perf/util/nexus-rv-decoder/Build | 1 + .../util/nexus-rv-decoder/nexus-rv-decoder.c | 1364 +++++++++++++++++ .../util/nexus-rv-decoder/nexus-rv-decoder.h | 139 ++ .../perf/util/nexus-rv-decoder/nexus-rv-msg.h | 190 +++ tools/perf/util/rvtrace-decoder.c | 1039 +++++++++++++ tools/perf/util/rvtrace.h | 40 + tools/perf/util/symbol-elf.c | 4 + 34 files changed, 6320 insertions(+), 3 deletions(-) create mode 100644 drivers/hwtracing/coresight/rvtrace-atbbridge.c create mode 100644 drivers/hwtracing/coresight/rvtrace-core.c create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-core.c create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-sysfs.c create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder.h create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.c create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.h create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.c create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.h create mode 100644 include/linux/rvtrace.h create mode 100644 tools/arch/riscv/include/asm/insn.h 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/util/nexus-rv-decoder/Build create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.c create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.h create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-msg.h create mode 100644 tools/perf/util/rvtrace-decoder.c create mode 100644 tools/perf/util/rvtrace.h
From: liangzhen <zhen.liang@spacemit.com>
This series adds Linux RISC-V trace support via CoreSight, implementing RISC-V
trace drivers within the CoreSight framework and integrating them with perf tools.
The K3 SoC contains RISC-V Encoder, Funnel, ATB, CoreSight Funnel, and CoreSight TMC
components, which can be directly leveraged through the existing CoreSight infrastructure.
Linux RISC-V trace support form Anup Patel:
(https://patchwork.kernel.org/project/linux-riscv/cover/20260225062448.4027948-1-anup.patel@oss.qualcomm.com/)
which currently lacks ATB component support and guidance on reusing CoreSight components.
The series includes:
- RISC-V trace driver implementation within the CoreSight framework
- RISC-V Trace Encoder, Funnel, and ATB Bridge drivers as CoreSight devices
- RISC-V trace PMU record capabilities and parsing events in perf.
- RISC-V Nexus Trace decoder for perf tools
Any comments or suggestions are welcome.
Verification on K3 SoC:
To verify this patch series on K3 hardware, the following device tree are required:
1. RISC-V Trace Encoder node (8)
2. RISC-V ATB Bridge node (8)
3. RISC-V Trace Funnel node (2)
3. CoreSight Funnel configuration for RISC-V (1)
4. CoreSight TMC configuration for trace buffer (1)
/{
dummy_clk: apb-pclk {
compatible = "fixed-clock";
#clock-cells = <0x0>;
clock-output-names = "clk14mhz";
clock-frequency = <14000000>;
};
soc: soc {
#address-cells = <2>;
#size-cells = <2>;
encoder0: encoder@d9002000 {
compatible = "riscv,trace-encoder";
reg = <0x0 0xd9002000 0x0 0x1000>;
cpus = <&cpu_0>;
out-ports {
port {
cluster0_encoder0_out_port: endpoint {
remote-endpoint = <&cluster0_bridge0_in_port>;
};
};
};
};
bridge0: bridge@d9003000 {
compatible = "riscv,trace-atbbridge";
reg = <0x0 0xd9003000 0x0 0x1000>;
cpus = <&cpu_0>;
out-ports {
port {
cluster0_bridge0_out_port: endpoint {
remote-endpoint = <&cluster0_funnel_in_port0>;
};
};
};
in-ports {
port {
cluster0_bridge0_in_port: endpoint {
remote-endpoint = <&cluster0_encoder0_out_port>;
};
};
};
};
...
cluster0_funnel: funnel@d9000000 {
compatible = "riscv,trace-funnel";
reg = <0x0 0xd9000000 0x0 0x1000>;
cpus = <&cpu_0>, <&cpu_1>, <&cpu_2>, <&cpu_3>;
riscv,timestamp-present;
out-ports {
port {
cluster0_funnel_out_port: endpoint {
remote-endpoint = <&main_funnel_in_port0>;
};
};
};
in-ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
cluster0_funnel_in_port0: endpoint {
remote-endpoint = <&cluster0_bridge0_out_port>;
};
};
port@1 {
reg = <1>;
cluster0_funnel_in_port1: endpoint {
remote-endpoint = <&cluster0_bridge1_out_port>;
};
};
port@2 {
reg = <2>;
cluster0_funnel_in_port2: endpoint {
remote-endpoint = <&cluster0_bridge2_out_port>;
};
};
port@3 {
reg = <3>;
cluster0_funnel_in_port3: endpoint {
remote-endpoint = <&cluster0_bridge3_out_port>;
};
};
};
};
cluster1_funnel: funnel@d9010000 {
compatible = "riscv,trace-funnel";
reg = <0x0 0xd9010000 0x0 0x1000>;
cpus = <&cpu_4>, <&cpu_5>, <&cpu_6>, <&cpu_7>;
riscv,timestamp-present;
out-ports {
port {
cluster1_funnel_out_port: endpoint {
remote-endpoint = <&main_funnel_in_port1>;
};
};
};
in-ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
cluster1_funnel_in_port0: endpoint {
remote-endpoint = <&cluster1_bridge0_out_port>;
};
};
port@1 {
reg = <1>;
cluster1_funnel_in_port1: endpoint {
remote-endpoint = <&cluster1_bridge1_out_port>;
};
};
port@2 {
reg = <2>;
cluster1_funnel_in_port2: endpoint {
remote-endpoint = <&cluster1_bridge2_out_port>;
};
};
port@3 {
reg = <3>;
cluster1_funnel_in_port3: endpoint {
remote-endpoint = <&cluster1_bridge3_out_port>;
};
};
};
};
main_funnel: funnel@d9042000 {
compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
reg = <0x0 0xd9042000 0x0 0x1000>;
clocks = <&dummy_clk>;
clock-names = "apb_pclk";
out-ports {
port {
main_funnel_out_port: endpoint {
remote-endpoint = <&etf_in_port>;
};
};
};
in-ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
main_funnel_in_port0: endpoint {
remote-endpoint = <&cluster0_funnel_out_port>;
};
};
port@1 {
reg = <1>;
main_funnel_in_port1: endpoint {
remote-endpoint = <&cluster1_funnel_out_port>;
};
};
};
};
etf: etf@d9043000 {
compatible = "arm,coresight-tmc", "arm,primecell";
reg = <0x0 0xd9043000 0x0 0x1000>;
clocks = <&dummy_clk>;
clock-names = "apb_pclk";
out-ports {
port {
etf_out_port: endpoint {
remote-endpoint = <&etr_in_port>;
};
};
};
in-ports {
port {
etf_in_port: endpoint {
remote-endpoint = <&main_funnel_out_port>;
};
};
};
};
etr: etr@d9044000 {
compatible = "arm,coresight-tmc", "arm,primecell";
reg = <0x0 0xd9044000 0x0 0x1000>;
clocks = <&dummy_clk>;
clock-names = "apb_pclk";
arm,scatter-gather;
in-ports {
port {
etr_in_port: endpoint {
remote-endpoint = <&etf_out_port>;
};
};
};
};
};
};
Verification case:
~ # perf list pmu
rvtrace// [Kernel PMU event]
~ # perf record -e rvtrace/@tmc_etr0/ --per-thread uname
Linux
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.191 MB perf.data ]
~ # perf script
uname 137 [003] 1 branches: ffffffff80931470 rvtrace_poll_bit+0x38 ([kernel.kallsyms]) => ffffffff80931492 rvtrace_poll_bit+0x5a ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff809328a6 encoder_enable_hw+0x252 ([kernel.kallsyms]) => ffffffff809328ba encoder_enable_hw+0x266 ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff80932c4a encoder_enable+0x82 ([kernel.kallsyms]) => ffffffff80932c36 encoder_enable+0x6e ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff80928198 etm_event_start+0xf0 ([kernel.kallsyms]) => ffffffff809281aa etm_event_start+0x102 ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff809281e6 etm_event_start+0x13e ([kernel.kallsyms]) => ffffffff8092755e coresight_get_sink_id+0x16 ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff8092820e etm_event_start+0x166 ([kernel.kallsyms]) => ffffffff80928226 etm_event_start+0x17e ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff801c3bb4 perf_report_aux_output_id+0x0 ([kernel.kallsyms]) => ffffffff801c3bd6 perf_report_aux_output_id+0x22 ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff801c3c5a perf_report_aux_output_id+0xa6 ([kernel.kallsyms]) => ffffffff801c3bf0 perf_report_aux_output_id+0x3c ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff801c3c40 perf_report_aux_output_id+0x8c ([kernel.kallsyms]) => ffffffff801c3aea __perf_event_header__init_id+0x2a ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff801c3b42 __perf_event_header__init_id+0x82 ([kernel.kallsyms]) => ffffffff801c3b4a __perf_event_header__init_id+0x8a ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff801c3bb0 __perf_event_header__init_id+0xf0 ([kernel.kallsyms]) => ffffffff801c3b58 __perf_event_header__init_id+0x98 ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff8004c658 __task_pid_nr_ns+0x0 ([kernel.kallsyms]) => ffffffff8004c696 __task_pid_nr_ns+0x3e ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff8004c71e __task_pid_nr_ns+0xc6 ([kernel.kallsyms]) => ffffffff8004c6a4 __task_pid_nr_ns+0x4c ([kernel.kallsyms])
uname 137 [003] 1 branches: ffffffff8004c6e4 __task_pid_nr_ns+0x8c ([kernel.kallsyms]) => ffffffff8004c6e4 __task_pid_nr_ns+0x8c ([kernel.kallsyms])
...
liangzhen (12):
coresight: Add RISC-V support to CoreSight tracing
coresight: Initial implementation of RISC-V trace driver
coresight: Add RISC-V Trace Encoder driver
coresight: Add RISC-V Trace Funnel driver
coresight: Add RISC-V Trace ATB Bridge driver
coresight rvtrace: Add timestamp component support for encoder and
funnel
coresight: Add RISC-V PMU name support
perf tools: riscv: making rvtrace PMU listable
perf tools: Add RISC-V trace PMU record capabilities
perf tools: Add Nexus RISC-V Trace decoder
perf symbols: Add RISC-V PLT entry sizes
perf tools: Integrate RISC-V trace decoder into auxtrace
drivers/hwtracing/Kconfig | 2 +
drivers/hwtracing/coresight/Kconfig | 46 +-
drivers/hwtracing/coresight/Makefile | 6 +
drivers/hwtracing/coresight/coresight-core.c | 8 +
.../hwtracing/coresight/coresight-etm-perf.c | 1 -
.../hwtracing/coresight/coresight-etm-perf.h | 21 +
.../hwtracing/coresight/coresight-platform.c | 1 -
.../hwtracing/coresight/coresight-tmc-etf.c | 4 +
.../hwtracing/coresight/coresight-tmc-etr.c | 4 +
.../hwtracing/coresight/rvtrace-atbbridge.c | 239 +++
drivers/hwtracing/coresight/rvtrace-core.c | 135 ++
.../coresight/rvtrace-encoder-core.c | 562 +++++++
.../coresight/rvtrace-encoder-sysfs.c | 363 +++++
drivers/hwtracing/coresight/rvtrace-encoder.h | 151 ++
drivers/hwtracing/coresight/rvtrace-funnel.c | 337 ++++
drivers/hwtracing/coresight/rvtrace-funnel.h | 39 +
.../hwtracing/coresight/rvtrace-timestamp.c | 278 ++++
.../hwtracing/coresight/rvtrace-timestamp.h | 64 +
include/linux/coresight-pmu.h | 4 +
include/linux/rvtrace.h | 116 ++
tools/arch/riscv/include/asm/insn.h | 645 ++++++++
tools/perf/arch/riscv/util/Build | 2 +
tools/perf/arch/riscv/util/auxtrace.c | 490 ++++++
tools/perf/arch/riscv/util/pmu.c | 20 +
tools/perf/util/Build | 3 +
tools/perf/util/auxtrace.c | 4 +
tools/perf/util/auxtrace.h | 1 +
tools/perf/util/nexus-rv-decoder/Build | 1 +
.../util/nexus-rv-decoder/nexus-rv-decoder.c | 1364 +++++++++++++++++
.../util/nexus-rv-decoder/nexus-rv-decoder.h | 139 ++
.../perf/util/nexus-rv-decoder/nexus-rv-msg.h | 190 +++
tools/perf/util/rvtrace-decoder.c | 1039 +++++++++++++
tools/perf/util/rvtrace.h | 40 +
tools/perf/util/symbol-elf.c | 4 +
34 files changed, 6320 insertions(+), 3 deletions(-)
create mode 100644 drivers/hwtracing/coresight/rvtrace-atbbridge.c
create mode 100644 drivers/hwtracing/coresight/rvtrace-core.c
create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-core.c
create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-sysfs.c
create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder.h
create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.c
create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.h
create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.c
create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.h
create mode 100644 include/linux/rvtrace.h
create mode 100644 tools/arch/riscv/include/asm/insn.h
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/util/nexus-rv-decoder/Build
create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.c
create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.h
create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-msg.h
create mode 100644 tools/perf/util/rvtrace-decoder.c
create mode 100644 tools/perf/util/rvtrace.h
--
2.34.1
On Tue, Apr 14, 2026 at 9:12 AM Zane Leung <liangzhen@linux.spacemit.com> wrote:
>
> From: liangzhen <zhen.liang@spacemit.com>
>
> This series adds Linux RISC-V trace support via CoreSight, implementing RISC-V
> trace drivers within the CoreSight framework and integrating them with perf tools.
> The K3 SoC contains RISC-V Encoder, Funnel, ATB, CoreSight Funnel, and CoreSight TMC
> components, which can be directly leveraged through the existing CoreSight infrastructure.
>
> Linux RISC-V trace support form Anup Patel:
> (https://patchwork.kernel.org/project/linux-riscv/cover/20260225062448.4027948-1-anup.patel@oss.qualcomm.com/)
> which currently lacks ATB component support and guidance on reusing CoreSight components.
What stops you from adding RISC-V trace funnel and ATB bridge drivers
on top of this series ?
>
> The series includes:
> - RISC-V trace driver implementation within the CoreSight framework
The RISC-V trace very different from the CoreSight framework in many ways:
1) Types of components supported
2) Trace packet formats
3) The way MMIO based components are discoverd
4) ... and more ...
> - RISC-V Trace Encoder, Funnel, and ATB Bridge drivers as CoreSight devices
> - RISC-V trace PMU record capabilities and parsing events in perf.
> - RISC-V Nexus Trace decoder for perf tools
>
> Any comments or suggestions are welcome.
>
> Verification on K3 SoC:
> To verify this patch series on K3 hardware, the following device tree are required:
> 1. RISC-V Trace Encoder node (8)
> 2. RISC-V ATB Bridge node (8)
> 3. RISC-V Trace Funnel node (2)
> 3. CoreSight Funnel configuration for RISC-V (1)
> 4. CoreSight TMC configuration for trace buffer (1)
>
> /{
> dummy_clk: apb-pclk {
> compatible = "fixed-clock";
> #clock-cells = <0x0>;
> clock-output-names = "clk14mhz";
> clock-frequency = <14000000>;
> };
>
>
> soc: soc {
> #address-cells = <2>;
> #size-cells = <2>;
>
> encoder0: encoder@d9002000 {
> compatible = "riscv,trace-encoder";
> reg = <0x0 0xd9002000 0x0 0x1000>;
> cpus = <&cpu_0>;
> out-ports {
> port {
> cluster0_encoder0_out_port: endpoint {
> remote-endpoint = <&cluster0_bridge0_in_port>;
> };
> };
> };
> };
>
> bridge0: bridge@d9003000 {
> compatible = "riscv,trace-atbbridge";
> reg = <0x0 0xd9003000 0x0 0x1000>;
> cpus = <&cpu_0>;
> out-ports {
> port {
> cluster0_bridge0_out_port: endpoint {
> remote-endpoint = <&cluster0_funnel_in_port0>;
> };
> };
> };
> in-ports {
> port {
> cluster0_bridge0_in_port: endpoint {
> remote-endpoint = <&cluster0_encoder0_out_port>;
> };
> };
> };
> };
>
> ...
>
> cluster0_funnel: funnel@d9000000 {
> compatible = "riscv,trace-funnel";
> reg = <0x0 0xd9000000 0x0 0x1000>;
> cpus = <&cpu_0>, <&cpu_1>, <&cpu_2>, <&cpu_3>;
> riscv,timestamp-present;
> out-ports {
> port {
> cluster0_funnel_out_port: endpoint {
> remote-endpoint = <&main_funnel_in_port0>;
> };
> };
> };
> in-ports {
> #address-cells = <1>;
> #size-cells = <0>;
>
> port@0 {
> reg = <0>;
> cluster0_funnel_in_port0: endpoint {
> remote-endpoint = <&cluster0_bridge0_out_port>;
> };
> };
>
> port@1 {
> reg = <1>;
> cluster0_funnel_in_port1: endpoint {
> remote-endpoint = <&cluster0_bridge1_out_port>;
> };
> };
>
> port@2 {
> reg = <2>;
> cluster0_funnel_in_port2: endpoint {
> remote-endpoint = <&cluster0_bridge2_out_port>;
> };
> };
>
> port@3 {
> reg = <3>;
> cluster0_funnel_in_port3: endpoint {
> remote-endpoint = <&cluster0_bridge3_out_port>;
> };
> };
> };
> };
>
> cluster1_funnel: funnel@d9010000 {
> compatible = "riscv,trace-funnel";
> reg = <0x0 0xd9010000 0x0 0x1000>;
> cpus = <&cpu_4>, <&cpu_5>, <&cpu_6>, <&cpu_7>;
> riscv,timestamp-present;
> out-ports {
> port {
> cluster1_funnel_out_port: endpoint {
> remote-endpoint = <&main_funnel_in_port1>;
> };
> };
> };
> in-ports {
> #address-cells = <1>;
> #size-cells = <0>;
>
> port@0 {
> reg = <0>;
> cluster1_funnel_in_port0: endpoint {
> remote-endpoint = <&cluster1_bridge0_out_port>;
> };
> };
>
> port@1 {
> reg = <1>;
> cluster1_funnel_in_port1: endpoint {
> remote-endpoint = <&cluster1_bridge1_out_port>;
> };
> };
>
> port@2 {
> reg = <2>;
> cluster1_funnel_in_port2: endpoint {
> remote-endpoint = <&cluster1_bridge2_out_port>;
> };
> };
>
> port@3 {
> reg = <3>;
> cluster1_funnel_in_port3: endpoint {
> remote-endpoint = <&cluster1_bridge3_out_port>;
> };
> };
> };
> };
>
> main_funnel: funnel@d9042000 {
> compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
Is it legally allowed to mix and match ARM coresight IPs with
RISC-V trace components at hardware level ?
> reg = <0x0 0xd9042000 0x0 0x1000>;
> clocks = <&dummy_clk>;
> clock-names = "apb_pclk";
> out-ports {
> port {
> main_funnel_out_port: endpoint {
> remote-endpoint = <&etf_in_port>;
> };
> };
> };
> in-ports {
> #address-cells = <1>;
> #size-cells = <0>;
>
> port@0 {
> reg = <0>;
> main_funnel_in_port0: endpoint {
> remote-endpoint = <&cluster0_funnel_out_port>;
> };
> };
>
> port@1 {
> reg = <1>;
> main_funnel_in_port1: endpoint {
> remote-endpoint = <&cluster1_funnel_out_port>;
> };
> };
> };
> };
>
> etf: etf@d9043000 {
> compatible = "arm,coresight-tmc", "arm,primecell";
> reg = <0x0 0xd9043000 0x0 0x1000>;
> clocks = <&dummy_clk>;
> clock-names = "apb_pclk";
> out-ports {
> port {
> etf_out_port: endpoint {
> remote-endpoint = <&etr_in_port>;
> };
> };
> };
> in-ports {
> port {
> etf_in_port: endpoint {
> remote-endpoint = <&main_funnel_out_port>;
> };
> };
> };
> };
>
> etr: etr@d9044000 {
> compatible = "arm,coresight-tmc", "arm,primecell";
> reg = <0x0 0xd9044000 0x0 0x1000>;
> clocks = <&dummy_clk>;
> clock-names = "apb_pclk";
> arm,scatter-gather;
> in-ports {
> port {
> etr_in_port: endpoint {
> remote-endpoint = <&etf_out_port>;
> };
> };
> };
> };
> };
> };
>
> Verification case:
>
> ~ # perf list pmu
> rvtrace// [Kernel PMU event]
>
> ~ # perf record -e rvtrace/@tmc_etr0/ --per-thread uname
> Linux
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 0.191 MB perf.data ]
> ~ # perf script
> uname 137 [003] 1 branches: ffffffff80931470 rvtrace_poll_bit+0x38 ([kernel.kallsyms]) => ffffffff80931492 rvtrace_poll_bit+0x5a ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff809328a6 encoder_enable_hw+0x252 ([kernel.kallsyms]) => ffffffff809328ba encoder_enable_hw+0x266 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff80932c4a encoder_enable+0x82 ([kernel.kallsyms]) => ffffffff80932c36 encoder_enable+0x6e ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff80928198 etm_event_start+0xf0 ([kernel.kallsyms]) => ffffffff809281aa etm_event_start+0x102 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff809281e6 etm_event_start+0x13e ([kernel.kallsyms]) => ffffffff8092755e coresight_get_sink_id+0x16 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff8092820e etm_event_start+0x166 ([kernel.kallsyms]) => ffffffff80928226 etm_event_start+0x17e ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3bb4 perf_report_aux_output_id+0x0 ([kernel.kallsyms]) => ffffffff801c3bd6 perf_report_aux_output_id+0x22 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3c5a perf_report_aux_output_id+0xa6 ([kernel.kallsyms]) => ffffffff801c3bf0 perf_report_aux_output_id+0x3c ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3c40 perf_report_aux_output_id+0x8c ([kernel.kallsyms]) => ffffffff801c3aea __perf_event_header__init_id+0x2a ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3b42 __perf_event_header__init_id+0x82 ([kernel.kallsyms]) => ffffffff801c3b4a __perf_event_header__init_id+0x8a ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3bb0 __perf_event_header__init_id+0xf0 ([kernel.kallsyms]) => ffffffff801c3b58 __perf_event_header__init_id+0x98 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff8004c658 __task_pid_nr_ns+0x0 ([kernel.kallsyms]) => ffffffff8004c696 __task_pid_nr_ns+0x3e ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff8004c71e __task_pid_nr_ns+0xc6 ([kernel.kallsyms]) => ffffffff8004c6a4 __task_pid_nr_ns+0x4c ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff8004c6e4 __task_pid_nr_ns+0x8c ([kernel.kallsyms]) => ffffffff8004c6e4 __task_pid_nr_ns+0x8c ([kernel.kallsyms])
> ...
>
> liangzhen (12):
> coresight: Add RISC-V support to CoreSight tracing
> coresight: Initial implementation of RISC-V trace driver
> coresight: Add RISC-V Trace Encoder driver
> coresight: Add RISC-V Trace Funnel driver
> coresight: Add RISC-V Trace ATB Bridge driver
> coresight rvtrace: Add timestamp component support for encoder and
> funnel
> coresight: Add RISC-V PMU name support
> perf tools: riscv: making rvtrace PMU listable
> perf tools: Add RISC-V trace PMU record capabilities
> perf tools: Add Nexus RISC-V Trace decoder
> perf symbols: Add RISC-V PLT entry sizes
> perf tools: Integrate RISC-V trace decoder into auxtrace
>
> drivers/hwtracing/Kconfig | 2 +
> drivers/hwtracing/coresight/Kconfig | 46 +-
> drivers/hwtracing/coresight/Makefile | 6 +
> drivers/hwtracing/coresight/coresight-core.c | 8 +
> .../hwtracing/coresight/coresight-etm-perf.c | 1 -
> .../hwtracing/coresight/coresight-etm-perf.h | 21 +
> .../hwtracing/coresight/coresight-platform.c | 1 -
> .../hwtracing/coresight/coresight-tmc-etf.c | 4 +
> .../hwtracing/coresight/coresight-tmc-etr.c | 4 +
> .../hwtracing/coresight/rvtrace-atbbridge.c | 239 +++
> drivers/hwtracing/coresight/rvtrace-core.c | 135 ++
> .../coresight/rvtrace-encoder-core.c | 562 +++++++
> .../coresight/rvtrace-encoder-sysfs.c | 363 +++++
> drivers/hwtracing/coresight/rvtrace-encoder.h | 151 ++
> drivers/hwtracing/coresight/rvtrace-funnel.c | 337 ++++
> drivers/hwtracing/coresight/rvtrace-funnel.h | 39 +
> .../hwtracing/coresight/rvtrace-timestamp.c | 278 ++++
> .../hwtracing/coresight/rvtrace-timestamp.h | 64 +
> include/linux/coresight-pmu.h | 4 +
> include/linux/rvtrace.h | 116 ++
> tools/arch/riscv/include/asm/insn.h | 645 ++++++++
> tools/perf/arch/riscv/util/Build | 2 +
> tools/perf/arch/riscv/util/auxtrace.c | 490 ++++++
> tools/perf/arch/riscv/util/pmu.c | 20 +
> tools/perf/util/Build | 3 +
> tools/perf/util/auxtrace.c | 4 +
> tools/perf/util/auxtrace.h | 1 +
> tools/perf/util/nexus-rv-decoder/Build | 1 +
> .../util/nexus-rv-decoder/nexus-rv-decoder.c | 1364 +++++++++++++++++
> .../util/nexus-rv-decoder/nexus-rv-decoder.h | 139 ++
> .../perf/util/nexus-rv-decoder/nexus-rv-msg.h | 190 +++
> tools/perf/util/rvtrace-decoder.c | 1039 +++++++++++++
> tools/perf/util/rvtrace.h | 40 +
> tools/perf/util/symbol-elf.c | 4 +
> 34 files changed, 6320 insertions(+), 3 deletions(-)
> create mode 100644 drivers/hwtracing/coresight/rvtrace-atbbridge.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-core.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-core.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-sysfs.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder.h
> create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.h
> create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.h
> create mode 100644 include/linux/rvtrace.h
> create mode 100644 tools/arch/riscv/include/asm/insn.h
> 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/util/nexus-rv-decoder/Build
> create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.c
> create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.h
> create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-msg.h
> create mode 100644 tools/perf/util/rvtrace-decoder.c
> create mode 100644 tools/perf/util/rvtrace.h
>
> --
> 2.34.1
>
NACK to this approach of retrofitting RISC-V trace into ARM coresight.
Regards,
Anup
On 4/14/2026 3:23 PM, Anup Patel wrote:
> On Tue, Apr 14, 2026 at 9:12 AM Zane Leung <liangzhen@linux.spacemit.com> wrote:
>> From: liangzhen <zhen.liang@spacemit.com>
>>
>> This series adds Linux RISC-V trace support via CoreSight, implementing RISC-V
>> trace drivers within the CoreSight framework and integrating them with perf tools.
>> The K3 SoC contains RISC-V Encoder, Funnel, ATB, CoreSight Funnel, and CoreSight TMC
>> components, which can be directly leveraged through the existing CoreSight infrastructure.
>>
>> Linux RISC-V trace support form Anup Patel:
>> (https://patchwork.kernel.org/project/linux-riscv/cover/20260225062448.4027948-1-anup.patel@oss.qualcomm.com/)
>> which currently lacks ATB component support and guidance on reusing CoreSight components.
> What stops you from adding RISC-V trace funnel and ATB bridge drivers
> on top of this series ?
>
Firstly, my works started much earlier than this series. Secondly, it is difficult to add the coresight funnel and coresight tmc components to this series. Based on the coresight framework, I can directly reuse them.
>
>> The series includes:
>> - RISC-V trace driver implementation within the CoreSight framework
> The RISC-V trace very different from the CoreSight framework in many ways:
> 1) Types of components supported
> 2) Trace packet formats
> 3) The way MMIO based components are discoverd
> 4) ... and more ...
1) I believe that RISC-V tracing is coresight-alike, where have encoders/funnel/sink/bridge that are described through DT and controlled by MMIO.
2) I think the difference in package format is nothing more than the coresight frame generated by the ATB component to distinguish the trace source. After removing it, it becomes riscv trace data.
3) The current CoreSight framework code does not introduce this mechanism, it is described through DT.
>> - RISC-V Trace Encoder, Funnel, and ATB Bridge drivers as CoreSight devices
>> - RISC-V trace PMU record capabilities and parsing events in perf.
>> - RISC-V Nexus Trace decoder for perf tools
>>
>> Any comments or suggestions are welcome.
>>
>> Verification on K3 SoC:
>> To verify this patch series on K3 hardware, the following device tree are required:
>> 1. RISC-V Trace Encoder node (8)
>> 2. RISC-V ATB Bridge node (8)
>> 3. RISC-V Trace Funnel node (2)
>> 3. CoreSight Funnel configuration for RISC-V (1)
>> 4. CoreSight TMC configuration for trace buffer (1)
>>
>> /{
>> dummy_clk: apb-pclk {
>> compatible = "fixed-clock";
>> #clock-cells = <0x0>;
>> clock-output-names = "clk14mhz";
>> clock-frequency = <14000000>;
>> };
>>
>>
>> soc: soc {
>> #address-cells = <2>;
>> #size-cells = <2>;
>>
>> encoder0: encoder@d9002000 {
>> compatible = "riscv,trace-encoder";
>> reg = <0x0 0xd9002000 0x0 0x1000>;
>> cpus = <&cpu_0>;
>> out-ports {
>> port {
>> cluster0_encoder0_out_port: endpoint {
>> remote-endpoint = <&cluster0_bridge0_in_port>;
>> };
>> };
>> };
>> };
>>
>> bridge0: bridge@d9003000 {
>> compatible = "riscv,trace-atbbridge";
>> reg = <0x0 0xd9003000 0x0 0x1000>;
>> cpus = <&cpu_0>;
>> out-ports {
>> port {
>> cluster0_bridge0_out_port: endpoint {
>> remote-endpoint = <&cluster0_funnel_in_port0>;
>> };
>> };
>> };
>> in-ports {
>> port {
>> cluster0_bridge0_in_port: endpoint {
>> remote-endpoint = <&cluster0_encoder0_out_port>;
>> };
>> };
>> };
>> };
>>
>> ...
>>
>> cluster0_funnel: funnel@d9000000 {
>> compatible = "riscv,trace-funnel";
>> reg = <0x0 0xd9000000 0x0 0x1000>;
>> cpus = <&cpu_0>, <&cpu_1>, <&cpu_2>, <&cpu_3>;
>> riscv,timestamp-present;
>> out-ports {
>> port {
>> cluster0_funnel_out_port: endpoint {
>> remote-endpoint = <&main_funnel_in_port0>;
>> };
>> };
>> };
>> in-ports {
>> #address-cells = <1>;
>> #size-cells = <0>;
>>
>> port@0 {
>> reg = <0>;
>> cluster0_funnel_in_port0: endpoint {
>> remote-endpoint = <&cluster0_bridge0_out_port>;
>> };
>> };
>>
>> port@1 {
>> reg = <1>;
>> cluster0_funnel_in_port1: endpoint {
>> remote-endpoint = <&cluster0_bridge1_out_port>;
>> };
>> };
>>
>> port@2 {
>> reg = <2>;
>> cluster0_funnel_in_port2: endpoint {
>> remote-endpoint = <&cluster0_bridge2_out_port>;
>> };
>> };
>>
>> port@3 {
>> reg = <3>;
>> cluster0_funnel_in_port3: endpoint {
>> remote-endpoint = <&cluster0_bridge3_out_port>;
>> };
>> };
>> };
>> };
>>
>> cluster1_funnel: funnel@d9010000 {
>> compatible = "riscv,trace-funnel";
>> reg = <0x0 0xd9010000 0x0 0x1000>;
>> cpus = <&cpu_4>, <&cpu_5>, <&cpu_6>, <&cpu_7>;
>> riscv,timestamp-present;
>> out-ports {
>> port {
>> cluster1_funnel_out_port: endpoint {
>> remote-endpoint = <&main_funnel_in_port1>;
>> };
>> };
>> };
>> in-ports {
>> #address-cells = <1>;
>> #size-cells = <0>;
>>
>> port@0 {
>> reg = <0>;
>> cluster1_funnel_in_port0: endpoint {
>> remote-endpoint = <&cluster1_bridge0_out_port>;
>> };
>> };
>>
>> port@1 {
>> reg = <1>;
>> cluster1_funnel_in_port1: endpoint {
>> remote-endpoint = <&cluster1_bridge1_out_port>;
>> };
>> };
>>
>> port@2 {
>> reg = <2>;
>> cluster1_funnel_in_port2: endpoint {
>> remote-endpoint = <&cluster1_bridge2_out_port>;
>> };
>> };
>>
>> port@3 {
>> reg = <3>;
>> cluster1_funnel_in_port3: endpoint {
>> remote-endpoint = <&cluster1_bridge3_out_port>;
>> };
>> };
>> };
>> };
>>
>> main_funnel: funnel@d9042000 {
>> compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
> Is it legally allowed to mix and match ARM coresight IPs with
> RISC-V trace components at hardware level ?
The ATB Bridge allows sending RISC-V trace to Arm CoreSight infrastructure (instead of RISC-V compliant sink defined in this document) as an ATB initiator. see:
https://github.com/riscv-non-isa/riscv-nexus-trace/blob/105dc1c349556622e4d202d22b584a887ded462f/docs/RISC-V-Trace-Control-Interface.adoc#L184
For ATB Bridge, read trace using Coresight components (ETB/TMC/TPIU). see:
https://github.com/riscv-non-isa/riscv-nexus-trace/blob/105dc1c349556622e4d202d22b584a887ded462f/docs/RISC-V-Trace-Control-Interface.adoc#L1684
>
>> reg = <0x0 0xd9042000 0x0 0x1000>;
>> clocks = <&dummy_clk>;
>> clock-names = "apb_pclk";
>> out-ports {
>> port {
>> main_funnel_out_port: endpoint {
>> remote-endpoint = <&etf_in_port>;
>> };
>> };
>> };
>> in-ports {
>> #address-cells = <1>;
>> #size-cells = <0>;
>>
>> port@0 {
>> reg = <0>;
>> main_funnel_in_port0: endpoint {
>> remote-endpoint = <&cluster0_funnel_out_port>;
>> };
>> };
>>
>> port@1 {
>> reg = <1>;
>> main_funnel_in_port1: endpoint {
>> remote-endpoint = <&cluster1_funnel_out_port>;
>> };
>> };
>> };
>> };
>>
>> etf: etf@d9043000 {
>> compatible = "arm,coresight-tmc", "arm,primecell";
>> reg = <0x0 0xd9043000 0x0 0x1000>;
>> clocks = <&dummy_clk>;
>> clock-names = "apb_pclk";
>> out-ports {
>> port {
>> etf_out_port: endpoint {
>> remote-endpoint = <&etr_in_port>;
>> };
>> };
>> };
>> in-ports {
>> port {
>> etf_in_port: endpoint {
>> remote-endpoint = <&main_funnel_out_port>;
>> };
>> };
>> };
>> };
>>
>> etr: etr@d9044000 {
>> compatible = "arm,coresight-tmc", "arm,primecell";
>> reg = <0x0 0xd9044000 0x0 0x1000>;
>> clocks = <&dummy_clk>;
>> clock-names = "apb_pclk";
>> arm,scatter-gather;
>> in-ports {
>> port {
>> etr_in_port: endpoint {
>> remote-endpoint = <&etf_out_port>;
>> };
>> };
>> };
>> };
>> };
>> };
>>
>> Verification case:
>>
>> ~ # perf list pmu
>> rvtrace// [Kernel PMU event]
>>
>> ~ # perf record -e rvtrace/@tmc_etr0/ --per-thread uname
>> Linux
>> [ perf record: Woken up 1 times to write data ]
>> [ perf record: Captured and wrote 0.191 MB perf.data ]
>> ~ # perf script
>> uname 137 [003] 1 branches: ffffffff80931470 rvtrace_poll_bit+0x38 ([kernel.kallsyms]) => ffffffff80931492 rvtrace_poll_bit+0x5a ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff809328a6 encoder_enable_hw+0x252 ([kernel.kallsyms]) => ffffffff809328ba encoder_enable_hw+0x266 ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff80932c4a encoder_enable+0x82 ([kernel.kallsyms]) => ffffffff80932c36 encoder_enable+0x6e ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff80928198 etm_event_start+0xf0 ([kernel.kallsyms]) => ffffffff809281aa etm_event_start+0x102 ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff809281e6 etm_event_start+0x13e ([kernel.kallsyms]) => ffffffff8092755e coresight_get_sink_id+0x16 ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff8092820e etm_event_start+0x166 ([kernel.kallsyms]) => ffffffff80928226 etm_event_start+0x17e ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff801c3bb4 perf_report_aux_output_id+0x0 ([kernel.kallsyms]) => ffffffff801c3bd6 perf_report_aux_output_id+0x22 ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff801c3c5a perf_report_aux_output_id+0xa6 ([kernel.kallsyms]) => ffffffff801c3bf0 perf_report_aux_output_id+0x3c ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff801c3c40 perf_report_aux_output_id+0x8c ([kernel.kallsyms]) => ffffffff801c3aea __perf_event_header__init_id+0x2a ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff801c3b42 __perf_event_header__init_id+0x82 ([kernel.kallsyms]) => ffffffff801c3b4a __perf_event_header__init_id+0x8a ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff801c3bb0 __perf_event_header__init_id+0xf0 ([kernel.kallsyms]) => ffffffff801c3b58 __perf_event_header__init_id+0x98 ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff8004c658 __task_pid_nr_ns+0x0 ([kernel.kallsyms]) => ffffffff8004c696 __task_pid_nr_ns+0x3e ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff8004c71e __task_pid_nr_ns+0xc6 ([kernel.kallsyms]) => ffffffff8004c6a4 __task_pid_nr_ns+0x4c ([kernel.kallsyms])
>> uname 137 [003] 1 branches: ffffffff8004c6e4 __task_pid_nr_ns+0x8c ([kernel.kallsyms]) => ffffffff8004c6e4 __task_pid_nr_ns+0x8c ([kernel.kallsyms])
>> ...
>>
>> liangzhen (12):
>> coresight: Add RISC-V support to CoreSight tracing
>> coresight: Initial implementation of RISC-V trace driver
>> coresight: Add RISC-V Trace Encoder driver
>> coresight: Add RISC-V Trace Funnel driver
>> coresight: Add RISC-V Trace ATB Bridge driver
>> coresight rvtrace: Add timestamp component support for encoder and
>> funnel
>> coresight: Add RISC-V PMU name support
>> perf tools: riscv: making rvtrace PMU listable
>> perf tools: Add RISC-V trace PMU record capabilities
>> perf tools: Add Nexus RISC-V Trace decoder
>> perf symbols: Add RISC-V PLT entry sizes
>> perf tools: Integrate RISC-V trace decoder into auxtrace
>>
>> drivers/hwtracing/Kconfig | 2 +
>> drivers/hwtracing/coresight/Kconfig | 46 +-
>> drivers/hwtracing/coresight/Makefile | 6 +
>> drivers/hwtracing/coresight/coresight-core.c | 8 +
>> .../hwtracing/coresight/coresight-etm-perf.c | 1 -
>> .../hwtracing/coresight/coresight-etm-perf.h | 21 +
>> .../hwtracing/coresight/coresight-platform.c | 1 -
>> .../hwtracing/coresight/coresight-tmc-etf.c | 4 +
>> .../hwtracing/coresight/coresight-tmc-etr.c | 4 +
>> .../hwtracing/coresight/rvtrace-atbbridge.c | 239 +++
>> drivers/hwtracing/coresight/rvtrace-core.c | 135 ++
>> .../coresight/rvtrace-encoder-core.c | 562 +++++++
>> .../coresight/rvtrace-encoder-sysfs.c | 363 +++++
>> drivers/hwtracing/coresight/rvtrace-encoder.h | 151 ++
>> drivers/hwtracing/coresight/rvtrace-funnel.c | 337 ++++
>> drivers/hwtracing/coresight/rvtrace-funnel.h | 39 +
>> .../hwtracing/coresight/rvtrace-timestamp.c | 278 ++++
>> .../hwtracing/coresight/rvtrace-timestamp.h | 64 +
>> include/linux/coresight-pmu.h | 4 +
>> include/linux/rvtrace.h | 116 ++
>> tools/arch/riscv/include/asm/insn.h | 645 ++++++++
>> tools/perf/arch/riscv/util/Build | 2 +
>> tools/perf/arch/riscv/util/auxtrace.c | 490 ++++++
>> tools/perf/arch/riscv/util/pmu.c | 20 +
>> tools/perf/util/Build | 3 +
>> tools/perf/util/auxtrace.c | 4 +
>> tools/perf/util/auxtrace.h | 1 +
>> tools/perf/util/nexus-rv-decoder/Build | 1 +
>> .../util/nexus-rv-decoder/nexus-rv-decoder.c | 1364 +++++++++++++++++
>> .../util/nexus-rv-decoder/nexus-rv-decoder.h | 139 ++
>> .../perf/util/nexus-rv-decoder/nexus-rv-msg.h | 190 +++
>> tools/perf/util/rvtrace-decoder.c | 1039 +++++++++++++
>> tools/perf/util/rvtrace.h | 40 +
>> tools/perf/util/symbol-elf.c | 4 +
>> 34 files changed, 6320 insertions(+), 3 deletions(-)
>> create mode 100644 drivers/hwtracing/coresight/rvtrace-atbbridge.c
>> create mode 100644 drivers/hwtracing/coresight/rvtrace-core.c
>> create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-core.c
>> create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-sysfs.c
>> create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder.h
>> create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.c
>> create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.h
>> create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.c
>> create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.h
>> create mode 100644 include/linux/rvtrace.h
>> create mode 100644 tools/arch/riscv/include/asm/insn.h
>> 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/util/nexus-rv-decoder/Build
>> create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.c
>> create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.h
>> create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-msg.h
>> create mode 100644 tools/perf/util/rvtrace-decoder.c
>> create mode 100644 tools/perf/util/rvtrace.h
>>
>> --
>> 2.34.1
>>
> NACK to this approach of retrofitting RISC-V trace into ARM coresight.
I agree that integrating RISC-V trace directly into CoreSight is not a good approach, so I think we should abstract some of the logic of coresight and reuse it in RISC-V Trace.
>
> Regards,
> Anup
Thanks,
Zane
On 4/14/2026 11:41 AM, Zane Leung wrote:
> From: liangzhen <zhen.liang@spacemit.com>
>
I dont think you have looped relevant maintainers and reviewers for the
Coresight subsystem.
Thanks,
Jie
> This series adds Linux RISC-V trace support via CoreSight, implementing RISC-V
> trace drivers within the CoreSight framework and integrating them with perf tools.
> The K3 SoC contains RISC-V Encoder, Funnel, ATB, CoreSight Funnel, and CoreSight TMC
> components, which can be directly leveraged through the existing CoreSight infrastructure.
>
> Linux RISC-V trace support form Anup Patel:
> (https://patchwork.kernel.org/project/linux-riscv/cover/20260225062448.4027948-1-anup.patel@oss.qualcomm.com/)
> which currently lacks ATB component support and guidance on reusing CoreSight components.
>
> The series includes:
> - RISC-V trace driver implementation within the CoreSight framework
> - RISC-V Trace Encoder, Funnel, and ATB Bridge drivers as CoreSight devices
> - RISC-V trace PMU record capabilities and parsing events in perf.
> - RISC-V Nexus Trace decoder for perf tools
>
> Any comments or suggestions are welcome.
>
> Verification on K3 SoC:
> To verify this patch series on K3 hardware, the following device tree are required:
> 1. RISC-V Trace Encoder node (8)
> 2. RISC-V ATB Bridge node (8)
> 3. RISC-V Trace Funnel node (2)
> 3. CoreSight Funnel configuration for RISC-V (1)
> 4. CoreSight TMC configuration for trace buffer (1)
>
> /{
> dummy_clk: apb-pclk {
> compatible = "fixed-clock";
> #clock-cells = <0x0>;
> clock-output-names = "clk14mhz";
> clock-frequency = <14000000>;
> };
>
>
> soc: soc {
> #address-cells = <2>;
> #size-cells = <2>;
>
> encoder0: encoder@d9002000 {
> compatible = "riscv,trace-encoder";
> reg = <0x0 0xd9002000 0x0 0x1000>;
> cpus = <&cpu_0>;
> out-ports {
> port {
> cluster0_encoder0_out_port: endpoint {
> remote-endpoint = <&cluster0_bridge0_in_port>;
> };
> };
> };
> };
>
> bridge0: bridge@d9003000 {
> compatible = "riscv,trace-atbbridge";
> reg = <0x0 0xd9003000 0x0 0x1000>;
> cpus = <&cpu_0>;
> out-ports {
> port {
> cluster0_bridge0_out_port: endpoint {
> remote-endpoint = <&cluster0_funnel_in_port0>;
> };
> };
> };
> in-ports {
> port {
> cluster0_bridge0_in_port: endpoint {
> remote-endpoint = <&cluster0_encoder0_out_port>;
> };
> };
> };
> };
>
> ...
>
> cluster0_funnel: funnel@d9000000 {
> compatible = "riscv,trace-funnel";
> reg = <0x0 0xd9000000 0x0 0x1000>;
> cpus = <&cpu_0>, <&cpu_1>, <&cpu_2>, <&cpu_3>;
> riscv,timestamp-present;
> out-ports {
> port {
> cluster0_funnel_out_port: endpoint {
> remote-endpoint = <&main_funnel_in_port0>;
> };
> };
> };
> in-ports {
> #address-cells = <1>;
> #size-cells = <0>;
>
> port@0 {
> reg = <0>;
> cluster0_funnel_in_port0: endpoint {
> remote-endpoint = <&cluster0_bridge0_out_port>;
> };
> };
>
> port@1 {
> reg = <1>;
> cluster0_funnel_in_port1: endpoint {
> remote-endpoint = <&cluster0_bridge1_out_port>;
> };
> };
>
> port@2 {
> reg = <2>;
> cluster0_funnel_in_port2: endpoint {
> remote-endpoint = <&cluster0_bridge2_out_port>;
> };
> };
>
> port@3 {
> reg = <3>;
> cluster0_funnel_in_port3: endpoint {
> remote-endpoint = <&cluster0_bridge3_out_port>;
> };
> };
> };
> };
>
> cluster1_funnel: funnel@d9010000 {
> compatible = "riscv,trace-funnel";
> reg = <0x0 0xd9010000 0x0 0x1000>;
> cpus = <&cpu_4>, <&cpu_5>, <&cpu_6>, <&cpu_7>;
> riscv,timestamp-present;
> out-ports {
> port {
> cluster1_funnel_out_port: endpoint {
> remote-endpoint = <&main_funnel_in_port1>;
> };
> };
> };
> in-ports {
> #address-cells = <1>;
> #size-cells = <0>;
>
> port@0 {
> reg = <0>;
> cluster1_funnel_in_port0: endpoint {
> remote-endpoint = <&cluster1_bridge0_out_port>;
> };
> };
>
> port@1 {
> reg = <1>;
> cluster1_funnel_in_port1: endpoint {
> remote-endpoint = <&cluster1_bridge1_out_port>;
> };
> };
>
> port@2 {
> reg = <2>;
> cluster1_funnel_in_port2: endpoint {
> remote-endpoint = <&cluster1_bridge2_out_port>;
> };
> };
>
> port@3 {
> reg = <3>;
> cluster1_funnel_in_port3: endpoint {
> remote-endpoint = <&cluster1_bridge3_out_port>;
> };
> };
> };
> };
>
> main_funnel: funnel@d9042000 {
> compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
> reg = <0x0 0xd9042000 0x0 0x1000>;
> clocks = <&dummy_clk>;
> clock-names = "apb_pclk";
> out-ports {
> port {
> main_funnel_out_port: endpoint {
> remote-endpoint = <&etf_in_port>;
> };
> };
> };
> in-ports {
> #address-cells = <1>;
> #size-cells = <0>;
>
> port@0 {
> reg = <0>;
> main_funnel_in_port0: endpoint {
> remote-endpoint = <&cluster0_funnel_out_port>;
> };
> };
>
> port@1 {
> reg = <1>;
> main_funnel_in_port1: endpoint {
> remote-endpoint = <&cluster1_funnel_out_port>;
> };
> };
> };
> };
>
> etf: etf@d9043000 {
> compatible = "arm,coresight-tmc", "arm,primecell";
> reg = <0x0 0xd9043000 0x0 0x1000>;
> clocks = <&dummy_clk>;
> clock-names = "apb_pclk";
> out-ports {
> port {
> etf_out_port: endpoint {
> remote-endpoint = <&etr_in_port>;
> };
> };
> };
> in-ports {
> port {
> etf_in_port: endpoint {
> remote-endpoint = <&main_funnel_out_port>;
> };
> };
> };
> };
>
> etr: etr@d9044000 {
> compatible = "arm,coresight-tmc", "arm,primecell";
> reg = <0x0 0xd9044000 0x0 0x1000>;
> clocks = <&dummy_clk>;
> clock-names = "apb_pclk";
> arm,scatter-gather;
> in-ports {
> port {
> etr_in_port: endpoint {
> remote-endpoint = <&etf_out_port>;
> };
> };
> };
> };
> };
> };
>
> Verification case:
>
> ~ # perf list pmu
> rvtrace// [Kernel PMU event]
>
> ~ # perf record -e rvtrace/@tmc_etr0/ --per-thread uname
> Linux
> [ perf record: Woken up 1 times to write data ]
> [ perf record: Captured and wrote 0.191 MB perf.data ]
> ~ # perf script
> uname 137 [003] 1 branches: ffffffff80931470 rvtrace_poll_bit+0x38 ([kernel.kallsyms]) => ffffffff80931492 rvtrace_poll_bit+0x5a ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff809328a6 encoder_enable_hw+0x252 ([kernel.kallsyms]) => ffffffff809328ba encoder_enable_hw+0x266 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff80932c4a encoder_enable+0x82 ([kernel.kallsyms]) => ffffffff80932c36 encoder_enable+0x6e ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff80928198 etm_event_start+0xf0 ([kernel.kallsyms]) => ffffffff809281aa etm_event_start+0x102 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff809281e6 etm_event_start+0x13e ([kernel.kallsyms]) => ffffffff8092755e coresight_get_sink_id+0x16 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff8092820e etm_event_start+0x166 ([kernel.kallsyms]) => ffffffff80928226 etm_event_start+0x17e ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3bb4 perf_report_aux_output_id+0x0 ([kernel.kallsyms]) => ffffffff801c3bd6 perf_report_aux_output_id+0x22 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3c5a perf_report_aux_output_id+0xa6 ([kernel.kallsyms]) => ffffffff801c3bf0 perf_report_aux_output_id+0x3c ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3c40 perf_report_aux_output_id+0x8c ([kernel.kallsyms]) => ffffffff801c3aea __perf_event_header__init_id+0x2a ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3b42 __perf_event_header__init_id+0x82 ([kernel.kallsyms]) => ffffffff801c3b4a __perf_event_header__init_id+0x8a ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff801c3bb0 __perf_event_header__init_id+0xf0 ([kernel.kallsyms]) => ffffffff801c3b58 __perf_event_header__init_id+0x98 ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff8004c658 __task_pid_nr_ns+0x0 ([kernel.kallsyms]) => ffffffff8004c696 __task_pid_nr_ns+0x3e ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff8004c71e __task_pid_nr_ns+0xc6 ([kernel.kallsyms]) => ffffffff8004c6a4 __task_pid_nr_ns+0x4c ([kernel.kallsyms])
> uname 137 [003] 1 branches: ffffffff8004c6e4 __task_pid_nr_ns+0x8c ([kernel.kallsyms]) => ffffffff8004c6e4 __task_pid_nr_ns+0x8c ([kernel.kallsyms])
> ...
>
> liangzhen (12):
> coresight: Add RISC-V support to CoreSight tracing
> coresight: Initial implementation of RISC-V trace driver
> coresight: Add RISC-V Trace Encoder driver
> coresight: Add RISC-V Trace Funnel driver
> coresight: Add RISC-V Trace ATB Bridge driver
> coresight rvtrace: Add timestamp component support for encoder and
> funnel
> coresight: Add RISC-V PMU name support
> perf tools: riscv: making rvtrace PMU listable
> perf tools: Add RISC-V trace PMU record capabilities
> perf tools: Add Nexus RISC-V Trace decoder
> perf symbols: Add RISC-V PLT entry sizes
> perf tools: Integrate RISC-V trace decoder into auxtrace
>
> drivers/hwtracing/Kconfig | 2 +
> drivers/hwtracing/coresight/Kconfig | 46 +-
> drivers/hwtracing/coresight/Makefile | 6 +
> drivers/hwtracing/coresight/coresight-core.c | 8 +
> .../hwtracing/coresight/coresight-etm-perf.c | 1 -
> .../hwtracing/coresight/coresight-etm-perf.h | 21 +
> .../hwtracing/coresight/coresight-platform.c | 1 -
> .../hwtracing/coresight/coresight-tmc-etf.c | 4 +
> .../hwtracing/coresight/coresight-tmc-etr.c | 4 +
> .../hwtracing/coresight/rvtrace-atbbridge.c | 239 +++
> drivers/hwtracing/coresight/rvtrace-core.c | 135 ++
> .../coresight/rvtrace-encoder-core.c | 562 +++++++
> .../coresight/rvtrace-encoder-sysfs.c | 363 +++++
> drivers/hwtracing/coresight/rvtrace-encoder.h | 151 ++
> drivers/hwtracing/coresight/rvtrace-funnel.c | 337 ++++
> drivers/hwtracing/coresight/rvtrace-funnel.h | 39 +
> .../hwtracing/coresight/rvtrace-timestamp.c | 278 ++++
> .../hwtracing/coresight/rvtrace-timestamp.h | 64 +
> include/linux/coresight-pmu.h | 4 +
> include/linux/rvtrace.h | 116 ++
> tools/arch/riscv/include/asm/insn.h | 645 ++++++++
> tools/perf/arch/riscv/util/Build | 2 +
> tools/perf/arch/riscv/util/auxtrace.c | 490 ++++++
> tools/perf/arch/riscv/util/pmu.c | 20 +
> tools/perf/util/Build | 3 +
> tools/perf/util/auxtrace.c | 4 +
> tools/perf/util/auxtrace.h | 1 +
> tools/perf/util/nexus-rv-decoder/Build | 1 +
> .../util/nexus-rv-decoder/nexus-rv-decoder.c | 1364 +++++++++++++++++
> .../util/nexus-rv-decoder/nexus-rv-decoder.h | 139 ++
> .../perf/util/nexus-rv-decoder/nexus-rv-msg.h | 190 +++
> tools/perf/util/rvtrace-decoder.c | 1039 +++++++++++++
> tools/perf/util/rvtrace.h | 40 +
> tools/perf/util/symbol-elf.c | 4 +
> 34 files changed, 6320 insertions(+), 3 deletions(-)
> create mode 100644 drivers/hwtracing/coresight/rvtrace-atbbridge.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-core.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-core.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder-sysfs.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-encoder.h
> create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-funnel.h
> create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.c
> create mode 100644 drivers/hwtracing/coresight/rvtrace-timestamp.h
> create mode 100644 include/linux/rvtrace.h
> create mode 100644 tools/arch/riscv/include/asm/insn.h
> 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/util/nexus-rv-decoder/Build
> create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.c
> create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-decoder.h
> create mode 100644 tools/perf/util/nexus-rv-decoder/nexus-rv-msg.h
> create mode 100644 tools/perf/util/rvtrace-decoder.c
> create mode 100644 tools/perf/util/rvtrace.h
>
On 4/14/2026 12:15 PM, Jie Gan wrote: > > I dont think you have looped relevant maintainers and reviewers for the Coresight subsystem. > > Thanks, > Jie I will send it to all relevant maintainers and reviewers for the Coresight subsystem in next revision. Thanks, Zane
© 2016 - 2026 Red Hat, Inc.