OPBU Merge: Added MessageQCopy from omapzoom sysbios-rpmsg repo.
authorG Anthony <a0783926@ti.com>
Fri, 22 Feb 2013 01:51:50 +0000 (17:51 -0800)
committerG Anthony <a0783926@ti.com>
Tue, 26 Feb 2013 18:13:53 +0000 (10:13 -0800)
Source: omapzoom.org, sysbios-rpmsg repo, tag: 2.00.11.31.

See the git log there for this modules history.

Updated .gitignore to see new headers.

Updated config.bld to allow -gcc option for building rpmsg package.

Placed MessageQCopy_init() in a private _MessageQCopy.h header, as it
will be hidden from clients in an ipcmgr startup fxn.

Signed-off-by: G Anthony <a0783926@ti.com>
.gitignore
src/ti/ipc/rpmsg/MessageQCopy.c
src/ti/ipc/rpmsg/MessageQCopy.h
src/ti/ipc/rpmsg/Rpmsg.h
src/ti/ipc/rpmsg/_MessageQCopy.h [new file with mode: 0644]
src/ti/ipc/rpmsg/package.bld
src/ti/ipc/rpmsg/package.xs [new file with mode: 0644]

index 995bae27a45cb86170b88cc99431d979939026a2..fc5da2f11d5f3efffb92a8464693b3598265ce90 100644 (file)
@@ -45,3 +45,4 @@ packages/ti/ipc/transports/TransportVirtioSetup.h
 /linux/src/tests/MessageQMulti_*
 /linux/src/tests/NameServerApp_*
 /linux/src/tests/nano_test_*
+/linux/src/tests/ping_rpmsg_*
index 4f1122157b0c1b6139faad59d8435275e657f640..ee46b9cf9b35b9f7ee5ba50062e95d4efc3cb086 100644 (file)
 #include <ti/sdo/utils/List.h>
 #include <ti/ipc/MultiProc.h>
 
-#include "MessageQCopy.h"
-#include "VirtQueue.h"
+#include <ti/ipc/rpmsg/MessageQCopy.h>
+
+#include "_VirtQueue.h"
+
+/* TBD: VirtQueue.h needs to somehow get factored out of family directory .*/
+#if defined(OMAPL138)
+#include <ti/ipc/family/omapl138/VirtQueue.h>
+#elif defined(TCI6614)
+#include <ti/ipc/family/tci6614/VirtQueue.h>
+#elif defined(TCI6638)
+#include <ti/ipc/family/tci6638/VirtQueue.h>
+#else
+#error unknown processor!
+#endif
 
 /* =============================================================================
  * Structures & Enums
@@ -79,6 +91,8 @@
 typedef struct MessageQCopy_Object {
     UInt32           queueId;      /* Unique id (procId | queueIndex)       */
     Semaphore_Handle semHandle;    /* I/O Completion                        */
+    MessageQCopy_callback cb;      /* MessageQCopy Callback */
+    UArg             arg;          /* Callback argument */
     List_Handle      queue;        /* Queue of pending messages             */
     Bool             unblocked;    /* Use with signal to unblock _receive() */
 } MessageQCopy_Object;
@@ -134,7 +148,6 @@ static UInt8 recv_buffers[MAXHEAPSIZE];
 
 /* Module ref count: */
 static Int curInit = 0;
-extern Semaphore_Handle MessageQCopy_semHandle;
 
 /*
  *  ======== MessageQCopy_swiFxn ========
@@ -146,7 +159,7 @@ static Void MessageQCopy_swiFxn(UArg arg0, UArg arg1)
     MessageQCopy_Msg  msg;
     UInt16            dstProc = MultiProc_self();
     Bool              usedBufAdded = FALSE;
-    Int               len;
+    int len;
 
     Log_print0(Diags_ENTRY, "--> "FXNN);
 
@@ -158,12 +171,12 @@ static Void MessageQCopy_swiFxn(UArg arg0, UArg arg1)
                    "to: 0x%x, dataLen: %d",
                   (IArg)msg->srcAddr, (IArg)msg->dstAddr, (IArg)msg->dataLen);
 
-        /* Pass to desitination queue (which is on this proc): */
+        /* Pass to destination queue (on this proc), or callback: */
         MessageQCopy_send(dstProc, msg->dstAddr, msg->srcAddr,
                          (Ptr)msg->payload, msg->dataLen);
 
         VirtQueue_addUsedBuf(transport.virtQueue_fromHost, token,
-                                                            RP_MSG_BUF_SIZE);
+                                                            RPMSG_BUF_SIZE);
         usedBufAdded = TRUE;
     }
 
