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
 }