kernel/eka/include/drivers/smppower/idlehelper.h
branchRCL_3
changeset 44 3e88ff8f41d5
parent 43 c1f20ce4abcf
child 45 9e2d4f7f5028
equal deleted inserted replaced
43:c1f20ce4abcf 44:3e88ff8f41d5
     1 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL " http://www.eclipse.org/legal/epl-v10.html ".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // os\kernelhwsrv\kernel\eka\include\drivers\smppower\idlehelper.h
       
    15 // Helper classes required to implement CPU idle
       
    16 // functionality in a SMP BSP.
       
    17 
       
    18 
       
    19 /**
       
    20  @file
       
    21  @prototype
       
    22 */
       
    23 
       
    24 #ifndef __SMP_IDLE_HELPER_H__
       
    25 #define __SMP_IDLE_HELPER_H__
       
    26 
       
    27 #define __PM_IDLE_ASSERT_ALWAYS(aCond) \
       
    28 	__ASSERT_ALWAYS( (aCond), \
       
    29 		( \
       
    30 			Kern::Printf("Assertion '" #aCond "' failed;\nFile: '" __FILE__ "' Line: %d\n", __LINE__), \
       
    31 			Kern::Fault("TIdleSupport", 1) \
       
    32 		) )
       
    33 
       
    34 #define __PM_IDLE_ASSERT_DEBUG(aCond) \
       
    35 	__ASSERT_DEBUG( (aCond), \
       
    36 		( \
       
    37 			Kern::Printf("Assertion '" #aCond "' failed;\nFile: '" __FILE__ "' Line: %d\n", __LINE__), \
       
    38 			Kern::Fault("TIdleSupport", 1) \
       
    39 		) )
       
    40 
       
    41 
       
    42 
       
    43 #ifdef __SMP__
       
    44 
       
    45 #include <kernel/kpower.h>
       
    46 #include <e32btrace.h>
       
    47 #include <arm_gic.h>
       
    48 #include <kernel.h>
       
    49 #include <nk_priv.h>
       
    50 #include <nk_plat.h>
       
    51 
       
    52 
       
    53 const TUint32 KNoInterruptsPending = 1023;
       
    54 
       
    55 
       
    56 // Temp place holder for TRACE Categories
       
    57 const TInt KIsrPendingCat = 128;
       
    58 const TInt KPrintReg = 129;
       
    59 const TInt KIdleEntry = 130;
       
    60 const TUint8 KIdleEntryNormalCpu = 0x10;
       
    61 const TUint8 KIdleEntryLastCpu = 0;
       
    62 const TInt KIdleeXit = 131;
       
    63 const TUint8 KIdleeXitLastCpu0 = 0x1;
       
    64 const TUint8 KIdleeXitLastCpu1 = 0x1;
       
    65 const TUint8 KIdleeXitNormalCpu0 = 0x10;
       
    66 const TUint8 KIdleeXitNormalCpu1 = 0x11;
       
    67 const TInt KSyncPoint = 132;
       
    68 const TUint8 KSignalAndWaitFnEntry = 0x10;
       
    69 const TUint8 KSignalAndWaitFneXit = 0x11;
       
    70 const TUint8 KSignalAndWaitEntry = 0x0;
       
    71 const TUint8 KSignalAndWaiteXit = 0x1;
       
    72 const TInt KClearIPI = 133;
       
    73 const TInt KSendIPI = 134;
       
    74 const TInt KMisc=135;
       
    75 const TInt KIdleTickSupression=136;
       
    76 const TUint8 KCyclesInTickCyclesFullTick = 0x0;
       
    77 const TUint8 KNextInterrupt = 0x1;
       
    78 const TUint8 KTimeSleptTimeNextInt = 0x2;
       
    79 const TUint8 KTIcksSlept = 0x3;
       
    80 const TInt  KRetireCore=137;
       
    81 const TUint8 KRetireCoreEntry = 0x1;
       
    82 const TUint8 KRetireCoreeXit = 0x2;
       
    83 const TUint8 KRetireMarkCoreRetired = 0x3;
       
    84 const TInt  KEngageCore=138;
       
    85 const TUint8 KEngageMarkCoreEngaged = 0x3;
       
    86 const TInt KNTICK = 139;
       
    87 
       
    88 // End of Trace categories
       
    89 
       
    90 //#define DISABLE_TRACE
       
    91 #if defined(_DEBUG) && !defined(DISABLE_TRACE)
       
    92 
       
    93 #define PMBTRACE0(c,s) BTrace0((c),(s))
       
    94 #define PMBTRACE4(c,s,a1) BTrace4((c),(s),(a1))
       
    95 #define PMBTRACE8(c,s,a1,a2) BTrace8((c),(s),(a1),(a2))
       
    96 
       
    97 #else
       
    98 
       
    99 #define PMBTRACE0(c,s)
       
   100 #define PMBTRACE4(c,s,a1) 
       
   101 #define PMBTRACE8(c,s,a1,a2) 
       
   102 
       
   103 #endif
       
   104 
       
   105 //This will be defined in kernel header file nk_plat.h in the future
       
   106 #ifndef IDLE_WAKEUP_IPI_VECTOR
       
   107 #define IDLE_WAKEUP_IPI_VECTOR 0x07
       
   108 #endif
       
   109 
       
   110 
       
   111 #ifdef _DEBUG
       
   112 
       
   113 #define SYNCPOINT(obj,stage) (obj).SignalAndWait(stage) 
       
   114 
       
   115 #else
       
   116 
       
   117 #define SYNCPOINT(obj,stage) (obj).SignalAndWait()
       
   118 
       
   119 #endif//_DEBUG
       
   120 
       
   121 #define PROPER_WFI		//if defined uses ARM_WFI state otherwise a wait in loop
       
   122 #define SYNCPOINT_WFE 	//Sync Points use WFE and SEV
       
   123 
       
   124 //Base class for all sync points
       
   125 class TSyncPointBase
       
   126     {
       
   127 public:
       
   128     TSyncPointBase();
       
   129 #ifdef _DEBUG
       
   130     void SignalAndWait(TUint32 aStage);
       
   131 #else
       
   132     void SignalAndWait();
       
   133 #endif
       
   134     void Reset();
       
   135 protected:
       
   136     virtual void DoSW(TUint32 aCpuMask) = 0;
       
   137 public:
       
   138     volatile TUint32 iStageAndCPUWaitingMask;    // upper 16 are the stage and lower 16 are cpus waiting mask
       
   139     volatile TUint32* iAllEnagedCpusMask;
       
   140    };
       
   141 
       
   142     
       
   143 // Auto reseting sync point. Can not be broken. 
       
   144 class TSyncPoint : public TSyncPointBase
       
   145     {
       
   146 private:
       
   147     void DoSW(TUint32 aCpuMask);
       
   148     };
       
   149 
       
   150 // Very similar to normal breakpoint except that:
       
   151 // 1. It does not autoreset between calls, therefore a call to Reset is required between
       
   152 //    syncs.
       
   153 // 2. It can be broken. That is a call to Break will result in any cpu currently waiting on the point
       
   154 //    to be freed inmediatelly, and attempt to start to wait on the point to return inmediatelly. This
       
   155 //    condition remains until reset is called once more
       
   156 class TBreakableSyncPoint : public TSyncPointBase
       
   157     {
       
   158 public:
       
   159     void Break();
       
   160 private:
       
   161     void DoSW(TUint32 aCpuMask);
       
   162 };
       
   163 
       
   164 //Helper class for idle handler support to be used in smp bsp
       
   165 class TIdleSupport
       
   166 	{
       
   167 public:
       
   168 	static void SetupIdleSupport(TUint32 aGlobalIntDistAddress, TUint32 aBaseIntIfAddress, TUint32* aTimerCount=0);//setup GIC gid and cif base addresses
       
   169 	static void SetIdleIPIToHighestPriority();//sets idle IPI priority to be the highest
       
   170 	static void DoIdleIPI(TUint32);
       
   171 	static void ClearIdleIPI();
       
   172 	static void DoWFI();//puts current CPU in wait for interrupt state
       
   173 	static TBool IsIntPending();
       
   174 	static TInt	IntPending();
       
   175 	static TUint32 GetTimerCount();//HW timer can be used for tracing
       
   176 	//Atomic checks used to synchronise cores going idle
       
   177 	static TBool ClearLocalAndCheckGlobalIdle(TUint32);
       
   178 	static TBool SetLocalAndCheckSetGlobalIdle(TUint32);
       
   179 	static TBool FirstCoreAwake(TUint32);
       
   180     // Retiring Cores
       
   181     static void MarkCoreRetired(TUint32);
       
   182     static void MarkCoreEngaged(TUint32);
       
   183 	//Exit methods for sync points
       
   184 	static void SetExitRequired(TBreakableSyncPoint* aBreakSyncPoint=0);
       
   185 	static TBool GetExitRequired();	
       
   186 	static void  ResetLogic();//Reset helper class flags
       
   187 	static TUint32 GetCpusIdleMask();//gets bit mask containing idling CPU's
       
   188     static volatile TUint32* EngagedCpusMaskAddr();
       
   189     static TUint32 AllCpusMask();
       
   190 private:
       
   191     static TInt DoClearIdleIPI();
       
   192 private:
       
   193     static const TUint32 KGlobalIdleFlag = 0x8000000;
       
   194 	static volatile TUint32 iAllEngagedCpusMask;
       
   195 	static volatile TUint32 iIdlingCpus;//contains CPU's idle handler waiting to go idle
       
   196     static volatile TUint32 iRousingCpus;////contains CPU's waking up
       
   197 	static volatile TUint32 iExitRequired;
       
   198 	static TUint iGlobalIntDistAddress;//base address of gloabl interrupt dispatcher
       
   199 	static TUint iBaseIntIfAddress;//base address of CPu interrupt interface
       
   200 	static volatile TUint32* iTimerCount;//timer count register provided by bsp for tracing	
       
   201 	};
       
   202 
       
   203 
       
   204 #endif //__SMP__
       
   205 
       
   206 #endif //__SMP_IDLE_HELPER_H__
       
   207