diff --git a/arch/risc-v/src/mpfs/mpfs_ihc.c b/arch/risc-v/src/mpfs/mpfs_ihc.c index 037cb2de5cc80..cf68fcf35500f 100644 --- a/arch/risc-v/src/mpfs/mpfs_ihc.c +++ b/arch/risc-v/src/mpfs/mpfs_ihc.c @@ -905,9 +905,12 @@ mpfs_rptun_get_resource(struct rptun_dev_s *dev) rsc->rpmsg_vdev.gfeatures = 1 << VIRTIO_RPMSG_F_NS | 1 << VIRTIO_RPMSG_F_ACK; - /* Set to VIRTIO_CONFIG_STATUS_DRIVER_OK when master is up */ + /* If the master is up already, don't clear the status here */ - rsc->rpmsg_vdev.status = 0; + if (!g_shmem.master_up) + { + rsc->rpmsg_vdev.status = 0; + } rsc->rpmsg_vdev.config_len = sizeof(struct fw_rsc_config); rsc->rpmsg_vdev.num_of_vrings = VRINGS; @@ -1236,6 +1239,20 @@ static void mpfs_rptun_worker(void *arg) { struct mpfs_queue_table_s *info; + /* Check whether the struct is initialized yet */ + + if (*(uintptr_t *)&g_mpfs_virtqueue_table[0] == 0) + { + return; + } + + /* g_vq_idx may be temporarily illegal after a warm boot */ + + if ((g_vq_idx - VRING0_NOTIFYID) >= VRINGS) + { + return; + } + DEBUGASSERT((g_vq_idx - VRING0_NOTIFYID) < VRINGS); info = &g_mpfs_virtqueue_table[g_vq_idx - VRING0_NOTIFYID]; virtqueue_notification((struct virtqueue *)info->data); @@ -1266,7 +1283,20 @@ static int mpfs_rptun_thread(int argc, char *argv[]) while (1) { - DEBUGASSERT((g_vq_idx - VRING0_NOTIFYID) < VRINGS); + /* Check whether the struct is initialized yet */ + + if (*(uintptr_t *)&g_mpfs_virtqueue_table[0] == 0) + { + return 0; + } + + /* g_vq_idx may be temporarily illegal after a warm boot */ + + if ((g_vq_idx - VRING0_NOTIFYID) >= VRINGS) + { + return 0; + } + info = &g_mpfs_virtqueue_table[g_vq_idx - VRING0_NOTIFYID]; virtqueue_notification((struct virtqueue *)info->data); @@ -1349,6 +1379,18 @@ int mpfs_ihc_init(void) /* Initialize and wait for the master. This will block until. */ ihcinfo("Waiting for the master online...\n"); + + /* Check if the remote is already up. This is the case after reboot of + * this particular hart only. + */ + + if ((getreg32(MPFS_IHC_CTRL(CONTEXTA_HARTID, CONTEXTB_HARTID)) & (MPIE_EN + | ACKIE_EN)) != 0) + { + g_shmem.master_up = true; + g_shmem.rsc.rpmsg_vdev.status |= VIRTIO_CONFIG_STATUS_DRIVER_OK; + } + ret = mpfs_rptun_init(MPFS_RPTUN_SHMEM_NAME, MPFS_RPTUN_CPU_NAME); if (ret < 0) {