From 1c1ef6908d6b93d2ad088ecb42ce5a5dac26048b Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Wed, 28 Aug 2024 14:30:47 +0800 Subject: [PATCH] drivers/rptun: add rptun trace feature for debug Signed-off-by: Bowen Wang --- drivers/rptun/rptun.c | 150 +++++++++++++++++++++++++++++++++++++++++ openamp/Kconfig | 4 ++ openamp/open-amp.cmake | 4 ++ openamp/open-amp.defs | 4 ++ 4 files changed, 162 insertions(+) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 4f704ff1ce..b8e9e74a86 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -56,6 +57,12 @@ * Private Types ****************************************************************************/ +struct rptun_trace_s +{ + FAR void *hdr; + FAR void *backtrace[16]; +}; + struct rptun_priv_s { struct rpmsg_s rpmsg; @@ -64,6 +71,7 @@ struct rptun_priv_s struct remoteproc rproc; struct rpmsg_virtio_shm_pool pool[2]; sem_t semtx; + FAR struct rptun_trace_s *traces; sem_t semrx; pid_t tid; uint16_t headrx; @@ -128,6 +136,20 @@ static void rptun_panic(FAR struct rpmsg_s *rpmsg); static void rptun_dump(FAR struct rpmsg_s *rpmsg); static FAR const char *rptun_get_local_cpuname(FAR struct rpmsg_s *rpmsg); static FAR const char *rptun_get_cpuname(FAR struct rpmsg_s *rpmsg); +#ifdef CONFIG_OPENAMP_RPMSG_TRACE +static void rptun_trace_init(FAR struct rptun_priv_s *priv); +static void rptun_trace_uninit(FAR struct rptun_priv_s *priv); +static void rptun_trace_get_tx_buffer(FAR struct rpmsg_device *rdev, + FAR void *hdr); +static void rptun_trace_release_tx_buffer(FAR struct rpmsg_device *rdev, + FAR void *hdr); +static void rptun_dump_trace(FAR struct rpmsg_virtio_device *rvdev); + +#else +# define rptun_trace_init(priv) +# define rptun_trace_uninit(priv) +# define rptun_dump_trace(rvdev); +#endif /**************************************************************************** * Private Data @@ -722,6 +744,8 @@ static void rptun_dump(FAR struct rpmsg_s *rpmsg) metal_mutex_acquire(&rdev->lock); } + rptun_dump_trace(rvdev); + metal_log(METAL_LOG_EMERGENCY, "Dump rpmsg info between cpu (master: %s)%s <==> %s:\n", rpmsg_virtio_get_role(rvdev) == RPMSG_HOST ? "yes" : "no", @@ -918,6 +942,7 @@ static int rptun_dev_start(FAR struct remoteproc *rproc) return ret; } + rptun_trace_init(priv); priv->rvdev.rdev.ns_unbind_cb = rpmsg_ns_unbind; priv->rvdev.notify_wait_cb = rptun_notify_wait; @@ -981,6 +1006,7 @@ static int rptun_dev_stop(FAR struct remoteproc *rproc, bool stop_ns) /* Remote proc stop and shutdown */ remoteproc_shutdown(rproc); + rptun_trace_uninit(priv); return OK; } @@ -1113,6 +1139,130 @@ static metal_phys_addr_t rptun_da_to_pa(FAR struct rptun_dev_s *dev, return da; } +#ifdef CONFIG_OPENAMP_RPMSG_TRACE +static void *rptun_get_priv_by_rdev(FAR struct rpmsg_device *rdev) +{ + FAR struct rpmsg_virtio_device *rvdev; + FAR struct virtio_device *vdev; + FAR struct remoteproc_virtio *rpvdev; + FAR struct remoteproc *rproc; + + if (!rdev) + { + return NULL; + } + + rvdev = metal_container_of(rdev, struct rpmsg_virtio_device, rdev); + vdev = rvdev->vdev; + if (!vdev) + { + return NULL; + } + + rpvdev = metal_container_of(vdev, struct remoteproc_virtio, vdev); + rproc = rpvdev->priv; + if (!rproc) + { + return NULL; + } + + return rproc->priv; +} + +static void rptun_trace_init(FAR struct rptun_priv_s *priv) +{ + int txnum = priv->rvdev.svq->vq_nentries; + + priv->traces = kmm_zalloc(sizeof(*priv->traces) * txnum); + DEBUGASSERT(priv->traces != NULL); + + priv->rvdev.rdev.trace.get_tx_buffer = rptun_trace_get_tx_buffer; + priv->rvdev.rdev.trace.release_tx_buffer = rptun_trace_release_tx_buffer; +} + +static void rptun_trace_uninit(FAR struct rptun_priv_s *priv) +{ + priv->rvdev.rdev.trace.get_tx_buffer = NULL; + priv->rvdev.rdev.trace.release_tx_buffer = NULL; + + kmm_free(priv->traces); +} + +static void rptun_trace_get_tx_buffer(FAR struct rpmsg_device *rdev, + FAR void *hdr) +{ + FAR struct rptun_priv_s *priv = rptun_get_priv_by_rdev(rdev); + int txnum = priv->rvdev.svq->vq_nentries; + int i; + + for (i = 0; i < txnum; i++) + { + if (priv->traces[i].hdr == NULL) + { + break; + } + } + + if (i >= txnum) + { + metal_log(METAL_LOG_EMERGENCY, "Not find empty buffer i=%d num=%d\n", + i, txnum); + PANIC(); + } + + priv->traces[i].hdr = hdr; + backtrace(priv->traces[i].backtrace, 16); +} + +static void rptun_trace_release_tx_buffer(FAR struct rpmsg_device *rdev, + FAR void *hdr) +{ + FAR struct rptun_priv_s *priv = rptun_get_priv_by_rdev(rdev); + int txnum = priv->rvdev.svq->vq_nentries; + int i; + int j; + + for (i = 0; i < txnum; i++) + { + if (priv->traces[i].hdr == hdr) + { + break; + } + } + + if (i >= txnum) + { + metal_log(METAL_LOG_EMERGENCY, "Not find tx buffer i=%d num=%d\n", + i, txnum); + PANIC(); + } + + priv->traces[i].hdr = NULL; + + for (j = 0; j < 16; j++) + { + priv->traces[i].backtrace[j] = NULL; + } +} + +static void rptun_dump_trace(FAR struct rpmsg_virtio_device *rvdev) +{ + FAR struct rptun_priv_s *priv = rptun_get_priv_by_rdev(&rvdev->rdev); + char backtrace[256]; + int txnum = rvdev->svq->vq_nentries; + int i; + + metal_log(METAL_LOG_EMERGENCY, "Dump not released tx buffer:\n"); + for (i = 0; i < txnum; i++) + { + backtrace_format(backtrace, sizeof(backtrace), + priv->traces[i].backtrace, 16); + metal_log(METAL_LOG_EMERGENCY, "hdr: %p backtrace: %s\n", + priv->traces[i].hdr, backtrace); + } +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/openamp/Kconfig b/openamp/Kconfig index d15399e936..cda4c9a099 100644 --- a/openamp/Kconfig +++ b/openamp/Kconfig @@ -30,4 +30,8 @@ config OPENAMP_VIRTIO_DRIVER_SUPPORT bool "Enable VIRTIO_DRIVER_SUPPORT" default y +config OPENAMP_RPMSG_TRACE + bool "Enable OpenAMP Rpmsg Trace" + default n + endif # OPENAMP diff --git a/openamp/open-amp.cmake b/openamp/open-amp.cmake index 677e54ae60..156d3152da 100644 --- a/openamp/open-amp.cmake +++ b/openamp/open-amp.cmake @@ -113,3 +113,7 @@ target_include_directories( open_amp-static PRIVATE $) nuttx_add_external_library(open_amp-static MODE KERNEL) + +if(CONFIG_OPENAMP_RPMSG_TRACE) + target_compile_options(openamp PRIVATE -DRPMSG_TRACE) +endif() diff --git a/openamp/open-amp.defs b/openamp/open-amp.defs index 8ca50ff58c..4b1f8fe442 100644 --- a/openamp/open-amp.defs +++ b/openamp/open-amp.defs @@ -44,6 +44,10 @@ else CFLAGS += -DVIRTIO_DRIVER_SUPPORT=0 endif +ifeq ($(CONFIG_OPENAMP_RPMSG_TRACE),y) + CFLAGS += -DRPMSG_TRACE +endif + CSRCS += open-amp/lib/remoteproc/elf_loader.c CSRCS += open-amp/lib/remoteproc/remoteproc.c CSRCS += open-amp/lib/remoteproc/remoteproc_virtio.c