You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pk...@apache.org on 2022/03/30 07:00:22 UTC
[incubator-nuttx] 08/13: rptun: add rptun dump support
This is an automated email from the ASF dual-hosted git repository.
pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit f0ba2f028643600792d7870317f9fbad69484249
Author: ligd <li...@xiaomi.com>
AuthorDate: Fri Jan 14 23:25:49 2022 +0800
rptun: add rptun dump support
Signed-off-by: ligd <li...@xiaomi.com>
---
drivers/rptun/Make.defs | 3 +-
drivers/rptun/rpmsg_dump.c | 121 ++++++++++++++++++++++++++++++++++++++++++
drivers/rptun/rptun.c | 59 +++++++++++++++-----
include/nuttx/rptun/openamp.h | 3 ++
include/nuttx/rptun/rptun.h | 4 +-
5 files changed, 174 insertions(+), 16 deletions(-)
diff --git a/drivers/rptun/Make.defs b/drivers/rptun/Make.defs
index 00eacf4..8c79e0a 100644
--- a/drivers/rptun/Make.defs
+++ b/drivers/rptun/Make.defs
@@ -22,9 +22,10 @@
ifeq ($(CONFIG_RPTUN),y)
-CSRCS += rptun.c
+CSRCS += rptun.c rpmsg_dump.c
DEPPATH += --dep-path rptun
VPATH += :rptun
CFLAGS += ${shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)rptun}
+CFLAGS += ${shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)openamp$(DELIM)open-amp$(DELIM)lib}
endif
diff --git a/drivers/rptun/rpmsg_dump.c b/drivers/rptun/rpmsg_dump.c
new file mode 100644
index 0000000..413431a
--- /dev/null
+++ b/drivers/rptun/rpmsg_dump.c
@@ -0,0 +1,121 @@
+/****************************************************************************
+ * drivers/rptun/rpmsg_dump.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <metal/utilities.h>
+
+#include <rpmsg/rpmsg_internal.h>
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void rpmsg_dump_addr(FAR struct rpmsg_device *rdev,
+ FAR void *addr, bool rx)
+{
+ FAR struct rpmsg_hdr *hdr = addr;
+ FAR struct rpmsg_endpoint *ept;
+
+ ept = rpmsg_get_ept_from_addr(rdev, rx ? hdr->dst : hdr->src);
+ if (ept)
+ {
+ metal_log(METAL_LOG_INFO,
+ " %s buffer %p hold by %s\n",
+ rx ? "RX" : "TX", hdr, ept->name);
+ }
+}
+
+static void rpmsg_dump_buffer(FAR struct rpmsg_virtio_device *rvdev,
+ bool rx)
+{
+ FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq;
+ FAR void *addr;
+ int desc_idx;
+ int num;
+ int i;
+
+ num = rpmsg_buffer_nused(rvdev, rx);
+ metal_log(METAL_LOG_INFO,
+ " %s buffer, total %d, pending %d\n",
+ rx ? "RX" : "TX", vq->vq_nentries, num);
+
+ for (i = 0; i < num; i++)
+ {
+ if ((rpmsg_virtio_get_role(rvdev) == RPMSG_MASTER) ^ rx)
+ {
+ desc_idx = (vq->vq_ring.used->idx + i) & (vq->vq_nentries - 1);
+ desc_idx = vq->vq_ring.avail->ring[desc_idx];
+ }
+ else
+ {
+ desc_idx = (vq->vq_ring.avail->idx + i) & (vq->vq_nentries - 1);
+ desc_idx = vq->vq_ring.used->ring[desc_idx].id;
+ }
+
+ addr = metal_io_phys_to_virt(vq->shm_io,
+ vq->vq_ring.desc[desc_idx].addr);
+ if (addr)
+ {
+ rpmsg_dump_addr(&rvdev->rdev, addr, rx);
+ }
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+void rpmsg_dump(FAR struct rpmsg_virtio_device *rvdev)
+{
+ FAR struct rpmsg_device *rdev = &rvdev->rdev;
+ FAR struct rpmsg_endpoint *ept;
+ FAR struct metal_list *node;
+
+ if (!rvdev->vdev)
+ {
+ return;
+ }
+
+ metal_mutex_acquire(&rdev->lock);
+
+ metal_log(METAL_LOG_INFO,
+ "Dump rpmsg info between cpu %s <==> %s:\n",
+ CONFIG_RPTUN_LOCAL_CPUNAME, rpmsg_get_cpuname(rdev));
+
+ metal_log(METAL_LOG_INFO, " rpmsg ept list:\n");
+
+ metal_list_for_each(&rdev->endpoints, node)
+ {
+ ept = metal_container_of(node, struct rpmsg_endpoint, node);
+ metal_log(METAL_LOG_INFO, " ept %s\n", ept->name);
+ }
+
+ metal_log(METAL_LOG_INFO, " rpmsg buffer list:\n");
+
+ rpmsg_dump_buffer(rvdev, true);
+ rpmsg_dump_buffer(rvdev, false);
+
+ metal_mutex_release(&rdev->lock);
+}
diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c
index 3cf9cb5..e4c8a24 100644
--- a/drivers/rptun/rptun.c
+++ b/drivers/rptun/rptun.c
@@ -65,7 +65,7 @@ struct rptun_priv_s
{
FAR struct rptun_dev_s *dev;
struct remoteproc rproc;
- struct rpmsg_virtio_device vdev;
+ struct rpmsg_virtio_device rvdev;
struct rpmsg_virtio_shm_pool tx_shpool;
struct rpmsg_virtio_shm_pool rx_shpool;
struct metal_list bind;
@@ -340,7 +340,7 @@ static int rptun_callback(FAR void *arg, uint32_t vqid)
{
FAR struct rptun_priv_s *priv = arg;
- int status = rpmsg_virtio_get_status(&priv->vdev);
+ int status = rpmsg_virtio_get_status(&priv->rvdev);
if ((status & VIRTIO_CONFIG_STATUS_NEEDS_RESET)
&& (RPTUN_IS_MASTER(priv->dev) ^
@@ -693,13 +693,13 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
if (priv->rx_shpool.base)
{
- ret = rpmsg_init_vdev_ext(&priv->vdev, vdev, rptun_ns_bind,
+ ret = rpmsg_init_vdev_ext(&priv->rvdev, vdev, rptun_ns_bind,
metal_io_get_region(),
&priv->tx_shpool, &priv->rx_shpool);
}
else
{
- ret = rpmsg_init_vdev(&priv->vdev, vdev, rptun_ns_bind,
+ ret = rpmsg_init_vdev(&priv->rvdev, vdev, rptun_ns_bind,
metal_io_get_region(), &priv->tx_shpool);
}
@@ -709,7 +709,7 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
return ret;
}
- priv->vdev.rdev.ns_unbind_cb = rptun_ns_unbind;
+ priv->rvdev.rdev.ns_unbind_cb = rptun_ns_unbind;
/* Remote proc start */
@@ -737,7 +737,7 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
cb = metal_container_of(node, struct rptun_cb_s, node);
if (cb->device_created)
{
- cb->device_created(&priv->vdev.rdev, cb->priv);
+ cb->device_created(&priv->rvdev.rdev, cb->priv);
}
}
@@ -769,7 +769,7 @@ static int rptun_dev_stop(FAR struct remoteproc *rproc)
cb = metal_container_of(node, struct rptun_cb_s, node);
if (cb->device_destroy)
{
- cb->device_destroy(&priv->vdev.rdev, cb->priv);
+ cb->device_destroy(&priv->rvdev.rdev, cb->priv);
}
}
@@ -781,8 +781,8 @@ static int rptun_dev_stop(FAR struct remoteproc *rproc)
/* Remote proc remove */
- remoteproc_remove_virtio(rproc, priv->vdev.vdev);
- rpmsg_deinit_vdev(&priv->vdev);
+ remoteproc_remove_virtio(rproc, priv->rvdev.vdev);
+ rpmsg_deinit_vdev(&priv->rvdev);
return 0;
}
@@ -794,7 +794,7 @@ static int rptun_dev_reset(FAR struct remoteproc *rproc, int value)
value = (value & RPTUN_STATUS_MASK) | VIRTIO_CONFIG_STATUS_NEEDS_RESET
| (RPTUN_IS_MASTER(priv->dev) ? RPTUN_STATUS_FROM_MASTER : 0);
- rpmsg_virtio_set_status(&priv->vdev, value);
+ rpmsg_virtio_set_status(&priv->rvdev, value);
return RPTUN_NOTIFY(priv->dev, RPTUN_NOTIFY_ALL);
}
@@ -819,6 +819,9 @@ static int rptun_dev_ioctl(FAR struct file *filep, int cmd,
case RPTUNIOC_PANIC:
rptun_dev_reset(&priv->rproc, RPTUN_STATUS_PANIC);
break;
+ case RPTUNIOC_DUMP:
+ rpmsg_dump(&priv->rvdev);
+ break;
default:
ret = -ENOTTY;
break;
@@ -1007,6 +1010,21 @@ FAR const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev)
return RPTUN_GET_CPUNAME(priv->dev);
}
+int rpmsg_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, bool rx)
+{
+ FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq;
+
+ if ((rpmsg_virtio_get_role(rvdev) == RPMSG_MASTER) ^ rx)
+ {
+ return vq->vq_ring.avail->idx - vq->vq_ring.used->idx;
+ }
+ else
+ {
+ return vq->vq_nentries -
+ (vq->vq_ring.avail->idx - vq->vq_ring.used->idx);
+ }
+}
+
int rpmsg_register_callback(FAR void *priv_,
rpmsg_dev_cb_t device_created,
rpmsg_dev_cb_t device_destroy,
@@ -1033,12 +1051,12 @@ int rpmsg_register_callback(FAR void *priv_,
metal_list_for_each(&g_rptun_priv, node)
{
- struct rptun_priv_s *priv;
+ FAR struct rptun_priv_s *priv;
priv = metal_container_of(node, struct rptun_priv_s, node);
if (device_created)
{
- device_created(&priv->vdev.rdev, priv_);
+ device_created(&priv->rvdev.rdev, priv_);
}
if (ns_bind)
@@ -1048,7 +1066,7 @@ int rpmsg_register_callback(FAR void *priv_,
struct rptun_bind_s *bind;
bind = metal_container_of(bnode, struct rptun_bind_s, node);
- ns_bind(&priv->vdev.rdev, priv_, bind->name, bind->dest);
+ ns_bind(&priv->rvdev.rdev, priv_, bind->name, bind->dest);
}
}
}
@@ -1086,7 +1104,7 @@ void rpmsg_unregister_callback(FAR void *priv_,
priv = metal_container_of(pnode,
struct rptun_priv_s, node);
- device_destroy(&priv->vdev.rdev, priv_);
+ device_destroy(&priv->rvdev.rdev, priv_);
}
}
@@ -1234,3 +1252,16 @@ int rptun_panic(FAR const char *cpuname)
{
return rptun_reset(cpuname, RPTUN_STATUS_PANIC);
}
+
+void rptun_dump(void)
+{
+ FAR struct metal_list *node;
+
+ metal_list_for_each(&g_rptun_priv, node)
+ {
+ FAR struct rptun_priv_s *priv =
+ metal_container_of(node, struct rptun_priv_s, node);
+
+ rpmsg_dump(&priv->rvdev);
+ }
+}
diff --git a/include/nuttx/rptun/openamp.h b/include/nuttx/rptun/openamp.h
index 365e2bc..4188c41 100644
--- a/include/nuttx/rptun/openamp.h
+++ b/include/nuttx/rptun/openamp.h
@@ -58,6 +58,9 @@ int rpmsg_wait(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem);
int rpmsg_post(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem);
const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev);
+int rpmsg_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, bool rx);
+void rpmsg_dump(FAR struct rpmsg_virtio_device *rvdev);
+
int rpmsg_register_callback(FAR void *priv,
rpmsg_dev_cb_t device_created,
rpmsg_dev_cb_t device_destroy,
diff --git a/include/nuttx/rptun/rptun.h b/include/nuttx/rptun/rptun.h
index f51d9c6..eb31847 100644
--- a/include/nuttx/rptun/rptun.h
+++ b/include/nuttx/rptun/rptun.h
@@ -40,6 +40,7 @@
#define RPTUNIOC_STOP _RPTUNIOC(2)
#define RPTUNIOC_RESET _RPTUNIOC(3)
#define RPTUNIOC_PANIC _RPTUNIOC(4)
+#define RPTUNIOC_DUMP _RPTUNIOC(5)
#define RPTUN_NOTIFY_ALL (UINT32_MAX - 0)
@@ -60,7 +61,7 @@
****************************************************************************/
#define RPTUN_GET_CPUNAME(d) ((d)->ops->get_cpuname ? \
- (d)->ops->get_cpuname(d) : NULL)
+ (d)->ops->get_cpuname(d) : "")
/****************************************************************************
* Name: RPTUN_GET_FIRMWARE
@@ -318,6 +319,7 @@ int rptun_initialize(FAR struct rptun_dev_s *dev);
int rptun_boot(FAR const char *cpuname);
int rptun_reset(FAR const char *cpuname, int value);
int rptun_panic(FAR const char *cpuname);
+void rptun_dump(void);
#ifdef __cplusplus
}