You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by "yf13 (via GitHub)" <gi...@apache.org> on 2024/02/08 06:25:47 UTC
[PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
yf13 opened a new pull request, #11673:
URL: https://github.com/apache/nuttx/pull/11673
## Summary
K230 chip has two T-Head C908 RiscV cores, previously we run NuttX either on little or big cores. This patch runs NuttX on both cores with OpenAMP support via the RPTUN driver.
New additions:
- in arch/risc-v/src/k230
- k230_rptun.c K230 RPTUN driver
- k230_rptun.h K230 RPTUN driver header file
- in baords/risc-v/k230/canmv230
- configs/master Build config for master node
- configs/remote Build config for remote node
- scripts/ld-rptun.script Build script for RPTUN
Major changes:
- arch/risc-v/Kconfig Select NUTTSBI_LATE_INIT upon NUTTSBI
- in arch/risc-v/include
- k230/irq.h Add UART3 IRQ defs
- in arch/risc-v/src/k230
- Kconfig Add RPTUN related config items
- Make.defs Add k230-rptun.c to sources
- hardware/k230_memorymap.h Add K230 device and CSR defs
- k230_hart.c Add hart ctrl for RPTUN
- k230_hart.h Add hart ctrl for RPTUN
- k230_mm_init.c Add Svpmbt to support RPTUN
- k230_start.c Revised to support RPMsg UART
- in boards/risc-v/k230/canmv230
- scripts/Make.defs Add RPTUN script selection
- src/canmv_init.c Add RPTUN and RPMsg_UART initialization
## Impact
CanMV230 device
## Testing
Checked with CanMV230 device.
## Thanks
- to @xiaoxiang781216 and @CV-Bowen for sharing RPTUN information
- to @lupyuen for sharing experiences with T-Head MMU format
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "yf13 (via GitHub)" <gi...@apache.org>.
yf13 commented on PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#issuecomment-1937405825
@xiaoxiang781216 it seems that `Mac(sim-01)` is blocking CI checks now.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "yf13 (via GitHub)" <gi...@apache.org>.
yf13 commented on code in PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#discussion_r1485392116
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
+{
+ struct k230_rptun_dev_s *dev = arg;
+ bool should_notify = false;
+
+ if (dev->shmem != NULL)
+ {
+ if (dev->master && dev->seq != dev->shmem->seq_mst)
+ {
+ dev->seq = dev->shmem->seq_mst;
+ should_notify = true;
+ }
+ else if (!dev->master && dev->seq != dev->shmem->seq_rmt)
+ {
+ dev->seq = dev->shmem->seq_rmt;
+ should_notify = true;
+ }
+
+ if (should_notify && dev->callback != NULL)
+ {
+ dev->callback(dev->arg, RPTUN_NOTIFY_ALL);
+ }
+ }
+
+ work_queue(HPWORK, &dev->work, k230_rptun_work, dev,
+ CONFIG_K230_RPTUN_WORK_DELAY);
+}
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int k230_rptun_init(const char *shmname, const char *cpuname)
+{
+ struct k230_rptun_dev_s *dev = &g_rptun_dev;
+ int ret = OK;
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+ /* master is responsible for initializing shmem */
+
+ memset((void *)SHMEM, 0, SHMEM_SIZE);
+ rpinfo("\ncleared %d @ %p\n", SHMEM_SIZE, SHMEM);
+ dev->master = true;
+#else
+ dev->master = false;
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_init();
+#ifdef CONFIG_K230_RPTUN_MASTER
+ k230_rptun_ipi_master(dev);
+#else
+ k230_rptun_ipi_remote(dev);
+#endif
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+ /* Configure device */
+
+ dev->rptun.ops = &g_k230_rptun_ops;
+ strncpy(dev->cpuname, cpuname, RPMSG_NAME_SIZE);
+ strncpy(dev->shmname, shmname, RPMSG_NAME_SIZE);
+
+ ret = rptun_initialize(&dev->rptun);
+ if (ret < 0)
+ {
+ rperr("ERROR: rptun_initialize failed %d!\n", ret);
+ goto errout;
+ }
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ /* Create rptun RX thread */
+
+ ret = kthread_create("k230-rptun", CONFIG_RPTUN_PRIORITY,
+ CONFIG_RPTUN_STACKSIZE, k230_rptun_thread, NULL);
Review Comment:
IPI support is unavailable yet, thus no need for that thread.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "yf13 (via GitHub)" <gi...@apache.org>.
yf13 commented on code in PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#discussion_r1485411158
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
Review Comment:
okay, IPI related stuffs and empty panic/reset functions have been dropped.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#issuecomment-1936852293
> @acassis thanks for reminding, the doc has been updated and passed documentation checks. However, it seems that `linux/sim-01` is broken due to "lighting-app'? Please let me know if there is anything I can do.
@zhhyu7 look like matter ci break.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "yf13 (via GitHub)" <gi...@apache.org>.
yf13 commented on PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#issuecomment-1936774677
@acassis thanks for reminding, the doc has been updated.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#discussion_r1485056506
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
Review Comment:
don't need seq_rmt/seq_mst.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
+{
+ struct k230_rptun_dev_s *dev = arg;
+ bool should_notify = false;
+
+ if (dev->shmem != NULL)
+ {
+ if (dev->master && dev->seq != dev->shmem->seq_mst)
+ {
+ dev->seq = dev->shmem->seq_mst;
+ should_notify = true;
+ }
+ else if (!dev->master && dev->seq != dev->shmem->seq_rmt)
+ {
+ dev->seq = dev->shmem->seq_rmt;
+ should_notify = true;
+ }
+
+ if (should_notify && dev->callback != NULL)
+ {
+ dev->callback(dev->arg, RPTUN_NOTIFY_ALL);
+ }
+ }
+
+ work_queue(HPWORK, &dev->work, k230_rptun_work, dev,
+ CONFIG_K230_RPTUN_WORK_DELAY);
+}
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int k230_rptun_init(const char *shmname, const char *cpuname)
+{
+ struct k230_rptun_dev_s *dev = &g_rptun_dev;
+ int ret = OK;
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+ /* master is responsible for initializing shmem */
+
+ memset((void *)SHMEM, 0, SHMEM_SIZE);
+ rpinfo("\ncleared %d @ %p\n", SHMEM_SIZE, SHMEM);
+ dev->master = true;
+#else
+ dev->master = false;
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_init();
+#ifdef CONFIG_K230_RPTUN_MASTER
+ k230_rptun_ipi_master(dev);
+#else
+ k230_rptun_ipi_remote(dev);
+#endif
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+ /* Configure device */
+
+ dev->rptun.ops = &g_k230_rptun_ops;
+ strncpy(dev->cpuname, cpuname, RPMSG_NAME_SIZE);
+ strncpy(dev->shmname, shmname, RPMSG_NAME_SIZE);
+
+ ret = rptun_initialize(&dev->rptun);
+ if (ret < 0)
+ {
+ rperr("ERROR: rptun_initialize failed %d!\n", ret);
+ goto errout;
+ }
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ /* Create rptun RX thread */
+
+ ret = kthread_create("k230-rptun", CONFIG_RPTUN_PRIORITY,
+ CONFIG_RPTUN_STACKSIZE, k230_rptun_thread, NULL);
Review Comment:
where is k230_rptun_thread defined?
##########
arch/risc-v/src/k230/k230_rptun.h:
##########
@@ -0,0 +1,64 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.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 __ARCH_RISCV_SRC_K230_K230_RPTUN_H
+#define __ARCH_RISCV_SRC_K230_K230_RPTUN_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <sys/types.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: k230_rptun_init
+ *
+ * Description:
+ * This initializes K230 RPTUN device.
+ *
+ * Returns: OK on success, or negated number on error
+ *
+ ****************************************************************************/
+
+int k230_rptun_init(const char *shmname, const char *cpuname);
Review Comment:
remove shmname
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
Review Comment:
remov ALL empty functions
##########
boards/risc-v/k230/canmv230/src/canmv_init.c:
##########
@@ -142,4 +177,12 @@ void board_late_initialize(void)
mount(NULL, "/proc", "procfs", 0, NULL);
#endif
+
+#ifdef CONFIG_RPTUN
+#ifdef CONFIG_K230_RPTUN_MASTER
+ k230_rptun_init("rpshm", "remote");
+#else
Review Comment:
```suggestion
# else
```
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
Review Comment:
don't need seq_rmt/seq_mst.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
Review Comment:
why not handle irq directly?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#discussion_r1485054245
##########
boards/risc-v/k230/canmv230/src/canmv_init.c:
##########
@@ -142,4 +177,12 @@ void board_late_initialize(void)
mount(NULL, "/proc", "procfs", 0, NULL);
#endif
+
+#ifdef CONFIG_RPTUN
+#ifdef CONFIG_K230_RPTUN_MASTER
Review Comment:
```suggestion
# ifdef CONFIG_K230_RPTUN_MASTER
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "acassis (via GitHub)" <gi...@apache.org>.
acassis merged PR #11673:
URL: https://github.com/apache/nuttx/pull/11673
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "yf13 (via GitHub)" <gi...@apache.org>.
yf13 commented on code in PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#discussion_r1485392114
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
+{
+ struct k230_rptun_dev_s *dev = arg;
+ bool should_notify = false;
+
+ if (dev->shmem != NULL)
+ {
+ if (dev->master && dev->seq != dev->shmem->seq_mst)
+ {
+ dev->seq = dev->shmem->seq_mst;
+ should_notify = true;
+ }
+ else if (!dev->master && dev->seq != dev->shmem->seq_rmt)
+ {
+ dev->seq = dev->shmem->seq_rmt;
+ should_notify = true;
+ }
+
+ if (should_notify && dev->callback != NULL)
+ {
+ dev->callback(dev->arg, RPTUN_NOTIFY_ALL);
+ }
+ }
+
+ work_queue(HPWORK, &dev->work, k230_rptun_work, dev,
+ CONFIG_K230_RPTUN_WORK_DELAY);
+}
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int k230_rptun_init(const char *shmname, const char *cpuname)
+{
+ struct k230_rptun_dev_s *dev = &g_rptun_dev;
+ int ret = OK;
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+ /* master is responsible for initializing shmem */
+
+ memset((void *)SHMEM, 0, SHMEM_SIZE);
+ rpinfo("\ncleared %d @ %p\n", SHMEM_SIZE, SHMEM);
+ dev->master = true;
+#else
+ dev->master = false;
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_init();
+#ifdef CONFIG_K230_RPTUN_MASTER
+ k230_rptun_ipi_master(dev);
+#else
+ k230_rptun_ipi_remote(dev);
+#endif
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+ /* Configure device */
+
+ dev->rptun.ops = &g_k230_rptun_ops;
+ strncpy(dev->cpuname, cpuname, RPMSG_NAME_SIZE);
+ strncpy(dev->shmname, shmname, RPMSG_NAME_SIZE);
+
+ ret = rptun_initialize(&dev->rptun);
+ if (ret < 0)
+ {
+ rperr("ERROR: rptun_initialize failed %d!\n", ret);
+ goto errout;
+ }
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ /* Create rptun RX thread */
+
+ ret = kthread_create("k230-rptun", CONFIG_RPTUN_PRIORITY,
+ CONFIG_RPTUN_STACKSIZE, k230_rptun_thread, NULL);
Review Comment:
IPI support is not available now, thus no need for that thread.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
+{
+ struct k230_rptun_dev_s *dev = arg;
+ bool should_notify = false;
+
+ if (dev->shmem != NULL)
+ {
+ if (dev->master && dev->seq != dev->shmem->seq_mst)
+ {
+ dev->seq = dev->shmem->seq_mst;
+ should_notify = true;
+ }
+ else if (!dev->master && dev->seq != dev->shmem->seq_rmt)
+ {
+ dev->seq = dev->shmem->seq_rmt;
+ should_notify = true;
+ }
+
+ if (should_notify && dev->callback != NULL)
+ {
+ dev->callback(dev->arg, RPTUN_NOTIFY_ALL);
+ }
+ }
+
+ work_queue(HPWORK, &dev->work, k230_rptun_work, dev,
+ CONFIG_K230_RPTUN_WORK_DELAY);
+}
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int k230_rptun_init(const char *shmname, const char *cpuname)
+{
+ struct k230_rptun_dev_s *dev = &g_rptun_dev;
+ int ret = OK;
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+ /* master is responsible for initializing shmem */
+
+ memset((void *)SHMEM, 0, SHMEM_SIZE);
+ rpinfo("\ncleared %d @ %p\n", SHMEM_SIZE, SHMEM);
+ dev->master = true;
+#else
+ dev->master = false;
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_init();
+#ifdef CONFIG_K230_RPTUN_MASTER
+ k230_rptun_ipi_master(dev);
+#else
+ k230_rptun_ipi_remote(dev);
+#endif
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+ /* Configure device */
+
+ dev->rptun.ops = &g_k230_rptun_ops;
+ strncpy(dev->cpuname, cpuname, RPMSG_NAME_SIZE);
+ strncpy(dev->shmname, shmname, RPMSG_NAME_SIZE);
+
+ ret = rptun_initialize(&dev->rptun);
+ if (ret < 0)
+ {
+ rperr("ERROR: rptun_initialize failed %d!\n", ret);
+ goto errout;
+ }
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ /* Create rptun RX thread */
+
+ ret = kthread_create("k230-rptun", CONFIG_RPTUN_PRIORITY,
+ CONFIG_RPTUN_STACKSIZE, k230_rptun_thread, NULL);
Review Comment:
IPI support is unavailable yet, thus no need for that thread.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
Review Comment:
Simply because I haven't collected enough information about the chip's IPI hardware yet, so using lockless mode for communications. As per OpenAMP, lockless single-writer-single-reader should work though not efficient.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
Review Comment:
Simply because I haven't collected enough information about the chip's IPI hardware yet, so using lockless mode for communications. As per OpenAMP, lockless single-writer-single-reader should work though not efficient.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
+{
+ struct k230_rptun_dev_s *dev = arg;
+ bool should_notify = false;
+
+ if (dev->shmem != NULL)
+ {
+ if (dev->master && dev->seq != dev->shmem->seq_mst)
+ {
+ dev->seq = dev->shmem->seq_mst;
+ should_notify = true;
+ }
+ else if (!dev->master && dev->seq != dev->shmem->seq_rmt)
+ {
+ dev->seq = dev->shmem->seq_rmt;
+ should_notify = true;
+ }
+
+ if (should_notify && dev->callback != NULL)
+ {
+ dev->callback(dev->arg, RPTUN_NOTIFY_ALL);
+ }
+ }
+
+ work_queue(HPWORK, &dev->work, k230_rptun_work, dev,
+ CONFIG_K230_RPTUN_WORK_DELAY);
+}
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int k230_rptun_init(const char *shmname, const char *cpuname)
+{
+ struct k230_rptun_dev_s *dev = &g_rptun_dev;
+ int ret = OK;
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+ /* master is responsible for initializing shmem */
+
+ memset((void *)SHMEM, 0, SHMEM_SIZE);
+ rpinfo("\ncleared %d @ %p\n", SHMEM_SIZE, SHMEM);
+ dev->master = true;
+#else
+ dev->master = false;
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_init();
+#ifdef CONFIG_K230_RPTUN_MASTER
+ k230_rptun_ipi_master(dev);
+#else
+ k230_rptun_ipi_remote(dev);
+#endif
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+ /* Configure device */
+
+ dev->rptun.ops = &g_k230_rptun_ops;
+ strncpy(dev->cpuname, cpuname, RPMSG_NAME_SIZE);
+ strncpy(dev->shmname, shmname, RPMSG_NAME_SIZE);
+
+ ret = rptun_initialize(&dev->rptun);
+ if (ret < 0)
+ {
+ rperr("ERROR: rptun_initialize failed %d!\n", ret);
+ goto errout;
+ }
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ /* Create rptun RX thread */
+
+ ret = kthread_create("k230-rptun", CONFIG_RPTUN_PRIORITY,
+ CONFIG_RPTUN_STACKSIZE, k230_rptun_thread, NULL);
Review Comment:
IPI support is not available now, thus no need for that thread.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
+{
+ struct k230_rptun_dev_s *dev = arg;
+ bool should_notify = false;
+
+ if (dev->shmem != NULL)
+ {
+ if (dev->master && dev->seq != dev->shmem->seq_mst)
+ {
+ dev->seq = dev->shmem->seq_mst;
+ should_notify = true;
+ }
+ else if (!dev->master && dev->seq != dev->shmem->seq_rmt)
+ {
+ dev->seq = dev->shmem->seq_rmt;
+ should_notify = true;
+ }
+
+ if (should_notify && dev->callback != NULL)
+ {
+ dev->callback(dev->arg, RPTUN_NOTIFY_ALL);
+ }
+ }
+
+ work_queue(HPWORK, &dev->work, k230_rptun_work, dev,
+ CONFIG_K230_RPTUN_WORK_DELAY);
+}
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int k230_rptun_init(const char *shmname, const char *cpuname)
+{
+ struct k230_rptun_dev_s *dev = &g_rptun_dev;
+ int ret = OK;
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+ /* master is responsible for initializing shmem */
+
+ memset((void *)SHMEM, 0, SHMEM_SIZE);
+ rpinfo("\ncleared %d @ %p\n", SHMEM_SIZE, SHMEM);
+ dev->master = true;
+#else
+ dev->master = false;
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_init();
+#ifdef CONFIG_K230_RPTUN_MASTER
+ k230_rptun_ipi_master(dev);
+#else
+ k230_rptun_ipi_remote(dev);
+#endif
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+ /* Configure device */
+
+ dev->rptun.ops = &g_k230_rptun_ops;
+ strncpy(dev->cpuname, cpuname, RPMSG_NAME_SIZE);
+ strncpy(dev->shmname, shmname, RPMSG_NAME_SIZE);
+
+ ret = rptun_initialize(&dev->rptun);
+ if (ret < 0)
+ {
+ rperr("ERROR: rptun_initialize failed %d!\n", ret);
+ goto errout;
+ }
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ /* Create rptun RX thread */
+
+ ret = kthread_create("k230-rptun", CONFIG_RPTUN_PRIORITY,
+ CONFIG_RPTUN_STACKSIZE, k230_rptun_thread, NULL);
Review Comment:
IPI support is unavailable yet, thus no need for that thread.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
Review Comment:
Simply because I haven't collected enough information about the chip's IPI hardware yet, so using lockless mode for communications. As per OpenAMP, lockless single-writer-single-reader should work though not efficient.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
+{
+ struct k230_rptun_dev_s *dev = arg;
+ bool should_notify = false;
+
+ if (dev->shmem != NULL)
+ {
+ if (dev->master && dev->seq != dev->shmem->seq_mst)
+ {
+ dev->seq = dev->shmem->seq_mst;
+ should_notify = true;
+ }
+ else if (!dev->master && dev->seq != dev->shmem->seq_rmt)
+ {
+ dev->seq = dev->shmem->seq_rmt;
+ should_notify = true;
+ }
+
+ if (should_notify && dev->callback != NULL)
+ {
+ dev->callback(dev->arg, RPTUN_NOTIFY_ALL);
+ }
+ }
+
+ work_queue(HPWORK, &dev->work, k230_rptun_work, dev,
+ CONFIG_K230_RPTUN_WORK_DELAY);
+}
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int k230_rptun_init(const char *shmname, const char *cpuname)
+{
+ struct k230_rptun_dev_s *dev = &g_rptun_dev;
+ int ret = OK;
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+ /* master is responsible for initializing shmem */
+
+ memset((void *)SHMEM, 0, SHMEM_SIZE);
+ rpinfo("\ncleared %d @ %p\n", SHMEM_SIZE, SHMEM);
+ dev->master = true;
+#else
+ dev->master = false;
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_init();
+#ifdef CONFIG_K230_RPTUN_MASTER
+ k230_rptun_ipi_master(dev);
+#else
+ k230_rptun_ipi_remote(dev);
+#endif
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+ /* Configure device */
+
+ dev->rptun.ops = &g_k230_rptun_ops;
+ strncpy(dev->cpuname, cpuname, RPMSG_NAME_SIZE);
+ strncpy(dev->shmname, shmname, RPMSG_NAME_SIZE);
+
+ ret = rptun_initialize(&dev->rptun);
+ if (ret < 0)
+ {
+ rperr("ERROR: rptun_initialize failed %d!\n", ret);
+ goto errout;
+ }
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ /* Create rptun RX thread */
+
+ ret = kthread_create("k230-rptun", CONFIG_RPTUN_PRIORITY,
+ CONFIG_RPTUN_STACKSIZE, k230_rptun_thread, NULL);
Review Comment:
IPI support is not available now, thus no need for that thread.
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
+{
+ struct k230_rptun_dev_s *dev = arg;
+ bool should_notify = false;
+
+ if (dev->shmem != NULL)
+ {
+ if (dev->master && dev->seq != dev->shmem->seq_mst)
+ {
+ dev->seq = dev->shmem->seq_mst;
+ should_notify = true;
+ }
+ else if (!dev->master && dev->seq != dev->shmem->seq_rmt)
+ {
+ dev->seq = dev->shmem->seq_rmt;
+ should_notify = true;
+ }
+
+ if (should_notify && dev->callback != NULL)
+ {
+ dev->callback(dev->arg, RPTUN_NOTIFY_ALL);
+ }
+ }
+
+ work_queue(HPWORK, &dev->work, k230_rptun_work, dev,
+ CONFIG_K230_RPTUN_WORK_DELAY);
+}
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int k230_rptun_init(const char *shmname, const char *cpuname)
+{
+ struct k230_rptun_dev_s *dev = &g_rptun_dev;
+ int ret = OK;
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+ /* master is responsible for initializing shmem */
+
+ memset((void *)SHMEM, 0, SHMEM_SIZE);
+ rpinfo("\ncleared %d @ %p\n", SHMEM_SIZE, SHMEM);
+ dev->master = true;
+#else
+ dev->master = false;
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_init();
+#ifdef CONFIG_K230_RPTUN_MASTER
+ k230_rptun_ipi_master(dev);
+#else
+ k230_rptun_ipi_remote(dev);
+#endif
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+ /* Configure device */
+
+ dev->rptun.ops = &g_k230_rptun_ops;
+ strncpy(dev->cpuname, cpuname, RPMSG_NAME_SIZE);
+ strncpy(dev->shmname, shmname, RPMSG_NAME_SIZE);
+
+ ret = rptun_initialize(&dev->rptun);
+ if (ret < 0)
+ {
+ rperr("ERROR: rptun_initialize failed %d!\n", ret);
+ goto errout;
+ }
+
+#ifdef CONFIG_K230_RPTUN_IPI
+ /* Create rptun RX thread */
+
+ ret = kthread_create("k230-rptun", CONFIG_RPTUN_PRIORITY,
+ CONFIG_RPTUN_STACKSIZE, k230_rptun_thread, NULL);
Review Comment:
IPI support is unavailable yet, thus no need for that thread.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "yf13 (via GitHub)" <gi...@apache.org>.
yf13 commented on code in PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#discussion_r1485404602
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
Review Comment:
They are still needed for this non-IPI based solution., later once IPI is available, they will be turned off by MACROS.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "yf13 (via GitHub)" <gi...@apache.org>.
yf13 commented on code in PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#discussion_r1485392115
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
+ }
+ else
+ {
+ priv->shmem->seq_mst++;
+ }
+
+#endif /* CONFIG_K230_RPTUN_IPI */
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_reg_cb
+ ****************************************************************************/
+
+static int rp_set_callback(struct rptun_dev_s *dev, rptun_callback_t cb,
+ void *arg)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ priv->callback = cb;
+ priv->arg = arg;
+
+ rpinfo("%p, arg:%p\n", cb, arg);
+
+ return 0;
+}
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+/****************************************************************************
+ * Name: rp_reset
+ ****************************************************************************/
+
+static void rp_reset(struct rptun_dev_s *dev, int value)
+{
+ /* Only do hard reset for big core */
+
+ if (k230_hart_is_big())
+ {
+ rperr("Can't reset little core!\n");
+ }
+ else
+ {
+ k230_hart_big_stop();
+ k230_hart_big_boot(0);
+ }
+}
+
+/****************************************************************************
+ * Name: rp_panic
+ ****************************************************************************/
+
+static void rp_panic(struct rptun_dev_s *dev)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_REMOTE_PANIC);
+#else
+ rperr("TODO: ask remote to panic.\n");
+#endif
+}
+#endif
+
+#ifndef CONFIG_K230_RPTUN_IPI
+
+static void k230_rptun_work(void *arg)
Review Comment:
Simply because I haven't collected enough information about the chip's IPI hardware yet, so using lockless mode for communications. As per OpenAMP, lockless single-writer-single-reader should work, though not efficient.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "yf13 (via GitHub)" <gi...@apache.org>.
yf13 commented on code in PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#discussion_r1485403675
##########
arch/risc-v/src/k230/k230_rptun.c:
##########
@@ -0,0 +1,501 @@
+/****************************************************************************
+ * arch/risc-v/src/k230/k230_rptun.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/wqueue.h>
+
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/rptun/rptun.h>
+#include <nuttx/drivers/addrenv.h>
+#include <nuttx/list.h>
+
+#include <arch/barriers.h>
+
+#include <arch/board/board.h>
+#include "hardware/k230_memorymap.h"
+#include "k230_hart.h"
+#include "riscv_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_ERROR
+# define rperr _err
+# define rpwarn _warn
+# define rpinfo _info
+#else
+# define rperr(x...)
+# define rpwarn(x...)
+# define rpinfo(x...)
+#endif
+
+/* Vring config parameters taken from nrf53_rptun */
+
+#define VRINGS 2 /* Number of vrings */
+#define VRING_ALIGN 8 /* Vring alignment */
+#define VRING_NR 8 /* Number of descriptors */
+#define VRING_SIZE 512 /* Size of one descriptor */
+
+/* The RPMSG default channel used with only one RPMSG channel */
+
+#define VRING_SHMEM (CONFIG_K230_RPTUN_SHM_ADDR) /* Vring addr */
+#define VRING0_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring0 id */
+#define VRING1_NOTIFYID (RSC_NOTIFY_ID_ANY) /* Vring1 id */
+
+#define VRING_SHMEM_END (VRING_SHMEM + CONFIG_K230_RPTUN_SHM_SIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Use polling as fallback as IPI is not ready initially.
+ ****************************************************************************/
+
+struct k230_rptun_shmem_s
+{
+ volatile uintptr_t base;
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq_rmt; /* seqno for remote to watch */
+ volatile uint32_t seq_mst; /* seqno for master to watch */
+#endif
+ struct rptun_rsc_s rsc;
+};
+
+struct k230_rptun_dev_s
+{
+ struct rptun_dev_s rptun;
+ rptun_callback_t callback;
+ void *arg;
+ bool master;
+ struct k230_rptun_shmem_s *shmem;
+ struct simple_addrenv_s addrenv[VRINGS];
+ char cpuname[RPMSG_NAME_SIZE + 1];
+ char shmname[RPMSG_NAME_SIZE + 1];
+#ifndef CONFIG_K230_RPTUN_IPI
+ volatile uint32_t seq;
+ struct work_s work;
+#endif
+};
+
+#define as_k230_rptun_dev(d) container_of(d, struct k230_rptun_dev_s, rptun)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev);
+static const char *rp_get_firmware(struct rptun_dev_s *dev);
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev);
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev);
+static bool rp_is_autostart(struct rptun_dev_s *dev);
+static bool rp_is_master(struct rptun_dev_s *dev);
+static int rp_start(struct rptun_dev_s *dev);
+static int rp_stop(struct rptun_dev_s *dev);
+static int rp_notify(struct rptun_dev_s *dev, uint32_t notifyid);
+static int rp_set_callback(struct rptun_dev_s *, rptun_callback_t, void *);
+
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void rp_reset(struct rptun_dev_s *dev, int value);
+static void rp_panic(struct rptun_dev_s *dev);
+#endif
+
+#ifdef CONFIG_K230_RPTUN_IPI
+#ifdef CONFIG_K230_RPTUN_MASTER
+static void k230_rptun_ipi_master_callback(int id, void *arg);
+static void k230_rptun_ipi_master(struct k230_rptun_dev_s *dev);
+#else
+static void k230_rptun_ipi_remote_callback(int id, void *arg);
+static void k230_rptun_ipi_remote(struct k230_rptun_dev_s *dev)
+#endif /* CONFIG_K230_RPTUN_MASTER */
+
+#else /* !CONFIG_K230_RPTUN_IPI */
+static void k230_rptun_work(void *arg);
+#endif /* CONFIG_K230_RPTUN_IPI */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct rptun_ops_s g_k230_rptun_ops =
+{
+ .get_cpuname = rp_get_cpuname,
+ .get_firmware = rp_get_firmware,
+ .get_addrenv = rp_get_addrenv,
+ .get_resource = rp_get_resource,
+ .is_autostart = rp_is_autostart,
+ .is_master = rp_is_master,
+ .start = rp_start,
+ .stop = rp_stop,
+ .notify = rp_notify,
+ .register_callback = rp_set_callback,
+#ifdef CONFIG_K230_RPTUN_MASTER
+ .reset = rp_reset,
+ .panic = rp_panic
+#endif
+};
+
+#define SHMEM (struct k230_rptun_shmem_s*)VRING_SHMEM
+#define SHMEM_SIZE sizeof(struct k230_rptun_shmem_s)
+#define SHMEM_END (VRING_SHMEM + SHMEM_SIZE)
+
+static struct k230_rptun_dev_s g_rptun_dev;
+
+#ifdef CONFIG_K230_RPTUN_IPI
+static sem_t g_rptun_rx_sig = SEM_INITIALIZER(0);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp_get_cpuname
+ ****************************************************************************/
+
+static const char *rp_get_cpuname(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ return priv->cpuname;
+}
+
+/****************************************************************************
+ * Name: rp_get_firmware
+ * Returns: path to firmware ELF
+ ****************************************************************************/
+
+static const char *rp_get_firmware(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_addrenv
+ ****************************************************************************/
+
+static const struct rptun_addrenv_s *rp_get_addrenv(struct rptun_dev_s *dev)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: rp_get_resource
+ ****************************************************************************/
+
+static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ struct rptun_rsc_s *rsc;
+
+ if (priv->shmem != NULL)
+ {
+ return &priv->shmem->rsc;
+ }
+
+ priv->shmem = SHMEM;
+
+ if (priv->master)
+ {
+ /* Perform initial setup */
+
+ rsc = &priv->shmem->rsc;
+
+ rsc->rsc_tbl_hdr.ver = 1;
+ rsc->rsc_tbl_hdr.num = 1;
+ rsc->rsc_tbl_hdr.reserved[0] = 0;
+ rsc->rsc_tbl_hdr.reserved[1] = 0;
+ rsc->offset[0] = offsetof(struct rptun_rsc_s,
+ rpmsg_vdev);
+
+ rsc->rpmsg_vdev.type = RSC_VDEV;
+ rsc->rpmsg_vdev.id = VIRTIO_ID_RPMSG;
+ rsc->rpmsg_vdev.dfeatures = 1 << VIRTIO_RPMSG_F_NS
+ | 1 << VIRTIO_RPMSG_F_ACK
+ | 1 << VIRTIO_RPMSG_F_BUFSZ;
+ rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config);
+ rsc->rpmsg_vdev.num_of_vrings = VRINGS;
+
+ rsc->rpmsg_vring0.align = VRING_ALIGN;
+ rsc->rpmsg_vring0.num = VRING_NR;
+ rsc->rpmsg_vring0.notifyid = VRING0_NOTIFYID;
+ rsc->rpmsg_vring1.align = VRING_ALIGN;
+ rsc->rpmsg_vring1.num = VRING_NR;
+ rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID;
+ rsc->config.r2h_buf_size = VRING_SIZE;
+ rsc->config.h2r_buf_size = VRING_SIZE;
+
+ priv->shmem->base = (uintptr_t)priv->shmem;
+
+ rpinfo("shmem:%p, dev:%p\n", priv->shmem->base, dev);
+ }
+ else
+ {
+ /* TODO: use IPI later, polling now. */
+
+ rpinfo("wait for shmem %p...\n", priv->shmem);
+ while (priv->shmem->base == 0)
+ {
+ nxsig_usleep(100);
+ }
+
+ rpinfo("ready to go!\n");
+ }
+
+ return &priv->shmem->rsc;
+}
+
+/****************************************************************************
+ * Name: rp_is_autostart
+ ****************************************************************************/
+
+static bool rp_is_autostart(struct rptun_dev_s *dev)
+{
+ return true;
+}
+
+/****************************************************************************
+ * Name: rp_is_master
+ ****************************************************************************/
+
+static bool rp_is_master(struct rptun_dev_s *dev)
+{
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+ return priv->master;
+}
+
+/****************************************************************************
+ * Name: rp_start
+ ****************************************************************************/
+
+static int rp_start(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_stop
+ ****************************************************************************/
+
+static int rp_stop(struct rptun_dev_s *dev)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: rp_notify
+ ****************************************************************************/
+
+static int rp_notify(struct rptun_dev_s *dev, uint32_t vqid)
+{
+#ifdef CONFIG_K230_RPTUN_IPI
+ k230_ipi_signal(RPTUN_IPI_NOTIFY_RX);
+#else
+ struct k230_rptun_dev_s *priv = as_k230_rptun_dev(dev);
+
+ if (priv->master)
+ {
+ priv->shmem->seq_rmt++;
Review Comment:
They are still needed for now as IPI support is unavailable yet.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "acassis (via GitHub)" <gi...@apache.org>.
acassis commented on PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#issuecomment-1936464308
@yf13 suggestion: please extent this Testing and create an entry at https://nuttx.apache.org/docs/latest/platforms/risc-v/k230/boards/canmv230/index.html explain how to use it. So more people could test it easily and also it will avoid another hidden feature.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] risc-v/k230: initial Asymmetric Multi-Processing support [nuttx]
Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 commented on PR #11673:
URL: https://github.com/apache/nuttx/pull/11673#issuecomment-1936973072
@yf13 please reference this patch https://github.com/apache/nuttx/pull/11409.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org