host_linux: Add example for use case with host running linux
authorSam Nelson <sam.nelson@ti.com>
Mon, 22 May 2017 19:29:17 +0000 (15:29 -0400)
committerSam Nelson <sam.nelson@ti.com>
Fri, 2 Jun 2017 02:15:34 +0000 (22:15 -0400)
Uses local Shared region, Heapmem, Cache modules for linux

Signed-off-by: Sam Nelson <sam.nelson@ti.com>
50 files changed:
host_linux/simple_buffer_example/dsp/Dsp.cfg [new file with mode: 0644]
host_linux/simple_buffer_example/dsp/MainDsp.c [new file with mode: 0644]
host_linux/simple_buffer_example/dsp/Server.c [new file with mode: 0644]
host_linux/simple_buffer_example/dsp/Server.h [new file with mode: 0644]
host_linux/simple_buffer_example/dsp/makefile [new file with mode: 0644]
host_linux/simple_buffer_example/host/App.c [new file with mode: 0644]
host_linux/simple_buffer_example/host/App.h [new file with mode: 0644]
host_linux/simple_buffer_example/host/GateMutex.h [new file with mode: 0644]
host_linux/simple_buffer_example/host/HeapMem/HeapMem.h [new file with mode: 0644]
host_linux/simple_buffer_example/host/HeapMem/src/HeapMem.c [new file with mode: 0755]
host_linux/simple_buffer_example/host/HeapMem/src/inc/_HeapMem.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/IGateProvider.h [new file with mode: 0644]
host_linux/simple_buffer_example/host/SharedRegion/SharedRegion.h [new file with mode: 0644]
host_linux/simple_buffer_example/host/SharedRegion/src/SharedRegion.c [new file with mode: 0755]
host_linux/simple_buffer_example/host/SharedRegion/src/inc/_SharedRegion.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/Std.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/main_host.c [new file with mode: 0644]
host_linux/simple_buffer_example/host/makefile [new file with mode: 0644]
host_linux/simple_buffer_example/host/std_linux.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/Cache.c [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/Cache.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/IHeap.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/List.c [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/List.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/Memory.c [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/Memory.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/MemoryDefs.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/Trace.h [new file with mode: 0755]
host_linux/simple_buffer_example/host/utils/_MemoryDefs.h [new file with mode: 0755]
host_linux/simple_buffer_example/makefile [new file with mode: 0644]
host_linux/simple_buffer_example/products.mak [new file with mode: 0644]
host_linux/simple_buffer_example/readme.txt [new file with mode: 0644]
host_linux/simple_buffer_example/shared/66AK2E/config.bld [new file with mode: 0644]
host_linux/simple_buffer_example/shared/66AK2E/rsc_table_dsp.h [new file with mode: 0644]
host_linux/simple_buffer_example/shared/66AK2G/config.bld [new file with mode: 0644]
host_linux/simple_buffer_example/shared/66AK2G/rsc_table_dsp.h [new file with mode: 0644]
host_linux/simple_buffer_example/shared/AppCommon.h [new file with mode: 0644]
host_linux/simple_buffer_example/shared/DRA7XX/config.bld [new file with mode: 0644]
host_linux/simple_buffer_example/shared/DRA7XX/rsc_table_dsp.h [new file with mode: 0644]
host_linux/simple_buffer_example/shared/TCI6630/config.bld [new file with mode: 0644]
host_linux/simple_buffer_example/shared/TCI6630/rsc_table_dsp.h [new file with mode: 0644]
host_linux/simple_buffer_example/shared/TCI6636/config.bld [new file with mode: 0644]
host_linux/simple_buffer_example/shared/TCI6636/rsc_table_dsp.h [new file with mode: 0644]
host_linux/simple_buffer_example/shared/TCI6638/config.bld [new file with mode: 0644]
host_linux/simple_buffer_example/shared/TCI6638/rsc_table_dsp.h [new file with mode: 0644]
host_linux/simple_buffer_example/shared/bigdataxlat/bigdataxlat.c [new file with mode: 0644]
host_linux/simple_buffer_example/shared/bigdataxlat/bigdataxlat.h [new file with mode: 0644]
host_linux/simple_buffer_example/shared/bigdataxlat/bios/_bigdataxlat.h [new file with mode: 0644]
host_linux/simple_buffer_example/shared/bigdataxlat/linux/_bigdataxlat.h [new file with mode: 0644]
makefile

diff --git a/host_linux/simple_buffer_example/dsp/Dsp.cfg b/host_linux/simple_buffer_example/dsp/Dsp.cfg
new file mode 100644 (file)
index 0000000..a25c9cc
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2017 Texas Instruments Incorporated - http://www.ti.com
+ * 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.
+ */
+
+/*
+ *  ======== Dsp.cfg ========
+ *  Platform: DRA7XX_linux_elf
+ *  Target: ti.targets.elf.C66
+ */
+
+/* root of the configuration object model */
+var Program = xdc.useModule('xdc.cfg.Program');
+var cfgArgs = Program.build.cfgArgs;
+
+/* application uses the following modules and packages */
+xdc.useModule('xdc.runtime.Assert');
+xdc.useModule('xdc.runtime.Diags');
+xdc.useModule('xdc.runtime.Error');
+xdc.useModule('xdc.runtime.Log');
+xdc.useModule('xdc.runtime.Registry');
+
+xdc.useModule('ti.sysbios.knl.Semaphore');
+xdc.useModule('ti.sysbios.knl.Task');
+
+/*
+ *  ======== IPC Configuration ========
+ */
+xdc.useModule('ti.ipc.ipcmgr.IpcMgr');
+
+/* load the configuration shared across cores  */
+Program.global.procName = cfgArgs.procname;
+
+/* configure processor names */
+var procNameAry =  cfgArgs.procnamelist;
+
+var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
+MultiProc.setConfig(Program.global.procName, procNameAry);
+
+var BIOS        = xdc.useModule('ti.sysbios.BIOS');
+BIOS.addUserStartupFunction('&IpcMgr_ipcStartup');
+
+/*
+ *  ======== SYS/BIOS Configuration ========
+ */
+if (Program.build.profile == "debug") {
+    BIOS.libType = BIOS.LibType_Debug;
+} else {
+    BIOS.libType = BIOS.LibType_Custom;
+}
+
+/* no rts heap */
+Program.argSize = 100;  /* minimum size */
+Program.stack = 0x1000;
+
+var Task = xdc.useModule('ti.sysbios.knl.Task');
+Task.common$.namedInstance = true;
+
+/* default memory heap */
+var Memory = xdc.useModule('xdc.runtime.Memory');
+var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
+var heapMemParams = new HeapMem.Params();
+heapMemParams.size = 0x8000;
+Memory.defaultHeapInstance = HeapMem.create(heapMemParams);
+
+/* create a heap for MessageQ messages */
+var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');
+var params = new HeapBuf.Params;
+params.align = 8;
+params.blockSize = 512;
+params.numBlocks = 256;
+var msgHeap = HeapBuf.create(params);
+
+var MessageQ  = xdc.useModule('ti.sdo.ipc.MessageQ');
+MessageQ.registerHeapMeta(msgHeap, 0);
+
+/* Setup MessageQ transport */
+var VirtioSetup = xdc.useModule('ti.ipc.transports.TransportRpmsgSetup');
+MessageQ.SetupTransportProxy = VirtioSetup;
+
+/* Setup NameServer remote proxy */
+var NameServer = xdc.useModule("ti.sdo.utils.NameServer");
+var NsRemote = xdc.useModule("ti.ipc.namesrv.NameServerRemoteRpmsg");
+NameServer.SetupProxy = NsRemote;
+
+/* Enable Memory Translation module that operates on the BIOS Resource Table */
+var Resource = xdc.useModule('ti.ipc.remoteproc.Resource');
+Resource.loadSegment = Program.platform.codeMemory;
+/* Override default resource table to add CMEM memory section*/
+Resource.customTable = true;
+
+/*  Use SysMin because trace buffer address is required for Linux/QNX
+ *  trace debug driver, plus provides better performance.
+ */
+var System = xdc.useModule('xdc.runtime.System');
+var SysMin = xdc.useModule('ti.trace.SysMin');
+System.SupportProxy = SysMin;
+SysMin.bufSize  = 0x8000;
+
+Program.sectMap[".tracebuf"] = Program.platform.dataMemory;
+
+/* Add Shared Region module */
+var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
+
+/*
+ *  ======== Instrumentation Configuration ========
+ */
+
+/* system logger */
+var LoggerSys = xdc.useModule('xdc.runtime.LoggerSys');
+var LoggerSysParams = new LoggerSys.Params();
+var Defaults = xdc.useModule('xdc.runtime.Defaults');
+Defaults.common$.logger = LoggerSys.create(LoggerSysParams);
+
+/* enable runtime Diags_setMask() for non-XDC spec'd modules */
+var Diags = xdc.useModule('xdc.runtime.Diags');
+Diags.setMaskEnabled = true;
+
+/* override diags mask for selected modules */
+xdc.useModule('xdc.runtime.Main');
+Diags.setMaskMeta("xdc.runtime.Main",
+    Diags.ENTRY | Diags.EXIT | Diags.INFO, Diags.RUNTIME_ON);
+
+var Registry = xdc.useModule('xdc.runtime.Registry');
+Registry.common$.diags_ENTRY = Diags.RUNTIME_OFF;
+Registry.common$.diags_EXIT  = Diags.RUNTIME_OFF;
+Registry.common$.diags_INFO  = Diags.RUNTIME_OFF;
+Registry.common$.diags_USER1 = Diags.RUNTIME_OFF;
+Registry.common$.diags_LIFECYCLE = Diags.RUNTIME_OFF;
+Registry.common$.diags_STATUS = Diags.RUNTIME_OFF;
+
+var Main = xdc.useModule('xdc.runtime.Main');
+Main.common$.diags_ASSERT = Diags.ALWAYS_ON;
+Main.common$.diags_INTERNAL = Diags.ALWAYS_ON;
diff --git a/host_linux/simple_buffer_example/dsp/MainDsp.c b/host_linux/simple_buffer_example/dsp/MainDsp.c
new file mode 100644 (file)
index 0000000..fe58646
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ *  ======== main_Dsp1.c ========
+ *
+ */
+
+/* xdctools header files */
+#include <xdc/std.h>
+#include <xdc/runtime/Diags.h>
+#include <xdc/runtime/Error.h>
+#include <xdc/runtime/Log.h>
+#include <xdc/runtime/System.h>
+
+/* package header files */
+#include <ti/ipc/Ipc.h>
+#include <ti/sysbios/BIOS.h>
+#include <ti/sysbios/knl/Task.h>
+
+#include "rsc_table_dsp.h"
+
+/* local header files */
+#include "Server.h"
+
+/* private functions */
+static Void smain(UArg arg0, UArg arg1);
+
+
+/*
+ *  ======== main ========
+ */
+Int main(Int argc, Char* argv[])
+{
+    Error_Block     eb;
+    Task_Params     taskParams;
+
+    Log_print0(Diags_ENTRY, "--> main:");
+
+    /* must initialize the error block before using it */
+    Error_init(&eb);
+
+    /* create main thread (interrupts not enabled in main on BIOS) */
+    Task_Params_init(&taskParams);
+    taskParams.instance->name = "smain";
+    taskParams.arg0 = (UArg)argc;
+    taskParams.arg1 = (UArg)argv;
+    taskParams.stackSize = 0x1000;
+    Task_create(smain, &taskParams, &eb);
+
+    if (Error_check(&eb)) {
+        System_abort("main: failed to create application startup thread");
+    }
+
+    /* start scheduler, this never returns */
+    BIOS_start();
+
+    /* should never get here */
+    Log_print0(Diags_EXIT, "<-- main:");
+    return (0);
+}
+
+
+/*
+ *  ======== smain ========
+ */
+Void smain(UArg arg0, UArg arg1)
+{
+    Int                 status = 0;
+    Error_Block         eb;
+    Bool                running = TRUE;
+
+    Log_print0(Diags_ENTRY | Diags_INFO, "--> smain:");
+
+    Error_init(&eb);
+
+    /* initialize modules */
+    Server_init();
+
+    /* turn on Diags_INFO trace */
+    Diags_setMask("Server+F");
+
+    /* loop forever */
+    while (running) {
+
+        /* BEGIN server phase */
+
+        /* server setup phase */
+        status = Server_create();
+
+        if (status < 0) {
+            goto leave;
+        }
+
+        /* server execute phase */
+        status = Server_exec();
+
+        if (status < 0) {
+            goto leave;
+        }
+
+        Log_print0(Diags_INFO, "DSP: Test Passed");
+
+        /* server shutdown phase */
+        status = Server_delete();
+
+        if (status < 0) {
+            goto leave;
+        }
+
+        /* END server phase */
+
+    } /* while (running) */
+
+    /* finalize modules */
+    Server_exit();
+
+leave:
+    if (status < 0)
+        Log_print1(Diags_INFO, "DSP: Test Failed: %d", status);
+
+    Log_print1(Diags_EXIT, "<-- smain: %d", (IArg)status);
+    return;
+}
diff --git a/host_linux/simple_buffer_example/dsp/Server.c b/host_linux/simple_buffer_example/dsp/Server.c
new file mode 100644 (file)
index 0000000..c1b82fe
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/*
+ *  ======== Server.c ========
+ *
+ */
+
+/* this define must precede inclusion of any xdc header file */
+#define Registry_CURDESC Test__Desc
+#define MODULE_NAME "Server"
+
+/* xdctools header files */
+#include <xdc/std.h>
+#include <xdc/runtime/Assert.h>
+#include <xdc/runtime/Diags.h>
+#include <xdc/runtime/Log.h>
+#include <xdc/runtime/Registry.h>
+
+#include <stdio.h>
+
+/* package header files */
+#include <ti/ipc/MessageQ.h>
+#include <ti/ipc/MultiProc.h>
+#include <ti/ipc/SharedRegion.h>
+#include <ti/ipc/HeapMemMP.h>
+#include <ti/ipc/remoteproc/Resource.h>
+#include <ti/sysbios/hal/Cache.h>
+#include <xdc/runtime/IHeap.h>
+#include <xdc/runtime/Memory.h>
+
+#include <ti/sysbios/BIOS.h>
+#include <ti/sysbios/knl/Task.h>
+
+/* local header files */
+#include "../shared/AppCommon.h"
+
+/* module header file */
+#include "Server.h"
+
+/* module structure */
+typedef struct {
+    UInt16              hostProcId;         // host processor id
+    MessageQ_Handle     slaveQue;           // created locally
+} Server_Module;
+
+/* private data */
+Registry_Desc               Registry_CURDESC;
+static Server_Module        Module;
+
+/*
+ *  ======== Server_init ========
+ */
+Void Server_init(Void)
+{
+    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);
+
+    /* initialize module object state */
+    Module.hostProcId = MultiProc_getId("HOST");
+}
+
+/*
+ *  ======== Server_create ========
+ */
+Int Server_create()
+{
+    Int                 status = 0;
+    MessageQ_Params     msgqParams;
+    char                msgqName[32];
+
+    /* enable some log events */
+    Diags_setMask(MODULE_NAME"+EXF");
+
+    /* create local message queue (inbound messages) */
+    MessageQ_Params_init(&msgqParams);
+    sprintf(msgqName, App_SlaveMsgQueName, MultiProc_getName(MultiProc_self()));
+    Module.slaveQue = MessageQ_create(msgqName, &msgqParams);
+
+    if (Module.slaveQue == NULL) {
+        status = -1;
+        goto leave;
+    }
+
+    Log_print0(Diags_INFO,"Server_create: server is ready");
+
+leave:
+    Log_print1(Diags_EXIT, "<-- Server_create: %d", (IArg)status);
+    return (status);
+}
+
+/*
+ *  ======== Server_exec ========
+ */
+Int Server_exec()
+{
+    Int                 status;
+    Bool                running = TRUE;
+    App_Msg *           msg;
+    MessageQ_QueueId    queId;
+    UInt16  regionId1=1;
+    Uint32 *bigDataLocalPtr;
+    Int j;
+    UInt32 errorCount=0;
+    Int retVal;
+    bigDataLocalDesc_t bigDataLocalDesc;
+    SharedRegion_Entry srEntry;
+    void *sharedRegionAllocPtr=NULL;
+
+    Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_exec:");
+
+    while (running) {
+
+        /* wait for inbound message */
+        status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg,
+            MessageQ_FOREVER);
+
+        if (status < 0) {
+            goto leave;
+        }
+        Log_print1(Diags_ENTRY | Diags_INFO, "Message received...%d", msg->id);
+        switch (msg->cmd) {
+        case App_CMD_SHARED_REGION_INIT:
+            /* Create Shared region with information from init message */
+            /* Configure srEntry */
+            
+            status = Resource_physToVirt((UInt32)msg->u.sharedRegionInitCfg.base,
+                                         (UInt32 *)&sharedRegionAllocPtr);
+            if(status != Resource_S_SUCCESS) {
+                printf("Resource_physToVirt failed \n");
+                goto leave;
+            }
+            srEntry.base = sharedRegionAllocPtr;
+            srEntry.len = msg->u.sharedRegionInitCfg.size;
+            srEntry.ownerProcId = MultiProc_self();
+            srEntry.isValid = TRUE;
+            /* Make sure CacheEnable is TRUE if using cached memory */
+            srEntry.cacheEnable = TRUE;
+            srEntry.createHeap = FALSE;
+            srEntry.cacheLineSize = 128;
+            srEntry.name = "SR1";
+
+            status = SharedRegion_setEntry (regionId1, &srEntry);
+            Log_print0(Diags_ENTRY | Diags_INFO, "Shared region entry configured...");
+
+        break;
+
+        case App_CMD_BIGDATA:
+#ifdef DEBUG
+            Log_print1(Diags_ENTRY | Diags_INFO, "msg->cmd=App_CMD_BIGDATA,msg->ptr=0x%x",
+                (IArg)msg->u.bigDataSharedDesc.sharedPtr);
+#endif
+
+            /* Translate to local descriptor */
+            retVal = bigDataXlatetoLocalAndSync(regionId1,
+                &msg->u.bigDataSharedDesc, &bigDataLocalDesc);
+            if (retVal) {
+                status = -1;
+                goto leave;
+            }
+            bigDataLocalPtr = (Uint32 *)bigDataLocalDesc.localPtr;
+#ifdef DEBUG
+            /* print message from buffer */
+            Log_print1(Diags_INFO, " Received message %d", msg->id);
+            Log_print1(Diags_INFO, " Local Pointer 0x%x", (UInt32)bigDataLocalPtr);
+            Log_print0(Diags_INFO, " First 8 bytes: ");
+            for ( j = 0; j < 8 && j < bigDataLocalDesc.size/sizeof(uint32_t); j+=4)
+                Log_print4(Diags_INFO, "0x%x, 0x%x, 0x%x, 0x%x",
+                    bigDataLocalPtr[j], bigDataLocalPtr[j+1], bigDataLocalPtr[j+2], bigDataLocalPtr[j+3]);
+            Log_print0(Diags_INFO, " Last 8 bytes: ");
+            for ( j = (bigDataLocalDesc.size/sizeof(uint32_t))-8 ;
+                 j < bigDataLocalDesc.size/sizeof(uint32_t); j+=4)
+                Log_print4(Diags_INFO, "0x%x, 0x%x, 0x%x, 0x%x",
+                    bigDataLocalPtr[j], bigDataLocalPtr[j+1], bigDataLocalPtr[j+2], bigDataLocalPtr[j+3]);
+#endif
+            /* Check values to see expected results */
+            for( j=0; j < bigDataLocalDesc.size/sizeof(uint32_t); j++) {
+                if ( bigDataLocalPtr[j] != (msg->id+j) ) {
+                    errorCount++;
+                }
+            }
+
+            /* Fill new data */
+            for ( j=0; j < bigDataLocalDesc.size/sizeof(uint32_t); j++)
+                bigDataLocalPtr[j] = msg->id + 10 +j;
+
+            /* Translate to Shared Descriptor and Sync */
+            retVal = bigDataXlatetoGlobalAndSync(regionId1,
+                &bigDataLocalDesc, &msg->u.bigDataSharedDesc);
+            if (retVal) {
+                status = -1;
+                goto leave;
+            }    
+        break;
+
+        case App_CMD_SHUTDOWN:
+            running = FALSE;
+        break;
+
+        default:
+        break;
+        }
+
+        /* process the message */
+        Log_print2(Diags_INFO, "Server_exec: processed id %d, cmd=0x%x", msg->id, msg->cmd);
+
+        /* send message back */
+        queId = MessageQ_getReplyQueue(msg);
+        MessageQ_put(queId, (MessageQ_Msg)msg);
+    } /* while (running) */
+
+leave:
+    /* Print error count if non-zero */
+    if (errorCount) {
+        Log_print1(Diags_INFO, "Server_exec: Error Count %d", errorCount);
+        status = -1;
+    }
+    else
+        Log_print0(Diags_INFO, "Server_exec: Data check clean");
+
+    Log_print1(Diags_EXIT, "<-- Server_exec: %d", (IArg)status);
+    return(status);
+}
+
+/*
+ *  ======== Server_delete ========
+ */
+
+Int Server_delete()
+{
+    Int         status;
+
+    Log_print0(Diags_ENTRY, "--> Server_delete:");
+
+    /* delete the video message queue */
+    status = MessageQ_delete(&Module.slaveQue);
+
+    if (status < 0) {
+        goto leave;
+    }
+
+leave:
+    if (status < 0) {
+        Log_error1("Server_finish: error=0x%x", (IArg)status);
+    }
+
+    /* disable log events */
+    Log_print1(Diags_EXIT, "<-- Server_delete: %d", (IArg)status);
+    Diags_setMask(MODULE_NAME"-EXF");
+
+    return(status);
+}
+
+/*
+ *  ======== Server_exit ========
+ */
+
+Void Server_exit(Void)
+{
+    /*
+     * Note that there isn't a Registry_removeModule() yet:
+     *     https://bugs.eclipse.org/bugs/show_bug.cgi?id=315448
+     *
+     * ... but this is where we'd call it.
+     */
+}
diff --git a/host_linux/simple_buffer_example/dsp/Server.h b/host_linux/simple_buffer_example/dsp/Server.h
new file mode 100644 (file)
index 0000000..c09438f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+#  Copyright (c) 2012-2017 Texas Instruments Incorporated - http://www.ti.com
+ * 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.
+ */
+
+/*
+ *  ======== Server.h ========
+ */
+
+#ifndef Server__include
+#define Server__include
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+Void Server_init(Void);
+Void Server_exit(Void);
+
+Int Server_create(Void);
+Int Server_exec(Void);
+Int Server_delete(Void);
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+#endif /* Server__include */
diff --git a/host_linux/simple_buffer_example/dsp/makefile b/host_linux/simple_buffer_example/dsp/makefile
new file mode 100644 (file)
index 0000000..c600505
--- /dev/null
@@ -0,0 +1,164 @@
+#
+#  Copyright (c) 2017 Texas Instruments Incorporated - http://www.ti.com
+#  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.
+#
+
+#
+#  ======== makefile ========
+#
+
+EXBASE = ..
+include $(EXBASE)/products.mak
+
+srcs = MainDsp.c Server.c
+objs = $(addprefix bin/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.oe66,$(srcs)))
+CONFIG = bin/$(PLATFORM)/$(PROFILE)/configuro
+
+locallibsrcs = shared/bigdataxlat/bigdataxlat.c
+locallibobjs = $(addprefix bin/shared/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.oe66,$(locallibsrcs)))
+
+PKGPATH := $(BIOS_INSTALL_DIR)/packages
+PKGPATH := $(PKGPATH)+$(IPC_INSTALL_DIR)/packages
+PKGPATH := $(PKGPATH)+$(XDC_INSTALL_DIR)/packages
+
+-include $(addprefix bin/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.oe66.dep,$(srcs)))
+-include $(addprefix bin/shared/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.oe66.dep,$(locallibsrcs)))
+
+.PRECIOUS: %/compiler.opt %/linker.cmd
+.PHONY: release debug install server_dsp.x
+
+all: release
+
+debug:
+       $(MAKE) PROFILE=debug PROCLIST="$(PROCLIST)" server_dsp.x
+
+release:
+       $(MAKE) PROFILE=release PROCLIST="$(PROCLIST)" server_dsp.x
+
+server_dsp.x: bin/$(PLATFORM)/$(PROFILE)/server_dsp.xe66
+
+bin/$(PLATFORM)/$(PROFILE)/server_dsp.xe66: $(objs) $(locallibobjs) $(libs) $(CONFIG)/linker.cmd
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+       $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+
+bin/$(PLATFORM)/$(PROFILE)/obj/%.oe66: %.c $(CONFIG)/compiler.opt
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+       $(CC) $(CPPFLAGS) $(CFLAGS) --output_file=$@ -fc $<
+
+bin/shared/$(PLATFORM)/$(PROFILE)/obj/%.oe66: ../%.c $(CONFIG)/compiler.opt
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+       $(CC) $(CPPFLAGS) $(CFLAGS) --output_file=$@ -fc $<
+
+%/compiler.opt %/linker.cmd: Dsp.cfg ../shared/$(PLATFORM)/config.bld
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+       $(XDC_INSTALL_DIR)/xs --xdcpath="$(subst +,;,$(PKGPATH))" \
+            xdc.tools.configuro -o $(CONFIG) \
+            -t ti.targets.elf.C66 \
+            -c $(ti.targets.elf.C66) \
+            -p $(DSP_PLATFORM) \
+            -b ../shared/$(PLATFORM)/config.bld -r $(PROFILE) \
+            --cfgArgs "{ \
+                procnamelist: [$(PROC_NAME_LIST)], \
+                procname: \"$(PROC_DSP_NAME)\", \
+                profile: \"$(PROFILE)\" \
+            }" \
+            Dsp.cfg
+
+install:
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+#      @$(MKDIR) $(EXEC_DIR)/debug
+#      $(CP) bin/$(PLATFORM)/debug/server_dsp.xe66 $(EXEC_DIR)/debug
+       @$(MKDIR) $(EXEC_DIR)/release
+       $(CP) bin/$(PLATFORM)/release/server_dsp.xe66 $(EXEC_DIR)/release
+
+help:
+       @$(ECHO) "make                   # build executable"
+       @$(ECHO) "make clean             # clean everything"
+
+clean::
+       $(RMDIR) bin
+
+#  ======== install validation ========
+ifeq (install,$(MAKECMDGOALS))
+ifeq (,$(EXEC_DIR))
+$(error must specify EXEC_DIR)
+endif
+endif
+
+#  ======== toolchain macros ========
+CGTOOLS = $(ti.targets.elf.C66)
+
+CC = $(CGTOOLS)/bin/cl6x -c
+LD = $(CGTOOLS)/bin/cl6x -z
+
+CPPFLAGS =
+CFLAGS = -qq -pdsw225 -ppd=$@.dep -ppa $(CCPROFILE_$(PROFILE)) -@$(CONFIG)/compiler.opt -I.
+CFLAGS += -I../shared/$(PLATFORM) -I../shared/bigdataxlat -I../shared/bigdataxlat/bios
+
+# entry point is set to an aligned address so that IPC can load the slave
+LDFLAGS = -w -q -u _c_int00 -c -m $(@D)/obj/$(@F).map
+LDLIBS = -l $(CGTOOLS)/lib/libc.a
+
+CCPROFILE_debug = -D_DEBUG_=1 --symdebug:dwarf
+CCPROFILE_release = -O2
+
+#  ======== standard macros ========
+ifneq (,$(wildcard $(XDC_INSTALL_DIR)/xdc.exe))
+    # use these on Windows
+    CP      = $(XDC_INSTALL_DIR)/bin/cp
+    ECHO    = $(XDC_INSTALL_DIR)/bin/echo
+    MKDIR   = $(XDC_INSTALL_DIR)/bin/mkdir -p
+    RM      = $(XDC_INSTALL_DIR)/bin/rm -f
+    RMDIR   = $(XDC_INSTALL_DIR)/bin/rm -rf
+else
+    # use these on Linux
+    CP      = cp
+    ECHO    = echo
+    MKDIR   = mkdir -p
+    RM      = rm -f
+    RMDIR   = rm -rf
+endif
+
+#  ======== create output directories ========
+ifneq (clean,$(MAKECMDGOALS))
+ifneq (,$(PROFILE))
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj))
+    $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj)
+endif
+ifeq (,$(wildcard bin/shared/$(PLATFORM)/$(PROFILE)/obj/shared/bigdataxlat/bios))
+    $(shell $(MKDIR) -p bin/shared/$(PLATFORM)/$(PROFILE)/obj/shared/bigdataxlat/bios)
+endif
+endif
+endif
diff --git a/host_linux/simple_buffer_example/host/App.c b/host_linux/simple_buffer_example/host/App.c
new file mode 100644 (file)
index 0000000..720b91b
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2013-2017, 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.
+ */
+
+/*
+ *  ======== App.c ========
+ *
+ */
+
+/* host header files */
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <ti/cmem.h>
+
+/* package header files */
+#include <ti/ipc/Std.h>
+#include "Std.h"
+#include <ti/ipc/MessageQ.h>
+#include "HeapMem.h"
+#include "SharedRegion.h"
+#include "MemoryDefs.h"
+
+/* local header files */
+#include "../shared/AppCommon.h"
+#include "App.h"
+
+/* Application specific defines */
+#define BIG_DATA_POOL_SIZE 0x1000000
+
+/* round up the value 'size' to the next 'align' boundary */
+#define ROUNDUP(size, align) \
+    (UInt32)(((UInt32)(size) + ((UInt32)(align) - 1)) & ~((UInt32)(align) - 1))
+
+/* module structure */
+typedef struct {
+    MessageQ_Handle         hostQue;    // created locally
+    MessageQ_QueueId        slaveQue;   // opened remotely
+    UInt16                  heapId;     // MessageQ heapId
+    UInt32                  msgSize;
+} App_Module;
+
+/* private data */
+static App_Module Module;
+
+/*
+ *  ======== App_create ========
+ */
+
+Int App_create(UInt16 remoteProcId)
+{
+    Int                 status = 0;
+    MessageQ_Params     msgqParams;
+    char                msgqName[32];
+
+    printf("--> App_create:\n");
+
+    /* setting default values */
+    Module.hostQue = NULL;
+    Module.slaveQue = MessageQ_INVALIDMESSAGEQ;
+    Module.heapId = App_MsgHeapId;
+    Module.msgSize = sizeof(App_Msg);
+
+    /* create local message queue (inbound messages) */
+    MessageQ_Params_init(&msgqParams);
+
+    Module.hostQue = MessageQ_create(App_HostMsgQueName, &msgqParams);
+
+    if (Module.hostQue == NULL) {
+        printf("App_create: Failed creating MessageQ\n");
+        status = -1;
+        goto leave;
+    }
+
+    /* open the remote message queue */
+    sprintf(msgqName, App_SlaveMsgQueName, MultiProc_getName(remoteProcId));
+
+    do {
+        status = MessageQ_open(msgqName, &Module.slaveQue);
+        sleep(1);
+    } while (status == MessageQ_E_NOTFOUND);
+
+    if (status < 0) {
+        printf("App_create: Failed opening MessageQ\n");
+        goto leave;
+    }
+
+    printf("App_create: Host is ready\n");
+
+leave:
+    printf("<-- App_create:\n");
+    return(status);
+}
+
+/*
+ *  ======== App_delete ========
+ */
+Int App_delete(Void)
+{
+    Int         status;
+
+    printf("--> App_delete:\n");
+
+    /* close remote resources */
+    status = MessageQ_close(&Module.slaveQue);
+
+    if (status < 0) {
+        goto leave;
+    }
+
+    /* delete the host message queue */
+    status = MessageQ_delete(&Module.hostQue);
+
+    if (status < 0) {
+        goto leave;
+    }
+
+leave:
+    printf("<-- App_delete:\n");
+    return(status);
+}
+
+/*
+ *  ======== App_exec ========
+ */
+Int App_exec(Void)
+{
+    Int         status;
+    App_Msg *   msg;
+    UInt32 *bigDataLocalPtr;
+    Int         i,j;
+    UInt16  regionId1=1;
+    SharedRegion_Entry *pSrEntry;
+    void *sharedRegionAllocPtr=NULL;
+    Int pool_id;
+    CMEM_AllocParams cmemAttrs;
+    HeapMem_Handle sr1Heap;
+    UInt16 regionId;
+    UInt32 errorCount=0;
+    Int retVal;
+    bigDataLocalDesc_t bigDataLocalDesc;
+    SharedRegion_Config sharedRegionConfig;
+    SharedRegion_Entry srEntry;
+    HeapMem_Config HeapMemConfig;
+    HeapMem_Params heapMem_params;
+    Memory_Stats stats;
+    HeapMem_ExtendedStats extStats;
+
+    printf("--> App_exec:\n");
+
+    /* CMEM: contiguous memory manager for HLOS */
+    /* initialised here */
+    status = CMEM_init();
+
+    if (status < 0) {
+        printf("CMEM_init failed\n");
+        goto leave;
+    }
+    else {
+        printf("CMEM_init success\n");
+    }
+
+    pool_id = CMEM_getPool(BIG_DATA_POOL_SIZE);
+    if (pool_id < 0) {
+        printf("CMEM_getPool failed\n");
+        goto leave;
+    }
+    printf("CMEM_getPool success\n");
+
+    cmemAttrs.type = CMEM_HEAP;
+    cmemAttrs.flags =  CMEM_CACHED;
+    cmemAttrs.alignment = 0;
+    sharedRegionAllocPtr = CMEM_allocPool(pool_id, &cmemAttrs);
+    if (sharedRegionAllocPtr == NULL) {
+        printf("CMEM_allocPool failed\n");
+        goto leave;
+    }
+    printf("CMEM_allocPool success: Allocated buffer %p\n", sharedRegionAllocPtr);
+
+    /* Create shared region */
+    SharedRegion_getConfig (&sharedRegionConfig);
+    status = SharedRegion_setup (&sharedRegionConfig);
+    if (status < 0) {
+        printf("SharedRegion_setup failed\n");
+        goto leave;
+    }
+    printf("SharedRegion_setup success\n");
+
+    /* Configure srEntry */
+    srEntry.base = sharedRegionAllocPtr;
+    srEntry.len = BIG_DATA_POOL_SIZE;
+    srEntry.ownerProcId = MultiProc_self();
+    /* Make sure this is enabled if using Cached memory */
+    srEntry.isValid = TRUE;
+    srEntry.cacheEnable = TRUE;
+    srEntry.createHeap = FALSE;
+    srEntry.cacheLineSize = 128;
+    srEntry.name = "SR1";
+
+    status = SharedRegion_setEntry (regionId1, &srEntry);
+
+    pSrEntry = SharedRegion_getEntryPtr(regionId1);
+    printf("App_taskFxn: SR_1, base 0x%x, len=%x\n", (UInt32)pSrEntry->base, pSrEntry->len);
+
+    regionId = regionId1;
+
+    /* Setup HeapMem module */
+    HeapMem_getConfig (&HeapMemConfig);
+    status = HeapMem_setup (&HeapMemConfig);
+    if (status < 0) {
+        printf("HeapMem_setup failed\n");
+        goto leave;
+    }
+    printf("HeapMem_setup success\n");
+
+   /* Create HeapMP at run-time:
+       This heap is intended to be used for big data ipc */
+    HeapMem_Params_init(&heapMem_params);
+    heapMem_params.name = "sr1HeapMem";
+    heapMem_params.sharedAddr = pSrEntry->base;
+    heapMem_params.sharedBufSize = ROUNDUP(pSrEntry->len, pSrEntry->cacheLineSize); 
+    heapMem_params.gate = NULL;
+    sr1Heap = HeapMem_create(&heapMem_params);
+    if (!sr1Heap) {
+        printf("sr1Heap creation failed\n");
+        status = -1;
+        goto leave;
+    }
+    printf("HeapMem_create success\n");
+    HeapMem_getStats((HeapMem_Handle)sr1Heap, &stats);
+    printf("App_taskFxn: SR_1 heap, totalSize=%d,totalFreeSize=%d,largestFreeSize=%d\n", stats.totalSize, stats.totalFreeSize, stats.largestFreeSize);
+    HeapMem_getExtendedStats((HeapMem_Handle)sr1Heap, &extStats);
+    printf("App_taskFxn: SR_1 heap, buf=0x%p,size=%d\n", extStats.buf, extStats.size);
+
+    /* fill process pipeline */
+    for (i = 1; i <= 3; i++) {
+        printf("App_exec: sending message %d\n", i);
+
+        /* allocate message */
+        msg = (App_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
+
+        if (msg == NULL) {
+            status = -1;
+            goto leave;
+        }
+
+        /* set the return address in the message header */
+        MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
+
+        if ( i == 1) {
+            /* fill in message payload for Shared region init*/
+            msg->cmd = App_CMD_SHARED_REGION_INIT;
+            msg->id = i;
+            msg->regionId = regionId;
+            /* Passing the local shared memory address to the remote */
+            /* Actually this can be any allocated buffer for the used for the heap */
+            msg->u.sharedRegionInitCfg.base = CMEM_getPhys(pSrEntry->base);
+            printf("Shared memory phys Addr %llx\n", msg->u.sharedRegionInitCfg.base);
+            if (!msg->u.sharedRegionInitCfg.base) {
+                printf("CMEM_getPhys failed\n");
+            }
+            msg->u.sharedRegionInitCfg.size = (UInt64)(pSrEntry->len);
+        } else {
+            /* fill in message payload */
+            msg->cmd = App_CMD_NOP;
+            msg->id = i;
+       }
+
+        /* send message */
+        MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
+    }
+
+    /* process steady state (keep pipeline full) */
+    for (i = 4; i <= 16; i++) {
+
+        /* Now this section of code starts receiving messages
+           See the next section for the code for sending further messages */
+        /* Receive messages: Start <======================================= */
+
+        /* wait for return message */
+        status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
+            MessageQ_FOREVER);
+
+        if (status < 0) {
+            goto leave;
+        }
+
+        /* extract message payload */
+
+        if (msg->cmd == App_CMD_BIGDATA) {
+
+            retVal = bigDataXlatetoLocalAndSync(msg->regionId,
+                &msg->u.bigDataSharedDesc, &bigDataLocalDesc);
+            if (retVal) {
+                status = -1;
+                goto leave;
+            }
+            bigDataLocalPtr = (UInt32 *)bigDataLocalDesc.localPtr;
+#ifdef DEBUG
+            /* print data from big data buffer */
+            printf(" Received back buffer %d\n", msg->id);
+            printf(" First 8 bytes: \n");
+            for ( j = 0; j < 8 && j < bigDataLocalDesc.size/sizeof(uint32_t); j+=4)
+                printf("0x%x, 0x%x, 0x%x, 0x%x\n",
+                    bigDataLocalPtr[j], bigDataLocalPtr[j+1], bigDataLocalPtr[j+2], bigDataLocalPtr[j+3]);
+            printf(" Last 8 bytes: \n");
+            for ( j = (bigDataLocalDesc.size/sizeof(uint32_t))-8 ;
+                 j < bigDataLocalDesc.size/sizeof(uint32_t); j+=4)
+                printf("0x%x, 0x%x, 0x%x, 0x%x\n",
+                    bigDataLocalPtr[j], bigDataLocalPtr[j+1], bigDataLocalPtr[j+2], bigDataLocalPtr[j+3]);
+#endif
+            /* Check values to see expected results */
+            for( j=0; j < bigDataLocalDesc.size/sizeof(uint32_t); j++) {
+                if ( bigDataLocalPtr[j] != (msg->id+10+j) ) {
+                    errorCount++;
+                }
+            }
+
+            /* Free big data buffer */
+            HeapMem_free(sr1Heap, bigDataLocalPtr, bigDataLocalDesc.size);
+        }
+
+        printf("App_exec: message received %d\n", msg->id);
+
+        /* free the message */
+        MessageQ_free((MessageQ_Msg)msg);
+
+        printf("App_exec: Preparing message %d\n", i);
+
+        /* Receive messages: End =======================================> */
+
+        /* Send messages: Start  <======================================= */
+
+        /* allocate message */
+        msg = (App_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
+
+        if (msg == NULL) {
+            status = -1;
+            printf("MessageQ_alloc failed\n");
+            goto leave;
+        }
+
+        /* set the return address in the message header */
+        MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
+
+        /* fill in message payload */
+        if (i < 14) {
+
+            /* Send Big data messages */
+
+            msg->cmd = App_CMD_BIGDATA;
+            msg->id = i;
+
+            /* Allocate buffer from HeapMem */
+            bigDataLocalPtr = (UInt32 *)(HeapMem_alloc(sr1Heap, BIGDATA_BUF_SIZE, BIGDATA_BUF_ALIGN));
+
+            if (!bigDataLocalPtr) {
+                status = -1;
+                printf("HeapMem_alloc failed\n");
+                goto leave;
+            }
+
+            /* Fill Big data buffer */
+            for(j=0; j< BIGDATA_BUF_SIZE/sizeof(uint32_t); j++) {
+               bigDataLocalPtr[j] = j+i;
+            }
+
+            /* Populate the Local descriptor */
+            bigDataLocalDesc.localPtr = (Ptr)bigDataLocalPtr;
+            bigDataLocalDesc.size = BIGDATA_BUF_SIZE;
+
+            retVal = bigDataXlatetoGlobalAndSync(regionId,
+                &bigDataLocalDesc, &msg->u.bigDataSharedDesc);
+            if (retVal) {
+                status = -1;
+                printf("bigDataXlatetoGlobalAndSync failed\n");
+                goto leave;
+            }
+            msg->regionId = regionId;
+        } else {
+            if (i == 16) {
+                /* Last message will tell the slave to shutdown */
+                msg->cmd = App_CMD_SHUTDOWN;
+                msg->id = i;
+            } else {
+                /* Send dummy NOP messages before shutdown */
+                msg->cmd = App_CMD_NOP;
+                msg->id = i;
+            }
+        }
+        printf("App_exec: Sending message %d\n", i);
+
+        /* send message */
+        MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
+
+        /* Send messages: End  =======================================> */
+
+    }
+
+    /* drain process pipeline */
+    for (i = 1; i <= 3; i++) {
+
+        /* wait for return message */
+        status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
+            MessageQ_FOREVER);
+
+        if (status < 0) {
+            printf("MessageQ_get failed\n");
+            goto leave;
+        }
+        printf("App_exec: message received: %d\n", msg->id);
+
+        /* extract message payload */
+
+        /* free the message */
+        MessageQ_free((MessageQ_Msg)msg);
+    }
+
+leave:
+    if (sr1Heap) {
+        HeapMem_delete(&sr1Heap);
+    }
+    if (sharedRegionAllocPtr) {
+        /* free the message */
+        CMEM_free(sharedRegionAllocPtr, &cmemAttrs);
+    }
+    /* Print error count if non-zero */
+    if (errorCount) {
+        printf("App_exec: Error Count %d\n", errorCount);
+        status = -1;
+    }
+    else
+        printf("App_exec: Data check clean\n");
+
+    printf("<-- App_exec: %d\n", status);
+    return(status);
+}
diff --git a/host_linux/simple_buffer_example/host/App.h b/host_linux/simple_buffer_example/host/App.h
new file mode 100644 (file)
index 0000000..e40bfb8
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013-2017, 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.
+ */
+
+/*
+ *  ======== App.h ========
+ *
+ */
+
+#ifndef App__include
+#define App__include
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+Int App_create(UInt16 remoteProcId);
+Int App_delete();
+Int App_exec();
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+#endif /* App__include */
diff --git a/host_linux/simple_buffer_example/host/GateMutex.h b/host_linux/simple_buffer_example/host/GateMutex.h
new file mode 100644 (file)
index 0000000..e644d56
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2013-2014, 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.
+ */
+
+/*
+ *  ======== GateMutex.h ========
+ *
+ *  Gate based on Mutex
+ *
+ */
+
+#ifndef GATEMUTEX_H_0x72D0
+#define GATEMUTEX_H_0x72D0
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* =============================================================================
+ *  Status codes
+ * =============================================================================
+ */
+/*!
+ *  @def    GateMutex_E_INVALIDARG
+ *  @brief  Argument passed to a function is invalid.
+ */
+#define GateMutex_E_INVALIDARG       -1
+
+/*!
+ *  @def    GateMutex_E_MEMORY
+ *  @brief  Memory allocation failed.
+ */
+#define GateMutex_E_MEMORY           -2
+
+/*!
+ *  @def    GateMutex_E_BUSY
+ *  @brief  The name is already registered or not.
+ */
+#define GateMutex_E_BUSY             -3
+
+/*!
+ *  @def    GateMutex_E_FAIL
+ *  @brief  Generic failure.
+ */
+#define GateMutex_E_FAIL             -4
+
+/*!
+ *  @def    GateMutex_E_NOTFOUND
+ *  @brief  Name not found in the nameserver.
+ */
+#define GateMutex_E_NOTFOUND         -5
+
+/*!
+ *  @def    GateMutex_E_INVALIDSTATE
+ *  @brief  Module is not initialized.
+ */
+#define GateMutex_E_INVALIDSTATE     -6
+
+/*!
+ *  @def    GateMutex_E_INUSE
+ *  @brief  Indicates that the instance is in use.
+ */
+#define GateMutex_E_INUSE            -7
+
+/*!
+ *  @def    GateMutex_S_SUCCESS
+ *  @brief  Operation successful.
+ */
+#define GateMutex_S_SUCCESS          0
+
+
+/* =============================================================================
+ *  Macros and types
+ * =============================================================================
+ */
+/*! @brief  Object for Gate Mutex */
+typedef struct GateMutex_Object GateMutex_Object;
+
+/*! @brief  Handle for Gate Mutex */
+typedef struct GateMutex_Object * GateMutex_Handle;
+
+/*! No parameters for GateMutex creation */
+typedef Void GateMutex_Params;
+
+/* =============================================================================
+ *  APIs
+ * =============================================================================
+ */
+/* Function to create a GateMutex */
+GateMutex_Handle
+GateMutex_create (const GateMutex_Params * params, Error_Block *eb);
+
+/* Function to delete a Gate Mutex */
+Int GateMutex_delete (GateMutex_Handle * gmHandle);
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* GATEMUTEX_H_0x72D0 */
diff --git a/host_linux/simple_buffer_example/host/HeapMem/HeapMem.h b/host_linux/simple_buffer_example/host/HeapMem/HeapMem.h
new file mode 100644 (file)
index 0000000..2a83e6f
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2008-2017, 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       ti/ipc/HeapMem.h
+ *
+ *  @brief      Multi-processor variable size buffer heap implementation
+ *
+ *  @note       HeapMem is currently only available for SYS/BIOS.
+ *
+ *  HeapMem is a heap implementation that manages variable size buffers that
+ *  can be used in a multiprocessor system with shared memory. HeapMem
+ *  manages a single buffer in shared memory from which blocks of user-
+ *  specified length are allocated and freed.
+ *
+ *  The HeapMem module uses a NameServer instance to
+ *  store instance information when an instance is created.  The name supplied
+ *  must be unique for all HeapMem instances.
+ *
+ *  HeapMem_create() initializes the shared memory as needed. Once an
+ *  instance is created, HeapMem_open() can be called. The
+ *  open is used to gain access to the same HeapMem instance.
+ *  Generally an instance is created on one processor and opened on the
+ *  other processor(s).
+ *
+ *  The open returns a HeapMem instance handle like the create,
+ *  however the open does not modify the shared memory.
+ *
+ *  Because HeapMem is a variable-size heap implementation, it is also used
+ *  by the SharedRegion module to manage shared memory in each shared
+ *  region.  When any shared memory IPC instance is created in a
+ *  particular shared region, the HeapMem that manages shared memory in the
+ *  shared region allocates shared memory for the instance.
+ *
+ *  The HeapMem header should be included in an application as follows:
+ *  @code
+ *  #include <ti/ipc/HeapMem.h>
+ *  @endcode
+ */
+
+#ifndef ti_ipc_HeapMem__include
+#define ti_ipc_HeapMem__include
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include <ti/ipc/GateMP.h>
+
+/* =============================================================================
+ *  All success and failure codes for the module
+ * =============================================================================
+ */
+
+/*!
+ *  @brief  The resource is still in use
+ */
+#define HeapMem_S_BUSY               2
+
+/*!
+ *  @brief  The module has been already setup
+ */
+#define HeapMem_S_ALREADYSETUP       1
+
+/*!
+ *  @brief  Operation is successful.
+ */
+#define HeapMem_S_SUCCESS            0
+
+/*!
+ *  @brief  Generic failure.
+ */
+#define HeapMem_E_FAIL              -1
+
+/*!
+ *  @brief  Argument passed to function is invalid.
+ */
+#define HeapMem_E_INVALIDARG        -2
+
+/*!
+ *  @brief  Operation resulted in memory failure.
+ */
+#define HeapMem_E_MEMORY            -3
+
+/*!
+ *  @brief  The specified entity already exists.
+ */
+#define HeapMem_E_ALREADYEXISTS     -4
+
+/*!
+ *  @brief  Unable to find the specified entity.
+ */
+#define HeapMem_E_NOTFOUND          -5
+
+/*!
+ *  @brief  Operation timed out.
+ */
+#define HeapMem_E_TIMEOUT           -6
+
+/*!
+ *  @brief  Module is not initialized.
+ */
+#define HeapMem_E_INVALIDSTATE      -7
+
+/*!
+ *  @brief  A failure occurred in an OS-specific call  */
+#define HeapMem_E_OSFAILURE         -8
+
+/*!
+ *  @brief  Specified resource is not available  */
+#define HeapMem_E_RESOURCE          -9
+
+/*!
+ *  @brief  Operation was interrupted. Please restart the operation  */
+#define HeapMem_E_RESTART           -10
+
+/* =============================================================================
+ *  Structures & Enums
+ * =============================================================================
+ */
+
+/*!
+ *  @brief  HeapMem_Handle type
+ */
+typedef struct HeapMem_Object *HeapMem_Handle;
+
+/*!
+ *  @brief  Structure defining parameters for the HeapMem module.
+ *
+ *  @sa     HeapMem_create()
+ */
+typedef struct HeapMem_Params {
+    String name;
+    /*!< Name of this instance.
+     *
+     *  The name (if not NULL) must be unique among all HeapMem
+     *  instances in the entire system.  When creating a new
+     *  heap, it is necessary to supply an instance name.
+     *
+     *  The name does not have to be persistent.  The supplied string is copied
+     *  into persistent memory.
+     */
+
+    UInt16 regionId;
+    /*!< Shared region ID
+     *
+     *  The index corresponding to the shared region from which shared memory
+     *  will be allocated.
+     */
+
+    /*! @cond */
+    Ptr sharedAddr;
+    /*!< Physical address of the shared memory
+     *
+     *  This value can be left as 'null' unless it is required to place the
+     *  heap at a specific location in shared memory.  If sharedAddr is null,
+     *  then shared memory for a new instance will be allocated from the
+     *  heap belonging to the region identified by #HeapMem_Params.regionId.
+     */
+    /*! @endcond */
+
+    SizeT sharedBufSize;
+    /*!< Size of shared buffer
+     *
+     *  This is the size of the buffer to be used in the HeapMem instance.
+     *  The actual buffer size in the created instance might actually be less
+     *  than the value supplied in 'sharedBufSize' because of alignment
+     *  constraints.
+     *
+     *  It is important to note that the total amount of shared memory required
+     *  for a HeapMem instance will be greater than the size supplied here.
+     *  Additional space will be consumed by shared instance attributes and
+     *  alignment-related padding.
+     */
+
+    GateMP_Handle gate;
+    /*!< GateMP used for critical region management of the shared memory
+     *
+     *  Using the default value of NULL will result in use of the GateMP
+     *  system gate for context protection.
+     */
+
+} HeapMem_Params;
+
+/*!
+ *  @brief  Stats structure for HeapMem_getExtendedStats()
+ *
+ *  @sa     HeapMem_getExtendedStats()
+ */
+typedef struct HeapMem_ExtendedStats {
+    Ptr   buf;
+    /*!< Local address of the shared buffer */
+
+    SizeT size;
+    /*!< Size of the shared buffer */
+} HeapMem_ExtendedStats;
+
+/*!
+ *  @brief  Structure defining config parameters for the HeapMem module.
+ */
+typedef struct HeapMem_Config_tag {
+    UInt32      maxNameLen;
+    /*!< Maximum length of name */
+    UInt32      maxRunTimeEntries;
+    /*!< Maximum number of entries */
+} HeapMem_Config;
+
+/* =============================================================================
+ *  HeapMem Module-wide Functions
+ * =============================================================================
+ */
+/*!
+ *  @brief      Get the default configuration for the HeapMem module.
+ *
+ *              This function can be called by the application to get their
+ *              configuration parameter to HeapMem_setup filled in by
+ *              the HeapMem module with the default parameters. If the
+ *              user does not wish to make any change in the default parameters,
+ *              this API is not required to be called.
+ *
+ *  @param      cfgParams  Pointer to the HeapMem module configuration
+ *                         structure in which the default config is to be
+ *                         returned.
+ *
+ *  @sa         HeapMem_setup
+ */
+Void HeapMem_getConfig (HeapMem_Config * cfgParams);
+
+/*!
+ *  @brief      Setup the HeapMem module.
+ *
+ *              This function sets up the HeapMem module. This function
+ *              must be called before any other instance-level APIs can be
+ *              invoked.
+ *              Module-level configuration needs to be provided to this
+ *              function. If the user wishes to change some specific config
+ *              parameters, then HeapMem_getConfig can be called to get
+ *              the configuration filled with the default values. After this,
+ *              only the required configuration values can be changed. If the
+ *              user does not wish to make any change in the default parameters,
+ *              the application can simply call HeapMem_setup with NULL
+ *              parameters. The default parameters would get automatically used.
+ *
+ *  @param      cfg   Optional HeapMem module configuration. If provided
+ *                    as NULL, default configuration is used.
+ *
+ *  @sa        HeapMem_destroy
+ *             HeapMem_getConfig
+ *             NameServer_create
+ *             NameServer_delete
+ *             GateMutex_delete
+ */
+Int HeapMem_setup (const HeapMem_Config * config);
+
+/*!
+ *  @brief      Close a HeapMem instance
+ *
+ *  Closing an instance will free local memory consumed by the opened
+ *  instance. All opened instances should be closed before the instance
+ *  is deleted.
+ *
+ *  @param[in,out]  handlePtr   Pointer to handle returned from
+ *                              HeapMem_open()
+ *
+ *  @return     HeapMem status:
+ *              - #HeapMem_S_SUCCESS: Heap successfully closed
+ *
+ *  @sa         HeapMem_open()
+ */
+Int HeapMem_close(HeapMem_Handle *handlePtr);
+
+/*!
+ *  @brief      Create a HeapMem instance
+ *
+ *  @param[in]  params      HeapMem parameters
+ *
+ *  @return     HeapMem Handle
+ *
+ *  @sa         HeapMem_delete()
+ */
+HeapMem_Handle HeapMem_create(const HeapMem_Params *params);
+
+/*!
+ *  @brief      Delete a created HeapMem instance
+ *
+ *  @param[in,out]  handlePtr   Pointer to handle to delete.
+ *
+ *  @return     HeapMem status:
+ *              - #HeapMem_S_SUCCESS: Heap successfully deleted
+ *
+ *  @sa         HeapMem_create()
+ */
+Int HeapMem_delete(HeapMem_Handle *handlePtr);
+
+/*!
+ *  @brief      Open a created HeapMem instance
+ *
+ *  Once an instance is created, an open can be performed. The
+ *  open is used to gain access to the same HeapMem instance.
+ *  Generally an instance is created on one processor and opened on the
+ *  other processor.
+ *
+ *  The open returns a HeapMem instance handle like the create,
+ *  however the open does not initialize the shared memory. The supplied
+ *  name is used to identify the created instance.
+ *
+ *  Call #HeapMem_close when the opened instance is not longer needed.
+ *
+ *  @param[in]  name        Name of created HeapMem instance
+ *  @param[out] handlePtr   Pointer to HeapMem handle to be opened
+ *
+ *  @return     HeapMem status:
+ *              - #HeapMem_S_SUCCESS: Heap successfully opened
+ *              - #HeapMem_E_NOTFOUND: Heap is not yet ready to be opened.
+ *              - #HeapMem_E_FAIL: A general failure has occurred
+ *
+ *  @sa         HeapMem_close
+ */
+Int HeapMem_open(String name, HeapMem_Handle *handlePtr);
+
+/*! @cond */
+Int HeapMem_openByAddr(Ptr sharedAddr, HeapMem_Handle *handlePtr);
+
+/*! @endcond */
+
+/*!
+ *  @brief      Initialize a HeapMem parameters struct
+ *
+ *  @param[out] params      Pointer to creation parameters
+ *
+ *  @sa         HeapMem_create()
+ */
+Void HeapMem_Params_init(HeapMem_Params *params);
+
+/*! @cond */
+/*!
+ *  @brief      Amount of shared memory required for creation of each instance
+ *
+ *  @param[in]  params      Pointer to the parameters that will be used in
+ *                          the create.
+ *
+ *  @return     Number of MAUs needed to create the instance.
+ */
+SizeT HeapMem_sharedMemReq(const HeapMem_Params *params);
+
+/*! @endcond */
+
+/* =============================================================================
+ *  HeapMem Per-instance Functions
+ * =============================================================================
+ */
+
+/*!
+ *  @brief      Allocate a block of memory of specified size and alignment
+ *
+ *  The actual block returned may be larger than requested to satisfy
+ *  alignment requirements. NULL is returned if the alloc fails.
+ *
+ *  HeapMem_alloc will lock the heap using the HeapMem gate
+ *  while it traverses the list of free blocks to find a large enough block
+ *  for the request.
+ *
+ *  Guidelines for using large heaps and multiple alloc() calls.
+ *      - If possible, allocate larger blocks first. Previous allocations
+ *        of small memory blocks can reduce the size of the blocks
+ *        available for larger memory allocations.
+ *      - Realize that allocation can fail even if the heap contains a
+ *        sufficient absolute amount of unallocated space. This is
+ *        because the largest free memory block may be smaller than
+ *        total amount of unallocated memory.
+ *
+ *  @param[in]  handle    Handle to previously created/opened instance.
+ *  @param[in]  size      Size to be allocated (in MADUs)
+ *  @param[in]  align     Alignment for allocation (power of 2)
+ *
+ *  @sa         HeapMem_free()
+ */
+Void *HeapMem_alloc(HeapMem_Handle handle, SizeT size, SizeT align);
+
+/*!
+ *  @brief      Frees a block of memory.
+ *
+ *  HeapMem_free() places the memory block specified by addr and size back
+ *  into the free pool of the heap specified. The newly freed block is combined
+ *  with any adjacent free blocks. The space is then available for future
+ *  allocations.
+ *
+ *  HeapMem_free() will lock the heap using the HeapMem gate if one is
+ *  specified or the system GateMP if not.
+ *
+ *  @param[in]  handle    Handle to previously created/opened instance.
+ *  @param[in]  block     Block of memory to be freed.
+ *  @param[in]  size      Size to be freed (in MADUs)
+ *
+ *  @sa         HeapMem_alloc()
+ */
+Void HeapMem_free(HeapMem_Handle handle, Ptr block, SizeT size);
+
+/*!
+ *  @brief      Get extended memory statistics
+ *
+ *  This function retrieves extended statistics for a HeapMem
+ *  instance. Refer to #HeapMem_ExtendedStats for more information
+ *  regarding what information is returned.
+ *
+ *  @param[in]  handle    Handle to previously created/opened instance.
+ *  @param[out] stats     ExtendedStats structure
+ *
+ *  @sa     HeapMem_getStats
+ */
+Void HeapMem_getExtendedStats(HeapMem_Handle handle,
+                                HeapMem_ExtendedStats *stats);
+
+/*!
+ *  @brief      Get memory statistics
+ *
+ *  @param[in]  handle    Handle to previously created/opened instance.
+ *  @param[out] stats     Memory statistics structure
+ *
+ *  @sa     HeapMem_getExtendedStats()
+ */
+Void HeapMem_getStats(HeapMem_Handle handle, Ptr stats);
+
+/*!
+ *  @brief      Restore an instance to it's original created state.
+ *
+ *  This function restores an instance to
+ *  its original created state. Any memory previously allocated from the
+ *  heap is no longer valid after this API is called. This function
+ *  does not check whether there is allocated memory or not.
+ *
+ *  @param[in]  handle    Handle to previously created/opened instance.
+ */
+Void HeapMem_restore(HeapMem_Handle handle);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+#endif /* ti_ipc_HeapMem__include */
diff --git a/host_linux/simple_buffer_example/host/HeapMem/src/HeapMem.c b/host_linux/simple_buffer_example/host/HeapMem/src/HeapMem.c
new file mode 100755 (executable)
index 0000000..0c3f540
--- /dev/null
@@ -0,0 +1,2371 @@
+/*
+ *  @file   HeapMem.c
+ *
+ *  @brief      Defines HeapMem based memory allocator.
+ *
+ *  HeapMem is a heap implementation that manages variable size buffers that
+ *  can be used in a multiprocessor system with shared memory. HeapMem
+ *  manages a single buffer in shared memory from which blocks of user-
+ *  specified length are allocated and freed.
+ *
+ *  The HeapMem module uses a NameServerinstance to
+ *  store instance information when an instance is created.  The name supplied
+ *  must be unique for all HeapMem instances.
+ *
+ *  The create initializes the shared memory as needed. Once an
+ *  instance is created, an open can be performed. The
+ *  open is used to gain access to the same HeapMem instance.
+ *  Generally an instance is created on one processor and opened on the
+ *  other processor(s).
+ *
+ *  The open returns a HeapMem instance handle like the create,
+ *  however the open does not modify the shared memory.
+ *
+ *  Because HeapMem is a variable-size heap implementation, it is also used
+ *  by Shared Region to manage shared memory in each shared
+ *  region.  When any shared memory IPC instance is created in a
+ *  particular shared region, the HeapMem that manages shared memory in the
+ *  shared region allocates shared memory for the instance.
+ *
+ *
+ *
+ *  ============================================================================
+ *
+ *  Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ *  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.
+ *  Contact information for paper mail:
+ *  Texas Instruments
+ *  Post Office Box 655303
+ *  Dallas, Texas 75265
+ *  Contact information: 
+ *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ *  ============================================================================
+ *  
+ */
+
+/* Standard headers */
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* IPC headers */
+#include <ti/ipc/Std.h>
+#include "Std.h"
+#include <ti/ipc/MultiProc.h>
+#include <SharedRegion.h>
+#include <IGateProvider.h>
+#include <GateMutex.h>
+
+#include "List.h"
+#include "HeapMem.h"
+#include "Memory.h"
+#include "Cache.h"
+
+#include "_SharedRegion.h"
+
+#define ENABLE_LOCAL_LOCK
+
+/* Module level headers */
+#include <_HeapMem.h>
+/* round up the value 'size' to the next 'align' boundary */
+#define ROUNDUP(size, align) \
+    (UInt32)(((UInt32)(size) + ((UInt32)(align) - 1)) & ~((UInt32)(align) - 1))
+
+#define SYSLINK_BUILD_OPTIMIZE
+
+/* =============================================================================
+ * Globals
+ * =============================================================================
+ */
+/*!
+ *  @var    HeapMem_nameServer
+ *
+ *  @brief  Name of the reserved NameServer used for HeapMem.
+ */
+#define HeapMem_NAMESERVER  "HeapMem"
+
+/*! @brief Macro to make a correct module magic number with refCount */
+#define HeapMem_MAKE_MAGICSTAMP(x) ((HeapMem_MODULEID << 12u) | (x))
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+/*!
+ *  @brief  Structure defining processor related information for the
+ *          module.
+ */
+typedef struct HeapMem_ProcAttrs_tag {
+    Bool   creator;   /*!< Creatoror opener */
+    UInt16 procId;    /*!< Processor Identifier */
+    UInt32 openCount; /*!< How many times it is opened on a processor */
+} HeapMem_ProcAttrs;
+
+/* Header */
+typedef struct HeapMem_Header_tag {
+    SharedRegion_SRPtr next;
+    /* SRPtr to next header (Header *)    */
+    Bits32             size;
+    /* Size of this segment (Memory.size) */
+} HeapMem_Header;
+
+/*! Structure of attributes in shared memory */
+typedef struct HeapMem_Attrs_tag {
+    Bits32              status;
+    /* Module status                 */
+    SharedRegion_SRPtr  bufPtr;
+    /* Memory managed by instance    */
+    HeapMem_Header    head;
+    /* HeapMem      head */
+    SharedRegion_SRPtr  gateMPAddr;
+    /* GateMP SRPtr (shm safe)       */
+} HeapMem_Attrs;
+
+/*!
+ *  Structure for HeapMem module state
+ */
+typedef struct HeapMem_ModuleObject {
+    UInt32                 refCount;
+    /*!< Reference count */
+    IGateProvider_Handle   localLock;
+    /*!< Handle to lock for protecting objList */
+    List_Object            objList;
+    /*!< List holding created objects */
+    HeapMem_Config       cfg;
+    /*!< Current config values */
+    HeapMem_Config       defaultCfg;
+    /*!< Default config values */
+    HeapMem_Params       defaultInstParams;
+    /*!< Default instance creation parameters */
+} HeapMem_ModuleObject;
+
+/*!
+ *  @brief  Structure for the Handle for the HeapMem.
+ */
+typedef struct HeapMem_Obj_tag {
+    List_Elem           listElem;
+    /* Used for creating a linked list */
+    volatile HeapMem_Attrs   * attrs;
+    /* Local pointer to attrs        */
+    GateMP_Handle       gate;
+    /* Gate for critical regions     */
+    Ptr                 nsKey;
+    /* Used to remove NS entry       */
+    Bool                cacheEnabled;
+    /* Whether to do cache calls     */
+    UInt16              regionId;
+    /* SharedRegion index            */
+    UInt32              allocSize;
+    /* Shared memory allocated       */
+    Char              * buf;
+    /* Local pointer to buf          */
+    UInt32              minAlign;
+    /* Minimum alignment required    */
+    UInt32              bufSize;
+    /* Buffer Size */
+    HeapMem_ProcAttrs owner;
+    /* Processor related information for owner processor */
+    Ptr                 top;
+    /* Pointer to the top Object */
+    HeapMem_Params    params;
+    /* instance creation parameters */
+} HeapMem_Obj;
+
+/* =============================================================================
+ * Globals
+ * =============================================================================
+ */
+#if !defined(SYSLINK_BUILD_DEBUG)
+static
+#endif /* if !defined(SYSLINK_BUILD_DEBUG) */
+HeapMem_ModuleObject HeapMem_state =
+{
+    .defaultCfg.maxNameLen            = 32u,
+    .defaultCfg.maxRunTimeEntries     = 32u,
+    .defaultInstParams.gate           = NULL,
+    .defaultInstParams.name           = NULL,
+    .defaultInstParams.regionId       = 0u,
+    .defaultInstParams.sharedAddr     = NULL,
+    .defaultInstParams.sharedBufSize  = 0,
+};
+
+/*!
+ *  @var    HeapMem_module
+ *
+ *  @brief  Pointer to the HeapMem module state.
+ */
+#if !defined(SYSLINK_BUILD_DEBUG)
+static
+#endif /* if !defined(SYSLINK_BUILD_DEBUG) */
+HeapMem_ModuleObject * HeapMem_module = &HeapMem_state;
+
+/* =============================================================================
+ * Forward declaration of internal function
+ * =============================================================================
+ */
+/*!
+ *  @brief      Creates a new instance of HeapMem module.
+ *              This is an internal function as both HeapMem_create
+ *              and HeapMem_open use the functionality.
+ *
+ *  @param      handlePtr  Return value: Handle
+ *  @param      params  Instance config-params structure.
+ *  @param      createFlag Indicates whether this is a create or open call.
+ *
+ *  @sa         HeapMem_delete,
+ *              ListMP_Params_init
+ *              ListMP_sharedMemReq
+ *              Gate_enter
+ *              Gate_leave
+ *              GateMutex_delete
+ *              NameServer_addUInt32
+ */
+Int _HeapMem_create (      HeapMem_Handle * handlePtr,
+                       const HeapMem_Params * params,
+                             Bool               createFlag);
+
+/* slice and dice the buffer */
+Int HeapMem_postInit (HeapMem_Object * handle);
+
+/* =============================================================================
+ * APIS
+ * =============================================================================
+ */
+/* Get the default configuration for the HeapMem module. */
+Void
+HeapMem_getConfig (HeapMem_Config * cfgParams)
+{
+    GT_1trace (curTrace, GT_ENTER, "HeapMem_getConfig", cfgParams);
+
+    GT_assert (curTrace, (cfgParams != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (cfgParams == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_getConfig",
+                             HeapMem_E_INVALIDARG,
+                             "Argument of type (HeapMem_Config *) passed "
+                             "is null!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+    if ((HeapMem_module->refCount & HeapMem_MAKE_MAGICSTAMP(0)) < 
+        HeapMem_MAKE_MAGICSTAMP(1)) {
+            memcpy (cfgParams,
+                         &HeapMem_module->defaultCfg,
+                         sizeof (HeapMem_Config));
+        }
+        else {
+            memcpy (cfgParams,
+                         &HeapMem_module->cfg,
+                         sizeof (HeapMem_Config));
+        }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_ENTER, "HeapMem_getConfig");
+}
+
+/* Setup the HeapMem module. */
+Int
+HeapMem_setup (const HeapMem_Config * cfg)
+{
+    Int               status = HeapMem_S_SUCCESS;
+    Error_Block       eb;
+    HeapMem_Config  tmpCfg;
+
+    GT_1trace (curTrace, GT_ENTER, "HeapMem_setup", cfg);
+    Error_init (&eb);
+
+    if (cfg == NULL) {
+        HeapMem_getConfig (&tmpCfg);
+        cfg = &tmpCfg;
+    }
+
+    if (cfg == NULL) {
+        HeapMem_getConfig (&tmpCfg);
+        cfg = &tmpCfg;
+    }
+
+    /* This sets the refCount variable is not initialized, upper 16 bits is
+     * written with module Id to ensure correctness of refCount variable.
+     */
+    if((HeapMem_module->refCount & HeapMem_MAKE_MAGICSTAMP(0))
+        != HeapMem_MAKE_MAGICSTAMP(0)) {
+        HeapMem_module->refCount = HeapMem_MAKE_MAGICSTAMP(0);
+    }
+    if ( ++HeapMem_module->refCount
+        != HeapMem_MAKE_MAGICSTAMP(1u)) {
+        status = HeapMem_S_ALREADYSETUP;
+        GT_0trace (curTrace,
+                   GT_2CLASS,
+                   "HeapMem Module already initialized!");
+    }
+    else {
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        if (cfg->maxNameLen == 0) {
+            /*! @retval HeapMem_E_INVALIDARG cfg->maxNameLen passed is 0 */
+            status = HeapMem_E_INVALIDARG;
+            GT_setFailureReason (curTrace,
+                                 GT_4CLASS,
+                                 "HeapMem_setup",
+                                 status,
+                                 "cfg->maxNameLen passed is 0!");
+        }
+        else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+                /* Construct the list object */
+                List_construct (&HeapMem_module->objList, NULL);
+                /* Copy the cfg */
+                memcpy ((Ptr) &HeapMem_module->cfg,
+                             (Ptr) cfg,
+                             sizeof (HeapMem_Config));
+#ifdef ENABLE_LOCAL_LOCK
+                /* Create a lock for protecting list object */
+                HeapMem_module->localLock = (IGateProvider_Handle)
+                               GateMutex_create ((GateMutex_Params*)NULL, &eb);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                if (HeapMem_module->localLock == NULL) {
+                    /*! @retval HeapMem_E_FAIL Failed to create the localLock*/
+                    status = HeapMem_E_FAIL;
+                    GT_setFailureReason (curTrace,
+                                         GT_4CLASS,
+                                         "HeapMem_setup",
+                                         HeapMem_E_FAIL,
+                                         "Failed to create the localLock!");
+                    HeapMem_destroy ();
+                }
+            }
+        }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+    }
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_setup", status);
+
+    /*! @retval HeapMem_S_SUCCESS Operation successful */
+    return status;
+}
+
+/* Function to destroy the HeapMem module. */
+Int
+HeapMem_destroy (void)
+{
+    Int           status = HeapMem_S_SUCCESS;
+    List_Elem  *  elem;
+
+    GT_0trace (curTrace, GT_ENTER, "HeapMem_destroy");
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        /*! @retval HeapMem_E_INVALIDSTATE Module was not initialized */
+        status = HeapMem_E_INVALIDSTATE;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_destroy",
+                             status,
+                             "Module was not initialized!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        if (   --HeapMem_module->refCount
+            == HeapMem_MAKE_MAGICSTAMP(0)) {
+            /* Temporarily increment refCount here. */
+           HeapMem_module->refCount = 
+                        HeapMem_MAKE_MAGICSTAMP(1);
+            /* Check if any HeapMem instances have not been deleted so far.
+             * If not, delete them.
+             */
+            List_traverse (elem, (List_Handle) &HeapMem_module->objList) {
+                if (   (   ((HeapMem_Obj *) elem)->owner.procId
+                    == MultiProc_self ())) {
+                    status = HeapMem_delete ((HeapMem_Handle*)
+                                             &(((HeapMem_Obj *) elem)->top));
+                }
+                else {
+                    status = HeapMem_close ((HeapMem_Handle *)
+                                              &(((HeapMem_Obj *) elem)->top));
+                }
+            }
+
+            /* Decrease the refCount */
+            HeapMem_module->refCount =
+                        HeapMem_MAKE_MAGICSTAMP(0);
+
+            /* Destruct the list object */
+            List_destruct (&HeapMem_module->objList);
+#ifdef ENABLE_LOCAL_LOCK
+            /* Delete the list lock */
+            if (HeapMem_module->localLock != NULL) {
+                status = GateMutex_delete ((GateMutex_Handle *)
+                                           &HeapMem_module->localLock);
+                GT_assert (curTrace, (status >= 0));
+                if (status < 0) {
+                    /* Override the status to return a HeapMem status code. */
+                    status = HeapMem_E_FAIL;
+                }
+            }
+#endif
+            memset (&HeapMem_module->cfg, 0, sizeof (HeapMem_Config));
+        }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_destroy", status);
+
+    /*! @retval HeapMem_S_SUCCESS Operation successful */
+    return status;
+}
+
+/* Initialize this config-params structure with supplier-specified
+ * defaults before instance creation.
+ */
+Void
+HeapMem_Params_init (HeapMem_Params * params)
+{
+    GT_1trace (curTrace, GT_ENTER, "HeapMem_Params_init", params);
+
+    GT_assert (curTrace, (params != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_Params_init",
+                             HeapMem_E_INVALIDSTATE,
+                             "Module was not initialized!");
+    }
+    else if (params == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_Params_init",
+                             HeapMem_E_INVALIDARG,
+                             "Argument of type (HeapMem_Params *) is "
+                             "NULL!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        memcpy (params,
+                     &(HeapMem_module->defaultInstParams),
+                     sizeof (HeapMem_Params));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_LEAVE, "HeapMem_Params_init");
+}
+
+/*!
+ *  @brief      Creates a new instance of HeapMem module.
+ *
+ *  @param      params  Instance config-params structure.
+ *
+ *  @sa         HeapMem_delete,
+ *              ListMP_Params_init
+ *              ListMP_sharedMemReq
+ *              Gate_enter
+ *              Gate_leave
+ *              NameServer_addUInt32
+ */
+HeapMem_Handle
+HeapMem_create (const HeapMem_Params * params)
+{
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    Int                status = HeapMem_S_SUCCESS;
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+    HeapMem_Object * handle = NULL;
+    HeapMem_Params   sparams;
+
+    GT_1trace (curTrace, GT_ENTER, "HeapMem_create", params);
+
+    GT_assert (curTrace, (params != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        /*! @retval NULL if Module was not initialized */
+        status = HeapMem_E_INVALIDSTATE;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_create",
+                             status,
+                             "Module was not initialized!");
+    }
+    else if (params == NULL) {
+        /*! @retval NULL if params pointer passed is NULL */
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_create",
+                             status,
+                             "params pointer passed is NULL!");
+    }
+    else if (params->sharedBufSize == 0) {
+        /*! @retval HeapMem_E_INVALIDARG if Shared Buffer size cannot be 0
+         */
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_create",
+                             status,
+                             "Shared buffer size is 0!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        memcpy (&sparams,
+                     (Ptr)params,
+                     sizeof (HeapMem_Params));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        status =
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        _HeapMem_create ((HeapMem_Handle *) &handle, &sparams, TRUE);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        if (status < 0) {
+            GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_create",
+                             status,
+                             "_HeapMem_create failed in HeapMem_create!");
+        }
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_create", handle);
+
+    /*! @retval Valid-Handle Operation successful*/
+    return (HeapMem_Handle) handle;
+}
+
+/* Deletes an instance of HeapMem module. */
+Int
+HeapMem_delete (HeapMem_Handle * handlePtr)
+{
+    Int                status = HeapMem_S_SUCCESS;
+    HeapMem_Object * handle = NULL;
+    HeapMem_Obj    * obj    = NULL;
+    HeapMem_Params * params = NULL;
+    HeapMem_Handle * regionHeap = NULL;
+#ifdef ENABLE_GATEMP
+    IArg               key    = 0;
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+    IArg               key1   = 0;
+#endif
+
+    GT_1trace (curTrace, GT_ENTER, "HeapMem_delete", handlePtr);
+
+    GT_assert (curTrace, (handlePtr != NULL));
+    GT_assert (curTrace, ((handlePtr != NULL) && (*handlePtr != NULL)));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        status = HeapMem_E_INVALIDSTATE;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_delete",
+                             status,
+                             "Module was not initialized!");
+    }
+    else if (handlePtr == NULL) {
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_delete",
+                             status,
+                             "The parameter handlePtr i.e. pointer to handle "
+                             "passed is NULL!");
+    }
+    else if (*handlePtr == NULL) {
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_delete",
+                             status,
+                             "Handle passed is NULL!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        handle = (HeapMem_Object *) (*handlePtr);
+
+        obj    = (HeapMem_Obj *) handle->obj;
+
+        if (obj != NULL) {
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+            /* Check if we have created the HeapMem or not */
+            if (obj->owner.procId != MultiProc_self ()) {
+                status = HeapMem_E_INVALIDSTATE;
+                GT_setFailureReason (curTrace,
+                                 GT_4CLASS,
+                                 "HeapMem_delete",
+                                 status,
+                                 "Instance was not created on this processor!");
+             }
+             else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_GATEMP
+                /* Take the local lock */
+               key = GateMP_enter (obj->gate);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                if (obj->owner.openCount > 1) {
+                    status = HeapMem_E_INVALIDSTATE;
+                    GT_setFailureReason (curTrace,
+                                         GT_4CLASS,
+                                         "HeapMem_delete",
+                                         status,
+                                         "Unmatched open/close calls!");
+#ifdef ENABLE_GATEMP
+                    /* Release the global lock */
+                    GateMP_leave (obj->gate, key);
+#endif
+                }
+                else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_LOCAL_LOCK
+                    /* Remove from  the local list */
+                    key1 = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+                    List_remove ((List_Handle) &HeapMem_module->objList,
+                                 &obj->listElem);
+#ifdef ENABLE_LOCAL_LOCK
+                    IGateProvider_leave (HeapMem_module->localLock, key1);
+#endif
+
+                    params = (HeapMem_Params *) &obj->params;
+
+                    if (EXPECT_TRUE(params->name != NULL)) {
+
+                        Memory_free (NULL,
+                                     obj->params.name,
+                                     strlen(obj->params.name) + 1u);
+                    }
+
+                    /* Set status to 'not created' */
+                    if (obj->attrs != NULL) {
+                        obj->attrs->status = 0;
+                        if (obj->cacheEnabled) {
+                            Cache_wbInv ((Ptr) obj->attrs,
+                                         sizeof (HeapMem_Attrs),
+                                         Cache_Type_ALL,
+                                         TRUE);
+                        }
+                    }
+
+#ifdef ENABLE_GATEMP
+                    /* Release the shared lock */
+                   GateMP_leave (obj->gate, key);
+#endif
+
+                    /* If necessary, free shared memory  if memory is internally
+                     * allocated
+                     */
+                    regionHeap = SharedRegion_getHeap (obj->regionId);
+
+                    if (   (regionHeap != NULL)
+                        && (obj->params.sharedAddr == NULL)
+                        && (obj->attrs != NULL)){
+                        Memory_free ((IHeap_Handle) regionHeap,
+                                     (Ptr) obj->attrs,
+                                     obj->allocSize);
+                    }
+
+                    /* Now free the handle */
+                    Memory_free (NULL, obj, sizeof (HeapMem_Obj));
+                    Memory_free (NULL, handle, sizeof (HeapMem_Object));
+                    *handlePtr = NULL;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                }
+            }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        }
+        else {
+            Memory_free (NULL, handle, sizeof (HeapMem_Object));
+            *handlePtr = NULL;
+        }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_delete", status);
+
+    return status;
+}
+
+/*  Opens a created instance of HeapMem module. */
+Int
+HeapMem_open (String             name,
+                HeapMem_Handle * handlePtr)
+{
+    Int                  status = HeapMem_S_SUCCESS;
+    SharedRegion_SRPtr   sharedShmBase = SharedRegion_INVALIDSRPTR;
+    Ptr                  sharedAddr    = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg                 key    = 0;
+#endif
+    Bool                 doneFlag = FALSE;
+    List_Elem      *     elem     = NULL;
+
+    GT_2trace (curTrace, GT_ENTER, "HeapMem_open", name, handlePtr);
+
+    GT_assert (curTrace, (name != NULL));
+    GT_assert (curTrace, (handlePtr != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        status = HeapMem_E_INVALIDSTATE;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_open",
+                             status,
+                             "Module was not initialized!");
+    }
+    else if (name == NULL) {
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_open",
+                             status,
+                             "name passed is NULL!");
+    }
+    else if (handlePtr == NULL) {
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_open",
+                             status,
+                             "Pointer to handle instance passed is NULL!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        /* First check in the local list */
+        List_traverse (elem, (List_Handle) &HeapMem_module->objList) {
+            if (((HeapMem_Obj *) elem)->params.name != NULL) {
+                if (strcmp (   ((HeapMem_Obj *)elem)->params.name, name)
+                                == 0) {
+#ifdef ENABLE_LOCAL_LOCK
+                    key = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+                    /* Check if we have created the HeapMem or not */
+                    if (   ((HeapMem_Obj *) elem)->owner.procId
+                        == MultiProc_self ()) {
+                        ((HeapMem_Obj *) elem)->owner.openCount++;
+                    }
+
+                    *handlePtr = (((HeapMem_Obj *) elem)->top);
+#ifdef ENABLE_LOCAL_LOCK
+                    IGateProvider_leave (HeapMem_module->localLock, key);
+#endif
+                    doneFlag = TRUE;
+                    break;
+                }
+            }
+        }
+
+        if (EXPECT_TRUE (doneFlag == FALSE)) {
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+            else if (EXPECT_FALSE (status < 0)) {
+                /* Override the status to return a HeapMem status code. */
+                status = HeapMem_E_FAIL;
+                GT_setFailureReason (curTrace,
+                                     GT_4CLASS,
+                                     "HeapMem_open",
+                                     status,
+                                     "Failure in NameServer_get!");
+            }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+            {
+                /* Convert from shared region pointer to local address*/
+                sharedAddr = SharedRegion_getPtr (sharedShmBase);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                if (EXPECT_FALSE (sharedAddr == NULL)) {
+                    status = HeapMem_E_FAIL;
+                    GT_setFailureReason (curTrace,
+                                         GT_4CLASS,
+                                         "HeapMem_open",
+                                         status,
+                                         "Invalid pointer received from"
+                                         "NameServer!");
+                }
+                else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                    status = HeapMem_openByAddr (sharedAddr, handlePtr);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                    if (EXPECT_FALSE (status < 0)) {
+                        GT_setFailureReason (curTrace,
+                                             GT_4CLASS,
+                                             "HeapMem_open",
+                                             status,
+                                            "Failed to open HeapMem handle!");
+                    }
+                }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+            }
+        }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_open", status);
+
+    return status;
+}
+
+/* Closes previously opened instance of HeapMem module. */
+Int
+HeapMem_close (HeapMem_Handle * handlePtr)
+{
+    Int                status = HeapMem_S_SUCCESS;
+    HeapMem_Object * handle = NULL;
+    HeapMem_Obj    * obj    = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg               key    = 0;
+#endif
+    GT_1trace (curTrace, GT_ENTER, "HeapMem_close", handlePtr);
+
+    GT_assert (curTrace, (handlePtr != NULL));
+    GT_assert (curTrace, ((handlePtr != NULL) && (*handlePtr != NULL)));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        status = HeapMem_E_INVALIDSTATE;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_close",
+                             status,
+                             "Module was not initialized!");
+    }
+    else if (handlePtr == NULL) {
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_close",
+                             status,
+                             "The parameter handlePtr i.e. pointer to handle "
+                             "passed is NULL!");
+    }
+    else if (*handlePtr == NULL) {
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_close",
+                             status,
+                             "*handlePtr passed is NULL!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        handle = (HeapMem_Object *) (*handlePtr);
+        obj    = (HeapMem_Obj *) handle->obj;
+        if (obj != NULL) {
+#ifdef ENABLE_LOCAL_LOCK
+            key = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+            if (obj->owner.procId == MultiProc_self ()) {
+                obj->owner.openCount--;
+            }
+
+            /* Check if HeapMem is opened on same processor and this is the
+             * last closure.
+             */
+            if (    (obj->owner.creator   == FALSE)
+                &&  (obj->owner.openCount == 0)) {
+                List_remove ((List_Handle) &HeapMem_module->objList,
+                             &obj->listElem);
+
+                if (obj->gate != NULL) {
+#ifdef ENABLE_GATEMP
+                    /* Close the  instance gate*/
+                    GateMP_close (&obj->gate);
+#endif
+                }
+
+                /* Now free the handle */
+                Memory_free (NULL, obj, sizeof (HeapMem_Obj));
+                obj = NULL;
+                Memory_free (NULL, handle, sizeof (HeapMem_Object));
+                *handlePtr = NULL;
+            }
+
+#ifdef ENABLE_LOCAL_LOCK
+            IGateProvider_leave (HeapMem_module->localLock, key);
+#endif
+        }
+        else {
+            Memory_free (NULL, handle, sizeof (HeapMem_Object));
+            *handlePtr = NULL;
+        }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_close", status);
+
+    return status;
+}
+
+/*
+ * NOTE:
+ * Embedded within the code for HeapMem_alloc and HeapMem_free are comments
+ * that can be used to match a shared memory reference with its required
+ * cache call.  This is done because the code for alloc and free is complex.
+ * These two-character comments indicate
+ * 1) The type of cache operation that is being performed {A, B}
+ *    A = Cache_inv
+ *    B = Cache_wbInv
+ * 2) A numerical id of the specific cache call that is performed.
+ *    1, 2, 3
+ *    For example, the comment 'A2' indicates that the corresponding cache call
+ *    is a Cache_inv operation identified by the number '2'
+ */
+
+/*
+ *  ======== HeapMem_alloc ========
+ *  HeapMem is implemented such that all of the memory and blocks it works
+ *  with have an alignment that is a multiple of the minimum alignment and have
+ *  a size which is a multiple of the minAlign. Maintaining this requirement
+ *  throughout the implementation ensures that there are never any odd
+ *  alignments or odd block sizes to deal with.
+ *
+ *  Specifically:
+ *  The buffer managed by HeapMem:
+ *    1. Is aligned on a multiple of obj->minAlign
+ *    2. Has an adjusted size that is a multiple of obj->minAlign
+ *  All blocks on the freelist:
+ *    1. Are aligned on a multiple of obj->minAlign
+ *    2. Have a size that is a multiple of obj->minAlign
+ *  All allocated blocks:
+ *    1. Are aligned on a multiple of obj->minAlign
+ *    2. Have a size that is a multiple of obj->minAlign
+ *
+ */
+
+/* Allocs a block */
+Void *
+HeapMem_alloc (HeapMem_Handle handle,
+                 UInt32           reqSize,
+                 UInt32           reqAlign)
+{
+    HeapMem_Obj    * obj    = NULL;
+    Char             * allocAddr = NULL;
+#ifdef ENABLE_GATEMP
+    IArg             key    = 0;
+#endif
+    HeapMem_Header * prevHeader;
+    HeapMem_Header * newHeader;
+    HeapMem_Header * curHeader;
+    UInt32           curSize;
+    UInt32           adjSize;
+    UInt32           remainSize; /* free memory after allocated memory */
+    UInt32           adjAlign;
+    UInt32           offset;
+
+    GT_3trace (curTrace, GT_ENTER, "HeapMem_alloc",
+               handle, reqSize, reqAlign);
+
+    GT_assert (curTrace, (handle != NULL));
+    GT_assert (curTrace, (reqSize != 0u));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_alloc",
+                             HeapMem_E_INVALIDSTATE,
+                             "Module was not initialized!");
+    }
+    else if (EXPECT_FALSE (handle == NULL)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_alloc",
+                             HeapMem_E_INVALIDARG,
+                             "Invalid NULL handle pointer specified!");
+    }
+    else if (EXPECT_FALSE ((reqAlign & (reqAlign - 1)) != 0)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_alloc",
+                             HeapMem_E_MEMORY,
+                             "Requested reqAlign is not a power of 2!");
+    }
+    else if (EXPECT_FALSE (reqSize == 0)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_alloc",
+                             HeapMem_E_INVALIDARG,
+                             "Requested block size is zero!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        obj = (HeapMem_Obj *) ((HeapMem_Object *) handle)->obj;
+        GT_assert (curTrace, (obj != NULL));
+
+        adjSize = (UInt32) reqSize;
+
+        /* Make size requested a multiple of obj->minAlign */
+        if ((offset = (adjSize & (obj->minAlign - 1))) != 0) {
+            adjSize = adjSize + (obj->minAlign - offset);
+        }
+
+        /*
+         *  Make sure the alignment is at least as large as obj->minAlign
+         *  Note: adjAlign must be a power of 2 (by function constraint) and
+         *  obj->minAlign is also a power of 2,
+         */
+        adjAlign = reqAlign;
+        if (adjAlign == 0) {
+            adjAlign =  obj->minAlign;
+        }
+
+        if (adjAlign & (obj->minAlign - 1)) {
+            /* adjAlign is less than obj->minAlign */
+            adjAlign = obj->minAlign;
+        }
+
+        /* No need to Cache_inv Attrs- 'head' should be constant */
+        prevHeader = (HeapMem_Header *) &obj->attrs->head;
+
+#ifdef ENABLE_GATEMP
+        key = GateMP_enter (obj->gate);
+#endif
+
+        /*
+         *  The block will be allocated from curHeader. Maintain a pointer to
+         *  prevHeader so prevHeader->next can be updated after the alloc.
+         */
+        if (EXPECT_FALSE (obj->cacheEnabled)) {
+            Cache_inv (prevHeader,
+                       sizeof (HeapMem_Header),
+                       Cache_Type_ALL,
+                       TRUE); /* A1 */
+        }
+        curHeader = (HeapMem_Header *) SharedRegion_getPtr (prevHeader->next);
+        /* A1 */
+
+        /* Loop over the free list. */
+        while (curHeader != NULL) {
+            /* Invalidate curHeader */
+            if (EXPECT_FALSE (obj->cacheEnabled)) {
+                Cache_inv (curHeader,
+                           sizeof (HeapMem_Header),
+                           Cache_Type_ALL,
+                           TRUE); /* A2 */
+            }
+
+            curSize = curHeader->size;
+
+            /*
+             *  Determine the offset from the beginning to make sure
+             *  the alignment request is honored.
+             */
+            offset = (UInt32)curHeader & (adjAlign - 1);
+            if (offset) {
+                offset = adjAlign - offset;
+            }
+
+            /* Internal Assert that offset is a multiple of obj->minAlign */
+            if (((offset & (obj->minAlign - 1)) != 0)) {
+                GT_setFailureReason (curTrace,
+                                     GT_4CLASS,
+                                     "HeapMem_alloc",
+                                     HeapMem_E_FAIL,
+                                     "offset is not a multiple of"
+                                     " obj->minAlign!");
+            }
+            else {
+                /* big enough? */
+                if (curSize >= (adjSize + offset)) {
+                    /* Set the pointer that will be returned. Alloc from front */
+                    allocAddr = (Char *) ((UInt32) curHeader + offset);
+
+                    /*
+                     *  Determine the remaining memory after the allocated block.
+                     *  Note: this cannot be negative because of above comparison.
+                     */
+                    remainSize = curSize - adjSize - offset;
+
+                    /* Internal Assert that remainSize is a multiple of
+                     * obj->minAlign
+                     */
+                    if (((remainSize & (obj->minAlign - 1)) != 0)) {
+                        allocAddr = NULL;
+                        GT_setFailureReason (curTrace,
+                                             GT_4CLASS,
+                                             "HeapMem_alloc",
+                                             HeapMem_E_FAIL,
+                                             "remainSize is not a multiple of"
+                                             " obj->minAlign!");
+                        break;
+                    }
+                    else {
+                        /*
+                         *  If there is memory at the beginning (due to alignment
+                         *  requirements), maintain it in the list.
+                         *
+                         *  offset and remainSize must be multiples of
+                         *  sizeof(HeapMem_Header). Therefore the address of the newHeader
+                         *  below must be a multiple of the sizeof(HeapMem_Header), thus
+                         *  maintaining the requirement.
+                         */
+                        if (offset) {
+                            /* Adjust the curHeader size accordingly */
+                            curHeader->size = offset; /* B2 */
+                            /* Cache wb at end of this if block */
+
+                            /*
+                             *  If there is remaining memory, add into the free list.
+                             *  Note: no need to coalesce and we have HeapMem locked so
+                             *        it is safe.
+                             */
+                            if (remainSize) {
+                                newHeader = (HeapMem_Header *)
+                                            ((UInt32) allocAddr + adjSize);
+
+                                /* curHeader has been inv at top of 'while' loop */
+                                newHeader->next = curHeader->next;  /* B1 */
+                                newHeader->size = remainSize;       /* B1 */
+                                if (EXPECT_FALSE (obj->cacheEnabled)) {
+                                    /* Writing back curHeader will cache-wait */
+                                    Cache_wbInv (newHeader,
+                                                 sizeof (HeapMem_Header),
+                                                 Cache_Type_ALL,
+                                                 FALSE); /* B1 */
+                                }
+
+                                curHeader->next = SharedRegion_getSRPtr
+                                                                (newHeader,
+                                                                 obj->regionId);
+                                GT_assert (curTrace,
+                                           (    curHeader->next
+                                            !=  SharedRegion_INVALIDSRPTR));
+                            }
+
+                            /* Write back (and invalidate) newHeader and curHeader */
+                            if (EXPECT_FALSE (obj->cacheEnabled)) {
+                                /* B2 */
+                                Cache_wbInv (curHeader,
+                                             sizeof (HeapMem_Header),
+                                             Cache_Type_ALL,
+                                             TRUE);
+                            }
+                        }
+                        else {
+                            /*
+                             *  If there is any remaining, link it in,
+                             *  else point to the next free block.
+                             *  Note: no need to coalesce and we have HeapMem locked so
+                             *        it is safe.
+                             */
+                            if (remainSize) {
+                                newHeader = (HeapMem_Header *)
+                                            ((UInt32) allocAddr + adjSize);
+
+                                newHeader->next  = curHeader->next; /* A2, B3  */
+                                newHeader->size  = remainSize;      /* B3      */
+
+                                if (EXPECT_FALSE (obj->cacheEnabled)) {
+                                    /* Writing back prevHeader will cache-wait */
+                                    Cache_wbInv (newHeader,
+                                                 sizeof (HeapMem_Header),
+                                                 Cache_Type_ALL,
+                                                 FALSE); /* B3 */
+                                }
+
+                                /* B4 */
+                                prevHeader->next = SharedRegion_getSRPtr (newHeader,
+                                                                          obj->regionId);
+                            }
+                            else {
+                                /* curHeader has been inv at top of 'while' loop */
+                                prevHeader->next = curHeader->next; /* A2, B4 */
+                            }
+
+                            if (EXPECT_FALSE (obj->cacheEnabled)) {
+                                /* B4 */
+                                Cache_wbInv (prevHeader,
+                                             sizeof(HeapMem_Header),
+                                             Cache_Type_ALL,
+                                             TRUE);
+                            }
+                        }
+                    }
+
+                    /* Success, return the allocated memory */
+                    break;
+
+                }
+                else {
+                    prevHeader = curHeader;
+                    curHeader = SharedRegion_getPtr (curHeader->next);
+                }
+            }
+        }
+
+#ifdef ENABLE_GATEMP
+        GateMP_leave (obj->gate, key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_alloc", allocAddr);
+
+    return allocAddr;
+}
+
+/* Frees a block */
+Void
+HeapMem_free (HeapMem_Handle   handle,
+                Ptr                addr,
+                UInt32             size)
+{
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    Int                status = HeapMem_S_SUCCESS;
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+    HeapMem_Obj    * obj    = NULL;
+#ifdef ENABLE_GATEMP
+    IArg               key    = 0;
+#endif
+    HeapMem_Header * curHeader = NULL;
+    HeapMem_Header * newHeader = NULL;
+    HeapMem_Header * nextHeader= NULL;
+    SizeT              offset;
+
+    GT_3trace (curTrace, GT_ENTER, "HeapMem_free", handle, addr, size);
+
+    GT_assert (curTrace, (handle != NULL));
+    GT_assert (curTrace, (addr != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        status = HeapMem_E_INVALIDSTATE;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_free",
+                             status,
+                             "Module was not initialized!");
+    }
+    else if (EXPECT_FALSE (handle == NULL)) {
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_free",
+                             status,
+                             "Invalid NULL handle pointer specified!");
+    }
+    else if (EXPECT_FALSE (addr == NULL)) {
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_free",
+                             status,
+                             "Invalid NULL addr pointer specified!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        obj = (HeapMem_Obj *) ((HeapMem_Object *) handle)->obj;
+        GT_assert (curTrace, (obj != NULL));
+        GT_assert (curTrace, ((UInt32)addr % obj->minAlign == 0));
+
+        /*
+         * obj->attrs never changes, doesn't need Gate protection
+         * and Cache invalidate
+         */
+        curHeader = (HeapMem_Header *) &(obj->attrs->head);
+
+        /* Restore size to actual allocated size */
+        offset = size & (obj->minAlign - 1);
+        if (offset != 0) {
+            size += obj->minAlign - offset;
+        }
+
+#ifdef ENABLE_GATEMP
+        key = GateMP_enter (obj->gate);
+#endif
+
+        newHeader = (HeapMem_Header *) addr;
+
+        if (EXPECT_FALSE (obj->cacheEnabled)) {
+            /* A1 */
+            Cache_inv (curHeader,
+                       sizeof (HeapMem_Header),
+                       Cache_Type_ALL,
+                       TRUE);
+        }
+        nextHeader = SharedRegion_getPtr (curHeader->next);
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        /* Make sure the entire buffer is in the range of the heap. */
+        if (EXPECT_FALSE (!(    ((SizeT) newHeader >= (SizeT) obj->buf)
+                            && (   (SizeT) newHeader + size
+                                <= (SizeT) obj->buf + obj->bufSize)))) {
+            status = HeapMem_E_FAIL;
+            GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_free",
+                             status,
+                             "Entire buffer is not in the range of the heap!");
+        }
+        else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+            /* Go down freelist and find right place for buf */
+            while ((nextHeader != NULL) && (nextHeader < newHeader)) {
+                if (EXPECT_FALSE (obj->cacheEnabled)) {
+                    Cache_inv (nextHeader,
+                               sizeof(HeapMem_Header),
+                               Cache_Type_ALL,
+                               TRUE); /* A2 */
+                }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                /* Make sure the addr is not in this free block */
+                if (EXPECT_FALSE (    (SizeT) newHeader
+                                  < ((SizeT) nextHeader + nextHeader->size))) {
+                    /* A2 */
+                    status = HeapMem_E_INVALIDSTATE;
+                    GT_setFailureReason (curTrace,
+                                     GT_4CLASS,
+                                     "HeapMem_free",
+                                     status,
+                                     "Address is in this free block");
+                    break;
+                }
+                else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                    curHeader = nextHeader;
+                    /* A2 */
+                    nextHeader = SharedRegion_getPtr (nextHeader->next);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+            }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+            if (EXPECT_TRUE (status >= 0)) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                /* B2 */
+                newHeader->next = SharedRegion_getSRPtr (nextHeader,
+                                                         obj->regionId);
+                newHeader->size = size;
+
+                /* B1, A1 */
+                curHeader->next = SharedRegion_getSRPtr (newHeader,
+                                                         obj->regionId);
+
+                /* Join contiguous free blocks */
+                if (nextHeader != NULL) {
+                    /*
+                     *  Verify the free size is not overlapping. Not all cases
+                     *  are detectable, but it is worth a shot. Note: only do
+                     *  this assert if nextHeader is non-NULL.
+                     */
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                    if (EXPECT_FALSE (  ((SizeT) newHeader + size)
+                                      > (SizeT) nextHeader)) {
+                        /* A2 */
+                        status = HeapMem_E_INVALIDSTATE;
+                        GT_setFailureReason (curTrace,
+                                         GT_4CLASS,
+                                         "HeapMem_free",
+                                         status,
+                                         "Free size is overlapping");
+                    }
+                    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                        /* Join with upper block */
+                        if (((UInt32) newHeader + size) == (UInt32)nextHeader) {
+                            if (EXPECT_FALSE (obj->cacheEnabled)) {
+                                Cache_inv (nextHeader,
+                                           sizeof(HeapMem_Header),
+                                           Cache_Type_ALL,
+                                           TRUE);
+                            }
+                            newHeader->next = nextHeader->next; /* A2, B2 */
+                            newHeader->size += nextHeader->size; /* A2, B2 */
+
+                            /* Correct size for following Cache_wbInv. Needed
+                             * due to another cache line fill caused by
+                             * reading nextHeader->next
+                             */
+                            size += obj->minAlign;
+
+                            /* Don't Cache_wbInv, this will be done later */
+                        }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                if (EXPECT_TRUE (status >= 0)) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                    /*
+                     *  Join with lower block. Make sure to check to see if not the
+                     *  first block. No need to invalidate attrs since head shouldn't change.
+                     */
+                    if (   (curHeader != &obj->attrs->head)
+                        && (    ((UInt32) curHeader + curHeader->size)
+                            ==  (UInt32) newHeader)) {
+                        /*
+                         * Don't Cache_inv newHeader since newHeader has
+                         * data that hasn't been written back yet (B2)
+                         */
+                        curHeader->next = newHeader->next; /* B1, B2 */
+                        curHeader->size += newHeader->size; /* B1, B2 */
+                    }
+
+                    if (EXPECT_FALSE (obj->cacheEnabled)) {
+                        Cache_wbInv (curHeader,
+                                     sizeof (HeapMem_Header),
+                                     Cache_Type_ALL,
+                                     FALSE); /* B1 */
+                        /*
+                         *  Invalidate entire buffer being freed to ensure that
+                         *  stale cache data in block isn't evicted later.
+                         */
+                        Cache_wbInv (newHeader,
+                                     size,
+                                     Cache_Type_ALL,
+                                     TRUE);  /* B2 */
+                    }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                }
+            }
+        }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_GATEMP
+        GateMP_leave (obj->gate, key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_LEAVE, "HeapMem_free");
+}
+
+/* Get memory statistics */
+Void
+HeapMem_getStats (HeapMem_Handle  handle,
+                    Ptr               stats)
+{
+    HeapMem_Obj    * obj    = NULL;
+    HeapMem_Header * curHeader = NULL;
+    Memory_Stats     * memStats  = NULL;
+#ifdef ENABLE_GATEMP
+    IArg               key       = 0;
+#endif
+
+    GT_2trace (curTrace, GT_ENTER, "HeapMem_getStats", handle, stats);
+
+    GT_assert (curTrace, (handle != NULL));
+    GT_assert (curTrace, (stats != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_getStats",
+                             HeapMem_E_INVALIDARG,
+                             "Module was not initialized!");
+    }
+    else if (EXPECT_FALSE (handle == NULL)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_getStats",
+                             HeapMem_E_INVALIDARG,
+                             "handle passed is null!");
+    }
+    else if (EXPECT_FALSE (stats == NULL)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_getStats",
+                             HeapMem_E_INVALIDARG,
+                             "Invalid NULL stats pointer specified!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        obj = (HeapMem_Obj *) ((HeapMem_Object *) handle)->obj;
+        GT_assert (curTrace, (obj != NULL));
+
+        memStats = (Memory_Stats *) stats;
+
+        memStats->totalSize         = obj->bufSize;
+        memStats->totalFreeSize     = 0;  /* determined later */
+        memStats->largestFreeSize   = 0;  /* determined later */
+
+#ifdef ENABLE_GATEMP
+        key = GateMP_enter(obj->gate);
+#endif
+
+        /* Invalidate curHeader */
+        if (EXPECT_FALSE (obj->cacheEnabled)) {
+            Cache_inv ((Ptr) &(obj->attrs->head),
+                       sizeof (HeapMem_Header),
+                       Cache_Type_ALL,
+                       TRUE);
+        }
+
+        curHeader = SharedRegion_getPtr ((SharedRegion_SRPtr)
+                                                    obj->attrs->head.next);
+
+        while (curHeader != NULL) {
+            /* Invalidate curHeader */
+            if (EXPECT_FALSE (obj->cacheEnabled)) {
+                Cache_inv (curHeader,
+                           sizeof (HeapMem_Header),
+                           Cache_Type_ALL,
+                           TRUE);
+            }
+
+            memStats->totalFreeSize += curHeader->size;
+            if (memStats->largestFreeSize < curHeader->size) {
+                memStats->largestFreeSize = curHeader->size;
+            }
+            /* This condition is required to avoid
+             * assertions during call to SharedRegion_getPtr  because at the end
+             * of the calculation curHeader->next  will become
+             * SharedRegion_INVALIDSRPTR.
+             */
+            if (curHeader->next != SharedRegion_INVALIDSRPTR) {
+                curHeader = SharedRegion_getPtr ((SharedRegion_SRPtr)
+                                                               curHeader->next);
+            }
+            else {
+                curHeader = NULL;
+            }
+        }
+
+#ifdef ENABLE_GATEMP
+        GateMP_leave(obj->gate, key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_LEAVE, "HeapMem_getStats");
+}
+
+/* Indicate whether the heap may block during an alloc or free call */
+Bool
+HeapMem_isBlocking (HeapMem_Handle handle)
+{
+    Bool isBlocking = FALSE;
+
+    GT_1trace (curTrace, GT_ENTER, "Heap_isBlocking", handle);
+
+    GT_assert (curTrace, (handle != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (handle == NULL)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_isBlocking",
+                             HeapMem_E_INVALIDARG,
+                             "handle passed is null!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        /* TBD: Figure out how to determine whether the gate is blocking */
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_isBlocking", isBlocking);
+
+    return isBlocking;
+}
+
+/* Get extended statistics */
+Void
+HeapMem_getExtendedStats (HeapMem_Handle           handle,
+                            HeapMem_ExtendedStats  * stats)
+{
+    HeapMem_Obj * obj = NULL;
+
+    GT_2trace (curTrace, GT_ENTER, "HeapMem_getExtendedStats", handle, stats);
+
+    GT_assert (curTrace, (handle != NULL));
+    GT_assert (curTrace, (stats != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_getExtendedStats",
+                             HeapMem_E_INVALIDSTATE,
+                             "Module was not initialized!");
+    }
+    else if (EXPECT_FALSE (handle == NULL)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_getExtendedStats",
+                             HeapMem_E_INVALIDARG,
+                             "Invalid NULL handle pointer specified!");
+    }
+    else if (EXPECT_FALSE (stats == NULL)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_getExtendedStats",
+                             HeapMem_E_INVALIDARG,
+                             "Invalid NULL stats pointer specified!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        obj = (HeapMem_Obj *) ((HeapMem_Object *) handle)->obj;
+        GT_assert (curTrace, (obj != NULL));
+
+        stats->buf   = obj->buf;
+        stats->size  = obj->bufSize;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_LEAVE, "HeapMem_getExtendedStats");
+}
+
+/* Returns the shared memory size requirement for a single instance. */
+SizeT
+HeapMem_sharedMemReq (const HeapMem_Params * params)
+{
+    SizeT   memReq = 0;
+    UInt32  minAlign;
+    UInt16  regionId;
+
+    GT_1trace (curTrace, GT_ENTER, "HeapMem_sharedMemReq", params);
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (params == NULL)) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_sharedMemReq",
+                             HeapMem_E_INVALIDARG,
+                             "Params pointer passed is NULL!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        if (params->sharedAddr == NULL) {
+            regionId = params->regionId;
+        }
+        else {
+            regionId = SharedRegion_getId(params->sharedAddr);
+        }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        if (regionId == SharedRegion_INVALIDREGIONID)  {
+            GT_setFailureReason (curTrace,
+                                 GT_4CLASS,
+                                 "HeapMem_sharedMemReq",
+                                 HeapMem_E_FAIL,
+                                 "params->sharedAddr is not in a"
+                                 " valid SharedRegion!");
+        }
+        else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+            minAlign = sizeof (HeapMem_Header);
+            if (SharedRegion_getCacheLineSize(regionId) > minAlign) {
+                minAlign = SharedRegion_getCacheLineSize (regionId);
+            }
+
+            /* Add size of HeapMem Attrs */
+            memReq = ROUNDUP (sizeof(HeapMem_Attrs), minAlign);
+
+            /* Add the buffer size */
+            memReq += params->sharedBufSize;
+
+            /* Make sure the size is a multiple of minAlign (round down) */
+            memReq = (memReq / minAlign) * minAlign;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        }
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_sharedMemReq", memReq);
+
+    return memReq;
+}
+
+/*!
+ *  @brief      Returns the HeapMem kernel object pointer.
+ *
+ *  @param      handle  Handle to previousely created/opened instance.
+ *
+ */
+Void *
+HeapMem_getKnlHandle (HeapMem_Handle handle)
+{
+    GT_1trace (curTrace, GT_ENTER, "HeapMem_getKnlHandle", handle);
+
+    GT_assert (curTrace, (handle != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        /*! @retval NULL Module was not initialized */
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_getKnlHandle",
+                             HeapMem_E_INVALIDSTATE,
+                             "Module was not initialized!");
+    }
+    else if (EXPECT_FALSE (handle == NULL)) {
+        /*! @retval NULL handle passed is NULL */
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_getKnlHandle",
+                             HeapMem_E_INVALIDARG,
+                             "handle passed is NULL!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        /* Nothing to be done for kernel-side implementation. */
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_getKnlHandle", handle);
+
+    /*! @retval Kernel-Object-handle Operation successfully completed. */
+    return (handle);
+}
+
+/* HeapMem open by address */
+Int
+HeapMem_openByAddr (Ptr                sharedAddr,
+                      HeapMem_Handle * handlePtr)
+{
+    Int               status   = HeapMem_S_SUCCESS;
+    Bool              doneFlag = FALSE;
+    HeapMem_Attrs * attrs    = NULL;
+    List_Elem *       elem     = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg              key;
+#endif
+    UInt16            id;
+    HeapMem_Params  params;
+
+    GT_2trace (curTrace, GT_ENTER, "HeapMem_openByAddr",
+               sharedAddr, handlePtr);
+
+    GT_assert (curTrace, (handlePtr != NULL));
+    GT_assert (curTrace, (sharedAddr != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+                                                HeapMem_MAKE_MAGICSTAMP(0),
+                                                HeapMem_MAKE_MAGICSTAMP(1))
+                      == TRUE)) {
+        status = HeapMem_E_INVALIDSTATE;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_openByAddr",
+                             status,
+                             "Module was not initialized!");
+    }
+    else if (EXPECT_FALSE (handlePtr == NULL)) {
+        status = HeapMem_E_INVALIDARG;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "HeapMem_openByAddr",
+                             status,
+                             "handlePtr pointer passed is NULL!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        /* First check in the local list */
+        List_traverse (elem, (List_Handle) &HeapMem_module->objList) {
+            if (((HeapMem_Obj *) elem)->params.sharedAddr == sharedAddr) {
+#ifdef ENABLE_LOCAL_LOCK
+                key = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+                if (   ((HeapMem_Obj *)elem)->owner.procId
+                    == MultiProc_self ()) {
+                    ((HeapMem_Obj *)elem)->owner.openCount++;
+                }
+#ifdef ENABLE_LOCAL_LOCK
+                IGateProvider_leave (HeapMem_module->localLock, key);
+#endif
+                *handlePtr = (((HeapMem_Obj *)elem)->top);
+                doneFlag = TRUE;
+                break;
+            }
+        }
+
+        /* If not already existing locally, create object locally for open. */
+        if (EXPECT_FALSE (doneFlag == FALSE)) {
+            HeapMem_Params_init(&params);
+            params.sharedAddr = sharedAddr;
+            attrs = (HeapMem_Attrs *) sharedAddr;
+            id = SharedRegion_getId (sharedAddr);
+
+            if (EXPECT_FALSE (SharedRegion_isCacheEnabled (id))) {
+                Cache_inv (attrs,
+                           sizeof (HeapMem_Attrs),
+                           Cache_Type_ALL,
+                           TRUE);
+            }
+
+            if (EXPECT_FALSE (attrs->status != HeapMem_CREATED)) {
+                *handlePtr = NULL;
+                status = HeapMem_E_NOTFOUND;
+                /* Don't set failure reason since this is an expected
+                 * run-time failure.
+                 */
+                GT_1trace (curTrace,
+                           GT_3CLASS,
+                           "HeapMem Instance is not created yet at the "
+                           "provided shared addr.\n"
+                           "    sharedAddr [0x%x]!",
+                           sharedAddr);
+            }
+            else {
+                status = _HeapMem_create (handlePtr, &params, FALSE);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                if (EXPECT_FALSE (status < 0)) {
+                    GT_setFailureReason (curTrace,
+                                         GT_4CLASS,
+                                         "HeapMem_openByAddr",
+                                         status,
+                                         "_HeapMem_create failed!");
+                }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+            }
+        }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_openByAddr", status);
+
+    return (status);
+}
+
+/* =============================================================================
+ * Internal function
+ * =============================================================================
+ */
+GateMP_Handle HeapMem_getGate(HeapMem_Handle handle)
+{
+    HeapMem_Object *  object;
+    HeapMem_Obj    *  obj;
+
+    object = (HeapMem_Object *)handle;
+    obj = (HeapMem_Obj *)(object->obj);
+    return(obj->gate);
+}
+
+/* Creates a new instance of HeapMem module.
+ * This is an internal function as both HeapMem_create
+ * and HeapMem_open use the functionality.
+ */
+Int
+_HeapMem_create (      HeapMem_Handle *  handlePtr,
+                   const HeapMem_Params *  params,
+                         Bool                createFlag)
+{
+    Int                 status = HeapMem_S_SUCCESS;
+    HeapMem_Obj    *  obj    = NULL;
+    HeapMem_Object *  handle = NULL;
+#ifdef ENABLE_GATEMP
+    GateMP_Handle       gateHandle = NULL;
+    Ptr                 localAddr = NULL;
+    SharedRegion_SRPtr  sharedShmBase;
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+    IArg                key;
+#endif
+
+    GT_3trace (curTrace, GT_ENTER, "_HeapMem_create",
+               handlePtr, params, createFlag);
+
+    GT_assert (curTrace, (handlePtr != NULL));
+    GT_assert (curTrace, (params != NULL));
+
+    /* No need for parameter checks, since this is an internal function. */
+
+    /* Create the generic handle */
+    handle = (HeapMem_Object *) Memory_calloc (NULL,
+                                                 sizeof (HeapMem_Object),
+                                                 0u,
+                                                 NULL);
+    *handlePtr = (HeapMem_Handle) handle;
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (handle == NULL) {
+        /*! @retval HeapMem_E_MEMORY Memory allocation failed for pointer of
+         *          type HeapMem_Object
+         */
+        status = HeapMem_E_MEMORY;
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "_HeapMem_create",
+                             status,
+                             "Memory allocation failed for pointer"
+                             " of type HeapMem_Object!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        /* Create the Heap Buf specific handle */
+        obj = (HeapMem_Obj *) Memory_calloc (NULL,
+                                               sizeof (HeapMem_Obj),
+                                               0u,
+                                               NULL);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        if (obj == NULL) {
+            /*! @retval HeapMem_E_MEMORY Memory allocation failed for pointer
+             *          of type HeapMem_Obj
+             */
+            status = HeapMem_E_MEMORY;
+            GT_setFailureReason (curTrace,
+                                 GT_4CLASS,
+                                 "_HeapMem_create",
+                                 status,
+                                 "Memory allocation failed for pointer"
+                                 " of type HeapMem_Obj");
+        }
+        else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+            handle->obj = (HeapMem_Obj *) obj ;
+            handle->alloc = (IHeap_allocFxn) &HeapMem_alloc;
+            handle->free  = (IHeap_freeFxn) &HeapMem_free;
+            handle->getStats     = (IHeap_getStatsFxn) &HeapMem_getStats;
+            handle->getKnlHandle = (IHeap_getKnlHandleFxn)
+                                                    &HeapMem_getKnlHandle;
+            handle->isBlocking   = (IHeap_isBlockingFxn) &HeapMem_isBlocking;
+
+            obj->nsKey     = NULL;
+            obj->allocSize = 0;
+
+            /* Put in the local list */
+#ifdef ENABLE_LOCAL_LOCK
+            key = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+            List_elemClear (&obj->listElem);
+            List_put ((List_Handle) &HeapMem_module->objList, &obj->listElem);
+#ifdef ENABLE_LOCAL_LOCK
+            IGateProvider_leave (HeapMem_module->localLock, key);
+#endif
+
+            if (createFlag == FALSE) {
+                obj->owner.creator = FALSE;
+                obj->owner.openCount = 0u;
+                obj->owner.procId = MultiProc_INVALIDID;
+                obj->top = handle;
+
+                obj->attrs = (HeapMem_Attrs *) params->sharedAddr;
+
+                /* No need to Cache_inv- already done in openByAddr() */
+                obj->buf = (Char *) SharedRegion_getPtr ((SharedRegion_SRPtr)
+                                                            obj->attrs->bufPtr);
+                obj->bufSize      = obj->attrs->head.size;
+                obj->regionId     = SharedRegion_getId (obj->buf);
+                GT_assert (curTrace,
+                           (obj->regionId != SharedRegion_INVALIDSRPTR));
+                obj->cacheEnabled = SharedRegion_isCacheEnabled (obj->regionId);
+
+                /* Set minAlign */
+                obj->minAlign = sizeof (HeapMem_Header); /* 64 bits = 8 bytes */
+                if (    SharedRegion_getCacheLineSize (obj->regionId)
+                    >   obj->minAlign) {
+                    obj->minAlign = SharedRegion_getCacheLineSize (
+                                                                obj->regionId);
+                }
+
+#ifdef ENABLE_GATEMP
+                localAddr = SharedRegion_getPtr (obj->attrs->gateMPAddr);
+                status = GateMP_openByAddr (localAddr, &gateHandle);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                if (status < 0) {
+                    /* Override the status with a HeapMem status code. */
+                    status = HeapMem_E_FAIL;
+                    GT_setFailureReason (curTrace,
+                                         GT_4CLASS,
+                                         "_HeapMem_create",
+                                         status,
+                                         "Failed to open GateMP!");
+                }
+                else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                    obj->gate = gateHandle;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#endif
+            }
+            else {
+                /* Creating the HeapMem ... */
+                obj->owner.creator = TRUE;
+                obj->owner.openCount = 1u;
+                obj->owner.procId = MultiProc_self ();
+                obj->top = handle;
+
+                /* Creating the gate */
+                if (params->gate != NULL) {
+                    obj->gate = params->gate;
+                }
+#ifdef ENABLE_GATEMP
+                else {
+                    /* If no gate specified, get the default system gate */
+                    obj->gate = GateMP_getDefaultRemote ();
+                }
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                if (obj->gate == NULL) {
+                    status = HeapMem_E_FAIL;
+                    GT_setFailureReason (curTrace,
+                                         GT_4CLASS,
+                                         "_HeapMem_create",
+                                         status,
+                                         "GateMP is NULL!");
+                }
+                else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                    obj->bufSize = params->sharedBufSize;
+
+                    if (params->sharedAddr == NULL) {
+                        /* Creating using a shared region ID */
+                        /* It is allowed to have NULL name for an anonymous, not
+                         * to be opened by name, heap.
+                         */
+                        obj->attrs = NULL; /* Will be alloced in postInit */
+                        obj->regionId = params->regionId;
+                    }
+                    else {
+                        /* Creating using sharedAddr */
+                        obj->regionId = SharedRegion_getId (params->sharedAddr);
+
+                        /* Assert that the buffer is in a valid shared
+                         * region
+                         */
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                        if (obj->regionId == SharedRegion_INVALIDREGIONID) {
+                            status = HeapMem_E_FAIL;
+                            /*! @retval HeapMem_E_FAIL params->sharedAddr is
+                                              not in a valid SharedRegion. */
+                            GT_setFailureReason (curTrace,
+                                                 GT_4CLASS,
+                                                 "_HeapMem_create",
+                                                 status,
+                                                 "params->sharedAddr is not in"
+                                                 " a valid SharedRegion!");
+                        }
+                        else if (  ((UInt32) params->sharedAddr
+                                 % SharedRegion_getCacheLineSize (obj->regionId)
+                                 != 0)) {
+                            status = HeapMem_E_FAIL;
+                            /*! @retval HeapMem_E_FAIL params->sharedAddr does
+                                        not meet cache alignment constraints */
+                            GT_setFailureReason (curTrace,
+                                         GT_4CLASS,
+                                         "_ListMP_create",
+                                         status,
+                                         "params->sharedAddr does not"
+                                         " meet cache alignment constraints!");
+                        }
+                        else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                            /* obj->buf will get alignment-adjusted in
+                             * postInit
+                             */
+                            obj->buf = (Ptr) (  (UInt32) params->sharedAddr
+                                              + sizeof (HeapMem_Attrs));
+                            obj->attrs = (HeapMem_Attrs *) params->sharedAddr;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                        }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                    }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                    if (status >= 0) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                        obj->cacheEnabled = SharedRegion_isCacheEnabled (
+                                                                obj->regionId);
+
+                        /* Set minAlign */
+                        obj->minAlign = sizeof (HeapMem_Header);
+                        if (    SharedRegion_getCacheLineSize(obj->regionId)
+                            >   obj->minAlign) {
+                            obj->minAlign = SharedRegion_getCacheLineSize (
+                                                                obj->regionId);
+                        }
+
+                        status = HeapMem_postInit ((HeapMem_Object *)
+                                                         handle);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                        if (EXPECT_FALSE (status < 0)) {
+                            GT_setFailureReason (curTrace,
+                                                 GT_4CLASS,
+                                                 "_HeapMem_create",
+                                                 status,
+                                                 "HeapMem_postInit failed!");
+                        }
+                    }
+                }
+
+                if (status >= 0) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                    /* Populate the params member */
+                    memcpy ((Ptr) &obj->params,
+                                 (Ptr) params,
+                                 sizeof (HeapMem_Params));
+
+                    /* Copy the name */
+                    if (params->name != NULL) {
+                        obj->params.name = (String) Memory_alloc (NULL,
+                                            (strlen (params->name)+ 1u),
+                                            0,
+                                            NULL);
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                        if (obj->params.name == NULL) {
+                            /*! @retval HeapMem_E_MEMORY Memory allocation
+                             *          failed for name
+                             */
+                            status = HeapMem_E_MEMORY;
+                            GT_setFailureReason (curTrace,
+                                                 GT_4CLASS,
+                                                 "_HeapMem_create",
+                                                 status,
+                                                 "Memory allocation "
+                                                 "failed for name!");
+                        }
+                        else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                            strncpy (obj->params.name,
+                                         params->name,
+                                         strlen (params->name) + 1u);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+                        }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                    }
+                }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+            }
+        }
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (status < 0) {
+        if (createFlag == TRUE) {
+            HeapMem_delete ((HeapMem_Handle *) handlePtr);
+        }
+        else {
+            HeapMem_close ((HeapMem_Handle *) handlePtr);
+        }
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "_HeapMem_create", status);
+
+    /*! @retval HeapMem_S_SUCCESS Operation successful*/
+    return status;
+}
+
+/*
+ *  Slice and dice the buffer up into the correct size blocks and
+ *  add to the freelist.
+ */
+Int
+HeapMem_postInit (HeapMem_Object * handle)
+{
+    Int              status     = HeapMem_S_SUCCESS;
+    HeapMem_Obj *  obj        = NULL;
+    HeapMem_Handle regionHeap = NULL;
+    HeapMem_Params params;
+
+    GT_0trace (curTrace, GT_LEAVE, "HeapMem_postInit");
+
+    GT_assert (curTrace, (handle != NULL));
+
+    /* No need for parameter checks, since this is an internal function. */
+
+    obj = handle->obj;
+
+    if (obj->attrs == NULL) {
+        /* Need to allocate from the heap */
+        HeapMem_Params_init (&params);
+        params.regionId      = obj->regionId;
+        params.sharedBufSize = obj->bufSize;
+        obj->allocSize = HeapMem_sharedMemReq (&params);
+        regionHeap = SharedRegion_getHeap (obj->regionId);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        if (regionHeap == NULL) {
+            status = HeapMem_E_FAIL;
+            GT_setFailureReason (curTrace,
+                                 GT_4CLASS,
+                                 "HeapMem_postInit",
+                                 status,
+                                 "Shared Region heap is null!");
+
+        }
+        else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+            obj->attrs = Memory_alloc ((IHeap_Handle) regionHeap,
+                                       obj->allocSize,
+                                       obj->minAlign,
+                                       NULL);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+            if (obj->attrs == NULL) {
+                status = HeapMem_E_MEMORY;
+                GT_setFailureReason (curTrace,
+                                     GT_4CLASS,
+                                     "HeapMem_postInit",
+                                     status,
+                                     "Failed to allocate shared memory!");
+            }
+            else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+                obj->buf = (Ptr)((UInt32)obj->attrs + sizeof(HeapMem_Attrs));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+            }
+        }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+    }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (status >= 0) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        /* Round obj->buf up by obj->minAlign */
+        obj->buf = (Ptr) ROUNDUP ((obj->buf), (obj->minAlign));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        if (EXPECT_FALSE (  obj->bufSize
+                          < SharedRegion_getCacheLineSize (obj->regionId))) {
+            status = HeapMem_E_FAIL;
+            GT_setFailureReason (curTrace,
+                                 GT_4CLASS,
+                                 "HeapMem_postInit",
+                                 status,
+                                 "Buffer is not large enough!");
+        }
+        else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+            /* Make sure the size is a multiple of obj->minAlign */
+            obj->bufSize = (obj->bufSize / obj->minAlign) * obj->minAlign;
+#ifdef ENABLE_GATEMP
+            obj->attrs->gateMPAddr = GateMP_getSharedAddr (obj->gate);
+#endif
+            obj->attrs->bufPtr     = SharedRegion_getSRPtr (obj->buf,
+                                                            obj->regionId);
+
+            /* Store computed obj->bufSize in shared mem */
+            obj->attrs->head.size = obj->bufSize;
+
+            /* Place the initial header */
+            HeapMem_restore ((HeapMem_Handle) handle);
+
+            /* Last thing, set the status */
+            obj->attrs->status = HeapMem_CREATED;
+
+            if (EXPECT_FALSE (obj->cacheEnabled)) {
+                Cache_wbInv ((Ptr) obj->attrs,
+                             sizeof (HeapMem_Attrs),
+                             Cache_Type_ALL,
+                             TRUE);
+            }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+        }
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "HeapMem_postInit", status);
+
+    return status;
+}
+
+/* Restore an instance to it's original created state. */
+Void
+HeapMem_restore (HeapMem_Handle handle)
+{
+    HeapMem_Header * begHeader = NULL;
+    HeapMem_Obj    * obj       = NULL;
+
+    GT_1trace (curTrace, GT_ENTER, "HeapMem_restore", handle);
+
+    obj = ((HeapMem_Object *) handle)->obj;
+    GT_assert (curTrace, (obj != NULL));
+
+    /*
+     *  Fill in the top of the memory block
+     *  next: pointer will be NULL (end of the list)
+     *  size: size of this block
+     *  NOTE: no need to Cache_inv because obj->attrs->bufPtr should be const
+     */
+    begHeader = (HeapMem_Header *) obj->buf;
+    begHeader->next = (SharedRegion_SRPtr) SharedRegion_INVALIDSRPTR;
+    begHeader->size = obj->bufSize;
+
+    obj->attrs->head.next = obj->attrs->bufPtr;
+    if (EXPECT_FALSE (obj->cacheEnabled)) {
+        Cache_wbInv ((Ptr) &(obj->attrs->head),
+                     sizeof (HeapMem_Header),
+                     Cache_Type_ALL,
+                     FALSE);
+        Cache_wbInv (begHeader,
+                     sizeof (HeapMem_Header),
+                     Cache_Type_ALL,
+                     TRUE);
+    }
+
+    GT_0trace (curTrace, GT_LEAVE, "HeapMem_restore");
+}
diff --git a/host_linux/simple_buffer_example/host/HeapMem/src/inc/_HeapMem.h b/host_linux/simple_buffer_example/host/HeapMem/src/inc/_HeapMem.h
new file mode 100755 (executable)
index 0000000..6569135
--- /dev/null
@@ -0,0 +1,131 @@
+/** 
+ *  @file   _HeapMem.h
+ *
+ *  @brief      Defines HeapMem based memory allocator.
+ *
+ *
+ */
+/* 
+ *  ============================================================================
+ *
+ *  Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ *  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.
+ *  Contact information for paper mail:
+ *  Texas Instruments
+ *  Post Office Box 655303
+ *  Dallas, Texas 75265
+ *  Contact information: 
+ *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ *  ============================================================================
+ *  
+ */
+
+
+
+#ifndef HeapMem_H_0x4C56
+#define HeapMem_H_0x4C56
+
+
+/* Osal & Utils headers */
+#include "IHeap.h"
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/*!
+ *  @def    HeapMem_MODULEID
+ *  @brief  Unique module ID.
+ */
+#define HeapMem_MODULEID        (0x4AD8)
+
+/*!
+ *  @var    HeapMem_CREATED
+ *
+ *  @brief  HeapMemMp tag used in the attrs->status field
+ */
+#define HeapMem_CREATED     0x07041976
+
+/*
+ *  @brief  Object for the HeapMem Handle
+ */
+#define HeapMem_Object IHeap_Object
+
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+
+/* =============================================================================
+ *  APIs
+ * =============================================================================
+ */
+
+/*!
+ *  @brief      Function to destroy the HeapMem module.
+ *
+ *  @param      None
+ *
+ *  @sa         HeapMem_setup
+ *              HeapMem_getConfig
+ *              NameServer_create
+ *              NameServer_delete
+ *              GateMutex_delete
+ */
+Int HeapMem_destroy (void);
+
+/*!
+ *  @brief      Returns the HeapMem kernel object pointer.
+ *
+ *  @param      handle  Handle to previousely created/opened instance.
+ *
+ */
+Ptr HeapMem_getKnlHandle (HeapMem_Handle hpHandle);
+
+/*!
+ *  @brief      Returns a HeapMem user object pointer.
+ *
+ *  @param      handle  Handle to kernel handle for which user handle is to be
+ *                      provided.
+ *
+ */
+Ptr HeapMem_getUsrHandle (HeapMem_Handle hpHandle);
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* HeapMem_H_0x4C56 */
+
diff --git a/host_linux/simple_buffer_example/host/IGateProvider.h b/host_linux/simple_buffer_example/host/IGateProvider.h
new file mode 100644 (file)
index 0000000..8339401
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2013-2014, 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.
+ */
+
+/*
+ *  ======= IGateProvider.h ========
+ *
+ *  Interface implemented by all gate providers.
+ *
+ *  Gates are used serialize access to data structures that are used by more
+ *  than one thread.
+ *
+ *  Gates are responsible for ensuring that only one out of multiple threads
+ *  can access a data structure at a time.  There
+ *  are important scheduling latency and performance considerations that
+ *  affect the "type" of gate used to protect each data structure.  For
+ *  example, the best way to protect a shared counter is to simply disable
+ *  all interrupts before the update and restore the interrupt state after
+ *  the update; disabling all interrupts prevents all thread switching, so
+ *  the update is guaranteed to be "atomic".  Although highly efficient, this
+ *  method of creating atomic sections causes serious system latencies when
+ *  the time required to update the data structure can't be bounded.
+ *
+ *  For example, a memory manager's list of free blocks can grow indefinitely
+ *  long during periods of high fragmentation.  Searching such a list with
+ *  interrupts disabled would cause system latencies to also become unbounded.
+ *  In this case, the best solution is to provide a gate that suspends the
+ *  execution of  threads that try to enter a gate that has already been
+ *  entered; i.e., the gate "blocks" the thread until the thread
+ *  already in the gate leaves.  The time required to enter and leave the
+ *  gate is greater than simply enabling and restoring interrupts, but since
+ *  the time spent within the gate is relatively large, the overhead caused by
+ *  entering and leaving gates will not become a significant percentage of
+ *  overall system time.  More importantly, threads that do not need to
+ *  access the shared data structure are completely unaffected by threads
+ *  that do access it.
+ *
+ */
+
+#ifndef __IGATEPROVIDER_H__
+#define __IGATEPROVIDER_H__
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ *  Macros
+ * -----------------------------------------------------------------------------
+ */
+/*! Invalid Igate */
+#define IGateProvider_NULL      (IGateProvider_Handle)0xFFFFFFFF
+
+/*!
+ *  ======== IGateProvider_Q_BLOCKING ========
+ *  Blocking quality
+ *
+ *  Gates with this "quality" may cause the calling thread to block;
+ *  i.e., suspend execution until another thread leaves the gate.
+ */
+#define IGateProvider_Q_BLOCKING 1
+
+/*!
+ *  ======== IGateProvider_Q_PREEMPTING ========
+ *  Preempting quality
+ *
+ *  Gates with this "quality" allow other threads to preempt the thread
+ *  that has already entered the gate.
+ */
+#define IGateProvider_Q_PREEMPTING 2
+
+/*!
+ *  ======== IGateProvider_SuperObject ========
+ *  Object embedded in other Gate modules. (Inheritance)
+ */
+#define IGateProvider_SuperObject                                              \
+        IGateProvider_ENTER enter;                                             \
+        IGateProvider_LEAVE leave
+
+
+/*!
+ *
+ */
+#define IGateProvider_ObjectInitializer(x,y)                                   \
+        ((IGateProvider_Handle)(x))->enter = (IGateProvider_ENTER)y##_enter;   \
+        ((IGateProvider_Handle)(x))->leave = (IGateProvider_LEAVE)y##_leave;
+
+/* -----------------------------------------------------------------------------
+ *  Defines
+ * -----------------------------------------------------------------------------
+ */
+/*! Prototype of enter function */
+typedef IArg (*IGateProvider_ENTER) (Void *);
+
+/*! Prototype of leave function */
+typedef Void (*IGateProvider_LEAVE) (Void *, IArg);
+
+
+/* -----------------------------------------------------------------------------
+ *  Structs & Enums
+ * -----------------------------------------------------------------------------
+ */
+/*!
+ * Structure for generic gate instance
+ */
+typedef struct IGateProvider_Object {
+        IGateProvider_SuperObject;
+} IGateProvider_Object, *IGateProvider_Handle;
+
+
+/* -----------------------------------------------------------------------------
+ *  APIs
+ * -----------------------------------------------------------------------------
+ */
+/*!
+ *  Enter this gate
+ *
+ *  Each gate provider can implement mutual exclusion using different
+ *  algorithms; e.g., disabling all scheduling, disabling the scheduling
+ *  of all threads below a specified "priority level", suspending the
+ *  caller when the gate has been entered by another thread and
+ *  re-enabling it when the the other thread leaves the gate.  However,
+ *  in all cases, after this method returns that caller has exclusive
+ *  access to the data protected by this gate.
+ *
+ *  A thread may reenter a gate without blocking or failing.
+ *
+ *  @param handle Handle to the Gate.
+ *
+ *  @retval IArg Returns the instance specific return values.
+ *
+ *  @sa IGateProvider_leave
+ *
+ */
+static inline IArg IGateProvider_enter (IGateProvider_Handle  handle)
+{
+    IArg key = 0;
+
+    if (handle != 0x0 && handle != IGateProvider_NULL) {
+        key = (handle->enter) ((void *)handle);
+    }
+    return key;
+}
+
+
+/*!
+ *  Leave this gate
+ *
+ *  This method is only called by threads that have previously entered
+ *  this gate via `{@link #enter}`.  After this method returns, the
+ *  caller must not access the data structure protected by this gate
+ *  (unless the caller has entered the gate more than once and other
+ *  calls to `leave` remain to balance the number of previous
+ *  calls to `enter`).
+ *
+ *  @param handle Handle to the Gate.
+ *  @param key    Instance specific argument.
+ *
+ *  @sa IGateProvider_enter
+ *
+ */
+static inline Void IGateProvider_leave (IGateProvider_Handle  handle, IArg key)
+{
+    if (handle != 0x0 && handle != IGateProvider_NULL)
+        (handle->leave) ((void *)handle, key);
+}
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* ifndef __IGATEPROVIDER_H__ */
diff --git a/host_linux/simple_buffer_example/host/SharedRegion/SharedRegion.h b/host_linux/simple_buffer_example/host/SharedRegion/SharedRegion.h
new file mode 100644 (file)
index 0000000..02d7cfc
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 2017 Texas Instruments Incorporated - http://www.ti.com
+ * 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       SharedRegion.h
+ *
+ *  @brief      Shared memory manager and address translator
+ *
+ *  @note       SharedRegion is currently only available for SYS/BIOS.
+ *
+ *  The SharedRegion module is designed to be used in a multi-processor
+ *  environment in which memory regions are shared and accessed
+ *  across different processors. The module itself does not use any shared
+ *  memory, because all module state is stored locally.  SharedRegion
+ *  APIs use the system gate for thread protection.
+ *
+ *  This module creates and stores a local shared memory region table.  The
+ *  table contains the processor's view for every shared region in the system.
+ *  The table must not contain any overlapping regions.  Each processor's
+ *  view of a particular shared memory region is determined by the region id.
+ *  In cases where a processor cannot access a certain shared memory region,
+ *  that shared memory region should be left invalid for that processor.
+ *  Note:  The number of entries must be the same on all processors.
+ *
+ *  Each shared region contains the following:
+ *    - @b base - The base address
+ *    - @b len - The length
+ *    - @b name - The name of the region
+ *    - @b isValid - Whether the region is valid
+ *    - @b ownerProcId - The id of the processor which owns the region
+ *    - @b cacheEnable - Whether the region is cacheable
+ *    - @b cacheLineSize - The cache line size
+ *    - @b createHeap - Whether a heap is created for the region.
+ *
+ *  A region is added using the SharedRegion_setEntry() API.
+ *  The length of a region must be the same across all processors.
+ *  The owner of the region can be specified.  If specified, the owner
+ *  manages the shared region.  It creates a HeapMemMP instance which spans
+ *  the full size of the region.  The other processors open the same HeapMemMP
+ *  instance.
+ *
+ *  Note: Prior to calling Ipc_start(), If a SharedRegion's 'isValid'
+ *  is true and 'createHeap' is true then the owner of the SharedRegion
+ *  must be the same as the owner of SharedRegion 0.
+ *
+ *  After a shared region is valid, SharedRegion APIs can be used to convert
+ *  pointers between the local processor's address space and the SharedRegion-
+ *  pointer (SRPtr) address space.  These APIs include
+ *  SharedRegion_getId(), SharedRegion_getSRPtr() and SharedRegion_getPtr().
+ *  An example is shown below:
+ *
+ *  @code
+ *  SharedRegion_SRPtr srptr;
+ *  Ptr     addr;
+ *  UInt16  id;
+ *
+ *  // to get the id of the local address if id is not already known.
+ *  id = SharedRegion_getId(addr);
+ *
+ *  // to get the shared region pointer for the local address
+ *  srptr = SharedRegion_getSRPtr(addr, id);
+ *
+ *  // to get the local address from the shared region pointer
+ *  addr = SharedRegion_getPtr(srptr);
+ *  @endcode
+ *
+ *  The SharedRegion header should be included in an application as follows:
+ *  @code
+ *  #include <ti/ipc/SharedRegion.h>
+ *  @endcode
+ */
+
+#ifndef SharedRegion__include
+#define SharedRegion__include
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* ============================================================================
+ *  All success and failure codes for the module
+ * =============================================================================
+ */
+
+/*!
+ *  @brief  The resource is still in use
+ */
+#define SharedRegion_S_BUSY             2
+
+/*!
+ *  @brief  The module has been already setup
+ */
+#define SharedRegion_S_ALREADYSETUP     1
+
+/*!
+ *  @brief  Operation is successful.
+ */
+#define SharedRegion_S_SUCCESS          0
+
+/*!
+ *  @brief  Generic failure.
+ */
+#define SharedRegion_E_FAIL             -1
+
+/*!
+ *  @brief  Argument passed to function is invalid.
+ */
+#define SharedRegion_E_INVALIDARG       -2
+
+/*!
+ *  @brief  Operation resulted in memory failure.
+ */
+#define SharedRegion_E_MEMORY           -3
+
+/*!
+ *  @brief  The specified entity already exists.
+ */
+#define SharedRegion_E_ALREADYEXISTS    -4
+
+/*!
+ *  @brief  Unable to find the specified entity.
+ */
+#define SharedRegion_E_NOTFOUND         -5
+
+/*!
+ *  @brief  Operation timed out.
+ */
+#define SharedRegion_E_TIMEOUT          -6
+
+/*!
+ *  @brief  Module is not initialized.
+ */
+#define SharedRegion_E_INVALIDSTATE     -7
+
+/*!
+ *  @brief  A failure occurred in an OS-specific call
+ */
+#define SharedRegion_E_OSFAILURE        -8
+
+/*!
+ *  @brief  Specified resource is not available
+ */
+#define SharedRegion_E_RESOURCE         -9
+
+/*!
+ *  @brief  Operation was interrupted. Please restart the operation
+ */
+#define SharedRegion_E_RESTART          -10
+
+/* =============================================================================
+ *  Macros
+ * =============================================================================
+ */
+
+/*!
+ *  @brief  Invalid region id
+ */
+#define SharedRegion_INVALIDREGIONID    (0xFFFF)
+
+/* =============================================================================
+ *  Structures & Enums
+ * =============================================================================
+ */
+/*!
+ *  @brief  Module configuration structure.
+ */
+typedef struct SharedRegion_Config {
+    SizeT      cacheLineSize;
+    /*!<
+     *  Worst-case cache line size
+     *
+     *  This is the default system cache line size for all modules.
+     *  When a module puts structures in shared memory, this value is
+     *  used to make sure items are aligned on a cache line boundary.
+     *  If no cacheLineSize is specified for a region, it will use this
+     *  value.
+     */
+
+    UInt16     numEntries;
+    /*!<
+     *  The number of shared region table entries.
+     *
+     *  This value is used for calculating the number of bits for the offset.
+     *  Note: This value must be the same across all processors in the system.
+     *        Increasing this parameter will increase the footprint and
+     *        the time for translating a pointer to a SRPtr.
+     */
+
+    Bool       translate;
+    /*!< This configuration parameter should be set to 'true'
+     *   if and only if all shared memory regions are the same
+     *   for all processors. If 'true', it results in a fast
+     *   getPtr and getSRPtr.
+     */
+} SharedRegion_Config;
+
+/*!
+ *  @brief  SharedRegion pointer type
+ */
+typedef Bits32 SharedRegion_SRPtr;
+
+/*!
+ *  @brief  Structure defining a region
+ */
+typedef struct SharedRegion_Entry {
+    Ptr base;
+    /*!< @brief The base address of the region */
+
+    SizeT len;
+    /*!< @brief The length of the region
+     *
+     *  The length of a region must be the same across all
+     *  processors in the system.
+     */
+
+    UInt16 ownerProcId;
+    /*!< @brief The MultiProc id of the owner of the region
+     *
+     *  The owner id for a shared region must be the same across
+     *  all processors in the system.
+     */
+
+    Bool isValid;
+    /*!< @brief Whether the region is valid */
+
+    Bool cacheEnable;
+    /*!< @brief Whether to perform cache operations for the region
+     *
+     *  If 'TRUE', a cache invalidate is performed before any read
+     *  and a cache write back invalidate is performed after any
+     *  write for the shared region.  The cache operations are done
+     *  for all caches.  If 'FALSE', no cache operations are performed.
+     */
+
+    SizeT cacheLineSize;
+    /*!< @brief The cache line size of the region
+     *
+     *  The cache line size for a region must be the same across
+     *  all processors in the system.  It is used for structure
+     *  alignment and padding.
+     */
+
+    Bool createHeap;
+    /*!< @brief Whether a heap is created for the region
+     *
+     *  If 'TRUE', a HeapMemMP instance is created with the size
+     *  spanning the length of the shared region minus any memory
+     *  that is reserved in the region.  If 'FALSE', no heap
+     *  is created in the shared region.
+     */
+
+    String name;
+    /*!< @brief The name of the region.
+     *
+     *  The name must be in persistent memory.  It is used for
+     *  displaying in ROV.
+     */
+} SharedRegion_Entry;
+
+
+/* =============================================================================
+ *  SharedRegion Module-wide Functions
+ * =============================================================================
+ */
+
+/*!
+ *  @brief      Clears the @c regionid entry
+ *
+ *  SharedRegion_clearEntry() is used to render invalid a shared region that is
+ *  currently valid.  If the region has a heap, it will either be closed or
+ *  deleted as necessary.  All attributes of region are reset to defaults.
+ *
+ *  Calling SharedRegion_clearEntry() upon a region that is already invalid
+ *  simply resets the region attributes to their defaults.
+ *
+ *  @note Region #0 is special and can neither be cleared nor set.
+ *
+ *  @param      regionId  the region id
+ *
+ *  @return     Status
+ *              - #SharedRegion_S_SUCCESS:  Operation was successful
+ *              - #SharedRegion_E_FAIL:  Delete or close of heap created
+ *                in region failed.
+ *
+ *  @sa         SharedRegion_setEntry()
+ */
+Int SharedRegion_clearEntry(UInt16 regionId);
+
+/*!
+ *  @brief      Initializes the entry fields
+ *
+ *  @param      entry  pointer to a SharedRegion entry
+ *
+ *  @sa         SharedRegion_setEntry()
+ */
+Void SharedRegion_entryInit(SharedRegion_Entry *entry);
+
+/*!
+ *  @brief      Gets the cache line size for the specified region id
+ *
+ *  @param      regionId  the region id
+ *
+ *  @return     Cache line size
+ *
+ *  @sa         SharedRegion_isCacheEnabled()
+ */
+SizeT SharedRegion_getCacheLineSize(UInt16 regionId);
+
+/*!
+ *  @brief      Gets the entry information for the specified region id
+ *
+ *  @param      regionId  the region id
+ *  @param      entry     pointer to return region information
+ *
+ *  @return     Status
+ *              - #SharedRegion_S_SUCCESS:  Operation was successful
+ *              - #SharedRegion_E_FAIL:  Operation failed
+ *
+ *  @sa         SharedRegion_setEntry()
+ */
+Int SharedRegion_getEntry(UInt16 regionId, SharedRegion_Entry *entry);
+
+/*!
+ *  @brief      Return the address of the shared region entry structure
+ *
+ *  This function is to be used only for module startup configuration.
+ *  The returned address gives you direct access to the in-memory entry
+ *  structure. Use it to configure the entry just before the module
+ *  startup phase begins. It is intended to support single-image loading.
+ *
+ *  Do not use this function during normal run-time operations; use
+ *  SharedRegion_getEntry() instead.
+ */
+SharedRegion_Entry *SharedRegion_getEntryPtr(UInt16 regionId);
+
+/*!
+ *  @brief      Gets the heap associated with the specified region id
+ *
+ *  The heap handle returned is of type xdc.runtime.IHeap.
+ *  This handle type can be used with xdc.runtime.Memory.
+ *
+ *  The following code shows an example.
+ *
+ *  @code
+ *  #include <xdc/runtime/IHeap.h>
+ *  #include <xdc/runtime/Memory.h>
+ *  #include <ti/ipc/SharedRegion.h>
+ *
+ *  IHeap_Handle heap;
+ *  UInt16       regionId;
+ *  SizeT        size;
+ *  SizeT        align;
+ *
+ *  heap = (IHeap_Handle)SharedRegion_getHeap(regionId);  // get the heap
+ *  Memory_alloc(heap, size, align, NULL);  // alloc memory from heap
+ *  @endcode
+ *
+ *  @param      regionId  the region id
+ *
+ *  @return     Handle of the heap, NULL if the region has no heap
+ */
+Ptr SharedRegion_getHeap(UInt16 regionId);
+
+/*!
+ *  @brief      Gets the region id for the specified address
+ *
+ *  @param      addr  address
+ *
+ *  @return     region id
+ */
+UInt16 SharedRegion_getId(Ptr addr);
+
+/*!
+ *  @brief      Gets the id of a region, given its name
+ *
+ *  @param      name  name of the region
+ *
+ *  @return     region id
+ */
+UInt16 SharedRegion_getIdByName(String name);
+
+/*!
+ *  @brief      Gets the number of regions
+ *
+ *  @return     number of regions
+ */
+UInt16 SharedRegion_getNumRegions(Void);
+
+/*!
+ *  @brief      Calculate the local pointer from the shared region pointer
+ *
+ *  @param      srptr  SharedRegion pointer
+ *
+ *  @return     local pointer or NULL if shared region pointer is invalid
+ *
+ *  @sa         SharedRegion_getSRPtr()
+ */
+Ptr SharedRegion_getPtr(SharedRegion_SRPtr srptr);
+
+/*!
+ *  @brief      Calculate the shared region pointer given local address and id
+ *
+ *  @param      addr      the local address
+ *  @param      regionId  region id
+ *
+ *  @return     SharedRegion pointer
+ *
+ *  @sa         SharedRegion_getPtr()
+ */
+SharedRegion_SRPtr SharedRegion_getSRPtr(Ptr addr, UInt16 regionId);
+
+/*!
+ *  @brief      whether cache enable was specified
+ *
+ *  @param      regionId  region id
+ *
+ *  @return     'TRUE' if cache enable specified, otherwise 'FALSE'
+ */
+Bool SharedRegion_isCacheEnabled(UInt16 regionId);
+
+/*!
+ *  @brief      Sets the entry at the specified region id
+ *
+ *  SharedRegion_setEntry() is used to set up a shared region that is
+ *  currently invalid.  Configuration is performed using the values supplied
+ *  in the 'entry' parameter.  If the 'createHeap' flag is TRUE, then a
+ *  region heap will be created (if the processor is the region owner)
+ *  or opened.
+ *
+ *  If 'createHeap' is TRUE, SharedRegion_setEntry() must always be called by
+ *  a 'client' of the shared region only after the region owner has called
+ *  SharedRegion_setEntry().  It is unsafe to poll using SharedRegion_setEntry()
+ *  to wait for the corresponding heap to be created by the owner.  An external
+ *  synchronization mechanism (i.e. Notify, shared memory, etc) must be used
+ *  to ensure the proper sequence of operations.
+ *
+ *  NOTE: This function should never be called upon a region
+ *  that is currently valid.
+ *
+ *  @param      regionId  region id
+ *  @param      entry     pointer to set region information.
+ *
+ *  @return     Status
+ *              - #SharedRegion_S_SUCCESS:  Operation was successful
+ *              - #SharedRegion_E_FAIL:  Region already exists or overlaps with
+ *                 with another region
+ *              - #SharedRegion_E_MEMORY: Unable to create Heap
+ */
+Int SharedRegion_setEntry(UInt16 regionId, SharedRegion_Entry *entry);
+
+/*!
+ *  @brief      Whether address translation is enabled
+ *
+ *  @return     'TRUE' if translate is enabled otherwise 'FALSE'
+ */
+Bool SharedRegion_translateEnabled(Void);
+
+/*!
+ *  @brief      Returns the SharedRegion_SRPtr value that maps to NULL
+ *
+ *  @return     Value in SRPtr-space that maps to NULL in Ptr-space
+ */
+SharedRegion_SRPtr SharedRegion_invalidSRPtr(Void);
+
+/*!
+ *  @brief      Function to setup the SharedRegion module.
+ *
+ *  @param      cfgParams   Configuration values.
+ */
+Void SharedRegion_getConfig (SharedRegion_Config * config);
+
+/*!
+ *  @brief      Function to setup the SharedRegion module.
+ *
+ *              Here if user passes both numEntries and indexBits, than
+ *              numEntries takes precedence over indexBits.
+ *
+ *  @param      cfg   Configuration values.
+ *
+ *  @sa         SharedRegion_destroy
+ */
+Int SharedRegion_setup (SharedRegion_Config * config);
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* SharedRegion__include */
diff --git a/host_linux/simple_buffer_example/host/SharedRegion/src/SharedRegion.c b/host_linux/simple_buffer_example/host/SharedRegion/src/SharedRegion.c
new file mode 100755 (executable)
index 0000000..f9c4ae1
--- /dev/null
@@ -0,0 +1,1481 @@
+/*
+ *  Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ *  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   SharedRegion.c
+ *
+ *  @brief  Shared Region Manager
+ */
+
+/* Standard headers */
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* IPC headers */
+#include <ti/ipc/Std.h>
+#include "Std.h"
+#include <ti/ipc/MultiProc.h>
+#include <IGateProvider.h>
+#include <GateMutex.h>
+
+#include "Trace.h"
+#include "Cache.h"
+#include "Memory.h"
+
+#include "_SharedRegion.h"
+
+#define ENABLE_LOCAL_LOCK
+
+#define ROUNDUP(size, align) \
+    (UInt32)(((UInt32)(size) + ((UInt32)(align) - 1)) & ~((UInt32)(align) - 1))
+
+/* =============================================================================
+ * Macros
+ * =============================================================================
+ */
+/* Macro to make a correct module magic number with refCount */
+#define SharedRegion_MAKE_MAGICSTAMP(x) ((SharedRegion_MODULEID << 16u) | (x))
+
+/* =============================================================================
+ * Structure & Enums
+ * =============================================================================
+ */
+
+/*!
+ *  @brief  Module state object.
+ */
+typedef struct SharedRegion_ModuleObject_tag {
+    UInt32                    refCount;
+    /*!< Reference count */
+#ifdef ENABLE_LOCAL_LOCK
+    IGateProvider_Handle      localLock;
+    /*!< Handle to a gate instance */
+#endif
+    SharedRegion_Region     * regions;
+    /*!< Pointer to the regions */
+    SharedRegion_Config       cfg;
+    /*!< Current config values */
+    SharedRegion_Config       defCfg;
+    /*!< Default config values */
+    UInt32                    numOffsetBits;
+    /*!< number of bits for the offset for a SRPtr. This value is calculated */
+    UInt32                    offsetMask;
+    /*!< offset bitmask using for generating a SRPtr */
+    bool                      isStarted;
+    /*!< indicates whether shared region start API is called */
+    UInt32                    *regionRefCount;
+    /* To keep track of how many start/stop region API is  called for a region*/
+} SharedRegion_ModuleObject;
+
+/* =============================================================================
+ * Global
+ * =============================================================================
+ */
+/*!
+ *  @brief  Shared region state object variable with default settings
+ */
+static
+SharedRegion_ModuleObject SharedRegion_state = {
+    .numOffsetBits        = 0,
+    .regions              = NULL,
+#ifdef ENABLE_LOCAL_LOCK
+    .localLock            = NULL,
+#endif
+    .regionRefCount       = NULL,
+    .offsetMask           = 0,
+    .defCfg.numEntries    = 4u,
+    .defCfg.translate     = TRUE,
+    .defCfg.cacheLineSize = 128u
+};
+
+/*!
+ *  @var    SharedRegion_module
+ *
+ *  @brief  Pointer to the SharedRegion module state.
+ */
+static
+SharedRegion_ModuleObject * SharedRegion_module = &SharedRegion_state;
+
+/*!
+ *  @brief  SharedRegion_CREATED flag in shared memory
+ */
+const UInt32 SharedRegion_CREATED = 0x08111963;
+
+/*!
+ *  @brief  SharedRegion_VERSION attribute in shared memory
+ */
+const UInt32 SharedRegion_VERSION = 1;
+
+/* =============================================================================
+ * Forward declarations of internal functions
+ * =============================================================================
+ */
+/*!
+ *  @brief      Checks to make sure overlap does not exists.
+ *              Return error if overlap found.
+ *
+ *  @param      base      Base of Shared Region
+ *  @param      len       Length of Shared Region
+ *
+ *  @sa         None
+ */
+static Int SharedRegion_checkOverlap (Ptr base, UInt32 len);
+
+/*
+ *  @brief      Return the number of offsetBits bits
+ *
+ *  @param      None
+ *
+ *  @sa         None
+ */
+static UInt32 SharedRegion_getNumOffsetBits (Void);
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+/* Function to get the configuration */
+Void
+SharedRegion_getConfig (SharedRegion_Config * config)
+{
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_getConfig", config);
+
+    GT_assert (curTrace, (config != NULL));
+
+    if ((SharedRegion_module->refCount & SharedRegion_MAKE_MAGICSTAMP(0)) < 
+        SharedRegion_MAKE_MAGICSTAMP(1)) {
+        memcpy ((Ptr) config,
+                     (Ptr) &SharedRegion_module->defCfg,
+                     sizeof (SharedRegion_Config));
+    }
+    else {
+        memcpy ((Ptr) config,
+                     (Ptr) &SharedRegion_module->cfg,
+                     sizeof (SharedRegion_Config));
+    }
+
+    GT_0trace (curTrace, GT_LEAVE, "SharedRegion_getConfig");
+}
+
+/* Function to setup the SharedRegion module. */
+Int
+SharedRegion_setup (SharedRegion_Config * cfg)
+{
+    Int                 status = SharedRegion_S_SUCCESS;
+    UInt32         eb;
+    SharedRegion_Config tmpCfg;
+    UInt32              i;
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_setup", cfg);
+    eb=0;
+
+    if (cfg == NULL) {
+        SharedRegion_getConfig (&tmpCfg);
+        cfg = &tmpCfg;
+    }
+
+    if (cfg == NULL) {
+        SharedRegion_getConfig (&tmpCfg);
+        cfg = &tmpCfg;
+    }
+
+    /* This sets the refCount variable is not initialized, upper 16 bits is
+     * written with module Id to ensure correctness of refCount variable.
+     */
+    if((SharedRegion_module->refCount & SharedRegion_MAKE_MAGICSTAMP(0))
+        != SharedRegion_MAKE_MAGICSTAMP(0)) {
+        SharedRegion_module->refCount = SharedRegion_MAKE_MAGICSTAMP(0);
+    }
+    if (++SharedRegion_module->refCount 
+        != SharedRegion_MAKE_MAGICSTAMP(1u)) {
+        status = SharedRegion_S_ALREADYSETUP;
+        GT_0trace (curTrace,
+                   GT_2CLASS,
+                   "SharedRegion Module already initialized!");
+    }
+    else {
+        /* copy the user provided values into the state object */
+        memcpy ((Ptr) &SharedRegion_module->cfg,
+                     (Ptr) cfg,
+                     sizeof (SharedRegion_Config));
+
+        /* In a single processor system, we should never translate.
+         * but on HlOS side  where there are user space virtual space
+         * we should set translate = TRUE.
+         */
+
+        SharedRegion_module->cfg.translate = TRUE;
+
+        /* Allocate memory for the regions */
+        SharedRegion_module->regions = (SharedRegion_Region *)
+                                            malloc(sizeof(SharedRegion_Region)
+                                                   *SharedRegion_module->cfg.numEntries);
+
+            SharedRegion_module->regionRefCount = malloc (sizeof (UInt32)
+                                                          * SharedRegion_module->cfg.numEntries);
+            GT_assert(curTrace,(SharedRegion_module->regionRefCount != NULL));
+
+                for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+                    SharedRegion_module->regions[i].entry.base = NULL;
+                    SharedRegion_module->regions[i].entry.len = 0;
+                    SharedRegion_module->regions[i].entry.ownerProcId = 0;
+                    SharedRegion_module->regions[i].entry.isValid = FALSE;
+                    SharedRegion_module->regions[i].entry.cacheEnable = FALSE;
+                    SharedRegion_module->regions[i].entry.cacheLineSize =
+                                            SharedRegion_module->cfg.cacheLineSize;
+                    SharedRegion_module->regions[i].entry.createHeap   = FALSE;
+                    SharedRegion_module->regions[i].reservedSize = 0;
+#ifdef ENABLE_HEAPMP
+                    SharedRegion_module->regions[i].heap = NULL;
+#endif
+                    SharedRegion_module->regions[i].entry.name = NULL;
+                }
+
+                /* set the defaults for region 0  */
+#ifdef ENABLE_HEAPMP
+                SharedRegion_module->regions[0].entry.createHeap  = TRUE;
+#endif
+                SharedRegion_module->regions[0].entry.ownerProcId = MultiProc_self();
+
+                SharedRegion_module->numOffsetBits = SharedRegion_getNumOffsetBits ();
+                SharedRegion_module->offsetMask =
+                                        (1 << SharedRegion_module->numOffsetBits) - 1;
+                SharedRegion_module->isStarted = FALSE;
+#ifdef ENABLE_LOCAL_LOCK
+                /* Create a lock for protecting list object */
+                SharedRegion_module->localLock = (IGateProvider_Handle)
+                               GateMutex_create ((GateMutex_Params*)NULL, &eb);
+#endif
+    }
+
+    if (status < 0) {
+        SharedRegion_destroy ();
+    }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_setup", status);
+
+    /*! @retval SharedRegion_SUCCESS operation was successful */
+    return status;
+}
+
+/* Function to destroy the SharedRegion module. */
+Int
+SharedRegion_destroy (Void)
+{
+    Int status = SharedRegion_S_SUCCESS;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg key;
+#endif
+    GT_0trace (curTrace, GT_ENTER, "SharedRegion_destroy");
+
+        if (  --SharedRegion_module->refCount
+            == SharedRegion_MAKE_MAGICSTAMP(0)) {
+#ifdef ENABLE_LOCAL_LOCK
+            /* Enter the gate */
+            key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+            if (SharedRegion_module->regionRefCount != NULL) {
+                free (SharedRegion_module->regionRefCount);
+                SharedRegion_module->regionRefCount = NULL;
+            }
+
+            if (SharedRegion_module->regions != NULL) {
+                free (SharedRegion_module->regions);
+                SharedRegion_module->regions = NULL;
+            }
+
+            memset (&SharedRegion_module->cfg,
+                        0,
+                        sizeof (SharedRegion_Config));
+
+            SharedRegion_module->numOffsetBits = 0;
+            SharedRegion_module->offsetMask    = 0;
+#ifdef ENABLE_LOCAL_LOCK
+            /* Leave the gate */
+            IGateProvider_leave (SharedRegion_module->localLock, key);
+            /* Delete the local lock */
+            if (SharedRegion_module->localLock != NULL) {
+                status = GateMutex_delete ((GateMutex_Handle *)
+                                           &SharedRegion_module->localLock);
+                GT_assert (curTrace, (status >= 0));
+                if (status < 0) {
+                    status = SharedRegion_E_FAIL;
+                }
+            }
+#endif
+        }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_destroy", status);
+
+    return status;
+}
+
+/* API to know whether shared region is started or not.Returns true if shared
+ * region is already started othere wise returns false.
+ */
+Int
+_SharedRegion_isStarted(Void)
+{
+    return(SharedRegion_module->isStarted) ;
+}
+
+/* Creates a heap by owner of region for each SharedRegion.
+ * Function is called by Ipc_start(). Requires that SharedRegion 0
+ * be valid before calling start().
+ */
+Int
+SharedRegion_start (Void)
+{
+    Int                   status  = SharedRegion_S_SUCCESS;
+    SharedRegion_Region * region  = NULL;
+#ifdef ENABLE_HEAPMP
+    Ptr                   sharedAddr = NULL;
+    HeapMemMP_Handle      heapHandle = NULL;
+    HeapMemMP_Params      params;
+#endif
+    Int                   i;
+
+    GT_0trace (curTrace, GT_ENTER, "SharedRegion_start");
+
+        /*
+         *  Loop through shared regions. If an owner of a region is specified
+         *  and createHeap has been specified for the SharedRegion, then
+         *  the owner creates a HeapMemMP and the other processors open it.
+         */
+        for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+            region = &(SharedRegion_module->regions[i]);
+            if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+                if ((region->entry.ownerProcId == MultiProc_self())
+                    && (region->entry.createHeap)
+                    && (region->heap == NULL)) {
+                    /* get the next free address in each region */
+                    sharedAddr = (Ptr)((UInt32)region->entry.base
+                                                 + region->reservedSize);
+
+                    /*  Create the HeapMemMP in the region. */
+                    HeapMemMP_Params_init(&params);
+                    params.sharedAddr = sharedAddr;
+                    params.sharedBufSize = region->entry.len - region->reservedSize;
+
+                    /* Adjust to account for the size of HeapMemMP_Attrs */
+                    params.sharedBufSize -= (HeapMemMP_sharedMemReq(&params)
+                                         - params.sharedBufSize);
+                    heapHandle = HeapMemMP_create(&params);
+
+                        /* put heap handle into SharedRegion Module state */
+                        region->heap = heapHandle;
+                }
+#endif
+                SharedRegion_module->regionRefCount[i] += 1;
+            }
+        }
+
+        /* Set flag indiacting shared region has been started */
+        SharedRegion_module->isStarted = TRUE;
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_start", status);
+
+    return status;
+}
+
+/* Function to stop the SharedRegion module.  */
+Int
+SharedRegion_stop (Void)
+{
+    Int                   status    = SharedRegion_S_SUCCESS;
+#ifdef ENABLE_HEAPMP
+    Int                   tmpStatus = SharedRegion_S_SUCCESS;
+#endif
+    SharedRegion_Region * region  = NULL;
+    Int                   i;
+
+    GT_0trace (curTrace, GT_ENTER, "SharedRegion_stop");
+
+        /*
+         *  Loop through shared regions. If an owner of a region is specified
+         *  and createHeap has been specified for the SharedRegion, then
+         *  the other processors close it and the owner deletes the HeapMemMP.
+         */
+        for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+            region = &(SharedRegion_module->regions[i]);
+            if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+                if ((region->entry.ownerProcId == MultiProc_self ())
+                    && (region->entry.createHeap)
+                    && (region->heap != NULL)) {
+                    /* Delete heap */
+                    tmpStatus = HeapMemMP_delete ((HeapMemMP_Handle *)
+                                                        &(region->heap));
+                    if ((tmpStatus < 0) && (status >= 0)) {
+                        status = SharedRegion_E_FAIL;
+                    }
+                }
+#endif
+                memset (region, 0, sizeof (SharedRegion_Region));
+                SharedRegion_entryInit (&(region->entry));
+
+                SharedRegion_module->regionRefCount[i] -= 1;
+            }
+        }
+
+        /* set the defaults for region 0  */
+        memset (&(SharedRegion_module->regions[0]),
+                    0,
+                    sizeof (SharedRegion_Region));
+        SharedRegion_entryInit (&(SharedRegion_module->regions[0].entry));
+        SharedRegion_module->regions[0].entry.createHeap  = TRUE;
+        SharedRegion_module->regions[0].entry.ownerProcId = MultiProc_self();
+        /* Set flag indicating shared region has been started */
+        SharedRegion_module->isStarted = FALSE;
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_stop", status);
+
+    return status;
+}
+
+/* Opens a heap, for non-owner processors, for each SharedRegion. */
+Int
+SharedRegion_attach (UInt16 remoteProcId)
+{
+    Int                   status     = SharedRegion_S_SUCCESS;
+    SharedRegion_Region * region     = NULL;
+#ifdef ENABLE_HEAPMP
+    Ptr                   sharedAddr = NULL;
+#endif
+    Int                   i;
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_attach", remoteProcId);
+
+    GT_assert (curTrace, (remoteProcId < MultiProc_MAXPROCESSORS));
+
+        /*
+         *  Loop through the regions and open the heap if not owner
+         */
+        for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+            region = &(SharedRegion_module->regions [i]);
+            if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+                if ((region->entry.ownerProcId != MultiProc_self ()) &&
+                    (region->entry.ownerProcId != MultiProc_INVALIDID) &&
+                    (region->entry.createHeap) &&
+                    (region->heap == NULL)) {
+                    /* SharedAddr should match creator's for each region */
+                    sharedAddr = (Ptr) ((UInt32) region->entry.base +
+                                                    region->reservedSize);
+
+                    /* Heap should already be created so open by address */
+                    status = HeapMemMP_openByAddr (sharedAddr,
+                                        (HeapMemMP_Handle *) &(region->heap));
+                    if (status < 0) {
+                        status = SharedRegion_E_FAIL;
+
+                        /* Break the loop on failure. */
+                        break;
+                    }
+                }
+#endif
+                SharedRegion_module->regionRefCount[i] ++;
+                       }
+        }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_attach", status);
+
+    return status;
+}
+
+/* Closes a heap, for non-owner processors, for each SharedRegion. */
+Int
+SharedRegion_detach (UInt16 remoteProcId)
+{
+    Int                   status    = SharedRegion_S_SUCCESS;
+#ifdef ENABLE_HEAPMP
+    Int                   tmpStatus = SharedRegion_S_SUCCESS;
+#endif
+    SharedRegion_Region * region    = NULL;
+    UInt16                i;
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_detach", remoteProcId);
+
+    GT_assert (curTrace, (remoteProcId < MultiProc_MAXPROCESSORS));
+
+        /*
+         *  Loop through the regions and open the heap if not owner
+         */
+        for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+            region = &(SharedRegion_module->regions [i]);
+            if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+                if ((region->entry.ownerProcId != MultiProc_self ()) &&
+                    (region->entry.ownerProcId != MultiProc_INVALIDID) &&
+                    (region->entry.createHeap) && (region->heap != NULL)) {
+                       /* Close the heap */
+                       tmpStatus = HeapMemMP_close ((HeapMemMP_Handle *)
+                           &(region->heap));
+                       if ((tmpStatus < 0) && (status >= 0)) {
+                           status = SharedRegion_E_FAIL;
+
+                       }
+                   }
+#endif
+                   SharedRegion_module->regionRefCount[i]--;
+            }
+        }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_detach", status);
+
+    return status;
+}
+
+/* Returns the address pointer associated with the shared region pointer. */
+Ptr
+SharedRegion_getPtr (SharedRegion_SRPtr srPtr)
+{
+    SharedRegion_Region * region    = NULL;
+    Ptr                   returnPtr = NULL;
+    UInt16                regionId;
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_getPtr", srPtr);
+
+    /* srPtr can be invalid. */
+
+    if (srPtr != SharedRegion_INVALIDSRPTR) {
+        if (SharedRegion_module->cfg.translate == FALSE) {
+            returnPtr = (Ptr) srPtr;
+        }
+        else {
+            regionId = (UInt32) (srPtr >> SharedRegion_module->numOffsetBits);
+
+                region = &(SharedRegion_module->regions [regionId]);
+
+                returnPtr = (Ptr)(  (srPtr & SharedRegion_module->offsetMask)
+                                  + (UInt32) region->entry.base);
+
+        }
+    }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getPtr", returnPtr);
+
+    return returnPtr;
+}
+
+/* Returns the address pointer associated with the shared region pointer. */
+SharedRegion_SRPtr
+SharedRegion_getSRPtr (Ptr addr, UInt16 id)
+{
+    SharedRegion_Region * region = NULL;
+    SharedRegion_SRPtr    retPtr = SharedRegion_INVALIDSRPTR;
+
+    GT_2trace (curTrace, GT_ENTER, "SharedRegion_getSRPtr", addr, id);
+
+    /* addr can be NULL. */
+
+    /* Return invalid for NULL addr */
+    if (addr != NULL) {
+        GT_assert (curTrace, (id != SharedRegion_INVALIDREGIONID));
+        GT_assert (curTrace,
+                   (    (id != SharedRegion_INVALIDREGIONID)
+                    &&  (id < SharedRegion_module->cfg.numEntries)));
+
+            /* if no shared region configured, set SRPtr to addr */
+            if (SharedRegion_module->cfg.translate == FALSE) {
+                retPtr = (SharedRegion_SRPtr) addr;
+            }
+            else {
+                region = &(SharedRegion_module->regions[id]);
+
+                /*
+                 *  Note: The very last byte on the very last id cannot be
+                 *        mapped because SharedRegion_INVALIDSRPTR which is ~0
+                 *        denotes an error. Since pointers should be word
+                 *        aligned, we don't expect this to be a problem.
+                 *
+                 *        ie: numEntries = 4,
+                 *            id = 3, base = 0x00000000, len = 0x40000000
+                 *            ==> address 0x3fffffff would be invalid because
+                 *                the SRPtr for this address is 0xffffffff
+                 */
+                if (    ((UInt32) addr >= (UInt32) region->entry.base)
+                    &&  (  (UInt32) addr
+                         < ((UInt32) region->entry.base + region->entry.len))) {
+                    retPtr = (SharedRegion_SRPtr)
+                              (  (id << SharedRegion_module->numOffsetBits)
+                               | ((UInt32) addr - (UInt32) region->entry.base));
+                }
+                else {
+                    retPtr = SharedRegion_INVALIDSRPTR;
+                    GT_setFailureReason (curTrace,
+                                         GT_4CLASS,
+                                         "SharedRegion_getSRPtr",
+                                         SharedRegion_E_INVALIDARG,
+                                         "Provided addr is not in correct range"
+                                         " for the specified id!");
+                }
+            }
+
+    }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getSRPtr", retPtr);
+
+    return retPtr;
+}
+
+/* Whether address translation is enabled */
+Bool
+SharedRegion_translateEnabled (Void)
+{
+    GT_0trace (curTrace, GT_ENTER, "SharedRegion_translateEnabled");
+    GT_1trace (curTrace,
+               GT_LEAVE,
+               "SharedRegion_translateEnabled",
+               SharedRegion_module->cfg.translate);
+
+    return (SharedRegion_module->cfg.translate);
+}
+
+/* Gets the number of regions */
+UInt16
+SharedRegion_getNumRegions (Void)
+{
+    GT_0trace (curTrace, GT_ENTER, "SharedRegion_getNumRegions");
+    GT_1trace (curTrace,
+               GT_LEAVE,
+               "SharedRegion_getNumRegions",
+               SharedRegion_module->cfg.numEntries);
+    return (SharedRegion_module->cfg.numEntries);
+}
+
+/* Sets the table information entry in the table. */
+Int
+SharedRegion_setEntry (UInt16                id,
+                       SharedRegion_Entry  * entry)
+{
+    Int                   status  = SharedRegion_S_SUCCESS;
+    SharedRegion_Region * region  = NULL;
+#ifdef ENABLE_HEAPMP
+    Ptr                   sharedAddr    = NULL;
+#endif
+#ifdef ENABLE_HEAPMP
+    HeapMemMP_Handle      heapHandle    = NULL;
+    HeapMemMP_Handle   *  heapHandlePtr = NULL;
+    HeapMemMP_Params      params;
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+    IArg                  key;
+#endif
+
+    GT_2trace (curTrace, GT_ENTER, "SharedRegion_setEntry", id, entry);
+
+    GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+    GT_assert (curTrace, (entry != NULL));
+
+        region = &(SharedRegion_module->regions [id]);
+
+        /* Make sure region does not overlap existing ones */
+        status = SharedRegion_checkOverlap (region->entry.base,
+                                            region->entry.len);
+
+            if (region->entry.isValid) {
+                /* region already exist */
+                SharedRegion_module->regionRefCount[id] += 1;
+            }
+            else {
+#ifdef ENABLE_LOCAL_LOCK
+                /* needs to be thread safe */
+                key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+                /* set specified region id to entry values */
+                memcpy ((Ptr) &(region->entry),
+                             (Ptr) entry,
+                             sizeof (SharedRegion_Entry));
+#ifdef ENABLE_LOCAL_LOCK
+                /* leave gate */
+                IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+#ifdef ENABLE_HEAPMP
+                if (entry->ownerProcId == MultiProc_self ()) {
+                    if ((entry->createHeap) && (region->heap == NULL)) {
+                        /* get current Ptr (reserve memory with size of 0) */
+                        sharedAddr = SharedRegion_reserveMemory (id, 0);
+                        HeapMemMP_Params_init (&params);
+                        params.sharedAddr    = sharedAddr;
+                        params.sharedBufSize =   region->entry.len
+                                              -  region->reservedSize;
+
+                        /*
+                         *  Calculate size of HeapMemMP_Attrs and adjust
+                         *  sharedBufSize. Size of HeapMemMP_Attrs =
+                         *  HeapMemMP_sharedMemReq(&params) - params.sharedBufSize
+                         */
+                        params.sharedBufSize -= (  HeapMemMP_sharedMemReq (&params)
+                                                 - params.sharedBufSize);
+
+                        heapHandle = HeapMemMP_create (&params);
+                        if (heapHandle == NULL) {
+                            region->entry.isValid = FALSE;
+                            status = SharedRegion_E_MEMORY;
+
+                        }
+                        else {
+                            region->heap = heapHandle;
+                        }
+                    }
+                }
+                else {
+                    if ((entry->createHeap) && (region->heap == NULL)) {
+                        /* sharedAddr should match creator's for each region */
+                        sharedAddr = (Ptr)(  (UInt32) region->entry.base
+                                           + region->reservedSize);
+
+                        /* set the pointer to a heap handle */
+                        heapHandlePtr = (HeapMemMP_Handle *) &(region->heap);
+
+                        /* open the heap by address */
+                        status = HeapMemMP_openByAddr (sharedAddr, heapHandlePtr);
+                        if (status < 0) {
+                            region->entry.isValid = FALSE;
+                            status = SharedRegion_E_FAIL;
+
+                        }
+                    }
+                }
+#endif
+                if (region->entry.isValid) {
+                    SharedRegion_module->regionRefCount[id] ++;
+                }
+            }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_setEntry", status);
+
+    return (status);
+}
+
+/* Clears the region in the table. */
+Int
+SharedRegion_clearEntry (UInt16 id)
+{
+    Int                   status     = SharedRegion_S_SUCCESS;
+    SharedRegion_Region * region     = NULL;
+#ifdef ENABLE_HEAPMP
+    HeapMemMP_Handle      heapmemPtr = NULL;
+    UInt16                myId;
+    UInt16                ownerProcId;
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+    IArg                  key;
+#endif
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_clearEntry", id);
+
+    GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+    /* Need to make sure not trying to clear Region 0 */
+
+#ifdef ENABLE_HEAPMP
+        myId = MultiProc_self ();
+#endif
+
+#ifdef ENABLE_LOCAL_LOCK
+        /* Needs to be thread safe */
+        key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+
+        region = &(SharedRegion_module->regions [id]);
+
+#ifdef ENABLE_HEAPMP
+        /* Store these fields to local variables */
+        ownerProcId = region->entry.ownerProcId;
+        heapmemPtr  = region->heap;
+#endif
+        if (region->entry.isValid) {
+            SharedRegion_module->regionRefCount[id] -= 1;
+        }
+
+        if (SharedRegion_module->regionRefCount[id] == 0) {
+           /* Assert if region is 0.
+            * Region 0 should always be cleared through SharedRegion_stop API
+            */
+            GT_assert (curTrace, (id != 0));
+            /* Clear region to their defaults */
+            region->entry.isValid       = FALSE;
+            region->entry.base          = NULL;
+            region->entry.len           = 0u;
+            region->entry.ownerProcId   = 0u;
+            region->entry.cacheEnable   = FALSE;
+            region->entry.cacheLineSize = SharedRegion_module->cfg.cacheLineSize;
+            region->entry.createHeap    = TRUE;
+            region->entry.name          = NULL;
+            region->reservedSize        = 0u;
+#ifdef ENABLE_HEAPMP
+            region->heap                = NULL;
+#endif
+
+#ifdef ENABLE_LOCAL_LOCK
+            IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+#ifdef ENABLE_HEAPMP
+            /* Delete or close previous created heap outside the gate */
+            if (heapmemPtr != NULL) {
+                if (ownerProcId == myId) {
+                    status = HeapMemMP_delete ((HeapMemMP_Handle *) &heapmemPtr);
+                    if (status < 0) {
+                        status = SharedRegion_E_FAIL;
+
+                    }
+                }
+                else if (ownerProcId != MultiProc_INVALIDID) {
+                    status = HeapMemMP_close ((HeapMemMP_Handle *) &heapmemPtr);
+                    if (status < 0) {
+                        status = SharedRegion_E_FAIL;
+
+                    }
+                }
+            }
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+            /* Needs to be thread safe */
+            key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+        }
+#ifdef ENABLE_LOCAL_LOCK
+        IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_clearEntry", status);
+
+    return status;
+}
+
+/* Clears the reserve memory for each region in the table. */
+Void
+SharedRegion_clearReservedMemory (Void)
+{
+    SharedRegion_Region * region = NULL;
+    Int                   i;
+
+    GT_0trace (curTrace, GT_ENTER, "SharedRegion_clearReservedMemory");
+
+    /*
+     *  Loop through shared regions. If an owner of a region is specified,
+     *  the owner zeros out the reserved memory in each region.
+     */
+    for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+        region = &(SharedRegion_module->regions [i]);
+        if (   (region->entry.isValid)
+            && (region->entry.ownerProcId == MultiProc_self ())) {
+            /* Clear reserved memory, if any */
+            if (region->reservedSize != 0) {
+                memset (region->entry.base, 0, region->reservedSize);
+
+                /* Writeback invalidate the cache if enabled in region */
+                if (region->entry.cacheEnable) {
+                    Cache_wbInv (region->entry.base,
+                                 region->reservedSize,
+                                 Cache_Type_ALL,
+                                 TRUE);
+                }
+            }
+        }
+    }
+
+    GT_0trace (curTrace, GT_LEAVE, "SharedRegion_clearReservedMemory");
+}
+
+/* Initializes the entry fields */
+Void
+SharedRegion_entryInit (SharedRegion_Entry * entry)
+{
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_entryInit", entry);
+
+    GT_assert (curTrace, (entry != NULL));
+
+        /* init the entry to default values */
+        entry->base          = NULL;
+        entry->len           = 0u;
+        entry->ownerProcId   = 0u;
+        entry->cacheEnable   = TRUE;
+        entry->cacheLineSize = SharedRegion_module->cfg.cacheLineSize;
+        entry->createHeap    = TRUE;
+        entry->name          = NULL;
+        entry->isValid       = FALSE;
+
+    GT_0trace (curTrace, GT_LEAVE, "SharedRegion_entryInit");
+}
+
+/* Returns Heap Handle of associated id */
+Ptr
+SharedRegion_getHeap (UInt16 id)
+{
+#ifdef ENABLE_HEAPMP
+    HeapMemMP_Handle heap = NULL;
+#endif
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_getHeap", id);
+
+    GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+        /*
+         *  If translate == TRUE or translate == FALSE
+         *  and 'id' is not INVALIDREGIONID, then assert id is valid.
+         *  Return the heap associated with the region id.
+         *
+         *  If those conditions are not met, the id is from
+         *  an addres in local memory so return NULL.
+         */
+        if (    (SharedRegion_module->cfg.translate)
+            ||  (   (SharedRegion_module->cfg.translate == FALSE)
+                 && (id != SharedRegion_INVALIDREGIONID))) {
+            if (id >= SharedRegion_module->cfg.numEntries) {
+                /* Need to make sure id is smaller than numEntries */
+                GT_setFailureReason (curTrace,
+                                     GT_4CLASS,
+                                     "SharedRegion_getHeap",
+                                     SharedRegion_E_INVALIDARG,
+                                     "id cannot be larger than numEntries!");
+            }
+            else {
+#ifdef ENABLE_HEAPMP
+                heap = SharedRegion_module->regions [id].heap;
+#endif
+            }
+        }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getHeap", heap);
+
+#ifdef ENABLE_HEAPMP
+    return (Ptr) heap;
+#else
+    return NULL;
+#endif
+}
+
+/* Returns the id of shared region in which the pointer resides.
+ * Returns 0 if SharedRegion_module->cfg.translate set to TRUE.
+ * It returns SharedRegion_INVALIDREGIONID if no entry is found.
+ */
+UInt16
+SharedRegion_getId (Ptr addr)
+{
+    SharedRegion_Region * region   = NULL;
+    UInt16                regionId = SharedRegion_INVALIDREGIONID;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg                  key;
+#endif
+    UInt16                i;
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_getId", addr);
+
+    /* addr can be NULL. */
+
+    /* Return invalid for NULL addr */
+    if (addr != NULL) {
+#ifdef ENABLE_LOCAL_LOCK
+        key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+
+        for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+            region = &(SharedRegion_module->regions [i]);
+            if (   (region->entry.isValid)
+                && (addr >= region->entry.base)
+                && (  addr
+                    < (Ptr)((UInt32) region->entry.base + region->entry.len))) {
+                regionId = i;
+                break;
+            }
+        }
+
+#ifdef ENABLE_LOCAL_LOCK
+        IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+    }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getId", regionId);
+
+    return (regionId);
+}
+
+/* Returns the id of shared region that matches name.
+ * Returns SharedRegion_INVALIDREGIONID if no region is found.
+ */
+UInt16
+SharedRegion_getIdByName (String name)
+{
+    SharedRegion_Region * region   = NULL;
+    UInt16                regionId = SharedRegion_INVALIDREGIONID;
+    UInt16                i;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg                  key;
+#endif
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_getIdByName", name);
+
+    GT_assert (curTrace, (name != NULL));
+
+#ifdef ENABLE_LOCAL_LOCK
+        /* Needs to be thread safe */
+        key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+
+        /* loop through entries to find matching name */
+        for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+            region = &(SharedRegion_module->regions [i]);
+
+            if (region->entry.isValid) {
+                if (strcmp (region->entry.name, name) == 0) {
+                    regionId = i;
+                    break;
+                }
+            }
+        }
+
+#ifdef ENABLE_LOCAL_LOCK
+        /* leave the gate */
+        IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getIdByName", regionId);
+
+    return (regionId);
+}
+
+/* Gets the entry information for the specified region id */
+Int
+SharedRegion_getEntry (UInt16               id,
+                       SharedRegion_Entry * entry)
+{
+    Int                   status = SharedRegion_S_SUCCESS;
+    SharedRegion_Region * region = NULL;
+
+    GT_2trace (curTrace, GT_ENTER, "SharedRegion_getEntry", id, entry);
+
+    GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+    GT_assert (curTrace, (entry != NULL));
+
+        region = &(SharedRegion_module->regions [id]);
+
+        memcpy ((Ptr) entry,
+                     (Ptr) &(region->entry),
+                     sizeof (SharedRegion_Entry));
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getEntry", status);
+
+    return status;
+}
+
+/* Get cache line size */
+SizeT
+SharedRegion_getCacheLineSize (UInt16 id)
+{
+    SizeT cacheLineSize = 0u;
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_getCacheLineSize", id);
+
+    GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+        /*
+         *  If translate == TRUE or translate == FALSE
+         *  and 'id' is not INVALIDREGIONID, then assert id is valid.
+         *  Return the heap associated with the region id.
+         *
+         *  If those conditions are not met, the id is from
+         *  an addres in local memory so return NULL.
+         */
+        if (    (SharedRegion_module->cfg.translate)
+            ||  (   (SharedRegion_module->cfg.translate == FALSE)
+                 && (id != SharedRegion_INVALIDREGIONID))) {
+            if (id >= SharedRegion_module->cfg.numEntries) {
+                /* Need to make sure id is smaller than numEntries */
+                GT_setFailureReason (curTrace,
+                                     GT_4CLASS,
+                                     "SharedRegion_getCacheLineSize",
+                                     SharedRegion_E_INVALIDARG,
+                                     "id cannot be larger than numEntries!");
+            }
+            else {
+                cacheLineSize =
+                        SharedRegion_module->regions [id].entry.cacheLineSize;
+            }
+        }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getCacheLineSize",
+               cacheLineSize);
+
+    return cacheLineSize;
+}
+
+/* Is cache enabled */
+Bool
+SharedRegion_isCacheEnabled (UInt16 id)
+{
+    Bool cacheEnable = FALSE;
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_isCacheEnabled", id);
+
+    GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+        /*
+         *  If translate == TRUE or translate == FALSE
+         *  and 'id' is not INVALIDREGIONID, then assert id is valid.
+         *  Return the heap associated with the region id.
+         *
+         *  If those conditions are not met, the id is from
+         *  an addres in local memory so return NULL.
+         */
+        if (    (SharedRegion_module->cfg.translate)
+            ||  (   (SharedRegion_module->cfg.translate == FALSE)
+                 && (id != SharedRegion_INVALIDREGIONID))) {
+            if (id >= SharedRegion_module->cfg.numEntries) {
+                /* Need to make sure id is smaller than numEntries */
+                GT_setFailureReason (curTrace,
+                                     GT_4CLASS,
+                                     "SharedRegion_isCacheEnabled",
+                                     SharedRegion_E_INVALIDARG,
+                                     "id cannot be larger than numEntries!");
+            }
+            else {
+                cacheEnable =
+                            SharedRegion_module->regions[id].entry.cacheEnable;
+            }
+        }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_isCacheEnabled", cacheEnable);
+
+    return (cacheEnable);
+}
+
+/* Returns invalid SRPtr value. */
+SharedRegion_SRPtr SharedRegion_invalidSRPtr (Void)
+{
+    return (SharedRegion_INVALIDSRPTR);
+}
+
+/* =============================================================================
+ *  Internal Functions
+ * =============================================================================
+ */
+/* Reserves the specified amount of memory from the specified region id. */
+Ptr
+SharedRegion_reserveMemory (UInt16 id, SizeT size)
+{
+    Ptr                   retPtr = NULL;
+    SharedRegion_Region * region = NULL;
+    UInt32                minAlign;
+    SizeT                 newSize;
+    SizeT                 curSize;
+
+    GT_2trace (curTrace, GT_ENTER, "SharedRegion_reserveMemory", id, size);
+
+    GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+    minAlign = Memory_getMaxDefaultTypeAlign ();
+
+    if (SharedRegion_getCacheLineSize (id) > minAlign) {
+        minAlign = SharedRegion_getCacheLineSize (id);
+    }
+
+    region = &(SharedRegion_module->regions [id]);
+
+    /* Set the current size to the reservedSize */
+    curSize = region->reservedSize;
+
+    /* No need to round here since curSize is already aligned */
+    retPtr = (Ptr)((UInt32) region->entry.base + curSize);
+
+    /*  Round the new size to the min alignment since */
+    newSize = ROUNDUP (size, minAlign);
+
+    /* Add the new size to current size */
+    region->reservedSize = curSize + newSize;
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_reserveMemory", retPtr);
+
+    return (retPtr);
+}
+
+/* Reserves the specified amount of memory from the specified region id. */
+Void
+SharedRegion_unreserveMemory (UInt16 id, SizeT size)
+{
+    SharedRegion_Region * region = NULL;
+    UInt32                minAlign;
+    SizeT                 newSize;
+    SizeT                 curSize;
+
+    GT_2trace (curTrace, GT_ENTER, "SharedRegion_unreserveMemory", id, size);
+
+    GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+    minAlign = Memory_getMaxDefaultTypeAlign ();
+
+    if (SharedRegion_getCacheLineSize (id) > minAlign) {
+        minAlign = SharedRegion_getCacheLineSize (id);
+    }
+
+    region = &(SharedRegion_module->regions [id]);
+
+    /* Set the current size to the unreservedSize */
+    curSize = region->reservedSize;
+
+    /*  Round the new size to the min alignment since */
+    newSize = ROUNDUP (size, minAlign);
+
+    /* Add the new size to current size */
+    region->reservedSize = curSize - newSize;
+
+    GT_0trace (curTrace, GT_LEAVE, "SharedRegion_unreserveMemory");
+
+    return ;
+}
+
+/* Return the number of offsetBits bits */
+static UInt32 SharedRegion_getNumOffsetBits (Void)
+{
+    UInt32    numEntries = SharedRegion_module->cfg.numEntries;
+    UInt32    indexBits  = 0;
+    UInt32    numOffsetBits = 0;
+
+    GT_0trace (curTrace, GT_ENTER, "SharedRegion_getNumOffsetBits");
+
+    if (numEntries == 0) {
+        indexBits = 0;
+    }
+    else if (numEntries == 1) {
+        indexBits = 1;
+    }
+    else {
+        numEntries = numEntries - 1;
+
+        /* determine the number of bits for the index */
+        while (numEntries) {
+            indexBits++;
+            numEntries = numEntries >> 1;
+        }
+    }
+
+    numOffsetBits = 32 - indexBits;
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getNumOffsetBits",
+            numOffsetBits);
+
+    return (numOffsetBits);
+}
+
+/* Checks to make sure overlap does not exists. */
+static Int SharedRegion_checkOverlap(Ptr base, SizeT len)
+{
+    Int                   status = SharedRegion_S_SUCCESS;
+    SharedRegion_Region * region = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg                  key    = 0;
+#endif
+    UInt32                i;
+
+    GT_2trace (curTrace, GT_ENTER, "SharedRegion_checkOverlap", base, len);
+
+#ifdef ENABLE_LOCAL_LOCK
+    key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+    /* check whether new region overlaps existing ones */
+    for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+        region = &(SharedRegion_module->regions [i]);
+        if (region->entry.isValid) {
+            if ((base == region->entry.base)&&(len == region->entry.len)) {
+                /* OK.Return sucess as user is going to create the same
+                 * shared region from different process
+                 */
+                break;
+            }
+            else if (base >= region->entry.base) {
+                if (   base
+                        <  (Ptr)(   (UInt32) region->entry.base
+                                +   region->entry.len)) {
+                    status = SharedRegion_E_FAIL;
+                    GT_setFailureReason (curTrace,
+                            GT_4CLASS,
+                            "SharedRegion_checkOverlap",
+                            status,
+                            "Specified region falls within another"
+                            " region!");
+                    /* Break on failure. */
+                    break;
+                }
+            }
+            else {
+                if ((Ptr) ((UInt32) base + len) > region->entry.base) {
+                    status = SharedRegion_E_FAIL;
+                    GT_setFailureReason (curTrace,
+                            GT_4CLASS,
+                            "SharedRegion_checkOverlap",
+                            status,
+                            "Specified region spans across"
+                            " multiple regions!");
+                    /* Break on failure. */
+                    break;
+                }
+            }
+        }
+    }
+
+#ifdef ENABLE_LOCAL_LOCK
+    IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_checkOverlap", status);
+
+    return (status);
+}
+
+/* Return the region info */
+Void
+SharedRegion_getRegionInfo (UInt16                i,
+                            SharedRegion_Region * region)
+{
+    SharedRegion_Region * regions = NULL;
+
+    GT_2trace (curTrace, GT_ENTER, "SharedRegion_getRegionInfo", i, region);
+
+    GT_assert (curTrace, (i < SharedRegion_module->cfg.numEntries));
+    GT_assert (curTrace, (region != NULL));
+
+        regions = &(SharedRegion_module->regions[i]);
+
+        memcpy ((Ptr) region,
+                     (Ptr) regions,
+                     sizeof (SharedRegion_Region));
+
+    GT_0trace (curTrace, GT_LEAVE, "SharedRegion_getRegionInfo");
+}
+
+/* Sets the table information entry in the table (doesn't create heap). */
+Int
+_SharedRegion_setEntry (UInt16                id,
+                        SharedRegion_Entry  * entry)
+{
+    Int                   status  = SharedRegion_S_SUCCESS;
+    SharedRegion_Region * region  = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg                  key;
+#endif
+
+    GT_2trace (curTrace, GT_ENTER, "_SharedRegion_setEntry", id, entry);
+
+    GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+    GT_assert (curTrace, (entry != NULL));
+
+        region = &(SharedRegion_module->regions [id]);
+
+        /* Make sure region does not overlap existing ones */
+        status = SharedRegion_checkOverlap (region->entry.base,
+                                            region->entry.len);
+#ifdef ENABLE_LOCAL_LOCK
+            /* needs to be thread safe */
+            key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+
+            /* set specified region id to entry values */
+            memcpy ((Ptr) &(region->entry),
+                         (Ptr) entry,
+                         sizeof (SharedRegion_Entry));
+
+#ifdef ENABLE_LOCAL_LOCK
+            /* leave gate */
+            IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+    GT_1trace (curTrace, GT_LEAVE, "_SharedRegion_setEntry", status);
+
+    return (status);
+}
+
+/* Gets region ID when given a physical address */
+UInt16 _SharedRegion_getIdPhys(Ptr physAddr)
+{
+    SharedRegion_Region * region   = NULL;
+    UInt16                regionId = SharedRegion_INVALIDREGIONID;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg                  key;
+#endif
+    UInt16                i;
+    Ptr                   base;
+
+    GT_1trace (curTrace, GT_ENTER, "SharedRegion_getIdPhys", physAddr);
+
+    /* physAddr can be NULL. */
+
+    /* Return invalid for NULL physAddr */
+    if (physAddr != NULL) {
+#ifdef ENABLE_LOCAL_LOCK
+        key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+        for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+            region = &SharedRegion_module->regions[i];
+            if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+                if (region->entry.createHeap) {
+                    base = MemoryOS_translate(region->entry.base,
+                                              Memory_XltFlags_Virt2Phys);
+                }
+                else
+#endif
+               {
+                    base = region->entry.base;
+                }
+                if ((physAddr >= base) &&
+                    (physAddr < (Ptr)((UInt32)base + region->entry.len))) {
+
+                    regionId = i;
+                    break;
+                }
+            }
+        }
+
+#ifdef ENABLE_LOCAL_LOCK
+        IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+    }
+
+    GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getIdPhys", regionId);
+
+    return (regionId);
+}
+
+/*
+ *  ======== SharedRegion_getEntryPtr ========
+ */
+SharedRegion_Entry *SharedRegion_getEntryPtr(UInt16 id)
+{
+    SharedRegion_Region *region;
+
+    region = &(SharedRegion_module->regions[id]);
+    return ((SharedRegion_Entry *)(&region->entry));
+}
diff --git a/host_linux/simple_buffer_example/host/SharedRegion/src/inc/_SharedRegion.h b/host_linux/simple_buffer_example/host/SharedRegion/src/inc/_SharedRegion.h
new file mode 100755 (executable)
index 0000000..f9695b0
--- /dev/null
@@ -0,0 +1,217 @@
+/** 
+ *  @file   _SharedRegion.h
+ *
+ *  @brief      Shared Region Manager internal functions
+ *
+ *
+ */
+/* 
+ *  ============================================================================
+ *
+ *  Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ *  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.
+ *  Contact information for paper mail:
+ *  Texas Instruments
+ *  Post Office Box 655303
+ *  Dallas, Texas 75265
+ *  Contact information: 
+ *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ *  ============================================================================
+ *  
+ */
+
+
+
+#ifndef _SharedRegion_H_0X5D8A
+#define _SharedRegion_H_0X5D8A
+
+
+/* Standard headers */
+#include "SharedRegion.h"
+#ifdef ENABLE_GATEMP
+#include <ti/ipc/HeapMemMP.h>
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ *  @def    SharedRegion_MODULEID
+ *  @brief  Module ID for Shared region manager.
+ */
+#define SharedRegion_MODULEID      (0x5D8A)
+
+/*!
+ *  @brief  Name of the reserved name server used for application.
+ */
+#define SharedRegion_NAMESERVER        "SHAREDREGION"
+
+/*!
+ *  @def        SharedRegion_INVALIDSRPTR
+ *  @brief      Invalid SharedRegion pointer. Default value for when translate
+ *              is true.
+ */
+#define SharedRegion_INVALIDSRPTR (~0)
+
+
+/*!
+ *  @brief  Information stored on a per region basis
+ */
+typedef struct SharedRegion_Region_tag {
+    SharedRegion_Entry entry;
+    SizeT              reservedSize;
+//    HeapMemMP_Handle   heap;
+} SharedRegion_Region;
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+
+/*!
+ *  @brief      Function to destroy the SharedRegion module.
+ *
+ *  @sa         SharedRegion_setup
+ */
+Int SharedRegion_destroy (Void);
+
+/*!
+ *  @brief      Creates a heap by owner of region for each SharedRegion.
+ *              Function is called by Ipc_start(). Requires that SharedRegion 0
+ *              be valid before calling start().
+ *
+ *  @param      None
+ *
+ *  @sa         Ipc_start
+ */
+Int SharedRegion_start (Void);
+
+/*!
+ *  @brief      Function to stop Shared Region 0
+ *
+ *  @param      None
+ *
+ *  @sa         Ipc_stop
+ */
+Int SharedRegion_stop (Void);
+
+/*!
+ *  @brief      Opens a heap, for non-owner processors, for each SharedRegion.
+ *
+ *  @param      None
+ *
+ *  @sa         SharedRegion_detach
+ */
+Int SharedRegion_attach (UInt16 remoteProcId);
+
+/*!
+ *  @brief      Closes a heap, for non-owner processors, for each SharedRegion.
+ *
+ *  @param      None
+ *
+ *  @sa         SharedRegion_attach
+ */
+Int SharedRegion_detach (UInt16 remoteProcId);
+
+/*!
+ *  @brief      Reserve shared region memory
+ *
+ *  @param      id      Shared region id
+ *  @param      size    Shared region size
+ *
+ *  @sa         None
+ */
+Ptr SharedRegion_reserveMemory (UInt16 id, UInt32 size);
+
+
+/*!
+ *  @brief      Reserve shared region memory
+ *
+ *  @param      id      Shared region id
+ *  @param      size    Shared region size
+ *
+ *  @sa         None
+ */
+Void SharedRegion_unreserveMemory (UInt16 id, UInt32 size);
+
+
+/*!
+ *  @brief      Sets the entry at the specified region id (doesn't create heap)
+ *
+ *  @param      regionId  region id
+ *  @param      entry     pointer to set region information.
+ *
+ *  @return     Status
+ *              - #SharedRegion_S_SUCCESS:  Operation was successful
+ *              - #SharedRegion_E_FAIL:  Region already exists or overlaps with
+ *                                       with another region
+ *              - #SharedRegion_E_MEMORY: Unable to create Heap
+ */
+Int _SharedRegion_setEntry(UInt16 regionId, SharedRegion_Entry *entry);
+
+
+/*! @brief      Function to clear the reserved memory */
+Void SharedRegion_clearReservedMemory (Void);
+
+/*! @brief      Return the region info
+ *
+ *  @param      i       Shared region id
+ *  @param      region  Pointer to region structure
+ */
+Void SharedRegion_getRegionInfo (UInt16                i,
+                                 SharedRegion_Region * region);
+
+/* User space internal API */
+/*! Sets the regions in user space that are created in knl space and
+ * not on user space
+ */
+Int
+_SharedRegion_setRegions (Void);
+
+/*! Clears the regions in user space that are created in knl space and
+ * not on user space.
+ */
+Int
+_SharedRegion_clearRegions (Void);
+
+/*! To know if shared region start has been called  */
+Int
+_SharedRegion_isStarted(Void);
+
+/*! Get shared region Id from physical address */
+UInt16
+_SharedRegion_getIdPhys(Ptr physAddr);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* _SharedRegion_H_0X5D8A */
diff --git a/host_linux/simple_buffer_example/host/Std.h b/host_linux/simple_buffer_example/host/Std.h
new file mode 100755 (executable)
index 0000000..150102d
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ *  @file   Std.h
+ *
+ *  @brief      This will have definitions of standard data types for
+ *              platform abstraction.
+ *
+ *
+ */
+/*
+ *  ============================================================================
+ *
+ *  Copyright (c) 2017, Texas Instruments Incorporated
+ *
+ *  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.
+ *  ============================================================================
+ *
+ */
+
+
+#if !defined(T_STD_H)
+#define T_STD_H
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+#include <std_linux.h>
+
+typedef unsigned long long      UInt64;
+
+/*! Data type for errors */
+typedef UInt32            Error_Block;
+
+/*! Initialize error block */
+#define Error_init(eb) *eb = 0
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* T_STD_H */
diff --git a/host_linux/simple_buffer_example/host/main_host.c b/host_linux/simple_buffer_example/host/main_host.c
new file mode 100644 (file)
index 0000000..d00fab6
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2013-2017 Texas Instruments Incorporated - http://www.ti.com
+ * 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.
+ */
+
+/*
+ *  ======== main_host.c ========
+ *
+ */
+
+/* cstdlib header files */
+#include <stdio.h>
+#include <stdlib.h>
+
+/* package header files */
+#include <ti/ipc/Std.h>
+#include <ti/ipc/Ipc.h>
+#include <ti/ipc/transports/TransportRpmsg.h>
+
+#include <ti/ipc/MultiProc.h>
+
+/* local header files */
+#include "App.h"
+
+/* private functions */
+static Int Main_main(Void);
+static Int Main_parseArgs(Int argc, Char *argv[]);
+
+
+#define Main_USAGE "\
+Usage:\n\
+    app_host [options] procName\n\
+\n\
+Arguments:\n\
+    procName      : the name of the remote processor\n\
+\n\
+Options:\n\
+    h   : print this help message\n\
+    l   : list the available remote names\n\
+\n\
+Examples:\n\
+    app_host DSP\n\
+    app_host -l\n\
+    app_host -h\n\
+\n"
+
+/* private data */
+static String   Main_remoteProcName = NULL;
+
+
+/*
+ *  ======== main ========
+ */
+Int main(Int argc, Char* argv[])
+{
+    Int status;
+
+    printf("--> main:\n");
+
+    /* configure the transport factory */
+    Ipc_transportConfig(&TransportRpmsg_Factory);
+
+    /* parse command line */
+    status = Main_parseArgs(argc, argv);
+
+    if (status < 0) {
+        goto leave;
+    }
+
+    /* Ipc initialization */
+    status = Ipc_start();
+
+    if (status >= 0) {
+        /* application create, exec, delete */
+        status = Main_main();
+
+        /* Ipc finalization */
+        Ipc_stop();
+    }
+    else {
+        printf("Ipc_start failed: status = %d\n", status);
+        goto leave;
+    }
+
+leave:
+    printf("<-- main:\n");
+    status = (status >= 0 ? 0 : status);
+
+    return (status);
+}
+
+
+/*
+ *  ======== Main_main ========
+ */
+Int Main_main(Void)
+{
+    UInt16      remoteProcId;
+    Int         status = 0;
+
+    printf("--> Main_main:\n");
+
+    remoteProcId = MultiProc_getId(Main_remoteProcName);
+
+    /* application create phase */
+    status = App_create(remoteProcId);
+
+    if (status < 0) {
+        goto leave;
+    }
+
+    /* application execute phase */
+    status = App_exec();
+
+    if (status < 0) {
+        goto leave;
+    }
+
+    /* application delete phase */
+    status = App_delete();
+
+    if (status < 0) {
+        goto leave;
+    }
+
+leave:
+    printf("<-- Main_main:\n");
+
+    if (status < 0)
+        printf("\n Host: Test Failed, error %d\n", status);
+    else
+        printf("\n Host: Test Passed \n");
+
+    status = (status >= 0 ? 0 : status);
+    return (status);
+}
+
+
+/*
+ *  ======== Main_parseArgs ========
+ */
+Int Main_parseArgs(Int argc, Char *argv[])
+{
+    Int             x, cp, opt, argNum;
+    UInt16          i, numProcs;
+    String          name;
+    Int             status = 0;
+
+
+    /* parse the command line options */
+    for (opt = 1; (opt < argc) && (argv[opt][0] == '-'); opt++) {
+        for (x = 0, cp = 1; argv[opt][cp] != '\0'; cp++) {
+            x = (x << 8) | (int)argv[opt][cp];
+        }
+
+        switch (x) {
+            case 'h': /* -h */
+                printf("%s", Main_USAGE);
+                exit(0);
+                break;
+
+            case 'l': /* -l */
+                printf("Processor List\n");
+                status = Ipc_start();
+                if (status >= 0) {
+                    numProcs = MultiProc_getNumProcessors();
+                    for (i = 0; i < numProcs; i++) {
+                        name = MultiProc_getName(i);
+                        printf("    procId=%d, procName=%s\n", i, name);
+                    }
+                    Ipc_stop();
+                }
+                else {
+                    printf(
+                        "Error: %s, line %d: Ipc_start failed\n",
+                        __FILE__, __LINE__);
+                    goto leave;
+                }
+                exit(0);
+                break;
+
+            default:
+                printf(
+                    "Error: %s, line %d: invalid option, %c\n",
+                    __FILE__, __LINE__, (Char)x);
+                printf("%s", Main_USAGE);
+                status = -1;
+                goto leave;
+        }
+    }
+
+    /* parse the command line arguments */
+    for (argNum = 1; opt < argc; argNum++, opt++) {
+
+        switch (argNum) {
+            case 1: /* name of proc #1 */
+                Main_remoteProcName = argv[opt];
+                break;
+
+            default:
+                printf(
+                    "Error: %s, line %d: too many arguments\n",
+                    __FILE__, __LINE__);
+                printf("%s", Main_USAGE);
+                status = -1;
+                goto leave;
+        }
+    }
+
+    /* validate command line arguments */
+    if (Main_remoteProcName == NULL) {
+        printf("Error: missing procName argument\n");
+        printf("%s", Main_USAGE);
+        status = -1;
+        goto leave;
+    }
+
+leave:
+    return(status);
+}
diff --git a/host_linux/simple_buffer_example/host/makefile b/host_linux/simple_buffer_example/host/makefile
new file mode 100644 (file)
index 0000000..f229c63
--- /dev/null
@@ -0,0 +1,190 @@
+#
+#  Copyright (c) 2017 Texas Instruments Incorporated - http://www.ti.com
+#  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.
+#
+
+#
+#  ======== Makefile ========
+#
+
+srcs = main_host.c App.c
+locallibsrcs = shared/bigdataxlat/bigdataxlat.c \
+  host/SharedRegion/src/SharedRegion.c \
+  host/HeapMem/src/HeapMem.c \
+  host/utils/List.c \
+  host/utils/Memory.c \
+  host/utils/Cache.c
+
+EXBASE = ..
+include $(EXBASE)/products.mak
+-include $(addprefix bin/$(PROFILE)/obj/,$(patsubst %.c,%.ov7A.dep,$(srcs)))
+-include $(addprefix bin/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.ov7A.dep,$(locallibsrcs)))
+
+objs = $(addprefix bin/$(PROFILE)/obj/,$(patsubst %.c,%.ov7A,$(srcs)))
+locallibobjs = $(addprefix bin/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.ov7A,$(locallibsrcs)))
+
+ifdef LIBS_STATIC
+libs = libtitransportrpmsg.a \
+       libtiipc.a \
+       libtiipcutils.a
+else
+# Use dynamic or shared libs
+#libs = $(IPC_INSTALL_DIR)/linux/src/api/.libs/libtiipc.so \
+#       $(IPC_INSTALL_DIR)/linux/src/utils/.libs/libtiipcutils.so \
+#       $(IPC_INSTALL_DIR)/linux/src/transport/.libs/libtitransportrpmsg.so
+libs =
+endif
+
+all:
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+#      $(MAKE) PROFILE=debug app_host
+       $(MAKE) PROFILE=release app_host
+
+help:
+       @$(ECHO) "make                  # build executables"
+       @$(ECHO) "make clean            # clean everything"
+
+install:
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+#      @$(MKDIR) $(EXEC_DIR)/debug
+#      $(CP) bin/debug/app_host $(EXEC_DIR)/debug
+       @$(MKDIR) $(EXEC_DIR)/release
+       $(CP) bin/$(PLATFORM)/release/app_host $(EXEC_DIR)/release
+
+clean::
+       $(RMDIR) bin
+
+#
+#  ======== rules ========
+#
+app_host: bin/$(PLATFORM)/$(PROFILE)/app_host
+bin/$(PLATFORM)/$(PROFILE)/app_host: $(objs) $(locallibobjs) $(libs)
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+       $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+
+bin/$(PROFILE)/obj/%.ov7A: %.c
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+       $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+bin/$(PLATFORM)/$(PROFILE)/obj/%.ov7A: ../%.c
+       @$(ECHO) "#"
+       @$(ECHO) "# Making $@ ..."
+       $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+#  ======== install validation ========
+ifeq (install,$(MAKECMDGOALS))
+ifeq (,$(EXEC_DIR))
+$(error must specify EXEC_DIR)
+endif
+endif
+
+#  ======== toolchain macros ========
+ifndef LINUX_SYSROOT_DIR
+CC = $(TOOLCHAIN_PREFIX)gcc
+AR = $(TOOLCHAIN_PREFIX)ar
+LD = $(TOOLCHAIN_PREFIX)gcc
+CFLAGS =
+CPPFLAGS =
+LDFLAGS = -L$(IPC_INSTALL_DIR)/linux/src/api/.libs/ \
+    -L$(IPC_INSTALL_DIR)/linux/src/utils/.libs \
+    -L$(IPC_INSTALL_DIR)/linux/src/transport/.libs \
+    -L$(CMEM_INSTALL_DIR)/src/cmem/api/.libs
+else
+LD = $(CC)
+endif
+
+CFLAGS += -c -MD -MF $@.dep
+ARFLAGS = cr
+
+CPPFLAGS += -D_REENTRANT
+
+CFLAGS += -Wall -ffloat-store -fPIC -Wunused -pthread -Dfar= $(CCPROFILE_$(PROFILE)) \
+    -I. -I.. -I../shared/bigdataxlat -I../shared/bigdataxlat/linux -I../host/SharedRegion -I../host/SharedRegion/src/inc \
+    -I../host/HeapMem -I../host/HeapMem/src/inc -I../host/utils
+
+ifdef LINUX_SYSROOT_DIR
+CFLAGS += -I$(LINUX_SYSROOT_DIR)
+else
+CFLAGS += -I$(IPC_INSTALL_DIR)/linux/include -I$(IPC_INSTALL_DIR)/packages -I$(CMEM_INSTALL_DIR)/include
+endif
+
+LDFLAGS += $(LDPROFILE_$(PROFILE)) -Wall -Wl,-Map=$@.map
+
+LDLIBS = -lpthread -lc -lrt -lticmem
+ifndef LIBS_STATIC
+LDLIBS +=-ltiipc -ltiipcutils -ltitransportrpmsg
+endif
+CCPROFILE_debug = -ggdb -D DEBUG
+CCPROFILE_release = -O3 -D NDEBUG
+
+LDPROFILE_debug = -ggdb
+LDPROFILE_release = -O3
+
+#  ======== standard macros ========
+ifneq (,$(wildcard $(XDC_INSTALL_DIR)/bin/echo.exe))
+    # use these on Windows
+    CP      = $(XDC_INSTALL_DIR)/bin/cp
+    ECHO    = $(XDC_INSTALL_DIR)/bin/echo
+    MKDIR   = $(XDC_INSTALL_DIR)/bin/mkdir -p
+    RM      = $(XDC_INSTALL_DIR)/bin/rm -f
+    RMDIR   = $(XDC_INSTALL_DIR)/bin/rm -rf
+else
+    # use these on Linux
+    CP      = cp
+    ECHO    = echo
+    MKDIR   = mkdir -p
+    RM      = rm -f
+    RMDIR   = rm -rf
+endif
+
+#  ======== create output directories ========
+ifneq (clean,$(MAKECMDGOALS))
+ifneq (,$(PROFILE))
+ifeq (,$(wildcard bin/$(PROFILE)/obj))
+    $(shell $(MKDIR) -p bin/$(PROFILE)/obj)
+endif
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj/shared/bigdataxlat/linux))
+    $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj/shared/bigdataxlat/linux)
+endif
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj/host/SharedRegion/src))
+    $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj/host/SharedRegion/src)
+endif
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj/host/HeapMem/src))
+    $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj/host/HeapMem/src)
+endif
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj/host/utils))
+    $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj/host/utils)
+endif
+endif
+endif
diff --git a/host_linux/simple_buffer_example/host/std_linux.h b/host_linux/simple_buffer_example/host/std_linux.h
new file mode 100755 (executable)
index 0000000..6e6c108
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ *  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   ti/syslink/inc/knl/Linux/std_linux.h
+ */
+
+#if !defined(STD_LINUX_H)
+#define STD_LINUX_H
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* Branch Prediction for likely true case */
+#define EXPECT_TRUE(x)     __builtin_expect(!!(x), 1)
+/* Branch Prediction for likely false case */
+#define EXPECT_FALSE(x)    __builtin_expect(!!(x), 0)
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif
diff --git a/host_linux/simple_buffer_example/host/utils/Cache.c b/host_linux/simple_buffer_example/host/utils/Cache.c
new file mode 100755 (executable)
index 0000000..31928d8
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  @file   Cache.c
+ *
+ *  @brief      Cache API implementation
+ *
+ *
+ *  ============================================================================
+ *
+ *  Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ *  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.
+ *  Contact information for paper mail:
+ *  Texas Instruments
+ *  Post Office Box 655303
+ *  Dallas, Texas 75265
+ *  Contact information: 
+ *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ *  ============================================================================
+ *  
+ */
+
+/* Standard headers */
+#include <ti/ipc/Std.h>
+#include <ti/cmem.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif /* defined (__cplusplus) */
+
+/*
+ *  ======== Cache_inv ========
+ */
+Void Cache_inv(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait)
+{
+    /* Do cache inv using CMEM device */
+    CMEM_cacheInv(blockPtr, byteCnt);
+     
+}
+
+/*
+ *  ======== Cache_wb ========
+ */
+Void Cache_wb(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait)
+{
+    /* Do cache writeback using CMEM device */
+    CMEM_cacheWb(blockPtr, byteCnt);
+}
+
+/*
+ *  ======== Cache_wbInv ========
+ */
+Void Cache_wbInv(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait)
+{
+    /* Do cache write back and inv using CMEM device */
+    CMEM_cacheWbInv(blockPtr, byteCnt);
+}
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
diff --git a/host_linux/simple_buffer_example/host/utils/Cache.h b/host_linux/simple_buffer_example/host/utils/Cache.h
new file mode 100755 (executable)
index 0000000..56329b0
--- /dev/null
@@ -0,0 +1,157 @@
+/** 
+ *  @file   Cache.h
+ *
+ *  @brief      Defines Cache API interface.
+ *
+ *
+ */
+/* 
+ *  ============================================================================
+ *
+ *  Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ *  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.
+ *  Contact information for paper mail:
+ *  Texas Instruments
+ *  Post Office Box 655303
+ *  Dallas, Texas 75265
+ *  Contact information: 
+ *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ *  ============================================================================
+ *  
+ */
+
+
+
+#ifndef CACHE_H
+#define CACHE_H
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif /* defined (__cplusplus) */
+
+/* =============================================================================
+ *  All success and failure codes for the module
+ * =============================================================================
+ */
+
+/*!
+ *  @def    Cache_S_ALREADYSETUP
+ *  @brief  Cache module is already setup.
+ */
+#define Cache_S_ALREADYSETUP        (1)
+
+/*!
+ *  @def    Cache_S_SUCCESS
+ *  @brief  Operation is successful.
+ */
+#define Cache_S_SUCCESS             (0)
+
+/*!
+ *  @def    Cache_E_FAIL
+ *  @brief  Generic failure.
+ */
+#define Cache_E_FAIL                (-1)
+
+/*!
+ *  @def    Cache_E_INVALIDARG
+ *  @brief  Argument passed to a function is invalid.
+ */
+#define Cache_E_INVALIDARG          (-2)
+
+/*!
+ *  @def    Cache_E_OSFAILURE
+ *  @brief  Failure in OS call.
+ */
+#define Cache_E_OSFAILURE           (-3)
+
+/* ================================
+ *  Enums for the module
+ * ================================
+ */
+/*! Lists of bitmask cache types */
+enum Cache_Type {
+    Cache_Type_L1P = 0x1,         /*! Level 1 Program cache */
+    Cache_Type_L1D = 0x2,         /*! Level 1 Data cache */
+    Cache_Type_L1  = 0x3,         /*! Level 1 caches */
+    Cache_Type_L2P = 0x4,         /*! Level 2 Program cache */
+    Cache_Type_L2D = 0x8,         /*! Level 2 Data cache */
+    Cache_Type_L2  = 0xC,         /*! Level 2 caches */
+    Cache_Type_ALL = 0xffff       /*! All caches */
+};
+
+/*! Lists of cache modes */
+enum Cache_Mode {
+    Cache_Mode_FREEZE,
+    Cache_Mode_BYPASS,
+    Cache_Mode_NORMAL
+};
+
+/*!
+ *  @brief      Invalidate the Cache module.
+ *
+ *  @sa         Cache_inv
+ */
+Void Cache_inv(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait);
+
+/*!
+ *  @brief      Writeback the Cache module.
+ *
+ *  @sa         Cache_wb
+ */
+Void Cache_wb(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait);
+
+/*!
+ *  @brief      Write Back and Invalidate the Cache module.
+ *
+ *  @sa         Cache_wbInv
+ */
+Void Cache_wbInv(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait);
+
+/*!
+ *  @brief      Wait for cache operation to complete.
+ *
+ *  @sa         Cache_wait
+ */
+Void Cache_wait(Void);
+
+/*!
+ *  @brief      Set the mode of Cache module.
+ *
+ *  @sa         Cache_setMode
+ */
+enum Cache_Mode Cache_setMode(Bits16 type, enum Cache_Mode mode);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* CACHE_H */
diff --git a/host_linux/simple_buffer_example/host/utils/IHeap.h b/host_linux/simple_buffer_example/host/utils/IHeap.h
new file mode 100755 (executable)
index 0000000..8106941
--- /dev/null
@@ -0,0 +1,291 @@
+/** 
+ *  @file   IHeap.h
+ *
+ *  @brief      Defines Heap based memory allocator.
+ *
+ *              Heap implementation that manages fixed size buffers that can be
+ *              used in a multiprocessor system with shared memory.
+ *
+ *              The Heap manager provides functions to allocate and free storage
+ *              from a heap of type Heap which inherits from IHeap. Heap manages
+ *              a single fixed-size buffer, split into equally sized allocable
+ *              blocks.
+ *
+ *              The Heap manager is intended as a very fast memory
+ *              manager which can only allocate blocks of a single size. It is
+ *              ideal for managing a heap that is only used for allocating a
+ *              single type of object, or for objects that have very similar
+ *              sizes.
+ *
+ *              This module is instance based. Each instance requires shared
+ *              memory (for the buffers and other internal state).  This is
+ *              specified via the sharedAddr parameter to the create. The proper
+ *              sharedAddrSize parameter can be determined via the
+ *              sharedMemReq call. Note: the parameters to this
+ *              function must be the same that will used to create the instance.
+ *
+ *              The Heap module uses a NameServer instance to
+ *              store instance information when an instance is created and the
+ *              name parameter is non-NULL. If a name is supplied, it must be
+ *              unique for all Heap instances.
+ *
+ *              The create initializes the shared memory as needed. The shared
+ *              memory must be initialized to 0 before the Heap instance is
+ *              created or opened.
+ *
+ *              Once an instance is created, an open can be performed. The
+ *              open is used to gain access to the same Heap instance.
+ *              Generally an instance is created on one processor and opened
+ *              on the other processor(s).
+ *
+ *              The open returns a Heap instance handle like the create,
+ *              however the open does not modify the shared memory.
+ *
+ *              There are two options when opening the instance:
+ *              -Supply the same name as specified in the create. The Heap
+ *              module queries the NameServer to get the needed information.
+ *              -Supply the same sharedAddr value as specified in the create.
+ *
+ *              If the open is called before the instance is created, open
+ *              returns NULL.
+ *
+ *              Constraints:
+ *              -Align parameter must be a power of 2.
+ *              -The buffer passed to dynamically create a Heap must be aligned
+ *               according to the alignment parameter, and must be large enough
+ *               to account for the actual block size after it has been rounded
+ *               up to a multiple of the alignment.
+ *
+ *
+ */
+/* 
+ *  ============================================================================
+ *
+ *  Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ *  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.
+ *  Contact information for paper mail:
+ *  Texas Instruments
+ *  Post Office Box 655303
+ *  Dallas, Texas 75265
+ *  Contact information: 
+ *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ *  ============================================================================
+ *  
+ */
+
+
+
+#ifndef HEAP_H_0x7033
+#define HEAP_H_0x7033
+
+
+#include <assert.h>
+/* OSAL and utils */
+#include "MemoryDefs.h"
+#include <Trace.h>
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* =============================================================================
+ *  Forward declarations
+ * =============================================================================
+ */
+/*! @brief Forward declaration of structure defining object for the
+ *         Heap module
+ */
+typedef struct IHeap_Object_tag IHeap_Object;
+
+/*!
+ *  @brief  Handle for the Heap Buf.
+ */
+typedef IHeap_Object * IHeap_Handle;
+
+
+/* =============================================================================
+ *  Function pointer types for heap operations
+ * =============================================================================
+ */
+/*! @brief Type for function pointer to allocate a memory block */
+typedef Ptr (*IHeap_allocFxn) (IHeap_Handle    handle,
+                               SizeT           size,
+                               SizeT           align);
+
+/*! @brief Type for function pointer to free a memory block */
+typedef Void (*IHeap_freeFxn) (IHeap_Handle handle,
+                               Ptr          block,
+                               SizeT        size);
+
+/*! @brief Type for function pointer to get memory related statistics */
+typedef Void (*IHeap_getStatsFxn) (IHeap_Handle    handle,
+                                   Memory_Stats  * stats);
+
+/*
+ * ! @brief Type for function pointer to indicate whether the heap may block
+ *          during an alloc or free call
+ */
+typedef Bool (*IHeap_isBlockingFxn) (IHeap_Handle handle);
+
+/*! @brief Type for function pointer to get handle to kernel object */
+typedef Ptr (*IHeap_getKnlHandleFxn) (IHeap_Handle handle);
+
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+/*!
+ *  @brief  Structure for the Handle for the Heap.
+ */
+struct IHeap_Object_tag {
+    IHeap_allocFxn               alloc;
+    /*!<  Allocate a block */
+    IHeap_freeFxn                free;
+    /*!<  Free a block */
+    IHeap_getStatsFxn            getStats;
+    /*!<  Get statistics */
+    IHeap_isBlockingFxn          isBlocking;
+    /*!<  Does the Heap block during alloc/free? */
+    IHeap_getKnlHandleFxn        getKnlHandle;
+    /*!<  Get kernel object handle */
+    Ptr                          obj;
+    /*!<  Actual Heap Handle */
+};
+
+
+/* =============================================================================
+ *  APIs
+ * =============================================================================
+ */
+/*!
+ *  @brief      Allocate a block of memory of specified size.
+ *
+ *  @param      handle    Handle to previously created/opened instance.
+ *  @param      size      Size to be allocated (in bytes)
+ *  @param      align     Alignment for allocation (power of 2)
+ *
+ *  @retval     buffer    Allocated buffer
+ *
+ *  @sa         IHeap_free
+ */
+static inline Ptr IHeap_alloc (IHeap_Handle    handle,
+                               SizeT           size,
+                               SizeT           align)
+{
+    Ptr buffer;
+
+    GT_assert (curTrace, (((IHeap_Object *) handle)->alloc != NULL));
+    buffer = ((IHeap_Object *) handle)->alloc (handle, size, align);
+    return (buffer);
+}
+
+
+/*!
+ *  @brief      Frees a block of memory.
+ *
+ *  @param      handle    Handle to previously created/opened instance.
+ *  @param      block     Block of memory to be freed.
+ *  @param      size      Size to be freed (in bytes)
+ *
+ *  @sa         Heap_alloc
+ */
+static inline Void IHeap_free (IHeap_Handle handle,
+                               Ptr          block,
+                               SizeT        size)
+{
+    GT_assert (curTrace, (((IHeap_Object *) handle)->free != NULL));
+    ((IHeap_Object *) handle)->free (handle, block, size);
+}
+
+
+/*!
+ *  @brief      Get memory statistics
+ *
+ *  @param      handle    Handle to previously created/opened instance.
+ *  @params     stats     Memory statistics structure
+ *
+ *  @sa
+ */
+static inline Void IHeap_getStats (IHeap_Handle    handle,
+                                   Memory_Stats  * stats)
+{
+    GT_assert (curTrace, (((IHeap_Object *) handle)->getStats != NULL));
+    ((IHeap_Object *) handle)->getStats (handle, stats);
+}
+
+
+/*!
+ *  @brief      Indicate whether the heap may block during an alloc or free call
+ *
+ *  @param      handle    Handle to previously created/opened instance.
+ *
+ *  @retval     TRUE      Heap is blocking
+ *  @retval     FALSE     Heap is non-blocking
+ *
+ *  @sa
+ */
+static inline Bool IHeap_isBlocking (IHeap_Handle    handle)
+{
+    Bool isBlocking;
+    GT_assert (curTrace, (((IHeap_Object *) handle)->isBlocking != NULL));
+    isBlocking = ((IHeap_Object *) handle)->isBlocking (handle);
+    return (isBlocking);
+}
+
+
+/*!
+ *  @brief Function to get the kernel object pointer embedded in userspace heap.
+ *         Some Heap implementations return the kernel object handle.
+ *         Heaps which do not have kernel object pointer embedded return NULL.
+ *
+ *  @params handle handle to a heap instance
+ *
+ *  @retval     handle    Handle to kernel object.
+ *
+ *  @sa
+ */
+static inline Ptr IHeap_getKnlHandle (IHeap_Handle    handle)
+{
+    Ptr knlHandle;
+    GT_assert (curTrace, (((IHeap_Object *) handle)->getKnlHandle != NULL));
+    knlHandle = ((IHeap_Object *) handle)->getKnlHandle (handle);
+    return (knlHandle);
+}
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* HEAP_H_0x7033 */
+
diff --git a/host_linux/simple_buffer_example/host/utils/List.c b/host_linux/simple_buffer_example/host/utils/List.c
new file mode 100755 (executable)
index 0000000..923aece
--- /dev/null
@@ -0,0 +1,798 @@
+/*
+ *  @file   List.c
+ *
+ *  @brief      Creates a doubly linked list.
+ *
+ *
+ *  ============================================================================
+ *
+ *  Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ *  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.
+ *  Contact information for paper mail:
+ *  Texas Instruments
+ *  Post Office Box 655303
+ *  Dallas, Texas 75265
+ *  Contact information: 
+ *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ *  ============================================================================
+ *
+ */
+
+/* Standard headers */
+#include <ti/ipc/Std.h>
+#include "Std.h"
+#include "List.h"
+#include "Memory.h"
+
+#include "Trace.h"
+
+/* =============================================================================
+ *  All success and failure codes for the module. Defined here because they are
+ *  only used internally.
+ * =============================================================================
+ */
+
+/*!
+ *  @def    List_S_BUSY
+ *  @brief  The resource is still in use
+ */
+#define List_S_BUSY           2
+
+/*!
+ *  @def    List_S_ALREADYSETUP
+ *  @brief  The module has been already setup
+ */
+#define List_S_ALREADYSETUP   1
+
+/*!
+ *  @def    List_S_SUCCESS
+ *  @brief  Operation is successful.
+ */
+#define List_S_SUCCESS        0
+
+/*!
+ *  @def    List_E_FAIL
+ *  @brief  Generic failure.
+ */
+#define List_E_FAIL           -1
+
+/*!
+ *  @def    List_E_INVALIDARG
+ *  @brief  Argument passed to function is invalid.
+ */
+#define List_E_INVALIDARG     -2
+
+/*!
+ *  @def    List_E_MEMORY
+ *  @brief  Operation resulted in memory failure.
+ */
+#define List_E_MEMORY         -3
+
+/*!
+ *  @def    List_E_ALREADYEXISTS
+ *  @brief  The specified entity already exists.
+ */
+#define List_E_ALREADYEXISTS  -4
+
+/*!
+ *  @def    List_E_NOTFOUND
+ *  @brief  Unable to find the specified entity.
+ */
+#define List_E_NOTFOUND       -5
+
+/*!
+ *  @def    List_E_TIMEOUT
+ *  @brief  Operation timed out.
+ */
+#define List_E_TIMEOUT        -6
+
+/*!
+ *  @def    List_E_INVALIDSTATE
+ *  @brief  Module is not initialized.
+ */
+#define List_E_INVALIDSTATE   -7
+
+/*!
+ *  @def    List_E_OSFAILURE
+ *  @brief  A failure occurred in an OS-specific call
+ */
+#define List_E_OSFAILURE      -8
+
+/*!
+ *  @def    List_E_RESOURCE
+ *  @brief  Specified resource is not available
+ */
+#define List_E_RESOURCE       -9
+
+/*!
+ *  @def    List_E_RESTART
+ *  @brief  Operation was interrupted. Please restart the operation
+ */
+#define List_E_RESTART        -10
+
+/* Function to initialize the parameters structure */
+Void
+List_Params_init (List_Params * params)
+{
+    GT_1trace (curTrace, GT_ENTER, "List_Params_init", params);
+
+    GT_assert (curTrace, (params != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (params == NULL) {
+        /* No retVal since this is a Void function. */
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_Params_init",
+                             List_E_INVALIDARG,
+                             "Argument of type (List_Params *) is NULL!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_LEAVE, "List_Params_init");
+}
+
+/* Function to create a list. */
+List_Handle
+List_create (List_Params * params, Error_Block *eb)
+{
+    List_Object * obj = NULL;
+
+    GT_1trace (curTrace, GT_ENTER, "List_create", params);
+
+    (void) params;
+    (void) eb;
+
+    /* heapHandle can be NULL if created from default OS memory. */
+    obj = (List_Object *) Memory_alloc (NULL,
+                                        sizeof (List_Object),
+                                        0,
+                                        NULL);
+
+    GT_assert (curTrace, (obj != NULL));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (obj == NULL) {
+        /*! @retval NULL Allocate memory for handle failed */
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_create",
+                             List_E_MEMORY,
+                             "Allocating memory for handle failed");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        obj->elem.next  = obj->elem.prev = &(obj->elem);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "List_create", obj);
+
+    /*! @retval valid-handle Operation successful */
+    return (List_Handle) obj;
+}
+
+/* Function to delete the list */
+Void
+List_delete (List_Handle * handlePtr)
+{
+    List_Object * obj;
+
+    GT_1trace (curTrace, GT_ENTER, "List_delete", handlePtr);
+
+    GT_assert (curTrace, (handlePtr != NULL));
+    GT_assert (curTrace, ((handlePtr != NULL) && (*handlePtr != NULL)));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (handlePtr == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_delete",
+                             List_E_INVALIDARG,
+                             "handlePtr passed is invalid!");
+    }
+    else if (*handlePtr == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_delete",
+                             List_E_INVALIDARG,
+                             "*handlePtr passed is invalid!");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        obj = (List_Object *) (*handlePtr);
+        Memory_free (NULL, obj, sizeof (List_Object));
+        *handlePtr = NULL;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_LEAVE, "List_delete");
+}
+
+/* Function to initialize the List head */
+Void List_construct(List_Object *obj, List_Params *params)
+{
+    GT_1trace (curTrace, GT_ENTER, "List_construct", obj);
+
+    GT_assert (curTrace, (obj != NULL));
+    /* params is unused, so don't assert anything about it */
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (obj == NULL) {
+        GT_setFailureReason(curTrace, GT_4CLASS, "List_construct",
+                List_E_INVALIDARG, "Invalid NULL passed for obj parameter");
+    }
+    else {
+#endif
+
+        obj->elem.next = obj->elem.prev = &(obj->elem);
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif
+
+    GT_0trace(curTrace, GT_LEAVE, "List_construct");
+}
+
+/* Function to destruct List object */
+Void List_destruct(List_Object *obj)
+{
+#ifdef ENABLE_LOCAL_LOCK
+    IArg key;
+#endif
+
+    GT_1trace(curTrace, GT_ENTER, "List_destruct", obj);
+
+    GT_assert(curTrace, (obj != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (obj == NULL) {
+        GT_setFailureReason(curTrace, GT_4CLASS, "List_destruct",
+                List_E_INVALIDARG, "Invalid NULL passed for obj parameter");
+    }
+    else {
+#endif
+
+#ifdef ENABLE_LOCAL_LOCK
+        key = Gate_enterSystem ();;
+#endif
+        obj->elem.next = NULL;
+        obj->elem.prev = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+        Gate_leaveSystem(key);
+#endif
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif
+
+    GT_0trace (curTrace, GT_LEAVE, "List_destruct");
+}
+
+/* Function to remove specific elem from list */
+Void
+List_elemClear (List_Elem * elem)
+{
+    GT_1trace (curTrace, GT_ENTER, "List_elemClear", elem);
+
+    GT_assert (curTrace, (elem != NULL));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (elem == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_elemClear",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for elem parameter");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+         elem->next = elem->prev = elem;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_LEAVE, "List_elemClear");
+}
+
+/* Function to check if list is empty */
+Bool
+List_empty (List_Handle handle)
+{
+    Bool          isEmpty = FALSE;
+    List_Object * obj     = (List_Object *) handle;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg          key     = 0;
+#endif
+
+    GT_1trace (curTrace, GT_ENTER, "List_empty", handle);
+
+    GT_assert (curTrace, (handle != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (handle == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_empty",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for handle parameter");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_LOCAL_LOCK
+        key = Gate_enterSystem();
+#endif
+
+        if (obj->elem.next == &(obj->elem)) {
+            /*! @retval TRUE List is empty */
+            isEmpty = TRUE;
+        }
+#ifdef ENABLE_LOCAL_LOCK
+        Gate_leaveSystem(key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "List_empty", isEmpty);
+
+    /*! @retval FALSE List is not empty */
+    return isEmpty;
+}
+
+/* Function to get front element */
+Ptr
+List_get (List_Handle handle)
+{
+    List_Elem *   elem = NULL;
+    List_Object * obj  = (List_Object *) handle;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg          key  = 0;
+#endif
+
+    GT_1trace (curTrace, GT_ENTER, "List_get", handle);
+
+    GT_assert (curTrace, (handle != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (handle == NULL) {
+        /*! @retval NULL Invalid NULL passed for handle parameter */
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_get",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for handle parameter");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_LOCAL_LOCK
+        key = Gate_enterSystem();
+#endif
+
+        elem = List_dequeue(obj);
+
+#ifdef ENABLE_LOCAL_LOCK
+        Gate_leaveSystem(key);
+#endif
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "List_get", elem);
+
+    /*! @retval Valid-pointer Pointer to first element */
+    return elem ;
+}
+
+/* Function to put elem at the end */
+Void
+List_put (List_Handle handle, List_Elem * elem)
+{
+    List_Object * obj    = (List_Object *) handle;
+#ifdef ENABLE_LOCAL_LOCK
+    IArg          key    = 0;
+#endif
+
+    GT_2trace (curTrace, GT_ENTER, "List_put", handle, elem);
+
+    GT_assert (curTrace, (handle != NULL));
+    GT_assert (curTrace, (elem != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (handle == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_put",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for handle parameter");
+    }
+    else if (elem == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_put",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for elem parameter");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_LOCAL_LOCK
+        key = Gate_enterSystem();
+#endif
+        List_enqueue (obj, elem);
+#ifdef ENABLE_LOCAL_LOCK
+        Gate_leaveSystem(key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_LEAVE, "List_put");
+}
+
+/* Function to get next elem of current one (non-atomic) */
+Ptr
+List_next (List_Handle handle, List_Elem * elem)
+{
+    List_Elem *   retElem = NULL;
+    List_Object * obj     = (List_Object *) handle;
+
+    GT_2trace (curTrace, GT_ENTER, "List_Next", handle, elem);
+
+    GT_assert (curTrace, (handle != NULL)) ;
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (handle == NULL) {
+        /*! @retval NULL Invalid NULL passed for handle parameter */
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_next",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for handle parameter");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        /* elem == NULL -> start at the head */
+        if (elem == NULL) {
+            retElem = obj->elem.next;
+        }
+        else {
+            retElem = elem->next;
+        }
+
+        if (retElem == (List_Elem *) obj) {
+            /*! @retval NULL List reached end or list is empty */
+            retElem = NULL;
+        }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "List_Next", retElem);
+
+    /*! @retval Valid-pointer Pointer to the next element */
+    return retElem;
+}
+
+/* Function to get previous elem of current one (non-atomic) */
+Ptr
+List_prev (List_Handle handle, List_Elem * elem)
+{
+    List_Elem *   retElem = NULL;
+    List_Object * obj     = (List_Object *) handle;
+
+    GT_2trace (curTrace, GT_ENTER, "List_prev", handle, elem);
+
+    GT_assert (curTrace, (handle != NULL)) ;
+    GT_assert (curTrace, (elem != NULL)) ;
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (handle == NULL) {
+        /*! @retval NULL Invalid NULL passed for handle parameter */
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_prev",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for handle parameter");
+    }
+    else if (elem == NULL) {
+        /*! @retval NULL Invalid NULL passed for elem parameter */
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_prev",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for elem parameter");
+    }
+    else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+        /* elem == NULL -> start at the head */
+        if (elem == NULL) {
+            retElem = obj->elem.prev;
+        }
+        else {
+            retElem = elem->prev;
+        }
+
+        if (retElem == (List_Elem *)obj) {
+            /*! @retval NULL List reached end or list is empty */
+            retElem = NULL;
+        }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_1trace (curTrace, GT_LEAVE, "List_prev", retElem);
+
+    /*! @retval Valid-pointer Pointer to the prev element */
+    return retElem;
+}
+
+/* Function to insert elem before existing elem */
+Void
+List_insert  (List_Handle handle, List_Elem * newElem, List_Elem * curElem)
+{
+    GT_3trace (curTrace, GT_ENTER, "List_insert", handle, newElem, curElem);
+
+    GT_assert (curTrace, (handle     != NULL));
+    GT_assert (curTrace, (newElem != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (handle == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_insert",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for handle parameter");
+    }
+    else if (newElem == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_insert",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for newElem parameter");
+    }
+    else if (curElem == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_insert",
+                             List_E_INVALIDARG,
+                  "Invalid NULL passed for curElem parameter use List_putHead");
+    }else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+            /* Cannot directly call enqueue since the object has other fields */
+            newElem->next       = curElem;
+            newElem->prev       = curElem->prev;
+            newElem->prev->next = newElem;
+            curElem->prev       = newElem;
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+    GT_0trace (curTrace, GT_LEAVE, "List_insert");
+}
+
+/* Function to remove specific elem from list */
+Void
+List_remove (List_Handle handle, List_Elem * elem)
+{
+    GT_2trace (curTrace, GT_ENTER, "List_remove", handle, elem);
+
+    GT_assert (curTrace, (handle != NULL));
+    GT_assert (curTrace, (elem != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+    if (handle == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_remove",
+                             List_E_INVALIDARG,
+                             "Invalid NULL passed for handle parameter");
+    }
+    else if (elem == NULL) {
+        GT_setFailureReason (curTrace,
+                             GT_4CLASS,
+                             "List_remove",
+                             List_E_INVALIDARG,
+                &n