Power: Add power manager from omapzoom sysbios-rpmsg repo for OMAP5.
authorG Anthony <a0783926@ti.com>
Wed, 27 Feb 2013 01:50:08 +0000 (17:50 -0800)
committerG Anthony <a0783926@ti.com>
Wed, 27 Feb 2013 01:50:08 +0000 (17:50 -0800)
This is a dependency for OMAP5 IPC stack and samples.

Signed-off-by: G Anthony <a0783926@ti.com>
packages/ti/pm/IpcPower.c [new file with mode: 0644]
packages/ti/pm/IpcPower.h [new file with mode: 0644]
packages/ti/pm/IpcPowerDsp.c [new file with mode: 0644]
packages/ti/pm/_IpcPower.h [new file with mode: 0644]
packages/ti/pm/package.bld [new file with mode: 0644]
packages/ti/pm/package.xdc [new file with mode: 0644]
packages/ti/pm/package.xs [new file with mode: 0644]

diff --git a/packages/ti/pm/IpcPower.c b/packages/ti/pm/IpcPower.c
new file mode 100644 (file)
index 0000000..5834b59
--- /dev/null
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2011-2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** ============================================================================
+ *  @file       IpcPower.c
+ *
+ *  @brief      A simple Power Managment which responses to the host commands.
+ *
+ *  TODO:
+ *     - Add suspend/resume notifications
+ *  ============================================================================
+ */
+
+#include <xdc/std.h>
+#include <xdc/runtime/System.h>
+#include <xdc/runtime/Error.h>
+#include <xdc/runtime/Assert.h>
+#include <xdc/runtime/Memory.h>
+#include <xdc/runtime/Main.h>
+#include <xdc/runtime/Registry.h>
+#include <xdc/runtime/Log.h>
+#include <xdc/runtime/Diags.h>
+
+#include <ti/sysbios/BIOS.h>
+#include <ti/sysbios/knl/Semaphore.h>
+#include <ti/sysbios/knl/Task.h>
+#include <ti/sysbios/hal/Hwi.h>
+#include <ti/sysbios/knl/Swi.h>
+#include <ti/sysbios/knl/Clock.h>
+#include <ti/sysbios/timers/dmtimer/Timer.h>
+#ifndef SMP
+#include <ti/sysbios/family/arm/ducati/omap4430/Power.h>
+#include <ti/sysbios/family/arm/ducati/Core.h>
+#include <ti/ipc/MultiProc.h>
+#else
+#include <ti/sysbios/family/arm/ducati/smp/Power.h>
+#endif
+
+#include <ti/pm/IpcPower.h>
+#include "_IpcPower.h"
+
+#define MASTERCORE                      1
+#define NO_MASTERCORE                   0
+#define CPU_COPY                       -1
+#define REG32(A)   (*(volatile UInt32 *) (A))
+
+#define SET_DEEPSLEEP (REG32(M3_SCR_REG) | (1 << DEEPSLEEP_BIT))
+#define CLR_DEEPSLEEP (REG32(M3_SCR_REG) & (~(1 << DEEPSLEEP_BIT)))
+
+#ifndef SMP
+#pragma DATA_SECTION(IpcPower_hibLocks, ".ipcpower_data")
+UInt32 IpcPower_hibLocks[2]; /* One lock for each of the IPU cores */
+#else
+static UInt32 IpcPower_hibLocks; /* Only one lock in SMP mode */
+#endif
+
+/* PM transition debug counters */
+UInt32 IpcPower_idleCount = 0;
+UInt32 IpcPower_suspendCount = 0;
+UInt32 IpcPower_resumeCount = 0;
+
+/* Clock function pointer to handle custom clock functions */
+Void *IpcPower_clockFxn = NULL;
+
+/* Handle to store BIOS Tick Timer */
+static Timer_Handle tickTimerHandle = NULL;
+
+static Power_SuspendArgs PowerSuspArgs;
+static Swi_Handle suspendResumeSwi;
+#ifndef SMP
+static Semaphore_Handle IpcPower_semSuspend = NULL;
+static Semaphore_Handle IpcPower_semExit = NULL;
+static Task_Handle IpcPower_tskSuspend = NULL;
+static UInt16 sysm3ProcId;
+static UInt16 appm3ProcId;
+#endif
+static Int32 refWakeLockCnt;
+
+/* List for storing all registered callback functions */
+static IpcPower_CallbackElem *IpcPower_callbackList = NULL;
+
+/* Module ref count: */
+static Int curInit = 0;
+
+typedef enum IpcPower_SleepMode {
+    IpcPower_SLEEP_MODE_DEEPSLEEP,
+    IpcPower_SLEEP_MODE_WAKELOCK,
+    IpcPower_SLEEP_MODE_WAKEUNLOCK
+} IpcPower_SleepMode;
+
+/* Deep sleep state variable for IpcPower module */
+static Bool IpcPower_deepSleep = TRUE;
+
+
+/*
+ *  ======== IpcPower_callUserFxns ========
+ */
+static Void IpcPower_callUserFxns(IpcPower_Event event)
+{
+    IpcPower_CallbackElem *node = IpcPower_callbackList;
+
+    /* Call the registered functions matching the event */
+    while (node != NULL) {
+        if (node->event == event) {
+            (*(node->callback))(event, node->data);
+        }
+        node = node->next;
+    }
+}
+
+static inline Void IpcPower_sleepMode(IpcPower_SleepMode opt)
+{
+    IArg hwiKey;
+
+    /* Set/Restore the DeepSleep bit if no timer already in use */
+    hwiKey = Hwi_disable();
+    switch (opt) {
+        case IpcPower_SLEEP_MODE_WAKEUNLOCK:
+            if (refWakeLockCnt) {
+                refWakeLockCnt--;
+            }
+        case IpcPower_SLEEP_MODE_DEEPSLEEP:
+            if (!refWakeLockCnt) {
+                IpcPower_deepSleep = TRUE;
+            }
+            break;
+        case IpcPower_SLEEP_MODE_WAKELOCK:
+            refWakeLockCnt++;
+            IpcPower_deepSleep = FALSE;
+            break;
+    }
+    Hwi_restore(hwiKey);
+}
+
+static inline Void IpcPower_setWugen()
+{
+    REG32(WUGEN_MEVT1) |= WUGEN_INT_MASK;
+}
+
+/*
+ *  ======== IpcPower_suspendSwi ========
+ */
+#define FXNN "IpcPower_suspendSwi"
+static Void IpcPower_suspendSwi(UArg arg0, UArg arg1)
+{
+#ifndef SMP
+    if (MultiProc_self() == sysm3ProcId) {
+#endif
+        Log_print0(Diags_INFO, FXNN":Core0 Hibernation Swi");
+#ifndef SMP
+        PowerSuspArgs.pmMasterCore = MASTERCORE;
+    }
+    else if (MultiProc_self() == appm3ProcId) {
+        Log_print0(Diags_INFO, FXNN":Core1 Hibernation Swi");
+        PowerSuspArgs.pmMasterCore = NO_MASTERCORE;
+    }
+#endif
+    if (refWakeLockCnt) {
+        System_printf("Warning: Wake locks in use\n");
+    }
+
+    Power_suspend(&PowerSuspArgs);
+#ifndef SMP
+    IpcPower_sleepMode(IpcPower_SLEEP_MODE_DEEPSLEEP);
+    IpcPower_setWugen();
+
+    Log_print0(Diags_INFO, FXNN":Resume");
+#endif
+}
+#undef FXNN
+
+/* =============================================================================
+ *  IpcPower Functions:
+ * =============================================================================
+ */
+
+#ifndef SMP
+/*
+ *  ======== IpcPower_suspendTaskFxn ========
+ */
+Void IpcPower_suspendTaskFxn(UArg arg0, UArg arg1)
+{
+    while (curInit) {
+        /* Wait for suspend notification from host-side */
+        Semaphore_pend(IpcPower_semSuspend, BIOS_WAIT_FOREVER);
+
+        if (curInit) {
+            /* Call pre-suspend preparation function */
+            IpcPower_preSuspend();
+
+            Swi_post(suspendResumeSwi);
+
+            /* Call post-resume preparation function */
+            IpcPower_postResume();
+        }
+    }
+
+    /* Signal the task end */
+    Semaphore_post(IpcPower_semExit);
+}
+#endif
+
+/*
+ *  ======== IpcPower_init ========
+ */
+Void IpcPower_init()
+{
+    Swi_Params swiParams;
+#ifndef SMP
+    Task_Params taskParams;
+    UInt coreIdx = Core_getId();
+#endif
+    Int i;
+    UArg arg;
+    UInt func;
+    Timer_Handle tHandle = NULL;
+
+    if (curInit++) {
+        return;
+    }
+
+#ifndef SMP
+    IpcPower_hibLocks[coreIdx] = 0;
+
+    sysm3ProcId = MultiProc_getId("CORE0");
+    appm3ProcId = MultiProc_getId("CORE1");
+#else
+    IpcPower_hibLocks = 0;
+#endif
+    refWakeLockCnt = 0;
+
+    for (i = 0; i < Timer_Object_count(); i++) {
+        tHandle = Timer_Object_get(NULL, i);
+        func = (UInt) Timer_getFunc(tHandle, &arg);
+        if (func && ((func == (UInt) ti_sysbios_knl_Clock_doTick__I) ||
+                     (func == (UInt) Clock_tick) ||
+                     (func == (UInt) IpcPower_clockFxn))) {
+            tickTimerHandle = tHandle;
+            break;
+        }
+    }
+    if (tickTimerHandle == NULL) {
+        System_abort("IpcPower_init: Cannot find tickTimer Handle. Custom"
+                        " clock timer functions currently not supported.\n");
+    }
+
+#ifndef SMP
+    IpcPower_semSuspend = Semaphore_create(0, NULL, NULL);
+    IpcPower_semExit = Semaphore_create(0, NULL, NULL);
+
+    Task_Params_init(&taskParams);
+    taskParams.priority = Task_numPriorities - 1; /* Highest priority */
+    taskParams.instance->name = "ti.pm.IpcPower_tskSuspend";
+    IpcPower_tskSuspend = Task_create(IpcPower_suspendTaskFxn, &taskParams,
+                                                                        NULL);
+#endif
+
+    Swi_Params_init(&swiParams);
+    swiParams.priority = Swi_numPriorities - 1; /* Max Priority Swi */
+    suspendResumeSwi = Swi_create(IpcPower_suspendSwi, &swiParams, NULL);
+
+    /*Power settings for saving/restoring context */
+    PowerSuspArgs.rendezvousResume = TRUE;
+    PowerSuspArgs.dmaChannel = CPU_COPY;
+    PowerSuspArgs.intMask31_0 = 0x0;
+#ifndef SMP
+    PowerSuspArgs.intMask63_32 = 0x0;
+#else
+    PowerSuspArgs.intMask63_32 = WUGEN_MAILBOX_BIT << 16;
+#endif
+    PowerSuspArgs.intMask79_64 = 0x0;
+    IpcPower_sleepMode(IpcPower_SLEEP_MODE_DEEPSLEEP);
+    IpcPower_setWugen();
+}
+
+/*
+ *  ======== IpcPower_exit ========
+ */
+Void IpcPower_exit()
+{
+    --curInit;
+
+    if (curInit == 0) {
+#ifndef SMP
+        /* Unblock PM suspend task */
+        Semaphore_post(IpcPower_semSuspend);
+
+        /* Wait for task completion */
+        Semaphore_pend(IpcPower_semExit, BIOS_WAIT_FOREVER);
+
+        /* Delete the suspend task and semaphore */
+        Task_delete(&IpcPower_tskSuspend);
+        Semaphore_delete(&IpcPower_semSuspend);
+        Semaphore_delete(&IpcPower_semExit);
+#endif
+    }
+}
+
+/*
+ *  ======== IpcPower_suspend ========
+ */
+Void IpcPower_suspend()
+{
+    Assert_isTrue((curInit > 0) , NULL);
+
+#ifndef SMP
+    Semaphore_post(IpcPower_semSuspend);
+#else
+    Swi_post(suspendResumeSwi);
+#endif
+}
+
+/*
+ *  ======== IpcPower_idle ========
+ */
+Void IpcPower_idle()
+{
+    IpcPower_idleCount++;
+
+    REG32(M3_SCR_REG) = IpcPower_deepSleep ? SET_DEEPSLEEP : CLR_DEEPSLEEP;
+    asm(" wfi");
+}
+
+/*
+ *  ======== IpcPower_wakeLock ========
+ */
+Void IpcPower_wakeLock()
+{
+    IpcPower_sleepMode(IpcPower_SLEEP_MODE_WAKELOCK);
+}
+
+/*
+ *  ======== IpcPower_wakeUnlock ========
+ */
+Void IpcPower_wakeUnlock()
+{
+    IpcPower_sleepMode(IpcPower_SLEEP_MODE_WAKEUNLOCK);
+}
+
+/*
+ *  ======== IpcPower_hibernateLock ========
+ */
+UInt IpcPower_hibernateLock()
+{
+    IArg hwiKey;
+#ifndef SMP
+    UInt coreIdx = Core_getId();
+#endif
+
+    hwiKey = Hwi_disable();
+
+#ifndef SMP
+    IpcPower_hibLocks[coreIdx] += 1;
+#else
+    IpcPower_hibLocks++;
+#endif
+
+    Hwi_restore(hwiKey);
+
+#ifndef SMP
+    return (IpcPower_hibLocks[coreIdx]);
+#else
+    return IpcPower_hibLocks;
+#endif
+}
+
+/*
+ *  ======== IpcPower_hibernateUnlock ========
+ */
+UInt IpcPower_hibernateUnlock()
+{
+    IArg hwiKey;
+#ifndef SMP
+    UInt coreIdx = Core_getId();
+#endif
+
+    hwiKey = Hwi_disable();
+
+#ifndef SMP
+    if (IpcPower_hibLocks[coreIdx] > 0) {
+        IpcPower_hibLocks[coreIdx] -= 1;
+    }
+#else
+    if (IpcPower_hibLocks > 0) {
+        IpcPower_hibLocks--;
+    }
+#endif
+
+    Hwi_restore(hwiKey);
+
+#ifndef SMP
+    return (IpcPower_hibLocks[coreIdx]);
+#else
+    return (IpcPower_hibLocks);
+#endif
+}
+
+/*
+ *  ======== IpcPower_canHibernate ========
+ */
+Bool IpcPower_canHibernate()
+{
+#ifndef SMP
+    if (IpcPower_hibLocks[0] || IpcPower_hibLocks[1]) {
+#else
+    if (IpcPower_hibLocks) {
+#endif
+        return (FALSE);
+    }
+
+    return (TRUE);
+}
+
+/*
+ *  ======== IpcPower_registerCallback ========
+ */
+#define FXNN "IpcPower_registerCallback"
+Int IpcPower_registerCallback(Int event, IpcPower_CallbackFuncPtr cbck,
+                              Ptr data)
+{
+    IArg hwiKey;
+    IpcPower_CallbackElem **list, *node;
+    BIOS_ThreadType context = BIOS_getThreadType();
+
+    if ((context != BIOS_ThreadType_Task) &&
+        (context != BIOS_ThreadType_Main)) {
+        Log_print0(Diags_ERROR, FXNN":Invalid context\n");
+        return (IpcPower_E_FAIL);
+    }
+
+    list = &IpcPower_callbackList;
+
+    /* Allocate and update new element */
+    node = Memory_alloc(NULL, sizeof(IpcPower_CallbackElem), 0, NULL);
+    if (node == NULL) {
+        Log_print0(Diags_ERROR, FXNN":out of memory\n");
+        return (IpcPower_E_MEMORY);
+    }
+
+    node->next     = NULL;
+    node->event    = (IpcPower_Event) event;
+    node->callback = cbck;
+    node->data     = data;
+
+    hwiKey = Hwi_disable();  /* begin: critical section */
+    while (*list != NULL) {
+        list = &(*list)->next;
+    }
+    *list = node;
+    Hwi_restore(hwiKey);  /* end: critical section */
+
+    return (IpcPower_S_SUCCESS);
+}
+#undef FXNN
+
+/*
+ *  ======== IpcPower_unregisterCallback ========
+ */
+#define FXNN "IpcPower_unregisterCallback"
+Int IpcPower_unregisterCallback(Int event, IpcPower_CallbackFuncPtr cbck)
+{
+    IArg hwiKey;
+    IpcPower_CallbackElem **list, *node;
+    Int status = IpcPower_E_FAIL;
+    BIOS_ThreadType context = BIOS_getThreadType();
+
+    if ((context != BIOS_ThreadType_Task) &&
+        (context != BIOS_ThreadType_Main)) {
+        Log_print0(Diags_ERROR, FXNN":Invalid context\n");
+        return (status);
+    }
+
+
+    list = &IpcPower_callbackList;
+    node  = NULL;
+
+    hwiKey = Hwi_disable();  /* begin: critical section */
+    while (*list != NULL) {
+        if ( ((*list)->callback == cbck) &&
+             ((*list)->event == event) ) {
+            node   = *list;
+            *list  = (*list)->next;
+            status = IpcPower_S_SUCCESS;
+            break;
+        }
+        list = &(*list)->next;
+    }
+    Hwi_restore(hwiKey);  /* end: critical section */
+
+    if (status == IpcPower_S_SUCCESS) {
+        if (node != NULL) {
+            Memory_free(NULL, node, sizeof(IpcPower_CallbackElem));
+        }
+        else {
+            Log_print0(Diags_ERROR, FXNN":Invalid pointer\n");
+        }
+    }
+
+    return (status);
+}
+#undef FXNN
+
+/*
+ *  ======== IpcPower_preSuspend ========
+ */
+Void IpcPower_preSuspend(Void)
+{
+    IpcPower_suspendCount++;
+
+    /* Call all user registered suspend callback functions */
+    IpcPower_callUserFxns(IpcPower_Event_SUSPEND);
+}
+
+/*
+ *  ======== IpcPower_postResume ========
+ */
+Void IpcPower_postResume(Void)
+{
+    /* Restore timer registers */
+    Timer_restoreRegisters(tickTimerHandle, NULL);
+    Timer_start(tickTimerHandle);
+
+    /* Call all user registered resume callback functions */
+    IpcPower_callUserFxns(IpcPower_Event_RESUME);
+
+    IpcPower_resumeCount++;
+}
diff --git a/packages/ti/pm/IpcPower.h b/packages/ti/pm/IpcPower.h
new file mode 100644 (file)
index 0000000..2b00436
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2011-2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** ============================================================================
+ *  @file       IpcPower.h
+ *  ============================================================================
+ */
+
+#ifndef ti_pm_IpcPower__include
+#define ti_pm_IpcPower__include
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* =============================================================================
+ *  Structures & Definitions
+ * =============================================================================
+ */
+
+/*!
+ *  @def    IpcPower_S_SUCCESS
+ *  @brief  Operation is successful.
+ */
+#define IpcPower_S_SUCCESS               0
+
+/*!
+ *  @def    IpcPower_E_FAIL
+ *  @brief  Operation is not successful.
+ */
+#define IpcPower_E_FAIL                  -1
+
+/*!
+ *  @def    IpcPower_E_MEMORY
+ *  @brief  Operation resulted in memory failure.
+ */
+#define IpcPower_E_MEMORY                -2
+
+/*!
+ *  @brief  Event types for power management callbacks
+ */
+typedef enum IpcPower_Event {
+    IpcPower_Event_SUSPEND  = 0, /*! Callback event for Power suspend */
+    IpcPower_Event_RESUME   = 1  /*! Callback event for Power resume  */
+} IpcPower_Event;
+
+/*!
+ *  @brief  Power Event Callback function type definition
+ */
+typedef Void (*IpcPower_CallbackFuncPtr)(Int event, Ptr data);
+
+/* =============================================================================
+ *  IpcPower Functions:
+ * =============================================================================
+ */
+
+/*!
+ *  @brief      Initialize the IpcPower module
+ *
+ *  @sa         IpcPower_exit
+ */
+Void IpcPower_init();
+
+/*!
+ *  @brief      Finalize the IpcPower module
+ *
+ *  @sa         IpcPower_init
+ */
+Void IpcPower_exit();
+
+/*!
+ *  @brief      Initiate the suspend procedure
+ */
+Void IpcPower_suspend();
+
+/*!
+ *  @brief      Disable the deep sleep mode in the core
+ *
+ *  @sa         IpcPower_wakeUnlock
+ */
+Void IpcPower_wakeLock();
+
+/*!
+ *  @brief      Enable the core to go to deep sleep mode
+ *
+ *  @sa         IpcPower_wakeLock
+ */
+Void IpcPower_wakeUnlock();
+
+/*!
+ *  @brief      Disable the core to go to suspend / hibernate
+ *
+ *  @sa         IpcPower_hibernateUnlock, IpcPower_canHibernate
+ */
+UInt IpcPower_hibernateLock();
+
+/*!
+ *  @brief      Enable the core to go to suspend / hibernate
+ *
+ *  @sa         IpcPower_hibernateLock, IpcPower_canHibernate
+ */
+UInt IpcPower_hibernateUnlock();
+
+/*!
+ *  @brief      Return TRUE if hibernation is allowed
+ *
+ *  @sa         IpcPower_hibernateLock, IpcPower_hibernateUnlock
+ */
+Bool IpcPower_canHibernate();
+
+/*!
+ *  @brief      Register callback function for a Power event
+ *
+ *  @param[in]  event  Power Management callback event type.
+ *  @param[in]  fxn    Function being registered.
+ *  @param[in]  data   Data to be passed as argument to function.
+ *
+ *  @Returns    Returns SUCCESS or FAIL
+ *
+ *  @sa         IpcPower_registerCallback
+ */
+Int IpcPower_registerCallback(Int event, IpcPower_CallbackFuncPtr fxn,
+                              Ptr data);
+
+/*!
+ *  @brief      Unregister callback function for a Power event
+ *
+ *  @param[in]  event  Power Management callback event type.
+ *  @param[in]  fxn    Function being unregistered.
+ *
+ *  @Returns    Returns SUCCESS or FAIL
+ *
+ *  @sa         IpcPower_unregisterCallback
+ */
+Int IpcPower_unregisterCallback(Int event, IpcPower_CallbackFuncPtr fxn);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* ti_ipc_IpcPower__include */
diff --git a/packages/ti/pm/IpcPowerDsp.c b/packages/ti/pm/IpcPowerDsp.c
new file mode 100644 (file)
index 0000000..905ab8e
--- /dev/null
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2012-2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** ============================================================================
+ *  @file       IpcPowerDsp.c
+ *
+ *  @brief      A simple Power Managment which responses to the host commands.
+ *
+ *  TODO:
+ *     - Add suspend/resume notifications
+ *  ============================================================================
+ */
+
+#include <xdc/std.h>
+#include <xdc/runtime/System.h>
+#include <xdc/runtime/Error.h>
+#include <xdc/runtime/Assert.h>
+#include <xdc/runtime/Memory.h>
+#include <xdc/runtime/Main.h>
+#include <xdc/runtime/Log.h>
+#include <xdc/runtime/Diags.h>
+
+#include <ti/sysbios/BIOS.h>
+#include <ti/sysbios/knl/Semaphore.h>
+#include <ti/sysbios/knl/Task.h>
+#include <ti/sysbios/hal/Hwi.h>
+#include <ti/sysbios/knl/Swi.h>
+#include <ti/sysbios/knl/Clock.h>
+#include <ti/sysbios/timers/dmtimer/Timer.h>
+#include <ti/sysbios/family/c64p/tesla/Power.h>
+#include <ti/sysbios/family/c64p/tesla/Wugen.h>
+#include <ti/sysbios/family/c64p/tesla/package/internal/Power.xdc.h>
+
+#include <ti/ipc/MultiProc.h>
+
+#include <ti/pm/IpcPower.h>
+#include "_IpcPower.h"
+
+#define REG32(A)   (*(volatile UInt32 *) (A))
+
+static UInt32 IpcPower_hibLock;
+
+#define PDCCMD_REG      0x01810000
+#define SLEEP_MODE      0x15555
+#define GPT5_IRQ        51
+#define GPT6_IRQ        52
+#define MBX_DSP_IRQ     55
+
+static Swi_Handle suspendResumeSwi;
+static Semaphore_Handle IpcPower_semSuspend = NULL;
+static Semaphore_Handle IpcPower_semExit = NULL;
+static Task_Handle IpcPower_tskSuspend = NULL;
+
+/* List for storing all registered callback functions */
+static IpcPower_CallbackElem *IpcPower_callbackList = NULL;
+
+/* Module ref count: */
+static Int curInit = 0;
+
+/* PM transition debug counters */
+UInt32 IpcPower_idleCount = 0;
+UInt32 IpcPower_suspendCount = 0;
+UInt32 IpcPower_resumeCount = 0;
+
+/* Clock function pointer to handle custom clock functions */
+Void *IpcPower_clockFxn = NULL;
+
+/* Handle to store BIOS Tick Timer */
+static Timer_Handle tickTimerHandle = NULL;
+
+/*
+ *  ======== IpcPower_callUserFxns ========
+ */
+static Void IpcPower_callUserFxns(IpcPower_Event event)
+{
+    IpcPower_CallbackElem *node = IpcPower_callbackList;
+
+    /* Call the registered functions matching the event */
+    while (node != NULL) {
+        if (node->event == event) {
+            (*(node->callback))(event, node->data);
+        }
+        node = node->next;
+    }
+}
+
+/*
+ *  ======== IpcPower_suspendSwi ========
+ */
+static Void IpcPower_suspendSwi(UArg arg0, UArg arg1)
+{
+    /* Disable wakeup events */
+    Wugen_disableEvent(GPT5_IRQ);
+    Wugen_disableEvent(GPT6_IRQ);
+    Wugen_disableEvent(MBX_DSP_IRQ);
+
+    /* Invoke the BIOS suspend routine */
+    Power_suspend(Power_Suspend_HIBERNATE);
+
+    /* Re-enable wakeup events */
+    Wugen_enableEvent(GPT5_IRQ);
+    Wugen_enableEvent(GPT6_IRQ);
+    Wugen_enableEvent(MBX_DSP_IRQ);
+}
+
+/*
+ * =============================================================================
+ *  IpcPower Functions:
+ * =============================================================================
+ */
+
+/*
+ *  ======== IpcPower_suspendTaskFxn ========
+ */
+Void IpcPower_suspendTaskFxn(UArg arg0, UArg arg1)
+{
+    while (curInit) {
+        /* Wait for suspend notification from host-side */
+        Semaphore_pend(IpcPower_semSuspend, BIOS_WAIT_FOREVER);
+
+        if (curInit) {
+            /* Call pre-suspend preparation function */
+            IpcPower_preSuspend();
+
+            Swi_post(suspendResumeSwi);
+
+            /* Call post-resume preparation function */
+            IpcPower_postResume();
+        }
+    }
+
+    /* Signal the task end */
+    Semaphore_post(IpcPower_semExit);
+}
+
+/*
+ *  ======== IpcPower_init ========
+ */
+Void IpcPower_init()
+{
+    Swi_Params swiParams;
+    Task_Params taskParams;
+    Int i;
+    UArg arg;
+    UInt func;
+    Timer_Handle tHandle = NULL;
+
+    if (curInit++) {
+        return;
+    }
+
+    IpcPower_hibLock = 0;
+
+    for (i = 0; i < Timer_Object_count(); i++) {
+        tHandle = Timer_Object_get(NULL, i);
+        func = (UInt) Timer_getFunc(tHandle, &arg);
+        if (func && ((func == (UInt) ti_sysbios_knl_Clock_doTick__I) ||
+                     (func == (UInt) Clock_tick) ||
+                     (func == (UInt) IpcPower_clockFxn))) {
+            tickTimerHandle = tHandle;
+            break;
+        }
+    }
+    if (tickTimerHandle == NULL) {
+        System_abort("IpcPower_init: Cannot find tickTimer Handle. Custom"
+                        " clock timer functions currently not supported.\n");
+    }
+
+    IpcPower_semSuspend = Semaphore_create(0, NULL, NULL);
+    IpcPower_semExit = Semaphore_create(0, NULL, NULL);
+
+    Task_Params_init(&taskParams);
+    taskParams.priority = Task_numPriorities - 1; /* Highest priority */
+    taskParams.instance->name = "ti.pm.IpcPower_tskSuspend";
+    IpcPower_tskSuspend = Task_create(IpcPower_suspendTaskFxn, &taskParams,
+                                                                        NULL);
+
+    Swi_Params_init(&swiParams);
+    swiParams.priority = Swi_numPriorities - 1; /* Max Priority Swi */
+    suspendResumeSwi = Swi_create(IpcPower_suspendSwi, &swiParams, NULL);
+}
+
+/*
+ *  ======== IpcPower_exit ========
+ */
+Void IpcPower_exit()
+{
+    --curInit;
+
+    if (curInit == 0) {
+        /* Unblock PM suspend task */
+        Semaphore_post(IpcPower_semSuspend);
+
+        /* Wait for task completion */
+        Semaphore_pend(IpcPower_semExit, BIOS_WAIT_FOREVER);
+
+        /* Delete the suspend task and semaphore */
+        Task_delete(&IpcPower_tskSuspend);
+        Semaphore_delete(&IpcPower_semSuspend);
+        Semaphore_delete(&IpcPower_semExit);
+    }
+}
+
+/*
+ *  ======== IpcPower_suspend ========
+ */
+Void IpcPower_suspend()
+{
+    Assert_isTrue((curInit > 0) , NULL);
+
+    Semaphore_post(IpcPower_semSuspend);
+}
+
+/*
+ *  ======== IpcPower_idle ========
+ */
+Void IpcPower_idle()
+{
+    IpcPower_idleCount++;
+
+    REG32(PDCCMD_REG) = SLEEP_MODE;
+    REG32(PDCCMD_REG);
+
+    /* Enable wakeup events */
+    Wugen_enableEvent(GPT5_IRQ);
+    Wugen_enableEvent(GPT6_IRQ);
+    Wugen_enableEvent(MBX_DSP_IRQ);
+
+    asm(" idle");
+}
+
+/*
+ *  ======== IpcPower_hibernateLock ========
+ */
+UInt IpcPower_hibernateLock()
+{
+    IArg hwiKey, swiKey;
+
+    hwiKey = Hwi_disable();
+    swiKey = Swi_disable();
+
+    IpcPower_hibLock++;
+
+    Swi_restore(swiKey);
+    Hwi_restore(hwiKey);
+
+    return (IpcPower_hibLock);
+}
+
+/*
+ *  ======== IpcPower_hibernateUnlock ========
+ */
+UInt IpcPower_hibernateUnlock()
+{
+    IArg hwiKey, swiKey;
+
+    hwiKey = Hwi_disable();
+    swiKey = Swi_disable();
+
+    if (IpcPower_hibLock > 0) {
+        IpcPower_hibLock--;
+    }
+
+    Swi_restore(swiKey);
+    Hwi_restore(hwiKey);
+
+    return (IpcPower_hibLock);
+}
+
+
+/*
+ *  ======== IpcPower_canHibernate ========
+ */
+Bool IpcPower_canHibernate()
+{
+    if (IpcPower_hibLock) {
+        return (FALSE);
+    }
+
+    return (TRUE);
+}
+
+/*
+ *  ======== IpcPower_registerCallback ========
+ */
+#define FXNN "IpcPower_registerCallback"
+Int IpcPower_registerCallback(Int event, IpcPower_CallbackFuncPtr cbck,
+                              Ptr data)
+{
+    IArg hwiKey;
+    IpcPower_CallbackElem **list, *node;
+    BIOS_ThreadType context = BIOS_getThreadType();
+
+    if ((context != BIOS_ThreadType_Task) &&
+        (context != BIOS_ThreadType_Main)) {
+        Log_print0(Diags_ERROR, FXNN":Invalid context\n");
+        return (IpcPower_E_FAIL);
+    }
+
+    list = &IpcPower_callbackList;
+
+    /* Allocate and update new element */
+    node = Memory_alloc(NULL, sizeof(IpcPower_CallbackElem), 0, NULL);
+    if (node == NULL) {
+        Log_print0(Diags_ERROR, FXNN":out of memory\n");
+        return (IpcPower_E_MEMORY);
+    }
+
+    node->next     = NULL;
+    node->event    = (IpcPower_Event) event;
+    node->callback = cbck;
+    node->data     = data;
+
+    hwiKey = Hwi_disable();  /* begin: critical section */
+    while (*list != NULL) {
+        list = &(*list)->next;
+    }
+    *list = node;
+    Hwi_restore(hwiKey);  /* end: critical section */
+
+    return (IpcPower_S_SUCCESS);
+}
+#undef FXNN
+
+/*
+ *  ======== IpcPower_unregisterCallback ========
+ */
+#define FXNN "IpcPower_unregisterCallback"
+Int IpcPower_unregisterCallback(Int event, IpcPower_CallbackFuncPtr cbck)
+{
+    IArg hwiKey;
+    IpcPower_CallbackElem **list, *node;
+    Int status = IpcPower_E_FAIL;
+    BIOS_ThreadType context = BIOS_getThreadType();
+
+    if ((context != BIOS_ThreadType_Task) &&
+        (context != BIOS_ThreadType_Main)) {
+        Log_print0(Diags_ERROR, FXNN":Invalid context\n");
+        return (status);
+    }
+
+    list = &IpcPower_callbackList;
+    node  = NULL;
+
+    hwiKey = Hwi_disable();  /* begin: critical section */
+    while (*list != NULL) {
+        if ( ((*list)->callback == cbck) &&
+             ((*list)->event == event) ) {
+            node   = *list;
+            *list  = (*list)->next;
+            status = IpcPower_S_SUCCESS;
+            break;
+        }
+        list = &(*list)->next;
+    }
+    Hwi_restore(hwiKey);  /* end: critical section */
+
+    if (status == IpcPower_S_SUCCESS) {
+        if (node != NULL) {
+            Memory_free(NULL, node, sizeof(IpcPower_CallbackElem));
+        }
+        else {
+            Log_print0(Diags_ERROR, FXNN":Invalid pointer\n");
+        }
+    }
+
+    return (status);
+}
+#undef FXNN
+
+/*
+ *  ======== IpcPower_preSuspend ========
+ */
+Void IpcPower_preSuspend(Void)
+{
+    IpcPower_suspendCount++;
+
+    /* Call all user registered suspend callback functions */
+    IpcPower_callUserFxns(IpcPower_Event_SUSPEND);
+}
+
+/*
+ *  ======== IpcPower_postResume ========
+ */
+Void IpcPower_postResume(Void)
+{
+    /* Restore timer registers */
+    Timer_restoreRegisters(tickTimerHandle, NULL);
+    Timer_start(tickTimerHandle);
+
+    /* Call all user registered resume callback functions */
+    IpcPower_callUserFxns(IpcPower_Event_RESUME);
+
+    IpcPower_resumeCount++;
+}
diff --git a/packages/ti/pm/_IpcPower.h b/packages/ti/pm/_IpcPower.h
new file mode 100644 (file)
index 0000000..3edd596
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2011-2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/** ============================================================================
+ *  @file       _IpcPower.h
+ *  ============================================================================
+ */
+
+#ifndef ti_pm__IpcPower__include
+#define ti_pm__IpcPower__include
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* =============================================================================
+ *  Structures & Definitions
+ * =============================================================================
+ */
+
+#define MIRQ34_SHIFT                    2
+#define MIRQ37_SHIFT                    5
+#define MIRQ38_SHIFT                    6
+#define MIRQ39_SHIFT                    7
+
+#define WUGEN_MAILBOX_BIT               (1 << MIRQ34_SHIFT)
+#define WUGEN_GPT3_BIT                  (1 << MIRQ37_SHIFT)
+#define WUGEN_GPT4_BIT                  (1 << MIRQ38_SHIFT)
+#define WUGEN_GPT9_BIT                  (1 << MIRQ39_SHIFT)
+
+/* Wake-up masks for interrupts 00-31 */
+#define WUGEN_MEVT0                     0x4000100C
+/* Wake-up masks for interrupts 32-63 */
+#define WUGEN_MEVT1                     0x40001010
+
+/* Enable Mailbox, GPT3, and GPT4 interrupts as Wakeup sources */
+#define WUGEN_INT_MASK                  (WUGEN_MAILBOX_BIT | \
+                                         WUGEN_GPT3_BIT    | \
+                                         WUGEN_GPT4_BIT)
+
+#define M3_SCR_REG                      0xE000ED10
+
+#define SLEEPONEXIT_BIT                 1
+#define DEEPSLEEP_BIT                   2
+#define SEVONPEND_BIT                   4
+
+/* User registered functions storage element */
+typedef struct IpcPower_CallbackElem {
+    IpcPower_Event                  event;
+    IpcPower_CallbackFuncPtr        callback;
+    Ptr                             data;
+    struct IpcPower_CallbackElem    *next;
+} IpcPower_CallbackElem;
+
+/* Pre-suspend function managing user callbacks */
+Void IpcPower_preSuspend(Void);
+
+/* Post-suspend function managing user callbacks */
+Void IpcPower_postResume(Void);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* ti_ipc__IpcPower__include */
diff --git a/packages/ti/pm/package.bld b/packages/ti/pm/package.bld
new file mode 100644 (file)
index 0000000..bb9268c
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2011-2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  ======== package.bld ========
+ *
+ */
+
+/* explicit references to global objects */
+var Build = xdc.useModule('xdc.bld.BuildEnvironment');
+var Pkg = xdc.useModule('xdc.bld.PackageContents');
+var smpBuild = java.lang.System.getenv("BUILD_SMP");
+
+/* clean lib folder */
+Pkg.generatedFiles.$add("lib/");
+Pkg.libDir = "package/";
+
+/* add custom files to all releases */
+Pkg.attrs.exportSrc = false;
+Pkg.attrs.exportCfg = true;
+Pkg.otherFiles = [
+    "IpcPower.h"
+];
+
+/* list of libraries to build */
+var libArray = new Array();
+if (smpBuild == "1") {
+    /* pm library for IPU SMP target */
+    libArray.push(
+        {
+            name: "ti.pm_smp",
+            sources: [
+                "IpcPower",
+            ],
+            libAttrs: {
+                defs: " -DSMP"
+            },
+            isas: [ "v7M" ],
+        }
+    );
+}
+else {
+    /* pm library for IPU non-SMP target */
+    libArray.push(
+        {
+            name: "ti.pm",
+            sources: [
+                "IpcPower",
+            ],
+            isas: [ "v7M" ],
+        }
+    );
+
+    /* pm library for DSP target */
+    libArray.push(
+        {
+            name: "ti.pm",
+            sources: [
+                "IpcPowerDsp",
+            ],
+            isas: [ "64T" ],
+        }
+    );
+}
+
+/* generate the package libraries */
+/* check if profile specified in XDCARGS */
+/* XDCARGS="... profile=debug ..." */
+var cmdlProf = (" " + arguments.join(" ") + " ").match(/ profile=([^ ]+) /);
+cmdlProf = cmdlProf != null ? cmdlProf[1] : null;
+
+/* ==== loop over array of libraries ==== */
+for (var i = 0; i < libArray.length; i++) {
+    var lib = libArray[i];
+
+    /* ==== loop over all targets in build array ==== */
+    for (var j = 0; j < Build.targets.length; j++) {
+        var targ = Build.targets[j];
+
+        /* skip target if not compatible with source code */
+        if ("icw" in lib) {
+            var skipTarget = true;
+            var targIsaChain = "/" + targ.getISAChain().join("/") + "/";
+            for (var k = 0; k < lib.icw.length; k++) {
+                if (targIsaChain.match("/" + lib.icw[k] + "/")) {
+                    skipTarget = false;
+                    break;
+                }
+            }
+            if (skipTarget) continue;
+        }
+
+        /* skip target if it does not generate code for the given isa */
+        if ("isas" in lib) {
+            var skipTarget = true;
+            var list = "/" + lib.isas.join("/") + "/";
+            if (list.match("/" + targ.isa + "/")) {
+                skipTarget = false;
+            }
+            if (skipTarget) continue;
+        }
+
+        /* ==== loop over all profiles ==== */
+        for (var profile in targ.profiles) {
+
+            /* skip profile if different than specified on command line */
+            if ((cmdlProf != null) && (profile != cmdlProf)) {
+                continue;
+            }
+
+            /* name = lib/profile/name.a+suffix */
+            var name = "lib/" + profile + "/" + lib.name;
+
+            /* pass along library attributes specified in library array */
+            var libAttrs = "libAttrs" in lib ? lib.libAttrs : {};
+
+            /* must set profile explicitly */
+            libAttrs.profile = profile;
+
+            /* build the library */
+            var library = Pkg.addLibrary(name, targ, libAttrs);
+
+            /* add the source files */
+            library.addObjects(lib.sources);
+        }
+    }
+}
diff --git a/packages/ti/pm/package.xdc b/packages/ti/pm/package.xdc
new file mode 100644 (file)
index 0000000..ab3682c
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ *  ======== package.xdc ========
+ *
+ */
+
+/*!
+ *  ======== ti.pm ========
+ *  Inter processor communication Power Manager.
+ *
+ *  Contains modules that enable the Suspend and Resume of the slave
+ *  processors.
+ *
+ */
+
+package ti.pm [1,0,0,0] {
+}
diff --git a/packages/ti/pm/package.xs b/packages/ti/pm/package.xs
new file mode 100644 (file)
index 0000000..29d5d9b
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2011-2013, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * *  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * *  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * *  Neither the name of Texas Instruments Incorporated nor the names of
+ *    its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  ======== package.xs ========
+ *
+ */
+
+/*
+ *  ======== init ========
+ */
+function init()
+{
+    if (Program.build.target.name.match(/C64T/)) {
+        var Power = xdc.useModule('ti.sysbios.family.c64p.tesla.Power');
+    }
+
+    /* plug-in the power event hooks for SMP/BIOS */
+    if (Program.build.target.name.match(/M3/) &&
+        Program.platformName.match(/ipu/)) {
+        var Power = xdc.useModule('ti.sysbios.family.arm.ducati.smp.Power');
+        Power.preSuspendHooks.$add("&IpcPower_preSuspend");
+        Power.postSuspendHooks.$add("&IpcPower_postResume");
+    }
+
+    if (Program.build.target.name.match(/M3/) &&
+        !Program.platformName.match(/ipu/)) {
+        Program.sectMap[".ipcpower_data"] = new Program.SectionSpec();
+        Program.sectMap[".ipcpower_data"].type = "NOINIT";
+        Program.sectMap[".ipcpower_data"].loadAddress = 0x2100;
+    }
+}
+
+/*
+ *  ======== close ========
+ */
+function close()
+{
+    Program.exportModule('ti.sysbios.knl.Idle');
+}
+
+/*
+ *  ======== getLibs ========
+ */
+function getLibs(prog)
+{
+    var suffix;
+    var file;
+    var libAry = [];
+    var profile = this.profile;
+    var smp = "";
+
+    suffix = prog.build.target.findSuffix(this);
+    if (suffix == null) {
+        return "";  /* nothing to contribute */
+    }
+
+    if (prog.platformName.match(/ipu/)) {
+        smp = "_smp";
+    }
+
+    /* make sure the library exists, else fallback to a built library */
+    file = "lib/" + profile + "/ti.pm" + smp + ".a" + suffix;
+    if (java.io.File(this.packageBase + file).exists()) {
+        libAry.push(file);
+    }
+    else {
+        file = "lib/release/ti.pm" + smp + ".a" + suffix;
+        if (java.io.File(this.packageBase + file).exists()) {
+            libAry.push(file);
+        }
+        else {
+            /* fallback to a compatible library built by this package */
+            for (var p in this.build.libDesc) {
+                if (suffix == this.build.libDesc[p].suffix) {
+                    libAry.push(p);
+                    break;
+                }
+            }
+        }
+    }
+
+    return libAry.join(";");
+}