Linux: Added GateMP support for DRA7XX devices
authorArnie Reynoso <arnier@ti.com>
Tue, 21 Jan 2014 22:17:44 +0000 (14:17 -0800)
committerChris Ring <cring@ti.com>
Wed, 22 Jan 2014 16:34:58 +0000 (08:34 -0800)
GateMP support has been added using the device's spinlocks.

To enable GateMP on the host, throw -g option when launching the
LAD daemon as follows:

        ./lad_dra7xx log.txt -g

To enable GateMP on the slave core, the core must be configured as
the owner of SR0 and GateMP.hostSupport config param must be set
to 'true' as follows:

         var GateMP = xdc.useModule('ti.sdo.ipc.GateMP');
         GateMP.hostSupport = true;

The slave core with GateMP enabled must the loaded (remoteproc)
prior to the execution of LAD on the host. This adds a restriction
on LAD that wasn't previously there.

Note: Initial validation has only been performed on DRA7XX DSP1.

28 files changed:
.gitignore
Makefile.am
linux/include/GateHWSpinlock.h [new file with mode: 0644]
linux/include/GateMP_config.h [new file with mode: 0644]
linux/include/GateMutex.h [new file with mode: 0644]
linux/include/IGateProvider.h [new file with mode: 0644]
linux/include/IObject.h [new file with mode: 0644]
linux/include/_GateMP.h [new file with mode: 0644]
linux/include/_GateMP_daemon.h [new file with mode: 0644]
linux/include/_lad.h
linux/src/api/Ipc.c
linux/src/api/Makefile.am
linux/src/api/NameServer.c
linux/src/api/gates/GateHWSpinlock.c [new file with mode: 0644]
linux/src/api/gates/GateMP.c [new file with mode: 0644]
linux/src/api/gates/GateMutex.c [new file with mode: 0644]
linux/src/daemon/GateHWSpinlock.c [new file with mode: 0644]
linux/src/daemon/GateHWSpinlockCfg_dra7xx.c [new file with mode: 0644]
linux/src/daemon/GateHWSpinlock_daemon.c [new file with mode: 0644]
linux/src/daemon/GateMP_daemon.c [new file with mode: 0644]
linux/src/daemon/Makefile.am
linux/src/daemon/NameServer_daemon.c
linux/src/daemon/lad.c
linux/src/tests/GateMPApp.c [new file with mode: 0644]
linux/src/tests/GateMPApp.h [new file with mode: 0644]
linux/src/tests/Makefile.am
linux/src/tests/main_host.c [new file with mode: 0644]
packages/ti/ipc/tests/gatempapp_rsc_table_vayu_dsp.h

index 6a407071ae86111fd9631569fecf8eb070a4f940..cd98491fa56868b47f4c336b99151dae23b41204 100644 (file)
@@ -47,6 +47,7 @@ packages/ti/srvmgr/omx/OmxSrvMgr.h
 /linux/src/*/.libs
 /linux/src/*/*.o
 /linux/src/daemon/lad_*
+/linux/src/tests/GateMPApp
 /linux/src/tests/MessageQApp
 /linux/src/tests/MessageQBench
 /linux/src/tests/MessageQMulti
index 997f8fe1c19d70008a939e38c30b4d6e1b1c3e99..eeb5d108a61ee1fa7827ff1a3ddcd4c08c5357e3 100644 (file)
@@ -1,5 +1,5 @@
 ##
-##  Copyright (c) 2013, Texas Instruments Incorporated
+##  Copyright (c) 2013-2014, Texas Instruments Incorporated
 ##
 ##  Redistribution and use in source and binary forms, with or without
 ##  modification, are permitted provided that the following conditions
@@ -40,7 +40,7 @@ ipcincludedir = $(includedir)/ti/ipc
 
 # the list of common header files (to be installed later)
 ipcinclude_HEADERS = $(top_srcdir)/packages/ti/ipc/Ipc.h \
+                $(top_srcdir)/packages/ti/ipc/GateMP.h \
                 $(top_srcdir)/packages/ti/ipc/MessageQ.h \
                 $(top_srcdir)/packages/ti/ipc/MultiProc.h \
                 $(top_srcdir)/packages/ti/ipc/NameServer.h
