--- a/perfsrv/piprofiler/plugins/GeneralsPlugin/src/GeneralsDriver.cpp Fri Oct 08 14:56:39 2010 +0300
+++ b/perfsrv/piprofiler/plugins/GeneralsPlugin/src/GeneralsDriver.cpp Tue Oct 26 16:20:32 2010 +0300
@@ -23,6 +23,7 @@
#include <kern_priv.h>
#include <platform.h>
#include <arm.h>
+#include <kernel/kpower.h>
#ifdef __SMP__
#include <assp/naviengine/naviengine.h>
@@ -51,36 +52,24 @@
static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
static _LIT_SECURITY_POLICY_FAIL( KDenyAllPolicy );
-#define SEPARATE_DFC_QUEUE
// CONSTANTS
-
//_LIT(DProfilerThread,"DProfilerThread");
-//const TInt KDProfilerThreadPriority = 27;
+const TInt KDSamplerThreadPriority = 27;
-#ifdef SEPARATE_DFC_QUEUE
const TInt KGeneralsDriverThreadPriority = 24;
_LIT(KGeneralsDriverThread, "PIGeneralsDriver");
-#endif
-
// global Dfc Que
-//TDynamicDfcQue* gDfcQ;
+TDynamicDfcQue* gDfcQ;
-//#ifdef __SMP__
-//
-//enum TNaviEngineAsspInterruptIdExtension
-//{
-// KIntProfilerBase = 99 // Sampling profiler interrupt base.
-// // Each CPU is assigned a sampling interrupt from this base
-// // CPU-0's sampling interrupt is KIntIdSamplingBase + 0
-// // CPU-n's sampling interrupt is KIntIdSamplingBase + n
-//};
-//#endif
+#ifdef __SMP__
+static TSpinLock PiSpinLock = TSpinLock(TSpinLock::EOrderGenericIrqLow2);
+#endif
/*
*
*
- * Class DGfcProfilerFactory definition
+ * Class DGeneralsProfilerFactory definition
*
*
*/
@@ -100,11 +89,12 @@
/*
*
*
- * Class DGfcDriver definition
+ * Class DGeneralsDriver definition
*
*
*/
class DPluginDriver;
+class DSamplerPowerHandler;
class DGeneralsDriver : public DPluginDriver
{
@@ -112,20 +102,22 @@
public:
DGeneralsDriver();
~DGeneralsDriver();
-
+ TInt StartSampling(TInt aRate, TInt aInterruptNumber);
+ TInt StopSampling();
private:
- TInt NewStart(TInt aRate);
+ TInt isExecuted;
+ TInt NewStart(TInt aRate);
+ void IncrementSampleNeededState(TInt aId);
+ void DecrementSampleNeededState();
static void NewDoProfilerProfile(TAny*);
static void NewDoDfc(TAny*);
// called by each core
- static void Sample(TAny*);
+ static void Sample(TAny* aPtr);
TInt GetSampleTime(TUint32* time);
//TInt Test(TUint32 testCase);
- TInt StartSampling();
- TInt StopSampling();
void InitialiseSamplerList();
@@ -169,7 +161,7 @@
#endif
DProfilerGfcSampler<10000> gfcSampler;
DProfilerIttSampler<10000> ittSampler;
- DProfilerMemSampler<40000> memSampler;
+ DProfilerMemSampler<10000> memSampler;
DProfilerPriSampler<10000> priSampler;
#ifdef __SMP__
// DProfilerPriSampler<10000> priSampler2;
@@ -183,13 +175,46 @@
static const TInt KSamplerAmount = 8;
#endif
DProfilerSamplerBase* iSamplers[KSamplerAmount];
+ TUint iInterruptCounter[KMaxCpus];
TInt iMaxCpus;
TUint32 iStartTime;
-
-#ifdef SEPARATE_DFC_QUEUE
- TDynamicDfcQue* iDfcQ;
-#endif
+ TInt8 postSampleNeeded;
+ DSamplerPowerHandler* iPowerHandler;
+
+ /* using the HAL machine UID we determine the platform Bridge/Naviengine */
+ enum TPlatform
+ {
+ /* Bridge Platform STE500*/
+ EBridge,
+ /* Naviengine Platform NE1_TB */
+ ENaviengine,
+ /* Not recognised platform */
+ ENotRecognised,
+ /* Spare */
+ ESpare
+ };
+ TPlatform iPlatform;
+
+public:
+ TUint8 iStarted;
+ TUint8 iOff;
+ TInt iRate;
+ TInt iIntNo; // Interrupt Number
};
+/*
+ * PowerHandler
+ */
+class DSamplerPowerHandler : public DPowerHandler
+ {
+public: // from DPowerHandler
+ void PowerUp();
+ void PowerDown(TPowerState);
+public:
+ DSamplerPowerHandler(DGeneralsDriver* aChannel);
+public:
+ DGeneralsDriver* iChannel;
+ };
+
/*
*
@@ -219,14 +244,21 @@
DGeneralsProfilerFactory::~DGeneralsProfilerFactory()
{
-// if (gDfcQ)
-// {
-// gDfcQ->Destroy();
-// }
+ if (gDfcQ)
+ {
+ gDfcQ->Destroy();
+ }
}
TInt DGeneralsProfilerFactory::Install()
{
+ // Allocate a kernel thread to run the DFC
+ TInt r = Kern::DynamicDfcQCreate(gDfcQ, KDSamplerThreadPriority, KGeneralsDriverThread);
+ if (r != KErrNone)
+ {
+ return r;
+ }
+
return(SetName(&KPluginSamplerName));
}
@@ -275,6 +307,7 @@
sampleRunning = 0;
iSyncOffset = 0;
iStartTime = 0;
+ postSampleNeeded = 0;
InitialiseSamplerList();
}
@@ -306,6 +339,11 @@
#ifdef __SMP__
// get the number of cpus
iMaxCpus = NKern::NumberOfCpus();
+ for(TInt nCpu(0); nCpu < iMaxCpus; nCpu++)
+ {
+ iInterruptCounter[nCpu] = 0;
+ }
+
#else
iMaxCpus = 0;
#endif
@@ -315,14 +353,14 @@
TInt r(iSampleStartTimeProp.Attach(KGppPropertyCat, EGppPropertySyncSampleNumber));
if (r!=KErrNone)
{
- LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in attaching counter property, error %d", r);
+ Kern::Printf("DGeneralsDriver::InitialiseSamplerList() - error in attaching counter property, error %d", r);
}
LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - defining properties");
r = iSampleStartTimeProp.Define(RProperty::EInt, KAllowAllPolicy, KDenyAllPolicy, 0, NULL);
if (r!=KErrNone)
{
- LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in defining counter property, error %d", r);
- }
+ Kern::Printf("DGeneralsDriver::InitialiseSamplerList() - error in defining counter property, error %d", r);
+ }
}
@@ -341,7 +379,7 @@
TInt DGeneralsDriver::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer)
{
TUint8 err(KErrNone);
-
+ LOGSTRING("DGeneralsDriver::DoCreate()");
if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
return KErrNotSupported;
@@ -361,13 +399,20 @@
//Require Power Management and All Files to use this driver
// Not ideal, but better than nothing
if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
+ {
+ Kern::Printf("DGeneralsDriver::CurrentThreadHasCapability - denied");
return KErrPermissionDenied;
+ }
if(!Kern::CurrentThreadHasCapability(ECapabilityAllFiles,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
- return KErrPermissionDenied;
+ {
+ Kern::Printf("DGeneralsDriver::CurrentThreadHasCapability - denied");
+ return KErrPermissionDenied;
+ }
SSecurityInfo secureInfo = clientProcess->iS;
if (secureInfo.iSecureId != KProfilerExeSecurUid)
{
+ Kern::Printf("DGeneralsDriver::security - denied");
return KErrPermissionDenied;
}
}
@@ -378,22 +423,20 @@
iTimer.Cancel();
iNewDfc.Cancel();
- Kern::SetThreadPriority(24);
+ Kern::SetThreadPriority(KGeneralsDriverThreadPriority);
-#ifdef SEPARATE_DFC_QUEUE
- err = Kern::DynamicDfcQCreate(iDfcQ, KGeneralsDriverThreadPriority, TBuf8<32>( KGeneralsDriverThread ));
- if (KErrNone == err)
+ SetDfcQ(gDfcQ);
+ iNewDfc.SetDfcQ(iDfcQ);
+ iMsgQ.Receive();
+
+ // create the power handler
+ iPowerHandler = new DSamplerPowerHandler(this);
+ if (!iPowerHandler)
{
- SetDfcQ(iDfcQ);
- iNewDfc.SetDfcQ(iDfcQ);
- iMsgQ.Receive();
- return err;
+ Kern::Printf("DGeneralsDriver::DoCreate() : new DSamplerPowerHandler(this) failed");
+ return KErrNoMemory;
}
-#else
- SetDfcQ(Kern::DfcQue0());
- iNewDfc.SetDfcQ(iDfcQ);
- iMsgQ.Receive();
-#endif
+ iPowerHandler->Add();
return err;
}
@@ -403,11 +446,6 @@
iTimer.Cancel();
iNewDfc.Cancel();
-#ifdef SEPARATE_DFC_QUEUE
- if(iDfcQ)
- iDfcQ->Destroy();
-#endif
-
iSampleStartTimeProp.Close();
Kern::SafeClose((DObject*&)iClient,NULL);
}
@@ -450,48 +488,39 @@
#ifdef __SMP__
/*
- * Bind and enable the sampling interupts associated with each core.
+ * Bind and enable the sampling interrupts
*/
TInt err(0);
-
- TUint32 flags = NKern::EIrqBind_Count;
-
-// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
- err = NKern::InterruptBind( KIntProfilerBase - 32 , DGeneralsDriver::Sample, this, flags, 0);
- if(err < 0)
- Kern::Printf(" InterruptBind KIntProfilerBase - 32 ret = %d", err );
-
-// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
- err = NKern::InterruptBind( KIntProfilerBase + 1 - 32 , DGeneralsDriver::Sample, this, flags, 0);
- if(err < 0)
- Kern::Printf(" InterruptBind KIntProfilerBase + 1 - 32 ret = %d", err );
-
-// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
- err = NKern::InterruptBind(KIntProfilerBase + 2 - 32 , DGeneralsDriver::Sample, this, flags, 0);
- if(err < 0)
- Kern::Printf(" InterruptBind KIntProfilerBase + 2 - 32 ret = %d", err );
+ TUint32 flags(NKern::EIrqBind_Count);
+ TInt noofCpu(NKern::NumberOfCpus());
-// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
- err = NKern::InterruptBind(KIntProfilerBase + 3 - 32 , DGeneralsDriver::Sample, this, flags, 0);
- if(err < 0)
- Kern::Printf(" InterruptBind KIntProfilerBase + 3 - 32 ret = %d", err );
-
-
- err = NKern::InterruptEnable(KIntProfilerBase - 32);
- if(err < 0)
- Kern::Printf(" InterruptEnable KIntProfilerBase - 32 ret = %d", err );
-
- err = NKern::InterruptEnable(KIntProfilerBase + 1 - 32);
- if(err < 0)
- Kern::Printf(" InterruptEnable KIntProfilerBase + 1 - 32 ret = %d", err );
-
- err = NKern::InterruptEnable(KIntProfilerBase + 2 - 32);
- if(err < 0)
- Kern::Printf(" InterruptEnable KIntProfilerBase + 2 - 32 ret = %d", err );
-
- err = NKern::InterruptEnable(KIntProfilerBase + 3 - 32);
- if(err < 0)
- Kern::Printf(" InterruptEnable KIntProfilerBase + 3 - 32 ret = %d", err );
+ //Binding to the interrupt(s)
+ for( TInt nCpu(0); nCpu < noofCpu; nCpu++ )
+ {
+ LOGSTRING3(" > Interrupt::InterruptBind %d + %d - 32", iIntNo, nCpu );
+ err = NKern::InterruptBind( (iIntNo + nCpu - 32) , DGeneralsDriver::Sample, this, flags, 0);
+ if(err < 0)
+ {
+ Kern::Printf(" InterruptBind %d + %d - 32 Error = 0x%x", iIntNo, nCpu, err );
+ return err;
+ }
+ }
+
+ //Enabling Interrupt(s)
+ for( TInt nCpu(0); nCpu < noofCpu; nCpu++ )
+ {
+ LOGSTRING3(" > NKern::InterruptEnable %d + %d - 32", iIntNo, nCpu );
+ err = NKern::InterruptEnable(iIntNo + nCpu - 32);
+ if(err < 0)
+ {
+ Kern::Printf(" InterruptEnable %d + %d - 32 ret = 0x%x", iIntNo, nCpu, err );
+ return err;
+ }
+
+ /* For Bridge we enable one single interrupt for CPU 1 */
+ if(iPlatform == EBridge)
+ break;
+ }
#endif
@@ -502,6 +531,33 @@
return KErrNone;
}
+void DGeneralsDriver::IncrementSampleNeededState(TInt aId)
+ {
+ LOGSTRING2("DGeneralsDriver::IncrementSampleNeededState() - incrementing sample needed state, caller id: %d", (aId+1));
+#ifdef __SMP__
+ TInt intState(0);
+ intState = __SPIN_LOCK_IRQSAVE(PiSpinLock);
+#endif
+ postSampleNeeded++;
+#ifdef __SMP__
+ __SPIN_UNLOCK_IRQRESTORE(PiSpinLock, intState);
+#endif
+ }
+
+void DGeneralsDriver::DecrementSampleNeededState()
+ {
+ LOGSTRING("DGeneralsDriver::DecrementSampleNeededState() - decrementing sample needed state");
+#ifdef __SMP__
+ TInt intState(0);
+ intState = __SPIN_LOCK_IRQSAVE(PiSpinLock);
+#endif
+ postSampleNeeded--;
+#ifdef __SMP__
+ __SPIN_UNLOCK_IRQRESTORE(PiSpinLock, intState);
+#endif
+ }
+
+
/*
* This function is run in each interrupt
*/
@@ -510,83 +566,147 @@
void DGeneralsDriver::NewDoProfilerProfile(TAny* aPtr)
{
LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - entry");
-
+ DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
#ifdef __SMP__
TInt currCpu(NKern::CurrentCpu());
#endif
- TInt8 postSampleNeeded(0);
- DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
+
+ if(!d.iOff)
+ {
+ if (d.iState == ERunning && d.sampleRunning == 0)
+ {
+ // start timer again
+ d.iTimer.Again(d.iPeriod);
+ d.sampleRunning++;
+
+#ifdef __SMP__
+ // print out the sample tick
+ if(d.gppSampler.GetExportData()->sampleNumber% 1000 == 0)
+ {
+ Kern::Printf(("PIPROF SAMPLE TICK, #%d"), d.gppSampler.GetExportData()->sampleNumber);
+ }
+
+ // call the actual CPU sampling function for CPU 0 (in NaviEngine), later may be on any of the CPUs
+ Sample(aPtr);
+
+ /*
+ This is the master sampler from the watchdog timer, so
+ send interrupts to the other CPU(s)
+ */
+ TScheduler *theSched = TScheduler::Ptr();
+// GicDistributor* gicDist = (GicDistributor* )theSched->i_GicDistAddr;
+ GicDistributor* gicDist = (GicDistributor* )(theSched->iSX.iGicDistAddr);
+
+ // post-sampling for NTimer interrupted CPU
+ //d.postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
+
+ if (d.iPlatform == EBridge)
+ {
+ /* The Interrupt ID is hardcoded for Bridge to be 108/117, using SPI on ARM GIC
+ * Programming the GIC Distributor Set-Pending Register to raise an interrupt
+ * Programming the GIC Distributor Target Register to set an interrupt in CPU 1
+ */
+
+ /* Interrupt Processor Targets Registers (ICDIPTRn)
+ * target register ICDIPTR number, M, is given by M = N DIV 4
+ * so M is 27 for N = 108/117
+ * NTimer interrupt is always defaulted to CPU 0 so we have to interrupt CPU 1
+ * setting 0bxxxxxx1x CPU interface 1
+ */
+// gicDist->iTarget[27] |= 0x00000002;
+// gicDist->iTarget[27] &= 0xFE;
+ gicDist->iTarget[29] |= 0x00000200;
+ gicDist->iTarget[29] &= 0xFFFFFEFF;
- if (d.iState == ERunning && d.sampleRunning == 0)
- {
- // start timer again
- d.iTimer.Again(d.iPeriod);
- d.sampleRunning++;
-
-#ifdef __SMP__
- // print out the sample tick
- if(d.gppSampler.GetExportData()->sampleNumber% 1000 == 0)
- {
- Kern::Printf(("PIPROF SAMPLE TICK, #%d"), d.gppSampler.GetExportData()->sampleNumber);
- }
- // call the actual CPU sampling function for CPU 0 (in NaviEngine), later may be on any of the CPUs
- Sample(aPtr);
+ /* Interrupt Set-Pending Registers (ICDISPRn)
+ * the corresponding ICDISPR number, M, is given by M = N DIV 32
+ * M = 3 for N being 108/117
+ * the bit number of the required Set-pending bit in this register is N MOD 32
+ * which in this case is 12
+ */
+// gicDist->iPendingSet[3] = 1<<((12)); // N = 108
+ gicDist->iPendingSet[3] = 1<<((21)); // N = 117
+
+ arm_dsb();
+
+ }
+ else if (d.iPlatform == ENaviengine) //naviengine platform
+ {
+ for( TInt nCpu(0); nCpu < NKern::NumberOfCpus(); nCpu++ )
+ {
+ if( nCpu != currCpu )
+ {
+ //Kern::Printf(("DProfile::TimerSampleIsr() > iSoftIrq: to cpu%d, 0x%08X"), nCpu, ( 0x10000 << nCpu ) | (d.iIntNo + nCpu));
+ gicDist->iSoftIrq = ( 0x10000 << nCpu ) | (d.iIntNo + nCpu);
+ }
+ // post-sampling for CPUs with specifically generated interrupts
+ //d.postSampleNeeded += d.iSamplers[nCpu]->PostSampleNeeded();
+ }
+ arm_dsb();
+
+ }
+ else
+ {
+ Kern::Printf("DGeneralsDriver::NewDoProfilerProfile - SMP Platform not recognised " );
+ }
+
+#endif
+ // then sample the rest of non-cpu samplers
+ for(TInt i(0);i<KSamplerAmount;i++)
+ {
+ if(d.iSamplers[i]->iEnabled)
+ {
+ d.iSamplers[i]->Sample(aPtr);
+ if(d.iSamplers[i]->PostSampleNeeded())
+ {
+ d.IncrementSampleNeededState(i);
+ }
+ }
+ }
+
+// // check if post sampling is needed for samplers
+// for(TInt i(0);i<KSamplerAmount;i++)
+// {
+// if(d.iSamplers[i]->iEnabled)
+// {
+// if(d.iSamplers[i]->PostSampleNeeded())
+// {
+// d.IncrementSampleNeededState(i);
+// }
+// }
+// }
+
+ if(d.postSampleNeeded > 0 && d.doingDfc == 0)
+ //if(d.postSampleNeeded > 0)
+ {
+ LOGSTRING2("DGeneralsDriver::NewDoProfilerProfile - postSampleNeeded count %d ", d.postSampleNeeded );
+ d.doingDfc++;
+ d.iNewDfc.Add();
- // post-sampling for NTimer interrupted CPU
- postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
+ d.sampleRunning--;
- /*
- This is the master sampler from the watchdog timer, so
- send interrupts to the other CPUs
- */
- TScheduler *theSched = TScheduler::Ptr();
- GicDistributor* gicDist = (GicDistributor* )theSched->i_GicDistAddr;
-
- for( TInt nCpu(0); nCpu < d.iMaxCpus; nCpu++ )
+ return;
+ }
+ d.sampleRunning--;
+ } // if (d.iState == ERunning && d.sampleRunning == 0)
+ else if (d.iState == EStopping && d.sampleRunning == 0)
{
- if( nCpu != currCpu )
- {
- gicDist->iSoftIrq = ( 0x10000 << nCpu ) | (KIntProfilerBase + nCpu);
- }
- // post-sampling for CPUs with specifically generated interrupts
- postSampleNeeded += d.iSamplers[nCpu]->PostSampleNeeded();
+ // add a dfc for this final time
+ d.iNewDfc.Add();
+ LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - sampling added to dfc queue");
}
- arm_dsb();
-#endif
- // then sample the rest of non-cpu samplers
- for(TInt i(d.iMaxCpus);i<KSamplerAmount;i++)
+ else
{
- if(d.iSamplers[i]->iEnabled)
- {
- d.iSamplers[i]->Sample();
- postSampleNeeded += d.iSamplers[i]->PostSampleNeeded();
- }
+ // the previous sample has not finished,
+ Kern::Printf("DGeneralsDriver::NewDoProfilerProfile - Profiler Sampler Error - interrupted before finished sampling!!");
}
-
- if(postSampleNeeded > 0 && d.doingDfc == 0)
- {
- d.doingDfc++;
- d.iNewDfc.Add();
-
- d.sampleRunning--;
- return;
- }
- d.sampleRunning--;
+ LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - exit");
+ } // iOff
+ else
+ {
+ Kern::Printf("DGeneralsDriver::iOff");
}
- else if (d.iState == EStopping && d.sampleRunning == 0)
- {
- // add a dfc for this final time
- d.iNewDfc.Add();
- Kern::Printf("DGeneralsDriver::Sample - sampling added to dfc queue");
- }
- else
- {
- // the previous sample has not finished,
- Kern::Printf("DGeneralsDriver::NewDoProfilerProfile - Profiler Sampler Error - interrupted before finished sampling!!");
- }
- LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - exit");
- }
-
+}
void DGeneralsDriver::Sample(TAny* aPtr)
@@ -596,17 +716,14 @@
#ifdef __SMP__
DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
-// TInt currCpu(NKern::CurrentCpu());
+ TInt currCpu(NKern::CurrentCpu());
+ ++d.iInterruptCounter[currCpu];
- // sample the current cpu load
-// if(d.iSamplers[currCpu]->iEnabled)
-// {
- d.iSamplers[NKern::CurrentCpu()]->Sample();
-// postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
-// }
+ d.iSamplers[currCpu]->Sample(aPtr);
#endif
LOGSTRING("DGeneralsDriver::Sample - exit");
}
+
/*
* This function is run when any of the samplers
* requires post sampling
@@ -625,7 +742,10 @@
{
if(d.iSamplers[i]->PostSampleNeeded())
{
- d.iSamplers[i]->PostSample();
+ LOGSTRING3("DGeneralsDriver::NewDoDfc iSamplers[%d] PostSampleNeeded count %d", i, d.postSampleNeeded);
+ d.iSamplers[i]->PostSample();
+ d.DecrementSampleNeededState();
+ LOGSTRING3("DGeneralsDriver::NewDoDfc iSamplers[%d] PostSampleNeeded count %d", i, d.postSampleNeeded);
}
}
}
@@ -634,6 +754,7 @@
else if(d.iState == EStopping)
{
+ LOGSTRING("DGeneralsDriver::NewDoDfc state Stopping()");
// for all enabled samplers,
// perform end sampling
TBool releaseBuffer(false);
@@ -641,18 +762,23 @@
{
if(d.iSamplers[i]->iEnabled)
{
- LOGSTRING("DGeneralsDriver::NewDoDfc() - ending");
+ LOGSTRING("DGeneralsDriver::NewDoDfc() - ending");
+ if(d.iSamplers[i]->PostSampleNeeded())
+ {
+ LOGSTRING2("DGeneralsDriver::NewDoDfc iSamplers[%d] PostSampleNeeded still", i);
+ d.iSamplers[i]->PostSample();
+ }
// perform end sampling for all samplers
// stream mode samplers may be pending, if they
// are still waiting for another client buffer
if(d.iSamplers[i]->EndSampling() == KErrNotReady)
{
- LOGSTRING("DGeneralsDriver::NewDoDfc() - stream data pending");
+ LOGSTRING("DGeneralsDriver::NewDoDfc() - stream data pending");
releaseBuffer = true;
}
else
{
- LOGSTRING("DGeneralsDriver::NewDoDfc() - no data pending");
+ LOGSTRING("DGeneralsDriver::NewDoDfc() - no data pending");
releaseBuffer = true;
}
}
@@ -661,7 +787,7 @@
// At the end, once all the samplers are gone through, the buffer should be released
if (true == releaseBuffer)
{
- LOGSTRING("DGeneralsDriver::NewDoDfc() - release the buffer");
+ LOGSTRING("DGeneralsDriver::NewDoDfc() - release the buffer");
d.iSampleStream.ReleaseIfPending();
}
@@ -670,6 +796,7 @@
{
// sampling has ended
Kern::RequestComplete(d.iClient,d.iEndRequestStatus,KErrNone);
+ LOGSTRING("DGeneralsDriver::NewDoDfc() - request complete, stopped");
}
}
}
@@ -746,8 +873,10 @@
break;
case RPluginSampler::EStartSampling:
- LOGSTRING("DGeneralsDriver::HandleMsg - EStartSampling");
- r = StartSampling();
+ LOGSTRING("DGeneralsDriver::HandleMsg - EStartSampling");
+ iStarted = (TUint8)ETrue;
+ r=StartSampling(m.Int0(),m.Int1());
+ //r = StartSampling();
break;
case RPluginSampler::EGetSampleTime:
@@ -770,7 +899,7 @@
// Requests are handled here
case ~RPluginSampler::EStopAndWaitForEnd:
- LOGSTRING("DGeneralsDriver::HandleMsg - EStopAndWaitForEnd");
+ LOGSTRING("DGeneralsDriver::HandleMsg - EStopAndWaitForEnd");
iEndRequestStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0());
r = StopSampling();
#ifdef __SMP__
@@ -785,7 +914,7 @@
break;
default:
- LOGSTRING2("DGeneralsDriver::HandleMsg - ERROR, unknown command %d",id);
+ Kern::Printf("DGeneralsDriver::HandleMsg - ERROR, unknown command %d",id);
r = KErrNotSupported;
break;
}
@@ -798,44 +927,30 @@
inline void DGeneralsDriver::UnbindInterrupts()
{
TInt err(0);
-
- // disable interrupts when sampling stops, enabled again on start
- err = NKern::InterruptDisable(KIntProfilerBase - 32);
- if(err < 0)
- Kern::Printf(" InterruptDisable KIntProfilerBase - 32 ret = %d", err );
-
- err = NKern::InterruptDisable(KIntProfilerBase + 1 - 32);
- if(err < 0)
- Kern::Printf(" InterruptDisable KIntProfilerBase + 1 - 32 ret = %d", err );
-
- err = NKern::InterruptDisable(KIntProfilerBase + 2 - 32);
- if(err < 0)
- Kern::Printf(" InterruptDisable KIntProfilerBase + 2 - 32 ret = %d", err );
-
- err = NKern::InterruptDisable(KIntProfilerBase + 3 - 32);
- if(err < 0)
- Kern::Printf(" InterruptDisable KIntProfilerBase + 3 - 32 ret = %d", err );
-
-// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
- err = NKern::InterruptUnbind( KIntProfilerBase - 32);
- if(err < 0)
- Kern::Printf(" InterruptUnbind KIntProfilerBase - 32 ret = %d", err );
-
-// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
- err = NKern::InterruptUnbind( KIntProfilerBase + 1 - 32);
- if(err < 0)
- Kern::Printf(" InterruptUnbind KIntProfilerBase + 1 - 32 ret = %d", err );
-
-// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
- err = NKern::InterruptUnbind(KIntProfilerBase + 2 - 32);
- if(err < 0)
- Kern::Printf(" InterruptUnbind KIntProfilerBase + 2 - 32 ret = %d", err );
-
-// Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
- err = NKern::InterruptUnbind(KIntProfilerBase + 3 - 32);
- if(err < 0)
- Kern::Printf(" InterruptUnbind KIntProfilerBase + 3 - 32 ret = %d", err );
-
+ /*
+ * Disable and unbind the sampling interrupts associated with each core.
+ */
+ TInt noofCpu(NKern::NumberOfCpus());
+ //Disabling Interrupt(s)
+ for( TInt nCpu(0); nCpu < noofCpu; nCpu++ )
+ {
+ err = NKern::InterruptDisable(iIntNo + nCpu - 32);
+ if(err < 0)
+ {
+ Kern::Printf(" Interrupt Disable iIntNo + %d - 32 ret = %d", nCpu, err );
+ }
+ }
+
+ //UnBinding to the interrupt(s)
+ for( TInt nCpu(0); nCpu < noofCpu; nCpu++ )
+ {
+ LOGSTRING3(" > Interrupt::InterruptUnBind + %d -32 =%d", nCpu, iIntNo + nCpu -32 );
+ err = NKern::InterruptUnbind( (iIntNo + nCpu - 32) );
+ if(err < 0)
+ {
+ Kern::Printf(" InterruptUnBind iIntNo + %d - 32 Error = %d", nCpu, err );
+ }
+ }
}
#endif
@@ -865,12 +980,12 @@
// in that case, the request should be completed already
if(iSamplers[i]->EndSampling() == KErrNotReady)
{
- LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - still data pending");
- releaseBuffer = true;
+ LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - still data pending");
+ releaseBuffer = false;
}
else
{
- LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - no data pending");
+ LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - no data pending");
releaseBuffer = true;
}
}
@@ -878,7 +993,7 @@
// At the end, once all the samplers are gone through, the buffer should be released
if (true == releaseBuffer)
{
- LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - all data copied, release the buffer");
+ LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - all data copied, release the buffer");
iSampleStream.ReleaseIfPending();
}
}
@@ -903,10 +1018,10 @@
if( samplerIdToActivate == PROFILER_GPP_SAMPLER_ID )
{
for(TInt cpu(0);cpu<cpus;cpu++)
- {
- Kern::Printf("DGeneralsDriver::MarkTraceActive - activating CPU %d",cpu);
- iSamplers[cpu]->SetEnabledFlag(true);
- }
+ {
+ LOGSTRING2("DGeneralsDriver::MarkTraceActive - activating CPU %d",cpu);
+ iSamplers[cpu]->SetEnabledFlag(true);
+ }
return KErrNone;
}
#endif
@@ -919,7 +1034,7 @@
}
}
- LOGSTRING2("DGeneralsDriver::MarkTraceActive - %d not supported",samplerIdToActivate);
+ Kern::Printf("DGeneralsDriver::MarkTraceActive - %d not supported",samplerIdToActivate);
return KErrNotSupported;
}
@@ -948,7 +1063,7 @@
}
}
- LOGSTRING2("DGeneralsDriver::MarkTraceInactive - %d not supported",samplerIdToDisable);
+ Kern::Printf("DGeneralsDriver::MarkTraceInactive - %d not supported",samplerIdToDisable);
return KErrNotSupported;
}
@@ -1077,7 +1192,7 @@
* only if sampling is not running
*/
-TInt DGeneralsDriver::StartSampling()
+TInt DGeneralsDriver::StartSampling(TInt aRate, TInt aInterruptNumber)
{
LOGSTRING("DGeneralsDriver::StartSampling");
@@ -1086,6 +1201,7 @@
// reset iSampleStartTimeProp property value
iSampleStartTime = NKern::TickCount(); // get the system tick value for sync purposes
#ifdef __SMP__
+ TInt err;
iStartTime = (iSampleStartTime & 0xfffffff0);
#endif
TInt r(iSampleStartTimeProp.Set(iSampleStartTime));
@@ -1099,15 +1215,55 @@
{
// reset with stream option
#ifndef __SMP__
- Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, sync offset %d"), 0);
+ LOGSTRING2(("DGeneralsDriver::StartSampling - stream reset for generals driver, sync offset %d"), 0);
iSamplers[i]->Reset(&iSampleStream, 0);
#else
- Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, start time %d"), iStartTime);
+ LOGSTRING2(("DGeneralsDriver::StartSampling - stream reset for generals driver, start time %d"), iStartTime);
iSamplers[i]->Reset(&iSampleStream, iStartTime);
#endif
}
}
-
+#ifdef __SMP__
+ iRate = aRate;
+ iIntNo = aInterruptNumber;
+ // use HAL to understand the underlying hardware
+ // not so elegant but used for two SMP pltaforms Bridge and Naviengine
+ TVariantInfoV01 info;
+ TPckg<TVariantInfoV01> infoPckg(info);
+ err = Kern::HalFunction(EHalGroupVariant, EVariantHalVariantInfo, (TAny*)&infoPckg, NULL);
+
+ if(err != KErrNone)
+ {
+ Kern::Printf("Error in reading HAL Entry EVariantHalVariantInfo %r ", err);
+ }
+ if (info.iMachineUniqueId.iData[0] == KBridgeMachineUID)
+ {
+ iPlatform = EBridge;
+ LOGSTRING("DGeneralsDriver::StartSampling() - Bridge HW");
+ }
+ else if (info.iMachineUniqueId.iData[0] == KNaviengineMachineUID)
+ {
+ iPlatform = ENaviengine;
+ LOGSTRING("DGeneralsDriver::StartSampling() - NaviEngine HW");
+ }
+ else
+ {
+ Kern::Printf("DGeneralsDriver::StartSampling() - Unknown HW, 0x%x", info.iMachineUniqueId.iData[0]);
+ }
+
+ //users are restricted to use the default Interrupt Number for Bridge
+ if ((iPlatform == EBridge) && (aInterruptNumber != KValueZero) && (aInterruptNumber != KBridgeProfilerInterruptId) )
+ {
+ Kern::Printf("Invalid Interrupt Number for Bridge used %d interrupt...Please use %d Interrupt Number", iIntNo, KBridgeProfilerInterruptId);
+ return KErrNotSupported;
+ }
+ if (aInterruptNumber == KValueZero)
+ iIntNo = KDefaultInterruptNumber;
+
+ if (iPlatform == EBridge)
+ /* By default for Bridge we are using KBridgeProfilerInterruptId */
+ iIntNo = KBridgeProfilerInterruptId;
+#endif
NewStart(gppSampler.GetPeriod());
return KErrNone;
}
@@ -1124,7 +1280,8 @@
TInt DGeneralsDriver::StopSampling()
{
- LOGSTRING("DGeneralsDriver::StopSampling");
+ LOGSTRING2("DGeneralsDriver::StopSampling - iState %", iState);
+ TInt noofCpu(NKern::NumberOfCpus());
if(iState == ERunning)
{
@@ -1132,14 +1289,26 @@
// reset all enabled samplers
for(TInt i(0);i<KSamplerAmount;i++)
{
- // do the reset only for memory sampler
- if(iSamplers[i]->iEnabled && iSamplers[i]->iSamplerId == 4)
+ // do the reset only for memory and itt samplers
+ if(iSamplers[i]->iEnabled &&
+ (iSamplers[i]->iSamplerId == PROFILER_ITT_SAMPLER_ID ||
+ iSamplers[i]->iSamplerId == PROFILER_MEM_SAMPLER_ID ))
{
// reset with stream option
- LOGTEXT(("DGeneralsDriver::StopSampling - stream reset for samplers"));
- iSamplers[i]->Reset(&iSampleStream, 999999);
+ LOGSTRING(("DGeneralsDriver::StopSampling - stream reset for samplers"));
+ iSamplers[i]->Reset(&iSampleStream, KStateSamplingEnding);
}
}
+ LOGSTRING2("\nDGeneralsDriver::StopSampling - Number of times the Timer counter expired on CPU 0 = %d ", iInterruptCounter[0]);
+
+ for(TInt nCpu(1); nCpu < noofCpu; nCpu++)
+ {
+ Kern::Printf( "\n Number of times we interrupted CPU[%d] = %d and Number of Missed CPU interrupts = %d", nCpu, iInterruptCounter[nCpu],(iInterruptCounter[0] - iInterruptCounter[nCpu]));
+ Kern::Printf( "\n Number of times CPU sampler[0] accessed: %d", gppSampler.GetExportData()->sampleNumber);
+#ifdef __SMP__
+ Kern::Printf( "\n Number of times CPU sampler[1] accessed: %d", gppSampler2.GetExportData()->sampleNumber);
+#endif
+ }
return KErrNone;
}
@@ -1149,4 +1318,31 @@
}
}
+DSamplerPowerHandler::DSamplerPowerHandler(DGeneralsDriver* aChannel)
+ : DPowerHandler(KPluginSamplerName),
+ iChannel(aChannel)
+ {
+ LOGSTRING("DSamplerPowerHandler::DSamplerPowerHandler\n");
+ }
+
+void DSamplerPowerHandler::PowerUp()
+ {
+ LOGSTRING("DSamplerPowerHandler::PowerUp()1\n");
+ iChannel->iOff = (TUint8)EFalse;
+ if (iChannel->iStarted)
+ {
+ LOGSTRING("DSamplerPowerHandler::PowerUp()2\n");
+ iChannel->StartSampling(iChannel->iRate, iChannel->iIntNo);
+ }
+ PowerUpDone();
+ }
+
+void DSamplerPowerHandler::PowerDown(TPowerState)
+ {
+ LOGSTRING("DSamplerPowerHandler::PowerDown()\n");
+ iChannel->iOff = (TUint8)ETrue;
+ //iChannel->iState = EStopped;
+ iChannel->StopSampling();
+ PowerDownDone();
+ }