]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blobdiff - packages/ti/ipc/family/omap54xx/VirtQueue.c
VirtQueue: OMAP5: Poll for VDEV status in VirtQueue_startup()
[ipc/ipcdev.git] / packages / ti / ipc / family / omap54xx / VirtQueue.c
index 8c7dd5579828192ecd00f40484a158f0d240dc27..c055ada73ba895e589029bb95bfd5877a942ed79 100644 (file)
  *
  */
 
+/* this define must precede inclusion of any xdc header file */
+#define Registry_CURDESC ti_ipc_family_vayu__Desc
+#define MODULE_NAME "ti.ipc.family.omap54xx.VirtQueue"
+
 #include <xdc/std.h>
 #include <xdc/runtime/System.h>
+#include <xdc/runtime/Assert.h>
 #include <xdc/runtime/Error.h>
 #include <xdc/runtime/Memory.h>
+#include <xdc/runtime/Registry.h>
 #include <xdc/runtime/Log.h>
 #include <xdc/runtime/Diags.h>
 
 #include <ti/pm/IpcPower.h>
 #include <string.h>
 
+#include <ti/ipc/remoteproc/Resource.h>
+#include <ti/ipc/remoteproc/rsc_types.h>
 #include <ti/ipc/rpmsg/_VirtQueue.h>
 
 #include "InterruptProxy.h"
 #include "VirtQueue.h"
 
 
+/*
+ *  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)
+
 /* Used for defining the size of the virtqueue registry */
 #define NUM_QUEUES              4
 
@@ -198,6 +217,9 @@ typedef struct VirtQueue_Object {
     GateHwi_Handle       gateH;
 } VirtQueue_Object;
 
+/* module diags mask */
+Registry_Desc Registry_CURDESC;
+
 static struct VirtQueue_Object *queueRegistry[NUM_QUEUES] = {NULL};
 
 static UInt16 hostProcId;
@@ -212,6 +234,29 @@ extern Void OffloadM3_init();
 extern Int OffloadM3_processSysM3Tasks(UArg msg);
 #endif
 
+/*!
+ * ======== _VirtQueue_init ========
+ *
+ * This function adds the VirtQueue "module" to the Registry so that
+ * DIAGS will work with this non-XDC module.
+ * Since VirtQueue_init is not called by XDC-VirtQueue module clients, this
+ * function is called in the first VirtQueue fxn called: VirtQueue_create.
+ */
+static Void _VirtQueue_init()
+{
+    static int initialized = 0;
+
+    if (!initialized) {
+        Registry_Result result;
+
+        /* register with xdc.runtime to get a diags mask */
+        result = Registry_addModule(&Registry_CURDESC, MODULE_NAME);
+        Assert_isTrue(result == Registry_SUCCESS, (Assert_Id)NULL);
+
+        initialized = 1;
+    }
+}
+
 static inline Void * mapPAtoVA(UInt pa)
 {
     return (Void *)((pa & 0x000fffffU) | IPC_MEM_VRING0);
@@ -357,7 +402,7 @@ Int16 VirtQueue_getAvailBuf(VirtQueue_Handle vq, Void **buf, Int *len)
  */
 Void VirtQueue_disableCallback(VirtQueue_Object *vq)
 {
-    //TODO
+    /* TODO */
     Log_print0(Diags_USER1, "VirtQueue_disableCallback called.");
 }
 
@@ -368,7 +413,7 @@ Bool VirtQueue_enableCallback(VirtQueue_Object *vq)
 {
     Log_print0(Diags_USER1, "VirtQueue_enableCallback called.");
 
-    //TODO
+    /* TODO */
     return (FALSE);
 }
 
@@ -396,10 +441,10 @@ Void VirtQueue_isr(UArg msg)
             case (UInt)RP_MBOX_ABORT_REQUEST:
                 {
                     /* Suppress Coverity Error: FORWARD_NULL: */
-                    // coverity[assign_zero]
+                    /* coverity[assign_zero] */
                     Fxn f = (Fxn)0x0;
                     Log_print0(Diags_USER1, "Crash on demand ...\n");
-                    // coverity[var_deref_op]
+                    /* coverity[var_deref_op] */
                     f();
                 }
                 return;
@@ -489,6 +534,9 @@ VirtQueue_Handle VirtQueue_create(UInt16 remoteProcId, VirtQueue_Params *params,
     VirtQueue_Object *vq;
     Void *vringAddr;
 
+    /* Perform initialization we can't do in Instance_init (being non-XDC): */
+    _VirtQueue_init();
+
     vq = Memory_alloc(NULL, sizeof(VirtQueue_Object), 0, eb);
     if (NULL == vq) {
         return (NULL);
@@ -546,7 +594,7 @@ VirtQueue_Handle VirtQueue_create(UInt16 remoteProcId, VirtQueue_Params *params,
             RP_MSG_RING_SIZE);
 
     /* See coverity related comment in vring_init() */
-    // coverity[overrun-call]
+    /* coverity[overrun-call] */
     vring_init(&(vq->vring), RP_MSG_NUM_BUFS, vringAddr, RP_MSG_VRING_ALIGN);
 
     /*
@@ -585,7 +633,22 @@ Void VirtQueue_startup()
     }
 #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(VirtQueue_isr);
+    Log_print0(Diags_USER1, "Passed VirtQueue_startup\n");
 }
 
 /*!