From a27e0142c18b40b18d6a3ba641750225c0ed77db Mon Sep 17 00:00:00 2001 From: yanghuatao Date: Thu, 10 Aug 2023 16:06:57 +0800 Subject: [PATCH 01/22] nuttx/dirvers: Add secure rptun file rptun secure is a rptun driver used for the rpmsg communication between (Non-Secure) REE and (Secure) TEE environments. Signed-off-by: yanghuatao Signed-off-by: Bowen Wang --- drivers/rptun/Kconfig | 9 ++ drivers/rptun/Make.defs | 4 + drivers/rptun/rptun_secure.c | 221 +++++++++++++++++++++++++++++ include/nuttx/rptun/rptun_secure.h | 70 +++++++++ 4 files changed, 304 insertions(+) create mode 100644 drivers/rptun/rptun_secure.c create mode 100644 include/nuttx/rptun/rptun_secure.h diff --git a/drivers/rptun/Kconfig b/drivers/rptun/Kconfig index d9f52cd365c87..bc97fa539ed0d 100644 --- a/drivers/rptun/Kconfig +++ b/drivers/rptun/Kconfig @@ -12,6 +12,15 @@ menuconfig RPTUN if RPTUN +config RPTUN_SECURE + bool "rptun secure support" + default n + ---help--- + This is a rptun driver for communications between secure (TEE) + and non-secure (REE) environments. With this driver, REE and + TEE and communicate with each other by using the native rpmsg + or various Rpmsg services have been implemented in NuttX. + config RPTUN_IVSHMEM bool "rptun ivshmem support" default n diff --git a/drivers/rptun/Make.defs b/drivers/rptun/Make.defs index e4afb1657b8b7..05969d1f0ff24 100644 --- a/drivers/rptun/Make.defs +++ b/drivers/rptun/Make.defs @@ -28,6 +28,10 @@ ifeq ($(CONFIG_RPTUN_IVSHMEM),y) CSRCS += rptun_ivshmem.c endif +ifeq ($(CONFIG_RPTUN_SECURE),y) +CSRCS += rptun_secure.c +endif + DEPPATH += --dep-path rptun VPATH += :rptun CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)drivers$(DELIM)rptun diff --git a/drivers/rptun/rptun_secure.c b/drivers/rptun/rptun_secure.c new file mode 100644 index 0000000000000..539416c503b6b --- /dev/null +++ b/drivers/rptun/rptun_secure.c @@ -0,0 +1,221 @@ +/**************************************************************************** + * drivers/rptun/rptun_secure.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 +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rptun_secure_dev_s +{ + struct rptun_dev_s rptun; + rptun_callback_t callback; + FAR void *arg; + bool master; + FAR struct rptun_rsc_s *rsc; + char cpuname[RPMSG_NAME_SIZE + 1]; + int irq_event; + int irq_trigger; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static FAR const char *rptun_secure_get_cpuname(FAR struct rptun_dev_s *dev); +static struct +FAR rptun_rsc_s *rptun_secure_get_resource(FAR struct rptun_dev_s *dev); +static bool rptun_secure_is_autostart(FAR struct rptun_dev_s *dev); +static bool rptun_secure_is_master(FAR struct rptun_dev_s *dev); +static int rptun_secure_start(FAR struct rptun_dev_s *dev); +static int rptun_secure_stop(FAR struct rptun_dev_s *dev); +static int rptun_secure_notify(FAR struct rptun_dev_s *dev, + uint32_t notifyid); +static int rptun_secure_register_callback(FAR struct rptun_dev_s *dev, + rptun_callback_t callback, + FAR void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct rptun_ops_s g_rptun_secure_ops = +{ + .get_cpuname = rptun_secure_get_cpuname, + .get_resource = rptun_secure_get_resource, + .is_autostart = rptun_secure_is_autostart, + .is_master = rptun_secure_is_master, + .start = rptun_secure_start, + .stop = rptun_secure_stop, + .notify = rptun_secure_notify, + .register_callback = rptun_secure_register_callback, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static FAR const char *rptun_secure_get_cpuname(FAR struct rptun_dev_s *dev) +{ + FAR struct rptun_secure_dev_s *priv = (FAR struct rptun_secure_dev_s *)dev; + return priv->cpuname; +} + +static FAR struct rptun_rsc_s * +rptun_secure_get_resource(FAR struct rptun_dev_s *dev) +{ + FAR struct rptun_secure_dev_s *priv = (FAR struct rptun_secure_dev_s *)dev; + return priv->rsc; +} + +static bool rptun_secure_is_autostart(FAR struct rptun_dev_s *dev) +{ + return true; +} + +static bool rptun_secure_is_master(FAR struct rptun_dev_s *dev) +{ + FAR struct rptun_secure_dev_s *priv = (FAR struct rptun_secure_dev_s *)dev; + return priv->master; +} + +static int rptun_secure_start(FAR struct rptun_dev_s *dev) +{ + return 0; +} + +static int rptun_secure_stop(FAR struct rptun_dev_s *dev) +{ + return 0; +} + +static int rptun_secure_notify(FAR struct rptun_dev_s *dev, uint32_t vqid) +{ + FAR struct rptun_secure_dev_s *priv = (FAR struct rptun_secure_dev_s *)dev; + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); + up_trigger_irq(priv->irq_trigger, cpuset); + return 0; +} + +static int rptun_secure_register_callback(FAR struct rptun_dev_s *dev, + rptun_callback_t callback, + FAR void *arg) +{ + FAR struct rptun_secure_dev_s *priv = (FAR struct rptun_secure_dev_s *)dev; + + priv->callback = callback; + priv->arg = arg; + + if (callback) + { + up_enable_irq(priv->irq_event); + } + else + { + up_disable_irq(priv->irq_event); + } + + return 0; +} + +/**************************************************************************** + * Name: rprun_secure_interrupt + * + * Description: + * This is the interrupt handler. + * + * Input Parameters: + * irq - unused + * context - context, unused + * arg - private data pointer + * + * Returned Value: + * OK always + * + ****************************************************************************/ + +static int rprun_secure_interrupt(int irq, FAR void *context, FAR void *arg) +{ + FAR struct rptun_secure_dev_s *priv = arg; + + if (priv != NULL && priv->callback != NULL) + { + priv->callback(priv->arg, RPTUN_NOTIFY_ALL); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int rptun_secure_init(FAR const char *cpuname, bool master, + FAR struct rptun_rsc_s *rsc, int irq_event, + int irq_trigger) +{ + FAR struct rptun_secure_dev_s *dev; + int ret; + + dev = kmm_zalloc(sizeof(*dev)); + if (dev == NULL) + { + return -ENOMEM; + } + + dev->master = master; + dev->irq_trigger = irq_trigger; + dev->irq_event = irq_event; + dev->rptun.ops = &g_rptun_secure_ops; + dev->rsc = rsc; + strlcpy(dev->cpuname, cpuname, sizeof(dev->cpuname)); + + ret = irq_attach(dev->irq_event, + rprun_secure_interrupt, dev); + if (ret < 0) + { + kmm_free(dev); + return ret; + } + + ret = rptun_initialize(&dev->rptun); + if (ret < 0) + { + irq_detach(dev->irq_event); + kmm_free(dev); + return ret; + } + + return ret; +} diff --git a/include/nuttx/rptun/rptun_secure.h b/include/nuttx/rptun/rptun_secure.h new file mode 100644 index 0000000000000..e62e42482d48e --- /dev/null +++ b/include/nuttx/rptun/rptun_secure.h @@ -0,0 +1,70 @@ +/**************************************************************************** + * include/nuttx/rptun/rptun_secure.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_RPTUN_RPTUN_SECURE_H +#define __INCLUDE_NUTTX_RPTUN_RPTUN_SECURE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: rptun_secure_init + * + * Description: + * Initializes the rptun device. + * + * Input Parameters: + * cpuname - Local CPU name + * master - If is master + * rsc - The resource for shared memory + * irq_event - Interrupt ID to attach + * irq_trigger - Interrupt ID to trigger + * + * Returned Value: + * OK on success, negated errno on failure + * + ****************************************************************************/ + +int rptun_secure_init(FAR const char *cpuname, bool master, + FAR struct rptun_rsc_s *rsc, int irq_event, + int irq_trigger); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_RPTUN_RPTUN_SECURE_H */ From 317d48cb7d6b2162fd07f01c7a7d96c9a018d47f Mon Sep 17 00:00:00 2001 From: ligd Date: Sat, 30 Apr 2022 12:46:27 +0800 Subject: [PATCH 02/22] rptun: use local rx virtqueue idx to resolve remote low power Store the rx virtqueue idx to the local headrx index, and only process the data when the rx virtqueue has data to avoid access the ram in low power mode. Signed-off-by: ligd --- drivers/rptun/rptun.c | 46 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index f80af913965f1..5f8351602385e 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -70,6 +70,7 @@ struct rptun_priv_s pid_t tid; #ifdef CONFIG_RPTUN_PM bool stay; + uint16_t headrx; #endif }; @@ -222,8 +223,40 @@ static inline void rptun_pm_action(FAR struct rptun_priv_s *priv, leave_critical_section(flags); } +static inline void rptun_update_rx(FAR struct rptun_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) + { + priv->headrx = rvq->vq_ring.used->idx; + } + else + { + priv->headrx = rvq->vq_ring.avail->idx; + } +} + +static inline bool rptun_available_rx(FAR struct rptun_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 rptun_pm_action(priv, stay) +# define rptun_update_rx(priv) +# define rptun_available_rx(priv) true #endif static void rptun_start_worker(FAR void *arg) @@ -240,7 +273,10 @@ static void rptun_worker(FAR void *arg) { FAR struct rptun_priv_s *priv = arg; - remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL); + if (rptun_available_rx(priv)) + { + remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL); + } } static int rptun_thread(int argc, FAR char *argv[]) @@ -291,10 +327,8 @@ static int rptun_callback(FAR void *arg, uint32_t vqid) if (vqid == RPTUN_NOTIFY_ALL || vqid == vdev->vrings_info[rvq->vq_queue_index].notifyid) { - if (rptun_buffer_nused(&priv->rvdev, true)) - { - rptun_wakeup_rx(priv); - } + rptun_update_rx(priv); + rptun_wakeup_rx(priv); } if (vqid == RPTUN_NOTIFY_ALL || @@ -811,6 +845,8 @@ static int rptun_dev_start(FAR struct remoteproc *rproc) /* Register callback to mbox for receiving remote message */ RPTUN_REGISTER_CALLBACK(priv->dev, rptun_callback, priv); + + rptun_update_rx(priv); rptun_wakeup_rx(priv); /* Broadcast device_created to all registers */ From dd9eac5dcd0790bef75175353af36a5f91471e32 Mon Sep 17 00:00:00 2001 From: ligd Date: Thu, 5 Jan 2023 12:08:04 +0800 Subject: [PATCH 03/22] rptun/pm: add check to rptun_pm_callback() incase of start early Signed-off-by: ligd --- drivers/rptun/rptun.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 5f8351602385e..b20357052524c 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -228,6 +228,11 @@ static inline void rptun_update_rx(FAR struct rptun_priv_s *priv) FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; FAR struct virtqueue *rvq = rvdev->rvq; + if (priv->rproc.state != RPROC_RUNNING) + { + return; + } + if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) { priv->headrx = rvq->vq_ring.used->idx; @@ -243,6 +248,11 @@ static inline bool rptun_available_rx(FAR struct rptun_priv_s *priv) FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; FAR struct virtqueue *rvq = rvdev->rvq; + if (priv->rproc.state != RPROC_RUNNING) + { + return false; + } + if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) { return priv->headrx != rvq->vq_used_cons_idx; From 58e5230b084b6f142a2f3f8c50bae21394bfda12 Mon Sep 17 00:00:00 2001 From: ligd Date: Thu, 16 Jun 2022 20:38:51 +0800 Subject: [PATCH 04/22] rptun/pm: use pm_wakelock Signed-off-by: ligd --- drivers/rptun/rptun.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index b20357052524c..23b0d8e1e13bd 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -69,7 +69,7 @@ struct rptun_priv_s sem_t semrx; pid_t tid; #ifdef CONFIG_RPTUN_PM - bool stay; + struct pm_wakelock_s wakelock; uint16_t headrx; #endif }; @@ -205,19 +205,20 @@ static inline void rptun_pm_action(FAR struct rptun_priv_s *priv, bool stay) { irqstate_t flags; + int count; flags = enter_critical_section(); - if (stay && !priv->stay) + count = pm_wakelock_staycount(&priv->wakelock); + + if (stay && count == 0) { - pm_stay(PM_IDLE_DOMAIN, PM_IDLE); - priv->stay = true; + pm_wakelock_stay(&priv->wakelock); } - if (!stay && priv->stay && !rptun_buffer_nused(&priv->rvdev, false)) + if (!stay && count > 0 && !rptun_buffer_nused(&priv->rvdev, false)) { - pm_relax(PM_IDLE_DOMAIN, PM_IDLE); - priv->stay = false; + pm_wakelock_relax(&priv->wakelock); } leave_critical_section(flags); @@ -1063,7 +1064,9 @@ int rptun_initialize(FAR struct rptun_dev_s *dev) goto err_thread; } - /* Add priv to list */ +#ifdef CONFIG_RPTUN_PM + pm_wakelock_init(&priv->wakelock, "rptun", PM_IDLE_DOMAIN, PM_IDLE); +#endif return OK; From e21a27dc343b4a44cc7eaa8db6e0bfac12f72ffe Mon Sep 17 00:00:00 2001 From: ligd Date: Fri, 7 Apr 2023 23:38:33 +0800 Subject: [PATCH 05/22] rptun: add RPTUN_PM_AUTORELAX method. Signed-off-by: ligd --- drivers/rptun/Kconfig | 7 +++++++ drivers/rptun/rptun.c | 42 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/drivers/rptun/Kconfig b/drivers/rptun/Kconfig index bc97fa539ed0d..9dfc93ac2e9bf 100644 --- a/drivers/rptun/Kconfig +++ b/drivers/rptun/Kconfig @@ -78,4 +78,11 @@ config RPTUN_PM goto RAM-retention mode, can't access from another CPU. So, we provide this method to resolve this. +config RPTUN_PM_AUTORELAX + bool "rptun pm autorelax" + depends on RPTUN_PM + default y + ---help--- + use wd_timer to auto relax pm + endif # RPTUN diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 23b0d8e1e13bd..bcdb7a5c7b6ae 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -71,6 +71,7 @@ struct rptun_priv_s #ifdef CONFIG_RPTUN_PM struct pm_wakelock_s wakelock; uint16_t headrx; + struct wdog_s wdog; #endif }; @@ -201,6 +202,31 @@ static void rptun_wakeup_tx(FAR struct rptun_priv_s *priv) } #ifdef CONFIG_RPTUN_PM + +#ifdef CONFIG_RPTUN_PM_AUTORELAX +static void rptun_pm_callback(wdparm_t arg) +{ + FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)arg; + + if (priv->rproc.state != RPROC_RUNNING) + { + return; + } + + if (rptun_buffer_nused(&priv->rvdev, false)) + { + rptun_wakeup_tx(priv); + + wd_start(&priv->wdog, MSEC2TICK(RPTUN_TIMEOUT_MS), + rptun_pm_callback, (wdparm_t)priv); + } + else + { + pm_wakelock_relax(&priv->wakelock); + } +} +#endif + static inline void rptun_pm_action(FAR struct rptun_priv_s *priv, bool stay) { @@ -210,16 +236,21 @@ static inline void rptun_pm_action(FAR struct rptun_priv_s *priv, flags = enter_critical_section(); count = pm_wakelock_staycount(&priv->wakelock); - if (stay && count == 0) { pm_wakelock_stay(&priv->wakelock); +#ifdef CONFIG_RPTUN_PM_AUTORELAX + wd_start(&priv->wdog, MSEC2TICK(RPTUN_TIMEOUT_MS), + rptun_pm_callback, (wdparm_t)priv); +#endif } - if (!stay && count > 0 && !rptun_buffer_nused(&priv->rvdev, false)) +#ifndef CONFIG_RPTUN_PM_AUTORELAX + if (!stay && count > 0 && rptun_buffer_nused(&priv->rvdev, false) == 0) { pm_wakelock_relax(&priv->wakelock); } +#endif leave_critical_section(flags); } @@ -407,10 +438,11 @@ static int rptun_notify(FAR struct remoteproc *rproc, uint32_t id) { FAR struct rptun_priv_s *priv = rproc->priv; FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; - FAR struct virtqueue *vq = rvdev->svq; + FAR struct virtio_device *vdev = rvdev->vdev; + FAR struct virtqueue *svq = rvdev->svq; - if (rvdev->vdev && vq && - rvdev->vdev->vrings_info[vq->vq_queue_index].notifyid == id) + if (priv->rproc.state == RPROC_RUNNING && + id == vdev->vrings_info[svq->vq_queue_index].notifyid) { rptun_pm_action(priv, true); } From 31a98d9ddfe11384ad85541101006e35b4796230 Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Thu, 28 Mar 2024 15:16:40 +0800 Subject: [PATCH 06/22] drivers/rptun: flush the image memory when read from the file system Flush the image memory to make sure the remote core access the correct image. Signed-off-by: Bowen Wang --- drivers/rptun/rptun.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index bcdb7a5c7b6ae..93a018cb871da 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -981,6 +981,7 @@ static int rptun_store_load(FAR void *store_, size_t offset, { FAR struct rptun_store_s *store = store_; FAR char *tmp; + ssize_t ret; if (pa == METAL_BAD_PHYS) { @@ -1003,7 +1004,13 @@ static int rptun_store_load(FAR void *store_, size_t offset, } file_seek(&store->file, offset, SEEK_SET); - return file_read(&store->file, tmp, size); + ret = file_read(&store->file, tmp, size); + if (ret > 0) + { + metal_cache_flush(tmp, ret); + } + + return ret; } #endif From 0ca81db2ed0a7a928895abb135cf523445c105c7 Mon Sep 17 00:00:00 2001 From: ligd Date: Mon, 20 Jun 2022 21:47:20 +0800 Subject: [PATCH 07/22] rptun: use detail name for pm wakelock So we can distinguish the pm wakelock Signed-off-by: ligd --- drivers/rptun/rptun.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 93a018cb871da..1021e06d1081f 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -1104,7 +1104,8 @@ int rptun_initialize(FAR struct rptun_dev_s *dev) } #ifdef CONFIG_RPTUN_PM - pm_wakelock_init(&priv->wakelock, "rptun", PM_IDLE_DOMAIN, PM_IDLE); + snprintf(name, sizeof(name), "rptun-%s", RPTUN_GET_CPUNAME(dev)); + pm_wakelock_init(&priv->wakelock, name, PM_IDLE_DOMAIN, PM_IDLE); #endif return OK; From b95014202abd168b8d92501b3e3256f5af6e843c Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Wed, 18 Sep 2024 17:20:56 +0800 Subject: [PATCH 08/22] rptun: BUG fix, should not destory the semaphore twice This BUG is introduced in PR: https://github.com/apache/nuttx/pull/13172 Signed-off-by: Bowen Wang --- drivers/rptun/rptun.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 1021e06d1081f..18cc2042ca2bd 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -1111,8 +1111,6 @@ int rptun_initialize(FAR struct rptun_dev_s *dev) return OK; err_thread: - nxsem_destroy(&priv->semtx); - nxsem_destroy(&priv->semrx); rpmsg_unregister(name, &priv->rpmsg); err_driver: From 36b1570e28383aa432c18e135b4f5680650bd2f9 Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Wed, 18 Sep 2024 17:26:16 +0800 Subject: [PATCH 09/22] rptun/rptun_dump: remove unused rptun_dump.c rptun_dump related code has been moved to rptun.c from rptun_dump.c, but file rptun_dump.c is not deleted in PR: https://github.com/apache/nuttx/pull/11712 So delete this file. Signed-off-by: Bowen Wang --- drivers/rptun/rptun_dump.c | 142 ------------------------------------- 1 file changed, 142 deletions(-) delete mode 100644 drivers/rptun/rptun_dump.c diff --git a/drivers/rptun/rptun_dump.c b/drivers/rptun/rptun_dump.c deleted file mode 100644 index b51152f32a597..0000000000000 --- a/drivers/rptun/rptun_dump.c +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** - * drivers/rptun/rptun_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 -#include -#include - -#include - -#include "rptun.h" - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static void rptun_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_EMERGENCY, - " %s buffer %p hold by %s\n", - rx ? "RX" : "TX", hdr, ept->name); - } -} - -static void rptun_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 = rptun_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++) - { - 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) - { - rptun_dump_addr(&rvdev->rdev, addr, rx); - } - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -void rptun_dump(FAR struct rpmsg_virtio_device *rvdev) -{ - FAR struct rpmsg_device *rdev = &rvdev->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"); - - rptun_dump_buffer(rvdev, true); - rptun_dump_buffer(rvdev, false); - - if (needlock) - { - metal_mutex_release(&rdev->lock); - } -} From e7f4a2ea70d63a667557bd5aa46243ba23aca337 Mon Sep 17 00:00:00 2001 From: ligd Date: Wed, 27 Apr 2022 16:58:02 +0800 Subject: [PATCH 10/22] rptun: add timeout to wait_tx_buffer callback Signed-off-by: ligd --- drivers/rptun/rptun.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 18cc2042ca2bd..286b32241683c 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -54,6 +54,8 @@ #define RPTUNIOC_NONE 0 +#define RPTUN_TIMEOUT_MS 20 + /**************************************************************************** * Private Types ****************************************************************************/ @@ -501,7 +503,7 @@ static int rptun_notify_wait(FAR struct remoteproc *rproc, uint32_t id) /* Wait to wakeup */ - nxsem_wait(&priv->semtx); + nxsem_tickwait(&priv->semtx, MSEC2TICK(RPTUN_TIMEOUT_MS)); rptun_worker(priv); return 0; From 92cd7cf1c019156b5b1f55d6394f8a2fec640aa0 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sun, 18 Feb 2024 20:38:46 +0800 Subject: [PATCH 11/22] rptun: Rename rptun_panic_ to rptun_panic The function name rptun_panic_ is not consistent with other functions Signed-off-by: Xiang Xiao --- drivers/rptun/rptun.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 286b32241683c..d722063c005c5 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -127,7 +127,7 @@ static int rptun_wait(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); static int rptun_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); static int rptun_ioctl(FAR struct rpmsg_s *rpmsg, int cmd, unsigned long arg); -static void rptun_panic_(FAR struct rpmsg_s *rpmsg); +static void rptun_panic(FAR struct rpmsg_s *rpmsg); static void rptun_dump(FAR struct rpmsg_s *rpmsg); static FAR const char *rptun_get_local_cpuname(FAR struct rpmsg_s *rpmsg); static FAR const char *rptun_get_cpuname(FAR struct rpmsg_s *rpmsg); @@ -165,7 +165,7 @@ static const struct rpmsg_ops_s g_rptun_rpmsg_ops = rptun_wait, rptun_post, rptun_ioctl, - rptun_panic_, + rptun_panic, rptun_dump, rptun_get_local_cpuname, rptun_get_cpuname, @@ -632,7 +632,7 @@ static int rptun_ioctl(FAR struct rpmsg_s *rpmsg, int cmd, unsigned long arg) return ret; } -static void rptun_panic_(FAR struct rpmsg_s *rpmsg) +static void rptun_panic(FAR struct rpmsg_s *rpmsg) { FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; From 8a5424c9c555168bf766c0b9c73f98698517158a Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Fri, 23 Feb 2024 19:57:25 +0800 Subject: [PATCH 12/22] rptun: rptun pm and rptun dump support cacheable memory Should invalidate the memory when the data is located in shared memory and write by remote core. Signed-off-by: Bowen Wang --- drivers/rptun/rptun.c | 21 +++++++++++++++++++-- include/nuttx/rptun/rptun.h | 6 ++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index d722063c005c5..78e3d339f2290 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -180,9 +180,20 @@ static const struct rpmsg_ops_s g_rptun_rpmsg_ops = static int rptun_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; + uint16_t nused; + bool is_host = rpmsg_virtio_get_role(rvdev) == RPMSG_HOST; - if ((rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) ^ rx) + if (is_host) + { + RPTUN_INVALIDATE(vq->vq_ring.used->idx); + } + else + { + RPTUN_INVALIDATE(vq->vq_ring.avail->idx); + } + + nused = vq->vq_ring.avail->idx - vq->vq_ring.used->idx; + if (is_host ^ rx) { return nused; } @@ -269,10 +280,12 @@ static inline void rptun_update_rx(FAR struct rptun_priv_s *priv) if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) { + RPTUN_INVALIDATE(rvq->vq_ring.used->idx); priv->headrx = rvq->vq_ring.used->idx; } else { + RPTUN_INVALIDATE(rvq->vq_ring.avail->idx); priv->headrx = rvq->vq_ring.avail->idx; } } @@ -527,12 +540,16 @@ static void rptun_dump_buffer(FAR struct rpmsg_virtio_device *rvdev, { if ((rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) ^ rx) { + RPTUN_INVALIDATE(vq->vq_ring.used->idx); desc_idx = (vq->vq_ring.used->idx + i) & (vq->vq_nentries - 1); + RPTUN_INVALIDATE(vq->vq_ring.avail->ring[desc_idx]); desc_idx = vq->vq_ring.avail->ring[desc_idx]; } else { + RPTUN_INVALIDATE(vq->vq_ring.avail->idx); desc_idx = (vq->vq_ring.avail->idx + i) & (vq->vq_nentries - 1); + RPTUN_INVALIDATE(vq->vq_ring.used->ring[desc_idx].id); desc_idx = vq->vq_ring.used->ring[desc_idx].id; } diff --git a/include/nuttx/rptun/rptun.h b/include/nuttx/rptun/rptun.h index 32e62f58cf004..f6827e2dab31f 100644 --- a/include/nuttx/rptun/rptun.h +++ b/include/nuttx/rptun/rptun.h @@ -29,6 +29,7 @@ #ifdef CONFIG_RPTUN +#include #include #include #include @@ -45,6 +46,11 @@ #define RPTUNIOC_RESET _RPTUNIOC(102) #define RPTUN_NOTIFY_ALL (UINT32_MAX - 0) +#ifdef CONFIG_OPENAMP_CACHE +# define RPTUN_INVALIDATE(x) metal_cache_invalidate(&x, sizeof(x)) +#else +# define RPTUN_INVALIDATE(x) +#endif /* Access macros ************************************************************/ From 0d072ff428a78fa19648eda37a6f40e06728e1f2 Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Sat, 3 Aug 2024 18:27:44 +0800 Subject: [PATCH 13/22] drivers/rptun/rptun.c: move headrx out of CONFIG_RPTUN_PM headrx is very convient to check weather current core miss interrupt by comparing the headrx with the rx vring avail.idx for slave side or rx vring used.idx for master side. So move headrx out of the CONFIG_RPTUN_PM range. Signed-off-by: Bowen Wang --- drivers/rptun/rptun.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 78e3d339f2290..a9bd1b3ed5372 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -70,9 +70,9 @@ struct rptun_priv_s sem_t semtx; sem_t semrx; pid_t tid; + uint16_t headrx; #ifdef CONFIG_RPTUN_PM struct pm_wakelock_s wakelock; - uint16_t headrx; struct wdog_s wdog; #endif }; @@ -268,54 +268,53 @@ static inline void rptun_pm_action(FAR struct rptun_priv_s *priv, leave_critical_section(flags); } -static inline void rptun_update_rx(FAR struct rptun_priv_s *priv) +static inline bool rptun_available_rx(FAR struct rptun_priv_s *priv) { FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; FAR struct virtqueue *rvq = rvdev->rvq; if (priv->rproc.state != RPROC_RUNNING) { - return; + return false; } if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) { - RPTUN_INVALIDATE(rvq->vq_ring.used->idx); - priv->headrx = rvq->vq_ring.used->idx; + return priv->headrx != rvq->vq_used_cons_idx; } else { - RPTUN_INVALIDATE(rvq->vq_ring.avail->idx); - priv->headrx = rvq->vq_ring.avail->idx; + return priv->headrx != rvq->vq_available_idx; } } -static inline bool rptun_available_rx(FAR struct rptun_priv_s *priv) +#else +# define rptun_pm_action(priv, stay) +# define rptun_available_rx(priv) true +#endif + +static inline void rptun_update_rx(FAR struct rptun_priv_s *priv) { FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; FAR struct virtqueue *rvq = rvdev->rvq; if (priv->rproc.state != RPROC_RUNNING) { - return false; + return; } if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) { - return priv->headrx != rvq->vq_used_cons_idx; + RPTUN_INVALIDATE(rvq->vq_ring.used->idx); + priv->headrx = rvq->vq_ring.used->idx; } else { - return priv->headrx != rvq->vq_available_idx; + RPTUN_INVALIDATE(rvq->vq_ring.avail->idx); + priv->headrx = rvq->vq_ring.avail->idx; } } -#else -# define rptun_pm_action(priv, stay) -# define rptun_update_rx(priv) -# define rptun_available_rx(priv) true -#endif - static void rptun_start_worker(FAR void *arg) { FAR struct rptun_priv_s *priv = arg; @@ -665,6 +664,9 @@ static void rptun_dump(FAR struct rpmsg_s *rpmsg) FAR struct metal_list *node; bool needlock = true; + metal_log(METAL_LOG_EMERGENCY, "Remote: %s headrx %d\n", + RPTUN_GET_CPUNAME(priv->dev), priv->headrx); + if (!rvdev->vdev) { return; @@ -708,10 +710,6 @@ static void rptun_dump(FAR struct rpmsg_s *rpmsg) { metal_mutex_release(&rdev->lock); } - -#ifdef CONFIG_RPTUN_PM - metal_log(METAL_LOG_EMERGENCY, "rptun headrx %d\n", priv->headrx); -#endif } static FAR const char *rptun_get_local_cpuname(FAR struct rpmsg_s *rpmsg) From 9b23ecc214176b27d97b3933050cb58172014660 Mon Sep 17 00:00:00 2001 From: wangyongrong Date: Wed, 22 May 2024 16:41:21 +0800 Subject: [PATCH 14/22] rptun_ivshmem.c: Replace work queue with wdog wdog has better performance than work queue Signed-off-by: wangyongrong --- drivers/rptun/rptun_ivshmem.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/drivers/rptun/rptun_ivshmem.c b/drivers/rptun/rptun_ivshmem.c index ae4838d65b8c6..84e0a992eba1d 100644 --- a/drivers/rptun/rptun_ivshmem.c +++ b/drivers/rptun/rptun_ivshmem.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include /**************************************************************************** * Pre-processor Definitions @@ -43,7 +43,7 @@ #define RPTUN_IVSHMEM_SHMEM_BAR 2 #define RPTUN_IVSHMEM_READY 1 -#define RPTUN_IVSHMEM_WORK_DELAY MSEC2TICK(1) +#define RPTUN_IVSHMEM_WDOG_DELAY MSEC2TICK(1) /**************************************************************************** * Private Types @@ -76,9 +76,9 @@ struct rptun_ivshmem_dev_s char cpuname[RPMSG_NAME_SIZE + 1]; FAR struct ivshmem_device_s *ivdev; - /* Work queue for transmit */ + /* Wdog for transmit */ - struct work_s worker; + struct wdog_s wdog; }; /**************************************************************************** @@ -100,7 +100,7 @@ static int rptun_ivshmem_register_callback(FAR struct rptun_dev_s *dev, rptun_callback_t callback, FAR void *arg); -static void rptun_ivshmem_work(FAR void *arg); +static void rptun_ivshmem_wdog(wdparm_t arg); static int rptun_ivshmem_probe(FAR struct ivshmem_device_s *dev); static void rptun_ivshmem_remove(FAR struct ivshmem_device_s *dev); @@ -238,7 +238,7 @@ static int rptun_ivshmem_start(FAR struct rptun_dev_s *dev) return 0; } - return work_queue(HPWORK, &priv->worker, rptun_ivshmem_work, priv, 0); + return wd_start(&priv->wdog, 0, rptun_ivshmem_wdog, (wdparm_t)priv); } static int rptun_ivshmem_stop(FAR struct rptun_dev_s *dev) @@ -251,7 +251,7 @@ static int rptun_ivshmem_stop(FAR struct rptun_dev_s *dev) return 0; } - return work_cancel_sync(HPWORK, &priv->worker); + return wd_cancel(&priv->wdog); } static int rptun_ivshmem_notify(FAR struct rptun_dev_s *dev, uint32_t vqid) @@ -304,12 +304,13 @@ static int rptun_ivshmem_interrupt(int irq, FAR void *context, FAR void *arg) } /**************************************************************************** - * Name: rptun_ivshmem_work + * Name: rptun_ivshmem_wdog ****************************************************************************/ -static void rptun_ivshmem_work(FAR void *arg) +static void rptun_ivshmem_wdog(wdparm_t arg) { - FAR struct rptun_ivshmem_dev_s *priv = arg; + FAR struct rptun_ivshmem_dev_s *priv = + (FAR struct rptun_ivshmem_dev_s *)arg; bool should_notify = false; if (priv->master && priv->seq != priv->shmem->seqs) @@ -328,8 +329,8 @@ static void rptun_ivshmem_work(FAR void *arg) priv->callback(priv->arg, RPTUN_NOTIFY_ALL); } - work_queue(HPWORK, &priv->worker, rptun_ivshmem_work, priv, - RPTUN_IVSHMEM_WORK_DELAY); + wd_start(&priv->wdog, RPTUN_IVSHMEM_WDOG_DELAY, rptun_ivshmem_wdog, + (wdparm_t)priv); } /**************************************************************************** @@ -363,11 +364,8 @@ static int rptun_ivshmem_probe(FAR struct ivshmem_device_s *ivdev) if (!priv->master && !ivshmem_support_irq(ivdev)) { - pciinfo("queue the worker\n"); - - /* Queue the worker for slave, master will do this in ops->start() */ - - work_queue(HPWORK, &priv->worker, rptun_ivshmem_work, priv, 0); + pciinfo("Start the wdog\n"); + wd_start(&priv->wdog, 0, rptun_ivshmem_wdog, (wdparm_t)priv); } return ret; From f3a2fd3e6ef33cc867278a314815aefc9229f12e Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Tue, 11 Jun 2024 15:53:15 +0800 Subject: [PATCH 15/22] sim/sim_rptun: add 64-bit support for sim_rptun add remote addrenv to make the da is start from 0, so the uint32_t da in resource table can store the correct address Signed-off-by: Bowen Wang --- arch/sim/src/sim/sim_rptun.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/arch/sim/src/sim/sim_rptun.c b/arch/sim/src/sim/sim_rptun.c index fa55d282dc433..dde6b6f406c49 100644 --- a/arch/sim/src/sim/sim_rptun.c +++ b/arch/sim/src/sim/sim_rptun.c @@ -72,6 +72,7 @@ struct sim_rptun_dev_s uint32_t seq; struct sim_rptun_shmem_s *shmem; struct simple_addrenv_s addrenv[2]; + struct rptun_addrenv_s raddrenv[2]; char cpuname[RPMSG_NAME_SIZE + 1]; char shmemname[RPMSG_NAME_SIZE + 1]; pid_t pid; @@ -93,6 +94,15 @@ static const char *sim_rptun_get_cpuname(struct rptun_dev_s *dev) return priv->cpuname; } +static const struct rptun_addrenv_s * +sim_rptun_get_addrenv(struct rptun_dev_s *dev) +{ + struct sim_rptun_dev_s *priv = container_of(dev, + struct sim_rptun_dev_s, rptun); + + return &priv->raddrenv[0]; +} + static struct rptun_rsc_s * sim_rptun_get_resource(struct rptun_dev_s *dev) { @@ -101,18 +111,22 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) priv->shmem = host_allocshmem(priv->shmemname, sizeof(*priv->shmem)); - if (!priv->shmem) { return NULL; } + priv->raddrenv[0].da = 0; + priv->raddrenv[0].size = sizeof(*priv->shmem); + if (priv->master) { struct rptun_rsc_s *rsc = &priv->shmem->rsc; memset(priv->shmem->buf, 0, sizeof(priv->shmem->buf)); memset(rsc, 0, sizeof(struct rptun_rsc_s)); + priv->raddrenv[0].pa = (uintptr_t)priv->shmem; + rsc->rsc_tbl_hdr.ver = 1; rsc->rsc_tbl_hdr.num = 1; rsc->offset[0] = offsetof(struct rptun_rsc_s, @@ -164,11 +178,13 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) usleep(1000); } - priv->shmem->boots = SIM_RPTUN_STATUS_OK; + priv->raddrenv[0].pa = (uintptr_t)priv->shmem->base; + + priv->shmem->boots = SIM_RPTUN_STATUS_OK; - priv->addrenv[0].va = (uintptr_t)priv->shmem; - priv->addrenv[0].pa = priv->shmem->base; - priv->addrenv[0].size = sizeof(*priv->shmem); + priv->addrenv[0].va = (uintptr_t)priv->shmem; + priv->addrenv[0].pa = priv->shmem->base; + priv->addrenv[0].size = sizeof(*priv->shmem); simple_addrenv_initialize(&priv->addrenv[0]); } @@ -365,6 +381,7 @@ static void sim_rptun_work(wdparm_t arg) static const struct rptun_ops_s g_sim_rptun_ops = { .get_cpuname = sim_rptun_get_cpuname, + .get_addrenv = sim_rptun_get_addrenv, .get_resource = sim_rptun_get_resource, .is_autostart = sim_rptun_is_autostart, .is_master = sim_rptun_is_master, From d18c7f37f8cf75d8a75cc36249e9390ad773f903 Mon Sep 17 00:00:00 2001 From: Yongrong Wang Date: Fri, 26 Jul 2024 16:57:58 +0800 Subject: [PATCH 16/22] rptun.c/rpmsg_virtio.c: move panic logic from chip to rptun/rpmsg_virtio Move the panic logic in common places, later we can move more logic to the framework instead of having the drivers implement it repeatedly. Signed-off-by: Yongrong Wang Signed-off-by: Bowen Wang --- arch/sim/src/sim/sim_rpmsg_virtio.c | 2 ++ arch/sim/src/sim/sim_rptun.c | 2 ++ drivers/rpmsg/rpmsg_virtio.c | 50 +++++++++++++++++++++++++++ drivers/rpmsg/rpmsg_virtio_ivshmem.c | 2 ++ drivers/rptun/rptun.c | 51 ++++++++++++++++++++++++++-- drivers/rptun/rptun_ivshmem.c | 2 ++ include/nuttx/rpmsg/rpmsg_virtio.h | 2 ++ include/nuttx/rptun/rptun.h | 6 ++-- 8 files changed, 112 insertions(+), 5 deletions(-) diff --git a/arch/sim/src/sim/sim_rpmsg_virtio.c b/arch/sim/src/sim/sim_rpmsg_virtio.c index e06c6f11fcd0b..737c92bbcb5d6 100644 --- a/arch/sim/src/sim/sim_rpmsg_virtio.c +++ b/arch/sim/src/sim/sim_rpmsg_virtio.c @@ -115,6 +115,8 @@ sim_rpmsg_virtio_get_resource(struct rpmsg_virtio_s *dev) rsc->rpmsg_vring1.num = 8; rsc->config.r2h_buf_size = 2048; rsc->config.h2r_buf_size = 2048; + rsc->cmd_master = 0; + rsc->cmd_slave = 0; priv->shmem->base = (uintptr_t)priv->shmem; } diff --git a/arch/sim/src/sim/sim_rptun.c b/arch/sim/src/sim/sim_rptun.c index dde6b6f406c49..9f38217abb346 100644 --- a/arch/sim/src/sim/sim_rptun.c +++ b/arch/sim/src/sim/sim_rptun.c @@ -148,6 +148,8 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) rsc->rpmsg_vring1.notifyid = RSC_NOTIFY_ID_ANY; rsc->config.r2h_buf_size = 0x800; rsc->config.h2r_buf_size = 0x800; + rsc->cmd_master = 0; + rsc->cmd_slave = 0; priv->shmem->base = (uintptr_t)priv->shmem; diff --git a/drivers/rpmsg/rpmsg_virtio.c b/drivers/rpmsg/rpmsg_virtio.c index e192145b054df..da1f815f687e2 100644 --- a/drivers/rpmsg/rpmsg_virtio.c +++ b/drivers/rpmsg/rpmsg_virtio.c @@ -45,6 +45,8 @@ #define RPMSG_VIRTIO_TIMEOUT_MS 20 #define RPMSG_VIRTIO_NOTIFYID 0 +#define RPMSG_VIRTIO_CMD_PANIC 0x1 + /**************************************************************************** * Private Types ****************************************************************************/ @@ -69,6 +71,7 @@ struct rpmsg_virtio_priv_s 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); @@ -97,6 +100,7 @@ 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, @@ -267,6 +271,23 @@ static int rpmsg_virtio_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem) 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; + + if (RPMSG_VIRTIO_IS_MASTER(priv->dev)) + { + priv->rsc->cmd_master = RPMSG_VIRTIO_CMD_PANIC; + } + else + { + priv->rsc->cmd_slave = RPMSG_VIRTIO_CMD_PANIC; + } + + 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) @@ -430,6 +451,33 @@ static void rpmsg_virtio_wakeup_rx(FAR struct rpmsg_virtio_priv_s *priv) } } +static void rpmsg_virtio_command(FAR struct rpmsg_virtio_priv_s *priv) +{ + FAR struct rpmsg_virtio_rsc_s *rsc = priv->rsc; + uint32_t cmd; + + if (RPMSG_VIRTIO_IS_MASTER(priv->dev)) + { + cmd = rsc->cmd_slave; + rsc->cmd_slave = 0; + } + else + { + cmd = rsc->cmd_master; + rsc->cmd_master = 0; + } + + switch (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; @@ -437,6 +485,8 @@ static int rpmsg_virtio_callback(FAR void *arg, uint32_t vqid) 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) { diff --git a/drivers/rpmsg/rpmsg_virtio_ivshmem.c b/drivers/rpmsg/rpmsg_virtio_ivshmem.c index a08d1057edbd5..dec7ab147b8b1 100644 --- a/drivers/rpmsg/rpmsg_virtio_ivshmem.c +++ b/drivers/rpmsg/rpmsg_virtio_ivshmem.c @@ -148,6 +148,8 @@ rpmsg_virtio_ivshmem_get_resource(FAR struct rpmsg_virtio_s *dev) rsc->rpmsg_vring1.num = CONFIG_RPMSG_VIRTIO_IVSHMEM_BUFFNUM; rsc->config.r2h_buf_size = CONFIG_RPMSG_VIRTIO_IVSHMEM_BUFFSIZE; rsc->config.h2r_buf_size = CONFIG_RPMSG_VIRTIO_IVSHMEM_BUFFSIZE; + rsc->cmd_master = 0; + rsc->cmd_slave = 0; priv->shmem->basem = (uint64_t)(uintptr_t)priv->shmem; } diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index a9bd1b3ed5372..5243315d48956 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -52,10 +52,10 @@ # define ALIGN_UP(s, a) (((s) + (a) - 1) & ~((a) - 1)) #endif -#define RPTUNIOC_NONE 0 - #define RPTUN_TIMEOUT_MS 20 +#define RPTUN_CMD_PANIC 0x1 + /**************************************************************************** * Private Types ****************************************************************************/ @@ -372,6 +372,33 @@ static bool rptun_is_recursive(FAR struct rptun_priv_s *priv) return nxsched_gettid() == priv->tid; } +static void rptun_command(FAR struct rptun_priv_s *priv) +{ + FAR struct rptun_rsc_s *rsc = priv->rproc.rsc_table; + uint32_t cmd; + + if (RPTUN_IS_MASTER(priv->dev)) + { + cmd = rsc->cmd_slave; + rsc->cmd_slave = 0; + } + else + { + cmd = rsc->cmd_master; + rsc->cmd_master = 0; + } + + switch (cmd) + { + case RPTUN_CMD_PANIC: + PANIC(); + break; + + default: + break; + } +} + static int rptun_callback(FAR void *arg, uint32_t vqid) { FAR struct rptun_priv_s *priv = arg; @@ -380,6 +407,8 @@ static int rptun_callback(FAR void *arg, uint32_t vqid) FAR struct virtqueue *svq = rvdev->svq; FAR struct virtqueue *rvq = rvdev->rvq; + rptun_command(priv); + if (vqid == RPTUN_NOTIFY_ALL || vqid == vdev->vrings_info[rvq->vq_queue_index].notifyid) { @@ -651,8 +680,24 @@ static int rptun_ioctl(FAR struct rpmsg_s *rpmsg, int cmd, unsigned long arg) static void rptun_panic(FAR struct rpmsg_s *rpmsg) { FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; + FAR struct rptun_rsc_s *rsc = priv->rproc.rsc_table; + + if (priv->dev->ops->panic != NULL) + { + RPTUN_PANIC(priv->dev); + return; + } + + if (RPTUN_IS_MASTER(priv->dev)) + { + rsc->cmd_master = RPTUN_CMD_PANIC; + } + else + { + rsc->cmd_slave = RPTUN_CMD_PANIC; + } - RPTUN_PANIC(priv->dev); + rptun_notify(&priv->rproc, RPTUN_NOTIFY_ALL); } static void rptun_dump(FAR struct rpmsg_s *rpmsg) diff --git a/drivers/rptun/rptun_ivshmem.c b/drivers/rptun/rptun_ivshmem.c index 84e0a992eba1d..b468f54457d7a 100644 --- a/drivers/rptun/rptun_ivshmem.c +++ b/drivers/rptun/rptun_ivshmem.c @@ -191,6 +191,8 @@ rptun_ivshmem_get_resource(FAR struct rptun_dev_s *dev) rsc->rpmsg_vring1.notifyid = RSC_NOTIFY_ID_ANY; rsc->config.r2h_buf_size = CONFIG_RPTUN_IVSHMEM_BUFFSIZE; rsc->config.h2r_buf_size = CONFIG_RPTUN_IVSHMEM_BUFFSIZE; + rsc->cmd_master = 0; + rsc->cmd_slave = 0; priv->shmem->rsc_size = sizeof(struct rptun_rsc_s); priv->shmem->cmds = RPTUN_IVSHMEM_READY; diff --git a/include/nuttx/rpmsg/rpmsg_virtio.h b/include/nuttx/rpmsg/rpmsg_virtio.h index ff7d6be7c67cc..7dc1b9358a9df 100644 --- a/include/nuttx/rpmsg/rpmsg_virtio.h +++ b/include/nuttx/rpmsg/rpmsg_virtio.h @@ -160,6 +160,8 @@ struct aligned_data(8) rpmsg_virtio_rsc_s struct fw_rsc_vdev_vring rpmsg_vring0; struct fw_rsc_vdev_vring rpmsg_vring1; struct fw_rsc_config config; + uint32_t cmd_master; + uint32_t cmd_slave; }; struct rpmsg_virtio_s; diff --git a/include/nuttx/rptun/rptun.h b/include/nuttx/rptun/rptun.h index f6827e2dab31f..13524bcd1ad4b 100644 --- a/include/nuttx/rptun/rptun.h +++ b/include/nuttx/rptun/rptun.h @@ -294,7 +294,7 @@ ****************************************************************************/ #define RPTUN_RESET(d,v) ((d)->ops->reset ? \ - (d)->ops->reset(d,v) : -ENOSYS) + (d)->ops->reset(d,v) : UNUSED(d)) /**************************************************************************** * Name: RPTUN_PANIC @@ -311,7 +311,7 @@ ****************************************************************************/ #define RPTUN_PANIC(d) ((d)->ops->panic ? \ - (d)->ops->panic(d) : -ENOSYS) + (d)->ops->panic(d) : UNUSED(d)) /**************************************************************************** * Public Types @@ -335,6 +335,8 @@ struct aligned_data(8) rptun_rsc_s struct fw_rsc_vdev_vring rpmsg_vring0; struct fw_rsc_vdev_vring rpmsg_vring1; struct fw_rsc_config config; + uint32_t cmd_master; + uint32_t cmd_slave; }; struct rptun_dev_s; From 91a4d5c6c1e9d2a0086d25262ac119cfa0d5ad2c Mon Sep 17 00:00:00 2001 From: Yongrong Wang Date: Mon, 5 Aug 2024 20:00:12 +0800 Subject: [PATCH 17/22] sim_rptun.c: remove sim_rptun_panic Because we can use the common part implemented in rptun Signed-off-by: Yongrong Wang --- arch/sim/src/sim/sim_rptun.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/arch/sim/src/sim/sim_rptun.c b/arch/sim/src/sim/sim_rptun.c index 9f38217abb346..5ffebc5150d87 100644 --- a/arch/sim/src/sim/sim_rptun.c +++ b/arch/sim/src/sim/sim_rptun.c @@ -35,7 +35,6 @@ ****************************************************************************/ #define SIM_RPTUN_STOP 0x1 -#define SIM_RPTUN_PANIC 0x2 #define SIM_RPTUN_MASK 0xffff #define SIM_RPTUN_SHIFT 16 #define SIM_RPTUN_WORK_DELAY 1 @@ -292,21 +291,6 @@ static int sim_rptun_register_callback(struct rptun_dev_s *dev, return 0; } -static void sim_rptun_panic(struct rptun_dev_s *dev) -{ - struct sim_rptun_dev_s *priv = container_of(dev, - struct sim_rptun_dev_s, rptun); - - if (priv->master) - { - priv->shmem->cmdm = SIM_RPTUN_PANIC << SIM_RPTUN_SHIFT; - } - else - { - priv->shmem->cmds = SIM_RPTUN_PANIC << SIM_RPTUN_SHIFT; - } -} - static void sim_rptun_check_cmd(struct sim_rptun_dev_s *priv) { unsigned int cmd = priv->master ? priv->shmem->cmds : priv->shmem->cmdm; @@ -317,10 +301,6 @@ static void sim_rptun_check_cmd(struct sim_rptun_dev_s *priv) host_abort(cmd & SIM_RPTUN_MASK); break; - case SIM_RPTUN_PANIC: - PANIC(); - break; - default: break; } @@ -391,7 +371,6 @@ static const struct rptun_ops_s g_sim_rptun_ops = .stop = sim_rptun_stop, .notify = sim_rptun_notify, .register_callback = sim_rptun_register_callback, - .panic = sim_rptun_panic, }; /**************************************************************************** From 9d658866d40a339c6d36f5dfa99a9f2990df93c6 Mon Sep 17 00:00:00 2001 From: Yongrong Wang Date: Tue, 6 Aug 2024 11:32:14 +0800 Subject: [PATCH 18/22] rptun/rpmsg_virtio: remove chip cmd and reuse the common ones Add more common command for rptun and rpmsg_virtio frameworks, also modify the rptun and rpmsg_virtio driver to use the common commands. Signed-off-by: Yongrong Wang --- arch/sim/src/sim/sim_rpmsg_virtio.c | 2 -- arch/sim/src/sim/sim_rptun.c | 18 +++++++----------- drivers/rpmsg/rpmsg_virtio_ivshmem.c | 2 -- drivers/rptun/rptun.c | 8 +++----- drivers/rptun/rptun_ivshmem.c | 10 +++------- include/nuttx/rptun/rptun.h | 11 +++++++++++ 6 files changed, 24 insertions(+), 27 deletions(-) diff --git a/arch/sim/src/sim/sim_rpmsg_virtio.c b/arch/sim/src/sim/sim_rpmsg_virtio.c index 737c92bbcb5d6..e8362d225e431 100644 --- a/arch/sim/src/sim/sim_rpmsg_virtio.c +++ b/arch/sim/src/sim/sim_rpmsg_virtio.c @@ -47,8 +47,6 @@ struct sim_rpmsg_virtio_shmem_s volatile uintptr_t base; volatile unsigned int seqs; volatile unsigned int seqm; - volatile unsigned int cmds; - volatile unsigned int cmdm; volatile unsigned int boots; volatile unsigned int bootm; struct rpmsg_virtio_rsc_s rsc; diff --git a/arch/sim/src/sim/sim_rptun.c b/arch/sim/src/sim/sim_rptun.c index 5ffebc5150d87..d301217cc7bdf 100644 --- a/arch/sim/src/sim/sim_rptun.c +++ b/arch/sim/src/sim/sim_rptun.c @@ -34,9 +34,6 @@ * Pre-processor Definitions ****************************************************************************/ -#define SIM_RPTUN_STOP 0x1 -#define SIM_RPTUN_MASK 0xffff -#define SIM_RPTUN_SHIFT 16 #define SIM_RPTUN_WORK_DELAY 1 /* Status byte for master/slave to report progress */ @@ -54,8 +51,6 @@ struct sim_rptun_shmem_s volatile uint64_t base; volatile uint32_t seqs; volatile uint32_t seqm; - volatile uint32_t cmds; - volatile uint32_t cmdm; volatile uint32_t boots; volatile uint32_t bootm; struct rptun_rsc_s rsc; @@ -238,11 +233,11 @@ static int sim_rptun_stop(struct rptun_dev_s *dev) struct sim_rptun_dev_s *priv = container_of(dev, struct sim_rptun_dev_s, rptun); - /* Don't send SIM_RPTUN_STOP when slave recovery */ + /* Don't send RPTUN_CMD_STOP when slave recovery */ if (priv->shmem->boots & SIM_RPTUN_STATUS_OK) { - priv->shmem->cmdm = SIM_RPTUN_STOP << SIM_RPTUN_SHIFT; + priv->shmem->rsc.cmd_master = RPTUN_CMD(RPTUN_CMD_STOP, 0); } if ((priv->master & SIM_RPTUN_BOOT) && priv->pid > 0) @@ -293,12 +288,13 @@ static int sim_rptun_register_callback(struct rptun_dev_s *dev, static void sim_rptun_check_cmd(struct sim_rptun_dev_s *priv) { - unsigned int cmd = priv->master ? priv->shmem->cmds : priv->shmem->cmdm; + unsigned int cmd = priv->master ? priv->shmem->rsc.cmd_slave : + priv->shmem->rsc.cmd_master; - switch ((cmd >> SIM_RPTUN_SHIFT) & SIM_RPTUN_MASK) + switch (RPTUN_GET_CMD(cmd)) { - case SIM_RPTUN_STOP: - host_abort(cmd & SIM_RPTUN_MASK); + case RPTUN_CMD_STOP: + host_abort(RPTUN_GET_CMD_VAL(cmd)); break; default: diff --git a/drivers/rpmsg/rpmsg_virtio_ivshmem.c b/drivers/rpmsg/rpmsg_virtio_ivshmem.c index dec7ab147b8b1..7004d1d29265c 100644 --- a/drivers/rpmsg/rpmsg_virtio_ivshmem.c +++ b/drivers/rpmsg/rpmsg_virtio_ivshmem.c @@ -54,8 +54,6 @@ struct rpmsg_virtio_ivshmem_mem_s volatile uint64_t basem; volatile uint32_t seqs; volatile uint32_t seqm; - volatile uint32_t cmds; - volatile uint32_t cmdm; struct rpmsg_virtio_rsc_s rsc; }; diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 5243315d48956..a274501786047 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -54,8 +54,6 @@ #define RPTUN_TIMEOUT_MS 20 -#define RPTUN_CMD_PANIC 0x1 - /**************************************************************************** * Private Types ****************************************************************************/ @@ -388,7 +386,7 @@ static void rptun_command(FAR struct rptun_priv_s *priv) rsc->cmd_master = 0; } - switch (cmd) + switch (RPTUN_GET_CMD(cmd)) { case RPTUN_CMD_PANIC: PANIC(); @@ -690,11 +688,11 @@ static void rptun_panic(FAR struct rpmsg_s *rpmsg) if (RPTUN_IS_MASTER(priv->dev)) { - rsc->cmd_master = RPTUN_CMD_PANIC; + rsc->cmd_master = RPTUN_CMD(RPTUN_CMD_PANIC, 0); } else { - rsc->cmd_slave = RPTUN_CMD_PANIC; + rsc->cmd_slave = RPTUN_CMD(RPTUN_CMD_PANIC, 0); } rptun_notify(&priv->rproc, RPTUN_NOTIFY_ALL); diff --git a/drivers/rptun/rptun_ivshmem.c b/drivers/rptun/rptun_ivshmem.c index b468f54457d7a..670198d32ee50 100644 --- a/drivers/rptun/rptun_ivshmem.c +++ b/drivers/rptun/rptun_ivshmem.c @@ -42,7 +42,6 @@ container_of(ivshmem_get_driver(dev), struct rptun_ivshmem_dev_s, drv) #define RPTUN_IVSHMEM_SHMEM_BAR 2 -#define RPTUN_IVSHMEM_READY 1 #define RPTUN_IVSHMEM_WDOG_DELAY MSEC2TICK(1) /**************************************************************************** @@ -54,8 +53,6 @@ struct rptun_ivshmem_mem_s volatile uint64_t basem; volatile uint32_t seqs; volatile uint32_t seqm; - volatile uint32_t cmds; - volatile uint32_t cmdm; volatile uint32_t reserved; volatile uint32_t rsc_size; struct rptun_rsc_s rsc; @@ -155,12 +152,12 @@ rptun_ivshmem_get_resource(FAR struct rptun_dev_s *dev) /* Wait untils salve is ready */ - while (priv->shmem->cmds != RPTUN_IVSHMEM_READY) + while (RPTUN_GET_CMD(priv->shmem->rsc.cmd_slave) != RPTUN_CMD_READY) { usleep(1000); } - priv->shmem->cmds = 0; + priv->shmem->rsc.cmd_slave = 0; priv->shmem->basem = (uint64_t)(uintptr_t)priv->shmem; } else @@ -192,10 +189,9 @@ rptun_ivshmem_get_resource(FAR struct rptun_dev_s *dev) rsc->config.r2h_buf_size = CONFIG_RPTUN_IVSHMEM_BUFFSIZE; rsc->config.h2r_buf_size = CONFIG_RPTUN_IVSHMEM_BUFFSIZE; rsc->cmd_master = 0; - rsc->cmd_slave = 0; priv->shmem->rsc_size = sizeof(struct rptun_rsc_s); - priv->shmem->cmds = RPTUN_IVSHMEM_READY; + priv->shmem->rsc.cmd_slave = RPTUN_CMD_READY; /* Wait untils master is ready, salve need use master base to * initialize addrenv. diff --git a/include/nuttx/rptun/rptun.h b/include/nuttx/rptun/rptun.h index 13524bcd1ad4b..0fd0693bb3db1 100644 --- a/include/nuttx/rptun/rptun.h +++ b/include/nuttx/rptun/rptun.h @@ -46,6 +46,17 @@ #define RPTUNIOC_RESET _RPTUNIOC(102) #define RPTUN_NOTIFY_ALL (UINT32_MAX - 0) + +#define RPTUN_CMD_PANIC 0x1 +#define RPTUN_CMD_STOP 0x2 +#define RPTUN_CMD_READY 0x3 +#define RPTUN_CMD_MASK 0xffff +#define RPTUN_CMD_SHIFT 16 + +#define RPTUN_CMD(c,v) (((c) << RPTUN_CMD_SHIFT) | ((v) & RPTUN_CMD_MASK)) +#define RPTUN_GET_CMD(c) ((c) >> RPTUN_CMD_SHIFT) +#define RPTUN_GET_CMD_VAL(c) ((c) & RPTUN_CMD_MASK) + #ifdef CONFIG_OPENAMP_CACHE # define RPTUN_INVALIDATE(x) metal_cache_invalidate(&x, sizeof(x)) #else From 4acb838e0fa6db5c778871b090e5ed9aae05ef07 Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Wed, 14 Aug 2024 15:01:42 +0800 Subject: [PATCH 19/22] rptun: move rptun cmd definition before the resource table Because locate the command at the end the resource table is unfriendly when we want to support multi virtio devices instead only one virtio rpmsg device. Signed-off-by: Bowen Wang --- arch/sim/src/sim/sim_rptun.c | 16 +++++++++++----- drivers/rptun/rptun.c | 16 ++++++++-------- drivers/rptun/rptun_ivshmem.c | 10 +++++----- include/nuttx/rptun/rptun.h | 11 +++++++++-- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/arch/sim/src/sim/sim_rptun.c b/arch/sim/src/sim/sim_rptun.c index d301217cc7bdf..447cf9582650a 100644 --- a/arch/sim/src/sim/sim_rptun.c +++ b/arch/sim/src/sim/sim_rptun.c @@ -102,6 +102,7 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) { struct sim_rptun_dev_s *priv = container_of(dev, struct sim_rptun_dev_s, rptun); + struct rptun_cmd_s *cmd; priv->shmem = host_allocshmem(priv->shmemname, sizeof(*priv->shmem)); @@ -110,12 +111,15 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) return NULL; } + cmd = RPTUN_RSC2CMD(&priv->shmem->rsc); + priv->raddrenv[0].da = 0; priv->raddrenv[0].size = sizeof(*priv->shmem); if (priv->master) { struct rptun_rsc_s *rsc = &priv->shmem->rsc; + memset(priv->shmem->buf, 0, sizeof(priv->shmem->buf)); memset(rsc, 0, sizeof(struct rptun_rsc_s)); @@ -142,9 +146,8 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) rsc->rpmsg_vring1.notifyid = RSC_NOTIFY_ID_ANY; rsc->config.r2h_buf_size = 0x800; rsc->config.h2r_buf_size = 0x800; - rsc->cmd_master = 0; - rsc->cmd_slave = 0; + cmd->cmd_slave = 0; priv->shmem->base = (uintptr_t)priv->shmem; /* The master notifies its slave when it starts again */ @@ -174,6 +177,8 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) usleep(1000); } + cmd->cmd_master = 0; + priv->raddrenv[0].pa = (uintptr_t)priv->shmem->base; priv->shmem->boots = SIM_RPTUN_STATUS_OK; @@ -232,12 +237,13 @@ static int sim_rptun_stop(struct rptun_dev_s *dev) { struct sim_rptun_dev_s *priv = container_of(dev, struct sim_rptun_dev_s, rptun); + struct rptun_cmd_s *cmd = RPTUN_RSC2CMD(&priv->shmem->rsc); /* Don't send RPTUN_CMD_STOP when slave recovery */ if (priv->shmem->boots & SIM_RPTUN_STATUS_OK) { - priv->shmem->rsc.cmd_master = RPTUN_CMD(RPTUN_CMD_STOP, 0); + cmd->cmd_master = RPTUN_CMD(RPTUN_CMD_STOP, 0); } if ((priv->master & SIM_RPTUN_BOOT) && priv->pid > 0) @@ -288,8 +294,8 @@ static int sim_rptun_register_callback(struct rptun_dev_s *dev, static void sim_rptun_check_cmd(struct sim_rptun_dev_s *priv) { - unsigned int cmd = priv->master ? priv->shmem->rsc.cmd_slave : - priv->shmem->rsc.cmd_master; + struct rptun_cmd_s *rcmd = RPTUN_RSC2CMD(&priv->shmem->rsc); + uint32_t cmd = priv->master ? rcmd->cmd_slave : rcmd->cmd_master; switch (RPTUN_GET_CMD(cmd)) { diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index a274501786047..0a026998388b9 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -372,18 +372,18 @@ static bool rptun_is_recursive(FAR struct rptun_priv_s *priv) static void rptun_command(FAR struct rptun_priv_s *priv) { - FAR struct rptun_rsc_s *rsc = priv->rproc.rsc_table; + FAR struct rptun_cmd_s *rptun_cmd = RPTUN_RSC2CMD(priv->rproc.rsc_table); uint32_t cmd; if (RPTUN_IS_MASTER(priv->dev)) { - cmd = rsc->cmd_slave; - rsc->cmd_slave = 0; + cmd = rptun_cmd->cmd_slave; + rptun_cmd->cmd_slave = 0; } else { - cmd = rsc->cmd_master; - rsc->cmd_master = 0; + cmd = rptun_cmd->cmd_master; + rptun_cmd->cmd_master = 0; } switch (RPTUN_GET_CMD(cmd)) @@ -678,7 +678,7 @@ static int rptun_ioctl(FAR struct rpmsg_s *rpmsg, int cmd, unsigned long arg) static void rptun_panic(FAR struct rpmsg_s *rpmsg) { FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; - FAR struct rptun_rsc_s *rsc = priv->rproc.rsc_table; + FAR struct rptun_cmd_s *cmd = RPTUN_RSC2CMD(priv->rproc.rsc_table); if (priv->dev->ops->panic != NULL) { @@ -688,11 +688,11 @@ static void rptun_panic(FAR struct rpmsg_s *rpmsg) if (RPTUN_IS_MASTER(priv->dev)) { - rsc->cmd_master = RPTUN_CMD(RPTUN_CMD_PANIC, 0); + cmd->cmd_master = RPTUN_CMD(RPTUN_CMD_PANIC, 0); } else { - rsc->cmd_slave = RPTUN_CMD(RPTUN_CMD_PANIC, 0); + cmd->cmd_slave = RPTUN_CMD(RPTUN_CMD_PANIC, 0); } rptun_notify(&priv->rproc, RPTUN_NOTIFY_ALL); diff --git a/drivers/rptun/rptun_ivshmem.c b/drivers/rptun/rptun_ivshmem.c index 670198d32ee50..d736b6c8b26cc 100644 --- a/drivers/rptun/rptun_ivshmem.c +++ b/drivers/rptun/rptun_ivshmem.c @@ -142,6 +142,7 @@ rptun_ivshmem_get_resource(FAR struct rptun_dev_s *dev) { FAR struct rptun_ivshmem_dev_s *priv = (FAR struct rptun_ivshmem_dev_s *)dev; + FAR struct rptun_cmd_s *cmd = RPTUN_RSC2CMD(&priv->shmem->rsc); priv->raddrenv[0].da = 0; priv->raddrenv[0].size = priv->shmem_size; @@ -152,18 +153,17 @@ rptun_ivshmem_get_resource(FAR struct rptun_dev_s *dev) /* Wait untils salve is ready */ - while (RPTUN_GET_CMD(priv->shmem->rsc.cmd_slave) != RPTUN_CMD_READY) + while (RPTUN_GET_CMD(cmd->cmd_slave) != RPTUN_CMD_READY) { usleep(1000); } - priv->shmem->rsc.cmd_slave = 0; + cmd->cmd_slave = 0; priv->shmem->basem = (uint64_t)(uintptr_t)priv->shmem; } else { FAR struct rptun_rsc_s *rsc = &priv->shmem->rsc; - memset(priv->shmem, 0, priv->shmem_size); rsc->rsc_tbl_hdr.ver = 1; @@ -188,10 +188,10 @@ rptun_ivshmem_get_resource(FAR struct rptun_dev_s *dev) rsc->rpmsg_vring1.notifyid = RSC_NOTIFY_ID_ANY; rsc->config.r2h_buf_size = CONFIG_RPTUN_IVSHMEM_BUFFSIZE; rsc->config.h2r_buf_size = CONFIG_RPTUN_IVSHMEM_BUFFSIZE; - rsc->cmd_master = 0; priv->shmem->rsc_size = sizeof(struct rptun_rsc_s); - priv->shmem->rsc.cmd_slave = RPTUN_CMD_READY; + cmd->cmd_master = 0; + cmd->cmd_slave = RPTUN_CMD(RPTUN_CMD_READY, 0); /* Wait untils master is ready, salve need use master base to * initialize addrenv. diff --git a/include/nuttx/rptun/rptun.h b/include/nuttx/rptun/rptun.h index 0fd0693bb3db1..0dc1cf3fcd29a 100644 --- a/include/nuttx/rptun/rptun.h +++ b/include/nuttx/rptun/rptun.h @@ -57,6 +57,9 @@ #define RPTUN_GET_CMD(c) ((c) >> RPTUN_CMD_SHIFT) #define RPTUN_GET_CMD_VAL(c) ((c) & RPTUN_CMD_MASK) +#define RPTUN_RSC2CMD(r) \ + ((FAR struct rptun_cmd_s *)&((FAR struct resource_table *)(r))->reserved[0]) + #ifdef CONFIG_OPENAMP_CACHE # define RPTUN_INVALIDATE(x) metal_cache_invalidate(&x, sizeof(x)) #else @@ -337,6 +340,12 @@ struct rptun_addrenv_s size_t size; }; +begin_packed_struct struct rptun_cmd_s +{ + uint32_t cmd_master; + uint32_t cmd_slave; +} end_packed_struct; + struct aligned_data(8) rptun_rsc_s { struct resource_table rsc_tbl_hdr; @@ -346,8 +355,6 @@ struct aligned_data(8) rptun_rsc_s struct fw_rsc_vdev_vring rpmsg_vring0; struct fw_rsc_vdev_vring rpmsg_vring1; struct fw_rsc_config config; - uint32_t cmd_master; - uint32_t cmd_slave; }; struct rptun_dev_s; From ba8fcbdcc9576ae16e51202d0b7c04b90d1b1cea Mon Sep 17 00:00:00 2001 From: xuxingliang Date: Fri, 23 Aug 2024 19:44:11 +0800 Subject: [PATCH 20/22] rptun: fix memleak on failure Leak backtrace: 1 14 2096 9886 0x4318d768 [0x040320744] romfs/fs_romfsutil.c:1039 [0x04031fd3e] romfs/fs_romfs.c:281 [0x04027fa9e] vfs/fs_open.c:244 [0x0402ab986] rptun/rptun.c:955 [0x04034cc88] open-amp/lib/remoteproc/remoteproc.c:452 [0x0402ac8ac] rptun/rptun.c:748 [0x0402ad038] rptun/rptun.c:618 Signed-off-by: xuxingliang --- drivers/rptun/rptun.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 0a026998388b9..144bae67a4fd8 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -1022,7 +1022,13 @@ static int rptun_store_open(FAR void *store_, *img_data = store->buf; - return file_read(&store->file, store->buf, len); + ret = file_read(&store->file, store->buf, len); + if (ret < 0) + { + file_close(&store->file); + } + + return ret; } static void rptun_store_close(FAR void *store_) From 68b158880cec02c87a6b1e3db8921d47aa629f80 Mon Sep 17 00:00:00 2001 From: mazhuang Date: Tue, 20 Aug 2024 16:32:38 +0800 Subject: [PATCH 21/22] rptun/rptun_ivshmem:add restart cmd to reboot slave Master can send restart command to slave to reboot the slave core Signed-off-by: mazhuang Signed-off-by: Yongrong Wang --- drivers/rptun/rptun_ivshmem.c | 37 +++++++++++++++++++++++++++++++++++ include/nuttx/rptun/rptun.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/drivers/rptun/rptun_ivshmem.c b/drivers/rptun/rptun_ivshmem.c index d736b6c8b26cc..34ad6030b1f71 100644 --- a/drivers/rptun/rptun_ivshmem.c +++ b/drivers/rptun/rptun_ivshmem.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -285,6 +286,38 @@ static int rptun_ivshmem_register_callback(FAR struct rptun_dev_s *dev, return 0; } +/**************************************************************************** + * Name: rptun_ivshmem_check_cmd + ****************************************************************************/ + +static void rptun_ivshmem_check_cmd(FAR struct rptun_ivshmem_dev_s *priv) +{ + FAR struct rptun_cmd_s *rptun_cmd = RPTUN_RSC2CMD(&priv->shmem->rsc); + uint32_t cmd; + + if (priv->master) + { + cmd = RPTUN_GET_CMD(rptun_cmd->cmd_slave); + rptun_cmd->cmd_slave = RPTUN_CMD(RPTUN_CMD_DEFAULT, 0); + } + else + { + cmd = RPTUN_GET_CMD(rptun_cmd->cmd_master); + rptun_cmd->cmd_master = RPTUN_CMD(RPTUN_CMD_DEFAULT, 0); + } + + switch (cmd) + { + case RPTUN_CMD_RESTART: +#ifdef CONFIG_BOARDCTL_RESET + board_reset(0); +#endif + break; + default: + break; + } +} + /**************************************************************************** * Name: rptun_ivshmem_interrupt ****************************************************************************/ @@ -293,6 +326,8 @@ static int rptun_ivshmem_interrupt(int irq, FAR void *context, FAR void *arg) { FAR struct rptun_ivshmem_dev_s *priv = arg; + rptun_ivshmem_check_cmd(priv); + if (priv->callback != NULL) { priv->callback(priv->arg, RPTUN_NOTIFY_ALL); @@ -311,6 +346,8 @@ static void rptun_ivshmem_wdog(wdparm_t arg) (FAR struct rptun_ivshmem_dev_s *)arg; bool should_notify = false; + rptun_ivshmem_check_cmd(priv); + if (priv->master && priv->seq != priv->shmem->seqs) { priv->seq = priv->shmem->seqs; diff --git a/include/nuttx/rptun/rptun.h b/include/nuttx/rptun/rptun.h index 0dc1cf3fcd29a..1cbe39894af57 100644 --- a/include/nuttx/rptun/rptun.h +++ b/include/nuttx/rptun/rptun.h @@ -47,9 +47,11 @@ #define RPTUN_NOTIFY_ALL (UINT32_MAX - 0) +#define RPTUN_CMD_DEFAULT 0x0 #define RPTUN_CMD_PANIC 0x1 #define RPTUN_CMD_STOP 0x2 #define RPTUN_CMD_READY 0x3 +#define RPTUN_CMD_RESTART 0x4 #define RPTUN_CMD_MASK 0xffff #define RPTUN_CMD_SHIFT 16 From 2056b766298c8d1a54487cdf7cbb4f300ed8abfb Mon Sep 17 00:00:00 2001 From: Bowen Wang Date: Wed, 20 Dec 2023 10:46:07 +0800 Subject: [PATCH 22/22] include/nuttx/rptun/rptun.h: change offset type to uint32_t Sync the offset data type with resource table defined in OpenAMP and Linux. Signed-off-by: Bowen Wang --- include/nuttx/rptun/rptun.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nuttx/rptun/rptun.h b/include/nuttx/rptun/rptun.h index 1cbe39894af57..cfc8e0531fba3 100644 --- a/include/nuttx/rptun/rptun.h +++ b/include/nuttx/rptun/rptun.h @@ -351,7 +351,7 @@ begin_packed_struct struct rptun_cmd_s struct aligned_data(8) rptun_rsc_s { struct resource_table rsc_tbl_hdr; - unsigned int offset[2]; + uint32_t offset[2]; struct fw_rsc_trace log_trace; struct fw_rsc_vdev rpmsg_vdev; struct fw_rsc_vdev_vring rpmsg_vring0;