Skip to content

Commit

Permalink
risc-v/mpfs: ihc: don't wait for master if it's already up
Browse files Browse the repository at this point in the history
After rebooting this ihc client hart only, ihc will hang as it's
waiting for the initial handshake that just won't be there. Detect
this situation and let the rptun / ihc know the master is already
up. This makes the RPMSG bus usable even after NuttX reboot, in
case there's not much traffic. However, Linux is likely to mark
the virtio queue broken if there's descent amount of traffic. This
makes the bus no longer function.

Also deny uninitialized early access for particular structs.

Signed-off-by: Eero Nurkkala <[email protected]>
  • Loading branch information
eenurkka committed Sep 18, 2023
1 parent 364a80a commit 40abd9f
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions arch/risc-v/src/mpfs/mpfs_ihc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1236,6 +1239,13 @@ 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;
}

DEBUGASSERT((g_vq_idx - VRING0_NOTIFYID) < VRINGS);
info = &g_mpfs_virtqueue_table[g_vq_idx - VRING0_NOTIFYID];
virtqueue_notification((struct virtqueue *)info->data);
Expand Down Expand Up @@ -1266,6 +1276,13 @@ static int mpfs_rptun_thread(int argc, char *argv[])

while (1)
{
/* Check whether the struct is initialized yet */

if (*(uintptr_t *)&g_mpfs_virtqueue_table[0] == 0)
{
return 0;
}

DEBUGASSERT((g_vq_idx - VRING0_NOTIFYID) < VRINGS);
info = &g_mpfs_virtqueue_table[g_vq_idx - VRING0_NOTIFYID];
virtqueue_notification((struct virtqueue *)info->data);
Expand Down Expand Up @@ -1349,6 +1366,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)
{
Expand Down

0 comments on commit 40abd9f

Please sign in to comment.