rptun: add rptun dump support

Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2022-01-14 23:25:49 +08:00 committed by Petro Karashchenko
parent 5599f4e24a
commit f0ba2f0286
5 changed files with 174 additions and 16 deletions

View File

@ -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

121
drivers/rptun/rpmsg_dump.c Normal file
View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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,

View File

@ -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
}