[PATCH RFC 10/12] rvtrace: Add copyto_auxbuf callback for pre-ratified encoder and funnel
From: Eric Lin
Date: Tue Jun 30 2026 - 05:54:33 EST
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 <nick.hu@xxxxxxxxxx>
Signed-off-by: Nick Hu <nick.hu@xxxxxxxxxx>
Co-developed-by: Vincent Chen <vincent.chen@xxxxxxxxxx>
Signed-off-by: Vincent Chen <vincent.chen@xxxxxxxxxx>
Signed-off-by: Eric Lin <eric.lin@xxxxxxxxxx>
---
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