diff --git a/arch/arm/src/mx8mp/mx8mp_rptun.c b/arch/arm/src/mx8mp/mx8mp_rptun.c index 666d93009a8c0..0cee2454a5cf8 100644 --- a/arch/arm/src/mx8mp/mx8mp_rptun.c +++ b/arch/arm/src/mx8mp/mx8mp_rptun.c @@ -84,7 +84,7 @@ static const char *mx8mp_rptun_get_cpuname(struct rptun_dev_s *dev); static const char *mx8mp_rptun_get_firmware(struct rptun_dev_s *dev); static const struct rptun_addrenv_s * mx8mp_rptun_get_addrenv(struct rptun_dev_s *dev); -static struct rptun_rsc_s * +static struct resource_table * mx8mp_rptun_get_resource(struct rptun_dev_s *dev); static bool mx8mp_rptun_is_autostart(struct rptun_dev_s *dev); static bool mx8mp_rptun_is_master(struct rptun_dev_s *dev); @@ -154,14 +154,15 @@ mx8mp_rptun_get_addrenv(struct rptun_dev_s *dev) * Name: mx8mp_rptun_get_resource ****************************************************************************/ -static struct rptun_rsc_s *mx8mp_rptun_get_resource(struct rptun_dev_s *dev) +static struct resource_table * +mx8mp_rptun_get_resource(struct rptun_dev_s *dev) { struct mx8mp_rptun_dev_s *priv = container_of(dev, struct mx8mp_rptun_dev_s, rptun); if (priv->shmem != NULL) { - return &priv->shmem->rsc; + return &priv->shmem->rsc.rsc_tbl_hdr; } priv->shmem = (struct mx8mp_rptun_shmem_s *)VRING_SHMEM; @@ -171,7 +172,7 @@ static struct rptun_rsc_s *mx8mp_rptun_get_resource(struct rptun_dev_s *dev) mx8mp_copy_rsc_table(); } - return &priv->shmem->rsc; + return &priv->shmem->rsc.rsc_tbl_hdr; } /**************************************************************************** diff --git a/arch/arm/src/mx8mp/mx8mp_rsctable.c b/arch/arm/src/mx8mp/mx8mp_rsctable.c index 0210b14744200..cdd3b9759feb7 100644 --- a/arch/arm/src/mx8mp/mx8mp_rsctable.c +++ b/arch/arm/src/mx8mp/mx8mp_rsctable.c @@ -26,6 +26,7 @@ #include "mx8mp_rsctable.h" #include +#include /**************************************************************************** * Pre-processor Definitions @@ -38,7 +39,7 @@ #define RESOURCE_TABLE_BASE 0x550FF000 #define VRING_SIZE 0x8000 -#define NO_RESOURCE_ENTRIES (1) +#define NO_RESOURCE_ENTRIES (2) #define RSC_VDEV_FEATURE_NS (1) /* Support name service announcement */ #define MX8MP_RSC_TABLE_VERSION (1) @@ -67,7 +68,8 @@ const struct rptun_rsc_s g_mx8mp_rsc_table = .offset = { - offsetof(struct rptun_rsc_s, rpmsg_vdev) + offsetof(struct rptun_rsc_s, rpmsg_vdev), + offsetof(struct rptun_rsc_s, carveout) }, .log_trace = @@ -111,6 +113,18 @@ const struct rptun_rsc_s g_mx8mp_rsc_table = .config = { 0 + }, + + .carveout = + { + RSC_CARVEOUT, + (uintptr_t)&g_mx8mp_rsc_table + ALIGN_UP(sizeof(struct rptun_rsc_s), + VRING_ALIGN), + FW_RSC_U32_ADDR_ANY, + VRING_SIZE * RL_BUFFER_COUNT * NUM_VRINGS + 0x1000, + 0, + 0, + "rpmsg_shm" } }; diff --git a/arch/arm/src/nrf53/nrf53_rptun.c b/arch/arm/src/nrf53/nrf53_rptun.c index c99315abb9f25..70eb1afa5a430 100644 --- a/arch/arm/src/nrf53/nrf53_rptun.c +++ b/arch/arm/src/nrf53/nrf53_rptun.c @@ -102,7 +102,7 @@ struct nrf53_rptun_dev_s ****************************************************************************/ static const char *nrf53_rptun_get_cpuname(struct rptun_dev_s *dev); -static struct rptun_rsc_s * +static struct resource_table * nrf53_rptun_get_resource(struct rptun_dev_s *dev); static bool nrf53_rptun_is_autostart(struct rptun_dev_s *dev); static bool nrf53_rptun_is_master(struct rptun_dev_s *dev); @@ -167,7 +167,7 @@ static const char *nrf53_rptun_get_cpuname(struct rptun_dev_s *dev) * Name: nrf53_rptun_get_resource ****************************************************************************/ -static struct rptun_rsc_s * +static struct resource_table * nrf53_rptun_get_resource(struct rptun_dev_s *dev) { struct nrf53_rptun_dev_s *priv = container_of(dev, @@ -176,7 +176,7 @@ nrf53_rptun_get_resource(struct rptun_dev_s *dev) if (priv->shmem != NULL) { - return &priv->shmem->rsc; + return &priv->shmem->rsc.rsc_tbl_hdr; } #ifdef CONFIG_NRF53_APPCORE @@ -194,7 +194,7 @@ nrf53_rptun_get_resource(struct rptun_dev_s *dev) priv->shmem->base = (uintptr_t)priv->shmem; rsc->rsc_tbl_hdr.ver = 1; - rsc->rsc_tbl_hdr.num = 1; + rsc->rsc_tbl_hdr.num = 2; rsc->rsc_tbl_hdr.reserved[0] = 0; rsc->rsc_tbl_hdr.reserved[1] = 0; rsc->offset[0] = offsetof(struct rptun_rsc_s, @@ -216,6 +216,18 @@ nrf53_rptun_get_resource(struct rptun_dev_s *dev) rsc->rpmsg_vring1.notifyid = VRING1_NOTIFYID; rsc->config.r2h_buf_size = VRING_SIZE; rsc->config.h2r_buf_size = VRING_SIZE; + + /* Carveout, reserved 0x1000 for vrings and memory management header */ + + rsc->offset[1] = offsetof(struct rptun_rsc_s, + carveout); + rsc->carveout.type = RSC_CARVEOUT; + rsc->carveout.da = (uintptr_t)rsc + ALIGN_UP(sizeof + (struct rptun_rsc_s), VRING_ALIGN); + rsc->carveout.pa = FW_RSC_U32_ADDR_ANY; + rsc->carveout.len = VRING_SIZE * VRING_NR * VRINGS + + 0x1000; + memcpy(rsc->carveout.name, "rpmsg_shm", 10); } else { @@ -227,7 +239,7 @@ nrf53_rptun_get_resource(struct rptun_dev_s *dev) } } - return &priv->shmem->rsc; + return &priv->shmem->rsc.rsc_tbl_hdr; } /**************************************************************************** diff --git a/arch/arm/src/stm32h7/stm32_rptun.c b/arch/arm/src/stm32h7/stm32_rptun.c index 0c9584a80797d..06f225c80f0e8 100644 --- a/arch/arm/src/stm32h7/stm32_rptun.c +++ b/arch/arm/src/stm32h7/stm32_rptun.c @@ -108,7 +108,7 @@ struct stm32_rptun_dev_s ****************************************************************************/ static const char *stm32_rptun_get_cpuname(struct rptun_dev_s *dev); -static struct rptun_rsc_s * +static struct resource_table * stm32_rptun_get_resource(struct rptun_dev_s *dev); static bool stm32_rptun_is_autostart(struct rptun_dev_s *dev); static bool stm32_rptun_is_master(struct rptun_dev_s *dev); @@ -173,7 +173,7 @@ static const char *stm32_rptun_get_cpuname(struct rptun_dev_s *dev) * Name: stm32_rptun_get_resource ****************************************************************************/ -static struct rptun_rsc_s * +static struct resource_table * stm32_rptun_get_resource(struct rptun_dev_s *dev) { struct stm32_rptun_dev_s *priv = container_of(dev, @@ -182,7 +182,7 @@ stm32_rptun_get_resource(struct rptun_dev_s *dev) if (priv->shmem != NULL) { - return &priv->shmem->rsc; + return &priv->shmem->rsc.rsc_tbl_hdr; } #ifdef CONFIG_ARCH_CHIP_STM32H7_CORTEXM7 @@ -197,7 +197,7 @@ stm32_rptun_get_resource(struct rptun_dev_s *dev) rsc = &priv->shmem->rsc; rsc->rsc_tbl_hdr.ver = 1; - rsc->rsc_tbl_hdr.num = 1; + rsc->rsc_tbl_hdr.num = 2; rsc->rsc_tbl_hdr.reserved[0] = 0; rsc->rsc_tbl_hdr.reserved[1] = 0; rsc->offset[0] = offsetof(struct rptun_rsc_s, @@ -220,6 +220,18 @@ stm32_rptun_get_resource(struct rptun_dev_s *dev) rsc->config.r2h_buf_size = VRING_SIZE; rsc->config.h2r_buf_size = VRING_SIZE; + /* Carveout, reserved 0x1000 for vrings and memory management header */ + + rsc->offset[1] = offsetof(struct rptun_rsc_s, + carveout); + rsc->carveout.type = RSC_CARVEOUT; + rsc->carveout.da = (uintptr_t)rsc + ALIGN_UP(sizeof + (struct rptun_rsc_s), VRING_ALIGN); + rsc->carveout.pa = FW_RSC_U32_ADDR_ANY; + rsc->carveout.len = VRING_SIZE * VRING_NR * VRINGS + + 0x1000; + memcpy(rsc->carveout.name, "rpmsg_shm", 10); + priv->shmem->base = (uintptr_t)priv->shmem; } else @@ -232,7 +244,7 @@ stm32_rptun_get_resource(struct rptun_dev_s *dev) } } - return &priv->shmem->rsc; + return &priv->shmem->rsc.rsc_tbl_hdr; } /**************************************************************************** diff --git a/arch/risc-v/src/k230/k230_rptun.c b/arch/risc-v/src/k230/k230_rptun.c index 810a778d53323..5d0a1217b6fba 100644 --- a/arch/risc-v/src/k230/k230_rptun.c +++ b/arch/risc-v/src/k230/k230_rptun.c @@ -132,7 +132,7 @@ struct k230_rptun_dev_s ****************************************************************************/ static const char *rp_get_cpuname(struct rptun_dev_s *dev); -static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev); +static struct resource_table *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); @@ -173,14 +173,14 @@ static const char *rp_get_cpuname(struct rptun_dev_s *dev) return priv->peername; } -static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev) +static struct resource_table *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; + return &priv->shmem->rsc.rsc_tbl_hdr; } priv->shmem = SHMEM; @@ -192,7 +192,7 @@ static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev) rsc = &priv->shmem->rsc; rsc->rsc_tbl_hdr.ver = 1; - rsc->rsc_tbl_hdr.num = 1; + rsc->rsc_tbl_hdr.num = 2; rsc->rsc_tbl_hdr.reserved[0] = 0; rsc->rsc_tbl_hdr.reserved[1] = 0; rsc->offset[0] = offsetof(struct rptun_rsc_s, @@ -215,6 +215,18 @@ static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev) rsc->config.r2h_buf_size = VRING_SIZE; rsc->config.h2r_buf_size = VRING_SIZE; + /* Carveout, reserved 0x1000 for vrings and memory management header */ + + rsc->offset[1] = offsetof(struct rptun_rsc_s, + carveout); + rsc->carveout.type = RSC_CARVEOUT; + rsc->carveout.da = (uintptr_t)rsc + ALIGN_UP(sizeof + (struct rptun_rsc_s), VRING_ALIGN); + rsc->carveout.pa = FW_RSC_U32_ADDR_ANY; + rsc->carveout.len = VRING_SIZE * VRING_NR * VRINGS + + 0x1000; + memcpy(rsc->carveout.name, "rpmsg_shm", 10); + priv->shmem->base = (uintptr_t)priv->shmem; rpinfo("shmem:%lx, dev:%p\n", priv->shmem->base, dev); @@ -232,7 +244,7 @@ static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev) rpinfo("shmem:%lx, dev:%p\n", priv->shmem->base, dev); } - return &priv->shmem->rsc; + return &priv->shmem->rsc.rsc_tbl_hdr; } static bool rp_is_autostart(struct rptun_dev_s *dev) diff --git a/arch/risc-v/src/qemu-rv/qemu_rv_rptun.c b/arch/risc-v/src/qemu-rv/qemu_rv_rptun.c index 5c4bdc21fffcd..6f24c381651cf 100644 --- a/arch/risc-v/src/qemu-rv/qemu_rv_rptun.c +++ b/arch/risc-v/src/qemu-rv/qemu_rv_rptun.c @@ -117,7 +117,7 @@ struct qemu_rptun_dev_s ****************************************************************************/ static const char *rp_get_cpuname(struct rptun_dev_s *dev); -static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev); +static struct resource_table *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); @@ -201,14 +201,14 @@ static const char *rp_get_cpuname(struct rptun_dev_s *dev) return priv->peername; } -static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev) +static struct resource_table *rp_get_resource(struct rptun_dev_s *dev) { struct qemu_rptun_dev_s *priv = as_qemu_rptun_dev(dev); struct rptun_rsc_s *rsc; if (priv->shmem != NULL) { - return &priv->shmem->rsc; + return &priv->shmem->rsc.rsc_tbl_hdr; } priv->shmem = SHMEM + CONFIG_QEMU_RPTUN_SHM_SIZE * priv->ndx; @@ -220,7 +220,7 @@ static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev) rsc = &priv->shmem->rsc; rsc->rsc_tbl_hdr.ver = 1; - rsc->rsc_tbl_hdr.num = 1; + rsc->rsc_tbl_hdr.num = 2; rsc->rsc_tbl_hdr.reserved[0] = 0; rsc->rsc_tbl_hdr.reserved[1] = 0; rsc->offset[0] = offsetof(struct rptun_rsc_s, @@ -243,6 +243,18 @@ static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev) rsc->config.r2h_buf_size = VRING_SIZE; rsc->config.h2r_buf_size = VRING_SIZE; + /* Carveout, reserved 0x1000 for vrings and memory management header */ + + rsc->offset[1] = offsetof(struct rptun_rsc_s, + carveout); + rsc->carveout.type = RSC_CARVEOUT; + rsc->carveout.da = (uintptr_t)rsc + ALIGN_UP(sizeof + (struct rptun_rsc_s), VRING_ALIGN); + rsc->carveout.pa = FW_RSC_U32_ADDR_ANY; + rsc->carveout.len = VRING_SIZE * VRING_NR * VRINGS + + 0x1000; + memcpy(rsc->carveout.name, "rpmsg_shm", 10); + priv->shmem->base = (uintptr_t)priv->shmem; } else @@ -258,7 +270,7 @@ static struct rptun_rsc_s *rp_get_resource(struct rptun_dev_s *dev) } rpinfo("shmem:%p, dev:%p\n", (void *)priv->shmem->base, dev); - return &priv->shmem->rsc; + return &priv->shmem->rsc.rsc_tbl_hdr; } static bool rp_is_autostart(struct rptun_dev_s *dev) diff --git a/arch/sim/src/sim/posix/sim_hostmisc.c b/arch/sim/src/sim/posix/sim_hostmisc.c index 6015af0701eed..030d6a766ed8a 100644 --- a/arch/sim/src/sim/posix/sim_hostmisc.c +++ b/arch/sim/src/sim/posix/sim_hostmisc.c @@ -232,3 +232,12 @@ int host_waitpid(pid_t pid) pid = host_uninterruptible_errno(waitpid, pid, &status, 0); return pid < 0 ? pid : status; } + +/**************************************************************************** + * Name: host_kill + ****************************************************************************/ + +int host_kill(pid_t pid, int sig) +{ + return host_uninterruptible_errno(kill, pid, sig); +} diff --git a/arch/sim/src/sim/sim_internal.h b/arch/sim/src/sim/sim_internal.h index 68247ebb7da56..da376ca5dfe60 100644 --- a/arch/sim/src/sim/sim_internal.h +++ b/arch/sim/src/sim/sim_internal.h @@ -240,6 +240,7 @@ void host_init_cwd(void); pid_t host_posix_spawn(const char *path, char *const argv[], char *const envp[]); int host_waitpid(pid_t pid); +int host_kill(pid_t pid, int sig); /* sim_hostmemory.c *********************************************************/ diff --git a/arch/sim/src/sim/sim_rpmsg_virtio.c b/arch/sim/src/sim/sim_rpmsg_virtio.c index fbedcf8bd57c1..5cbbb20904acb 100644 --- a/arch/sim/src/sim/sim_rpmsg_virtio.c +++ b/arch/sim/src/sim/sim_rpmsg_virtio.c @@ -91,7 +91,6 @@ sim_rpmsg_virtio_get_resource(struct rpmsg_virtio_lite_s *dev) struct sim_rpmsg_virtio_dev_s *priv = container_of(dev, struct sim_rpmsg_virtio_dev_s, dev); struct rpmsg_virtio_lite_rsc_s *rsc; - struct rpmsg_virtio_lite_cmd_s *cmd; priv->shmem = host_allocshmem(priv->shmemname, sizeof(*priv->shmem)); if (!priv->shmem) @@ -100,7 +99,6 @@ sim_rpmsg_virtio_get_resource(struct rpmsg_virtio_lite_s *dev) } rsc = &priv->shmem->rsc; - cmd = RPMSG_VIRTIO_LITE_RSC2CMD(rsc); if (priv->master) { @@ -118,7 +116,6 @@ sim_rpmsg_virtio_get_resource(struct rpmsg_virtio_lite_s *dev) rsc->rpmsg_vring1.num = 8; rsc->config.r2h_buf_size = 2048; rsc->config.h2r_buf_size = 2048; - cmd->cmd_slave = 0; priv->shmem->base = (uintptr_t)priv->shmem; } @@ -131,7 +128,6 @@ sim_rpmsg_virtio_get_resource(struct rpmsg_virtio_lite_s *dev) usleep(1000); } - cmd->cmd_master = 0; priv->addrenv[0].va = (uintptr_t)priv->shmem; priv->addrenv[0].pa = priv->shmem->base; priv->addrenv[0].size = sizeof(*priv->shmem); diff --git a/arch/sim/src/sim/sim_rptun.c b/arch/sim/src/sim/sim_rptun.c index 5295cab5f5e5f..6371d14b08ba9 100644 --- a/arch/sim/src/sim/sim_rptun.c +++ b/arch/sim/src/sim/sim_rptun.c @@ -24,11 +24,13 @@ * Included Files ****************************************************************************/ -#include +#include + #include +#include #include #include -#include +#include #include "sim_internal.h" @@ -45,10 +47,33 @@ #define SIM_RPTUN_STATUS_OK 0x02 #define SIM_RPTUN_STATUS_NEED_RESET 0x04 +#define SIM_RPTUN_VIRTIO_NUM 3 +#define SIM_RPTUN_RSC_NUM (2 * SIM_RPTUN_VIRTIO_NUM) + /**************************************************************************** * Private Types ****************************************************************************/ +struct aligned_data(8) sim_rptun_rsc_s +{ + struct resource_table hdr; + uint32_t offset[SIM_RPTUN_RSC_NUM]; + struct fw_rsc_vdev rng0; + struct fw_rsc_vdev_vring rng0_vring; + struct fw_rsc_carveout rng0_carveout; + char rng0_shm[SIM_RPTUN_SHMEM_SIZE]; + struct fw_rsc_vdev rng1; + struct fw_rsc_vdev_vring rng1_vring; + struct fw_rsc_carveout rng1_carveout; + char rng1_shm[SIM_RPTUN_SHMEM_SIZE]; + struct fw_rsc_vdev rpmsg0; + struct fw_rsc_vdev_vring rpmsg0_vring0; + struct fw_rsc_vdev_vring rpmsg0_vring1; + struct fw_rsc_config rpmsg0_config; + struct fw_rsc_carveout rpmsg0_carveout; + char rpmsg0_shm[SIM_RPTUN_SHMEM_SIZE]; +}; + struct sim_rptun_shmem_s { volatile uint64_t base; @@ -56,8 +81,7 @@ struct sim_rptun_shmem_s volatile uint32_t seqm; volatile uint32_t boots; volatile uint32_t bootm; - struct rptun_rsc_s rsc; - char buf[0x10000]; + struct sim_rptun_rsc_s rsc; }; struct sim_rptun_dev_s @@ -74,9 +98,9 @@ struct sim_rptun_dev_s char shmemname[RPMSG_NAME_SIZE + 1]; pid_t pid; - /* Wdog for transmit */ + /* Workqueue for transmit */ - struct wdog_s wdog; + struct work_s work; }; /**************************************************************************** @@ -100,12 +124,11 @@ sim_rptun_get_addrenv(struct rptun_dev_s *dev) return &priv->raddrenv[0]; } -static struct rptun_rsc_s * +static struct resource_table * sim_rptun_get_resource(struct rptun_dev_s *dev) { struct sim_rptun_dev_s *priv = container_of(dev, struct sim_rptun_dev_s, rptun); - struct rptun_cmd_s *cmd; priv->shmem = host_allocshmem(priv->shmemname, sizeof(*priv->shmem)); @@ -114,44 +137,110 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) return NULL; } - cmd = RPTUN_RSC2CMD(&priv->shmem->rsc); - - priv->raddrenv[0].da = 0; - priv->raddrenv[0].size = sizeof(*priv->shmem); - if (priv->master) { - struct rptun_rsc_s *rsc = &priv->shmem->rsc; - - memset(priv->shmem->buf, 0, sizeof(priv->shmem->buf)); - memset(rsc, 0, sizeof(struct rptun_rsc_s)); - - priv->raddrenv[0].pa = (uintptr_t)priv->shmem; - - rsc->rsc_tbl_hdr.ver = 1; - rsc->rsc_tbl_hdr.num = 1; - rsc->offset[0] = offsetof(struct rptun_rsc_s, - 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 = 2; - rsc->rpmsg_vring0.da = 0; - rsc->rpmsg_vring0.align = 8; - rsc->rpmsg_vring0.num = 8; - rsc->rpmsg_vring0.notifyid = RSC_NOTIFY_ID_ANY; - rsc->rpmsg_vring1.da = 0; - rsc->rpmsg_vring1.align = 8; - rsc->rpmsg_vring1.num = 8; - rsc->rpmsg_vring1.notifyid = RSC_NOTIFY_ID_ANY; - rsc->config.r2h_buf_size = 0x800; - rsc->config.h2r_buf_size = 0x800; - - cmd->cmd_slave = 0; - priv->shmem->base = (uintptr_t)priv->shmem; + struct sim_rptun_rsc_s *rsc = &priv->shmem->rsc; + memset(rsc, 0, sizeof(struct sim_rptun_rsc_s)); + + rsc->hdr.ver = 1; + rsc->hdr.num = SIM_RPTUN_RSC_NUM; + + /* Virtio Driver 0, VIRTIO_ID_ENTROPY */ + + rsc->offset[0] = offsetof(struct sim_rptun_rsc_s, + rng0); + rsc->rng0.type = RSC_VDEV; + rsc->rng0.id = VIRTIO_ID_ENTROPY; + rsc->rng0.notifyid = RSC_NOTIFY_ID_ANY; + rsc->rng0.dfeatures = 0; + rsc->rng0.config_len = 0; + rsc->rng0.num_of_vrings = 1; + rsc->rng0.reserved[0] = VIRTIO_DEV_DRIVER; + rsc->rng0.reserved[1] = 0; + rsc->rng0_vring.align = 8; + rsc->rng0_vring.num = 8; + rsc->rng0_vring.notifyid = RSC_NOTIFY_ID_ANY; + rsc->rng0_vring.da = 0; + + /* Virtio Rng0 share memory buffer */ + + rsc->offset[1] = offsetof(struct sim_rptun_rsc_s, + rng0_carveout); + rsc->rng0_carveout.type = RSC_CARVEOUT; + rsc->rng0_carveout.da = offsetof(struct sim_rptun_shmem_s, + rsc.rng0_shm); + rsc->rng0_carveout.pa = FW_RSC_U32_ADDR_ANY; + rsc->rng0_carveout.len = sizeof(priv->shmem->rsc.rng0_shm); + memcpy(rsc->rng0_carveout.name, "rng0_shm", 9); + + /* Virtio Driver 1, VIRTIO_ID_ENTROPY */ + + rsc->offset[2] = offsetof(struct sim_rptun_rsc_s, + rng1); + rsc->rng1.type = RSC_VDEV; + rsc->rng1.id = VIRTIO_ID_ENTROPY; + rsc->rng1.notifyid = RSC_NOTIFY_ID_ANY; + rsc->rng1.dfeatures = 0; + rsc->rng1.config_len = 0; + rsc->rng1.num_of_vrings = 1; + rsc->rng1.reserved[0] = VIRTIO_DEV_DRIVER; + rsc->rng1.reserved[1] = 0; + rsc->rng1_vring.align = 8; + rsc->rng1_vring.num = 8; + rsc->rng1_vring.notifyid = RSC_NOTIFY_ID_ANY; + rsc->rng1_vring.da = 0; + + /* Virtio Rng1 share memory buffer */ + + rsc->offset[3] = offsetof(struct sim_rptun_rsc_s, + rng1_carveout); + rsc->rng1_carveout.type = RSC_CARVEOUT; + rsc->rng1_carveout.da = offsetof(struct sim_rptun_shmem_s, + rsc.rng1_shm); + rsc->rng1_carveout.pa = FW_RSC_U32_ADDR_ANY; + rsc->rng1_carveout.len = sizeof(priv->shmem->rsc.rng1_shm); + memcpy(rsc->rng1_carveout.name, "rng1_shm", 9); + + /* Virtio Driver 2, VIRTIO_ID_RPMSG */ + + rsc->offset[4] = offsetof(struct sim_rptun_rsc_s, + rpmsg0); + rsc->rpmsg0.type = RSC_VDEV; + rsc->rpmsg0.id = VIRTIO_ID_RPMSG; + rsc->rpmsg0.notifyid = RSC_NOTIFY_ID_ANY; + rsc->rpmsg0.dfeatures = (1 << VIRTIO_RPMSG_F_NS) | + (1 << VIRTIO_RPMSG_F_ACK) | + (1 << VIRTIO_RPMSG_F_BUFSZ) | + (1 << VIRTIO_RPMSG_F_CPUNAME); + rsc->rpmsg0.config_len = sizeof(struct fw_rsc_config); + rsc->rpmsg0.num_of_vrings = 2; + rsc->rpmsg0.reserved[0] = VIRTIO_DEV_DRIVER; + rsc->rpmsg0.reserved[1] = 0; + rsc->rpmsg0_vring0.align = 8; + rsc->rpmsg0_vring0.num = 8; + rsc->rpmsg0_vring0.notifyid = RSC_NOTIFY_ID_ANY; + rsc->rpmsg0_vring0.da = 0; + rsc->rpmsg0_vring1.align = 8; + rsc->rpmsg0_vring1.num = 8; + rsc->rpmsg0_vring1.notifyid = RSC_NOTIFY_ID_ANY; + rsc->rpmsg0_vring1.da = 0; + rsc->rpmsg0_config.h2r_buf_size = 0x600; + rsc->rpmsg0_config.r2h_buf_size = 0x600; + memcpy(rsc->rpmsg0_config.host_cpuname, "server", 6); + memcpy(rsc->rpmsg0_config.remote_cpuname, "proxy", 5); + + /* Virtio Rpmsg0 share memory buffer */ + + rsc->offset[5] = offsetof(struct sim_rptun_rsc_s, + rpmsg0_carveout); + rsc->rpmsg0_carveout.type = RSC_CARVEOUT; + rsc->rpmsg0_carveout.da = offsetof(struct sim_rptun_shmem_s, + rsc.rpmsg0_shm); + rsc->rpmsg0_carveout.pa = FW_RSC_U32_ADDR_ANY; + rsc->rpmsg0_carveout.len = sizeof(priv->shmem->rsc.rpmsg0_shm); + memcpy(rsc->rpmsg0_carveout.name, "rpmsg0_shm", 10); + + priv->shmem->base = (uintptr_t)priv->shmem; /* The master notifies its slave when it starts again */ @@ -180,10 +269,6 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) usleep(1000); } - cmd->cmd_master = 0; - - priv->raddrenv[0].pa = (uintptr_t)priv->shmem->base; - priv->shmem->boots = SIM_RPTUN_STATUS_OK; priv->addrenv[0].va = (uintptr_t)priv->shmem; @@ -193,7 +278,12 @@ sim_rptun_get_resource(struct rptun_dev_s *dev) simple_addrenv_initialize(&priv->addrenv[0]); } - return &priv->shmem->rsc; + priv->raddrenv[0].pa = priv->master ? (uintptr_t)priv->shmem : + (uintptr_t)priv->shmem->base; + priv->raddrenv[0].da = 0; + priv->raddrenv[0].size = sizeof(*priv->shmem); + + return &priv->shmem->rsc.hdr; } static bool sim_rptun_is_autostart(struct rptun_dev_s *dev) @@ -251,6 +341,7 @@ static int sim_rptun_stop(struct rptun_dev_s *dev) if ((priv->master & SIM_RPTUN_BOOT) && priv->pid > 0) { + host_kill(priv->pid, SIGKILL); host_waitpid(priv->pid); } @@ -327,7 +418,7 @@ static void sim_rptun_check_reset(struct sim_rptun_dev_s *priv) } } -static void sim_rptun_work(wdparm_t arg) +static void sim_rptun_work(void *arg) { struct sim_rptun_dev_s *dev = (struct sim_rptun_dev_s *)arg; @@ -358,7 +449,7 @@ static void sim_rptun_work(wdparm_t arg) } } - wd_start(&dev->wdog, SIM_RPTUN_WORK_DELAY, sim_rptun_work, (wdparm_t)dev); + work_queue(HPWORK, &dev->work, sim_rptun_work, dev, SIM_RPTUN_WORK_DELAY); } /**************************************************************************** @@ -405,5 +496,7 @@ int sim_rptun_init(const char *shmemname, const char *cpuname, int master) return ret; } - return wd_start(&dev->wdog, 0, sim_rptun_work, (wdparm_t)dev); + work_queue(HPWORK, &dev->work, sim_rptun_work, dev, 0); + + return 0; } diff --git a/drivers/rpmsg/CMakeLists.txt b/drivers/rpmsg/CMakeLists.txt index 753e8bc3cf653..99917c44304da 100644 --- a/drivers/rpmsg/CMakeLists.txt +++ b/drivers/rpmsg/CMakeLists.txt @@ -47,6 +47,10 @@ if(CONFIG_RPMSG) list(APPEND SRCS rpmsg_port_uart.c) endif() + if(CONFIG_RPMSG_VIRTIO) + list(APPEND SRCS rpmsg_virtio.c) + endif() + if(CONFIG_RPMSG_VIRTIO_LITE) list(APPEND SRCS rpmsg_virtio_lite.c) endif() diff --git a/drivers/rpmsg/Kconfig b/drivers/rpmsg/Kconfig index 80fde24e6bf6e..77d5968ee2c81 100644 --- a/drivers/rpmsg/Kconfig +++ b/drivers/rpmsg/Kconfig @@ -112,6 +112,26 @@ config RPMSG_PORT_UART_DEBUG endif # RPMSG_PORT_UART +config RPMSG_VIRTIO + bool + default n + select RPMSG + ---help--- + The Rpmsg VirtIO Lite, VirtIO-Rpmsg and VHost-Rpmsg common + part. + +if RPMSG_VIRTIO + +config RPMSG_VIRTIO_PRIORITY + int "rpmsg virtio priority" + default 224 + +config RPMSG_VIRTIO_STACKSIZE + int "rpmsg virtio stack size" + default DEFAULT_TASK_STACKSIZE + +endif # RPMSG_VIRTIO + config RPMSG_VIRTIO_LITE bool "rpmsg virtio transport support" default n diff --git a/drivers/rpmsg/Make.defs b/drivers/rpmsg/Make.defs index 164fabf176242..ed4924fa41089 100644 --- a/drivers/rpmsg/Make.defs +++ b/drivers/rpmsg/Make.defs @@ -55,6 +55,10 @@ ifeq ($(CONFIG_RPMSG_PORT_UART),y) CSRCS += rpmsg_port_uart.c endif +ifeq ($(CONFIG_RPMSG_VIRTIO),y) +CSRCS += rpmsg_virtio.c +endif + ifeq ($(CONFIG_RPMSG_VIRTIO_LITE),y) CSRCS += rpmsg_virtio_lite.c CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)openamp$(DELIM)open-amp$(DELIM)lib diff --git a/drivers/rpmsg/rpmsg_virtio.c b/drivers/rpmsg/rpmsg_virtio.c new file mode 100644 index 0000000000000..e2c74042fc385 --- /dev/null +++ b/drivers/rpmsg/rpmsg_virtio.c @@ -0,0 +1,609 @@ +/**************************************************************************** + * drivers/rpmsg/rpmsg_virtio.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define RPMSG_VIRTIO_FEATURES (1 << VIRTIO_RPMSG_F_NS | \ + 1 << VIRTIO_RPMSG_F_ACK | \ + 1 << VIRTIO_RPMSG_F_BUFSZ | \ + 1 << VIRTIO_RPMSG_F_CPUNAME) + +#ifdef CONFIG_OPENAMP_CACHE +# define RPMSG_VIRTIO_INVALIDATE(x) metal_cache_invalidate(&x, sizeof(x)) +#else +# define RPMSG_VIRTIO_INVALIDATE(x) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rpmsg_virtio_priv_s +{ + struct rpmsg_s rpmsg; + struct rpmsg_virtio_device rvdev; + struct rpmsg_virtio_shm_pool pool[2]; + struct virtio_device *vdev; + sem_t semrx; + sem_t semtx; + pid_t tid; + vq_callback cbrx; + vq_callback cbtx; + char local_cpuname[VIRTIO_RPMSG_CPUNAME_SIZE]; + char cpuname[VIRTIO_RPMSG_CPUNAME_SIZE]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int rpmsg_virtio_wait(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); +static int rpmsg_virtio_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); +static void rpmsg_virtio_dump(FAR struct rpmsg_s *rpmsg); +static FAR const char * +rpmsg_virtio_get_local_cpuname(FAR struct rpmsg_s *rpmsg); +static FAR const char *rpmsg_virtio_get_cpuname(FAR struct rpmsg_s *rpmsg); + +static void rpmsg_virtio_rx_callback(FAR struct virtqueue *vq); +static void rpmsg_virtio_tx_callback(FAR struct virtqueue *vq); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct rpmsg_ops_s g_rpmsg_virtio_ops = +{ + rpmsg_virtio_wait, + rpmsg_virtio_post, + NULL, + NULL, + rpmsg_virtio_dump, + rpmsg_virtio_get_local_cpuname, + rpmsg_virtio_get_cpuname, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rpmsg_virtio_is_recursive + ****************************************************************************/ + +static bool rpmsg_virtio_is_recursive(FAR struct rpmsg_virtio_priv_s *priv) +{ + return nxsched_gettid() == priv->tid; +} + +/**************************************************************************** + * Name: rpmsg_virtio_wakeup_rx + ****************************************************************************/ + +static void rpmsg_virtio_wakeup_rx(FAR struct rpmsg_virtio_priv_s *priv) +{ + int semcount; + + nxsem_get_value(&priv->semrx, &semcount); + while (semcount++ < 1) + { + nxsem_post(&priv->semrx); + } +} + +/**************************************************************************** + * Name: rpmsg_virtio_wakeup_tx + ****************************************************************************/ + +static void rpmsg_virtio_wakeup_tx(FAR struct rpmsg_virtio_priv_s *priv) +{ + int semcount; + + nxsem_get_value(&priv->semtx, &semcount); + while (semcount++ < 1) + { + nxsem_post(&priv->semtx); + } +} + +/**************************************************************************** + * Name: rpmsg_virtio_wait + ****************************************************************************/ + +static int rpmsg_virtio_wait(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem) +{ + FAR struct rpmsg_virtio_priv_s *priv = + (FAR struct rpmsg_virtio_priv_s *)rpmsg; + int ret; + + if (!rpmsg_virtio_is_recursive(priv)) + { + return nxsem_wait_uninterruptible(sem); + } + + while (1) + { + ret = nxsem_trywait(sem); + if (ret >= 0) + { + break; + } + + nxsem_wait(&priv->semtx); + priv->cbrx(priv->rvdev.rvq); + } + + return ret; +} + +/**************************************************************************** + * Name: rpmsg_virtio_post + ****************************************************************************/ + +static int rpmsg_virtio_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem) +{ + FAR struct rpmsg_virtio_priv_s *priv = + (FAR struct rpmsg_virtio_priv_s *)rpmsg; + int semcount; + int ret; + + nxsem_get_value(sem, &semcount); + ret = nxsem_post(sem); + + if (priv && semcount >= 0) + { + rpmsg_virtio_wakeup_tx(priv); + } + + return ret; +} + +/**************************************************************************** + * Name: rpmsg_virtio_buffer_nused + ****************************************************************************/ + +static int rpmsg_virtio_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, + bool rx) +{ + FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq; + bool is_host = rpmsg_virtio_get_role(rvdev) == RPMSG_HOST; + uint16_t nused; + + if (is_host) + { + RPMSG_VIRTIO_INVALIDATE(vq->vq_ring.used->idx); + } + else + { + RPMSG_VIRTIO_INVALIDATE(vq->vq_ring.avail->idx); + } + + nused = vq->vq_ring.avail->idx - vq->vq_ring.used->idx; + if (is_host ^ rx) + { + return nused; + } + else + { + return vq->vq_nentries - nused; + } +} + +/**************************************************************************** + * Name: rpmsg_virtio_dump_buffer + ****************************************************************************/ + +static void rpmsg_virtio_dump_buffer(FAR struct rpmsg_virtio_device *rvdev, + bool rx) +{ + FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq; + FAR void *addr; + int desc_idx; + int num; + int i; + + num = rpmsg_virtio_buffer_nused(rvdev, rx); + metal_log(METAL_LOG_EMERGENCY, + " %s buffer, total %d, pending %d\n", + rx ? "RX" : "TX", vq->vq_nentries, num); + + for (i = 0; i < num; i++) + { + if ((rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) ^ rx) + { + RPMSG_VIRTIO_INVALIDATE(vq->vq_ring.used->idx); + desc_idx = (vq->vq_ring.used->idx + i) & (vq->vq_nentries - 1); + RPMSG_VIRTIO_INVALIDATE(vq->vq_ring.avail->ring[desc_idx]); + desc_idx = vq->vq_ring.avail->ring[desc_idx]; + } + else + { + RPMSG_VIRTIO_INVALIDATE(vq->vq_ring.avail->idx); + desc_idx = (vq->vq_ring.avail->idx + i) & (vq->vq_nentries - 1); + RPMSG_VIRTIO_INVALIDATE(vq->vq_ring.used->ring[desc_idx].id); + desc_idx = vq->vq_ring.used->ring[desc_idx].id; + } + + addr = metal_io_phys_to_virt(vq->shm_io, + vq->vq_ring.desc[desc_idx].addr); + if (addr) + { + FAR struct rpmsg_hdr *hdr = addr; + FAR struct rpmsg_endpoint *ept; + + ept = rpmsg_get_ept_from_addr(&rvdev->rdev, + rx ? hdr->dst : hdr->src); + if (ept) + { + metal_log(METAL_LOG_EMERGENCY, + " %s buffer %p hold by %s\n", + rx ? "RX" : "TX", hdr, ept->name); + } + } + } +} + +/**************************************************************************** + * Name: rpmsg_virtio_dump + ****************************************************************************/ + +static void rpmsg_virtio_dump(FAR struct rpmsg_s *rpmsg) +{ + FAR struct rpmsg_virtio_priv_s *priv = + (FAR struct rpmsg_virtio_priv_s *)rpmsg; + FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; + FAR struct rpmsg_device *rdev = rpmsg->rdev; + FAR struct rpmsg_endpoint *ept; + FAR struct metal_list *node; + bool needunlock = false; + + if (!rvdev->vdev) + { + return; + } + + if (!up_interrupt_context() && !sched_idletask() && + !metal_mutex_is_acquired(&rdev->lock)) + { + metal_mutex_acquire(&rdev->lock); + needunlock = true; + } + + metal_log(METAL_LOG_EMERGENCY, + "Dump rpmsg info between cpu (master: %s)%s <==> %s:\n", + rpmsg_virtio_get_role(rvdev) == RPMSG_HOST ? "yes" : "no", + priv->local_cpuname, priv->cpuname); + + metal_log(METAL_LOG_EMERGENCY, "rpmsg vq RX:\n"); + virtqueue_dump(rvdev->rvq); + metal_log(METAL_LOG_EMERGENCY, "rpmsg vq TX:\n"); + virtqueue_dump(rvdev->svq); + + metal_log(METAL_LOG_EMERGENCY, " rpmsg ept list:\n"); + + metal_list_for_each(&rdev->endpoints, node) + { + ept = metal_container_of(node, struct rpmsg_endpoint, node); + metal_log(METAL_LOG_EMERGENCY, " ept %s\n", ept->name); + } + + metal_log(METAL_LOG_EMERGENCY, " rpmsg buffer list:\n"); + + rpmsg_virtio_dump_buffer(rvdev, true); + rpmsg_virtio_dump_buffer(rvdev, false); + + if (needunlock) + { + metal_mutex_release(&rdev->lock); + } +} + +/**************************************************************************** + * Name: rpmsg_virtio_get_local_cpuname + ****************************************************************************/ + +static FAR const char * +rpmsg_virtio_get_local_cpuname(FAR struct rpmsg_s *rpmsg) +{ + FAR struct rpmsg_virtio_priv_s *priv = + (FAR struct rpmsg_virtio_priv_s *)rpmsg; + + return priv->local_cpuname; +} + +/**************************************************************************** + * Name: rpmsg_virtio_get_cpuname + ****************************************************************************/ + +static FAR const char *rpmsg_virtio_get_cpuname(FAR struct rpmsg_s *rpmsg) +{ + FAR struct rpmsg_virtio_priv_s *priv = + (FAR struct rpmsg_virtio_priv_s *)rpmsg; + + return priv->cpuname; +} + +/**************************************************************************** + * Name: rpmsg_virtio_rx_callback + ****************************************************************************/ + +static void rpmsg_virtio_rx_callback(FAR struct virtqueue *vq) +{ + FAR struct rpmsg_virtio_priv_s *priv = + metal_container_of(vq->vq_dev->priv, struct rpmsg_virtio_priv_s, rvdev); + + rpmsg_virtio_wakeup_rx(priv); +} + +/**************************************************************************** + * Name: rpmsg_virtio_tx_callback + ****************************************************************************/ + +static void rpmsg_virtio_tx_callback(FAR struct virtqueue *vq) +{ + FAR struct rpmsg_virtio_priv_s *priv = + metal_container_of(vq->vq_dev->priv, struct rpmsg_virtio_priv_s, rvdev); + + rpmsg_virtio_wakeup_tx(priv); +} + +/**************************************************************************** + * Name: rpmsg_virtio_notify_wait + ****************************************************************************/ + +static int rpmsg_virtio_notify_wait(FAR struct rpmsg_device *rdev, + uint32_t id) +{ + FAR struct rpmsg_virtio_priv_s *priv = (FAR struct rpmsg_virtio_priv_s *) + metal_container_of(rdev, struct rpmsg_s, rdev); + + if (!rpmsg_virtio_is_recursive(priv)) + { + return -EAGAIN; + } + + /* Wait to wakeup */ + + virtqueue_enable_cb(priv->rvdev.svq); + nxsem_tickwait(&priv->semtx, MSEC2TICK(20)); + virtqueue_disable_cb(priv->rvdev.svq); + priv->cbrx(priv->rvdev.rvq); + return 0; +} + +/**************************************************************************** + * Name: rpmsg_virtio_start + ****************************************************************************/ + +static int rpmsg_virtio_start(FAR struct rpmsg_virtio_priv_s *priv) +{ + FAR struct virtio_device *vdev = priv->vdev; + int ret; + + ret = rpmsg_init_vdev(&priv->rvdev, vdev, rpmsg_ns_bind, + metal_io_get_region(), priv->pool); + if (ret < 0) + { + rpmsgerr("rpmsg_init_vdev failed, ret=%d\n", ret); + return ret; + } + + priv->cbrx = priv->rvdev.rvq->callback; + priv->cbtx = priv->rvdev.svq->callback; + priv->rvdev.rvq->callback = rpmsg_virtio_rx_callback; + priv->rvdev.svq->callback = rpmsg_virtio_tx_callback; + priv->rvdev.notify_wait_cb = rpmsg_virtio_notify_wait; + priv->rvdev.rdev.ns_unbind_cb = rpmsg_ns_unbind; + + /* Wake up the rx thread to process message */ + + rpmsg_virtio_wakeup_rx(priv); + + /* Broadcast device_created to all registers */ + + rpmsg_device_created(&priv->rpmsg); + + return ret; +} + +/**************************************************************************** + * Name: rpmsg_virtio_thread + ****************************************************************************/ + +static int rpmsg_virtio_thread(int argc, FAR char *argv[]) +{ + FAR struct rpmsg_virtio_priv_s *priv = (FAR struct rpmsg_virtio_priv_s *) + ((uintptr_t)strtoul(argv[2], NULL, 16)); + int ret; + + priv->tid = nxsched_gettid(); + ret = rpmsg_virtio_start(priv); + if (ret < 0) + { + rpmsgerr("virtio rpmsg start failed, ret=%d\n", ret); + return ret; + } + + while (1) + { + nxsem_wait_uninterruptible(&priv->semrx); + priv->cbrx(priv->rvdev.rvq); + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rpmsg_virtio_probe + ****************************************************************************/ + +int rpmsg_virtio_probe(FAR struct virtio_device *vdev) +{ + FAR struct rpmsg_virtio_priv_s *priv; + FAR char *argv[3]; + uint64_t features; + char name[32]; + char arg1[32]; + int ret; + + priv = kmm_zalloc(sizeof(*priv)); + if (priv == NULL) + { + rpmsgerr("No enough memory\n"); + return -ENOMEM; + } + + priv->vdev = vdev; + nxsem_init(&priv->semrx, 0, 0); + nxsem_init(&priv->semtx, 0, 0); + + if (vdev->role == VIRTIO_DEV_DRIVER) + { + virtio_set_status(vdev, VIRTIO_CONFIG_STATUS_DRIVER); + virtio_negotiate_features(vdev, RPMSG_VIRTIO_FEATURES, NULL); + virtio_set_status(vdev, VIRTIO_CONFIG_FEATURES_OK); + } + else + { + virtio_get_features(vdev, &features); + } + + /* Read the virtio rpmsg config to get the local/remote cpu name */ + + DEBUGASSERT(virtio_has_feature(vdev, VIRTIO_RPMSG_F_CPUNAME)); + if (vdev->role == VIRTIO_DEV_DRIVER) + { + virtio_read_config(vdev, offsetof(struct fw_rsc_config, host_cpuname), + priv->local_cpuname, sizeof(priv->local_cpuname)); + virtio_read_config(vdev, + offsetof(struct fw_rsc_config, remote_cpuname), + priv->cpuname, sizeof(priv->cpuname)); + } + else + { + virtio_read_config(vdev, offsetof(struct fw_rsc_config, host_cpuname), + priv->cpuname, sizeof(priv->cpuname)); + virtio_read_config(vdev, + offsetof(struct fw_rsc_config, remote_cpuname), + priv->local_cpuname, sizeof(priv->local_cpuname)); + } + + /* Register the rpmsg to rpmsg framework */ + + snprintf(name, sizeof(name), "/dev/rpmsg/%s", priv->cpuname); + ret = rpmsg_register(name, &priv->rpmsg, &g_rpmsg_virtio_ops); + if (ret < 0) + { + rpmsgerr("rpmsg register failed, ret=%d\n", ret); + goto err; + } + + snprintf(arg1, sizeof(arg1), "%p", priv); + argv[0] = priv->cpuname; + argv[1] = arg1; + argv[2] = NULL; + ret = kthread_create("rpmsg-virtio", CONFIG_RPMSG_VIRTIO_PRIORITY, + CONFIG_RPMSG_VIRTIO_STACKSIZE, + rpmsg_virtio_thread, argv); + if (ret < 0) + { + rpmsgerr("kthread_create failed, ret=%d\n", ret); + goto err_kthread; + } + + priv->tid = ret; + return ret; + +err_kthread: + rpmsg_unregister(name, &priv->rpmsg); +err: + nxsem_destroy(&priv->semtx); + nxsem_destroy(&priv->semrx); + kmm_free(priv); + return ret; +} + +/**************************************************************************** + * Name: rpmsg_virtio_remove + ****************************************************************************/ + +void rpmsg_virtio_remove(FAR struct virtio_device *vdev) +{ + FAR struct rpmsg_virtio_priv_s *priv = + metal_container_of(vdev->priv, struct rpmsg_virtio_priv_s, rvdev); + char name[32]; + + /* Unregister the rpmsg */ + + snprintf(name, sizeof(name), "/dev/rpmsg/%s", priv->cpuname); + rpmsg_unregister(name, &priv->rpmsg); + + /* Disable tx buffer return callback */ + + virtqueue_disable_cb(priv->rvdev.svq); + + /* Destory all the rpmsg services */ + + rpmsg_device_destory(&priv->rpmsg); + + /* Reset the rpmsg virtio device for driver */ + + if (vdev->role == VIRTIO_DEV_DRIVER) + { + virtio_reset_device(vdev); + } + + /* Deinit the rpmsg virtio device */ + + rpmsg_deinit_vdev(&priv->rvdev); + + /* Delete the kthread */ + + kthread_delete(priv->tid); + + /* Free the private data */ + + kmm_free(priv); +} diff --git a/drivers/rpmsg/rpmsg_virtio_ivshmem.c b/drivers/rpmsg/rpmsg_virtio_ivshmem.c index e339dd5eb7bf9..c5ae98d2f8620 100644 --- a/drivers/rpmsg/rpmsg_virtio_ivshmem.c +++ b/drivers/rpmsg/rpmsg_virtio_ivshmem.c @@ -165,7 +165,6 @@ rpmsg_virtio_ivshmem_get_resource(FAR struct rpmsg_virtio_lite_s *dev) usleep(1000); } - cmd->cmd_master = 0; priv->addrenv[0].va = (uint64_t)(uintptr_t)priv->shmem; priv->addrenv[0].pa = priv->shmem->basem; priv->addrenv[0].size = priv->shmem_size; diff --git a/drivers/rptun/Kconfig b/drivers/rptun/Kconfig index eeda7de9bddd1..ef630068c24a6 100644 --- a/drivers/rptun/Kconfig +++ b/drivers/rptun/Kconfig @@ -7,6 +7,8 @@ menuconfig RPTUN bool "Remote Proc Tunnel Driver Support" default n select RPMSG + select DRIVERS_VIRTIO + select DRIVERS_VHOST ---help--- RPTUN driver is used for multi-cores' communication. @@ -68,21 +70,4 @@ config RPTUN_LOADER bool "rptun loader support" default n -config RPTUN_PM - bool "rptun power management" - depends on PM - default n - ---help--- - If TX/RX buffer is supplied and powered by each CPU. - And when one CPU in DEEP sleep, then it's buffer will - goto RAM-retention mode, can't access from another CPU. - So, we provide this method to resolve this. - -config RPTUN_PM_AUTORELAX - bool "rptun pm autorelax" - depends on RPTUN_PM - default y - ---help--- - use wd_timer to auto relax pm - endif # RPTUN diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c index 05cd4e43a140f..ac5b001f0acf7 100644 --- a/drivers/rptun/rptun.c +++ b/drivers/rptun/rptun.c @@ -26,36 +26,35 @@ #include -#include +#include +#include #include #include #include -#include -#include -#include +#include #include #include -#include +#include #include -#include #include -#include -#include +#include +#include #include #include -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define RPTUN_TIMEOUT_MS 20 +#include /**************************************************************************** * Private Types ****************************************************************************/ +struct rptun_carveout_s +{ + FAR struct mm_heap_s *heap; + FAR void *base; + size_t size; +}; + struct rptun_priv_s { struct rpmsg_s rpmsg; @@ -68,10 +67,6 @@ struct rptun_priv_s sem_t semrx; pid_t tid; uint16_t headrx; -#ifdef CONFIG_RPTUN_PM - struct pm_wakelock_s wakelock; - struct wdog_s wdog; -#endif }; struct rptun_store_s @@ -100,10 +95,11 @@ rptun_get_mem(FAR struct remoteproc *rproc, metal_phys_addr_t da, FAR void *va, size_t size, FAR struct remoteproc_mem *buf); -static int rptun_notify_wait(FAR struct rpmsg_device *rdev, uint32_t id); static int rptun_dev_start(FAR struct remoteproc *rproc); -static int rptun_dev_stop(FAR struct remoteproc *rproc, bool stop_ns); +static int rptun_dev_stop(FAR struct remoteproc *rproc); +static int rptun_dev_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); #ifdef CONFIG_RPTUN_LOADER static int rptun_store_open(FAR void *store_, FAR const char *path, @@ -121,14 +117,9 @@ static metal_phys_addr_t rptun_pa_to_da(FAR struct rptun_dev_s *dev, static metal_phys_addr_t rptun_da_to_pa(FAR struct rptun_dev_s *dev, metal_phys_addr_t da); -static int rptun_wait(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); -static int rptun_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem); -static int rptun_ioctl(FAR struct rpmsg_s *rpmsg, int cmd, - unsigned long arg); -static void rptun_panic(FAR struct rpmsg_s *rpmsg); -static void rptun_dump(FAR struct rpmsg_s *rpmsg); -static FAR const char *rptun_get_local_cpuname(FAR struct rpmsg_s *rpmsg); -static FAR const char *rptun_get_cpuname(FAR struct rpmsg_s *rpmsg); +static FAR void *rptun_alloc_buf(FAR struct virtio_device *vdev, + size_t size, size_t align); +static void rptun_free_buf(FAR struct virtio_device *vdev, FAR void *buf); /**************************************************************************** * Private Data @@ -145,6 +136,16 @@ static const struct remoteproc_ops g_rptun_ops = .get_mem = rptun_get_mem, }; +static const struct file_operations g_rptun_fops = +{ + NULL, /* open */ + NULL, /* close */ + NULL, /* read */ + NULL, /* write */ + NULL, /* seek */ + rptun_dev_ioctl, /* ioctl */ +}; + #ifdef CONFIG_RPTUN_LOADER static const struct image_store_ops g_rptun_store_ops = { @@ -155,15 +156,10 @@ static const struct image_store_ops g_rptun_store_ops = }; #endif -static const struct rpmsg_ops_s g_rptun_rpmsg_ops = +static const struct virtio_memory_ops g_rptun_mmops = { - rptun_wait, - rptun_post, - rptun_ioctl, - rptun_panic, - rptun_dump, - rptun_get_local_cpuname, - rptun_get_cpuname, + .alloc = rptun_alloc_buf, + .free = rptun_free_buf, }; static struct metal_list g_rptun_priv = METAL_INIT_LIST(g_rptun_priv); @@ -173,255 +169,6 @@ static metal_mutex_t g_rptun_lock = METAL_MUTEX_INIT(g_rptun_lock); * Private Functions ****************************************************************************/ -static int rptun_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, bool rx) -{ - FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq; - uint16_t nused; - bool is_host = rpmsg_virtio_get_role(rvdev) == RPMSG_HOST; - - if (is_host) - { - RPTUN_INVALIDATE(vq->vq_ring.used->idx); - } - else - { - RPTUN_INVALIDATE(vq->vq_ring.avail->idx); - } - - nused = vq->vq_ring.avail->idx - vq->vq_ring.used->idx; - if (is_host ^ rx) - { - return nused; - } - else - { - return vq->vq_nentries - nused; - } -} - -static void rptun_wakeup_tx(FAR struct rptun_priv_s *priv) -{ - int semcount; - - nxsem_get_value(&priv->semtx, &semcount); - while (semcount++ < 1) - { - nxsem_post(&priv->semtx); - } -} - -#ifdef CONFIG_RPTUN_PM - -#ifdef CONFIG_RPTUN_PM_AUTORELAX -static void rptun_pm_callback(wdparm_t arg) -{ - FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)arg; - - if (priv->rproc.state != RPROC_RUNNING) - { - return; - } - - if (rptun_buffer_nused(&priv->rvdev, false)) - { - rptun_wakeup_tx(priv); - - wd_start(&priv->wdog, MSEC2TICK(RPTUN_TIMEOUT_MS), - rptun_pm_callback, (wdparm_t)priv); - } - else - { - pm_wakelock_relax(&priv->wakelock); - } -} -#endif - -static inline void rptun_pm_action(FAR struct rptun_priv_s *priv, - bool stay) -{ - irqstate_t flags; - int count; - - flags = enter_critical_section(); - - count = pm_wakelock_staycount(&priv->wakelock); - if (stay && count == 0) - { - pm_wakelock_stay(&priv->wakelock); -#ifdef CONFIG_RPTUN_PM_AUTORELAX - wd_start(&priv->wdog, MSEC2TICK(RPTUN_TIMEOUT_MS), - rptun_pm_callback, (wdparm_t)priv); -#endif - } - -#ifndef CONFIG_RPTUN_PM_AUTORELAX - if (!stay && count > 0 && rptun_buffer_nused(&priv->rvdev, false) == 0) - { - pm_wakelock_relax(&priv->wakelock); - } -#endif - - leave_critical_section(flags); -} - -static inline bool rptun_available_rx(FAR struct rptun_priv_s *priv) -{ - FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; - FAR struct virtqueue *rvq = rvdev->rvq; - - if (priv->rproc.state != RPROC_RUNNING) - { - return false; - } - - if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) - { - return priv->headrx != rvq->vq_used_cons_idx; - } - else - { - return priv->headrx != rvq->vq_available_idx; - } -} - -#else -# define rptun_pm_action(priv, stay) -# define rptun_available_rx(priv) true -#endif - -static inline void rptun_update_rx(FAR struct rptun_priv_s *priv) -{ - FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; - FAR struct virtqueue *rvq = rvdev->rvq; - - if (priv->rproc.state != RPROC_RUNNING) - { - return; - } - - if (rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) - { - RPTUN_INVALIDATE(rvq->vq_ring.used->idx); - priv->headrx = rvq->vq_ring.used->idx; - } - else - { - RPTUN_INVALIDATE(rvq->vq_ring.avail->idx); - priv->headrx = rvq->vq_ring.avail->idx; - } -} - -static void rptun_start_worker(FAR void *arg) -{ - FAR struct rptun_priv_s *priv = arg; - - if (priv->rproc.state == RPROC_OFFLINE) - { - rptun_dev_start(&priv->rproc); - } -} - -static void rptun_worker(FAR void *arg) -{ - FAR struct rptun_priv_s *priv = arg; - - if (rptun_available_rx(priv)) - { - remoteproc_get_notification(&priv->rproc, RPTUN_NOTIFY_ALL); - } -} - -static int rptun_thread(int argc, FAR char *argv[]) -{ - FAR struct rptun_priv_s *priv; - - priv = (FAR struct rptun_priv_s *)((uintptr_t)strtoul(argv[2], NULL, 16)); - priv->tid = nxsched_gettid(); - - if (RPTUN_IS_AUTOSTART(priv->dev)) - { - rptun_start_worker(priv); - } - - while (1) - { - nxsem_wait_uninterruptible(&priv->semrx); - rptun_worker(priv); - } - - return 0; -} - -static void rptun_wakeup_rx(FAR struct rptun_priv_s *priv) -{ - int semcount; - - nxsem_get_value(&priv->semrx, &semcount); - if (semcount < 1) - { - nxsem_post(&priv->semrx); - } -} - -static bool rptun_is_recursive(FAR struct rptun_priv_s *priv) -{ - return nxsched_gettid() == priv->tid; -} - -static void rptun_command(FAR struct rptun_priv_s *priv) -{ - FAR struct rptun_cmd_s *rptun_cmd = RPTUN_RSC2CMD(priv->rproc.rsc_table); - uint32_t cmd; - - if (RPTUN_IS_MASTER(priv->dev)) - { - cmd = rptun_cmd->cmd_slave; - rptun_cmd->cmd_slave = 0; - } - else - { - cmd = rptun_cmd->cmd_master; - rptun_cmd->cmd_master = 0; - } - - switch (RPTUN_GET_CMD(cmd)) - { - case RPTUN_CMD_PANIC: - PANIC(); - break; - - default: - break; - } -} - -static int rptun_callback(FAR void *arg, uint32_t vqid) -{ - FAR struct rptun_priv_s *priv = arg; - FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; - FAR struct virtio_device *vdev = rvdev->vdev; - FAR struct virtqueue *svq = rvdev->svq; - FAR struct virtqueue *rvq = rvdev->rvq; - - rptun_command(priv); - - if (vqid == RPTUN_NOTIFY_ALL || - vqid == vdev->vrings_info[rvq->vq_queue_index].notifyid) - { - rptun_update_rx(priv); - rptun_wakeup_rx(priv); - } - - if (vqid == RPTUN_NOTIFY_ALL || - vqid == vdev->vrings_info[svq->vq_queue_index].notifyid) - { - rptun_wakeup_tx(priv); - rptun_pm_action(priv, false); - } - - return OK; -} - static FAR struct remoteproc * rptun_init(FAR struct remoteproc *rproc, FAR const struct remoteproc_ops *ops, @@ -477,15 +224,6 @@ static int rptun_stop(FAR struct remoteproc *rproc) static int rptun_notify(FAR struct remoteproc *rproc, uint32_t id) { FAR struct rptun_priv_s *priv = rproc->priv; - FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; - FAR struct virtio_device *vdev = rvdev->vdev; - FAR struct virtqueue *svq = rvdev->svq; - - if (priv->rproc.state == RPROC_RUNNING && - id == vdev->vrings_info[svq->vq_queue_index].notifyid) - { - rptun_pm_action(priv, true); - } RPTUN_NOTIFY(priv->dev, id); return 0; @@ -530,255 +268,337 @@ rptun_get_mem(FAR struct remoteproc *rproc, return buf; } -static int rptun_notify_wait(FAR struct rpmsg_device *rdev, uint32_t id) +/**************************************************************************** + * Name: rptun_alloc_buf + ****************************************************************************/ + +static FAR void *rptun_alloc_buf(FAR struct virtio_device *vdev, + size_t size, size_t align) { - FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *) - metal_container_of(rdev, struct rpmsg_s, rdev); + FAR struct rptun_carveout_s *carveout = + (FAR struct rptun_carveout_s *)vdev->mm_priv; - if (!rptun_is_recursive(priv)) - { - return RPMSG_EOPNOTSUPP; - } + return mm_memalign(carveout->heap, align, size); +} - /* Wait to wakeup */ +/**************************************************************************** + * Name: rptun_free_buf + ****************************************************************************/ - nxsem_tickwait(&priv->semtx, MSEC2TICK(RPTUN_TIMEOUT_MS)); - rptun_worker(priv); +static void rptun_free_buf(FAR struct virtio_device *vdev, FAR void *buf) +{ + FAR struct rptun_carveout_s *carveout = + (FAR struct rptun_carveout_s *)vdev->mm_priv; - return 0; + mm_free(carveout->heap, buf); } -static void rptun_dump_buffer(FAR struct rpmsg_virtio_device *rvdev, - bool rx) -{ - FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq; - FAR void *addr; - int desc_idx; - int num; - int i; +/**************************************************************************** + * Name: rptun_init_carveout + ****************************************************************************/ - num = rptun_buffer_nused(rvdev, rx); - metal_log(METAL_LOG_EMERGENCY, - " %s buffer, total %d, pending %d\n", - rx ? "RX" : "TX", vq->vq_nentries, num); +static int rptun_init_carveout(FAR struct rptun_priv_s *priv, + FAR struct virtio_device *vdev, + FAR const char *shmname, + FAR void *shmbase, size_t shmlen) +{ + FAR struct rptun_carveout_s *carveout; - for (i = 0; i < num; i++) + if (vdev->role == VIRTIO_DEV_DEVICE) { - if ((rpmsg_virtio_get_role(rvdev) == RPMSG_HOST) ^ rx) - { - RPTUN_INVALIDATE(vq->vq_ring.used->idx); - desc_idx = (vq->vq_ring.used->idx + i) & (vq->vq_nentries - 1); - RPTUN_INVALIDATE(vq->vq_ring.avail->ring[desc_idx]); - desc_idx = vq->vq_ring.avail->ring[desc_idx]; - } - else - { - RPTUN_INVALIDATE(vq->vq_ring.avail->idx); - desc_idx = (vq->vq_ring.avail->idx + i) & (vq->vq_nentries - 1); - RPTUN_INVALIDATE(vq->vq_ring.used->ring[desc_idx].id); - desc_idx = vq->vq_ring.used->ring[desc_idx].id; - } + return OK; + } - addr = metal_io_phys_to_virt(vq->shm_io, - vq->vq_ring.desc[desc_idx].addr); - if (addr) - { - FAR struct rpmsg_hdr *hdr = addr; - FAR struct rpmsg_endpoint *ept; + carveout = kmm_zalloc(sizeof(*carveout)); + if (carveout == NULL) + { + return -ENOMEM; + } - ept = rpmsg_get_ept_from_addr(&rvdev->rdev, - rx ? hdr->dst : hdr->src); - if (ept) - { - metal_log(METAL_LOG_EMERGENCY, - " %s buffer %p hold by %s\n", - rx ? "RX" : "TX", hdr, ept->name); - } - } + carveout->base = shmbase; + carveout->size = shmlen; + carveout->heap = mm_initialize(shmname, shmbase, shmlen); + if (carveout->heap == NULL) + { + kmm_free(carveout); + return -ENOMEM; } + + vdev->mmops = &g_rptun_mmops; + vdev->mm_priv = carveout; + + rptuninfo("caveouts=%p heap=%p name=%s base=%p size=%zu\n", + carveout, carveout->heap, shmname, shmbase, shmlen); + return OK; } -static int rptun_wait(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem) +/**************************************************************************** + * Name: rptun_uninit_carveout + ****************************************************************************/ + +static void rptun_uninit_carveout(FAR struct virtio_device *vdev) { - FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; - int ret; + FAR struct rptun_carveout_s *carveout = vdev->mm_priv; - if (!rptun_is_recursive(priv)) + if (vdev->role == VIRTIO_DEV_DEVICE) { - return nxsem_wait_uninterruptible(sem); + return; } - while (1) - { - ret = nxsem_trywait(sem); - if (ret >= 0) - { - break; - } + mm_uninitialize(carveout->heap); + kmm_free(carveout); +} - nxsem_wait(&priv->semtx); - rptun_worker(priv); - } +/**************************************************************************** + * Name: rptun_get_carveout_memory + ****************************************************************************/ - return ret; +static FAR void * +rptun_get_carveout_memory(FAR struct rptun_priv_s *priv, + FAR struct fw_rsc_carveout *carveout, + FAR size_t *size) +{ + metal_phys_addr_t da = carveout->da; + + *size = carveout->len; + return remoteproc_mmap(&priv->rproc, NULL, &da, carveout->len, 0, NULL); } -static int rptun_post(FAR struct rpmsg_s *rpmsg, FAR sem_t *sem) +/**************************************************************************** + * Name: rptun_create_device + ****************************************************************************/ + +static int rptun_create_device(FAR struct rptun_priv_s *priv, + FAR struct virtio_device **vdev_, int index) { - FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; - int semcount; + FAR struct fw_rsc_carveout *carveout_rsc; + FAR struct fw_rsc_vdev *vdev_rsc; + FAR struct virtio_device *vdev; + FAR char *rsc = priv->rproc.rsc_table; + FAR char *shmbase; + unsigned int role; + size_t shmlen; + size_t off; + uint8_t i; int ret; - nxsem_get_value(sem, &semcount); - ret = nxsem_post(sem); + off = find_rsc(rsc, RSC_VDEV, index); + if (off == 0) + { + return index ? -ENODEV : -EINVAL; + } + + vdev_rsc = (FAR struct fw_rsc_vdev *)(rsc + off); - if (priv && semcount >= 0) + off = find_rsc(rsc, RSC_CARVEOUT, index); + if (off == 0) { - rptun_wakeup_tx(priv); + return -EINVAL; } - return ret; -} + carveout_rsc = (FAR struct fw_rsc_carveout *)(rsc + off); -static int rptun_ioctl(FAR struct rpmsg_s *rpmsg, int cmd, unsigned long arg) -{ - FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; - int ret = OK; + /* Get virtio device role from virtio device resource table */ - switch (cmd) + role = RPTUN_IS_MASTER(priv->dev) ^ + (vdev_rsc->reserved[0] == VIRTIO_DEV_DRIVER); + + /* Get share memory from carveout resource table */ + + shmbase = rptun_get_carveout_memory(priv, carveout_rsc, &shmlen); + DEBUGASSERT(shmbase != NULL); + + /* Calculate the da of all vrings and assign back to the resource table */ + + for (i = 0; i < vdev_rsc->num_of_vrings; i++) { - case RPTUNIOC_START: - if (priv->rproc.state == RPROC_OFFLINE) - { - ret = rptun_dev_start(&priv->rproc); - } - else - { - ret = rptun_dev_stop(&priv->rproc, false); - if (ret == OK) - { - ret = rptun_dev_start(&priv->rproc); - } - } - break; - case RPTUNIOC_STOP: - ret = rptun_dev_stop(&priv->rproc, true); - break; - case RPTUNIOC_RESET: - RPTUN_RESET(priv->dev, arg); - break; - default: - ret = -ENOTTY; - break; - } + FAR struct fw_rsc_vdev_vring *vring = &vdev_rsc->vring[i]; + metal_phys_addr_t vring_da = METAL_BAD_PHYS; + metal_phys_addr_t vring_pa; + uint32_t vring_sz; - return ret; -} + vring_sz = ALIGN_UP(vring_size(vring->num, vring->align), + vring->align); + vring_pa = metal_io_virt_to_phys(metal_io_get_region(), shmbase); + remoteproc_mmap(&priv->rproc, &vring_pa, &vring_da, vring_sz, 0, NULL); -static void rptun_panic(FAR struct rpmsg_s *rpmsg) -{ - FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; - FAR struct rptun_cmd_s *cmd = RPTUN_RSC2CMD(priv->rproc.rsc_table); + rptuninfo("vr[%u] shm=%p len=%zu, da=0x%lx pa=0x%lx sz=%" PRIu32 "\n", + i, shmbase, shmlen, vring_da, vring_pa, vring_sz); - if (priv->dev->ops->panic != NULL) + if ((vring->da == 0 || vring->da == FW_RSC_U32_ADDR_ANY) && + role == VIRTIO_DEV_DRIVER) + { + vring->da = vring_da; + } + + shmbase += vring_sz; + shmlen -= vring_sz; + } + + vdev = remoteproc_create_virtio(&priv->rproc, index, role, NULL); + if (vdev == NULL) { - RPTUN_PANIC(priv->dev); - return; + return -ENOMEM; } - if (RPTUN_IS_MASTER(priv->dev)) + ret = rproc_virtio_set_shm_io(vdev, metal_io_get_region()); + if (ret < 0) { - cmd->cmd_master = RPTUN_CMD(RPTUN_CMD_PANIC, 0); + goto err; } - else + + ret = rptun_init_carveout(priv, vdev, (FAR const char *)carveout_rsc->name, + shmbase, shmlen); + if (ret < 0) { - cmd->cmd_slave = RPTUN_CMD(RPTUN_CMD_PANIC, 0); + goto err; } - rptun_notify(&priv->rproc, RPTUN_NOTIFY_ALL); + *vdev_ = vdev; + return OK; + +err: + remoteproc_remove_virtio(&priv->rproc, vdev); + return ret; } -static void rptun_dump(FAR struct rpmsg_s *rpmsg) +/**************************************************************************** + * Name: rptun_remove_device + ****************************************************************************/ + +static void rptun_remove_device(FAR struct rptun_priv_s *priv, + FAR struct virtio_device *vdev) { - FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; - FAR struct rpmsg_virtio_device *rvdev = &priv->rvdev; - FAR struct rpmsg_device *rdev = rpmsg->rdev; - FAR struct rpmsg_endpoint *ept; - FAR struct metal_list *node; - bool needlock = true; + rptun_uninit_carveout(vdev); + remoteproc_remove_virtio(&priv->rproc, vdev); +} - metal_log(METAL_LOG_EMERGENCY, "Remote: %s headrx %d\n", - RPTUN_GET_CPUNAME(priv->dev), priv->headrx); +/**************************************************************************** + * Name: rptun_register_device + ****************************************************************************/ - if (!rvdev->vdev) - { - return; - } +static int rptun_register_device(FAR struct virtio_device *vdev) +{ + int ret = -ENODEV; - if (up_interrupt_context() || sched_idletask()) + if (vdev->role == VIRTIO_DEV_DRIVER) { - needlock = false; + ret = virtio_register_device(vdev); + if (ret < 0) + { + rptunerr("virtio_register_device failed, ret=%d\n", ret); + return ret; + } } - - if (needlock) + else if (vdev->role == VIRTIO_DEV_DEVICE) { - metal_mutex_acquire(&rdev->lock); + ret = vhost_register_device(vdev); + if (ret < 0) + { + rptunerr("vhost_register_device failed, ret=%d\n", ret); + return ret; + } } - metal_log(METAL_LOG_EMERGENCY, - "Dump rpmsg info between cpu (master: %s)%s <==> %s:\n", - rpmsg_virtio_get_role(rvdev) == RPMSG_HOST ? "yes" : "no", - CONFIG_RPMSG_LOCAL_CPUNAME, rpmsg_get_cpuname(rdev)); - - metal_log(METAL_LOG_EMERGENCY, "rpmsg vq RX:\n"); - virtqueue_dump(rvdev->rvq); - metal_log(METAL_LOG_EMERGENCY, "rpmsg vq TX:\n"); - virtqueue_dump(rvdev->svq); + return ret; +} - metal_log(METAL_LOG_EMERGENCY, " rpmsg ept list:\n"); +/**************************************************************************** + * Name: rptun_unregister_device + ****************************************************************************/ - metal_list_for_each(&rdev->endpoints, node) +static void rptun_unregister_device(FAR struct virtio_device *vdev) +{ + if (vdev->role == VIRTIO_DEV_DRIVER) + { + virtio_unregister_device(vdev); + } + else if (vdev->role == VIRTIO_DEV_DEVICE) { - ept = metal_container_of(node, struct rpmsg_endpoint, node); - metal_log(METAL_LOG_EMERGENCY, " ept %s\n", ept->name); + vhost_unregister_device(vdev); } +} - metal_log(METAL_LOG_EMERGENCY, " rpmsg buffer list:\n"); +/**************************************************************************** + * Name: rptun_remove_devices + ****************************************************************************/ - rptun_dump_buffer(rvdev, true); - rptun_dump_buffer(rvdev, false); +static void rptun_remove_devices(FAR struct rptun_priv_s *priv) +{ + FAR struct remoteproc *rproc = &priv->rproc; + FAR struct remoteproc_virtio *rvdev; + FAR struct metal_list *node; + FAR struct metal_list *temp; - if (needlock) + metal_mutex_acquire(&rproc->lock); + metal_list_for_each_safe(&rproc->vdevs, temp, node) { - metal_mutex_release(&rdev->lock); + rvdev = metal_container_of(node, struct remoteproc_virtio, node); + rptun_unregister_device(&rvdev->vdev); + rptun_remove_device(priv, &rvdev->vdev); } + + metal_mutex_release(&rproc->lock); } -static FAR const char *rptun_get_local_cpuname(FAR struct rpmsg_s *rpmsg) +/**************************************************************************** + * Name: rptun_create_devices + ****************************************************************************/ + +static int rptun_create_devices(FAR struct rptun_priv_s *priv) { - FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; + FAR struct virtio_device *vdev; + int ret; + int i; + + for (i = 0; ; i++) + { + ret = rptun_create_device(priv, &vdev, i); + if (ret == -ENODEV) + { + rptuninfo("No more virtio devices, i=%d\n", i); + return OK; + } + else if (ret < 0) + { + rptunerr("rptun_create_device failed, ret=%d i=%d\n", ret, i); + goto err; + } + + ret = rptun_register_device(vdev); + if (ret < 0) + { + rptunerr("rptun_register_device failed, ret=%d i=%d\n", ret, i); + goto err_create; + } + } + + return ret; - return RPTUN_GET_LOCAL_CPUNAME(priv->dev); +err_create: + rptun_remove_device(priv, vdev); +err: + rptun_remove_devices(priv); + return ret; } -static FAR const char *rptun_get_cpuname(FAR struct rpmsg_s *rpmsg) +static int rptun_callback(FAR void *arg, uint32_t vqid) { - FAR struct rptun_priv_s *priv = (FAR struct rptun_priv_s *)rpmsg; + FAR struct rptun_priv_s *priv = arg; - return RPTUN_GET_CPUNAME(priv->dev); + return remoteproc_get_notification(&priv->rproc, vqid); } static int rptun_dev_start(FAR struct remoteproc *rproc) { FAR struct rptun_priv_s *priv = rproc->priv; - FAR struct virtio_device *vdev; - FAR struct rptun_rsc_s *rsc; - unsigned int role = RPMSG_REMOTE; + FAR struct resource_table *rsc; int ret; ret = remoteproc_config(rproc, NULL); - if (ret) + if (ret < 0) { + rptunerr("remoteproc config failed, ret=%d\n", ret); return ret; } @@ -792,8 +612,9 @@ static int rptun_dev_start(FAR struct remoteproc *rproc) ret = remoteproc_load(rproc, RPTUN_GET_FIRMWARE(priv->dev), &store, &g_rptun_store_ops, NULL); - if (ret) + if (ret < 0) { + rptunerr("remoteproc load failed, ret=%d\n", ret); return ret; } @@ -805,133 +626,36 @@ static int rptun_dev_start(FAR struct remoteproc *rproc) rsc = RPTUN_GET_RESOURCE(priv->dev); if (!rsc) { + rptunerr("RPTUN_GET_RESOURCE failed\n"); return -EINVAL; } ret = remoteproc_set_rsc_table(rproc, (struct resource_table *)rsc, sizeof(struct rptun_rsc_s)); - if (ret) + if (ret < 0) { + rptunerr("remoteproc set rsc_table failed, ret=%d\n", ret); return ret; } } - /* Update resource table on MASTER side */ - - if (RPTUN_IS_MASTER(priv->dev)) - { - uint32_t tbsz; - uint32_t v0sz; - uint32_t v1sz; - uint32_t shbufsz; - metal_phys_addr_t da0; - metal_phys_addr_t da1; - uint32_t align0; - uint32_t align1; - FAR void *va0; - FAR void *va1; - FAR void *shbuf; - FAR struct metal_io_region *io; - metal_phys_addr_t pa0; - metal_phys_addr_t pa1; - - align0 = rsc->rpmsg_vring0.align; - align1 = rsc->rpmsg_vring1.align; - - v0sz = ALIGN_UP(vring_size(rsc->rpmsg_vring0.num, align0), align0); - v1sz = ALIGN_UP(vring_size(rsc->rpmsg_vring1.num, align1), align1); - - if (rsc->rpmsg_vring0.da == 0 || - rsc->rpmsg_vring0.da == FW_RSC_U32_ADDR_ANY || - rsc->rpmsg_vring1.da == 0 || - rsc->rpmsg_vring1.da == FW_RSC_U32_ADDR_ANY) - { - tbsz = ALIGN_UP(sizeof(struct rptun_rsc_s), MAX(align0, align1)); - - va0 = (FAR char *)rsc + tbsz; - va1 = (FAR char *)rsc + tbsz + v0sz; + /* Create the virtio deivces according to resource table */ - io = metal_io_get_region(); - pa0 = metal_io_virt_to_phys(io, va0); - pa1 = metal_io_virt_to_phys(io, va1); - - da0 = da1 = METAL_BAD_PHYS; - - remoteproc_mmap(rproc, &pa0, &da0, v0sz, 0, NULL); - remoteproc_mmap(rproc, &pa1, &da1, v1sz, 0, NULL); - - rsc->rpmsg_vring0.da = da0; - rsc->rpmsg_vring1.da = da1; - - shbuf = (FAR char *)rsc + tbsz + v0sz + v1sz; - shbufsz = rsc->config.r2h_buf_size * rsc->rpmsg_vring0.num + - rsc->config.h2r_buf_size * rsc->rpmsg_vring1.num; - - rpmsg_virtio_init_shm_pool(priv->pool, shbuf, shbufsz); - } - else - { - da0 = rsc->rpmsg_vring0.da; - shbuf = (FAR char *)remoteproc_mmap(rproc, NULL, &da0, - v0sz, 0, NULL) + v0sz; - shbufsz = rsc->config.r2h_buf_size * rsc->rpmsg_vring0.num; - rpmsg_virtio_init_shm_pool(&priv->pool[0], shbuf, shbufsz); - - da1 = rsc->rpmsg_vring1.da; - shbuf = (FAR char *)remoteproc_mmap(rproc, NULL, &da1, - v1sz, 0, NULL) + v1sz; - shbufsz = rsc->config.h2r_buf_size * rsc->rpmsg_vring1.num; - rpmsg_virtio_init_shm_pool(&priv->pool[1], shbuf, shbufsz); - } - - role = RPMSG_HOST; - } - - /* Remote proc create */ - - vdev = remoteproc_create_virtio(rproc, 0, role, NULL); - if (!vdev) - { - return -ENOMEM; - } - - if (priv->pool[1].base) - { - struct rpmsg_virtio_config config = - { - RPMSG_BUFFER_SIZE, - RPMSG_BUFFER_SIZE, - true, - }; - - ret = rpmsg_init_vdev_with_config(&priv->rvdev, vdev, rpmsg_ns_bind, - metal_io_get_region(), - priv->pool, - &config); - } - else - { - ret = rpmsg_init_vdev(&priv->rvdev, vdev, rpmsg_ns_bind, - metal_io_get_region(), priv->pool); - } - - if (ret) + ret = rptun_create_devices(priv); + if (ret < 0) { - remoteproc_remove_virtio(rproc, vdev); + rptunerr("rptun_create_devices failed, ret=%d\n", ret); return ret; } - priv->rvdev.rdev.ns_unbind_cb = rpmsg_ns_unbind; - priv->rvdev.notify_wait_cb = rptun_notify_wait; - /* Remote proc start */ ret = remoteproc_start(rproc); - if (ret) + if (ret < 0) { - rpmsg_deinit_vdev(&priv->rvdev); - remoteproc_remove_virtio(rproc, vdev); + rptun_remove_devices(priv); remoteproc_shutdown(rproc); + rptunerr("remoteproc_start failed, ret=%d\n", ret); return ret; } @@ -939,21 +663,10 @@ static int rptun_dev_start(FAR struct remoteproc *rproc) RPTUN_REGISTER_CALLBACK(priv->dev, rptun_callback, priv); - rptun_update_rx(priv); - rptun_wakeup_rx(priv); - - /* Broadcast device_created to all registers */ - - rpmsg_device_created(&priv->rpmsg); - - /* Open tx buffer return callback */ - - virtqueue_enable_cb(priv->rvdev.svq); - return 0; } -static int rptun_dev_stop(FAR struct remoteproc *rproc, bool stop_ns) +static int rptun_dev_stop(FAR struct remoteproc *rproc) { FAR struct rptun_priv_s *priv = rproc->priv; FAR struct rpmsg_device *rdev = &priv->rvdev.rdev; @@ -969,10 +682,6 @@ static int rptun_dev_stop(FAR struct remoteproc *rproc, bool stop_ns) return -EBUSY; } - rdev->support_ns = stop_ns; - - /* Unregister callback from mbox */ - RPTUN_UNREGISTER_CALLBACK(priv->dev); rpmsg_device_destory(&priv->rpmsg); @@ -989,6 +698,86 @@ static int rptun_dev_stop(FAR struct remoteproc *rproc, bool stop_ns) return OK; } +static int rptun_do_ioctl(FAR struct rptun_priv_s *priv, int cmd, + unsigned long arg) +{ + int ret = OK; + + switch (cmd) + { + case RPTUNIOC_START: + if (priv->rproc.state == RPROC_OFFLINE) + { + ret = rptun_dev_start(&priv->rproc); + } + else + { + ret = rptun_dev_stop(&priv->rproc); + if (ret == OK) + { + ret = rptun_dev_start(&priv->rproc); + } + } + break; + case RPTUNIOC_STOP: + ret = rptun_dev_stop(&priv->rproc); + break; + case RPTUNIOC_RESET: + RPTUN_RESET(priv->dev, arg); + break; + case RPTUNIOC_PANIC: + RPTUN_PANIC(priv->dev); + break; + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +static int rptun_dev_ioctl(FAR struct file *filep, int cmd, + unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + return rptun_do_ioctl(inode->i_private, cmd, arg); +} + +static int rptun_ioctl_foreach(FAR const char *cpuname, int cmd, + unsigned long value) +{ + FAR struct metal_list *node; + int ret = OK; + + if (!up_interrupt_context()) + { + metal_mutex_acquire(&g_rptun_lock); + } + + metal_list_for_each(&g_rptun_priv, node) + { + FAR struct rptun_priv_s *priv; + + priv = metal_container_of(node, struct rptun_priv_s, node); + + if (!cpuname || !strcmp(RPTUN_GET_CPUNAME(priv->dev), cpuname)) + { + ret = rptun_do_ioctl(priv, cmd, value); + if (ret < 0) + { + break; + } + } + } + + if (!up_interrupt_context()) + { + metal_mutex_release(&g_rptun_lock); + } + + return ret; +} + #ifdef CONFIG_RPTUN_LOADER static int rptun_store_open(FAR void *store_, FAR const char *path, @@ -1117,6 +906,19 @@ static metal_phys_addr_t rptun_da_to_pa(FAR struct rptun_dev_s *dev, return da; } +static int rptun_start_thread(int argc, FAR char *argv[]) +{ + FAR struct rptun_priv_s *priv = + (FAR struct rptun_priv_s *)((uintptr_t)strtoul(argv[2], NULL, 16)); + + if (priv->rproc.state == RPROC_OFFLINE) + { + rptun_dev_start(&priv->rproc); + } + + return 0; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -1125,8 +927,8 @@ int rptun_initialize(FAR struct rptun_dev_s *dev) { FAR struct rptun_priv_s *priv; FAR char *argv[3]; - char arg1[32]; char name[32]; + char arg1[32]; int ret; priv = kmm_zalloc(sizeof(struct rptun_priv_s)); @@ -1136,28 +938,32 @@ int rptun_initialize(FAR struct rptun_dev_s *dev) } priv->dev = dev; - nxsem_init(&priv->semtx, 0, 0); - nxsem_init(&priv->semrx, 0, 0); - remoteproc_init(&priv->rproc, &g_rptun_ops, priv); snprintf(name, sizeof(name), "/dev/rptun/%s", RPTUN_GET_CPUNAME(dev)); - ret = rpmsg_register(name, &priv->rpmsg, &g_rptun_rpmsg_ops); + ret = register_driver(name, &g_rptun_fops, 0222, priv); if (ret < 0) { + rptunerr("rptun register driver faile %d\n", ret); goto err_driver; } + /* Create a thread to register the virtio and vhost devices */ + snprintf(arg1, sizeof(arg1), "%p", priv); argv[0] = (FAR char *)RPTUN_GET_CPUNAME(dev); argv[1] = arg1; argv[2] = NULL; - ret = kthread_create("rptun", CONFIG_RPTUN_PRIORITY, - CONFIG_RPTUN_STACKSIZE, rptun_thread, argv); - if (ret < 0) + if (RPTUN_IS_AUTOSTART(dev)) { - goto err_thread; + ret = kthread_create("rptun", CONFIG_RPTUN_PRIORITY, + CONFIG_RPTUN_STACKSIZE, rptun_start_thread, argv); + if (ret < 0) + { + rptunerr("rptun thread create failed %d\n", ret); + goto err_thread; + } } #ifdef CONFIG_RPTUN_PM @@ -1171,13 +977,9 @@ int rptun_initialize(FAR struct rptun_dev_s *dev) return OK; err_thread: - rpmsg_unregister(name, &priv->rpmsg); - + unregister_driver(name); err_driver: - nxsem_destroy(&priv->semtx); - nxsem_destroy(&priv->semrx); kmm_free(priv); - return ret; } diff --git a/drivers/rptun/rptun_bmp.c b/drivers/rptun/rptun_bmp.c index 719d8e1b8bfb5..ad1087f09bea6 100644 --- a/drivers/rptun/rptun_bmp.c +++ b/drivers/rptun/rptun_bmp.c @@ -55,7 +55,7 @@ struct rptun_bmp_dev_s static FAR const char *rptun_bmp_get_cpuname(FAR struct rptun_dev_s *dev); static struct -FAR rptun_rsc_s *rptun_bmp_get_resource(FAR struct rptun_dev_s *dev); +FAR resource_table *rptun_bmp_get_resource(FAR struct rptun_dev_s *dev); static bool rptun_bmp_is_autostart(FAR struct rptun_dev_s *dev); static bool rptun_bmp_is_master(FAR struct rptun_dev_s *dev); static int rptun_bmp_start(FAR struct rptun_dev_s *dev); @@ -92,11 +92,11 @@ static FAR const char *rptun_bmp_get_cpuname(FAR struct rptun_dev_s *dev) return priv->cpuname; } -static FAR struct rptun_rsc_s * +static FAR struct resource_table * rptun_bmp_get_resource(FAR struct rptun_dev_s *dev) { FAR struct rptun_bmp_dev_s *priv = (FAR struct rptun_bmp_dev_s *)dev; - return priv->rsc; + return &priv->rsc->rsc_tbl_hdr; } static bool rptun_bmp_is_autostart(FAR struct rptun_dev_s *dev) diff --git a/drivers/rptun/rptun_ivshmem.c b/drivers/rptun/rptun_ivshmem.c index 57f461774738a..b48e8907567fa 100644 --- a/drivers/rptun/rptun_ivshmem.c +++ b/drivers/rptun/rptun_ivshmem.c @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -194,7 +193,6 @@ rptun_ivshmem_get_resource(FAR struct rptun_dev_s *dev) rsc->config.h2r_buf_size = CONFIG_RPTUN_IVSHMEM_BUFFSIZE; priv->shmem->rsc_size = sizeof(struct rptun_rsc_s); - cmd->cmd_master = 0; cmd->cmd_slave = RPTUN_CMD(RPTUN_CMD_READY, 0); /* Wait until master is ready, slave needs to use master base to @@ -289,38 +287,6 @@ static int rptun_ivshmem_register_callback(FAR struct rptun_dev_s *dev, return 0; } -/**************************************************************************** - * Name: rptun_ivshmem_check_cmd - ****************************************************************************/ - -static void rptun_ivshmem_check_cmd(FAR struct rptun_ivshmem_dev_s *priv) -{ - FAR struct rptun_cmd_s *rptun_cmd = RPTUN_RSC2CMD(&priv->shmem->rsc); - uint32_t cmd; - - if (priv->master) - { - cmd = RPTUN_GET_CMD(rptun_cmd->cmd_slave); - rptun_cmd->cmd_slave = RPTUN_CMD(RPTUN_CMD_DEFAULT, 0); - } - else - { - cmd = RPTUN_GET_CMD(rptun_cmd->cmd_master); - rptun_cmd->cmd_master = RPTUN_CMD(RPTUN_CMD_DEFAULT, 0); - } - - switch (cmd) - { - case RPTUN_CMD_RESTART: -#ifdef CONFIG_BOARDCTL_RESET - board_reset(0); -#endif - break; - default: - break; - } -} - /**************************************************************************** * Name: rptun_ivshmem_interrupt ****************************************************************************/ @@ -329,8 +295,6 @@ static int rptun_ivshmem_interrupt(int irq, FAR void *context, FAR void *arg) { FAR struct rptun_ivshmem_dev_s *priv = arg; - rptun_ivshmem_check_cmd(priv); - if (priv->callback != NULL) { priv->callback(priv->arg, RPTUN_NOTIFY_ALL); @@ -349,8 +313,6 @@ static void rptun_ivshmem_wdog(wdparm_t arg) (FAR struct rptun_ivshmem_dev_s *)arg; bool should_notify = false; - rptun_ivshmem_check_cmd(priv); - if (priv->master && priv->seq != priv->shmem->seqs) { priv->seq = priv->shmem->seqs; diff --git a/include/nuttx/rpmsg/rpmsg_virtio.h b/include/nuttx/rpmsg/rpmsg_virtio.h new file mode 100644 index 0000000000000..5093ec43e7f32 --- /dev/null +++ b/include/nuttx/rpmsg/rpmsg_virtio.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * include/nuttx/rpmsg/rpmsg_virtio.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_RPMSG_RPMSG_VIRTIO_H +#define __INCLUDE_NUTTX_RPMSG_RPMSG_VIRTIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_RPMSG_VIRTIO + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int rpmsg_virtio_probe(FAR struct virtio_device *vdev); +void rpmsg_virtio_remove(FAR struct virtio_device *vdev); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_RPMSG_VIRTIO */ + +#endif /* __INCLUDE_NUTTX_RPMSG_RPMSG_VIRTIO_H */ diff --git a/include/nuttx/rptun/rptun.h b/include/nuttx/rptun/rptun.h index 94597506de1a1..904db963c75f9 100644 --- a/include/nuttx/rptun/rptun.h +++ b/include/nuttx/rptun/rptun.h @@ -40,20 +40,19 @@ * Pre-processor Definitions ****************************************************************************/ -#define _RPTUNIOCVALID(c) _RPMSGIOCVALID(c) -#define _RPTUNIOC(nr) _RPMSGIOC(nr) +#define _RPTUNIOCVALID(c) _RPMSGIOCVALID(c) +#define _RPTUNIOC(nr) _RPMSGIOC(nr) -#define RPTUNIOC_START _RPTUNIOC(100) -#define RPTUNIOC_STOP _RPTUNIOC(101) -#define RPTUNIOC_RESET _RPTUNIOC(102) +#define RPTUNIOC_START _RPTUNIOC(100) +#define RPTUNIOC_STOP _RPTUNIOC(101) +#define RPTUNIOC_RESET _RPTUNIOC(102) +#define RPTUNIOC_PANIC _RPTUNIOC(103) -#define RPTUN_NOTIFY_ALL (UINT32_MAX - 0) +#define RPTUN_NOTIFY_ALL (UINT32_MAX - 0) -#define RPTUN_CMD_DEFAULT 0x0 #define RPTUN_CMD_PANIC 0x1 #define RPTUN_CMD_STOP 0x2 #define RPTUN_CMD_READY 0x3 -#define RPTUN_CMD_RESTART 0x4 #define RPTUN_CMD_MASK 0xffff #define RPTUN_CMD_SHIFT 16 @@ -72,23 +71,6 @@ /* Access macros ************************************************************/ -/**************************************************************************** - * Name: RPTUN_GET_LOCAL_CPUNAME - * - * Description: - * Get local cpu name - * - * Input Parameters: - * dev - Device-specific state data - * - * Returned Value: - * Cpu name on success, NULL on failure. - * - ****************************************************************************/ - -#define RPTUN_GET_LOCAL_CPUNAME(d) ((d)->ops->get_local_cpuname ? \ - (d)->ops->get_local_cpuname(d) : "") - /**************************************************************************** * Name: RPTUN_GET_CPUNAME * @@ -353,24 +335,25 @@ begin_packed_struct struct rptun_cmd_s struct aligned_data(8) rptun_rsc_s { struct resource_table rsc_tbl_hdr; - uint32_t offset[2]; + uint32_t offset[3]; struct fw_rsc_trace log_trace; struct fw_rsc_vdev rpmsg_vdev; struct fw_rsc_vdev_vring rpmsg_vring0; struct fw_rsc_vdev_vring rpmsg_vring1; struct fw_rsc_config config; + struct fw_rsc_carveout carveout; }; struct rptun_dev_s; struct rptun_ops_s { - CODE FAR const char *(*get_local_cpuname)(FAR struct rptun_dev_s *dev); CODE FAR const char *(*get_cpuname)(FAR struct rptun_dev_s *dev); CODE FAR const char *(*get_firmware)(FAR struct rptun_dev_s *dev); CODE FAR const struct rptun_addrenv_s *(*get_addrenv)( FAR struct rptun_dev_s *dev); - CODE FAR struct rptun_rsc_s *(*get_resource)(FAR struct rptun_dev_s *dev); + CODE FAR struct resource_table *(*get_resource)( + FAR struct rptun_dev_s *dev); CODE bool (*is_autostart)(FAR struct rptun_dev_s *dev); CODE bool (*is_master)(FAR struct rptun_dev_s *dev); @@ -407,6 +390,7 @@ int rptun_initialize(FAR struct rptun_dev_s *dev); int rptun_boot(FAR const char *cpuname); int rptun_poweroff(FAR const char *cpuname); int rptun_reset(FAR const char *cpuname, int value); +int rptun_panic(FAR const char *cpuname); #ifdef __cplusplus }