]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/commitdiff
VirtQueue: Poll for VDEV status in VirtQueue_startup() to sync rpmsg on boot.
authorG Anthony <a0783926@ti.com>
Thu, 25 Jul 2013 23:43:45 +0000 (16:43 -0700)
committerRamsey Harris <ramsey@ti.com>
Tue, 6 Aug 2013 18:02:18 +0000 (11:02 -0700)
Previously, various methods (or none) have been implemented to ensure that
the slave has buffers available in the vring to the host before sending its
first message.

VirtQueue_startup() now polls the status bit in the VDEV struct of the Resource
table for a completion status, written by the host after the VDEV is created
successfully.

This resolves a race condition where the first slave RPMSG send would block
in a non-task context on a Semaphore_pend(), when the slave loads faster than
than the host can prime the send buffers in the vring to the host.

This patch implements the solution for Vayu separately.

Signed-off-by: G Anthony <a0783926@ti.com>
packages/ti/ipc/family/vayu/VirtQueue.c

index 80310820508d6b8ba5a0425b6f17a22782686f74..42e9b8680afe849481b3c27760f2cb7c80545698 100644 (file)
@@ -80,6 +80,8 @@
 #endif
 #include <string.h>
 
 #endif
 #include <string.h>
 
+#include <ti/ipc/remoteproc/Resource.h>
+#include <ti/ipc/remoteproc/rsc_types.h>
 #include <ti/ipc/rpmsg/_VirtQueue.h>
 
 #include <ti/sdo/ipc/notifyDrivers/IInterrupt.h>
 #include <ti/ipc/rpmsg/_VirtQueue.h>
 
 #include <ti/sdo/ipc/notifyDrivers/IInterrupt.h>
@@ -605,6 +607,17 @@ VirtQueue_Handle VirtQueue_create(UInt16 remoteProcId, VirtQueue_Params *params,
     return (vq);
 }
 
     return (vq);
 }
 
+/*
+ *  The following three VIRTIO_* defines must match those in
+ *  <Linux_kernel>/include/uapi/linux/virtio_config.h
+ */
+#define VIRTIO_CONFIG_S_ACKNOWLEDGE     1
+#define VIRTIO_CONFIG_S_DRIVER          2
+#define VIRTIO_CONFIG_S_DRIVER_OK       4
+
+#define VRING_BUFS_PRIMED  (VIRTIO_CONFIG_S_ACKNOWLEDGE | \
+                            VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK)
+
 /*!
  * ======== VirtQueue_startup ========
  */
 /*!
  * ======== VirtQueue_startup ========
  */
@@ -624,7 +637,22 @@ Void VirtQueue_startup()
     IpcPower_init();
 #endif
 
     IpcPower_init();
 #endif
 
+    /*
+     * Wait for HLOS (Virtio device) to indicate that priming of host's receive
+     * buffers is complete, indicating that host is ready to send.
+     *
+     * Though this is a Linux Virtio configuration status, it must be
+     * implemented by each non-Linux HLOS as well.
+     */
+    Log_print1(Diags_USER1, "VirtQueue_startup: VDEV status: 0x%x\n",
+              Resource_getVdevStatus(VIRTIO_ID_RPMSG));
+    Log_print0(Diags_USER1, "VirtQueue_startup: Polling VDEV status...\n");
+    while (Resource_getVdevStatus(VIRTIO_ID_RPMSG) != VRING_BUFS_PRIMED);
+    Log_print1(Diags_USER1, "VirtQueue_startup: VDEV status: 0x%x\n",
+              Resource_getVdevStatus(VIRTIO_ID_RPMSG));
+
     InterruptProxy_intRegister(hostProcId, &intInfo, (Fxn)VirtQueue_isr, NULL);
     InterruptProxy_intRegister(hostProcId, &intInfo, (Fxn)VirtQueue_isr, NULL);
+    Log_print0(Diags_USER1, "Passed VirtQueue_startup\n");
 }
 
 /*!
 }
 
 /*!