diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile index 006d2b90023..a0fd93e1b59 100644 --- a/arch/sim/src/Makefile +++ b/arch/sim/src/Makefile @@ -254,7 +254,7 @@ ifeq ($(CONFIG_SIM_LIBUSB),y) endif endif -ifeq ($(CONFIG_RPMSG_VIRTIO),y) +ifeq ($(CONFIG_RPMSG_VIRTIO_LITE),y) CSRCS += sim_rpmsg_virtio.c endif diff --git a/arch/sim/src/sim/CMakeLists.txt b/arch/sim/src/sim/CMakeLists.txt index de809f0a5b7..498f4e3d0d5 100644 --- a/arch/sim/src/sim/CMakeLists.txt +++ b/arch/sim/src/sim/CMakeLists.txt @@ -119,7 +119,7 @@ if(CONFIG_LIBM_TOOLCHAIN) list(APPEND STDLIBS m) endif() -if(CONFIG_RPMSG_VIRTIO) +if(CONFIG_RPMSG_VIRTIO_LITE) list(APPEND SRCS sim_rpmsg_vritio.c) endif() diff --git a/arch/sim/src/sim/sim_internal.h b/arch/sim/src/sim/sim_internal.h index 9d48c35bfae..243f9212068 100644 --- a/arch/sim/src/sim/sim_internal.h +++ b/arch/sim/src/sim/sim_internal.h @@ -415,7 +415,7 @@ int sim_rptun_init(const char *shmemname, const char *cpuname, int master); /* sim_rpmsg_virtio.c *******************************************************/ -#ifdef CONFIG_RPMSG_VIRTIO +#ifdef CONFIG_RPMSG_VIRTIO_LITE int sim_rpmsg_virtio_init(const char *shmemname, const char *cpuname, bool master); #endif diff --git a/arch/sim/src/sim/sim_rpmsg_virtio.c b/arch/sim/src/sim/sim_rpmsg_virtio.c index d087a62a39d..918a8716a6b 100644 --- a/arch/sim/src/sim/sim_rpmsg_virtio.c +++ b/arch/sim/src/sim/sim_rpmsg_virtio.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include "sim_internal.h" @@ -46,18 +46,18 @@ struct sim_rpmsg_virtio_shmem_s { - volatile uintptr_t base; - volatile unsigned int seqs; - volatile unsigned int seqm; - volatile unsigned int boots; - volatile unsigned int bootm; - struct rpmsg_virtio_rsc_s rsc; - char buf[0x10000]; + volatile uintptr_t base; + volatile unsigned int seqs; + volatile unsigned int seqm; + volatile unsigned int boots; + volatile unsigned int bootm; + struct rpmsg_virtio_lite_rsc_s rsc; + char buf[0x10000]; }; struct sim_rpmsg_virtio_dev_s { - struct rpmsg_virtio_s dev; + struct rpmsg_virtio_lite_s dev; rpmsg_virtio_callback_t callback; void *arg; int master; @@ -76,7 +76,8 @@ struct sim_rpmsg_virtio_dev_s * Private Functions ****************************************************************************/ -static const char *sim_rpmsg_virtio_get_cpuname(struct rpmsg_virtio_s *dev) +static const char * +sim_rpmsg_virtio_get_cpuname(struct rpmsg_virtio_lite_s *dev) { struct sim_rpmsg_virtio_dev_s *priv = container_of(dev, struct sim_rpmsg_virtio_dev_s, dev); @@ -84,13 +85,13 @@ static const char *sim_rpmsg_virtio_get_cpuname(struct rpmsg_virtio_s *dev) return priv->cpuname; } -static struct rpmsg_virtio_rsc_s * -sim_rpmsg_virtio_get_resource(struct rpmsg_virtio_s *dev) +static struct rpmsg_virtio_lite_rsc_s * +sim_rpmsg_virtio_get_resource(struct rpmsg_virtio_lite_s *dev) { struct sim_rpmsg_virtio_dev_s *priv = container_of(dev, struct sim_rpmsg_virtio_dev_s, dev); - struct rpmsg_virtio_rsc_s *rsc; - struct rpmsg_virtio_cmd_s *cmd; + struct rpmsg_virtio_lite_rsc_s *rsc; + struct rpmsg_virtio_lite_cmd_s *cmd; priv->shmem = host_allocshmem(priv->shmemname, sizeof(*priv->shmem)); if (!priv->shmem) @@ -141,7 +142,7 @@ sim_rpmsg_virtio_get_resource(struct rpmsg_virtio_s *dev) return rsc; } -static int sim_rpmsg_virtio_is_master(struct rpmsg_virtio_s *dev) +static int sim_rpmsg_virtio_is_master(struct rpmsg_virtio_lite_s *dev) { struct sim_rpmsg_virtio_dev_s *priv = container_of(dev, struct sim_rpmsg_virtio_dev_s, dev); @@ -150,7 +151,7 @@ static int sim_rpmsg_virtio_is_master(struct rpmsg_virtio_s *dev) } static int -sim_rpmsg_virtio_register_callback(struct rpmsg_virtio_s *dev, +sim_rpmsg_virtio_register_callback(struct rpmsg_virtio_lite_s *dev, rpmsg_virtio_callback_t callback, void *arg) { @@ -184,7 +185,7 @@ static void sim_rpmsg_virtio_work(wdparm_t arg) if (should_notify && dev->callback != NULL) { - dev->callback(dev->arg, RPMSG_VIRTIO_NOTIFY_ALL); + dev->callback(dev->arg, RPMSG_VIRTIO_LITE_NOTIFY_ALL); } } @@ -192,7 +193,8 @@ static void sim_rpmsg_virtio_work(wdparm_t arg) sim_rpmsg_virtio_work, (wdparm_t)dev); } -static int sim_rpmsg_virtio_notify(struct rpmsg_virtio_s *dev, uint32_t vqid) +static int sim_rpmsg_virtio_notify(struct rpmsg_virtio_lite_s *dev, + uint32_t vqid) { struct sim_rpmsg_virtio_dev_s *priv = container_of(dev, struct sim_rpmsg_virtio_dev_s, dev); @@ -213,7 +215,7 @@ static int sim_rpmsg_virtio_notify(struct rpmsg_virtio_s *dev, uint32_t vqid) * Private Data ****************************************************************************/ -static const struct rpmsg_virtio_ops_s g_sim_rpmsg_virtio_ops = +static const struct rpmsg_virtio_lite_ops_s g_sim_rpmsg_virtio_ops = { .get_cpuname = sim_rpmsg_virtio_get_cpuname, .get_resource = sim_rpmsg_virtio_get_resource, @@ -243,7 +245,7 @@ int sim_rpmsg_virtio_init(const char *shmemname, const char *cpuname, strlcpy(priv->cpuname, cpuname, RPMSG_NAME_SIZE); strlcpy(priv->shmemname, shmemname, RPMSG_NAME_SIZE); - ret = rpmsg_virtio_initialize(&priv->dev); + ret = rpmsg_virtio_lite_initialize(&priv->dev); if (ret < 0) { kmm_free(priv); diff --git a/boards/sim/sim/sim/src/sim_bringup.c b/boards/sim/sim/sim/src/sim_bringup.c index 26eeddc25bc..be3a46f6617 100644 --- a/boards/sim/sim/sim/src/sim_bringup.c +++ b/boards/sim/sim/sim/src/sim_bringup.c @@ -485,7 +485,7 @@ int sim_bringup(void) # endif #endif -#ifdef CONFIG_RPMSG_VIRTIO +#ifdef CONFIG_RPMSG_VIRTIO_LITE # ifdef CONFIG_SIM_RPMSG_MASTER sim_rpmsg_virtio_init("server-proxy", "proxy", true); # else diff --git a/drivers/rpmsg/CMakeLists.txt b/drivers/rpmsg/CMakeLists.txt index 9e0c34e98ac..3c53305e8b1 100644 --- a/drivers/rpmsg/CMakeLists.txt +++ b/drivers/rpmsg/CMakeLists.txt @@ -47,8 +47,8 @@ if(CONFIG_RPMSG) list(APPEND SRCS rpmsg_port_uart.c) endif() - if(CONFIG_RPMSG_VIRTIO) - list(APPEND SRCS rpmsg_virtio.c) + if(CONFIG_RPMSG_VIRTIO_LITE) + list(APPEND SRCS rpmsg_virtio_lite.c) endif() if(CONFIG_RPMSG_VIRTIO_IVSHMEM) diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig index 5176dd4911b..25dafad3963 100644 --- a/drivers/rpmsg/Kconfig +++ b/drivers/rpmsg/Kconfig @@ -107,32 +107,50 @@ config RPMSG_PORT_UART_DEBUG endif # RPMSG_PORT_UART -config RPMSG_VIRTIO +config RPMSG_VIRTIO_LITE bool "rpmsg virtio transport support" default n select RPMSG -if RPMSG_VIRTIO +if RPMSG_VIRTIO_LITE -config RPMSG_VIRTIO_PRIORITY - int "rpmsg virtio rx thread priority" +config RPMSG_VIRTIO_LITE_PRIORITY + int "rpmsg virtio lite rx thread priority" default 224 -config RPMSG_VIRTIO_STACKSIZE - int "rpmsg virtio rx thread stack size" +config RPMSG_VIRTIO_LITE_STACKSIZE + int "rpmsg virtio lite rx thread stack size" default DEFAULT_TASK_STACKSIZE config RPMSG_VIRTIO_IVSHMEM - bool "rpmsg virtio ivshmem support" + bool "rpmsg virtio lite ivshmem support" default n depends on PCI_IVSHMEM ---help--- This is rpmsg virtio driver based on pci ivshmem. +config RPMSG_VIRTIO_LITE_PM + bool "rpmsg virtio lite power management" + depends on PM + default n + ---help--- + If TX/RX buffer is supplied and powered by each CPU. + And when one CPU in DEEP sleep, then it's buffer will + goto RAM-retention mode, can't access from another CPU. + So, we provide this method to resolve this. + +config RPMSG_VIRTIO_LITE_PM_AUTORELAX + bool "rpmsg virtio lite pm autorelax" + depends on RPMSG_VIRTIO_LITE_PM + default y + ---help--- + use wd_timer to auto relax pm + + if RPMSG_VIRTIO_IVSHMEM config RPMSG_VIRTIO_IVSHMEM_NAME - string "rpmsg virtio ivshmem name" + string "rpmsg virtio lite ivshmem name" ---help--- Using this config to custom the rpmsg virtio ivshmem id, cpuname and role, using ";" to split the names. @@ -141,14 +159,14 @@ config RPMSG_VIRTIO_IVSHMEM_NAME with remote cpu ids: "0","1", names: "cpu1", "cpu2", and roles: "master", "slave" config RPMSG_VIRTIO_IVSHMEM_BUFFSIZE - int "rpmsg virtio ivshmem rpmsg buffer size" + int "rpmsg virtio lite ivshmem rpmsg buffer size" default 2048 ---help--- The rpmsg buffer size in share memory, the RX and TX buffer size are same for now. config RPMSG_VIRTIO_IVSHMEM_BUFFNUM - int "rpmsg virtio ivshmem rpmsg buffer number" + int "rpmsg virtio lite ivshmem rpmsg buffer number" default 8 ---help--- The rpmsg virtio buffer number in share memory, the RX and TX buffer number diff --git a/drivers/rpmsg/Make.defs b/drivers/rpmsg/Make.defs index a98f5bd5836..f83f4696e43 100644 --- a/drivers/rpmsg/Make.defs +++ b/drivers/rpmsg/Make.defs @@ -51,8 +51,8 @@ ifeq ($(CONFIG_RPMSG_PORT_UART),y) CSRCS += rpmsg_port_uart.c endif -ifeq ($(CONFIG_RPMSG_VIRTIO),y) -CSRCS += rpmsg_virtio.c +ifeq ($(CONFIG_RPMSG_VIRTIO_LITE),y) +CSRCS += rpmsg_virtio_lite.c CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)openamp$(DELIM)open-amp$(DELIM)lib endif diff --git a/drivers/rpmsg/rpmsg_virtio.c b/drivers/rpmsg/rpmsg_virtio.c deleted file mode 100644 index 9df2175d545..00000000000 --- a/drivers/rpmsg/rpmsg_virtio.c +++ /dev/null @@ -1,684 +0,0 @@ -/**************************************************************************** - * drivers/rpmsg/rpmsg_virtio.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * 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 - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define RPMSG_VIRTIO_TIMEOUT_MS 20 -#define RPMSG_VIRTIO_NOTIFYID 0 - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct rpmsg_virtio_priv_s -{ - struct rpmsg_s rpmsg; - struct rpmsg_virtio_device rvdev; - FAR struct rpmsg_virtio_s *dev; - FAR struct rpmsg_virtio_rsc_s *rsc; - struct virtio_device vdev; - struct rpmsg_virtio_shm_pool pool[2]; - struct virtio_vring_info rvrings[2]; - sem_t semtx; - sem_t semrx; - pid_t tid; -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static int rpmsg_virtio_wait(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); -static int rpmsg_virtio_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); -static void rpmsg_virtio_panic(FAR struct rpmsg_s *rpmsg); -static void rpmsg_virtio_dump(FAR struct rpmsg_s *rpmsg); -static FAR const char * -rpmsg_virtio_get_local_cpuname(FAR struct rpmsg_s *rpmsg); -static FAR const char *rpmsg_virtio_get_cpuname(FAR struct rpmsg_s *rpmsg); - -static int rpmsg_virtio_create_virtqueues_(FAR struct virtio_device *vdev, - unsigned int flags, - unsigned int nvqs, - FAR const char *names[], - vq_callback callbacks[], - FAR void *callback_args[]); -static uint8_t rpmsg_virtio_get_status_(FAR struct virtio_device *dev); -static void rpmsg_virtio_set_status_(FAR struct virtio_device *dev, - uint8_t status); -static uint64_t rpmsg_virtio_get_features_(FAR struct virtio_device *dev); -static void rpmsg_virtio_set_features(FAR struct virtio_device *dev, - uint64_t feature); -static void rpmsg_virtio_notify(FAR struct virtqueue *vq); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const struct rpmsg_ops_s g_rpmsg_virtio_ops = -{ - .wait = rpmsg_virtio_wait, - .post = rpmsg_virtio_post, - .panic = rpmsg_virtio_panic, - .dump = rpmsg_virtio_dump, - .get_local_cpuname = rpmsg_virtio_get_local_cpuname, - .get_cpuname = rpmsg_virtio_get_cpuname, -}; - -static const struct virtio_dispatch g_rpmsg_virtio_dispatch = -{ - .create_virtqueues = rpmsg_virtio_create_virtqueues_, - .get_status = rpmsg_virtio_get_status_, - .set_status = rpmsg_virtio_set_status_, - .get_features = rpmsg_virtio_get_features_, - .set_features = rpmsg_virtio_set_features, - .notify = rpmsg_virtio_notify, -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static FAR struct rpmsg_virtio_priv_s * -rpmsg_virtio_get_priv(FAR struct virtio_device *vdev) -{ - FAR struct rpmsg_virtio_device *rvdev = vdev->priv; - - return metal_container_of(rvdev, struct rpmsg_virtio_priv_s, rvdev); -} - -static int rpmsg_virtio_create_virtqueues_(FAR struct virtio_device *vdev, - unsigned int flags, - unsigned int nvqs, - FAR const char *names[], - vq_callback callbacks[], - FAR void *callback_args[]) -{ - int ret; - int i; - - if (nvqs > vdev->vrings_num) - { - return ERROR_VQUEUE_INVLD_PARAM; - } - - /* Initialize virtqueue for each vring */ - - for (i = 0; i < nvqs; i++) - { - FAR struct virtio_vring_info *vinfo = &vdev->vrings_info[i]; - FAR struct vring_alloc_info *valloc = &vinfo->info; -#ifndef CONFIG_OPENAMP_VIRTIO_DEVICE_ONLY - if (vdev->role == VIRTIO_DEV_DRIVER) - { - size_t offset; - - offset = metal_io_virt_to_offset(vinfo->io, valloc->vaddr); - metal_io_block_set(vinfo->io, offset, 0, - vring_size(valloc->num_descs, valloc->align)); - } -#endif - - ret = virtqueue_create(vdev, i, names[i], valloc, - callbacks[i], vdev->func->notify, - vinfo->vq); - if (ret < 0) - { - return ret; - } - } - - return 0; -} - -static uint8_t rpmsg_virtio_get_status_(FAR struct virtio_device *vdev) -{ - FAR struct rpmsg_virtio_priv_s *priv = rpmsg_virtio_get_priv(vdev); - - return priv->rsc->rpmsg_vdev.status; -} - -static void rpmsg_virtio_set_status_(FAR struct virtio_device *vdev, - uint8_t status) -{ - FAR struct rpmsg_virtio_priv_s *priv = rpmsg_virtio_get_priv(vdev); - - priv->rsc->rpmsg_vdev.status = status; -} - -static uint64_t rpmsg_virtio_get_features_(FAR struct virtio_device *vdev) -{ - FAR struct rpmsg_virtio_priv_s *priv = rpmsg_virtio_get_priv(vdev); - - return priv->rsc->rpmsg_vdev.dfeatures; -} - -static void rpmsg_virtio_set_features(FAR struct virtio_device *vdev, - uint64_t features) -{ - FAR struct rpmsg_virtio_priv_s *priv = rpmsg_virtio_get_priv(vdev); - - priv->rsc->rpmsg_vdev.gfeatures = features; -} - -static void rpmsg_virtio_notify(FAR struct virtqueue *vq) -{ - FAR struct virtio_device *vdev = vq->vq_dev; - FAR struct rpmsg_virtio_priv_s *priv = rpmsg_virtio_get_priv(vdev); - - RPMSG_VIRTIO_NOTIFY(priv->dev, vdev->vrings_info->notifyid); -} - -static bool rpmsg_virtio_is_recursive(FAR struct rpmsg_virtio_priv_s *priv) -{ - return nxsched_gettid() == priv->tid; -} - -static int rpmsg_virtio_wait(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem) -{ - FAR struct rpmsg_virtio_priv_s *priv = - (FAR struct rpmsg_virtio_priv_s *)rpmsg; - int ret; - - if (!rpmsg_virtio_is_recursive(priv)) - { - return nxsem_wait_uninterruptible(sem); - } - - while (1) - { - ret = nxsem_trywait(sem); - if (ret >= 0) - { - break; - } - - nxsem_wait(&priv->semtx); - virtqueue_notification(priv->rvdev.rvq); - } - - return ret; -} - -static void rpmsg_virtio_wakeup_tx(FAR struct rpmsg_virtio_priv_s *priv) -{ - int semcount; - - nxsem_get_value(&priv->semtx, &semcount); - while (semcount++ < 1) - { - nxsem_post(&priv->semtx); - } -} - -static int rpmsg_virtio_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem) -{ - FAR struct rpmsg_virtio_priv_s *priv = - (FAR struct rpmsg_virtio_priv_s *)rpmsg; - int semcount; - int ret; - - nxsem_get_value(sem, &semcount); - ret = nxsem_post(sem); - - if (priv && semcount >= 0) - { - rpmsg_virtio_wakeup_tx(priv); - } - - return ret; -} - -static void rpmsg_virtio_panic(FAR struct rpmsg_s *rpmsg) -{ - FAR struct rpmsg_virtio_priv_s *priv = - (FAR struct rpmsg_virtio_priv_s *)rpmsg; - FAR struct rpmsg_virtio_cmd_s *cmd = RPMSG_VIRTIO_RSC2CMD(priv->rsc); - - if (RPMSG_VIRTIO_IS_MASTER(priv->dev)) - { - cmd->cmd_master = RPMSG_VIRTIO_CMD(RPMSG_VIRTIO_CMD_PANIC, 0); - } - else - { - cmd->cmd_slave = RPMSG_VIRTIO_CMD(RPMSG_VIRTIO_CMD_PANIC, 0); - } - - rpmsg_virtio_notify(priv->vdev.vrings_info->vq); -} - -#ifdef CONFIG_OPENAMP_DEBUG -static int rpmsg_virtio_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, - bool rx) -{ - FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq; - uint16_t nused = vq->vq_ring.avail->idx - vq->vq_ring.used->idx; - - if ((rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) ^ rx) - { - return nused; - } - else - { - return vq->vq_nentries - nused; - } -} - -static void rpmsg_virtio_dump_buffer(FAR struct rpmsg_virtio_device *rvdev, - bool rx) -{ - FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq; - int num; - int i; - - num = rpmsg_virtio_buffer_nused(rvdev, rx); - metal_log(METAL_LOG_EMERGENCY, - " %s buffer, total %d, pending %d\n", - rx ? "RX" : "TX", vq->vq_nentries, num); - - for (i = 0; i < num; i++) - { - FAR void *addr; - int desc_idx; - - if ((rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) ^ 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) - { - FAR struct rpmsg_hdr *hdr = addr; - FAR struct rpmsg_endpoint *ept; - - ept = rpmsg_get_ept_from_addr(&rvdev->rdev, - rx ? hdr->dst : hdr->src); - if (ept) - { - metal_log(METAL_LOG_EMERGENCY, - " %s buffer %p hold by %s\n", - rx ? "RX" : "TX", hdr, ept->name); - } - } - } -} - -static void rpmsg_virtio_dump(FAR struct rpmsg_s *rpmsg) -{ - FAR struct rpmsg_virtio_priv_s *priv = - (FAR struct rpmsg_virtio_priv_s *)rpmsg; - FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; - FAR struct rpmsg_device *rdev = rpmsg->rdev; - FAR struct rpmsg_endpoint *ept; - FAR struct metal_list *node; - bool needlock = true; - - if (!rvdev->vdev) - { - return; - } - - if (up_interrupt_context() || sched_idletask() || - nxmutex_is_hold(&rdev->lock)) - { - needlock = false; - } - - if (needlock) - { - metal_mutex_acquire(&rdev->lock); - } - - metal_log(METAL_LOG_EMERGENCY, - "Dump rpmsg info between cpu (master: %s)%s <==> %s:\n", - rpmsg_virtio_get_role(rvdev) == RPMSG_HOST ? "yes" : "no", - CONFIG_RPMSG_LOCAL_CPUNAME, rpmsg_get_cpuname(rdev)); - - metal_log(METAL_LOG_EMERGENCY, "rpmsg vq RX:\n"); - virtqueue_dump(rvdev->rvq); - metal_log(METAL_LOG_EMERGENCY, "rpmsg vq TX:\n"); - virtqueue_dump(rvdev->svq); - - metal_log(METAL_LOG_EMERGENCY, " rpmsg ept list:\n"); - - metal_list_for_each(&rdev->endpoints, node) - { - ept = metal_container_of(node, struct rpmsg_endpoint, node); - metal_log(METAL_LOG_EMERGENCY, " ept %s\n", ept->name); - } - - metal_log(METAL_LOG_EMERGENCY, " rpmsg buffer list:\n"); - - rpmsg_virtio_dump_buffer(rvdev, true); - rpmsg_virtio_dump_buffer(rvdev, false); - - if (needlock) - { - metal_mutex_release(&rdev->lock); - } -} -#else -static void rpmsg_virtio_dump(FAR struct rpmsg_s *rpmsg) -{ - /* Nothing */ -} -#endif - -static FAR const char * -rpmsg_virtio_get_local_cpuname(FAR struct rpmsg_s *rpmsg) -{ - FAR struct rpmsg_virtio_priv_s *priv = - (FAR struct rpmsg_virtio_priv_s *)rpmsg; - - return RPMSG_VIRTIO_GET_LOCAL_CPUNAME(priv->dev); -} - -static FAR const char *rpmsg_virtio_get_cpuname(FAR struct rpmsg_s *rpmsg) -{ - FAR struct rpmsg_virtio_priv_s *priv = - (FAR struct rpmsg_virtio_priv_s *)rpmsg; - - return RPMSG_VIRTIO_GET_CPUNAME(priv->dev); -} - -static void rpmsg_virtio_wakeup_rx(FAR struct rpmsg_virtio_priv_s *priv) -{ - int semcount; - - nxsem_get_value(&priv->semrx, &semcount); - if (semcount < 1) - { - nxsem_post(&priv->semrx); - } -} - -static void rpmsg_virtio_command(FAR struct rpmsg_virtio_priv_s *priv) -{ - FAR struct rpmsg_virtio_cmd_s *rpmsg_virtio_cmd = - RPMSG_VIRTIO_RSC2CMD(priv->rsc); - uint32_t cmd; - - if (RPMSG_VIRTIO_IS_MASTER(priv->dev)) - { - cmd = rpmsg_virtio_cmd->cmd_slave; - rpmsg_virtio_cmd->cmd_slave = 0; - } - else - { - cmd = rpmsg_virtio_cmd->cmd_master; - rpmsg_virtio_cmd->cmd_master = 0; - } - - switch (RPMSG_VIRTIO_GET_CMD(cmd)) - { - case RPMSG_VIRTIO_CMD_PANIC: - PANIC(); - break; - - default: - break; - } -} - -static int rpmsg_virtio_callback(FAR void *arg, uint32_t vqid) -{ - FAR struct rpmsg_virtio_priv_s *priv = arg; - FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; - FAR struct virtio_device *vdev = rvdev->vdev; - FAR struct virtqueue *rvq = rvdev->rvq; - - rpmsg_virtio_command(priv); - - if (vqid == RPMSG_VIRTIO_NOTIFY_ALL || - vqid == vdev->vrings_info[rvq->vq_queue_index].notifyid) - { - rpmsg_virtio_wakeup_rx(priv); - } - - return OK; -} - -static int rpmsg_virtio_notify_wait(FAR struct rpmsg_device *rdev, - uint32_t id) -{ - FAR struct rpmsg_virtio_priv_s *priv = - metal_container_of(rdev, struct rpmsg_virtio_priv_s, rvdev.rdev); - - if (!rpmsg_virtio_is_recursive(priv)) - { - return -EAGAIN; - } - - /* Wait to wakeup */ - - nxsem_tickwait(&priv->semtx, MSEC2TICK(RPMSG_VIRTIO_TIMEOUT_MS)); - virtqueue_notification(priv->rvdev.rvq); - - return 0; -} - -static int rpmsg_virtio_start(FAR struct rpmsg_virtio_priv_s *priv) -{ - FAR struct virtio_vring_info *rvrings = priv->rvrings; - FAR struct virtio_device *vdev = &priv->vdev; - FAR struct rpmsg_virtio_rsc_s *rsc; - struct rpmsg_virtio_config config; - FAR void *shbuf0; - FAR void *shbuf1; - uint32_t align0; - uint32_t align1; - uint32_t tbsz; - uint32_t v0sz; - uint32_t v1sz; - uint32_t shbufsz0; - uint32_t shbufsz1; - int ret; - - rsc = RPMSG_VIRTIO_GET_RESOURCE(priv->dev); - if (!rsc) - { - return -EINVAL; - } - - priv->rsc = rsc; - - vdev->notifyid = RPMSG_VIRTIO_NOTIFYID; - vdev->vrings_num = rsc->rpmsg_vdev.num_of_vrings; - vdev->role = RPMSG_VIRTIO_IS_MASTER(priv->dev) ? RPMSG_HOST : RPMSG_REMOTE; - vdev->func = &g_rpmsg_virtio_dispatch; - - align0 = rsc->rpmsg_vring0.align; - align1 = rsc->rpmsg_vring1.align; - tbsz = ALIGN_UP(sizeof(struct rpmsg_virtio_rsc_s), MAX(align0, align1)); - v0sz = ALIGN_UP(vring_size(rsc->rpmsg_vring0.num, align0), align0); - v1sz = ALIGN_UP(vring_size(rsc->rpmsg_vring1.num, align1), align1); - - shbuf0 = (FAR char *)rsc + tbsz + v0sz + v1sz; - shbufsz0 = rsc->config.r2h_buf_size * rsc->rpmsg_vring0.num; - shbuf1 = shbuf0 + shbufsz0; - shbufsz1 = rsc->config.h2r_buf_size * rsc->rpmsg_vring1.num; - - rvrings[0].io = metal_io_get_region(); - rvrings[0].info.vaddr = (FAR char *)rsc + tbsz; - rvrings[0].info.num_descs = rsc->rpmsg_vring0.num; - rvrings[0].info.align = rsc->rpmsg_vring0.align; - rvrings[0].vq = virtqueue_allocate(rsc->rpmsg_vring0.num); - if (rvrings[0].vq == NULL) - { - return -ENOMEM; - } - - rvrings[1].io = metal_io_get_region(); - rvrings[1].info.vaddr = (FAR char *)rsc + tbsz + v0sz; - rvrings[1].info.num_descs = rsc->rpmsg_vring1.num; - rvrings[1].info.align = rsc->rpmsg_vring1.align; - rvrings[1].vq = virtqueue_allocate(rsc->rpmsg_vring1.num); - if (rvrings[1].vq == NULL) - { - ret = -ENOMEM; - goto err_vq0; - } - - vdev->vrings_info = &rvrings[0]; - - rpmsg_virtio_init_shm_pool(&priv->pool[0], shbuf0, shbufsz0); - rpmsg_virtio_init_shm_pool(&priv->pool[1], shbuf1, shbufsz1); - - config.h2r_buf_size = rsc->config.h2r_buf_size; - config.r2h_buf_size = rsc->config.r2h_buf_size; - config.split_shpool = true; - - ret = rpmsg_init_vdev_with_config(&priv->rvdev, vdev, rpmsg_ns_bind, - metal_io_get_region(), - priv->pool, &config); - if (ret != 0) - { - rpmsgerr("rpmsg_init_vdev failed %d\n", ret); - ret = -ENOMEM; - goto err_vq1; - } - - priv->rvdev.rdev.ns_unbind_cb = rpmsg_ns_unbind; - priv->rvdev.notify_wait_cb = rpmsg_virtio_notify_wait; - - RPMSG_VIRTIO_REGISTER_CALLBACK(priv->dev, rpmsg_virtio_callback, priv); - - rpmsg_virtio_wakeup_rx(priv); - - /* Broadcast device_created to all registers */ - - rpmsg_device_created(&priv->rpmsg); - - return 0; - -err_vq1: - virtqueue_free(rvrings[1].vq); -err_vq0: - virtqueue_free(rvrings[0].vq); - return ret; -} - -static int rpmsg_virtio_thread(int argc, FAR char *argv[]) -{ - FAR struct rpmsg_virtio_priv_s *priv = (FAR struct rpmsg_virtio_priv_s *) - ((uintptr_t)strtoul(argv[2], NULL, 16)); - int ret; - - priv->tid = nxsched_gettid(); - - ret = rpmsg_virtio_start(priv); - if (ret < 0) - { - rpmsgerr("rpmsg virtio thread start failed %d\n", ret); - return ret; - } - - while (1) - { - nxsem_wait_uninterruptible(&priv->semrx); - virtqueue_notification(priv->rvdev.rvq); - } - - return 0; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -int rpmsg_virtio_initialize(FAR struct rpmsg_virtio_s *dev) -{ - FAR struct rpmsg_virtio_priv_s *priv; - FAR char *argv[3]; - char arg1[32]; - char name[32]; - int ret; - - priv = kmm_zalloc(sizeof(struct rpmsg_virtio_priv_s)); - if (priv == NULL) - { - return -ENOMEM; - } - - priv->dev = dev; - nxsem_init(&priv->semrx, 0, 0); - nxsem_init(&priv->semtx, 0, 0); - - snprintf(name, sizeof(name), "/dev/rpmsg/%s", - RPMSG_VIRTIO_GET_CPUNAME(dev)); - ret = rpmsg_register(name, &priv->rpmsg, &g_rpmsg_virtio_ops); - if (ret < 0) - { - goto err_driver; - } - - snprintf(arg1, sizeof(arg1), "%p", priv); - argv[0] = (FAR char *)RPMSG_VIRTIO_GET_CPUNAME(dev); - argv[1] = arg1; - argv[2] = NULL; - - ret = kthread_create("rpmsg_virtio", CONFIG_RPMSG_VIRTIO_PRIORITY, - CONFIG_RPMSG_VIRTIO_STACKSIZE, - rpmsg_virtio_thread, argv); - if (ret < 0) - { - goto err_thread; - } - - return OK; - -err_thread: - rpmsg_unregister(name, &priv->rpmsg); - -err_driver: - nxsem_destroy(&priv->semrx); - nxsem_destroy(&priv->semtx); - kmm_free(priv); - - return ret; -} diff --git a/drivers/rpmsg/rpmsg_virtio_ivshmem.c b/drivers/rpmsg/rpmsg_virtio_ivshmem.c index f3d1fc4c3c2..dadc009f8fb 100644 --- a/drivers/rpmsg/rpmsg_virtio_ivshmem.c +++ b/drivers/rpmsg/rpmsg_virtio_ivshmem.c @@ -32,8 +32,8 @@ #include #include -#include #include +#include #include /**************************************************************************** @@ -53,15 +53,15 @@ struct rpmsg_virtio_ivshmem_mem_s { - volatile uint64_t basem; - volatile uint32_t seqs; - volatile uint32_t seqm; - struct rpmsg_virtio_rsc_s rsc; + volatile uint64_t basem; + volatile uint32_t seqs; + volatile uint32_t seqm; + struct rpmsg_virtio_lite_rsc_s rsc; }; struct rpmsg_virtio_ivshmem_dev_s { - struct rpmsg_virtio_s dev; + struct rpmsg_virtio_lite_s dev; struct ivshmem_driver_s drv; FAR struct ivshmem_device_s *ivdev; rpmsg_virtio_callback_t callback; @@ -84,15 +84,15 @@ struct rpmsg_virtio_ivshmem_dev_s ****************************************************************************/ static const FAR char * -rpmsg_virtio_ivshmem_get_cpuname(FAR struct rpmsg_virtio_s *dev); -static FAR struct rpmsg_virtio_rsc_s * -rpmsg_virtio_ivshmem_get_resource(FAR struct rpmsg_virtio_s *dev); +rpmsg_virtio_ivshmem_get_cpuname(FAR struct rpmsg_virtio_lite_s *dev); +static FAR struct rpmsg_virtio_lite_rsc_s * +rpmsg_virtio_ivshmem_get_resource(FAR struct rpmsg_virtio_lite_s *dev); static int -rpmsg_virtio_ivshmem_is_master(FAR struct rpmsg_virtio_s *dev); -static int rpmsg_virtio_ivshmem_notify(FAR struct rpmsg_virtio_s *dev, +rpmsg_virtio_ivshmem_is_master(FAR struct rpmsg_virtio_lite_s *dev); +static int rpmsg_virtio_ivshmem_notify(FAR struct rpmsg_virtio_lite_s *dev, uint32_t notifyid); static int -rpmsg_virtio_ivshmem_register_callback(FAR struct rpmsg_virtio_s *dev, +rpmsg_virtio_ivshmem_register_callback(FAR struct rpmsg_virtio_lite_s *dev, rpmsg_virtio_callback_t callback, FAR void *arg); static int rpmsg_virtio_ivshmem_probe(FAR struct ivshmem_device_s *ivdev); @@ -102,7 +102,7 @@ static void rpmsg_virtio_ivshmem_remove(FAR struct ivshmem_device_s *ivdev); * Private Data ****************************************************************************/ -static const struct rpmsg_virtio_ops_s g_rpmsg_virtio_ivshmem_ops = +static const struct rpmsg_virtio_lite_ops_s g_rpmsg_virtio_ivshmem_ops = { .get_cpuname = rpmsg_virtio_ivshmem_get_cpuname, .get_resource = rpmsg_virtio_ivshmem_get_resource, @@ -116,23 +116,23 @@ static const struct rpmsg_virtio_ops_s g_rpmsg_virtio_ivshmem_ops = ****************************************************************************/ static const FAR char * -rpmsg_virtio_ivshmem_get_cpuname(FAR struct rpmsg_virtio_s *dev) +rpmsg_virtio_ivshmem_get_cpuname(FAR struct rpmsg_virtio_lite_s *dev) { FAR struct rpmsg_virtio_ivshmem_dev_s *priv = (FAR struct rpmsg_virtio_ivshmem_dev_s *)dev; return priv->cpuname; } -static FAR struct rpmsg_virtio_rsc_s * -rpmsg_virtio_ivshmem_get_resource(FAR struct rpmsg_virtio_s *dev) +static FAR struct rpmsg_virtio_lite_rsc_s * +rpmsg_virtio_ivshmem_get_resource(FAR struct rpmsg_virtio_lite_s *dev) { FAR struct rpmsg_virtio_ivshmem_dev_s *priv = (FAR struct rpmsg_virtio_ivshmem_dev_s *)dev; - FAR struct rpmsg_virtio_rsc_s *rsc; - FAR struct rpmsg_virtio_cmd_s *cmd; + FAR struct rpmsg_virtio_lite_rsc_s *rsc; + FAR struct rpmsg_virtio_lite_cmd_s *cmd; rsc = &priv->shmem->rsc; - cmd = RPMSG_VIRTIO_RSC2CMD(rsc); + cmd = RPMSG_VIRTIO_LITE_RSC2CMD(rsc); if (priv->master) { @@ -178,14 +178,15 @@ rpmsg_virtio_ivshmem_get_resource(FAR struct rpmsg_virtio_s *dev) return rsc; } -static int rpmsg_virtio_ivshmem_is_master(FAR struct rpmsg_virtio_s *dev) +static int +rpmsg_virtio_ivshmem_is_master(FAR struct rpmsg_virtio_lite_s *dev) { FAR struct rpmsg_virtio_ivshmem_dev_s *priv = (FAR struct rpmsg_virtio_ivshmem_dev_s *)dev; return priv->master; } -static int rpmsg_virtio_ivshmem_notify(FAR struct rpmsg_virtio_s *dev, +static int rpmsg_virtio_ivshmem_notify(FAR struct rpmsg_virtio_lite_s *dev, uint32_t vqid) { FAR struct rpmsg_virtio_ivshmem_dev_s *priv = @@ -208,7 +209,7 @@ static int rpmsg_virtio_ivshmem_notify(FAR struct rpmsg_virtio_s *dev, } static int -rpmsg_virtio_ivshmem_register_callback(FAR struct rpmsg_virtio_s *dev, +rpmsg_virtio_ivshmem_register_callback(FAR struct rpmsg_virtio_lite_s *dev, rpmsg_virtio_callback_t callback, FAR void *arg) { @@ -231,7 +232,7 @@ static int rpmsg_virtio_ivshmem_interrupt(int irq, FAR void *context, if (priv->callback != NULL) { - priv->callback(priv->arg, RPMSG_VIRTIO_NOTIFY_ALL); + priv->callback(priv->arg, RPMSG_VIRTIO_LITE_NOTIFY_ALL); } return 0; @@ -260,7 +261,7 @@ static void rpmsg_virtio_ivshmem_wdog(wdparm_t arg) if (should_notify && priv->callback != NULL) { - priv->callback(priv->arg, RPMSG_VIRTIO_NOTIFY_ALL); + priv->callback(priv->arg, RPMSG_VIRTIO_LITE_NOTIFY_ALL); } wd_start(&priv->wdog, RPMSG_VIRTIO_IVSHMEM_WDOG_DELAY, @@ -288,7 +289,7 @@ static int rpmsg_virtio_ivshmem_probe(FAR struct ivshmem_device_s *ivdev) /* Do rpmsg virtio initialize */ - ret = rpmsg_virtio_initialize(&priv->dev); + ret = rpmsg_virtio_lite_initialize(&priv->dev); if (ret < 0) { rpmsgerr("Rpmsg virtio initialize failed, ret=%d\n", ret); diff --git a/drivers/rpmsg/rpmsg_virtio_lite.c b/drivers/rpmsg/rpmsg_virtio_lite.c new file mode 100644 index 00000000000..38eb9d7641f --- /dev/null +++ b/drivers/rpmsg/rpmsg_virtio_lite.c @@ -0,0 +1,835 @@ +/**************************************************************************** + * drivers/rpmsg/rpmsg_virtio_lite.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define RPMSG_VIRTIO_LITE_TIMEOUT_MS 20 +#define RPMSG_VIRTIO_LITE_NOTIFYID 0 + +#ifdef CONFIG_OPENAMP_CACHE +# define RPMSG_VIRTIO_INVALIDATE(x) metal_cache_invalidate(&x, sizeof(x)) +#else +# define RPMSG_VIRTIO_INVALIDATE(x) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rpmsg_virtio_lite_priv_s +{ + struct rpmsg_s rpmsg; + struct rpmsg_virtio_device rvdev; + FAR struct rpmsg_virtio_lite_s *dev; + FAR struct rpmsg_virtio_lite_rsc_s *rsc; + struct virtio_device vdev; + struct rpmsg_virtio_shm_pool pool[2]; + struct virtio_vring_info rvrings[2]; + sem_t semtx; + sem_t semrx; + pid_t tid; + uint16_t headrx; +#ifdef CONFIG_RPMSG_VIRTIO_LITE_PM + struct pm_wakelock_s wakelock; + struct wdog_s wdog; +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int rpmsg_virtio_lite_wait(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); +static int rpmsg_virtio_lite_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); +static void rpmsg_virtio_lite_panic(FAR struct rpmsg_s *rpmsg); +static void rpmsg_virtio_lite_dump(FAR struct rpmsg_s *rpmsg); +static FAR const char * +rpmsg_virtio_lite_get_local_cpuname(FAR struct rpmsg_s *rpmsg); +static FAR const char * +rpmsg_virtio_lite_get_cpuname(FAR struct rpmsg_s *rpmsg); + +static int +rpmsg_virtio_lite_create_virtqueues_(FAR struct virtio_device *vdev, + unsigned int flags, + unsigned int nvqs, + FAR const char *names[], + vq_callback callbacks[], + FAR void *callback_args[]); +static uint8_t rpmsg_virtio_lite_get_status_(FAR struct virtio_device *dev); +static void rpmsg_virtio_lite_set_status_(FAR struct virtio_device *dev, + uint8_t status); +static uint64_t +rpmsg_virtio_lite_get_features_(FAR struct virtio_device *dev); +static void rpmsg_virtio_lite_set_features(FAR struct virtio_device *dev, + uint64_t feature); +static void rpmsg_virtio_lite_notify(FAR struct virtqueue *vq); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct rpmsg_ops_s g_rpmsg_virtio_lite_ops = +{ + .wait = rpmsg_virtio_lite_wait, + .post = rpmsg_virtio_lite_post, + .panic = rpmsg_virtio_lite_panic, + .dump = rpmsg_virtio_lite_dump, + .get_local_cpuname = rpmsg_virtio_lite_get_local_cpuname, + .get_cpuname = rpmsg_virtio_lite_get_cpuname, +}; + +static const struct virtio_dispatch g_rpmsg_virtio_lite_dispatch = +{ + .create_virtqueues = rpmsg_virtio_lite_create_virtqueues_, + .get_status = rpmsg_virtio_lite_get_status_, + .set_status = rpmsg_virtio_lite_set_status_, + .get_features = rpmsg_virtio_lite_get_features_, + .set_features = rpmsg_virtio_lite_set_features, + .notify = rpmsg_virtio_lite_notify, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#if defined(CONFIG_OPENAMP_DEBUG) || \ + defined(CONFIG_RPMSG_VIRTIO_LITE_PM_AUTORELAX) +static int +rpmsg_virtio_lite_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, + bool rx) +{ + FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq; + uint16_t nused = vq->vq_ring.avail->idx - vq->vq_ring.used->idx; + + if ((rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) ^ rx) + { + return nused; + } + else + { + return vq->vq_nentries - nused; + } +} +#endif + +static void +rpmsg_virtio_lite_wakeup_tx(FAR struct rpmsg_virtio_lite_priv_s *priv) +{ + int semcount; + + nxsem_get_value(&priv->semtx, &semcount); + while (semcount++ < 1) + { + nxsem_post(&priv->semtx); + } +} + +#ifdef CONFIG_RPMSG_VIRTIO_LITE_PM + +#ifdef CONFIG_RPMSG_VIRTIO_LITE_PM_AUTORELAX +static void rpmsg_virtio_lite_pm_callback(wdparm_t arg) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + (FAR struct rpmsg_virtio_lite_priv_s *)arg; + + if (rpmsg_virtio_lite_buffer_nused(&priv->rvdev, false)) + { + rpmsg_virtio_lite_wakeup_tx(priv); + + wd_start(&priv->wdog, MSEC2TICK(RPMSG_VIRTIO_LITE_TIMEOUT_MS), + rpmsg_virtio_lite_pm_callback, (wdparm_t)priv); + } + else + { + pm_wakelock_relax(&priv->wakelock); + } +} +#endif + +static inline void +rpmsg_virtio_lite_pm_action(FAR struct rpmsg_virtio_lite_priv_s *priv, + bool stay) +{ + irqstate_t flags; + int count; + + flags = enter_critical_section(); + + count = pm_wakelock_staycount(&priv->wakelock); + if (stay && count == 0) + { + pm_wakelock_stay(&priv->wakelock); +#ifdef CONFIG_RPMSG_VIRTIO_LITE_PM_AUTORELAX + wd_start(&priv->wdog, MSEC2TICK(RPMSG_VIRTIO_LITE_TIMEOUT_MS), + rpmsg_virtio_lite_pm_callback, (wdparm_t)priv); +#endif + } + +#ifndef CONFIG_RPMSG_VIRTIO_LITE_PM_AUTORELAX + if (!stay && count > 0 && + rpmsg_virtio_lite_buffer_nused(&priv->rvdev, false) == 0) + { + pm_wakelock_relax(&priv->wakelock); + } +#endif + + leave_critical_section(flags); +} + +static inline bool +rpmsg_virtio_lite_available_rx(FAR struct rpmsg_virtio_lite_priv_s *priv) +{ + FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; + FAR struct virtqueue *rvq = rvdev->rvq; + + if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) + { + return priv->headrx != rvq->vq_used_cons_idx; + } + else + { + return priv->headrx != rvq->vq_available_idx; + } +} + +#else +# define rpmsg_virtio_lite_pm_action(priv, stay) +# define rpmsg_virtio_lite_available_rx(priv) true +#endif + +static inline void +rpmsg_virtio_lite_update_rx(FAR struct rpmsg_virtio_lite_priv_s *priv) +{ + FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; + FAR struct virtqueue *rvq = rvdev->rvq; + + if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) + { + RPMSG_VIRTIO_INVALIDATE(rvq->vq_ring.used->idx); + priv->headrx = rvq->vq_ring.used->idx; + } + else + { + RPMSG_VIRTIO_INVALIDATE(rvq->vq_ring.avail->idx); + priv->headrx = rvq->vq_ring.avail->idx; + } +} + +static FAR struct rpmsg_virtio_lite_priv_s * +rpmsg_virtio_lite_get_priv(FAR struct virtio_device *vdev) +{ + FAR struct rpmsg_virtio_device *rvdev = vdev->priv; + + return metal_container_of(rvdev, struct rpmsg_virtio_lite_priv_s, rvdev); +} + +static int +rpmsg_virtio_lite_create_virtqueues_(FAR struct virtio_device *vdev, + unsigned int flags, + unsigned int nvqs, + FAR const char *names[], + vq_callback callbacks[], + FAR void *callback_args[]) +{ + int ret; + int i; + + if (nvqs > vdev->vrings_num) + { + return ERROR_VQUEUE_INVLD_PARAM; + } + + /* Initialize virtqueue for each vring */ + + for (i = 0; i < nvqs; i++) + { + FAR struct virtio_vring_info *vinfo = &vdev->vrings_info[i]; + FAR struct vring_alloc_info *valloc = &vinfo->info; +#ifndef CONFIG_OPENAMP_VIRTIO_DEVICE_ONLY + if (vdev->role == VIRTIO_DEV_DRIVER) + { + size_t offset; + + offset = metal_io_virt_to_offset(vinfo->io, valloc->vaddr); + metal_io_block_set(vinfo->io, offset, 0, + vring_size(valloc->num_descs, valloc->align)); + } +#endif + + ret = virtqueue_create(vdev, i, names[i], valloc, + callbacks[i], vdev->func->notify, + vinfo->vq); + if (ret < 0) + { + return ret; + } + } + + return 0; +} + +static uint8_t rpmsg_virtio_lite_get_status_(FAR struct virtio_device *vdev) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + rpmsg_virtio_lite_get_priv(vdev); + + return priv->rsc->rpmsg_vdev.status; +} + +static void rpmsg_virtio_lite_set_status_(FAR struct virtio_device *vdev, + uint8_t status) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + rpmsg_virtio_lite_get_priv(vdev); + + priv->rsc->rpmsg_vdev.status = status; +} + +static uint64_t +rpmsg_virtio_lite_get_features_(FAR struct virtio_device *vdev) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + rpmsg_virtio_lite_get_priv(vdev); + + return priv->rsc->rpmsg_vdev.dfeatures; +} + +static void rpmsg_virtio_lite_set_features(FAR struct virtio_device *vdev, + uint64_t features) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + rpmsg_virtio_lite_get_priv(vdev); + + priv->rsc->rpmsg_vdev.gfeatures = features; +} + +static void rpmsg_virtio_lite_notify(FAR struct virtqueue *vq) +{ + FAR struct virtio_device *vdev = vq->vq_dev; + FAR struct rpmsg_virtio_lite_priv_s *priv = + rpmsg_virtio_lite_get_priv(vdev); + FAR struct virtqueue *svq = priv->rvdev.svq; + + if (vdev->vrings_info->notifyid == + vdev->vrings_info[svq->vq_queue_index].notifyid) + { + rpmsg_virtio_lite_pm_action(priv, true); + } + + RPMSG_VIRTIO_LITE_NOTIFY(priv->dev, vdev->vrings_info->notifyid); +} + +static bool +rpmsg_virtio_lite_is_recursive(FAR struct rpmsg_virtio_lite_priv_s *priv) +{ + return nxsched_gettid() == priv->tid; +} + +static int rpmsg_virtio_lite_wait(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + (FAR struct rpmsg_virtio_lite_priv_s *)rpmsg; + int ret; + + if (!rpmsg_virtio_lite_is_recursive(priv)) + { + return nxsem_wait_uninterruptible(sem); + } + + while (1) + { + ret = nxsem_trywait(sem); + if (ret >= 0) + { + break; + } + + nxsem_wait(&priv->semtx); + virtqueue_notification(priv->rvdev.rvq); + } + + return ret; +} + +static int rpmsg_virtio_lite_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + (FAR struct rpmsg_virtio_lite_priv_s *)rpmsg; + int semcount; + int ret; + + nxsem_get_value(sem, &semcount); + ret = nxsem_post(sem); + + if (priv && semcount >= 0) + { + rpmsg_virtio_lite_wakeup_tx(priv); + } + + return ret; +} + +static void rpmsg_virtio_lite_panic(FAR struct rpmsg_s *rpmsg) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + (FAR struct rpmsg_virtio_lite_priv_s *)rpmsg; + FAR struct rpmsg_virtio_lite_cmd_s *cmd = + RPMSG_VIRTIO_LITE_RSC2CMD(priv->rsc); + + if (RPMSG_VIRTIO_LITE_IS_MASTER(priv->dev)) + { + cmd->cmd_master = RPMSG_VIRTIO_LITE_CMD( + RPMSG_VIRTIO_LITE_CMD_PANIC, 0); + } + else + { + cmd->cmd_slave = RPMSG_VIRTIO_LITE_CMD( + RPMSG_VIRTIO_LITE_CMD_PANIC, 0); + } + + rpmsg_virtio_lite_notify(priv->vdev.vrings_info->vq); +} + +#ifdef CONFIG_OPENAMP_DEBUG +static void +rpmsg_virtio_lite_dump_buffer(FAR struct rpmsg_virtio_device *rvdev, bool rx) +{ + FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq; + int num; + int i; + + num = rpmsg_virtio_lite_buffer_nused(rvdev, rx); + metal_log(METAL_LOG_EMERGENCY, + " %s buffer, total %d, pending %d\n", + rx ? "RX" : "TX", vq->vq_nentries, num); + + for (i = 0; i < num; i++) + { + FAR void *addr; + int desc_idx; + + if ((rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) ^ 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) + { + FAR struct rpmsg_hdr *hdr = addr; + FAR struct rpmsg_endpoint *ept; + + ept = rpmsg_get_ept_from_addr(&rvdev->rdev, + rx ? hdr->dst : hdr->src); + if (ept) + { + metal_log(METAL_LOG_EMERGENCY, + " %s buffer %p hold by %s\n", + rx ? "RX" : "TX", hdr, ept->name); + } + } + } +} + +static void rpmsg_virtio_lite_dump(FAR struct rpmsg_s *rpmsg) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + (FAR struct rpmsg_virtio_lite_priv_s *)rpmsg; + FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; + FAR struct rpmsg_device *rdev = rpmsg->rdev; + FAR struct rpmsg_endpoint *ept; + FAR struct metal_list *node; + bool needlock = true; + + metal_log(METAL_LOG_EMERGENCY, "Remote: %s headrx %d\n", + RPMSG_VIRTIO_LITE_GET_CPUNAME(priv->dev), priv->headrx); + + if (!rvdev->vdev) + { + return; + } + + if (up_interrupt_context() || sched_idletask() || + nxmutex_is_hold(&rdev->lock)) + { + needlock = false; + } + + if (needlock) + { + metal_mutex_acquire(&rdev->lock); + } + + metal_log(METAL_LOG_EMERGENCY, + "Dump rpmsg info between cpu (master: %s)%s <==> %s:\n", + rpmsg_virtio_get_role(rvdev) == RPMSG_HOST ? "yes" : "no", + CONFIG_RPMSG_LOCAL_CPUNAME, rpmsg_get_cpuname(rdev)); + + metal_log(METAL_LOG_EMERGENCY, "rpmsg vq RX:\n"); + virtqueue_dump(rvdev->rvq); + metal_log(METAL_LOG_EMERGENCY, "rpmsg vq TX:\n"); + virtqueue_dump(rvdev->svq); + + metal_log(METAL_LOG_EMERGENCY, " rpmsg ept list:\n"); + + metal_list_for_each(&rdev->endpoints, node) + { + ept = metal_container_of(node, struct rpmsg_endpoint, node); + metal_log(METAL_LOG_EMERGENCY, " ept %s\n", ept->name); + } + + metal_log(METAL_LOG_EMERGENCY, " rpmsg buffer list:\n"); + + rpmsg_virtio_lite_dump_buffer(rvdev, true); + rpmsg_virtio_lite_dump_buffer(rvdev, false); + + if (needlock) + { + metal_mutex_release(&rdev->lock); + } +} +#else +static void rpmsg_virtio_lite_dump(FAR struct rpmsg_s *rpmsg) +{ + /* Nothing */ +} +#endif + +static FAR const char * +rpmsg_virtio_lite_get_local_cpuname(FAR struct rpmsg_s *rpmsg) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + (FAR struct rpmsg_virtio_lite_priv_s *)rpmsg; + + return RPMSG_VIRTIO_LITE_GET_LOCAL_CPUNAME(priv->dev); +} + +static FAR const char * +rpmsg_virtio_lite_get_cpuname(FAR struct rpmsg_s *rpmsg) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + (FAR struct rpmsg_virtio_lite_priv_s *)rpmsg; + + return RPMSG_VIRTIO_LITE_GET_CPUNAME(priv->dev); +} + +static void +rpmsg_virtio_lite_wakeup_rx(FAR struct rpmsg_virtio_lite_priv_s *priv) +{ + int semcount; + + nxsem_get_value(&priv->semrx, &semcount); + if (semcount < 1) + { + nxsem_post(&priv->semrx); + } +} + +static void rpmsg_virtio_lite_command(struct rpmsg_virtio_lite_priv_s *priv) +{ + FAR struct rpmsg_virtio_lite_cmd_s *rpmsg_virtio_cmd = + RPMSG_VIRTIO_LITE_RSC2CMD(priv->rsc); + uint32_t cmd; + + if (RPMSG_VIRTIO_LITE_IS_MASTER(priv->dev)) + { + cmd = rpmsg_virtio_cmd->cmd_slave; + rpmsg_virtio_cmd->cmd_slave = 0; + } + else + { + cmd = rpmsg_virtio_cmd->cmd_master; + rpmsg_virtio_cmd->cmd_master = 0; + } + + switch (RPMSG_VIRTIO_LITE_GET_CMD(cmd)) + { + case RPMSG_VIRTIO_LITE_CMD_PANIC: + PANIC(); + break; + + default: + break; + } +} + +static int rpmsg_virtio_lite_callback(FAR void *arg, uint32_t vqid) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = arg; + FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; + FAR struct virtio_device *vdev = rvdev->vdev; + FAR struct virtqueue *rvq = rvdev->rvq; + FAR struct virtqueue *svq = rvdev->svq; + + rpmsg_virtio_lite_command(priv); + + if (vqid == RPMSG_VIRTIO_LITE_NOTIFY_ALL || + vqid == vdev->vrings_info[rvq->vq_queue_index].notifyid) + { + rpmsg_virtio_lite_update_rx(priv); + rpmsg_virtio_lite_wakeup_rx(priv); + } + + if (vqid == RPMSG_VIRTIO_LITE_NOTIFY_ALL || + vqid == vdev->vrings_info[svq->vq_queue_index].notifyid) + { + rpmsg_virtio_lite_wakeup_tx(priv); + rpmsg_virtio_lite_pm_action(priv, false); + } + + return OK; +} + +static int rpmsg_virtio_lite_notify_wait(FAR struct rpmsg_device *rdev, + uint32_t id) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + metal_container_of(rdev, struct rpmsg_virtio_lite_priv_s, rvdev.rdev); + + if (!rpmsg_virtio_lite_is_recursive(priv)) + { + return -EAGAIN; + } + + /* Wait to wakeup */ + + nxsem_tickwait(&priv->semtx, MSEC2TICK(RPMSG_VIRTIO_LITE_TIMEOUT_MS)); + virtqueue_notification(priv->rvdev.rvq); + + return 0; +} + +static int rpmsg_virtio_lite_start(FAR struct rpmsg_virtio_lite_priv_s *priv) +{ + FAR struct virtio_vring_info *rvrings = priv->rvrings; + FAR struct virtio_device *vdev = &priv->vdev; + FAR struct rpmsg_virtio_lite_rsc_s *rsc; + struct rpmsg_virtio_config config; + FAR void *shbuf0; + FAR void *shbuf1; + uint32_t align0; + uint32_t align1; + uint32_t tbsz; + uint32_t v0sz; + uint32_t v1sz; + uint32_t shbufsz0; + uint32_t shbufsz1; + int ret; + + rsc = RPMSG_VIRTIO_LITE_GET_RESOURCE(priv->dev); + if (!rsc) + { + return -EINVAL; + } + + priv->rsc = rsc; + + vdev->notifyid = RPMSG_VIRTIO_LITE_NOTIFYID; + vdev->vrings_num = rsc->rpmsg_vdev.num_of_vrings; + vdev->role = RPMSG_VIRTIO_LITE_IS_MASTER(priv->dev) ? + RPMSG_HOST : RPMSG_REMOTE; + vdev->func = &g_rpmsg_virtio_lite_dispatch; + + align0 = rsc->rpmsg_vring0.align; + align1 = rsc->rpmsg_vring1.align; + tbsz = ALIGN_UP(sizeof(*rsc), MAX(align0, align1)); + v0sz = ALIGN_UP(vring_size(rsc->rpmsg_vring0.num, align0), align0); + v1sz = ALIGN_UP(vring_size(rsc->rpmsg_vring1.num, align1), align1); + + shbuf0 = (FAR char *)rsc + tbsz + v0sz + v1sz; + shbufsz0 = rsc->config.r2h_buf_size * rsc->rpmsg_vring0.num; + shbuf1 = shbuf0 + shbufsz0; + shbufsz1 = rsc->config.h2r_buf_size * rsc->rpmsg_vring1.num; + + rvrings[0].io = metal_io_get_region(); + rvrings[0].info.vaddr = (FAR char *)rsc + tbsz; + rvrings[0].info.num_descs = rsc->rpmsg_vring0.num; + rvrings[0].info.align = rsc->rpmsg_vring0.align; + rvrings[0].vq = virtqueue_allocate(rsc->rpmsg_vring0.num); + if (rvrings[0].vq == NULL) + { + return -ENOMEM; + } + + rvrings[1].io = metal_io_get_region(); + rvrings[1].info.vaddr = (FAR char *)rsc + tbsz + v0sz; + rvrings[1].info.num_descs = rsc->rpmsg_vring1.num; + rvrings[1].info.align = rsc->rpmsg_vring1.align; + rvrings[1].vq = virtqueue_allocate(rsc->rpmsg_vring1.num); + if (rvrings[1].vq == NULL) + { + ret = -ENOMEM; + goto err_vq0; + } + + vdev->vrings_info = &rvrings[0]; + + rpmsg_virtio_init_shm_pool(&priv->pool[0], shbuf0, shbufsz0); + rpmsg_virtio_init_shm_pool(&priv->pool[1], shbuf1, shbufsz1); + + config.h2r_buf_size = rsc->config.h2r_buf_size; + config.r2h_buf_size = rsc->config.r2h_buf_size; + config.split_shpool = true; + + ret = rpmsg_init_vdev_with_config(&priv->rvdev, vdev, rpmsg_ns_bind, + metal_io_get_region(), + priv->pool, &config); + if (ret != 0) + { + rpmsgerr("rpmsg_init_vdev failed %d\n", ret); + ret = -ENOMEM; + goto err_vq1; + } + + priv->rvdev.rdev.ns_unbind_cb = rpmsg_ns_unbind; + priv->rvdev.notify_wait_cb = rpmsg_virtio_lite_notify_wait; + + RPMSG_VIRTIO_LITE_REGISTER_CALLBACK(priv->dev, rpmsg_virtio_lite_callback, + priv); + + rpmsg_virtio_lite_update_rx(priv); + rpmsg_virtio_lite_wakeup_rx(priv); + + /* Broadcast device_created to all registers */ + + rpmsg_device_created(&priv->rpmsg); + + return 0; + +err_vq1: + virtqueue_free(rvrings[1].vq); +err_vq0: + virtqueue_free(rvrings[0].vq); + return ret; +} + +static int rpmsg_virtio_lite_thread(int argc, FAR char *argv[]) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv = + (FAR struct rpmsg_virtio_lite_priv_s *) + ((uintptr_t)strtoul(argv[2], NULL, 16)); + int ret; + + priv->tid = nxsched_gettid(); + + ret = rpmsg_virtio_lite_start(priv); + if (ret < 0) + { + rpmsgerr("rpmsg virtio thread start failed %d\n", ret); + return ret; + } + + while (1) + { + nxsem_wait_uninterruptible(&priv->semrx); + if (rpmsg_virtio_lite_available_rx(priv)) + { + virtqueue_notification(priv->rvdev.rvq); + } + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int rpmsg_virtio_lite_initialize(FAR struct rpmsg_virtio_lite_s *dev) +{ + FAR struct rpmsg_virtio_lite_priv_s *priv; + FAR char *argv[3]; + char arg1[32]; + char name[32]; + int ret; + + priv = kmm_zalloc(sizeof(struct rpmsg_virtio_lite_priv_s)); + if (priv == NULL) + { + return -ENOMEM; + } + + priv->dev = dev; + nxsem_init(&priv->semrx, 0, 0); + nxsem_init(&priv->semtx, 0, 0); + + snprintf(name, sizeof(name), "/dev/rpmsg/%s", + RPMSG_VIRTIO_LITE_GET_CPUNAME(dev)); + ret = rpmsg_register(name, &priv->rpmsg, &g_rpmsg_virtio_lite_ops); + if (ret < 0) + { + goto err_driver; + } + + snprintf(arg1, sizeof(arg1), "%p", priv); + argv[0] = (FAR char *)RPMSG_VIRTIO_LITE_GET_CPUNAME(dev); + argv[1] = arg1; + argv[2] = NULL; + + ret = kthread_create("rpmsg_virtio", CONFIG_RPMSG_VIRTIO_LITE_PRIORITY, + CONFIG_RPMSG_VIRTIO_LITE_STACKSIZE, + rpmsg_virtio_lite_thread, argv); + if (ret < 0) + { + goto err_thread; + } + + return OK; + +err_thread: + rpmsg_unregister(name, &priv->rpmsg); + +err_driver: + nxsem_destroy(&priv->semrx); + nxsem_destroy(&priv->semtx); + kmm_free(priv); + + return ret; +} diff --git a/include/nuttx/rpmsg/rpmsg_virtio.h b/include/nuttx/rpmsg/rpmsg_virtio_lite.h similarity index 71% rename from include/nuttx/rpmsg/rpmsg_virtio.h rename to include/nuttx/rpmsg/rpmsg_virtio_lite.h index 52e0e131537..c4ff4b1d658 100644 --- a/include/nuttx/rpmsg/rpmsg_virtio.h +++ b/include/nuttx/rpmsg/rpmsg_virtio_lite.h @@ -1,5 +1,5 @@ /**************************************************************************** - * include/nuttx/rpmsg/rpmsg_virtio.h + * include/nuttx/rpmsg/rpmsg_virtio_lite.h * * SPDX-License-Identifier: Apache-2.0 * @@ -20,8 +20,8 @@ * ****************************************************************************/ -#ifndef __INCLUDE_NUTTX_RPMSG_RPMSG_VIRTIO_H -#define __INCLUDE_NUTTX_RPMSG_RPMSG_VIRTIO_H +#ifndef __INCLUDE_NUTTX_RPMSG_RPMSG_VIRTIO_LITE_H +#define __INCLUDE_NUTTX_RPMSG_RPMSG_VIRTIO_LITE_H /**************************************************************************** * Included Files @@ -29,7 +29,7 @@ #include -#ifdef CONFIG_RPMSG_VIRTIO +#ifdef CONFIG_RPMSG_VIRTIO_LITE #include #include @@ -39,24 +39,24 @@ * Pre-processor Definitions ****************************************************************************/ -#define RPMSG_VIRTIO_NOTIFY_ALL UINT32_MAX +#define RPMSG_VIRTIO_LITE_NOTIFY_ALL UINT32_MAX -#define RPMSG_VIRTIO_CMD_PANIC 0x1 -#define RPMSG_VIRTIO_CMD_MASK 0xffff -#define RPMSG_VIRTIO_CMD_SHIFT 16 +#define RPMSG_VIRTIO_LITE_CMD_PANIC 0x1 +#define RPMSG_VIRTIO_LITE_CMD_MASK 0xffff +#define RPMSG_VIRTIO_LITE_CMD_SHIFT 16 -#define RPMSG_VIRTIO_CMD(c,v) (((c) << RPMSG_VIRTIO_CMD_SHIFT) | \ - ((v) & RPMSG_VIRTIO_CMD_MASK)) -#define RPMSG_VIRTIO_GET_CMD(c) ((c) >> RPMSG_VIRTIO_CMD_SHIFT) +#define RPMSG_VIRTIO_LITE_CMD(c,v) (((c) << RPMSG_VIRTIO_LITE_CMD_SHIFT) | \ + ((v) & RPMSG_VIRTIO_LITE_CMD_MASK)) +#define RPMSG_VIRTIO_LITE_GET_CMD(c) ((c) >> RPMSG_VIRTIO_LITE_CMD_SHIFT) -#define RPMSG_VIRTIO_RSC2CMD(r) \ - ((FAR struct rpmsg_virtio_cmd_s *) \ - &((FAR struct resource_table *)(r))->reserved[0]) +#define RPMSG_VIRTIO_LITE_RSC2CMD(r) \ + ((FAR struct rpmsg_virtio_lite_cmd_s *) \ + &((FAR struct resource_table *)(r))->reserved[0]) /* Access macros ************************************************************/ /**************************************************************************** - * Name: RPMSG_VIRTIO_GET_LOCAL_CPUNAME + * Name: RPMSG_VIRTIO_LITE_GET_LOCAL_CPUNAME * * Description: * Get remote cpu name @@ -69,11 +69,11 @@ * ****************************************************************************/ -#define RPMSG_VIRTIO_GET_LOCAL_CPUNAME(d) \ +#define RPMSG_VIRTIO_LITE_GET_LOCAL_CPUNAME(d) \ ((d)->ops->get_local_cpuname ? (d)->ops->get_local_cpuname(d) : "") /**************************************************************************** - * Name: RPMSG_VIRTIO_GET_CPUNAME + * Name: RPMSG_VIRTIO_LITE_GET_CPUNAME * * Description: * Get remote cpu name @@ -86,11 +86,11 @@ * ****************************************************************************/ -#define RPMSG_VIRTIO_GET_CPUNAME(d) \ +#define RPMSG_VIRTIO_LITE_GET_CPUNAME(d) \ ((d)->ops->get_cpuname ? (d)->ops->get_cpuname(d) : "") /**************************************************************************** - * Name: RPMSG_VIRTIO_GET_RESOURCE + * Name: RPMSG_VIRTIO_LITE_GET_RESOURCE * * Description: * Get rpmsg virtio resource @@ -103,11 +103,11 @@ * ****************************************************************************/ -#define RPMSG_VIRTIO_GET_RESOURCE(d) \ +#define RPMSG_VIRTIO_LITE_GET_RESOURCE(d) \ ((d)->ops->get_resource ? (d)->ops->get_resource(d) : NULL) /**************************************************************************** - * Name: RPMSG_VIRTIO_IS_MASTER + * Name: RPMSG_VIRTIO_LITE_IS_MASTER * * Description: * Is master or not @@ -120,11 +120,11 @@ * ****************************************************************************/ -#define RPMSG_VIRTIO_IS_MASTER(d) \ +#define RPMSG_VIRTIO_LITE_IS_MASTER(d) \ ((d)->ops->is_master ? (d)->ops->is_master(d) : false) /**************************************************************************** - * Name: RPMSG_VIRTIO_REGISTER_CALLBACK + * Name: RPMSG_VIRTIO_LITE_REGISTER_CALLBACK * * Description: * Attach to receive a callback when something is received on RPTUN @@ -139,11 +139,11 @@ * ****************************************************************************/ -#define RPMSG_VIRTIO_REGISTER_CALLBACK(d,c,a) \ +#define RPMSG_VIRTIO_LITE_REGISTER_CALLBACK(d,c,a) \ ((d)->ops->register_callback ? (d)->ops->register_callback(d,c,a) : -ENOSYS) /**************************************************************************** - * Name: RPMSG_VIRTIO_NOTIFY + * Name: RPMSG_VIRTIO_LITE_NOTIFY * * Description: * Notify remote core there is a message to get. @@ -157,7 +157,7 @@ * ****************************************************************************/ -#define RPMSG_VIRTIO_NOTIFY(d,v) \ +#define RPMSG_VIRTIO_LITE_NOTIFY(d,v) \ ((d)->ops->notify ? (d)->ops->notify(d,v) : -ENOSYS) /**************************************************************************** @@ -166,13 +166,13 @@ typedef CODE int (*rpmsg_virtio_callback_t)(FAR void *arg, uint32_t vqid); -begin_packed_struct struct rpmsg_virtio_cmd_s +begin_packed_struct struct rpmsg_virtio_lite_cmd_s { uint32_t cmd_master; uint32_t cmd_slave; } end_packed_struct; -struct aligned_data(8) rpmsg_virtio_rsc_s +struct aligned_data(8) rpmsg_virtio_lite_rsc_s { struct resource_table rsc_tbl_hdr; uint32_t offset[2]; @@ -183,23 +183,24 @@ struct aligned_data(8) rpmsg_virtio_rsc_s struct fw_rsc_config config; }; -struct rpmsg_virtio_s; -struct rpmsg_virtio_ops_s +struct rpmsg_virtio_lite_s; +struct rpmsg_virtio_lite_ops_s { - CODE FAR const char *(*get_local_cpuname)(FAR struct rpmsg_virtio_s *dev); - CODE FAR const char *(*get_cpuname)(FAR struct rpmsg_virtio_s *dev); - CODE FAR struct rpmsg_virtio_rsc_s * - (*get_resource)(FAR struct rpmsg_virtio_s *dev); - CODE int (*is_master)(FAR struct rpmsg_virtio_s *dev); - CODE int (*notify)(FAR struct rpmsg_virtio_s *dev, uint32_t vqid); - CODE int (*register_callback)(FAR struct rpmsg_virtio_s *dev, + CODE FAR const char * + (*get_local_cpuname)(FAR struct rpmsg_virtio_lite_s *dev); + CODE FAR const char *(*get_cpuname)(FAR struct rpmsg_virtio_lite_s *dev); + CODE FAR struct rpmsg_virtio_lite_rsc_s * + (*get_resource)(FAR struct rpmsg_virtio_lite_s *dev); + CODE int (*is_master)(FAR struct rpmsg_virtio_lite_s *dev); + CODE int (*notify)(FAR struct rpmsg_virtio_lite_s *dev, uint32_t vqid); + CODE int (*register_callback)(FAR struct rpmsg_virtio_lite_s *dev, rpmsg_virtio_callback_t callback, FAR void *arg); }; -struct rpmsg_virtio_s +struct rpmsg_virtio_lite_s { - FAR const struct rpmsg_virtio_ops_s *ops; + FAR const struct rpmsg_virtio_lite_ops_s *ops; }; /**************************************************************************** @@ -214,12 +215,12 @@ extern "C" #define EXTERN extern #endif -int rpmsg_virtio_initialize(FAR struct rpmsg_virtio_s *dev); +int rpmsg_virtio_lite_initialize(FAR struct rpmsg_virtio_lite_s *dev); #ifdef __cplusplus } #endif -#endif /* CONFIG_RPTUN */ +#endif /* CONFIG_RPMSG_VIRTIO_LITE */ -#endif /* __INCLUDE_NUTTX_RPMSG_RPMSG_VIRTIO_H */ +#endif /* __INCLUDE_NUTTX_RPMSG_RPMSG_VIRTIO_LITE_H */