-
diff --git a/linux/include/GateHWSpinlock.h b/linux/include/GateHWSpinlock.h
new file mode 100644 (file)
index 0000000..610cc7a
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2008-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.
+ */
+/*
+ *  ======== GateHWSpinlock.h ========
+ */
+
+#ifndef GATEHWSPINLOCK_H_0xF416
+#define GATEHWSPINLOCK_H_0xF416
+
+/* Utilities & Osal headers */
+#include <ti/ipc/Std.h>
+
+#include <ti/ipc/GateMP.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ *  @def    GateHWSpinlock_MODULEID
+ *  @brief  Unique module ID.
+ */
+#define GateHWSpinlock_MODULEID               (0xc43d)
+
+/* =============================================================================
+ * Module Success and Failure codes
+ * =============================================================================
+ */
+/*!
+ *  @def    GateHWSpinlock_E_INVALIDARG
+ *  @brief  Argument passed to a function is invalid.
+ */
+#define GateHWSpinlock_E_INVALIDARG       -1
+
+/*!
+ *  @def    GateHWSpinlock_E_MEMORY
+ *  @brief  Memory allocation failed.
+ */
+#define GateHWSpinlock_E_MEMORY           -2
+
+/*!
+ *  @def    GateHWSpinlock_E_BUSY
+ *  @brief  the name is already registered or not.
+ */
+#define GateHWSpinlock_E_BUSY             -3
+
+/*!
+ *  @def    GateHWSpinlock_E_FAIL
+ *  @brief  Generic failure.
+ */
+#define GateHWSpinlock_E_FAIL             -4
+
+/*!
+ *  @def    GateHWSpinlock_E_NOTFOUND
+ *  @brief  name not found in the nameserver.
+ */
+#define GateHWSpinlock_E_NOTFOUND         -5
+
+/*!
+ *  @def    GateHWSpinlock_E_INVALIDSTATE
+ *  @brief  Module is not initialized.
+ */
+#define GateHWSpinlock_E_INVALIDSTATE     -6
+
+/*!
+ *  @def    GateHWSpinlock_E_NOTONWER
+ *  @brief  Instance is not created on this processor.
+ */
+#define GateHWSpinlock_E_NOTONWER         -7
+
+/*!
+ *  @def    GateHWSpinlock_E_REMOTEACTIVE
+ *  @brief  Remote opener of the instance has not closed the instance.
+ */
+#define GateHWSpinlock_E_REMOTEACTIVE     -8
+
+/*!
+ *  @def    GateHWSpinlock_E_INUSE
+ *  @brief  Indicates that the instance is in use..
+ */
+#define GateHWSpinlock_E_INUSE            -9
+
+/*!
+ *  @def    GateHWSpinlock_E_OSFAILURE
+ *  @brief  Failure in OS call.
+ */
+#define GateHWSpinlock_E_OSFAILURE        -10
+
+/*!
+ *  @def    GateHWSpinlock_E_VERSION
+ *  @brief  Version mismatch error.
+ */
+#define GateHWSpinlock_E_VERSION          -11
+
+/*!
+ *  @def    GateHWSpinlock_S_SUCCESS
+ *  @brief  Operation successful.
+ */
+#define GateHWSpinlock_S_SUCCESS            0
+
+/*!
+ *  @def    GateHWSpinlock_S_ALREADYSETUP
+ *  @brief  The GATEHWSPINLOCK module has already been setup in this process.
+ */
+#define GateHWSpinlock_S_ALREADYSETUP     1
+
+/* =============================================================================
+ * Macros
+ * =============================================================================
+ */
+/*! @brief Forward declaration of structure defining object for the
+ *                 GateHWSpinlock. */
+typedef struct GateHWSpinlock_Object GateHWSpinlock_Object;
+
+/*!
+ *  @brief  Handle for the GateHWSpinlock.
+ */
+typedef struct GateHWSpinlock_Object * GateHWSpinlock_Handle;
+
+/* Q_BLOCKING */
+#define GateHWSem_Q_BLOCKING   (1)
+
+/* Q_PREEMPTING */
+#define GateHWSem_Q_PREEMPTING (2)
+
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+
+/*!
+ *  @brief  Structure defining config parameters for the GateHWSpinlock module.
+ */
+typedef struct GateHWSpinlock_Config {
+    UInt32               baseAddr;
+    /* Device-specific base address for HW Semaphore subsystem in HOST OS
+     * address space, this is updated in Ipc module */
+    UInt32               size;
+    /* Device-specific size for HW Semaphore subsystem */
+    UInt32               offset;
+    /* Device-specific size for HW Semaphore subsystem */
+} GateHWSpinlock_Config;
+
+/*!
+ *  @brief  Structure defining config parameters for the GateHWSpinlock
+ *          instances.
+ */
+typedef struct GateHWSpinlock_Params {
+    Bits32 resourceId;
+    Bool   openFlag;
+    UInt16 regionId;
+    Ptr    sharedAddr;
+} GateHWSpinlock_Params;
+
+
+typedef enum GateHWSpinlock_LocalProtect {
+        GateHWSpinlock_LocalProtect_NONE      = 0,
+        GateHWSpinlock_LocalProtect_INTERRUPT = 1,
+        GateHWSpinlock_LocalProtect_TASKLET   = 2,
+        GateHWSpinlock_LocalProtect_THREAD    = 3,
+        GateHWSpinlock_LocalProtect_PROCESS   = 4
+} GateHWSpinlock_LocalProtect;
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+/* Function to get the default configuration for the GateHWSpinlock module. */
+Void
+GateHWSpinlock_getConfig (GateHWSpinlock_Config * cfgParams);
+
+/* Function to setup the GateHWSpinlock module. */
+Int
+GateHWSpinlock_setup (const GateHWSpinlock_Config * config);
+
+/* Function to destroy the GateHWSpinlock module */
+Int
+GateHWSpinlock_destroy (Void);
+
+/* Initialize parameter structure */
+Void GateHWSpinlock_Params_init(GateHWSpinlock_Params *params);
+
+/* Function to start GateHWSpinlock module */
+Int32 GateHWSpinlock_start(Void);
+
+/* Funciton to stop GateHWSpinlock module */
+Int GateHWSpinlock_stop(Void);
+
+/* Function to create an instance of GateHWSpinlock */
+GateHWSpinlock_Handle
+GateHWSpinlock_create (      GateHWSpinlock_LocalProtect localProtect,
+                       const GateHWSpinlock_Params *     params);
+
+/* Function to delete an instance of GateHWSpinlock */
+Int
+GateHWSpinlock_delete (GateHWSpinlock_Handle * handlePtr);
+
+/* Function to delete all instances of GateHWSpinlock */
+Int
+GateHWSpinlock_deleteAll (Void);
+
+/* Function to enter the GateHWSpinlock instance */
+IArg
+GateHWSpinlock_enter  (GateHWSpinlock_Handle handle);
+
+/* Function to leave the GateHWSpinlock instance */
+Int
+GateHWSpinlock_leave  (GateHWSpinlock_Handle handle, IArg   key);
+
+/*!
+ *  @brief      Function to return the number of instances configured in the
+ *              module.
+ *
+ *  @return     Number of instances configured.
+ */
+UInt32 GateHWSpinlock_getNumInstances (Void);
+
+/*!
+ *  @brief      Function to initialize the locks
+ *              module.
+ *
+ */
+Void GateHWSpinlock_locksinit(Void);
+
+/* This is exported from daemon/GateHWSpinlockCfg_<PLATFORM>.c */
+extern GateHWSpinlock_Config _GateHWSpinlock_cfgParams;
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* GATEHWSPINLOCK_H_0xF416 */
diff --git a/linux/include/GateMP_config.h b/linux/include/GateMP_config.h
new file mode 100644 (file)
index 0000000..5a63e38
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/*
+ *  ======== GateMP_config.h ========
+ *
+ *  Define the configuration of parameters used in GateMP. This file also
+ *  configures the various proxies.
+ *
+ */
+
+#ifndef GATEMP_CONFIG
+#define GATEMP_CONFIG
+
+#include <GateHWSpinlock.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define MAX_RUNTIME_ENTRIES   128  /* Max number of GateMP instances + 1 */
+#define MAX_NAME_LEN          32   /* Max name length of GateMP instances */
+
+/* Proxy functions and data structures */
+#define GateMP_RemoteSystemProxy_Params_init(x) GateHWSpinlock_Params_init(x)
+#define GateMP_RemoteSystemProxy_create        GateHWSpinlock_create
+#define GateMP_RemoteSystemProxy_delete        GateHWSpinlock_delete
+#define GateMP_RemoteSystemProxy_Params        GateHWSpinlock_Params
+#define GateMP_RemoteSystemProxy_Handle        GateHWSpinlock_Handle
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* GATEMP_CONFIG */
diff --git a/linux/include/GateMutex.h b/linux/include/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/linux/include/IGateProvider.h b/linux/include/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/linux/include/IObject.h b/linux/include/IObject.h
new file mode 100644 (file)
index 0000000..94e3a49
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008-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.
+ */
+
+/*
+ *  ======== IObject.h ========
+ *
+ *  Interface to provide object creation facilities.
+ *
+ *
+ */
+
+#ifndef __IOBJECT_H__
+#define __IOBJECT_H__
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* ObjType */
+typedef enum Ipc_ObjType {
+    Ipc_ObjType_CREATESTATIC         = 0x1,
+    Ipc_ObjType_CREATESTATIC_REGION  = 0x2,
+    Ipc_ObjType_CREATEDYNAMIC        = 0x4,
+    Ipc_ObjType_CREATEDYNAMIC_REGION = 0x8,
+    Ipc_ObjType_OPENDYNAMIC          = 0x10,
+    Ipc_ObjType_LOCAL                = 0x20
+} Ipc_ObjType;
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* ifndef __IOBJECT_H__ */
diff --git a/linux/include/_GateMP.h b/linux/include/_GateMP.h
new file mode 100644 (file)
index 0000000..b73c78f
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+/*
+ *  ======== _GateMP.h ========
+ *
+ *  Internal header
+ *
+ */
+#ifndef _GATEMP_H
+#define _GATEMP_H
+
+#include <ti/ipc/GateMP.h>
+
+#include <IObject.h>
+#include <IGateProvider.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* Helper macros */
+#define GETREMOTE(mask) ((GateMP_RemoteProtect)(mask >> 8))
+#define GETLOCAL(mask)  ((GateMP_LocalProtect)(mask & 0xFF))
+#define SETMASK(remoteProtect, localProtect) \
+                        ((Bits32)(remoteProtect << 8 | localProtect))
+
+/*!
+ *  @brief  Structure for the Handle for the GateMP.
+ */
+typedef struct {
+    GateMP_Params           params;
+    /*!< Instance specific creation parameters */
+    GateMP_RemoteProtect    remoteProtect;
+    GateMP_LocalProtect     localProtect;
+    Ptr                     nsKey;
+    Int                     numOpens;
+
+    Bits16                  mask;
+    Bits16                  creatorProcId;
+    Bits32                  arg;
+
+    IGateProvider_Handle    gateHandle; /* remote gate handle */
+    Ipc_ObjType             objType;
+    IGateProvider_Handle    localGate;  /* local gate handle */
+
+    UInt                    resourceId;
+    /*!< Resource id of GateMP proxy */
+} GateMP_Object;
+
+/* Check GateMP has been setup */
+Bool GateMP_isSetup(Void);
+
+/* Start GateMP module */
+Int GateMP_start(Void);
+
+/* Stop the GateMP module */
+Int GateMP_stop(Void);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* _GATEMP_H */
diff --git a/linux/include/_GateMP_daemon.h b/linux/include/_GateMP_daemon.h
new file mode 100644 (file)
index 0000000..1c879d7
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+/*
+ *  ======== _GateMP_daemon.h ========
+ *
+ *  Internal header
+ *
+ */
+
+#ifndef _GATEMP_DAEMON_H
+#define _GATEMP_DAEMON_H
+
+#include <ti/ipc/GateMP.h>
+#include <ti/ipc/NameServer.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * Setup the GateMP module.
+ */
+Int GateMP_setup(Void);
+
+/*!
+ * Function to destroy the GateMP module.
+ */
+Void GateMP_destroy(Void);
+
+/*!
+ * Find a free resource id for a particular protection type.
+ */
+Int GateMP_getFreeResource(GateMP_RemoteProtect type);
+
+/*!
+ * Release a resource id for a particular protection type.
+ */
+Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type);
+
+/*!
+ * Get the total number of resources for a particular protection type.
+ */
+Int GateMP_getNumResources(GateMP_RemoteProtect type);
+
+/*!
+ * Get the NameServer handle for GateMP.
+ */
+NameServer_Handle GateMP_getNameServer(Void);
+
+/*!
+ * Find out whether GateMP is setup
+ */
+Bool GateMP_isSetup(Void);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* _GATEMP_DAEMONH */
index d184df4f073b39f72c9e0a4c2f945cc973871970..9489ef370df2039a63a198a2acdc025533e3370d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, Texas Instruments Incorporated
+ * Copyright (c) 2012-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -46,6 +46,9 @@ extern "C" {
 #include <ti/ipc/MultiProc.h>
 #include <_MultiProc.h>
 #include <stdio.h>
+#include <ti/ipc/GateMP.h>
+#include <_GateMP.h>
+#include <GateHWSpinlock.h>
 
 extern Bool logFile;
 extern FILE *logPtr;
@@ -100,6 +103,8 @@ extern FILE *logPtr;
 
 #define LAD_MESSAGEQCREATEMAXNAMELEN 32
 
+#define LAD_MAXENTRYNAMELEN 32   /* size limit for LAD NameServer name */
+#define LAD_MAXENTRYVALUELEN 32  /* size limit for LAD NameServer value */
 
 typedef enum {
     LAD_CONNECT = 0,
@@ -109,6 +114,8 @@ typedef enum {
     LAD_NAMESERVER_PARAMS_INIT,
     LAD_NAMESERVER_CREATE,
     LAD_NAMESERVER_DELETE,
+    LAD_NAMESERVER_ADD,
+    LAD_NAMESERVER_GET,
     LAD_NAMESERVER_ADDUINT32,
     LAD_NAMESERVER_GETUINT32,
     LAD_NAMESERVER_REMOVE,
@@ -120,6 +127,12 @@ typedef enum {
     LAD_MESSAGEQ_DELETE,
     LAD_MESSAGEQ_MSGINIT,
     LAD_MULTIPROC_GETCONFIG,
+    LAD_GATEMP_START,
+    LAD_GATEMP_GETNUMRESOURCES,
+    LAD_GATEMP_GETFREERESOURCE,
+    LAD_GATEMP_RELEASERESOURCE,
+    LAD_GATEMP_ISSETUP,
+    LAD_GATEHWSPINLOCK_GETCONFIG,
     LAD_EXIT
 } _LAD_Command;
 
@@ -133,7 +146,7 @@ struct LAD_CommandObj {
             Char protocol[LAD_MAXLENGTHPROTOVERS];
         } connect;
         struct {
-            Char name[NameServer_Params_MAXNAMELEN];
+            Char name[LAD_MAXENTRYNAMELEN];
             NameServer_Params params;
         } create;
         struct {
@@ -141,17 +154,29 @@ struct LAD_CommandObj {
         } delete;
         struct {
             NameServer_Handle handle;
-            Char name[NameServer_Params_MAXNAMELEN];
+            Char name[LAD_MAXENTRYNAMELEN];
+            UInt8 buf[LAD_MAXENTRYVALUELEN];
+            UInt32 len;
+        } add;
+        struct {
+            NameServer_Handle handle;
+            Char name[LAD_MAXENTRYNAMELEN];
+            UInt32 len;
+            UInt16 procId[MultiProc_MAXPROCESSORS];
+        } get;
+        struct {
+            NameServer_Handle handle;
+            Char name[LAD_MAXENTRYNAMELEN];
             UInt32 val;
         } addUInt32;
         struct {
             NameServer_Handle handle;
-            Char name[NameServer_Params_MAXNAMELEN];
+            Char name[LAD_MAXENTRYNAMELEN];
             UInt16 procId[MultiProc_MAXPROCESSORS];
         } getUInt32;
         struct {
             NameServer_Handle handle;
-            Char name[NameServer_Params_MAXNAMELEN];
+            Char name[LAD_MAXENTRYNAMELEN];
         } remove;
         struct {
             NameServer_Handle handle;
@@ -167,10 +192,28 @@ struct LAD_CommandObj {
         struct {
             Void *serverHandle;
         } messageQDelete;
+        struct {
+            GateMP_RemoteProtect type;
+        } gateMPGetNumResources;
+        struct {
+            GateMP_RemoteProtect type;
+        } gateMPGetFreeResource;
+        struct {
+            GateMP_RemoteProtect type;
+            Int32 id;
+        } gateMPReleaseResource;
+        struct {
+            Bool result;
+        } gateMPIsSetup;
     } args;
 };
 
 union LAD_ResponseObj {
+    struct {
+       Int status;
+       UInt32 len;
+       UInt8 buf[LAD_MAXENTRYVALUELEN];
+    } get;
     struct {
        Int status;
        UInt32 val;
@@ -207,6 +250,29 @@ union LAD_ResponseObj {
        Int status;
        MultiProc_Config cfg;
     } multiprocGetConfig;
+    struct {
+       Int status;
+       NameServer_Handle nameServerHandle;
+    } gateMPStart;
+    struct {
+       Int status;
+       Int32 value;
+    } gateMPGetNumResources;
+    struct {
+       Int status;
+       Int32 id;
+    } gateMPGetFreeResource;
+    struct {
+       Int status;
+    } gateMPReleaseResource;
+    struct {
+       Int status;
+       Bool result;
+    } gateMPIsSetup;
+    struct {
+       Int status;
+       GateHWSpinlock_Config cfgParams;
+    } gateHWSpinlockGetConfig;
     NameServer_Params params;
     NameServer_Handle handle;
     Ptr entryPtr;
index 214c6264612627943c5e500607488ba11093372d..b768feb605d404b9498993601a6394ae8b09faf4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, Texas Instruments Incorporated
+ * Copyright (c) 2012-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 /* IPC startup/shutdown stuff: */
 #include <ti/ipc/MultiProc.h>
+#include <GateHWSpinlock.h>
+#include <_GateMP.h>
 #include <_MultiProc.h>
 #include <_MessageQ.h>
 #include <_NameServer.h>
 
+GateHWSpinlock_Config _GateHWSpinlock_cfgParams;
+
 static LAD_ClientHandle ladHandle;
 
 static void cleanup(int arg);
@@ -70,12 +74,13 @@ static void cleanup(int arg);
 /* Function to start Ipc */
 Int Ipc_start (Void)
 {
-    MessageQ_Config   msgqCfg;
-    MultiProc_Config  mpCfg;
-    Int32             status;
-    LAD_Status        ladStatus;
-    UInt16            rprocId;
-    Int32             attachedAny = 0;
+    MessageQ_Config        msgqCfg;
+    MultiProc_Config       mpCfg;
+    GateHWSpinlock_Config  gateHWCfg;
+    Int32                  status;
+    LAD_Status             ladStatus;
+    UInt16                 rprocId;
+    Int32                  attachedAny = 0;
 
     /* Catch ctrl-C, and cleanup: */
     (void) signal(SIGINT, cleanup);
@@ -129,6 +134,45 @@ Int Ipc_start (Void)
         status = Ipc_E_FAIL;
     }
 
+    /* Start GateMP only if device has support */
+#if defined(GATEMP_SUPPORT)
+    if (GateMP_isSetup()) {
+        /*
+         * Get HWSpinlock base address and size from LAD and
+         * initialize the local config structure.
+         */
+        GateHWSpinlock_getConfig(&gateHWCfg);
+        _GateHWSpinlock_cfgParams = gateHWCfg;
+
+        status = GateHWSpinlock_start();
+        if (status < 0) {
+            printf("Ipc_start: GateHWSpinlock_start failed: %d\n",
+                status);
+            status = Ipc_E_FAIL;
+            goto gatehwspinlockstart_fail;
+        }
+        else {
+            status = GateMP_start();
+            if (status < 0) {
+                printf("Ipc_start: GateMP_start failed: %d\n",
+                status);
+                status = Ipc_E_FAIL;
+                goto gatempstart_fail;
+            }
+        }
+    }
+#endif
+    /* Success */
+    goto exit;
+#if defined(GATEMP_SUPPORT)
+gatempstart_fail:
+    GateHWSpinlock_stop();
+gatehwspinlockstart_fail:
+    for (rprocId = rprocId - 1; (rprocId > 0) && (status >= 0); rprocId--) {
+        MessageQ_detach(rprocId);
+    }
+#endif
+
 exit:
     return (status);
 }
index 6f03c8ded5802056a0329cae4769225ae385727e..a0780343d98806a26132b2ff32ec11555a746552 100644 (file)
@@ -1,5 +1,5 @@
 ##
-##  Copyright (c) 2013, Texas Instruments Incorporated
+##  Copyright (c) 2013-2014, Texas Instruments Incorporated
 ##
 ##  Redistribution and use in source and binary forms, with or without
 ##  modification, are permitted provided that the following conditions
@@ -36,6 +36,10 @@ AM_CFLAGS = -I$(top_srcdir)/linux/include -I$(top_srcdir)/hlos_common/include \
         -I$(top_srcdir)/packages -I$(KERNEL_INSTALL_DIR)/include/generated/uapi\
         -D_GNU_SOURCE -Wall @AM_CFLAGS@
 
+if DRA7XX
+AM_CFLAGS += -DGATEMP_SUPPORT
+endif
+
 ###############################################################################
 # THE LIBRARIES TO BUILD
 ###############################################################################
@@ -69,6 +73,18 @@ libtiipc_la_SOURCES =    \
                         NameServer.c \
                         Ipc.c
 
+if DRA7XX
+libtiipc_la_SOURCES +=  $(top_srcdir)/linux/include/IGateProvider.h \
+                        $(top_srcdir)/linux/include/GateHWSpinlock.h \
+                        $(top_srcdir)/linux/include/GateMutex.h \
+                        $(top_srcdir)/linux/include/GateMP_config.h \
+                        $(top_srcdir)/linux/include/_GateMP.h \
+                        $(top_srcdir)/packages/ti/ipc/GateMP.h \
+                        $(top_srcdir)/linux/src/api/gates/GateMP.c \
+                        $(top_srcdir)/linux/src/api/gates/GateMutex.c \
+                        $(top_srcdir)/linux/src/api/gates/GateHWSpinlock.c
+endif
+
 # Add version info to the shared library
 libtiipc_la_LDFLAGS = -version-info 1:0:0
                                                
index 84047f01d2bb3e603de43b1cd92d59e4acd366c5..0c5f18f82b6e2d63cab2318c07aaa1dc4263c2f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Texas Instruments Incorporated
+ * Copyright (c) 2012-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -216,6 +216,109 @@ NameServer_Handle NameServer_create(String name,
     return rsp.handle;
 }
 
+Ptr NameServer_add(NameServer_Handle nsHandle, String name, Ptr buf,
+                   UInt32 len)
+{
+    Int status;
+    LAD_ClientHandle clHandle;
+    struct LAD_CommandObj cmd;
+    union LAD_ResponseObj rsp;
+
+    clHandle = LAD_findHandle();
+    if (clHandle == LAD_MAXNUMCLIENTS) {
+        PRINTVERBOSE1(
+          "NameServer_add: can't find connection to daemon for pid %d\n",
+          getpid())
+
+        return NULL;
+    }
+
+    cmd.cmd = LAD_NAMESERVER_ADD;
+    cmd.clientId = clHandle;
+    cmd.args.add.handle = nsHandle;
+    strncpy(cmd.args.add.name, name, LAD_MAXENTRYNAMELEN);
+    cmd.args.add.len = len;
+
+    if (buf != NULL) {
+        memcpy(cmd.args.add.buf, buf, len);
+    }
+
+    if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+        PRINTVERBOSE1(
+          "NameServer_add: sending LAD command failed, status=%d\n",
+          status)
+        return NULL;
+    }
+
+    if ((status = LAD_getResponse(clHandle, &rsp)) != LAD_SUCCESS) {
+        PRINTVERBOSE1(
+           "NameServer_add: no LAD response, status=%d\n", status)
+        return NULL;
+    }
+
+    PRINTVERBOSE1(
+       "NameServer_add: got LAD response for client %d\n", clHandle)
+
+    return rsp.entryPtr;
+}
+
+Int NameServer_get(NameServer_Handle nsHandle, String name, Ptr buf,
+                   UInt32 * len, UInt16 procId[])
+{
+    Int status;
+    LAD_ClientHandle clHandle;
+    struct LAD_CommandObj cmd;
+    union LAD_ResponseObj rsp;
+
+    clHandle = LAD_findHandle();
+    if (clHandle == LAD_MAXNUMCLIENTS) {
+        PRINTVERBOSE1(
+          "NameServer_get: can't find connection to daemon for pid %d\n",
+           getpid())
+
+        return NameServer_E_RESOURCE;
+    }
+
+    cmd.cmd = LAD_NAMESERVER_GET;
+    cmd.clientId = clHandle;
+    cmd.args.get.handle = nsHandle;
+    strncpy(cmd.args.get.name, name, LAD_MAXENTRYNAMELEN);
+    if (procId != NULL) {
+        memcpy(cmd.args.get.procId, procId,
+               sizeof(UInt16) * MultiProc_MAXPROCESSORS);
+    }
+    else {
+        cmd.args.get.procId[0] = (UInt16)-1;
+    }
+
+    cmd.args.get.len = *len;
+
+    if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+        PRINTVERBOSE1(
+           "NameServer_get: sending LAD command failed, status=%d\n",
+            status)
+        return NameServer_E_FAIL;
+    }
+
+    if ((status = LAD_getResponse(clHandle, &rsp)) != LAD_SUCCESS) {
+        PRINTVERBOSE1("NameServer_get: no LAD response, status=%d\n",
+                       status)
+        return NameServer_E_FAIL;
+    }
+
+    *len = rsp.get.len;
+    if (rsp.get.buf != NULL) {
+        memcpy(buf, rsp.get.buf, *len);
+    }
+
+    status = rsp.status;
+
+    PRINTVERBOSE1("NameServer_get: got LAD response for client %d\n",
+                   clHandle)
+
+    return status;
+}
+
 Ptr NameServer_addUInt32(NameServer_Handle nsHandle, String name, UInt32 value)
 {
     Int status;
@@ -235,7 +338,7 @@ Ptr NameServer_addUInt32(NameServer_Handle nsHandle, String name, UInt32 value)
     cmd.cmd = LAD_NAMESERVER_ADDUINT32;
     cmd.clientId = clHandle;
     cmd.args.addUInt32.handle = nsHandle;
-    strncpy(cmd.args.addUInt32.name, name, NameServer_Params_MAXNAMELEN);
+    strncpy(cmd.args.addUInt32.name, name, LAD_MAXENTRYNAMELEN);
     cmd.args.addUInt32.val = value;
 
     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
@@ -278,7 +381,7 @@ Int NameServer_getUInt32(NameServer_Handle nsHandle, String name, Ptr buf,
     cmd.cmd = LAD_NAMESERVER_GETUINT32;
     cmd.clientId = clHandle;
     cmd.args.getUInt32.handle = nsHandle;
-    strncpy(cmd.args.getUInt32.name, name, NameServer_Params_MAXNAMELEN);
+    strncpy(cmd.args.getUInt32.name, name, LAD_MAXENTRYNAMELEN);
     if (procId != NULL) {
         memcpy(cmd.args.getUInt32.procId, procId,
                sizeof(UInt16) * MultiProc_MAXPROCESSORS);
@@ -329,7 +432,7 @@ Int NameServer_remove(NameServer_Handle nsHandle, String name)
     cmd.cmd = LAD_NAMESERVER_REMOVE;
     cmd.clientId = clHandle;
     cmd.args.remove.handle = nsHandle;
-    strncpy(cmd.args.remove.name, name, NameServer_Params_MAXNAMELEN);
+    strncpy(cmd.args.remove.name, name, LAD_MAXENTRYNAMELEN);
 
     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
         PRINTVERBOSE1(
diff --git a/linux/src/api/gates/GateHWSpinlock.c b/linux/src/api/gates/GateHWSpinlock.c
new file mode 100644 (file)
index 0000000..65f3e62
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * 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.
+ */
+
+/*
+ *  ======== GateHWSpinlock.c ========
+ */
+
+/* Standard headers */
+#include <ti/ipc/Std.h>
+
+/* Utilities & OSAL headers */
+#include <ti/ipc/MultiProc.h>
+#include <ti/ipc/GateMP.h>
+
+#include <GateHWSpinlock.h>
+
+#include <IGateProvider.h>
+
+/*
+ * TODO: does this belong in ti/ipc/Std.h? We should consider getting rid of
+ *       error blocks from the GateMutex.h interface.
+ */
+typedef UInt32            Error_Block;
+#include <GateMutex.h>
+
+/* Socket Utils */
+#include <_lad.h>
+#include <ladclient.h>
+
+/* Linux headers */
+#include <assert.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+/* GateHWSpinlock Module Local State */
+typedef struct {
+    UInt32 *                        baseAddr;   /* base addr lock registers */
+    GateMutex_Handle                gmHandle;   /* handle to gate mutex */
+} GateHWSpinlock_Module_State;
+
+/* GateHWSpinlock instance object */
+struct GateHWSpinlock_Object {
+    IGateProvider_SuperObject; /* For inheritance from IGateProvider */
+    UInt                        lockNum;
+    UInt                        nested;
+    IGateProvider_Handle        localGate;
+    int                         token;  /* HWSpinlock token */
+};
+
+
+/* =============================================================================
+ * Globals
+ * =============================================================================
+ */
+GateHWSpinlock_Config _GateHWSpinlock_cfgParams;
+
+static GateHWSpinlock_Module_State GateHWSpinlock_state =
+{
+    .baseAddr = NULL,
+    .gmHandle = NULL
+};
+
+static GateHWSpinlock_Module_State *Mod = &GateHWSpinlock_state;
+
+static GateHWSpinlock_Params GateHWSpinlock_defInstParams =
+{
+    .resourceId = 0,
+    .openFlag   = FALSE,
+    .regionId   = 0,
+    .sharedAddr = NULL
+};
+
+static Bool verbose = FALSE;
+
+/* =============================================================================
+ * APIS
+ * =============================================================================
+ */
+/* Function to get configuration address & sizes for the GateHWSpinlock module.
+ *
+ */
+Void GateHWSpinlock_getConfig (GateHWSpinlock_Config * cfgParams)
+{
+    Int status;
+    LAD_ClientHandle handle;
+    struct LAD_CommandObj cmd;
+    union LAD_ResponseObj rsp;
+
+    assert (cfgParams != NULL);
+
+    handle = LAD_findHandle();
+    if (handle == LAD_MAXNUMCLIENTS) {
+        PRINTVERBOSE0(
+          "GateHWSpinlock_getConfig: can't find connection to daemon for pid")
+        PRINTVERBOSE1("%d\n", getpid())
+
+        return;
+    }
+
+    cmd.cmd = LAD_GATEHWSPINLOCK_GETCONFIG;
+    cmd.clientId = handle;
+
+    if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+        PRINTVERBOSE1(
+          "GateHWSpinlock_getConfig: sending LAD command failed, status=%d\n",
+          status)
+        return;
+    }
+
+    if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
+        PRINTVERBOSE1("GateHWSpinlock_getConfig: no LAD response, status=%d\n",
+        status)
+        return;
+    }
+    status = rsp.gateHWSpinlockGetConfig.status;
+
+    PRINTVERBOSE2(
+      "GateHWSpinlock_getConfig: got LAD response for client %d, status=%d\n",
+      handle, status)
+
+    memcpy(cfgParams, &rsp.gateHWSpinlockGetConfig.cfgParams,
+        sizeof(*cfgParams));
+
+    return;
+}
+
+
+/*
+ *  Function to start the GateHWSpinlock module.
+ */
+Int32 GateHWSpinlock_start(Void)
+{
+    Int32               status = GateHWSpinlock_S_SUCCESS;
+    UInt32              dst;
+    Int32               fdMem;
+
+    fdMem = open ("/dev/mem", O_RDWR | O_SYNC);
+
+    if (fdMem < 0){
+        PRINTVERBOSE0("GateHWSpinlock_start: failed to open the /dev/mem");
+        status = GateHWSpinlock_E_OSFAILURE;
+    }
+
+    /* map the hardware lock registers into the local address space */
+    if (status == GateHWSpinlock_S_SUCCESS) {
+        dst = (UInt32)mmap(NULL, _GateHWSpinlock_cfgParams.size,
+                            (PROT_READ | PROT_WRITE),
+                            (MAP_SHARED), fdMem,
+                            (off_t)_GateHWSpinlock_cfgParams.baseAddr);
+
+        if (dst == (UInt32)MAP_FAILED) {
+            PRINTVERBOSE0("GateHWSpinlock_start: Memory map failed")
+            status = GateHWSpinlock_E_OSFAILURE;
+        }
+        else {
+            Mod->baseAddr = (UInt32 *)(dst + _GateHWSpinlock_cfgParams.offset);
+            status = GateHWSpinlock_S_SUCCESS;
+        }
+    }
+
+    /* create GateMutex for local protection*/
+    if (status == GateHWSpinlock_S_SUCCESS) {
+        Mod->gmHandle = GateMutex_create(NULL, NULL);
+
+        if (Mod->gmHandle == NULL) {
+            PRINTVERBOSE0("GateHWSpinlock_start: GateMutex create failed")
+            status = GateHWSpinlock_E_FAIL;
+            GateHWSpinlock_stop();
+        }
+    }
+
+    return (status);
+}
+
+/*
+ *  Function to stop the GateHWSpinlock module.
+ */
+Int GateHWSpinlock_stop(Void)
+{
+    Int32               status = GateHWSpinlock_S_SUCCESS;
+
+    /* delete GateMutex */
+    if (Mod->gmHandle != NULL) {
+        status = GateMutex_delete(&Mod->gmHandle);
+    }
+
+    /* release lock register mapping */
+    if (Mod->baseAddr != NULL) {
+        munmap((void *)_GateHWSpinlock_cfgParams.baseAddr,
+           _GateHWSpinlock_cfgParams.size);
+    }
+
+    return(status);
+}
+
+/*
+ *  Initialize parameter structure
+ */
+Void GateHWSpinlock_Params_init(GateHWSpinlock_Params *params)
+{
+    assert(params != NULL);
+
+    memcpy(params, &GateHWSpinlock_defInstParams,
+        sizeof(GateHWSpinlock_Params));
+}
+
+/*
+ * Create a GateHWSpinlock instance
+ */
+/* TODO: change the function to accept a local gate. Do this on all platforms */
+GateHWSpinlock_Handle GateHWSpinlock_create(GateHWSpinlock_LocalProtect
+    localProtect, const GateHWSpinlock_Params * params)
+{
+    GateHWSpinlock_Object * obj = (GateHWSpinlock_Object *)calloc(1,
+        sizeof (GateHWSpinlock_Object));
+
+    if (!obj) {
+        PRINTVERBOSE0("GateHWSpinlock_create: memory allocation failure")
+        return NULL;
+    }
+
+    IGateProvider_ObjectInitializer(obj, GateHWSpinlock);
+    /* TODO: handle more local protection types */
+    obj->localGate = (IGateProvider_Handle)Mod->gmHandle;
+    obj->lockNum = params->resourceId;
+    obj->nested = 0;
+
+    return (GateHWSpinlock_Handle)obj;
+}
+
+/*
+ * Delete a GateHWSpinlock instance
+ */
+Int GateHWSpinlock_delete (GateHWSpinlock_Handle * handle)
+{
+    GateHWSpinlock_Object * obj;
+    Int  status = GateHWSpinlock_S_SUCCESS;
+
+    if (handle == NULL) {
+        return GateHWSpinlock_E_INVALIDARG;
+    }
+    if (*handle == NULL) {
+        return GateHWSpinlock_E_INVALIDARG;
+    }
+
+    obj = (GateHWSpinlock_Object *)(*handle);
+
+    free(obj);
+    *handle = NULL;
+
+    return (status);
+}
+
+/*
+ *  Enter a GateHWSpinlock instance
+ */
+IArg GateHWSpinlock_enter(GateHWSpinlock_Object *obj)
+{
+    volatile UInt32 *baseAddr = Mod->baseAddr;
+    IArg key;
+
+    key = IGateProvider_enter(obj->localGate);
+
+    /* if gate already entered, just return with current key */
+    obj->nested++;
+    if (obj->nested > 1) {
+        return(key);
+    }
+
+    /* enter the spinlock */
+    while (1) {
+        /* read the spinlock, returns non-zero when we get it */
+        if (baseAddr[obj->lockNum] == 0) {
+            break;
+        }
+        obj->nested--;
+        IGateProvider_leave(obj->localGate, key);
+        key = IGateProvider_enter(obj->localGate);
+        obj->nested++; /* re-nest the gate */
+    }
+
+    return (key);
+}
+
+/*
+ *  Leave a GateHWSpinlock instance
+ */
+Int GateHWSpinlock_leave(GateHWSpinlock_Object *obj, IArg key)
+{
+    volatile UInt32 *baseAddr = Mod->baseAddr;
+
+    obj->nested--;
+
+    /* release the spinlock if not nested */
+    if (obj->nested == 0) {
+        baseAddr[obj->lockNum] = 0;
+    }
+
+    IGateProvider_leave(obj->localGate, key);
+
+    return GateHWSpinlock_S_SUCCESS;
+}
diff --git a/linux/src/api/gates/GateMP.c b/linux/src/api/gates/GateMP.c
new file mode 100644 (file)
index 0000000..15d2fd1
--- /dev/null
@@ -0,0 +1,848 @@
+/*
+ * 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.
+ */
+/*
+ *  ======== GateMP.c ========
+ */
+#include <ti/ipc/Std.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <pthread.h>
+#include <assert.h>
+
+#include <ti/ipc/GateMP.h>
+#include <ti/ipc/NameServer.h>
+#include <ti/ipc/MultiProc.h>
+
+#include <GateMP_config.h>
+
+#include <_GateMP.h>
+
+/* Socket Protocol Family */
+#include <net/rpmsg.h>
+
+/* Socket utils: */
+#include <SocketFxns.h>
+
+#include <ladclient.h>
+#include <_lad.h>
+
+
+/* structure for GateMP module state */
+typedef struct {
+    GateMP_Params       defaultInstParams;
+    /* Default instance creation parameters */
+    GateMP_Handle       defaultGate;
+    /* Handle to default gate */
+    NameServer_Handle   nameServer;
+    /* NameServer for GateMP instances */
+    Bool                isStarted;
+    /* Has GateMP been started */
+    pthread_mutex_t     mutex;
+    /* Mutex for use on local process to serialize access to gate obj */
+    GateMP_Object **    remoteSystemGates;
+    /* Remote system gates */
+    Int                 numRemoteSystem;
+    /* Number of remote system gates */
+} GateMP_ModuleObject;
+
+
+static Bool verbose = FALSE;
+
+/* Internal structure defining parameters for GateMP_Instance_init */
+typedef struct {
+    String name;                        /* Name of instance */
+    UInt16 regionId;                    /* not used on host*/
+    Ptr sharedAddr;                     /* not used on host*/
+    GateMP_LocalProtect localProtect;   /* Local protection level  */
+    GateMP_RemoteProtect remoteProtect; /* Remote protection level */
+    UInt32 resourceId;                  /* resource id */
+    Bool openFlag;                      /* Is this open or create? */
+} _GateMP_Params;
+
+static Int GateMP_getNumResources(GateMP_RemoteProtect type);
+static Int GateMP_getFreeResource(GateMP_RemoteProtect type);
+static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type);
+static GateMP_Handle _GateMP_create (const _GateMP_Params * params);
+static Int GateMP_Instance_init(GateMP_Object *obj,
+    const _GateMP_Params *params);
+static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status);
+
+/* -----------------------------------------------------------------------------
+ * Globals
+ * -----------------------------------------------------------------------------
+ */
+static GateMP_ModuleObject GateMP_state =
+{
+    .remoteSystemGates  = NULL,
+    .defaultGate        = NULL,
+    .nameServer         = NULL,
+    .mutex              = PTHREAD_MUTEX_INITIALIZER,
+//    .gateMutex          = NULL,
+//    .gateProcess        = NULL
+};
+
+static GateMP_ModuleObject *GateMP_module = &GateMP_state;
+
+static GateMP_Params GateMP_defInstParams =
+{
+    .name           = NULL,
+    .regionId       = 0,
+    .sharedAddr     = NULL,
+    .localProtect   = GateMP_LocalProtect_PROCESS,
+    .remoteProtect  = GateMP_RemoteProtect_SYSTEM
+};
+
+Int GateMP_start(Void)
+{
+    Int status;
+    LAD_ClientHandle handle;
+    struct LAD_CommandObj cmd;
+    union LAD_ResponseObj rsp;
+
+    handle = LAD_findHandle();
+    if (handle == LAD_MAXNUMCLIENTS) {
+        PRINTVERBOSE1(
+          "GateMP_start: can't find connection to daemon for pid %d\n",
+           getpid())
+
+        return -1;
+    }
+
+    cmd.cmd = LAD_GATEMP_START;
+    cmd.clientId = handle;
+
+    if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+        PRINTVERBOSE1(
+          "GateMP_start: sending LAD command failed, status=%d\n", status)
+        return -1;
+    }
+
+    if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
+        PRINTVERBOSE1("GateMP_start: no LAD response, status=%d\n", status)
+        return -1;
+    }
+
+    status = rsp.gateMPStart.status;
+
+    PRINTVERBOSE2(
+      "GateMP_start: got LAD response for client %d, status=%d\n",
+      handle, status)
+
+    /*
+     * Initialize module state. Note that Nameserver handles are compatible
+     * across processes.
+     */
+    GateMP_module->nameServer = rsp.gateMPStart.nameServerHandle;
+
+
+    /* allocate memory for remote system gate handles */
+    if (status == GateMP_S_SUCCESS) {
+        GateMP_module->numRemoteSystem =
+            GateMP_getNumResources(GateMP_RemoteProtect_SYSTEM);
+        if (GateMP_module->numRemoteSystem > 0) {
+            GateMP_module->remoteSystemGates = calloc(1,
+                GateMP_module->numRemoteSystem *
+                sizeof(IGateProvider_Handle));
+
+            if (GateMP_module->remoteSystemGates == NULL) {
+                status = GateMP_E_MEMORY;
+                PRINTVERBOSE0("GateMP_start: memory allocation failed")
+            }
+        }
+        else {
+            GateMP_module->remoteSystemGates = NULL;
+        }
+    }
+
+    if (status == GateMP_S_SUCCESS) {
+        /* Open default gate */
+        status = GateMP_open("_GateMP_TI_dGate", &GateMP_module->defaultGate);
+        if (status < 0) {
+            PRINTVERBOSE1("GateMP_start: could not open default gate, \
+                status=%d\n", status)
+        }
+    }
+
+    /* in failure case, release acquired resources in reverse order */
+    if (status < 0) {
+        GateMP_stop();
+    }
+
+    GateMP_module->isStarted = TRUE;
+
+    return status;
+}
+
+Int GateMP_stop(Void)
+{
+    Int status = GateMP_S_SUCCESS;
+
+    PRINTVERBOSE0("GateMP_stop: entered\n")
+
+    /* close the default gate */
+    if (GateMP_module->defaultGate) {
+        GateMP_close(&GateMP_module->defaultGate);
+        GateMP_module->defaultGate = NULL;
+    }
+
+    /* free system gate array */
+    if (GateMP_module->remoteSystemGates != NULL) {
+        free(GateMP_module->remoteSystemGates);
+        GateMP_module->remoteSystemGates = NULL;
+    }
+
+    GateMP_module->isStarted = FALSE;
+
+    return status;
+}
+
+Void GateMP_Params_init(GateMP_Params *params)
+{
+    if (params != NULL) {
+        memcpy(params, &GateMP_defInstParams, sizeof(GateMP_Params));
+    }
+    else {
+        PRINTVERBOSE0("GateMP_Params_init: Params argument cannot be NULL")
+    }
+
+    return;
+}
+
+GateMP_Handle GateMP_create(const GateMP_Params *params)
+{
+    _GateMP_Params      _params;
+    GateMP_Handle       handle = NULL;
+
+    if (GateMP_module->isStarted == FALSE) {
+        PRINTVERBOSE0("GateMP_create: GateMP module has not been started!")
+    }
+    else {
+        memset(&_params, 0, sizeof(_GateMP_Params));
+        memcpy(&_params, params, sizeof(GateMP_Params));
+
+        handle = _GateMP_create(&_params);
+    }
+
+    return(handle);
+}
+
+static GateMP_Handle _GateMP_create(const _GateMP_Params *params)
+{
+    GateMP_Handle       handle = NULL;
+    GateMP_Object *     obj = NULL;
+    Int                 status;
+
+    /* allocate the instance object */
+    obj = (GateMP_Object *)calloc(1, sizeof(GateMP_Object));
+
+    if (obj != NULL) {
+        status = GateMP_Instance_init(obj, params);
+        if (status < 0) {
+            free(obj);
+        }
+        else {
+            handle = (GateMP_Handle)obj;
+        }
+    }
+    else {
+        PRINTVERBOSE0("GateMP_create: Memory allocation failed")
+    }
+
+    return(handle);
+}
+
+Int GateMP_open(String name, GateMP_Handle *handle)
+{
+    Int             status = GateMP_S_SUCCESS;
+    UInt32          len;
+    UInt32          nsValue[4];
+    GateMP_Object * obj = NULL;
+    UInt32          arg;
+    UInt32          mask;
+    UInt32          creatorProcId;
+    _GateMP_Params  params;
+
+    /* assert that a valid pointer has been supplied */
+    if (handle == NULL) {
+        PRINTVERBOSE0("GateMP_open: handle cannot be null")
+        status = GateMP_E_INVALIDARG;
+    }
+
+    if (status == GateMP_S_SUCCESS) {
+        len = sizeof(nsValue);
+
+        status = NameServer_get(GateMP_module->nameServer, name, &nsValue,
+            &len, NULL);
+
+        if (status < 0) {
+            *handle = NULL;
+            status = GateMP_E_NOTFOUND;
+        }
+        else {
+            arg = nsValue[2];
+            mask = nsValue[3];
+            creatorProcId = nsValue[1] >> 16;
+        }
+    }
+
+    if (status == GateMP_S_SUCCESS) {
+        /*
+         * The least significant bit of nsValue[1] == 0 means its a
+         * local (private) GateMP, otherwise its a remote (shared) GateMP.
+         */
+        if ((nsValue[1] & 0x1) == 0) {
+            if ((nsValue[1] >> 16) != MultiProc_self()) {
+                /* error: trying to open another processor's private gate */
+                *handle = NULL;
+                PRINTVERBOSE0("GateMP_open: cannot open private gate from \
+                    another processor")
+                status = GateMP_E_FAIL;
+            }
+            else if (nsValue[0] != getpid()) {
+                /* error: trying to open another process's private gate */
+                *handle = NULL;
+                PRINTVERBOSE0("GateMP_open: cannot open private gate from \
+                    another process")
+                status = GateMP_E_FAIL;
+            }
+        }
+    }
+
+    if (status == GateMP_S_SUCCESS) {
+        /* local gate */
+        if (GETREMOTE(mask) == GateMP_RemoteProtect_NONE) {
+            if (creatorProcId != MultiProc_self()) {
+                status = GateMP_E_FAIL;
+            }
+            else {
+                *handle = (GateMP_Handle)arg;
+                obj = (GateMP_Object *)(*handle);
+                pthread_mutex_lock(&GateMP_module->mutex);
+                obj->numOpens++;
+                pthread_mutex_unlock(&GateMP_module->mutex);
+            }
+        }
+        else {
+            /* remote case */
+            switch (GETREMOTE(mask)) {
+                case GateMP_RemoteProtect_SYSTEM:
+                case GateMP_RemoteProtect_CUSTOM1:
+                case GateMP_RemoteProtect_CUSTOM2:
+                    obj = GateMP_module->remoteSystemGates[arg];
+                    break;
+
+                default:
+                    status = GateMP_E_FAIL;
+                    PRINTVERBOSE0("GateMP_open: unsupported remote protection \
+                        type")
+                    break;
+            }
+
+            /*  If the object is NULL, then it must have been created
+             *  on a remote processor or in another process on the
+             *  local processor. Need to create a local object. This is
+             *  accomplished by setting the openFlag to TRUE.
+             */
+            if (status == GateMP_S_SUCCESS) {
+                if (obj == NULL) {
+                    /* create a GateMP object with the openFlag set to true */
+                    params.name = NULL;
+                    params.openFlag = TRUE;
+                    params.sharedAddr = NULL;
+                    params.resourceId = arg;
+                    params.localProtect = GETLOCAL(mask);
+                    params.remoteProtect = GETREMOTE(mask);
+
+                    obj = (GateMP_Object *)_GateMP_create(&params);
+
+                    if (obj == NULL) {
+                        status = GateMP_E_FAIL;
+                    }
+                }
+                else {
+                    pthread_mutex_lock(&GateMP_module->mutex);
+                    obj->numOpens++;
+                    pthread_mutex_unlock(&GateMP_module->mutex);
+                }
+            }
+
+            /* Return the "opened" GateMP instance  */
+            *handle = (GateMP_Handle)obj;
+        }
+    }
+
+    return status;
+}
+
+GateMP_Handle GateMP_getDefaultRemote()
+{
+    return(GateMP_module->defaultGate);
+}
+
+GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
+{
+    GateMP_Object *obj;
+
+    obj = (GateMP_Object *)handle;
+    return(obj->localProtect);
+}
+
+GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
+{
+    GateMP_Object *obj;
+
+    obj = (GateMP_Object *)handle;
+    return (obj->remoteProtect);
+}
+
+static Int GateMP_getNumResources(GateMP_RemoteProtect type)
+{
+    Int status;
+    LAD_ClientHandle handle;
+    struct LAD_CommandObj cmd;
+    union LAD_ResponseObj rsp;
+
+    handle = LAD_findHandle();
+    if (handle == LAD_MAXNUMCLIENTS) {
+        PRINTVERBOSE1(
+          "GateMP_getNumResources: can't find connection to daemon for pid %d\n",
+           getpid())
+
+        return -1;
+    }
+
+    cmd.cmd = LAD_GATEMP_GETNUMRESOURCES;
+    cmd.clientId = handle;
+    cmd.args.gateMPGetNumResources.type = type;
+
+
+    if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+        PRINTVERBOSE1(
+          "GateMP_getNumResources: sending LAD command failed, status=%d\n", status)
+        return -1;
+    }
+
+    if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
+        PRINTVERBOSE1("GateMP_getNumResources: no LAD response, status=%d\n", status)
+        return -1;
+    }
+
+    status = rsp.gateMPGetNumResources.status;
+
+    PRINTVERBOSE2(
+      "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
+      handle, status)
+
+
+    return (rsp.gateMPGetNumResources.value);
+}
+
+static Int GateMP_getFreeResource(GateMP_RemoteProtect type)
+{
+    Int status;
+    LAD_ClientHandle handle;
+    struct LAD_CommandObj cmd;
+    union LAD_ResponseObj rsp;
+
+    handle = LAD_findHandle();
+    if (handle == LAD_MAXNUMCLIENTS) {
+        PRINTVERBOSE1(
+          "GateMP_getFreeResource: can't find connection to daemon for pid %d\n",
+           getpid())
+
+        return -1;
+    }
+
+    cmd.cmd = LAD_GATEMP_GETFREERESOURCE;
+    cmd.clientId = handle;
+    cmd.args.gateMPGetFreeResource.type = type;
+
+    if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+        PRINTVERBOSE1(
+          "GateMP_getFreeResource: sending LAD command failed, status=%d\n", status)
+        return -1;
+    }
+
+    if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
+        PRINTVERBOSE1("GateMP_getFreeResource: no LAD response, status=%d\n", status)
+        return -1;
+    }
+
+    status = rsp.gateMPGetFreeResource.status;
+
+    PRINTVERBOSE2(
+      "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
+      handle, status)
+
+    return (rsp.gateMPGetFreeResource.id);
+}
+
+static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
+{
+    Int status;
+    LAD_ClientHandle handle;
+    struct LAD_CommandObj cmd;
+    union LAD_ResponseObj rsp;
+
+    handle = LAD_findHandle();
+    if (handle == LAD_MAXNUMCLIENTS) {
+        PRINTVERBOSE1(
+          "GateMP_releaseResource: can't find connection to daemon for pid %d\n",
+           getpid())
+
+        return -1;
+    }
+
+    cmd.cmd = LAD_GATEMP_RELEASERESOURCE;
+    cmd.clientId = handle;
+    cmd.args.gateMPReleaseResource.type = type;
+    cmd.args.gateMPReleaseResource.id   = id;
+
+    if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+        PRINTVERBOSE1(
+          "GateMP_releaseResource: sending LAD command failed, status=%d\n", status)
+        return -1;
+    }
+
+    if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
+        PRINTVERBOSE1("GateMP_releaseResource: no LAD response, status=%d\n", status)
+        return -1;
+    }
+
+    status = rsp.gateMPReleaseResource.status;
+
+    PRINTVERBOSE2(
+      "GateMP_releaseResource: got LAD response for client %d, status=%d\n",
+      handle, status)
+
+    return (status);
+}
+
+Bool GateMP_isSetup(Void)
+{
+    Int status;
+    LAD_ClientHandle handle;
+    struct LAD_CommandObj cmd;
+    union LAD_ResponseObj rsp;
+
+    handle = LAD_findHandle();
+    if (handle == LAD_MAXNUMCLIENTS) {
+        PRINTVERBOSE1(
+          "GateMP_isSetup: can't find connection to daemon for pid %d\n",
+           getpid())
+
+        return -1;
+    }
+
+    cmd.cmd = LAD_GATEMP_ISSETUP;
+    cmd.clientId = handle;
+    cmd.args.gateMPIsSetup.result = FALSE;
+
+    if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+        PRINTVERBOSE1(
+          "GateMP_isSetup: sending LAD command failed, status=%d\n", status)
+        return -1 ;
+    }
+
+    if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
+        PRINTVERBOSE1("GateMP_isSetup: no LAD response, status=%d\n", status)
+        return -1;
+    }
+
+    status = rsp.gateMPIsSetup.status;
+
+    PRINTVERBOSE2(
+      "GateMP_isSetup: got LAD response for client %d, status=%d\n",
+      handle, status)
+
+    assert(status == GateMP_S_SUCCESS);
+
+    return (rsp.gateMPIsSetup.result);
+}
+
+Int GateMP_close(GateMP_Handle *handle)
+{
+    GateMP_Object * obj;
+    Int             status = GateMP_S_SUCCESS;
+
+    obj = (GateMP_Object *)(*handle);
+
+    pthread_mutex_lock(&GateMP_module->mutex);
+
+    /*  Cannot call with the numOpens equal to zero.  This is either
+     *  a created handle or been closed already.
+     */
+    if (obj->numOpens == 0) {
+        status = GateMP_E_INVALIDSTATE;
+    }
+
+    if (status == GateMP_S_SUCCESS) {
+        obj->numOpens--;
+
+        /*  If the count is zero and the gate is opened, then this
+         *  object was created in the open (i.e. the create happened
+         *  on a remote processor or another process).
+         */
+        if ((obj->numOpens == 0) && (obj->objType == Ipc_ObjType_OPENDYNAMIC)) {
+            GateMP_delete(handle);
+        }
+        else {
+            *handle = NULL;
+        }
+    }
+
+    pthread_mutex_unlock(&GateMP_module->mutex);
+
+    return(status);
+}
+
+Int GateMP_delete(GateMP_Handle *handlePtr)
+{
+    Int               status = GateMP_S_SUCCESS;
+
+    if ((handlePtr == NULL) || (*handlePtr == NULL)) {
+        status =  GateMP_E_INVALIDARG;
+    }
+    else {
+        GateMP_Instance_finalize((GateMP_Object *)(*handlePtr), 0);
+        free(*handlePtr);
+        *handlePtr = NULL;
+    }
+
+    return status;
+}
+
+static Int GateMP_Instance_init(GateMP_Object *obj,
+    const _GateMP_Params *params)
+{
+    GateMP_RemoteSystemProxy_Params     systemParams;
+    UInt32                              nsValue[4];
+
+    obj->resourceId = (UInt)-1;
+
+    /* TODO: create/open the local gate instance */
+    obj->localGate = NULL;
+
+    /* open GateMP instance */
+    if (params->openFlag == TRUE) {
+        /* all open work done here except for remote gateHandle */
+        obj->localProtect  = params->localProtect;
+        obj->remoteProtect = params->remoteProtect;
+        obj->nsKey         = 0;
+        obj->numOpens      = 1;
+
+        obj->objType       = Ipc_ObjType_OPENDYNAMIC;
+    }
+
+    /* create GateMP instance */
+    else {
+        obj->localProtect  = params->localProtect;
+        obj->remoteProtect = params->remoteProtect;
+        obj->nsKey         = 0;
+        obj->numOpens      = 0;
+
+        if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
+            /* TODO: create a local gate */
+            obj->gateHandle = obj->localGate;
+
+            /* create a local gate allocating from the local heap */
+            obj->objType = Ipc_ObjType_LOCAL;
+            obj->arg = (Bits32)obj;
+            obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
+            obj->creatorProcId = MultiProc_self();
+
+            if (params->name != NULL) {
+                /*  nsv[0]       : creator process id
+                 *  nsv[1](31:16): creator procId
+                 *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
+                 *  nsv[2]       : local gate object
+                 *  nsv[3]       : protection mask
+                 */
+                nsValue[0] = getpid();
+                nsValue[1] = MultiProc_self() << 16;
+                nsValue[2] = obj->arg;
+                nsValue[3] = obj->mask;
+                obj->nsKey = NameServer_add(GateMP_module->nameServer,
+                        params->name, &nsValue, sizeof(nsValue));
+                if (obj->nsKey == NULL) {
+                    PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
+                    return (GateMP_E_FAIL);
+                }
+            }
+
+            /* nothing else to do for local gates */
+            return(0);
+        }
+
+        obj->objType = Ipc_ObjType_CREATEDYNAMIC;
+    }
+
+    /* proxy work for open and create done here */
+    switch (obj->remoteProtect) {
+        /* TODO: implement other types of remote protection */
+        case GateMP_RemoteProtect_SYSTEM:
+        case GateMP_RemoteProtect_CUSTOM1:
+        case GateMP_RemoteProtect_CUSTOM2:
+            if (obj->objType == Ipc_ObjType_OPENDYNAMIC) {
+                /* resourceId set by open call */
+                obj->resourceId = params->resourceId;
+            }
+            else {
+                /* created instance */
+                obj->resourceId = GateMP_getFreeResource(obj->remoteProtect);
+                if (obj->resourceId == -1) {
+                    return (GateMP_E_RESOURCE);
+                }
+            }
+
+            /* create the proxy object */
+            GateMP_RemoteSystemProxy_Params_init(&systemParams);
+            systemParams.resourceId = obj->resourceId;
+            systemParams.openFlag = (obj->objType == Ipc_ObjType_OPENDYNAMIC);
+            //systemParams.sharedAddr = obj->proxyAttrs;
+
+            /*
+             * TODO: Currently passing in localProtect instead of localGate,
+             * since existing GateHWSpinlock.h defines it this way
+             */
+            obj->gateHandle = (IGateProvider_Handle)
+                GateMP_RemoteSystemProxy_create(obj->localProtect,
+                    &systemParams);
+
+            if (obj->gateHandle == NULL) {
+                PRINTVERBOSE0("GateMP_Instance_init: failed to create proxy\n");
+                return(GateMP_E_FAIL);
+            }
+
+            /* store the object handle in the gate array */
+            GateMP_module->remoteSystemGates[obj->resourceId] = obj;
+            break;
+
+        default:
+            break;
+    }
+
+    /* add name/attrs to NameServer table */
+    if (obj->objType != Ipc_ObjType_OPENDYNAMIC) {
+        obj->arg = obj->resourceId;
+        obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
+
+        if (params->name != NULL) {
+            /*  nsv[0]       : creator pid
+             *  nsv[1](31:16): creator procId
+             *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
+             *  nsv[2]       : resource id
+             *  nsv[3]       : protection mask
+             */
+            nsValue[0] = getpid();
+            nsValue[1] = MultiProc_self() << 16 | 1;
+            nsValue[2] = obj->resourceId;
+            nsValue[3] = obj->mask;
+            obj->nsKey = NameServer_add(GateMP_module->nameServer,
+                    params->name, &nsValue, sizeof(nsValue));
+
+            if (obj->nsKey == NULL) {
+                PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
+                return (GateMP_E_FAIL);
+            }
+        }
+    }
+
+    return (GateMP_S_SUCCESS);
+}
+
+static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status)
+{
+    GateMP_Object ** remoteGates = NULL;
+
+    /* remove from NameServer */
+    if (obj->nsKey != 0) {
+        NameServer_removeEntry(GateMP_module->nameServer, obj->nsKey);
+        obj->nsKey = 0;
+    }
+
+    /* delete the remote gate */
+    switch (obj->remoteProtect) {
+
+        case GateMP_RemoteProtect_SYSTEM:
+        case GateMP_RemoteProtect_CUSTOM1:
+        case GateMP_RemoteProtect_CUSTOM2:
+            if (obj->gateHandle != NULL) {
+                GateMP_RemoteSystemProxy_delete(
+                        (GateMP_RemoteSystemProxy_Handle *)&obj->gateHandle);
+            }
+            remoteGates = GateMP_module->remoteSystemGates;
+            break;
+
+        case GateMP_RemoteProtect_NONE:
+            /*  nothing else to finalize */
+            return;
+
+        default:
+            /* Nothing to do */
+            break;
+    }
+
+    /* TODO: close/delete local gate */
+
+    /* clear the handle array entry in local memory */
+    if (obj->resourceId != (UInt)-1) {
+        remoteGates[obj->resourceId] = NULL;
+    }
+
+    if ((obj->objType != Ipc_ObjType_OPENDYNAMIC)
+        && (obj->resourceId != (UInt)-1)) {
+        GateMP_releaseResource(obj->resourceId, obj->remoteProtect);
+    }
+
+}
+
+IArg GateMP_enter(GateMP_Handle handle)
+{
+    GateMP_Object * obj;
+    IArg            key;
+
+    obj = (GateMP_Object *)handle;
+    key = IGateProvider_enter(obj->gateHandle);
+
+    return(key);
+}
+
+Void GateMP_leave(GateMP_Handle handle, IArg key)
+{
+    GateMP_Object *obj;
+
+    obj = (GateMP_Object *)handle;
+    IGateProvider_leave(obj->gateHandle, key);
+}
diff --git a/linux/src/api/gates/GateMutex.c b/linux/src/api/gates/GateMutex.c
new file mode 100644 (file)
index 0000000..11d6284
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * 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.c ========
+ */
+
+
+/* Standard headers */
+#include <ti/ipc/Std.h>
+
+/* Linux headers */
+#include <stdlib.h>
+#include <pthread.h>
+#include <string.h>
+#include <assert.h>
+
+#include <IGateProvider.h>
+
+/*
+ * TODO: does this belong in ti/ipc/Std.h? We should consider getting rid of
+ *       error blocks from the GateMutex.h interface.
+ */
+typedef UInt32            Error_Block;
+#include <GateMutex.h>
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ *  Structs & Enums
+ * -----------------------------------------------------------------------------
+ */
+struct GateMutex_Object {
+    IGateProvider_SuperObject;   /* For inheritance from IGateProvider */
+    pthread_mutex_t mutex;       /* Mutex lock */
+};
+
+
+/* -----------------------------------------------------------------------------
+ *  Forward declarations
+ * -----------------------------------------------------------------------------
+ */
+IArg GateMutex_enter(GateMutex_Handle gmhandle);
+Void GateMutex_leave(GateMutex_Handle gmhandle, IArg key);
+
+
+/* -----------------------------------------------------------------------------
+ *  APIs
+ * -----------------------------------------------------------------------------
+ */
+GateMutex_Handle GateMutex_create(const GateMutex_Params * params,
+    Error_Block *eb)
+{
+    pthread_mutexattr_t attr;
+
+    GateMutex_Object * obj = (GateMutex_Object *)calloc(1,
+        sizeof(GateMutex_Object));
+    if (obj == NULL) {
+        return NULL;
+    }
+
+    memset(obj, 0, sizeof(GateMutex_Object));
+    IGateProvider_ObjectInitializer(obj, GateMutex);
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+    pthread_mutex_init(&(obj->mutex), &attr);
+
+    return (GateMutex_Handle)obj;
+}
+
+Int GateMutex_delete(GateMutex_Handle * handle)
+{
+    if (handle == NULL) {
+        return GateMutex_E_INVALIDARG;
+    }
+    if (*handle == NULL) {
+        return GateMutex_E_INVALIDARG;
+    }
+    free(*handle);
+    *handle = NULL;
+
+    return GateMutex_S_SUCCESS;
+}
+
+IArg GateMutex_enter (GateMutex_Handle gmHandle)
+{
+    GateMutex_Object * obj = (GateMutex_Object *)gmHandle;
+    int ret;
+
+    ret = pthread_mutex_lock(&(obj->mutex));
+    assert(ret == 0);
+
+    return (IArg)ret;
+}
+
+Void GateMutex_leave (GateMutex_Handle gmHandle, IArg key)
+{
+    GateMutex_Object * obj = (GateMutex_Object *)gmHandle;
+    int ret;
+
+    ret = pthread_mutex_unlock(&(obj->mutex));
+    assert(ret == 0);
+}
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
diff --git a/linux/src/daemon/GateHWSpinlock.c b/linux/src/daemon/GateHWSpinlock.c
new file mode 100644 (file)
index 0000000..115f78b
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * 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.
+ */
+
+/*
+ *  ======== GateHWSpinlock.c ========
+ */
+
+/* Standard headers */
+#include <ti/ipc/Std.h>
+
+/* Utilities & OSAL headers */
+#include <ti/ipc/MultiProc.h>
+#include <ti/ipc/GateMP.h>
+
+#include <GateHWSpinlock.h>
+
+#include <IGateProvider.h>
+
+/*
+ * TODO: does this belong in ti/ipc/Std.h? We should consider getting rid of
+ *       error blocks from the GateMutex.h interface.
+ */
+typedef UInt32            Error_Block;
+#include <GateMutex.h>
+
+/* Module level headers */
+#include <_lad.h>
+
+/* Linux headers */
+#include <assert.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+/* GateHWSpinlock Module Local State */
+typedef struct {
+    UInt32 *                        baseAddr;   /* base addr lock registers */
+    GateMutex_Handle                gmHandle;   /* handle to gate mutex */
+} GateHWSpinlock_Module_State;
+
+/* GateHWSpinlock instance object */
+struct GateHWSpinlock_Object {
+    IGateProvider_SuperObject; /* For inheritance from IGateProvider */
+    UInt                        lockNum;
+    UInt                        nested;
+    IGateProvider_Handle        localGate;
+    int                         token;  /* HWSpinlock token */
+};
+
+
+/* =============================================================================
+ * Globals
+ * =============================================================================
+ */
+GateHWSpinlock_Config _GateHWSpinlock_cfgParams;
+
+static GateHWSpinlock_Module_State GateHWSpinlock_state =
+{
+    .baseAddr = NULL,
+    .gmHandle = NULL
+};
+
+static GateHWSpinlock_Module_State *Mod = &GateHWSpinlock_state;
+
+static GateHWSpinlock_Params GateHWSpinlock_defInstParams =
+{
+    .resourceId = 0,
+    .openFlag   = FALSE,
+    .regionId   = 0,
+    .sharedAddr = NULL
+};
+
+/* =============================================================================
+ * APIS
+ * =============================================================================
+ */
+/*
+ *  Function to start the GateHWSpinlock module.
+ */
+Int32 GateHWSpinlock_start(Void)
+{
+    Int32               status = GateHWSpinlock_S_SUCCESS;
+    UInt32              dst;
+    Int32               fdMem;
+
+    fdMem = open ("/dev/mem", O_RDWR | O_SYNC);
+
+    if (fdMem < 0){
+        LOG0("GateHWSpinlock_start: failed to open the /dev/mem");
+        status = GateHWSpinlock_E_OSFAILURE;
+    }
+
+    /* map the hardware lock registers into the local address space */
+    if (status == GateHWSpinlock_S_SUCCESS) {
+        dst = (UInt32)mmap(NULL, _GateHWSpinlock_cfgParams.size,
+                            (PROT_READ | PROT_WRITE),
+                            (MAP_SHARED), fdMem,
+                            (off_t)_GateHWSpinlock_cfgParams.baseAddr);
+
+        if (dst == (UInt32)MAP_FAILED) {
+            LOG0("GateHWSpinlock_start: Memory map failed")
+            status = GateHWSpinlock_E_OSFAILURE;
+        }
+        else {
+            Mod->baseAddr = (UInt32 *)(dst + _GateHWSpinlock_cfgParams.offset);
+            status = GateHWSpinlock_S_SUCCESS;
+        }
+    }
+
+    /* create GateMutex for local protection*/
+    if (status == GateHWSpinlock_S_SUCCESS) {
+        Mod->gmHandle = GateMutex_create(NULL, NULL);
+
+        if (Mod->gmHandle == NULL) {
+            LOG0("GateHWSpinlock_start: GateMutex create failed")
+            status = GateHWSpinlock_E_FAIL;
+            GateHWSpinlock_stop();
+        }
+    }
+
+    return (status);
+}
+
+/*
+ *  Function to stop the GateHWSpinlock module.
+ */
+Int GateHWSpinlock_stop(Void)
+{
+    Int32               status = GateHWSpinlock_S_SUCCESS;
+
+    /* delete GateMutex */
+    if (Mod->gmHandle != NULL) {
+        status = GateMutex_delete(&Mod->gmHandle);
+    }
+
+    /* release lock register mapping */
+    if (Mod->baseAddr != NULL) {
+        munmap((void *)_GateHWSpinlock_cfgParams.baseAddr,
+           _GateHWSpinlock_cfgParams.size);
+    }
+
+    return(status);
+}
+
+/*
+ *  Initialize parameter structure
+ */
+Void GateHWSpinlock_Params_init(GateHWSpinlock_Params *params)
+{
+    assert(params != NULL);
+
+    memcpy(params, &GateHWSpinlock_defInstParams,
+        sizeof(GateHWSpinlock_Params));
+}
+
+/*
+ * Create a GateHWSpinlock instance
+ */
+/* TODO: change the function to accept a local gate. Do this on all platforms */
+GateHWSpinlock_Handle GateHWSpinlock_create(GateHWSpinlock_LocalProtect
+    localProtect, const GateHWSpinlock_Params * params)
+{
+    GateHWSpinlock_Object * obj = (GateHWSpinlock_Object *)calloc(1,
+        sizeof (GateHWSpinlock_Object));
+
+    if (!obj) {
+        LOG0("GateHWSpinlock_create: memory allocation failure")
+        return NULL;
+    }
+
+    IGateProvider_ObjectInitializer(obj, GateHWSpinlock);
+    /* TODO: handle more local protection types */
+    obj->localGate = (IGateProvider_Handle)Mod->gmHandle;
+    obj->lockNum = params->resourceId;
+    obj->nested = 0;
+
+    return (GateHWSpinlock_Handle)obj;
+}
+
+/*
+ * Delete a GateHWSpinlock instance
+ */
+Int GateHWSpinlock_delete (GateHWSpinlock_Handle * handle)
+{
+    GateHWSpinlock_Object * obj;
+    Int  status = GateHWSpinlock_S_SUCCESS;
+
+    if (handle == NULL) {
+        return GateHWSpinlock_E_INVALIDARG;
+    }
+    if (*handle == NULL) {
+        return GateHWSpinlock_E_INVALIDARG;
+    }
+
+    obj = (GateHWSpinlock_Object *)(*handle);
+
+    free(obj);
+    *handle = NULL;
+
+    return (status);
+}
+
+/*
+ *  Enter a GateHWSpinlock instance
+ */
+IArg GateHWSpinlock_enter(GateHWSpinlock_Object *obj)
+{
+    volatile UInt32 *baseAddr = Mod->baseAddr;
+    IArg key;
+
+    key = IGateProvider_enter(obj->localGate);
+
+    /* if gate already entered, just return with current key */
+    obj->nested++;
+    if (obj->nested > 1) {
+        return(key);
+    }
+
+    /* enter the spinlock */
+    while (1) {
+        /* read the spinlock, returns non-zero when we get it */
+        if (baseAddr[obj->lockNum] == 0) {
+            break;
+        }
+        obj->nested--;
+        IGateProvider_leave(obj->localGate, key);
+        key = IGateProvider_enter(obj->localGate);
+        obj->nested++; /* re-nest the gate */
+    }
+
+    return (key);
+}
+
+/*
+ *  Leave a GateHWSpinlock instance
+ */
+Int GateHWSpinlock_leave(GateHWSpinlock_Object *obj, IArg key)
+{
+    volatile UInt32 *baseAddr = Mod->baseAddr;
+
+    obj->nested--;
+
+    /* release the spinlock if not nested */
+    if (obj->nested == 0) {
+        baseAddr[obj->lockNum] = 0;
+    }
+
+    IGateProvider_leave(obj->localGate, key);
+
+    return GateHWSpinlock_S_SUCCESS;
+}
diff --git a/linux/src/daemon/GateHWSpinlockCfg_dra7xx.c b/linux/src/daemon/GateHWSpinlockCfg_dra7xx.c
new file mode 100644 (file)
index 0000000..ebe323a
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 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.
+ */
+/*
+ * ======== GateHWSpinlockCfg_dra7xx.c ========
+ * GateHWSpinlock configuration for DRA7xx device
+ */
+
+/* Standard IPC headers */
+#include <ti/ipc/Std.h>
+
+#include <GateHWSpinlock.h>
+
+GateHWSpinlock_Config _GateHWSpinlock_cfgParams =  {
+   .baseAddr = 0x4A0F6000,
+   .size = 0x1000,
+   .offset = 0x800,
+};
diff --git a/linux/src/daemon/GateHWSpinlock_daemon.c b/linux/src/daemon/GateHWSpinlock_daemon.c
new file mode 100644 (file)
index 0000000..bc19c79
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+/*!
+ *  @file      GateHwSpinlock_daemon.c
+ *
+ *  @brief     GateHWSpinlock to get the base address, size and offset for the
+ *              device's spinlock registers.
+ *
+ */
+
+/* Standard IPC headers */
+#include <ti/ipc/Std.h>
+
+/* Linux specific header files */
+#include <assert.h>
+#include <string.h>
+
+/* Module level headers */
+#include <GateHWSpinlock.h>
+
+/* for Logging */
+#include <_lad.h>
+
+
+/* =============================================================================
+ *  APIs
+ * =============================================================================
+ */
+/* Get the default config address & sizes of the GateHWSpinlock module. */
+Void GateHWSpinlock_getConfig (GateHWSpinlock_Config * cfgParams)
+{
+    int i;
+
+    assert (cfgParams != NULL);
+
+    /* Setup MultiProc config */
+    memcpy (cfgParams, &_GateHWSpinlock_cfgParams,
+        sizeof(GateHWSpinlock_Config));
+
+    LOG1("GateHWSpinlock_getConfig()\tbaseAddr = 0x%x\n",
+        _GateHWSpinlock_cfgParams.baseAddr);
+    LOG2("\tsize = 0x%x\n\toffset = 0x%x\n",
+         _GateHWSpinlock_cfgParams.size, _GateHWSpinlock_cfgParams.offset);
+}
diff --git a/linux/src/daemon/GateMP_daemon.c b/linux/src/daemon/GateMP_daemon.c
new file mode 100644 (file)
index 0000000..306a755
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * 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.
+ */
+
+/*
+ *  ======== GateMP_daemon.c ========
+ */
+
+
+/* Standard headers */
+#include <ti/ipc/Std.h>
+
+/* Linux specific header files */
+#include <pthread.h>
+
+/* System headers */
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <assert.h>
+
+/* Module level headers */
+#include <ti/ipc/GateMP.h>
+#include <ti/ipc/NameServer.h>
+#include <ti/ipc/MultiProc.h>
+#include <_MultiProc.h>
+#include <GateMP_config.h>
+#include <_GateMP.h>
+
+#include <IGateProvider.h>
+#include <_GateMP_daemon.h>
+#include <_lad.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#define NUM_INFO_FIELDS       6    /* Number of fields in info entry */
+
+/* Values used to populate the resource 'inUse' arrays */
+#define UNUSED          ((UInt8)0)
+#define USED            ((UInt8)1)
+#define RESERVED        ((UInt8)-1)
+
+/* Name of GateMP's nameserver */
+#define GateMP_NAMESERVER  "GateMP"
+
+#define PAGE_ALIGN(size, psz)  (((size) + psz - 1) & ~(psz -1))
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+
+/* structure for GateMP module state */
+typedef struct {
+    Int               numRemoteSystem;
+    Int               numRemoteCustom1;
+    Int               numRemoteCustom2;
+    UInt8 *           remoteSystemInUse;
+    UInt8 *           remoteCustom1InUse;
+    UInt8 *           remoteCustom2InUse;
+    GateMP_Handle     defaultGate;
+    NameServer_Handle nameServer;
+    Bool              isSetup;
+} GateMP_ModuleObject;
+
+/* Internal functions */
+static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr);
+static Int GateMP_closeDefaultGate(GateMP_Handle *handlePtr);
+
+/* =============================================================================
+ *  Globals
+ * =============================================================================
+ */
+/*
+ * GateMP_state
+ */
+static GateMP_ModuleObject GateMP_state = {
+    .numRemoteSystem                 = 0,
+    .numRemoteCustom1                = 0,
+    .numRemoteCustom2                = 0,
+    .remoteSystemInUse               = NULL,
+    .remoteCustom1InUse              = NULL,
+    .remoteCustom2InUse              = NULL,
+    .defaultGate                     = NULL,
+    .nameServer                      = NULL,
+    .isSetup                         = FALSE
+};
+
+static GateMP_ModuleObject * GateMP_module = &GateMP_state;
+
+/* =============================================================================
+ * APIS
+ * =============================================================================
+ */
+
+/* Function to setup the gatemp module. */
+Int GateMP_setup(Void)
+{
+    Int               status = GateMP_S_SUCCESS;
+    NameServer_Params params;
+    UInt32            nsValue[NUM_INFO_FIELDS];
+    UInt32            len;
+    UInt32            size;
+    Int32             fdMem;
+
+    NameServer_Params_init(&params);
+    params.maxRuntimeEntries = MAX_RUNTIME_ENTRIES;
+    params.maxNameLen = MAX_NAME_LEN;
+
+    /* Assume info entry has more fields than other entries */
+    params.maxValueLen = NUM_INFO_FIELDS * sizeof(UInt32);
+
+    GateMP_module->nameServer =
+                NameServer_create(GateMP_NAMESERVER, &params);
+
+    if (GateMP_module->nameServer == NULL) {
+        status = GateMP_E_FAIL;
+        LOG0("GateMP_setup: NameServer_create failed\n");
+    }
+
+    if (status == GateMP_S_SUCCESS) {
+        do {
+            sleep(1);   /* Give the slaves some time to get NameServer ready */
+            status = GateMP_openDefaultGate(&GateMP_module->defaultGate);
+        } while (status == GateMP_E_NOTFOUND);
+
+
+        if (status < 0) {
+            LOG0("GateMP_setup: failed to open default gate\n");
+            status = GateMP_E_FAIL;
+        }
+    }
+
+    if (status == GateMP_S_SUCCESS) {
+        /* Process global info NameServer entry */
+        len = sizeof(nsValue);
+
+        status = NameServer_get(GateMP_module->nameServer, "_GateMP_TI_info",
+            &nsValue, &len, NULL);
+
+        if (status < 0) {
+            LOG0("GateMP_setup: failed to find info entry\n");
+            status = GateMP_E_NOTFOUND;
+        }
+        else {
+            fdMem = open ("/dev/mem", O_RDWR | O_SYNC);
+
+            if (fdMem < 0){
+                LOG0("GateMP_setup: failed to open the /dev/mem!\n");
+                status = GateMP_E_FAIL;
+                goto cleanup;
+            }
+
+            GateMP_module->numRemoteSystem = nsValue[3];
+            GateMP_module->numRemoteCustom1 = nsValue[4];
+            GateMP_module->numRemoteCustom2 = nsValue[5];
+
+            /* Map InUse arrays to daemon's address space */
+            size = GateMP_module->numRemoteSystem * sizeof (UInt8) +
+                (nsValue[0] & (sysconf(_SC_PAGE_SIZE) - 1));
+            size = PAGE_ALIGN(size, sysconf(_SC_PAGE_SIZE));
+            GateMP_module->remoteSystemInUse = mmap(NULL, size,
+                (PROT_READ|PROT_WRITE), (MAP_SHARED), fdMem,
+                (off_t)nsValue[0] & ~(sysconf(_SC_PAGE_SIZE) - 1));
+            if (GateMP_module->remoteSystemInUse == MAP_FAILED) {
+                 GateMP_module->remoteSystemInUse = NULL;
+                 status = GateMP_E_MEMORY;
+                 LOG1("Failed to map remoteSystemInUse=0x%p to host address" \
+                      "  space!", GateMP_module->remoteSystemInUse);
+            }
+
+            size = GateMP_module->numRemoteCustom1 * sizeof (UInt8) +
+                (nsValue[0] & (sysconf(_SC_PAGE_SIZE) - 1));
+            size = PAGE_ALIGN(size, sysconf(_SC_PAGE_SIZE));
+            if (status == GateMP_S_SUCCESS) {
+                GateMP_module->remoteCustom1InUse = mmap(NULL, size,
+                    (PROT_READ|PROT_WRITE), (MAP_SHARED), fdMem,
+                    (off_t)nsValue[1] & ~(sysconf(_SC_PAGE_SIZE) - 1));
+                if (GateMP_module->remoteCustom1InUse == MAP_FAILED) {
+                    GateMP_module->remoteCustom1InUse = NULL;
+                    status = GateMP_E_MEMORY;
+                    LOG1("Failed to map remoteCustom1InUse=%p to host address" \
+                        " space!", GateMP_module->remoteCustom1InUse);
+                }
+            }
+
+            size = GateMP_module->numRemoteCustom2 * sizeof (UInt8) +
+                (nsValue[0] & (sysconf(_SC_PAGE_SIZE) - 1));
+            size = PAGE_ALIGN(size, sysconf(_SC_PAGE_SIZE));
+            if (status == GateMP_S_SUCCESS) {
+                GateMP_module->remoteCustom2InUse = mmap(NULL, size,
+                    (PROT_READ|PROT_WRITE), (MAP_SHARED), fdMem,
+                    (off_t)nsValue[2] & ~(sysconf(_SC_PAGE_SIZE) - 1));
+                if (GateMP_module->remoteCustom2InUse == MAP_FAILED) {
+                    GateMP_module->remoteCustom2InUse = NULL;
+                    status = GateMP_E_MEMORY;
+                    LOG1("Failed to map remoteCustom2InUse=%p to host address" \
+                        " space!", GateMP_module->remoteCustom2InUse);
+                }
+            }
+        }
+    }
+
+    /* TODO: setup the proxy map */
+
+cleanup:
+    /* clean up if error */
+    if (status < 0) {
+        GateMP_destroy();
+    }
+
+    GateMP_module->isSetup = TRUE;
+
+    return (status);
+}
+
+Void GateMP_destroy(Void)
+{
+    if (GateMP_module->remoteSystemInUse) {
+        munmap((unsigned int *)GateMP_module->remoteSystemInUse,
+            GateMP_module->numRemoteSystem * sizeof (UInt8));
+        GateMP_module->remoteSystemInUse = NULL;
+    }
+
+    if (GateMP_module->remoteCustom1InUse) {
+        munmap((unsigned int *)GateMP_module->remoteCustom1InUse,
+            GateMP_module->numRemoteCustom1 * sizeof (UInt8));
+        GateMP_module->remoteCustom1InUse = NULL;
+    }
+
+    if (GateMP_module->remoteCustom2InUse) {
+        munmap((unsigned int *)GateMP_module->remoteCustom2InUse,
+            GateMP_module->numRemoteCustom2 * sizeof (UInt8));
+        GateMP_module->remoteCustom2InUse = NULL;
+    }
+
+    if (GateMP_module->defaultGate) {
+        GateMP_closeDefaultGate(&GateMP_module->defaultGate);
+    }
+
+    if (GateMP_module->nameServer) {
+        NameServer_delete(&GateMP_module->nameServer);
+        GateMP_module->nameServer = NULL;
+    }
+
+    GateMP_module->isSetup = FALSE;
+
+    return;
+}
+
+/* Open default gate during GateMP_setup. Should only be called once */
+static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr)
+{
+    Int             status = GateMP_S_SUCCESS;
+    UInt32          len;
+    UInt32          nsValue[4];
+    GateMP_Object * obj = NULL;
+    UInt32          arg;
+    UInt32          mask;
+    UInt32          creatorProcId;
+
+    GateMP_RemoteSystemProxy_Params     systemParams;
+
+    /* assert that a valid pointer has been supplied */
+    if (handlePtr == NULL) {
+        LOG0("GateMP_open: argument cannot be null\n");
+        status = GateMP_E_INVALIDARG;
+    }
+
+    if (status == GateMP_S_SUCCESS) {
+        len = sizeof(nsValue);
+
+        status = NameServer_get(GateMP_module->nameServer, "_GateMP_TI_dGate",
+            &nsValue, &len, NULL);
+
+        if (status < 0) {
+            *handlePtr = NULL;
+            status = GateMP_E_NOTFOUND;
+        }
+        else {
+            arg = nsValue[2];
+            mask = nsValue[3];
+            creatorProcId = nsValue[1] >> 16;
+        }
+    }
+
+    if (status == GateMP_S_SUCCESS) {
+        /* allocate the instance object */
+        obj = (GateMP_Object *)calloc(1, sizeof (GateMP_Object));
+        if (obj != NULL) {
+            obj->localGate  = NULL;  /* TODO: create the local gate instance */
+            obj->localProtect  = GETLOCAL(mask);
+            obj->remoteProtect = GETREMOTE(mask);
+            obj->nsKey         = 0;
+            obj->numOpens      = 1;
+            obj->objType       = Ipc_ObjType_OPENDYNAMIC;
+            obj->resourceId    = arg;
+
+            assert(obj->remoteProtect == GateMP_RemoteProtect_SYSTEM);
+
+            /* create the proxy object */
+            GateMP_RemoteSystemProxy_Params_init(&systemParams);
+            systemParams.resourceId = obj->resourceId;
+            systemParams.openFlag = TRUE;
+
+            /*
+             * TODO: Currently passing in localProtect instead of localGate,
+             * since GateHWSpinlock owns the local gate
+             */
+            obj->gateHandle = (IGateProvider_Handle)
+                GateMP_RemoteSystemProxy_create(obj->localProtect,
+                    &systemParams);
+
+            if (obj->gateHandle == NULL) {
+                LOG0("GateMP_openDefaultGate: failed to create proxy\n");
+                free(obj);
+                obj = NULL;
+            }
+        }
+        else {
+            LOG0("GateMP_openDefaultGate: Memory allocation failed")
+        }
+
+        if (obj == NULL) {
+            status = GateMP_E_FAIL;
+        }
+    }
+
+    /* Return the "opened" GateMP instance  */
+    *handlePtr = (GateMP_Handle)obj;
+
+    return status;
+}
+
+static Int GateMP_closeDefaultGate(GateMP_Handle *handlePtr)
+{
+    Int status = GateMP_S_SUCCESS;
+    GateMP_Object * obj = *(GateMP_Object **)handlePtr;
+
+    if (obj->gateHandle != NULL) {
+        /* Default gate is always of type System when more than 1 processor */
+        GateMP_RemoteSystemProxy_delete(
+            (GateMP_RemoteSystemProxy_Handle *)&obj->gateHandle);
+    }
+
+    free(*handlePtr);
+    *handlePtr = NULL;
+
+    return(status);
+}
+
+Int GateMP_getFreeResource(GateMP_RemoteProtect type)
+{
+    IArg   key;
+    Bool   flag = FALSE;
+    Int    resourceId = -1;
+    UInt8* inUse = NULL;
+    Int    num = 0;
+
+    /* Remote case */
+    switch (type) {
+        /* TODO: currently only support System proxy */
+        case GateMP_RemoteProtect_SYSTEM:
+        case GateMP_RemoteProtect_CUSTOM1:
+        case GateMP_RemoteProtect_CUSTOM2:
+            inUse = GateMP_module->remoteSystemInUse;
+            num = GateMP_module->numRemoteSystem;
+            break;
+
+        default:
+            LOG0("GateMP_getFreeResource: Invalid remote protection type\n");
+            break;
+    }
+
+    if (inUse != NULL) {
+        assert(GateMP_module->defaultGate != NULL);
+        key = GateMP_enter(GateMP_module->defaultGate);
+
+        /*
+         *  Find a free resource id. Note: zero is reserved on the
+         *  system proxy for the default gate.
+         */
+        for (resourceId = 0; resourceId < num; resourceId++) {
+            /*
+             *  If not in-use, set the inUse to TRUE to prevent other
+             *  creates from getting this one.
+             */
+            if (inUse[resourceId] == UNUSED) {
+                flag = TRUE;
+
+                /* Denote in shared memory that the resource is used */
+                inUse[resourceId] = USED;
+                break;
+            }
+        }
+
+        GateMP_leave(GateMP_module->defaultGate, key);
+    }
+
+    if (flag == FALSE) {
+        resourceId = -1;
+    }
+
+    return (resourceId);
+}
+
+Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
+{
+    Int    status = GateMP_S_SUCCESS;
+    IArg   key;
+    UInt8* inUse = NULL;
+    Int    num = 0;
+
+    /* Remote case */
+    switch (type) {
+        /* TODO: currently only support System proxy */
+        case GateMP_RemoteProtect_SYSTEM:
+        case GateMP_RemoteProtect_CUSTOM1:
+        case GateMP_RemoteProtect_CUSTOM2:
+            inUse = GateMP_module->remoteSystemInUse;
+            num = GateMP_module->numRemoteSystem;
+            break;
+
+        default:
+            LOG0("GateMP_releaseResource: Invalid remote protection type\n");
+            status = GateMP_E_FAIL;
+            break;
+    }
+
+    if ((inUse != NULL) && (id < num)) {
+        assert(GateMP_module->defaultGate != NULL);
+        key = GateMP_enter(GateMP_module->defaultGate);
+        inUse[id] = UNUSED;
+        GateMP_leave(GateMP_module->defaultGate, key);
+    }
+    else {
+        /* Should not happen if module is properly setup */
+        status = GateMP_E_FAIL;
+    }
+
+    return (status);
+}
+
+Int GateMP_getNumResources(GateMP_RemoteProtect type)
+{
+    Int   num = -1;
+
+    /* Remote case */
+    switch (type) {
+        /* TODO: currently only support System proxy */
+        case GateMP_RemoteProtect_SYSTEM:
+        case GateMP_RemoteProtect_CUSTOM1:
+        case GateMP_RemoteProtect_CUSTOM2:
+            num = GateMP_module->numRemoteSystem;
+            break;
+
+        default:
+            LOG0("GateMP_getNumResources: Invalid remote protection type\n");
+            break;
+    }
+
+    return (num);
+}
+
+NameServer_Handle GateMP_getNameServer(Void)
+{
+    return (GateMP_module->nameServer);
+}
+
+Bool GateMP_isSetup(Void)
+{
+    return (GateMP_module->isSetup);
+}
+
+IArg GateMP_enter(GateMP_Handle handle)
+{
+    GateMP_Object * obj;
+    IArg            key;
+
+    obj = (GateMP_Object *)handle;
+    key = IGateProvider_enter(obj->gateHandle);
+
+    return(key);
+}
+
+Void GateMP_leave(GateMP_Handle handle, IArg key)
+{
+    GateMP_Object *obj;
+
+    obj = (GateMP_Object *)handle;
+    IGateProvider_leave(obj->gateHandle, key);
+}
index fddbc414ec98d4455d3a8a6a736237a875d9c223..f205ddbf34700aebefe3cd3c9d1cd1f2c4124f17 100644 (file)
@@ -36,6 +36,10 @@ AM_CFLAGS = -I$(top_srcdir)/linux/include -I$(top_srcdir)/hlos_common/include \
         -I$(top_srcdir)/packages -I$(KERNEL_INSTALL_DIR)/include/generated/uapi\
         -D_GNU_SOURCE -Wall @AM_CFLAGS@
 