@@ -186,8 +199,8 @@ static Void callback_availBufReady(VirtQueue_Handle vq)
         Swi_post(transport.swiHandle);
     }
     else if (vq == transport.virtQueue_toHost) {
-       /* Note: We post nothing for transport.virtQueue_toHost, as we assume the
-        * host has already made all buffers available for sending.
+       /* Note: We normally post nothing for transport.virtQueue_toHost,
+        * unless we were starved for buffers, and we turned on notifications.
         */
         Semaphore_post(transport.semHandle_toHost);
         Log_print0(Diags_INFO, FXNN": virtQueue_toHost kicked");
@@ -212,8 +225,9 @@ Void MessageQCopy_init(UInt16 remoteProcId)
     HeapBuf_Params prms;
     int     i;
     Registry_Result result;
+    Bool    isHost;
+    VirtQueue_Params vqParams;
 
-    Semaphore_pend(MessageQCopy_semHandle, BIOS_WAIT_FOREVER);
     if (curInit++) {
         Log_print1(Diags_ENTRY, "--> "FXNN": (remoteProcId=%d)",
                     (IArg)remoteProcId);
@@ -249,31 +263,37 @@ Void MessageQCopy_init(UInt16 remoteProcId)
     }
     transport.semHandle_toHost = Semaphore_create(0, NULL, NULL);
 
+    isHost = (MultiProc_self() == MultiProc_getId("HOST"));
+
     /* Initialize Transport related objects: */
 
-    /*
-     * Plug Vring Interrupts, and create a pair VirtQueues (one for sending,
-     * one for receiving).
-     */
-    VirtQueue_startup();
+    VirtQueue_Params_init(&vqParams);
+    if (isHost)  {
+      /* We don't handle this case currently! Host would need to prime vq. */
+      Assert_isTrue(FALSE, NULL);
+    }
+    else {
+      vqParams.callback = (Fxn) callback_availBufReady;
+    }
 
     /*
-     * Note: order of these calls determines the virtqueue indices identifying
-     * the vrings toHost and fromHost:  toHost is first!
+     * Create a pair VirtQueues (one for sending, one for receiving).
+     * Note: First one gets an even, second gets odd vq ID.
      */
-    transport.virtQueue_toHost   = VirtQueue_create(callback_availBufReady,
-                                                    remoteProcId,
-                                                    ID_SELF_TO_A9);
-    transport.virtQueue_fromHost = VirtQueue_create(callback_availBufReady,
-                                                    remoteProcId,
-                                                    ID_A9_TO_SELF);
+    vqParams.vqId = ID_SELF_TO_A9;
+    transport.virtQueue_toHost   = (Ptr)VirtQueue_create(remoteProcId,
+                                                    &vqParams, NULL);
+    vqParams.vqId = ID_A9_TO_SELF;
+    transport.virtQueue_fromHost = (Ptr)VirtQueue_create(remoteProcId,
+                                                    &vqParams, NULL);
+
+    /* Plug Vring Interrupts, and wait for host ready to recv kick: */
+    VirtQueue_startup(remoteProcId, isHost);
 
     /* construct the Swi to process incoming messages: */
     transport.swiHandle = Swi_create(MessageQCopy_swiFxn, NULL, NULL);
 
 exit:
-    Semaphore_post(MessageQCopy_semHandle);
-
     Log_print0(Diags_EXIT, "<-- "FXNN);
 }
 #undef FXNN
