]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blobdiff - packages/ti/ipc/family/omap54xx/VirtQueue.c
In VirtQueue_create, clear the VRING_USED_F_NO_NOTIFY flag to ensure all VirtQueue_ki...
[ipc/ipcdev.git] / packages / ti / ipc / family / omap54xx / VirtQueue.c
index ab0117399e720fe62a73a17577984220c74f0455..8c7dd5579828192ecd00f40484a158f0d240dc27 100644 (file)
@@ -61,8 +61,8 @@
 #include <xdc/runtime/Diags.h>
 
 #include <ti/sysbios/hal/Hwi.h>
-#include <ti/sysbios/knl/Semaphore.h>
 #include <ti/sysbios/knl/Clock.h>
+#include <ti/sysbios/gates/GateHwi.h>
 #include <ti/sysbios/BIOS.h>
 #include <ti/sysbios/hal/Cache.h>
 
@@ -169,8 +169,8 @@ enum {
 #define ID_A9_TO_SYSM3      ID_A9_TO_SELF
 #define ID_DSP_TO_A9        ID_SELF_TO_A9
 #define ID_A9_TO_DSP        ID_A9_TO_SELF
-#define ID_APPM3_TO_A9      200
-#define ID_A9_TO_APPM3      201
+#define ID_APPM3_TO_A9      2
+#define ID_A9_TO_APPM3      3
 
 typedef struct VirtQueue_Object {
     /* Id for this VirtQueue_Object */
@@ -193,6 +193,9 @@ typedef struct VirtQueue_Object {
 
     /* Will eventually be used to kick remote processor */
     UInt16                  procId;
+
+    /* Gate to protect from multiple threads */
+    GateHwi_Handle       gateH;
 } VirtQueue_Object;
 
 static struct VirtQueue_Object *queueRegistry[NUM_QUEUES] = {NULL};
@@ -211,11 +214,7 @@ extern Int OffloadM3_processSysM3Tasks(UArg msg);
 
 static inline Void * mapPAtoVA(UInt pa)
 {
-#ifndef DSPC674
-    return (Void *)((pa & 0x000fffffU) | 0xa0000000U);
-#else
-    return (Void *)((pa & 0x000fffffU) | 0x9fb00000U);
-#endif
+    return (Void *)((pa & 0x000fffffU) | IPC_MEM_VRING0);
 }
 
 static inline UInt mapVAtoPA(Void * va)
@@ -247,8 +246,11 @@ Void VirtQueue_kick(VirtQueue_Handle vq)
 Int VirtQueue_addUsedBuf(VirtQueue_Handle vq, Int16 head, Int len)
 {
     struct vring_used_elem *used;
+    IArg key;
 
+    key = GateHwi_enter(vq->gateH);
     if ((head > vq->vring.num) || (head < 0)) {
+        GateHwi_leave(vq->gateH, key);
         Error_raise(NULL, Error_E_generic, 0, 0);
     }
 
@@ -261,6 +263,7 @@ Int VirtQueue_addUsedBuf(VirtQueue_Handle vq, Int16 head, Int len)
     used->len = len;
 
     vq->vring.used->idx++;
+    GateHwi_leave(vq->gateH, key);
 
     return (0);
 }
@@ -271,6 +274,7 @@ Int VirtQueue_addUsedBuf(VirtQueue_Handle vq, Int16 head, Int len)
 Int VirtQueue_addAvailBuf(VirtQueue_Object *vq, Void *buf)
 {
     UInt16 avail;
+    IArg key;
 
     if (vq->num_free == 0) {
         /* There's no more space */
@@ -279,10 +283,12 @@ Int VirtQueue_addAvailBuf(VirtQueue_Object *vq, Void *buf)
 
     vq->num_free--;
 
+    key = GateHwi_enter(vq->gateH);
     avail =  vq->vring.avail->idx++ % vq->vring.num;
 
     vq->vring.desc[avail].addr = mapVAtoPA(buf);
     vq->vring.desc[avail].len = RP_MSG_BUF_SIZE;
+    GateHwi_leave(vq->gateH, key);
 
     return (vq->num_free);
 }
@@ -294,16 +300,20 @@ Void *VirtQueue_getUsedBuf(VirtQueue_Object *vq)
 {
     UInt16 head;
     Void *buf;
+    IArg key;
 
+    key = GateHwi_enter(vq->gateH);
     /* There's nothing available? */
     if (vq->last_used_idx == vq->vring.used->idx) {
-        return (NULL);
+        buf = NULL;
     }
+    else {
+        head = vq->vring.used->ring[vq->last_used_idx % vq->vring.num].id;
+        vq->last_used_idx++;
 
-    head = vq->vring.used->ring[vq->last_used_idx % vq->vring.num].id;
-    vq->last_used_idx++;
-
-    buf = mapPAtoVA(vq->vring.desc[head].addr);
+        buf = mapPAtoVA(vq->vring.desc[head].addr);
+    }
+    GateHwi_leave(vq->gateH, key);
 
     return (buf);
 }
@@ -313,8 +323,10 @@ Void *VirtQueue_getUsedBuf(VirtQueue_Object *vq)
  */
 Int16 VirtQueue_getAvailBuf(VirtQueue_Handle vq, Void **buf, Int *len)
 {
-    UInt16 head;
+    Int16 head;
+    IArg key;
 
+    key = GateHwi_enter(vq->gateH);
     Log_print6(Diags_USER1, "getAvailBuf vq: 0x%x %d %d %d 0x%x 0x%x\n",
         (IArg)vq, vq->last_avail_idx, vq->vring.avail->idx, vq->vring.num,
         (IArg)&vq->vring.avail, (IArg)vq->vring.avail);
@@ -323,17 +335,19 @@ Int16 VirtQueue_getAvailBuf(VirtQueue_Handle vq, Void **buf, Int *len)
     if (vq->last_avail_idx == vq->vring.avail->idx) {
         /* We need to know about added buffers */
         vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
-
-        return (-1);
+        head = (-1);
     }
-    /*
-     * Grab the next descriptor number they're advertising, and increment
-     * the index we've seen.
-     */
-    head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num];
-
-    *buf = mapPAtoVA(vq->vring.desc[head].addr);
-    *len = vq->vring.desc[head].len;
+    else {
+        /*
+         * Grab the next descriptor number they're advertising, and increment
+         * the index we've seen.
+         */
+        head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num];
+
+        *buf = mapPAtoVA(vq->vring.desc[head].addr);
+        *len = vq->vring.desc[head].len;
+    }
+    GateHwi_leave(vq->gateH, key);
 
     return (head);
 }
@@ -381,8 +395,11 @@ Void VirtQueue_isr(UArg msg)
 
             case (UInt)RP_MBOX_ABORT_REQUEST:
                 {
+                    /* Suppress Coverity Error: FORWARD_NULL: */
+                    // coverity[assign_zero]
                     Fxn f = (Fxn)0x0;
                     Log_print0(Diags_USER1, "Crash on demand ...\n");
+                    // coverity[var_deref_op]
                     f();
                 }
                 return;
@@ -473,7 +490,15 @@ VirtQueue_Handle VirtQueue_create(UInt16 remoteProcId, VirtQueue_Params *params,
     Void *vringAddr;
 
     vq = Memory_alloc(NULL, sizeof(VirtQueue_Object), 0, eb);
-    if (!vq) {
+    if (NULL == vq) {
+        return (NULL);
+    }
+
+    /* Create the thread protection gate */
+    vq->gateH = GateHwi_create(NULL, eb);
+    if (Error_check(eb)) {
+        Log_error0("VirtQueue_create: could not create gate object");
+        Memory_free(NULL, vq, sizeof(VirtQueue_Object));
         return (NULL);
     }
 
@@ -486,7 +511,7 @@ VirtQueue_Handle VirtQueue_create(UInt16 remoteProcId, VirtQueue_Params *params,
     if (MultiProc_self() == appm3ProcId) {
         /* vqindices that belong to AppM3 should be big so they don't
          * collide with SysM3's virtqueues */
-        vq->id += 200;
+         vq->id += 2;
     }
 #endif
 
@@ -510,12 +535,18 @@ VirtQueue_Handle VirtQueue_create(UInt16 remoteProcId, VirtQueue_Params *params,
             vringAddr = (struct vring *) IPC_MEM_VRING3;
             break;
 #endif
+        default:
+            GateHwi_delete(&vq->gateH);
+            Memory_free(NULL, vq, sizeof(VirtQueue_Object));
+            return (NULL);
     }
 
     Log_print3(Diags_USER1,
             "vring: %d 0x%x (0x%x)\n", vq->id, (IArg)vringAddr,
             RP_MSG_RING_SIZE);
 
+    /* See coverity related comment in vring_init() */
+    // coverity[overrun-call]
     vring_init(&(vq->vring), RP_MSG_NUM_BUFS, vringAddr, RP_MSG_VRING_ALIGN);
 
     /*
@@ -523,7 +554,7 @@ VirtQueue_Handle VirtQueue_create(UInt16 remoteProcId, VirtQueue_Params *params,
      *  available
      */
     if (vq->procId == hostProcId) {
-        vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
+        vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
     }
 
     queueRegistry[vq->id] = vq;
@@ -565,14 +596,6 @@ Void VirtQueue_postCrashToMailbox(Void)
     InterruptProxy_intSend(0, (UInt)RP_MSG_MBOX_CRASH);
 }
 
-/*!
- * ======== VirtQueue_postInitDone ========
- */
-Void VirtQueue_postInitDone(Void)
-{
-    InterruptProxy_intSend(0, (UInt)RP_MSG_BOOTINIT_DONE);
-}
-
 #define CACHE_WB_TICK_PERIOD    5
 
 /*!