]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/commitdiff
VirtQueue: OMAPL138: Added Swi/Thread protection for vrings.
authorG Anthony <a0783926@ti.com>
Mon, 25 Mar 2013 18:32:46 +0000 (11:32 -0700)
committerG Anthony <a0783926@ti.com>
Mon, 1 Apr 2013 21:15:14 +0000 (14:15 -0700)
Uses GateAll, since protection is needed between Swis and Threads.

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

index 3c449e9d3be4b678fc5aec950546b94d77eeabc4..058f40d427fa80fbf4b215d11ca522a7f2a4dfe5 100644 (file)
@@ -61,6 +61,7 @@
 #include <xdc/runtime/Log.h>
 #include <xdc/runtime/Diags.h>
 #include <xdc/runtime/SysMin.h>
+#include <ti/sysbios/gates/GateAll.h>
 
 #include <ti/sysbios/knl/Clock.h>
 #include <ti/sysbios/hal/Cache.h>
@@ -123,19 +124,26 @@ static inline UInt mapVAtoPA(Void * va)
 /*
  * ======== VirtQueue_Instance_init ========
  */
-Void VirtQueue_Instance_init(VirtQueue_Object *vq, UInt16 remoteProcId,
-                             const VirtQueue_Params *params)
+Int VirtQueue_Instance_init(VirtQueue_Object *vq, UInt16 remoteProcId,
+                             const VirtQueue_Params *params, Error_Block *eb)
+
 {
     void *vringAddr = NULL;
-    Error_Block eb;
 
     VirtQueue_module->traceBufPtr = Resource_getTraceBufPtr();
 
-    Error_init(&eb);
+    /* Create the thread protection gate */
+    vq->gateH = GateAll_create(NULL, eb);
+    if (Error_check(eb)) {
+        Log_error0("VirtQueue_create: could not create gate object");
+        Error_raise(NULL, Error_E_generic, 0, 0);
+        return(0);
+    }
 
-    vq->vringPtr = Memory_calloc(NULL, sizeof(struct vring), 0, &eb);
+    vq->vringPtr = Memory_calloc(NULL, sizeof(struct vring), 0, eb);
     Assert_isTrue((vq->vringPtr != NULL), NULL);
 
+
     vq->callback = params->callback;
     vq->id = params->vqId;
     vq->procId = remoteProcId;
@@ -151,6 +159,12 @@ Void VirtQueue_Instance_init(VirtQueue_Object *vq, UInt16 remoteProcId,
         case ID_A9_TO_DSP:
             vringAddr = (struct vring *) IPU_MEM_VRING1;
             break;
+         default:
+            Log_error1("VirtQueue_create: invalid vq->id: %d", vq->id);
+            GateAll_delete(&vq->gateH);
+            Memory_free(NULL, vq->vringPtr, sizeof(struct vring));
+            Error_raise(NULL, Error_E_generic, 0, 0);
+            return(0);
     }
 
     Log_print3(Diags_USER1,
@@ -160,6 +174,7 @@ Void VirtQueue_Instance_init(VirtQueue_Object *vq, UInt16 remoteProcId,
     vring_init(vq->vringPtr, VirtQueue_RP_MSG_NUM_BUFS, vringAddr, VirtQueue_RP_MSG_VRING_ALIGN);
 
     queueRegistry[vq->id] = vq;
+    return(0);
 }
 
 /*
@@ -192,20 +207,24 @@ Int VirtQueue_addUsedBuf(VirtQueue_Handle vq, Int16 head, Int len)
 {
     struct vring_used_elem *used;
     struct vring *vring = vq->vringPtr;
+    IArg key;
 
+    key = GateAll_enter(vq->gateH);
     if ((head > vring->num) || (head < 0)) {
         Error_raise(NULL, Error_E_generic, 0, 0);
     }
-
-    /*
-    * The virtqueue contains a ring of used buffers.  Get a pointer to the
-    * next entry in that used ring.
-    */
-    used = &vring->used->ring[vring->used->idx % vring->num];
-    used->id = head;
-    used->len = len;
-
-    vring->used->idx++;
+    else {
+        /*
+         * The virtqueue contains a ring of used buffers.  Get a pointer to the
+         * next entry in that used ring.
+         */
+        used = &vring->used->ring[vring->used->idx % vring->num];
+        used->id = head;
+        used->len = len;
+
+        vring->used->idx++;
+    }
+    GateAll_leave(vq->gateH, key);
 
     return (0);
 }
@@ -217,18 +236,22 @@ Int VirtQueue_addAvailBuf(VirtQueue_Object *vq, Void *buf)
 {
     UInt16 avail;
     struct vring *vring = vq->vringPtr;
+    IArg key;
 
+    key = GateAll_enter(vq->gateH);
     if (vq->num_free == 0) {
         /* There's no more space */
         Error_raise(NULL, Error_E_generic, 0, 0);
     }
+    else {
+        vq->num_free--;
 
-    vq->num_free--;
+        avail =  vring->avail->idx++ % vring->num;
 
-    avail =  vring->avail->idx++ % vring->num;
-
-    vring->desc[avail].addr = mapVAtoPA(buf);
-    vring->desc[avail].len = RPMSG_BUF_SIZE;
+        vring->desc[avail].addr = mapVAtoPA(buf);
+        vring->desc[avail].len = RPMSG_BUF_SIZE;
+    }
+    GateAll_leave(vq->gateH, key);
 
     return (vq->num_free);
 }
@@ -241,17 +264,21 @@ Void *VirtQueue_getUsedBuf(VirtQueue_Object *vq)
     UInt16 head;
     Void *buf;
     struct vring *vring = vq->vringPtr;
+    IArg key;
 
+    key = GateAll_enter(vq->gateH);
     /* There's nothing available? */
     if (vq->last_used_idx == vring->used->idx) {
-        return (NULL);
+        buf = NULL;
     }
+    else {
+        head = vring->used->ring[vq->last_used_idx % vring->num].id;
+        vq->last_used_idx++;
+        vq->num_free++;
 
-    head = vring->used->ring[vq->last_used_idx % vring->num].id;
-    vq->last_used_idx++;
-    vq->num_free++;
-
-    buf = mapPAtoVA(vring->desc[head].addr);
+        buf = mapPAtoVA(vring->desc[head].addr);
+    }
+    GateAll_leave(vq->gateH, key);
 
     return (buf);
 }