+if DRA7XX
+AM_CFLAGS += -DGATEMP_SUPPORT
+endif
+
 ###############################################################################
 # THE PROGRAMS TO BUILD
 ###############################################################################
@@ -95,6 +99,22 @@ common_sources = \
                 $(top_srcdir)/packages/ti/ipc/NameServer.h \
                 $(top_srcdir)/packages/ti/ipc/MultiProc.h
 
+if DRA7XX
+common_sources += \
+                GateMP_daemon.c \
+               GateHWSpinlock.c \
+               GateHWSpinlock_daemon.c \
+               GateHWSpinlockCfg_dra7xx.c \
+               $(top_srcdir)/linux/src/api/gates/GateMutex.c \
+               $(top_srcdir)/linux/include/_GateMP.h \
+                $(top_srcdir)/linux/include/_GateMP_daemon.h \
+                $(top_srcdir)/linux/include/IGateProvider.h \
+                $(top_srcdir)/linux/include/GateHWSpinlock.h \
+                $(top_srcdir)/linux/include/GateMutex.h \
+                $(top_srcdir)/linux/include/GateMP_config.h \
+                $(top_srcdir)/packages/ti/ipc/GateMP.h
+endif
+
 # list of sources for the 'lad' binary and to add to the source distribution
 #
 # NOTE:  6636_SOURCES using 6638.c is not a typo!  6636 has the same