@@ -286,7 +306,6 @@ Void MessageQCopy_finalize()
 {
     Log_print0(Diags_ENTRY, "--> "FXNN);
 
-    Semaphore_pend(MessageQCopy_semHandle, BIOS_WAIT_FOREVER);
     if (!curInit || --curInit) {
          goto exit; /* module still in use, or uninitialized */
     }
@@ -299,8 +318,6 @@ Void MessageQCopy_finalize()
     GateSwi_delete(&module.gateSwi);
 
 exit:
-    Semaphore_post(MessageQCopy_semHandle);
-
     Log_print0(Diags_EXIT, "<-- "FXNN);
 }
 #undef FXNN
@@ -309,7 +326,10 @@ exit:
  *  ======== MessageQCopy_create ========
  */
 #define FXNN "MessageQCopy_create"
-MessageQCopy_Handle MessageQCopy_create(UInt32 reserved, UInt32 * endpoint)
+MessageQCopy_Handle MessageQCopy_create(UInt32 reserved,
+                                        MessageQCopy_callback cb,
+                                        UArg arg,
+                                        UInt32 * endpoint)
 {
     MessageQCopy_Object    *obj = NULL;
     Bool                   found = FALSE;
@@ -317,8 +337,9 @@ MessageQCopy_Handle MessageQCopy_create(UInt32 reserved, UInt32 * endpoint)
     UInt16                 queueIndex = 0;
     IArg key;
 
-    Log_print2(Diags_ENTRY, "--> "FXNN": (reserved=%d, endpoint=0x%x)",
-                (IArg)reserved, (IArg)endpoint);
+    Log_print4(Diags_ENTRY, "--> "FXNN": "
+                "(reserved=%d, cb=0x%x, arg=0x%x, endpoint=0x%x)",
+                (IArg)reserved, (IArg)cb, (IArg)arg, (IArg)endpoint);
 
     Assert_isTrue((curInit > 0) , NULL);
 
@@ -344,11 +365,20 @@ MessageQCopy_Handle MessageQCopy_create(UInt32 reserved, UInt32 * endpoint)
     if (found)  {
        obj = Memory_alloc(NULL, sizeof(MessageQCopy_Object), 0, NULL);
        if (obj != NULL) {
-           /* Allocate a semaphore to signal when messages received: */
-           obj->semHandle = Semaphore_create(0, NULL, NULL);
+           if (cb) {
+               /* Store callback and it's arg instead of semaphore: */
+               obj->cb = cb;
+               obj->arg= arg;
+           }
+           else {
+               obj->cb = NULL;
 
-           /* Create our queue of to be received messages: */
-           obj->queue = List_create(NULL, NULL);
+               /* Allocate a semaphore to signal when messages received: */
+               obj->semHandle = Semaphore_create(0, NULL, NULL);
+
+               /* Create our queue of to be received messages: */
+               obj->queue = List_create(NULL, NULL);
+           }
 
            /* Store our endpoint, and object: */
            obj->queueId = queueIndex;
@@ -387,14 +417,20 @@ Int MessageQCopy_delete(MessageQCopy_Handle *handlePtr)
 
     if (handlePtr && (obj = (MessageQCopy_Object *)(*handlePtr)))  {
 
-       Semaphore_delete(&(obj->semHandle));
-
-       /* Free/discard all queued message buffers: */
-       while ((payload = (Queue_elem *)List_get(obj->queue)) != NULL) {
-           HeapBuf_free(module.heap, (Ptr)payload, MSGBUFFERSIZE);
+       if (obj->cb) {
+           obj->cb = NULL;
+           obj->arg= NULL;
        }
+       else {
+           Semaphore_delete(&(obj->semHandle));
 
-       List_delete(&(obj->queue));
+           /* Free/discard all queued message buffers: */
+           while ((payload = (Queue_elem *)List_get(obj->queue)) != NULL) {
+               HeapBuf_free(module.heap, (Ptr)payload, MSGBUFFERSIZE);
+           }
+
+           List_delete(&(obj->queue));
+       }
 
        /* Null out our slot: */
        key = GateSwi_enter(module.gateSwi);
@@ -432,6 +468,8 @@ Int MessageQCopy_recv(MessageQCopy_Handle handle, Ptr data, UInt16 *len,
                (IArg)len, (IArg)rplyEndpt, (IArg)timeout);
 
     Assert_isTrue((curInit > 0) , NULL);
+    /* A callback was set: client should not be calling this fxn! */
+    Assert_isTrue((!obj->cb), NULL);
 
     /* Check vring for pending messages before we block: */
     Swi_post(transport.swiHandle);
@@ -486,7 +524,7 @@ Int MessageQCopy_send(UInt16 dstProc,
     Queue_elem        *payload;
     UInt              size;
     IArg              key;
-    Int               length;
+    int length;
 
     Log_print5(Diags_ENTRY, "--> "FXNN": (dstProc=%d, dstEndpt=%d, "
                "srcEndpt=%d, data=0x%x, len=%d", (IArg)dstProc, (IArg)dstEndpt,
@@ -513,7 +551,7 @@ Int MessageQCopy_send(UInt16 dstProc,
             msg->reserved = 0;
 
             VirtQueue_addUsedBuf(transport.virtQueue_toHost, token,
-                                                            RP_MSG_BUF_SIZE);
+                                                            RPMSG_BUF_SIZE);
             VirtQueue_kick(transport.virtQueue_toHost);
         }
         else {
@@ -537,6 +575,14 @@ Int MessageQCopy_send(UInt16 dstProc,
             return status;
         }
 
+        /* If callback registered, call it: */
+        if (obj->cb) {
+            Log_print2(Diags_INFO, FXNN": calling callback with data len: "
+                            "%d, from: %d\n", len, srcEndpt);
+            obj->cb(obj, obj->arg, data, len, srcEndpt);
+        }
+        else {
+            /* else, put on a Message queue on this processor: */
         /* Allocate a buffer to copy the payload: */
         size = len + sizeof(Queue_elem);
 
@@ -557,6 +603,7 @@ Int MessageQCopy_send(UInt16 dstProc,
         else {
             status = MessageQCopy_E_MEMORY;
             Log_print0(Diags_STATUS, FXNN": HeapBuf_alloc failed!");
+            }
         }
     }
 
@@ -575,6 +622,7 @@ Void MessageQCopy_unblock(MessageQCopy_Handle handle)
 
     Log_print1(Diags_ENTRY, "--> "FXNN": (handle=0x%x)", (IArg)handle);
 
+    Assert_isTrue((!obj->cb), NULL);
     /* Set instance to 'unblocked' state, and post */
     obj->unblocked = TRUE;
     Semaphore_post(obj->semHandle);
index 7378553b2ace6b7c1124937c5ab3b685ac7f4f96..786462c564c0d81f2954f68daa990a96969b4404 100644 (file)
@@ -121,7 +121,7 @@ extern "C" {
 
 /*!
  *  @def    MessageQ_E_UNBLOCKED
- *  @brief  MessageQ was unblocked
+ *  @brief  MessageQCopy was unblocked
  */
 #define MessageQCopy_E_UNBLOCKED            -19
 
@@ -141,6 +141,10 @@ extern "C" {
  */
 typedef struct MessageQCopy_Object *MessageQCopy_Handle;
 
+
+typedef Void (*MessageQCopy_callback)(MessageQCopy_Handle, UArg, Ptr,
+                                      UInt16, UInt32);
+
 /* =============================================================================
  *  MessageQCopy Functions:
  * =============================================================================
@@ -148,41 +152,30 @@ typedef struct MessageQCopy_Object *MessageQCopy_Handle;
 
 
 /*!
- *  @brief      Initialize MessageQCopy Module
- *
- *  Note: Multiple clients must serialize calls to this function.
- *
- *  @param[in]  remoteProcId      MultiProc ID of the peer.
- */
-Void MessageQCopy_init(UInt16 remoteProcId);
-
-/*!
- *  @brief      Tear down MessageQCopy Module
- *
- */
-Void MessageQCopy_finalize();
-
-
-/*!
- *  @brief      Create a MessageQ instance for receiving.
+ *  @brief      Create a MessageQCopy instance for receiving, with callback.
  *
- *  The returned handle is to an object containing a queue for receiving
- *  messages from the transport, and a 32 bit endpoint ID unique to this local
- *  processor.
+ *  This is an extension of MessageQCopy_create(), with the option of passing
+ *  a callback function and its argument to be called when a message is
+ *  received.
  *
  *  @param[in]   reserved     If value is MessageQCopy_ASSIGN_ANY, then
  *                            any Endpoint can be assigned; otherwise, value is
  *                            a reserved Endpoint ID, which must be less than
  *                            or equal to MessageQCopy_MAX_RESERVED_ENDPOINT.
+ *  @param[in]   callback     If non-NULL, on received data, this callback is
+ *                            called instead of posting the internal semaphore.
+ *  @param[in]   arg          Argument for the callback.
  *  @param[out]  endpoint     Endpoint ID for this side of the connection.
  *
  *
- *  @return     MessageQ Handle, or NULL if:
+ *  @return     MessageQCopy Handle, or NULL if:
  *                            - reserved endpoint already taken;
  *                            - could not allocate object
  */
-MessageQCopy_Handle MessageQCopy_create(UInt32 reserved, UInt32 * endpoint);
-
+MessageQCopy_Handle MessageQCopy_create(UInt32 reserved,
+                                        MessageQCopy_callback callback,
+                                        UArg arg,
+                                        UInt32 * endpoint);
 /*!
  *  @brief      Receives a message from a message queue
  *
@@ -200,14 +193,14 @@ MessageQCopy_Handle MessageQCopy_create(UInt32 reserved, UInt32 * endpoint);
  *  data is copied into the data pointer, and a #MessageQCopy_S_SUCCESS
  *  status is returned.
  *
- *  @param[in]  handle      MessageQ handle
+ *  @param[in]  handle      MessageQCopy handle
  *  @param[out] data        Pointer to the client's data buffer.
  *  @param[out] len         Amount of data received.
  *  @param[out] rplyEndpt   Endpoint of source (for replies).
  *  @param[in]  timeout     Maximum duration to wait for a message in
  *                          microseconds.
  *
- *  @return     MessageQ status:
+ *  @return     MessageQCopy status:
  *              - #MessageQCopy_S_SUCCESS: Message successfully returned
  *              - #MessageQCopy_E_TIMEOUT: MessageQCopy_recv timed out
  *              - #MessageQCopy_E_UNBLOCKED: MessageQ_get was unblocked
@@ -243,7 +236,7 @@ Int MessageQCopy_send(UInt16 dstProc,
                       UInt16 len);
 
 /*!
- *  @brief      Delete a created MessageQ instance.
+ *  @brief      Delete a created MessageQCopy instance.
  *
  *  This function deletes a created message queue instance. If the
  *  message queue is non-empty, any messages remaining in the queue
@@ -251,7 +244,7 @@ Int MessageQCopy_send(UInt16 dstProc,
  *
  *  @param[in,out]  handlePtr   Pointer to handle to delete.
  *
- *  @return     MessageQ status:
+ *  @return     MessageQCopy status:
  *              - #MessageQCopy_E_FAIL: delete failed
  *              - #MessageQCopy_S_SUCCESS: delete successful, *handlePtr = NULL.
  */
index f4670ef0242d8d69d6718adbd6da920d26df3d5b..0de8140d2b18afb9677304f3f41fb2aeba0a22d5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Texas Instruments Incorporated
+ * Copyright (c) 2012-2013, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,7 @@
 extern "C" {
 #endif
 
+
 enum Rpmsg_nsFlags {
     RPMSG_NS_CREATE = 0,
     RPMSG_NS_DESTROY = 1
diff --git a/src/ti/ipc/rpmsg/_MessageQCopy.h b/src/ti/ipc/rpmsg/_MessageQCopy.h
new file mode 100644 (file)
index 0000000..86bcda5
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2011-2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** ============================================================================
+ *  @file       _MessageQCopy.h
+ *
+ *  @brief      Private header for MessageQCopy_init()/finalize().
+ *
+ *  ============================================================================
+ */
+
+#ifndef ti_ipc__MessageQCopy__include
+#define ti_ipc__MessageQCopy__include
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ *  @brief      Initialize MessageQCopy Module
+ *
+ *  Note: Multiple clients must serialize calls to this function.
+ *
+ *  @param[in]  remoteProcId      MultiProc ID of the peer.
+ */
+Void MessageQCopy_init(UInt16 remoteProcId);
+
+/*!
+ *  @brief      Tear down MessageQCopy Module
+ *
+ */
+Void MessageQCopy_finalize();
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+#endif /* ti_ipc__MessageQCopy__include */
index 79ad9d63b7f8f442f5327d961223c9e3a7a9acfa..2f5541888ff3958295f624ac3c8e08dba9ef94c5 100644 (file)
@@ -38,9 +38,10 @@ var Pkg = xdc.useModule('xdc.bld.PackageContents');
 
 Pkg.attrs.exportSrc = true;
 
-Pkg.otherFiles = ["package.bld", "Rpmsg.h", "virtio_ring.h", "MessageQCopy.h"];
+Pkg.otherFiles = ["package.bld", "Rpmsg.h", "virtio_ring.h", "_MessageQCopy.h",
+                        "MessageQCopy.h", "NameMap.h"];
 
-var SRCS = ["MessageQCopy.c"];
+var SRCS = ["MessageQCopy.c", "NameMap.c"];
 
 /* remove this output directory during a clean */
 Pkg.generatedFiles.$add("lib/");
diff --git a/src/ti/ipc/rpmsg/package.xs b/src/ti/ipc/rpmsg/package.xs
new file mode 100644 (file)
index 0000000..6d83368
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2011-2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  ======== package.xs ========
+ *
+ */
+
+/*
+ *  ======== close ========
+ */
+function close()
+{
+    Program.exportModule('ti.sysbios.hal.Cache');
+    Program.exportModule('ti.sysbios.knl.Idle');
+}
+
+/*
+ *  ======== getLibs ========
+ */
+function getLibs(prog)
+{
+    var suffix = prog.build.target.findSuffix(this);
+    if (suffix == null) {
+        /* no matching lib found in this package, return "" */
+        $trace("Unable to locate a compatible library, returning none.",
+                1, ['getLibs']);
+        return ("");
+    }
+
+    /* the location of the libraries are in lib/<profile>/* */
+    var name = this.$name + ".a" + suffix;
+    var lib = "lib/" + this.profile + "/" + name;
+
+
+    /*
+     * If the requested profile doesn't exist, we return the 'release' library.
+     */
+    if (!java.io.File(this.packageBase + lib).exists()) {
+        $trace("Unable to locate lib for requested '" + this.profile +
+                "' profile.  Using 'release' profile.", 1, ['getLibs']);
+        lib = "lib/release/" + name;
+    }
+
+    return (lib);
+}
+
+/*
+ *  ======== getLibs ========
+ */
+function getLibs_opbu(prog)
+{
+    var suffix;
+    var file;
+    var libAry = [];
+    var profile = this.profile;
+    var smp = "";
+
+    suffix = prog.build.target.findSuffix(this);
+    if (suffix == null) {
+        return "";  /* nothing to contribute */
+    }
+
+    if (prog.platformName.match(/ipu/)) {
+        smp = "_smp";
+    }
+
+    /* make sure the library exists, else fallback to a built library */
+    file = "lib/" + profile + "/ti.ipc.rpmsg" + smp + ".a" + suffix;
+    if (java.io.File(this.packageBase + file).exists()) {
+        libAry.push(file);
+    }
+    else {
+        file = "lib/release/ti.ipc.rpmsg" + smp + ".a" + suffix;
+        if (java.io.File(this.packageBase + file).exists()) {
+            libAry.push(file);
+        }
+        else {
+            /* fallback to a compatible library built by this package */
+            for (var p in this.build.libDesc) {
+                if (suffix == this.build.libDesc[p].suffix) {
+                    libAry.push(p);
+                    break;
+                }
+            }
+        }
+    }
+
+    return libAry.join(";");
+}