@@ -261,9 +288,11 @@ Void *VirtQueue_getUsedBuf(VirtQueue_Object *vq)
  */
 Int16 VirtQueue_getAvailBuf(VirtQueue_Handle vq, Void **buf, Int *len)
 {
-    UInt16 head;
+    Int16 head;
     struct vring *vring = vq->vringPtr;
+    IArg key;
 
+    key = GateAll_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, vring->avail->idx, vring->num,
@@ -273,20 +302,22 @@ Int16 VirtQueue_getAvailBuf(VirtQueue_Handle vq, Void **buf, Int *len)
     if (vq->last_avail_idx == vring->avail->idx) {
         /* We need to know about added buffers */
         vring->used->flags &= ~VRING_USED_F_NO_NOTIFY;
-        return (-1);
+        head = (-1);
     }
-
-    /* No need to be kicked about added buffers anymore */
-    vring->used->flags |= VRING_USED_F_NO_NOTIFY;
-
-    /*
-     * Grab the next descriptor number they're advertising, and increment
-     * the index we've seen.
-     */
-    head = vring->avail->ring[vq->last_avail_idx++ % vring->num];
-
-    *buf = mapPAtoVA(vring->desc[head].addr);
-    *len = vring->desc[head].len;
+    else {
+        /* No need to be kicked about added buffers anymore */
+        vring->used->flags |= VRING_USED_F_NO_NOTIFY;
+
+        /*
+         * Grab the next descriptor number they're advertising, and increment
+         * the index we've seen.
+         */
+        head = vring->avail->ring[vq->last_avail_idx++ % vring->num];
+
+        *buf = mapPAtoVA(vring->desc[head].addr);
+        *len = vring->desc[head].len;
+    }
+    GateAll_leave(vq->gateH, key);
 
     return (head);
 }
@@ -381,5 +412,4 @@ Void VirtQueue_cacheWb()
     Assert_isTrue((VirtQueue_module->traceBufPtr != NULL), NULL);
     Cache_wb(VirtQueue_module->traceBufPtr, SysMin_bufSize, Cache_Type_ALL,
              FALSE);
-
 }
index 8c1a2c64ce26baeb635b4f820922863e8deadd15..f9d2e0a65bc3a7e224073f38be56511cdadd0945 100644 (file)
 
 import  ti.sysbios.knl.Swi;
 import  ti.sdo.utils.MultiProc;
+import  ti.sysbios.gates.GateAll;
 
 /*!
  *  ======== VirtQueue ========
  *
  */
 
+@InstanceInitError
 module VirtQueue
 {
     // -------- Module Constants --------
@@ -351,5 +353,6 @@ internal:   /* not for client use */
         UInt16 last_avail_idx;
         UInt16 last_used_idx;
         UInt16 procId;
+        GateAll.Handle gateH;
     };
 }
index e97e5cb4de96fde141c8dda149335a29da04ca5f..e92296e0604a798b8a335ade1c7958c22f7da998 100644 (file)
@@ -43,6 +43,7 @@ function module$use()
     xdc.useModule("ti.sysbios.knl.Swi");
     xdc.useModule("ti.sdo.ipc.family.da830.InterruptDsp");
     xdc.useModule("ti.ipc.remoteproc.Resource");
+    xdc.useModule("ti.sysbios.gates.GateAll");
 
     this.hostProcId = MultiProc.getIdMeta("HOST");
 }