diff -r a179b74831c9 -r c1f20ce4abcf kernel/eka/include/nkernsmp/arm/ncern.h --- a/kernel/eka/include/nkernsmp/arm/ncern.h Thu Aug 19 11:14:22 2010 +0300 +++ b/kernel/eka/include/nkernsmp/arm/ncern.h Tue Aug 31 16:34:26 2010 +0300 @@ -75,20 +75,45 @@ TLinAddr iInitR13Und; // initial value for R13_und }; - -/** Timer frequency specification +typedef void (*TDetachComplete)(void); -Stores a frequency as a fraction of a (separately stored) maximum. -The frequency must be at least 1/256 of the maximum. +struct SPerCpuUncached + { + volatile TUint32 iDetachCount; // Number of times core has detached from SMP cluster + volatile TUint32 iAttachCount; // Number of times core has reattached to SMP cluster + volatile TBool iPowerOffReq; // TRUE if core needs to be powered off + volatile TBool iPowerOnReq; // TRUE if core needs to be powered on + TDetachComplete iDetachCompleteFn; // idle handler jumps to this to request power down if necessary + // after cleaning and disabling caches, detaching from SMP cluster + // and saving state required to bring the core back up again + volatile TUint32 iDetachCompleteCpus; + }; -@internalTechnology +union UPerCpuUncached + { + SPerCpuUncached iU; + volatile TUint64 i__Dummy[8]; + }; + +__ASSERT_COMPILE(sizeof(SPerCpuUncached) <= 8*sizeof(TUint64)); + +/** Function to power up a CPU +@publishedPartner @prototype */ -struct STimerMult - { - TUint32 iFreq; // frequency as a fraction of maximum possible, multiplied by 2^32 - TUint32 iInverse; // 2^24/(iFreq/2^32) = 2^56/iFreq - }; +typedef void (*TCpuPowerUpFn)(TInt aCpu, SPerCpuUncached* aU); + +/** Function to power down a CPU +@publishedPartner +@prototype +*/ +typedef void (*TCpuPowerDownFn)(TInt aCpu, SPerCpuUncached* aU); + +/** Function to notify changes to system clock frequencies +@publishedPartner +@prototype +*/ +typedef TInt (*TFrequencyChangeFn)(); /** Variant interface block @internalTechnology @@ -104,8 +129,14 @@ TLinAddr iGicDistAddr; // address of GIC Distributor TLinAddr iGicCpuIfcAddr; // address of GIC CPU interface (must be same for all CPUs) TLinAddr iLocalTimerAddr; // address of per-CPU timer (must be same for all CPUs) - volatile STimerMult* iTimerMult[KMaxCpus]; // timer[i] frequency / iMaxTimerClock * 2^32 - volatile TUint32* iCpuMult[KMaxCpus]; // CPU[i] frequency / iMaxCpuClock * 2^32 + TLinAddr iGlobalTimerAddr; // address of global timer if it exists + SRatio* iTimerFreqR[KMaxCpus]; // timer[i] frequency as a fraction of iMaxTimerClock + SRatio* iCpuFreqR[KMaxCpus]; // CPU[i] frequency as a fraction of iMaxCpuClock + UPerCpuUncached* iUncached[KMaxCpus]; // Pointer to uncached memory for each CPU + TCpuPowerUpFn iCpuPowerUpFn; // function used to power up a retired CPU (NULL if core control not supported) + TCpuPowerDownFn iCpuPowerDownFn; // function used to power down a CPU (NULL if power down done within idle handler itself) + SRatio* iGTimerFreqR; // global timer frequency as a fraction of iMaxTimerClock + TFrequencyChangeFn iFrqChgFn; // function to notify frequency changes }; // End of file