[PATCH RFC 10/12] rvtrace: Add copyto_auxbuf callback for pre-ratified encoder and funnel

Eric Lin eric.lin at sifive.com
Tue Jun 30 02:46:33 PDT 2026


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 at sifive.com>
Signed-off-by: Nick Hu <nick.hu at sifive.com>
Co-developed-by: Vincent Chen <vincent.chen at sifive.com>
Signed-off-by: Vincent Chen <vincent.chen at sifive.com>
Signed-off-by: Eric Lin <eric.lin at sifive.com>
---
 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




More information about the linux-riscv mailing list