[PATCH RFC 10/12] rvtrace: Add copyto_auxbuf callback for pre-ratified encoder and funnel
From: Eric Lin <hidden>
Date: 2026-06-30 09:47:35
Also in:
linux-riscv, lkml
Subsystem:
hardware tracing facilities, the rest · Maintainers:
Alexander Shishkin, Linus Torvalds
Unlike the standard RISC-V trace ramsink, which is an independent device, the pre-ratified ramsink are embedded within the trace encoder or funnel MMIO registers. When pre-ratified encoder and funnel components act as a sink, the trace data must be copied from the trace buffer to the perf AUX buffer after tracing is stopped. To support this, export rvtrace_ramsink_copyto_auxbuf() and assign it as the copyto_auxbuf callback for the encoder and funnel drivers. Note: if an encoder or funnel component is acting as a source in a given path, we must check that the trace component is the last node in the trace path before invoking its copyto_auxbuf() callback. Co-developed-by: Nick Hu <redacted> Signed-off-by: Nick Hu <redacted> Co-developed-by: Vincent Chen <redacted> Signed-off-by: Vincent Chen <redacted> Signed-off-by: Eric Lin <redacted> --- drivers/hwtracing/rvtrace/rvtrace-core.c | 2 +- drivers/hwtracing/rvtrace/rvtrace-encoder.c | 10 ++++++++++ drivers/hwtracing/rvtrace/rvtrace-funnel.c | 10 ++++++++++ drivers/hwtracing/rvtrace/rvtrace-ramsink.c | 5 +++-- drivers/hwtracing/rvtrace/rvtrace-ramsink.h | 2 ++ 5 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/drivers/hwtracing/rvtrace/rvtrace-core.c b/drivers/hwtracing/rvtrace/rvtrace-core.c
index 153cf3ebffff..d902524e0358 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-core.c
+++ b/drivers/hwtracing/rvtrace/rvtrace-core.c@@ -677,7 +677,7 @@ int rvtrace_path_copyto_auxbuf(struct rvtrace_path *path, list_for_each_entry(node, &path->comp_list, head) { comp = node->comp; rtdrv = to_rvtrace_driver(comp->dev.driver); - if (!rtdrv->copyto_auxbuf) + if (!rtdrv->copyto_auxbuf || node->conn) continue; *bytes_copied = rtdrv->copyto_auxbuf(comp, buf);
diff --git a/drivers/hwtracing/rvtrace/rvtrace-encoder.c b/drivers/hwtracing/rvtrace/rvtrace-encoder.c
index b187731ff855..41e74cac0c25 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-encoder.c
+++ b/drivers/hwtracing/rvtrace/rvtrace-encoder.c@@ -7,6 +7,7 @@ #include <linux/rvtrace.h> #include <linux/types.h> #include "rvtrace-v0.h" +#include "rvtrace-ramsink.h" #define RVTRACE_COMPONENT_CTRL_ITRACE_SHIFT 2 #define RVTRACE_COMPONENT_CTRL_INSTMODE_SHIFT 4
@@ -78,6 +79,8 @@ static int rvtrace_encoder_stop(struct rvtrace_component *comp) static int rvtrace_encoder_probe(struct rvtrace_component *comp) { + struct rvtrace_v0_comp_features *data; + struct rvtrace_driver *rtdrv; int ret; u32 comp_maj;
@@ -87,6 +90,13 @@ static int rvtrace_encoder_probe(struct rvtrace_component *comp) ret = rvtrace_v0_ramsink_setup(comp); if (ret) return dev_err_probe(&comp->dev, ret, "failed to setup ramsink.\n"); + + data = (struct rvtrace_v0_comp_features *)comp->id.data; + if (data && (data->has_sba_sink || data->has_sram_sink)) { + rtdrv = to_rvtrace_driver(comp->dev.driver); + if (!rtdrv->copyto_auxbuf) + rtdrv->copyto_auxbuf = rvtrace_ramsink_copyto_auxbuf; + } } ret = rvtrace_enable_component(comp->pdata);
diff --git a/drivers/hwtracing/rvtrace/rvtrace-funnel.c b/drivers/hwtracing/rvtrace/rvtrace-funnel.c
index 21f58001d569..b30609278a79 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-funnel.c
+++ b/drivers/hwtracing/rvtrace/rvtrace-funnel.c@@ -8,6 +8,7 @@ #include <linux/rvtrace.h> #include <linux/types.h> #include "rvtrace-v0.h" +#include "rvtrace-ramsink.h" static int rvtrace_funnel_start(struct rvtrace_path_node *node) {
@@ -53,6 +54,8 @@ static int rvtrace_funnel_stop(struct rvtrace_component *comp) static int rvtrace_funnel_probe(struct rvtrace_component *comp) { struct fwnode_handle *fwnode = dev_fwnode(comp->pdata->dev); + struct rvtrace_v0_comp_features *data; + struct rvtrace_driver *rtdrv; int ret; u32 comp_maj;
@@ -62,6 +65,13 @@ static int rvtrace_funnel_probe(struct rvtrace_component *comp) ret = rvtrace_v0_ramsink_setup(comp); if (ret) return dev_err_probe(&comp->dev, ret, "failed to setup ramsink.\n"); + + data = (struct rvtrace_v0_comp_features *)comp->id.data; + if (data && (data->has_sba_sink || data->has_sram_sink)) { + rtdrv = to_rvtrace_driver(comp->dev.driver); + if (!rtdrv->copyto_auxbuf) + rtdrv->copyto_auxbuf = rvtrace_ramsink_copyto_auxbuf; + } } ret = rvtrace_enable_component(comp->pdata);
diff --git a/drivers/hwtracing/rvtrace/rvtrace-ramsink.c b/drivers/hwtracing/rvtrace/rvtrace-ramsink.c
index e794b01e19d0..d89cdcb971dd 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-ramsink.c
+++ b/drivers/hwtracing/rvtrace/rvtrace-ramsink.c@@ -179,8 +179,8 @@ static void tbuf_to_pbuf_copy(struct trace_buf *src, struct trace_buf *dst, size } } -static size_t rvtrace_ramsink_copyto_auxbuf(struct rvtrace_component *comp, - struct rvtrace_perf_auxbuf *buf) +size_t rvtrace_ramsink_copyto_auxbuf(struct rvtrace_component *comp, + struct rvtrace_perf_auxbuf *buf) { struct rvtrace_ramsink_priv *priv = dev_get_drvdata(&comp->dev); const struct rvtrace_ramsink_regs *regs = priv->regs;
@@ -224,6 +224,7 @@ static size_t rvtrace_ramsink_copyto_auxbuf(struct rvtrace_component *comp, dev_dbg(&comp->dev, "Copied %zu bytes\n", bytes); return bytes; } +EXPORT_SYMBOL_GPL(rvtrace_ramsink_copyto_auxbuf); static int rvtrace_ramsink_setup_buf(struct rvtrace_component *comp, struct rvtrace_ramsink_priv *priv)
diff --git a/drivers/hwtracing/rvtrace/rvtrace-ramsink.h b/drivers/hwtracing/rvtrace/rvtrace-ramsink.h
index 7e0391aeffd5..a398db78e803 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-ramsink.h
+++ b/drivers/hwtracing/rvtrace/rvtrace-ramsink.h@@ -7,5 +7,7 @@ #define __RVTRACE_RAMSINK_H__ int rvtrace_ramsink_setup(struct rvtrace_component *comp); +size_t rvtrace_ramsink_copyto_auxbuf(struct rvtrace_component *comp, + struct rvtrace_perf_auxbuf *buf); #endif /* __RVTRACE_RAMSINK_H__ */
--
2.34.1