rptun: add rptun dump support
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
5599f4e24a
commit
f0ba2f0286
@ -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
121
drivers/rptun/rpmsg_dump.c
Normal 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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user