index bc644e5b5d83ed78c257554044cb3b9cdb95daad..abaf757f800809cf808bc438ab8e8be84f0248de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, Texas Instruments Incorporated
+ * Copyright (c) 2012-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -250,6 +250,7 @@ static void NameServerRemote_processMessage(NameServerMsg * msg, UInt16 procId)
         LOG2("NameServer Request: instanceName: %s, name: %s\n",
              (String)msg->instanceName, (String)msg->name)
 
+        assert(msg->valueLen <= MAXVALUELEN);
         /*
          *  Message is a request. Lookup name in NameServer table.
          *  Send a response message back to source processor.
@@ -258,9 +259,16 @@ static void NameServerRemote_processMessage(NameServerMsg * msg, UInt16 procId)
 
         if (handle != NULL) {
             /* Search for the NameServer entry */
-            LOG0("Calling NameServer_getLocalUInt32...\n")
-            status = NameServer_getLocalUInt32(handle,
+            if (msg->valueLen <= sizeof (Bits32)) {
+                LOG0("Calling NameServer_getLocalUInt32...\n")
+                status = NameServer_getLocalUInt32(handle,
                      (String)msg->name, &msg->value);
+            }
+            else {
+                LOG0("Calling NameServer_getLocal...\n")
+                status = NameServer_getLocal(handle,
+                     (String)msg->name, (Ptr)msg->valueBuf, &msg->valueLen);
+            }
         }
 
         LOG2("NameServer Response: instanceName: %s, name: %s,",
@@ -625,12 +633,6 @@ NameServer_Handle NameServer_create(String name,
 
     pthread_mutex_lock(&NameServer_module->modGate);
 
-    if (params->maxValueLen > sizeof(UInt32)) {
-        LOG1("NameServer_create: params->maxValueLen (%d) too big for now\n", params->maxValueLen)
-       /* Can't handle more than UInt32 at this time: */
-       goto leave;
-    }
-
     /* check if the name is already created or not */
     handle = NameServer_getHandle(name);
     if (handle != NULL) {
@@ -751,6 +753,13 @@ Ptr NameServer_add(NameServer_Handle handle, String name, Ptr buf, UInt len)
     /* Calculate the hash */
     hash = stringHash(name);
 
+    if (len > handle->params.maxValueLen) {
+        status = NameServer_E_INVALIDARG;
+        LOG0("NameServer_add: value length exceeded maximum!\n")
+        new_node = NULL;
+        goto exit;
+    }
+
     pthread_mutex_lock(&handle->gate);
 
     /* Traverse the list to find duplicate check */
@@ -959,6 +968,7 @@ Int NameServer_getRemote(NameServer_Handle handle,
     uint64_t buf = 1;
     int numBytes;
     int err;
+    int i;
 
     /* Set Timeout to wait: */
     tv.tv_sec = 0;
@@ -1023,13 +1033,28 @@ Int NameServer_getRemote(NameServer_Handle handle,
 
         if (replyMsg->requestStatus) {
             /* name is found */
+
+            /* set length to amount of data that was copied */
+            *len = replyMsg->valueLen;
+
             /* set the contents of value */
-            *(UInt32 *)value = (UInt32)replyMsg->value;
+            if (*len <= sizeof (Bits32)) {
+                *(UInt32 *)value = (UInt32)replyMsg->value;
+                LOG2("NameServer_getRemote: Reply from: %d, %s:",
+                    procId, (String)replyMsg->instanceName)
+                LOG2("%s, value: 0x%x...\n",
+                    (String)replyMsg->name, *(UInt32 *)value)
+            }
+            else {
+                memcpy(value, replyMsg->valueBuf, *len);
+                LOG2("NameServer_getRemote: Reply from: %d, %s:",
+                    procId, (String)replyMsg->instanceName)
+                for (i = 0; i < *len/4; i++) {
+                    LOG2("%s, value buffer content: 0x%x...\n",
+                        (String)replyMsg->name, ((uint32_t *)value)[i])
+                }
+            }
 
-            LOG2("NameServer_getRemote: Reply from: %d, %s:",
-                 procId, (String)replyMsg->instanceName)
-            LOG2("%s, value: 0x%x...\n",
-                 (String)replyMsg->name, *(UInt32 *)value)
             goto exit;
         }
         else {
index 89c34eaac4f8b2d38bf17f48bd21d0f19d4d7efd..fa4f217342711ab6097455da80bc658666f97afe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, Texas Instruments Incorporated
+ * Copyright (c) 2012-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #include <_MessageQ.h>
 #include <ti/ipc/NameServer.h>
 #include <_NameServer.h>
+#include <ti/ipc/GateMP.h>
+#include <_GateMP_daemon.h>
+
+#include <GateHWSpinlock.h>
 
 #include <ladclient.h>
 #include <_lad.h>
@@ -61,6 +65,8 @@ FILE *logPtr = NULL;
 static String commandFIFOFile = LAD_COMMANDFIFO;
 static FILE *commandFIFOFilePtr = NULL;
 
+static Bool gatempEnabled = FALSE;
+
 /* LAD client info arrays */
 static Bool clientConnected[LAD_MAXNUMCLIENTS];
 static UInt clientPID[LAD_MAXNUMCLIENTS];
@@ -92,6 +98,8 @@ int main(int argc, char * argv[])
     Int flags;
     Int i;
     Int n;
+    Int c;
+    Int status;
     String tmpString;
 #if DAEMON
     pid_t pid;
@@ -136,6 +144,28 @@ int main(int argc, char * argv[])
                 fcntl(fileno(logPtr), F_SETFD, flags | FD_CLOEXEC);
             }
         }
+
+        /* parse other options. To pass options you must provide a log file */
+        while (1) {
+            c = getopt(argc, argv, "g");
+            if (c == -1) {
+                break;
+            }
+
+            switch (c)
+            {
+                case 'g':
+#if defined(GATEMP_SUPPORT)
+                    printf("\nGateMP support enabled on host\n");
+                    gatempEnabled = TRUE;
+#else
+                    printf("\nGateMP is not supported for this device\n");
+#endif
+                    break;
+                default:
+                    fprintf (stderr, "Unrecognized argument\n");
+            }
+        }
     }
 
 #if DAEMON
@@ -201,6 +231,32 @@ int main(int argc, char * argv[])
     /* set FIFO permissions to read/write */
     chmod(commandFIFOFile, 0666);
 
+    /* Setup modules relevant for GateMP if necessary */
+#if defined(GATEMP_SUPPORT)
+    if (gatempEnabled) {
+        /* Set up NameServer for resource manager process */
+        status = NameServer_setup();
+        if (status < 0) {
+            LOG0("\nERROR: unable to setup NameServer\n")
+            return(0);
+        }
+
+        status = GateHWSpinlock_start();
+        if (status < 0) {
+            LOG0("\nERROR: unable to start GateHWSpinlock\n");
+            return(0);
+        }
+
+        /* Set up GateMP */
+        status = GateMP_setup();
+        if (status < 0) {
+            LOG0("\nERROR: unable to setup GateMP\n")
+            NameServer_destroy();
+            return(0);
+        }
+    }
+#endif
+
 opencommandFIFO:
 
     /* now open file for FIFO - will block until writer arrives... */
@@ -209,6 +265,12 @@ opencommandFIFO:
     if (commandFIFOFilePtr == NULL) {
         LOG0("\nERROR: unable to open command FIFO\n")
         unlink(commandFIFOFile);
+#if defined(GATEMP_SUPPORT)
+        if (gatempEnabled) {
+            GateMP_destroy();
+            NameServer_destroy();
+        }
+#endif
         return(0);
     }
 
@@ -223,7 +285,7 @@ opencommandFIFO:
          * if last client closes FIFO then it must be closed and reopened ...
          */
         if (!n) {
-            LOG1("    EOF detected on FIFO, closing FIFO: %s\n", commandFIFOFile)
+            LOG1("   EOF detected on FIFO, closing FIFO: %s\n", commandFIFOFile)
             fclose(commandFIFOFilePtr);
 
             goto opencommandFIFO;
@@ -307,6 +369,47 @@ opencommandFIFO:
 
             break;
 
+          case LAD_NAMESERVER_ADD:
+            LOG1("LAD_NAMESERVER_ADD: calling NameServer_add(%p, ", cmd.args.add.handle)
+            LOG2("'%s', %p,", cmd.args.add.name, cmd.args.add.buf)
+            LOG1(" 0x%x)...\n", cmd.args.add.len)
+
+            rsp.entryPtr = NameServer_add(
+                cmd.args.add.handle,
+                cmd.args.add.name,
+                cmd.args.add.buf,
+                cmd.args.add.len);
+
+            LOG1("    entryPtr = %p\n", rsp.entryPtr)
+            LOG0("DONE\n")
+
+            break;
+
+          case LAD_NAMESERVER_GET:
+            LOG2("LAD_NAMESERVER_GET: calling NameServer_get(%p, '%s'",
+                cmd.args.get.handle, cmd.args.get.name)
+            LOG0(")...\n")
+
+            if (cmd.args.get.procId[0] == (UInt16)-1) {
+                procIdPtr = NULL;
+            }
+            else {
+                procIdPtr = cmd.args.get.procId;
+            }
+            rsp.status = NameServer_get(
+                cmd.args.get.handle,
+                cmd.args.get.name,
+                rsp.get.buf,
+                &cmd.args.get.len,
+                procIdPtr);
+            rsp.get.len = cmd.args.get.len;
+
+            LOG1("    value = 0x%x\n", rsp.get.len)
+            LOG1("    status = %d\n", rsp.status)
+            LOG0("DONE\n")
+
+            break;
+
           case LAD_NAMESERVER_ADDUINT32:
             LOG1("LAD_NAMESERVER_ADDUINT32: calling NameServer_addUInt32(%p, ", cmd.args.addUInt32.handle)
             LOG2("'%s', 0x%x)...\n", cmd.args.addUInt32.name, cmd.args.addUInt32.val)
@@ -455,6 +558,77 @@ opencommandFIFO:
 
             break;
 
+#if defined(GATEMP_SUPPORT)
+          case LAD_GATEMP_START:
+            LOG0("LAD_GATEMP_START: calling GateMP_start()...\n")
+
+            rsp.gateMPStart.nameServerHandle = GateMP_getNameServer();
+            rsp.gateMPStart.status = GateMP_S_SUCCESS;;
+
+            LOG1("    status = %d\n", rsp.gateMPStart.status)
+            LOG0("DONE\n")
+
+            break;
+
+          case LAD_GATEMP_GETNUMRESOURCES:
+            LOG0("LAD_GATEMP_GETNUMRESOURCES: calling GateMP_getNumResources()...\n")
+
+            rsp.gateMPGetNumResources.value = GateMP_getNumResources(
+                                          cmd.args.gateMPGetNumResources.type);
+            rsp.gateMPGetNumResources.status = GateMP_S_SUCCESS;;
+
+            LOG1("    status = %d\n", rsp.gateMPGetNumResources.status)
+            LOG0("DONE\n")
+
+            break;
+
+          case LAD_GATEMP_GETFREERESOURCE:
+            LOG0("LAD_GATEMP_GETFREERESOURCE: calling GateMP_getFreeResource()...\n")
+
+            rsp.gateMPGetFreeResource.id = GateMP_getFreeResource(
+                                          cmd.args.gateMPGetFreeResource.type);
+            rsp.gateMPGetFreeResource.status = GateMP_S_SUCCESS;;
+
+            LOG1("    status = %d\n", rsp.gateMPGetFreeResource.status)
+            LOG0("DONE\n")
+
+            break;
+
+          case LAD_GATEMP_RELEASERESOURCE:
+            LOG0("LAD_GATEMP_RELEASERESOURCE: calling GateMP_releaseResource()...\n")
+
+            rsp.gateMPReleaseResource.status = GateMP_releaseResource(
+                                          cmd.args.gateMPReleaseResource.id,
+                                          cmd.args.gateMPReleaseResource.type);
+
+            LOG1("    status = %d\n", rsp.gateMPReleaseResource.status)
+            LOG0("DONE\n")
+
+            break;
+
+          case LAD_GATEMP_ISSETUP:
+            LOG0("LAD_GATEMP_ISSETUP: calling GateMP_isSetup()...\n")
+
+            rsp.gateMPIsSetup.result = GateMP_isSetup();
+            rsp.gateMPIsSetup.status = GateMP_S_SUCCESS;
+
+            LOG1("    status = %d\n", rsp.gateMPIsSetup.status)
+            LOG0("DONE\n")
+
+            break;
+
+          case LAD_GATEHWSPINLOCK_GETCONFIG:
+            LOG0("LAD_GATEHWSPINLOCK_GETCONFIG: calling GateHWSpinlock_getConfig()...\n")
+
+            GateHWSpinlock_getConfig(&rsp.gateHWSpinlockGetConfig.cfgParams);
+            rsp.gateHWSpinlockGetConfig.status = 0;
+
+            LOG1("    status = %d\n", rsp.gateHWSpinlockGetConfig.status)
+            LOG0("DONE\n")
+
+            break;
+#endif
+
           case LAD_EXIT:
             goto exitNow;
 
@@ -476,6 +650,8 @@ opencommandFIFO:
           case LAD_NAMESERVER_PARAMS_INIT:
           case LAD_NAMESERVER_CREATE:
           case LAD_NAMESERVER_DELETE:
+          case LAD_NAMESERVER_ADD:
+          case LAD_NAMESERVER_GET:
           case LAD_NAMESERVER_ADDUINT32:
           case LAD_NAMESERVER_GETUINT32:
           case LAD_NAMESERVER_REMOVE:
@@ -487,6 +663,15 @@ opencommandFIFO:
           case LAD_MESSAGEQ_DELETE:
           case LAD_MESSAGEQ_MSGINIT:
           case LAD_MULTIPROC_GETCONFIG:
+#if defined(GATEMP_SUPPORT)
+          case LAD_GATEMP_START:
+          case LAD_GATEMP_GETNUMRESOURCES:
+          case LAD_GATEMP_GETFREERESOURCE:
+          case LAD_GATEMP_RELEASERESOURCE:
+          case LAD_GATEMP_ISSETUP:
+          case LAD_GATEHWSPINLOCK_GETCONFIG:
+#endif
+
             LOG0("Sending response...\n");
 
             fwrite(&rsp, LAD_RESPONSELENGTH, 1, responseFIFOFilePtr[clientId]);
@@ -500,6 +685,12 @@ opencommandFIFO:
     }
 
 exitNow:
+#if defined(GATEMP_SUPPORT)
+    if (gatempEnabled) {
+        GateMP_destroy();
+        NameServer_destroy();
+    }
+#endif
     if (logFile) {
         LOG0("\n\nLAD IS SELF TERMINATING...\n\n")
         fclose(logPtr);
diff --git a/linux/src/tests/GateMPApp.c b/linux/src/tests/GateMPApp.c
new file mode 100644 (file)
index 0000000..1b13460
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ * 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.
+ */
+
+/*
+ *  ======== GateMPApp.c ========
+ *
+ */
+
+/* host header files */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* package header files */
+#include <ti/ipc/Std.h>
+#include <ti/ipc/MessageQ.h>
+#include <ti/ipc/GateMP.h>
+
+/* local header files */
+#include "GateMPApp.h"
+
+/* CMEM */
+#include <ti/cmem.h>
+
+#include <ti/ipc/tests/GateMPAppCommon.h>
+
+/* module structure */
+typedef struct {
+    MessageQ_Handle       hostQue;    /* created locally */
+    MessageQ_QueueId      slaveQue;   /* opened remotely */
+    UInt16                heapId;     /* MessageQ heapId */
+    UInt32                msgSize;    /* Size of messages */
+    volatile UInt32 *     intPtr;     /* Integer pointer */
+    UInt32                physAddr;   /* Physical address of shared memory */
+    GateMP_Handle         hostGateMPHandle;  /* handle to host-created gate */
+    GateMP_Handle         slaveGateMPHandle; /* handle to slave-created gate */
+} GateMPApp_Module;
+
+/* private data */
+static GateMPApp_Module Module;
+
+/* Global CMEM attrs */
+CMEM_AllocParams          cmemAttrs;
+
+/*
+ *  ======== GateMPApp_create ========
+ */
+
+Int GateMPApp_create()
+{
+    Int                 status    =0;
+    MessageQ_Params     msgqParams;
+    GateMP_Params       gateParams;
+
+    printf("--> GateMPApp_create:\n");
+
+    /* setting default values */
+    Module.hostQue = NULL;
+    Module.slaveQue = MessageQ_INVALIDMESSAGEQ;
+    Module.heapId = GateMPApp_MsgHeapId;
+    Module.intPtr = NULL;
+    Module.physAddr = 0;
+    Module.hostGateMPHandle = NULL;
+    Module.slaveGateMPHandle = NULL;
+    Module.msgSize = sizeof(GateMPApp_Msg);
+
+    /* create local message queue (inbound messages) */
+    MessageQ_Params_init(&msgqParams);
+
+    Module.hostQue = MessageQ_create(GateMPApp_HostMsgQueName, &msgqParams);
+
+    if (Module.hostQue == NULL) {
+        printf("GateMPApp_create: Failed creating MessageQ\n");
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    /* open the remote message queue */
+    do {
+        status = MessageQ_open(GateMPApp_SlaveMsgQueName, &Module.slaveQue);
+        sleep(1);
+    } while (status == MessageQ_E_NOTFOUND);
+
+    if (status < 0) {
+        printf("GateMPApp_create: Failed opening MessageQ\n");
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    /* allocate space from shared memory for an integer */
+    cmemAttrs.type = CMEM_HEAP;
+    cmemAttrs.flags = CMEM_NONCACHED;
+    cmemAttrs.alignment = 0;
+    Module.intPtr = (UInt32 *)CMEM_alloc(sizeof(UInt32), &cmemAttrs);
+    if (Module.intPtr < 0) {
+        printf("GateMPApp_create: Could not allocate CMEM shared memory\n");
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    Module.physAddr = (UInt32)CMEM_getPhys((Void *)Module.intPtr);
+
+    if (Module.physAddr == 0) {
+        printf("GateMPApp_create: Failed to get physical buffer address\n");
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    /* create GateMP */
+    GateMP_Params_init(&gateParams);
+
+    gateParams.name             = GATEMP_HOST_NAME;
+    gateParams.localProtect     = GateMP_LocalProtect_PROCESS;
+    gateParams.remoteProtect    = GateMP_RemoteProtect_SYSTEM;
+
+    Module.hostGateMPHandle = GateMP_create (&gateParams);
+
+    if (Module.hostGateMPHandle == NULL) {
+        status = GATEMPAPP_E_FAILURE;
+        printf("GateMPApp_create: Failed to create GateMP\n");
+        goto leave;
+    }
+    printf("GateMPApp_create: Host is ready\n");
+
+leave:
+    printf("<-- GateMPApp_create:\n");
+    return(status);
+}
+
+
+/*
+ *  ======== GateMPApp_delete ========
+ */
+Int GateMPApp_delete(Void)
+{
+    Int         status;
+    GateMPApp_Msg *   msg;
+
+    printf("--> GateMPApp_delete:\n");
+
+    /* allocate message */
+    msg = (GateMPApp_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
+
+    if (msg == NULL) {
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    /* set the return address in the message header */
+    MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
+
+    /* sending shutdown command */
+    msg->cmd = GATEMPAPP_CMD_SHUTDOWN;
+    MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
+
+    /* wait for acknowledgement message */
+    status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
+            MessageQ_FOREVER);
+
+    if (status < 0) {
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    if (msg->cmd != GATEMPAPP_CMD_SHUTDOWN_ACK) {
+        status = GATEMPAPP_E_UNEXPECTEDMSG;
+        goto leave;
+    }
+
+    /* free the message */
+    MessageQ_free((MessageQ_Msg)msg);
+
+    /* delete GateMP */
+    GateMP_delete(&Module.hostGateMPHandle);
+
+    /* free shared memory buffer */
+    status = CMEM_free((Ptr)Module.intPtr, &cmemAttrs);
+    if(status < 0) {
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    /* close remote resources */
+    status = MessageQ_close(&Module.slaveQue);
+
+    if (status < 0) {
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    /* delete the host message queue */
+    status = MessageQ_delete(&Module.hostQue);
+
+    if (status < 0) {
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+leave:
+    printf("<-- GateMPApp_delete:\n");
+    return(status);
+}
+
+
+/*
+ *  ======== GateMPApp_exec ========
+ */
+Int GateMPApp_exec(Void)
+{
+    Int         status;
+    Int         i;
+    GateMPApp_Msg *   msg;
+    IArg        gateKey         = 0;
+    UInt32      num;
+
+    printf("--> GateMPApp_exec:\n");
+
+    /* set shared variable initial value */
+    *Module.intPtr = 500;
+
+    /* allocate message */
+    msg = (GateMPApp_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
+    if (msg == NULL) {
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    /* set the return address in the message header */
+    MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
+
+    /* fill in message payload */
+    msg->cmd = GATEMPAPP_CMD_SPTR_ADDR;
+    msg->payload = Module.physAddr;
+
+    /* send message */
+    MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
+
+    /* wait for return message */
+    status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
+        MessageQ_FOREVER);
+    if (status < 0) {
+        goto leave;
+    }
+
+    if (msg->cmd != GATEMPAPP_CMD_SPTR_ADDR_ACK)
+    {
+        status = GATEMPAPP_E_UNEXPECTEDMSG;
+        goto leave;
+    }
+
+    /* free the message */
+    MessageQ_free((MessageQ_Msg)msg);
+
+    /* open slave-created GateMP */
+    do {
+        status = GateMP_open(GATEMP_SLAVE_NAME, &Module.slaveGateMPHandle);
+    } while (status == GateMP_E_NOTFOUND);
+
+    if (status < 0) {
+        printf("GateMPApp_exec: Failed to open slave-created GateMP");
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    printf("GateMPApp_exec: Using host-created gate\n");
+    for (i = 0; i < LOOP_ITR; i++) {
+        /* read the shared variable as long as no one is currently modifying
+         * it
+         */
+
+        /* enter GateMP */
+        gateKey = GateMP_enter(Module.hostGateMPHandle);
+
+        /* randomly modify the shared variable */
+        if (rand() % 2) {
+            *Module.intPtr -= 1;
+        }
+        else {
+            *Module.intPtr += 1;
+        }
+
+        /* read shared variable value */
+        num = *Module.intPtr;
+        printf("GateMPApp_exec: Current value: %d, " \
+            "previously read=%d\n", *Module.intPtr, num);
+
+        if (*Module.intPtr != num) {
+            printf("GateMPApp_exec: mismatch in variable value." \
+                "Test failed.\n");
+            status = GATEMPAPP_E_FAILURE;
+            goto leave;
+        }
+
+        /* exit GateMP */
+        GateMP_leave(Module.hostGateMPHandle, gateKey);
+    }
+
+    /* allocate message */
+    msg = (GateMPApp_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
+    if (msg == NULL) {
+        status = GATEMPAPP_E_FAILURE;
+        goto leave;
+    }
+
+    /* set the return address in the message header */
+    MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
+
+    /* fill in message payload */
+    msg->cmd = GATEMPAPP_CMD_SYNC;
+
+    /* send sync message */
+    MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
+
+    /* wait for return sync message before we switch gates */
+    status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
+        MessageQ_FOREVER);
+    if (status < 0) {
+        goto leave;
+    }
+
+    if (msg->cmd != GATEMPAPP_CMD_SYNC)
+    {
+        status = GATEMPAPP_E_UNEXPECTEDMSG;
+        goto leave;
+    }
+
+    /* free the message */
+    MessageQ_free((MessageQ_Msg)msg);
+
+    printf("GateMPApp_exec: Using slave-created gate\n");
+    for (i = 0; i < LOOP_ITR; i++) {
+        /* read the shared variable as long as no one is currently modifying
+         * it
+         */
+
+        /* enter GateMP */
+        gateKey = GateMP_enter(Module.slaveGateMPHandle);
+
+        /* randomly modify the shared variable */
+        if (rand() % 2) {
+            *Module.intPtr -= 1;
+        }
+        else {
+            *Module.intPtr += 1;
+        }
+
+        /* read shared variable value */
+        num = *Module.intPtr;
+        printf("GateMPApp_exec: Current value: %d, " \
+            "previously read=%d\n", *Module.intPtr, num);
+
+        if (*Module.intPtr != num) {
+            printf("GateMPApp_exec: mismatch in variable value." \
+                "Test failed.\n");
+            status = GATEMPAPP_E_FAILURE;
+            goto leave;
+        }
+
+        /* exit GateMP */
+        GateMP_leave(Module.slaveGateMPHandle, gateKey);
+    }
+
+leave:
+    if (Module.slaveGateMPHandle) {
+        GateMP_close(&Module.slaveGateMPHandle);
+    }
+
+    printf("<-- GateMPApp_exec: %d\n", status);
+    return(status);
+}
diff --git a/linux/src/tests/GateMPApp.h b/linux/src/tests/GateMPApp.h
new file mode 100644 (file)
index 0000000..c5be284
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+/*
+ *  ======== GateMPApp.h ========
+ *
+ */
+
+#ifndef GateMPApp__include
+#define GateMPApp__include
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+Int GateMPApp_create();
+Int GateMPApp_delete();
+Int GateMPApp_exec();
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+#endif /* GateMPApp__include */
index 471ccd3b9c3aa7dcea54acd4f8d915a32fd92d34..0a8a0171add8f2eb95189504e869adc10873fd9e 100644 (file)
@@ -72,7 +72,7 @@ endif
 else
 if DRA7XX
 # Add platform specific bin application's here
-  bin_PROGRAMS +=
+  bin_PROGRAMS += GateMPApp
 if KDIR
 if DRM
   bin_PROGRAMS += mmrpc_test
@@ -162,6 +162,14 @@ nano_test_SOURCES = $(common_sources) nano_test.c
 # list of sources for the 'Msgq100' binary
 Msgq100_SOURCES = $(common_sources) Msgq100.c
 
+# list of sources for the 'GateMPApp' binary
+GateMPApp_SOURCES = $(common_sources) \
+                $(top_srcdir)/linux/src/tests/main_host.c \
+                $(top_srcdir)/linux/src/tests/GateMPApp.c \
+                $(top_srcdir)/linux/src/tests/GateMPApp.h \
+                $(top_srcdir)/packages/ti/ipc/GateMP.h \
+                $(top_srcdir)/packages/ti/ipc/tests/GateMPAppCommon.h
+
 common_libraries = -lpthread $(top_builddir)/linux/src/api/libtiipc.la \
                 $(top_builddir)/linux/src/utils/libtiipcutils.la
 
@@ -199,4 +207,9 @@ nano_test_LDADD = $(common_libraries) \
 Msgq100_LDADD = $(common_libraries) \
                 $(AM_LDFLAGS)
 
+# the additional libraries needed to link GateMPApp
+GateMPApp_LDADD = $(common_libraries) \
+                $(CMEM_INSTALL_DIR)/src/cmem/api/.libs/libticmem.a \
+                $(AM_LDFLAGS)
+
 ###############################################################################
diff --git a/linux/src/tests/main_host.c b/linux/src/tests/main_host.c
new file mode 100644 (file)
index 0000000..3c5525c
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+/*
+ *  ======== 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/MultiProc.h>
+
+#include <ti/cmem.h>
+
+/* local header files */
+#include "GateMPApp.h"
+
+/* private functions */
+static Int Main_main(Void);
+static Int Main_parseArgs(Int argc, Char *argv[]);
+
+
+#define Main_USAGE "\
+Usage:\n\
+    GateMPApp [options]\n\
+\n\
+Options:\n\
+    h   : print this help message\n\
+\n\
+Examples:\n\
+    GateMPApp\n\
+    GateMPApp -h\n\
+\n"
+
+
+/*
+ *  ======== main ========
+ */
+Int main(Int argc, Char* argv[])
+{
+    Int status;
+
+    printf("--> main:\n");
+
+    /* parse command line */
+    status = Main_parseArgs(argc, argv);
+
+    if (status < 0) {
+        goto leave;
+    }
+
+    status = CMEM_init();
+    if (status < 0) {
+        printf("CMEM_init failed\n");
+        goto leave;
+    }
+    else {
+        printf("CMEM_init success\n");
+    }
+
+    /* 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)
+{
+    Int         status = 0;
+
+    printf("--> Main_main:\n");
+
+    /* BEGIN application phase */
+
+    /* application create phase */
+    status = GateMPApp_create();
+
+    if (status < 0) {
+        goto leave;
+    }
+
+    /* application execute phase */
+    status = GateMPApp_exec();
+
+    if (status < 0) {
+        goto leave;
+    }
+
+    /* application delete phase */
+    status = GateMPApp_delete();
+
+    if (status < 0) {
+        goto leave;
+    }
+
+leave:
+    printf("<-- Main_main:\n");
+
+    status = (status >= 0 ? 0 : status);
+    return (status);
+}
+
+
+/*
+ *  ======== Main_parseArgs ========
+ */
+Int Main_parseArgs(Int argc, Char *argv[])
+{
+    Int             x, cp, opt;
+    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;
+
+            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 */
+    if (opt < argc) {
+        printf(
+            "Error: %s, line %d: too many arguments\n",
+            __FILE__, __LINE__);
+        printf("%s", Main_USAGE);
+        status = -1;
+        goto leave;
+    }
+
+leave:
+    return(status);
+}
index b55788c311505eeeb3042c6e51eb6ae6855e7205..7a7c96936c3ee84b7127307b887b597b313d3d8f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Texas Instruments Incorporated
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * Assign fixed RAM addresses to facilitate a fixed MMU table.
  */
 /* This address is derived from current IPU & ION carveouts */
-#ifdef OMAP5
 #define PHYS_MEM_IPC_VRING      0x95000000
-#else
-#define PHYS_MEM_IPC_VRING      0x98800000
-#endif
 
 /* Need to be identical to that of IPU */
 #define PHYS_MEM_IOBUFS         0xBA300000