perfsrv/piprofiler/plugins/GeneralsPlugin/src/GeneralsDriver.cpp
changeset 62 1c2bb2fc7c87
parent 51 98307c651589
equal deleted inserted replaced
56:aa2539c91954 62:1c2bb2fc7c87
    21 //
    21 //
    22 
    22 
    23 #include <kern_priv.h>
    23 #include <kern_priv.h>
    24 #include <platform.h>
    24 #include <platform.h>
    25 #include <arm.h>
    25 #include <arm.h>
       
    26 #include <kernel/kpower.h>
    26 
    27 
    27 #ifdef __SMP__
    28 #ifdef __SMP__
    28 #include <assp/naviengine/naviengine.h> 
    29 #include <assp/naviengine/naviengine.h> 
    29 #include <nkernsmp/arm/arm_gic.h>
    30 #include <nkernsmp/arm/arm_gic.h>
    30 #include <nkernsmp/arm/arm_tmr.h>
    31 #include <nkernsmp/arm/arm_tmr.h>
    49 // for security check
    50 // for security check
    50 #define KProfilerExeSecurUid 0x2001E5AD
    51 #define KProfilerExeSecurUid 0x2001E5AD
    51 static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
    52 static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
    52 static _LIT_SECURITY_POLICY_FAIL( KDenyAllPolicy );
    53 static _LIT_SECURITY_POLICY_FAIL( KDenyAllPolicy );
    53 
    54 
    54 #define SEPARATE_DFC_QUEUE
       
    55 // CONSTANTS
    55 // CONSTANTS
    56 
       
    57 //_LIT(DProfilerThread,"DProfilerThread");
    56 //_LIT(DProfilerThread,"DProfilerThread");
    58 //const TInt KDProfilerThreadPriority = 27;
    57 const TInt KDSamplerThreadPriority = 27;
    59 
    58 
    60 #ifdef SEPARATE_DFC_QUEUE
       
    61 const TInt KGeneralsDriverThreadPriority = 24;
    59 const TInt KGeneralsDriverThreadPriority = 24;
    62 _LIT(KGeneralsDriverThread, "PIGeneralsDriver");
    60 _LIT(KGeneralsDriverThread, "PIGeneralsDriver");
    63 
    61 
    64 #endif
       
    65 
       
    66 // global Dfc Que
    62 // global Dfc Que
    67 //TDynamicDfcQue* gDfcQ;
    63 TDynamicDfcQue* gDfcQ;
    68 
    64 
    69 //#ifdef __SMP__
    65 #ifdef __SMP__
    70 //
    66 static TSpinLock PiSpinLock = TSpinLock(TSpinLock::EOrderGenericIrqLow2);
    71 //enum  TNaviEngineAsspInterruptIdExtension
    67 #endif
    72 //{
    68 
    73 //    KIntProfilerBase = 99      //  Sampling profiler interrupt base. 
    69 /*
    74 //    //  Each CPU is assigned a sampling interrupt from this base
    70  *
    75 //    //  CPU-0's sampling interrupt is KIntIdSamplingBase + 0
    71  *
    76 //    //  CPU-n's sampling interrupt is KIntIdSamplingBase + n
    72  *	Class DGeneralsProfilerFactory definition
    77 //};
       
    78 //#endif
       
    79 
       
    80 /*
       
    81  *
       
    82  *
       
    83  *	Class DGfcProfilerFactory definition
       
    84  *
    73  *
    85  *
    74  *
    86  */
    75  */
    87 
    76 
    88 class DGeneralsProfilerFactory : public DLogicalDevice
    77 class DGeneralsProfilerFactory : public DLogicalDevice
    98 };
    87 };
    99 
    88 
   100 /*
    89 /*
   101  *
    90  *
   102  *
    91  *
   103  *	Class DGfcDriver definition
    92  *	Class DGeneralsDriver definition
   104  *
    93  *
   105  *
    94  *
   106  */
    95  */
   107 class DPluginDriver;
    96 class DPluginDriver;
       
    97 class DSamplerPowerHandler;
   108 
    98 
   109 class DGeneralsDriver : public DPluginDriver
    99 class DGeneralsDriver : public DPluginDriver
   110 {
   100 {
   111 
   101 
   112 public:
   102 public:
   113 	DGeneralsDriver();
   103 	DGeneralsDriver();
   114 	~DGeneralsDriver();
   104 	~DGeneralsDriver();
   115 
   105     TInt                    StartSampling(TInt aRate, TInt aInterruptNumber);
       
   106     TInt                    StopSampling();
   116 private:
   107 private:
   117 	TInt					NewStart(TInt aRate);
   108     TInt                    isExecuted;
       
   109     TInt                    NewStart(TInt aRate);
       
   110     void                    IncrementSampleNeededState(TInt aId);
       
   111     void                    DecrementSampleNeededState();
   118 	static void				NewDoProfilerProfile(TAny*);
   112 	static void				NewDoProfilerProfile(TAny*);
   119 	static void				NewDoDfc(TAny*);
   113 	static void				NewDoDfc(TAny*);
   120 	
   114 	
   121 	// called by each core
   115 	// called by each core
   122 	static void				Sample(TAny*);
   116 	static void				Sample(TAny* aPtr);
   123 
   117 
   124 	TInt					GetSampleTime(TUint32* time);
   118 	TInt					GetSampleTime(TUint32* time);
   125 	//TInt					Test(TUint32 testCase); 
   119 	//TInt					Test(TUint32 testCase); 
   126 
   120 
   127 	TInt					StartSampling();
       
   128 	TInt                    StopSampling();
       
   129 
   121 
   130 	void					InitialiseSamplerList(); 
   122 	void					InitialiseSamplerList(); 
   131 
   123 
   132 	DProfilerSamplerBase*	GetSamplerForId(TInt samplerId);
   124 	DProfilerSamplerBase*	GetSamplerForId(TInt samplerId);
   133 	TInt					GetSamplerVersion(TDes* aDes);
   125 	TInt					GetSamplerVersion(TDes* aDes);
   167     DProfilerGppSampler<10000>  gppSampler3;
   159     DProfilerGppSampler<10000>  gppSampler3;
   168     DProfilerGppSampler<10000>  gppSampler4;
   160     DProfilerGppSampler<10000>  gppSampler4;
   169 #endif
   161 #endif
   170 	DProfilerGfcSampler<10000> 	gfcSampler;
   162 	DProfilerGfcSampler<10000> 	gfcSampler;
   171 	DProfilerIttSampler<10000> 	ittSampler;
   163 	DProfilerIttSampler<10000> 	ittSampler;
   172 	DProfilerMemSampler<40000> 	memSampler;
   164 	DProfilerMemSampler<10000> 	memSampler;
   173 	DProfilerPriSampler<10000> 	priSampler;
   165 	DProfilerPriSampler<10000> 	priSampler;
   174 #ifdef __SMP__
   166 #ifdef __SMP__
   175 //    DProfilerPriSampler<10000>  priSampler2;
   167 //    DProfilerPriSampler<10000>  priSampler2;
   176 //    DProfilerPriSampler<10000>  priSampler3;
   168 //    DProfilerPriSampler<10000>  priSampler3;
   177 //    DProfilerPriSampler<10000>  priSampler4;
   169 //    DProfilerPriSampler<10000>  priSampler4;
   181 	static const TInt			KSamplerAmount = 5;
   173 	static const TInt			KSamplerAmount = 5;
   182 #else
   174 #else
   183     static const TInt           KSamplerAmount = 8;
   175     static const TInt           KSamplerAmount = 8;
   184 #endif
   176 #endif
   185 	DProfilerSamplerBase*		iSamplers[KSamplerAmount];
   177 	DProfilerSamplerBase*		iSamplers[KSamplerAmount];
       
   178     TUint                       iInterruptCounter[KMaxCpus];
   186     TInt                        iMaxCpus;
   179     TInt                        iMaxCpus;
   187     TUint32                     iStartTime; 
   180     TUint32                     iStartTime; 
   188 	
   181     TInt8                       postSampleNeeded;
   189 #ifdef SEPARATE_DFC_QUEUE
   182     DSamplerPowerHandler*       iPowerHandler;
   190 	TDynamicDfcQue*             iDfcQ;
   183     
   191 #endif
   184     /* using the HAL machine UID we determine the platform Bridge/Naviengine */
       
   185       enum TPlatform
       
   186           {
       
   187           /* Bridge Platform STE500*/
       
   188           EBridge,
       
   189           /* Naviengine Platform NE1_TB */
       
   190           ENaviengine,
       
   191           /* Not recognised platform */
       
   192           ENotRecognised,
       
   193           /* Spare */
       
   194           ESpare
       
   195           };
       
   196       TPlatform iPlatform;
       
   197 
       
   198 public:
       
   199     TUint8 iStarted;
       
   200     TUint8 iOff;
       
   201     TInt iRate;
       
   202     TInt iIntNo; // Interrupt Number
   192 };
   203 };
       
   204 /*
       
   205  * PowerHandler
       
   206  */
       
   207 class DSamplerPowerHandler : public DPowerHandler
       
   208     {
       
   209 public: // from DPowerHandler
       
   210     void PowerUp();
       
   211     void PowerDown(TPowerState);
       
   212 public:
       
   213     DSamplerPowerHandler(DGeneralsDriver* aChannel);
       
   214 public:
       
   215     DGeneralsDriver* iChannel;
       
   216     };
       
   217 
   193 
   218 
   194 /*
   219 /*
   195  *
   220  *
   196  *
   221  *
   197  *	Class DGeneralsProfilerFactory implementation
   222  *	Class DGeneralsProfilerFactory implementation
   217     iVersion=TVersion(1,0,1);
   242     iVersion=TVersion(1,0,1);
   218     }
   243     }
   219 
   244 
   220 DGeneralsProfilerFactory::~DGeneralsProfilerFactory()
   245 DGeneralsProfilerFactory::~DGeneralsProfilerFactory()
   221     {
   246     {
   222 //    if (gDfcQ)
   247     if (gDfcQ)
   223 //        {
   248         {
   224 //        gDfcQ->Destroy();
   249         gDfcQ->Destroy();
   225 //        }
   250         }
   226     }
   251     }
   227 
   252 
   228 TInt DGeneralsProfilerFactory::Install()
   253 TInt DGeneralsProfilerFactory::Install()
   229     {
   254     {
       
   255     // Allocate a kernel thread to run the DFC 
       
   256     TInt r = Kern::DynamicDfcQCreate(gDfcQ, KDSamplerThreadPriority, KGeneralsDriverThread);
       
   257     if (r != KErrNone)
       
   258         {
       
   259         return r;
       
   260         }
       
   261 
   230     return(SetName(&KPluginSamplerName));
   262     return(SetName(&KPluginSamplerName));
   231     }
   263     }
   232 
   264 
   233 void DGeneralsProfilerFactory::GetCaps(TDes8& aDes) const
   265 void DGeneralsProfilerFactory::GetCaps(TDes8& aDes) const
   234     {
   266     {
   273 	iEndRequestStatus = 0;
   305 	iEndRequestStatus = 0;
   274 	doingDfc = 0;
   306 	doingDfc = 0;
   275 	sampleRunning = 0;
   307 	sampleRunning = 0;
   276 	iSyncOffset = 0;
   308 	iSyncOffset = 0;
   277 	iStartTime = 0;
   309 	iStartTime = 0;
       
   310 	postSampleNeeded = 0;
   278 	InitialiseSamplerList();
   311 	InitialiseSamplerList();
   279     }
   312     }
   280 
   313 
   281 /*
   314 /*
   282  *
   315  *
   304 	iSamplers[i] = &priSampler;i++;
   337 	iSamplers[i] = &priSampler;i++;
   305 	
   338 	
   306 #ifdef __SMP__
   339 #ifdef __SMP__
   307     // get the number of cpus
   340     // get the number of cpus
   308     iMaxCpus = NKern::NumberOfCpus();
   341     iMaxCpus = NKern::NumberOfCpus();
       
   342     for(TInt nCpu(0); nCpu < iMaxCpus; nCpu++)
       
   343         {
       
   344         iInterruptCounter[nCpu] = 0;
       
   345         }
       
   346 
   309 #else
   347 #else
   310     iMaxCpus = 0;
   348     iMaxCpus = 0;
   311 #endif
   349 #endif
   312     
   350     
   313 	// initialize synchronizing property
   351 	// initialize synchronizing property
   314 	LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - initializing property");
   352 	LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - initializing property");
   315 	TInt r(iSampleStartTimeProp.Attach(KGppPropertyCat, EGppPropertySyncSampleNumber));
   353 	TInt r(iSampleStartTimeProp.Attach(KGppPropertyCat, EGppPropertySyncSampleNumber));
   316     if (r!=KErrNone)
   354     if (r!=KErrNone)
   317         {
   355         {
   318         LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in attaching counter property, error %d", r);
   356         Kern::Printf("DGeneralsDriver::InitialiseSamplerList() - error in attaching counter property, error %d", r);
   319         }
   357         }
   320     LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - defining properties");
   358     LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - defining properties");
   321     r = iSampleStartTimeProp.Define(RProperty::EInt, KAllowAllPolicy, KDenyAllPolicy, 0, NULL);
   359     r = iSampleStartTimeProp.Define(RProperty::EInt, KAllowAllPolicy, KDenyAllPolicy, 0, NULL);
   322     if (r!=KErrNone)
   360     if (r!=KErrNone)
   323         {
   361         {
   324         LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in defining counter property, error %d", r);
   362         Kern::Printf("DGeneralsDriver::InitialiseSamplerList() - error in defining counter property, error %d", r);
   325         }	
   363         }
   326 	}
   364 	}
   327 
   365 
   328 
   366 
   329 DProfilerSamplerBase* DGeneralsDriver::GetSamplerForId(TInt samplerIdToGet)
   367 DProfilerSamplerBase* DGeneralsDriver::GetSamplerForId(TInt samplerIdToGet)
   330     {
   368     {
   339     }
   377     }
   340 
   378 
   341 TInt DGeneralsDriver::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer)
   379 TInt DGeneralsDriver::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer)
   342     {
   380     {
   343     TUint8 err(KErrNone);
   381     TUint8 err(KErrNone);
   344     
   382     LOGSTRING("DGeneralsDriver::DoCreate()");
   345     if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
   383     if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
   346 	   	return KErrNotSupported;
   384 	   	return KErrNotSupported;
   347     
   385     
   348     // just for testing 
   386     // just for testing 
   349 #ifndef __SMP__
   387 #ifndef __SMP__
   359     if (clientProcess)
   397     if (clientProcess)
   360         {
   398         {
   361         //Require Power Management and All Files to use this driver
   399         //Require Power Management and All Files to use this driver
   362         // Not ideal, but better than nothing
   400         // Not ideal, but better than nothing
   363         if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
   401         if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
       
   402             {
       
   403             Kern::Printf("DGeneralsDriver::CurrentThreadHasCapability - denied");
   364             return KErrPermissionDenied;
   404             return KErrPermissionDenied;
       
   405             }
   365         if(!Kern::CurrentThreadHasCapability(ECapabilityAllFiles,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
   406         if(!Kern::CurrentThreadHasCapability(ECapabilityAllFiles,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
   366             return KErrPermissionDenied;  
   407             {
       
   408                 Kern::Printf("DGeneralsDriver::CurrentThreadHasCapability - denied");
       
   409                 return KErrPermissionDenied;
       
   410             }
   367         
   411         
   368         SSecurityInfo secureInfo = clientProcess->iS;
   412         SSecurityInfo secureInfo = clientProcess->iS;
   369         if (secureInfo.iSecureId != KProfilerExeSecurUid)
   413         if (secureInfo.iSecureId != KProfilerExeSecurUid)
   370             {
   414             {
       
   415             Kern::Printf("DGeneralsDriver::security - denied");
   371             return KErrPermissionDenied;
   416             return KErrPermissionDenied;
   372             }
   417             }
   373         }
   418         }
   374     
   419     
   375     // initiate sample stream ready for collecting the trace data
   420     // initiate sample stream ready for collecting the trace data
   376 	iSampleStream.InsertCurrentClient(iClient);
   421 	iSampleStream.InsertCurrentClient(iClient);
   377 	
   422 	
   378 	iTimer.Cancel();
   423 	iTimer.Cancel();
   379 	iNewDfc.Cancel();
   424 	iNewDfc.Cancel();
   380 
   425 
   381 	Kern::SetThreadPriority(24);
   426 	Kern::SetThreadPriority(KGeneralsDriverThreadPriority);
   382 
   427 
   383 #ifdef SEPARATE_DFC_QUEUE
   428     SetDfcQ(gDfcQ);
   384 	err = Kern::DynamicDfcQCreate(iDfcQ, KGeneralsDriverThreadPriority, TBuf8<32>( KGeneralsDriverThread ));
   429     iNewDfc.SetDfcQ(iDfcQ);
   385 	if (KErrNone == err)
   430     iMsgQ.Receive();
   386         {
   431 	
   387         SetDfcQ(iDfcQ);
   432 	// create the power handler
   388         iNewDfc.SetDfcQ(iDfcQ);
   433     iPowerHandler = new DSamplerPowerHandler(this);
   389         iMsgQ.Receive();
   434     if (!iPowerHandler)
   390         return err;
   435         {
   391         }
   436         Kern::Printf("DGeneralsDriver::DoCreate() : new DSamplerPowerHandler(this) failed");
   392 #else
   437         return KErrNoMemory;
   393 	SetDfcQ(Kern::DfcQue0());
   438         }
   394 	iNewDfc.SetDfcQ(iDfcQ);
   439     iPowerHandler->Add();
   395 	iMsgQ.Receive();
       
   396 #endif
       
   397 	return err;
   440 	return err;
   398     }
   441     }
   399 
   442 
   400 DGeneralsDriver::~DGeneralsDriver()
   443 DGeneralsDriver::~DGeneralsDriver()
   401     {
   444     {
   402 	if (iState!=EStopped)
   445 	if (iState!=EStopped)
   403 	    iTimer.Cancel();
   446 	    iTimer.Cancel();
   404 	iNewDfc.Cancel();
   447 	iNewDfc.Cancel();
   405 	
       
   406 #ifdef SEPARATE_DFC_QUEUE
       
   407 	if(iDfcQ)
       
   408 	    iDfcQ->Destroy();
       
   409 #endif
       
   410 	
   448 	
   411 	iSampleStartTimeProp.Close();
   449 	iSampleStartTimeProp.Close();
   412 	Kern::SafeClose((DObject*&)iClient,NULL);
   450 	Kern::SafeClose((DObject*&)iClient,NULL);
   413     }
   451     }
   414 
   452 
   448 	// always use this rate
   486 	// always use this rate
   449 	iPeriod = aDelay;
   487 	iPeriod = aDelay;
   450 	
   488 	
   451 #ifdef __SMP__
   489 #ifdef __SMP__
   452     /*
   490     /*
   453      * Bind and enable the sampling interupts associated with each core. 
   491      * Bind and enable the sampling interrupts 
   454      */
   492      */
   455     TInt err(0);
   493     TInt err(0);
   456     
   494     TUint32 flags(NKern::EIrqBind_Count);
   457     TUint32 flags = NKern::EIrqBind_Count;
   495     TInt noofCpu(NKern::NumberOfCpus());
   458 
   496 
   459 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
   497     //Binding to the interrupt(s)
   460     err = NKern::InterruptBind( KIntProfilerBase - 32 , DGeneralsDriver::Sample, this, flags, 0);
   498     for( TInt nCpu(0); nCpu < noofCpu; nCpu++ )
   461     if(err < 0)
   499         {
   462         Kern::Printf(" InterruptBind KIntProfilerBase - 32 ret = %d", err );
   500         LOGSTRING3(" > Interrupt::InterruptBind %d + %d - 32", iIntNo, nCpu );
   463     
   501         err = NKern::InterruptBind( (iIntNo + nCpu - 32) , DGeneralsDriver::Sample, this, flags, 0);
   464 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
   502         if(err < 0)
   465     err = NKern::InterruptBind( KIntProfilerBase + 1 - 32 , DGeneralsDriver::Sample, this, flags, 0);
   503             {
   466     if(err < 0)
   504             Kern::Printf(" InterruptBind %d + %d - 32 Error = 0x%x", iIntNo, nCpu, err );
   467         Kern::Printf(" InterruptBind KIntProfilerBase + 1 - 32 ret = %d", err );
   505             return err;
   468 
   506             }
   469 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
   507         }
   470     err = NKern::InterruptBind(KIntProfilerBase + 2 - 32 , DGeneralsDriver::Sample, this, flags, 0);
   508      
   471     if(err < 0)
   509     //Enabling Interrupt(s)
   472         Kern::Printf(" InterruptBind KIntProfilerBase + 2 - 32 ret = %d", err );
   510     for( TInt nCpu(0); nCpu < noofCpu; nCpu++ )
   473 
   511         {
   474 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
   512         LOGSTRING3(" > NKern::InterruptEnable %d + %d - 32", iIntNo, nCpu );
   475     err = NKern::InterruptBind(KIntProfilerBase + 3 - 32 , DGeneralsDriver::Sample, this, flags, 0);
   513         err = NKern::InterruptEnable(iIntNo + nCpu - 32);
   476     if(err < 0)
   514         if(err < 0)
   477         Kern::Printf(" InterruptBind KIntProfilerBase + 3 - 32 ret = %d", err );
   515             {
   478 
   516             Kern::Printf(" InterruptEnable %d + %d - 32 ret = 0x%x", iIntNo, nCpu, err );
   479 
   517             return err;
   480     err = NKern::InterruptEnable(KIntProfilerBase - 32);
   518             }
   481     if(err < 0)
       
   482         Kern::Printf(" InterruptEnable KIntProfilerBase - 32 ret = %d", err );
       
   483     
       
   484     err = NKern::InterruptEnable(KIntProfilerBase + 1 - 32);
       
   485     if(err < 0)
       
   486         Kern::Printf(" InterruptEnable KIntProfilerBase + 1 - 32 ret = %d", err );
       
   487 
       
   488     err = NKern::InterruptEnable(KIntProfilerBase + 2 - 32);
       
   489     if(err < 0)
       
   490         Kern::Printf(" InterruptEnable KIntProfilerBase + 2 - 32 ret = %d", err );
       
   491 
       
   492     err = NKern::InterruptEnable(KIntProfilerBase + 3 - 32);
       
   493     if(err < 0)
       
   494         Kern::Printf(" InterruptEnable KIntProfilerBase + 3 - 32 ret = %d", err );
       
   495         
   519         
       
   520         /* For Bridge we enable one single interrupt for CPU 1 */
       
   521        if(iPlatform == EBridge)
       
   522            break;
       
   523         }
       
   524         
   496 #endif
   525 #endif
   497 	
   526 	
   498 	iTimer.OneShot(aDelay);
   527 	iTimer.OneShot(aDelay);
   499 	
   528 	
   500 	iState = ERunning;
   529 	iState = ERunning;
   501 
   530 
   502 	return KErrNone;
   531 	return KErrNone;
   503     }
   532     }
       
   533 
       
   534 void DGeneralsDriver::IncrementSampleNeededState(TInt aId)
       
   535     {
       
   536     LOGSTRING2("DGeneralsDriver::IncrementSampleNeededState() - incrementing sample needed state, caller id: %d", (aId+1));
       
   537 #ifdef __SMP__
       
   538     TInt intState(0);
       
   539     intState = __SPIN_LOCK_IRQSAVE(PiSpinLock);
       
   540 #endif
       
   541     postSampleNeeded++;
       
   542 #ifdef __SMP__
       
   543     __SPIN_UNLOCK_IRQRESTORE(PiSpinLock, intState);
       
   544 #endif
       
   545     }
       
   546 
       
   547 void DGeneralsDriver::DecrementSampleNeededState()
       
   548     {
       
   549     LOGSTRING("DGeneralsDriver::DecrementSampleNeededState() - decrementing sample needed state");
       
   550 #ifdef __SMP__
       
   551     TInt intState(0);
       
   552     intState = __SPIN_LOCK_IRQSAVE(PiSpinLock);
       
   553 #endif
       
   554     postSampleNeeded--;
       
   555 #ifdef __SMP__
       
   556     __SPIN_UNLOCK_IRQRESTORE(PiSpinLock, intState);
       
   557 #endif
       
   558     }
       
   559 
   504 
   560 
   505 /*
   561 /*
   506  *	This function is run in each interrupt
   562  *	This function is run in each interrupt
   507  */
   563  */
   508 // EKA-2 implementation of the sampler method
   564 // EKA-2 implementation of the sampler method
   509 
   565 
   510 void DGeneralsDriver::NewDoProfilerProfile(TAny* aPtr)
   566 void DGeneralsDriver::NewDoProfilerProfile(TAny* aPtr)
   511     {
   567     {
   512     LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - entry");
   568     LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - entry");
   513     
   569     DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
   514 #ifdef __SMP__      
   570 #ifdef __SMP__      
   515     TInt currCpu(NKern::CurrentCpu());
   571     TInt currCpu(NKern::CurrentCpu());
   516 #endif
   572 #endif
   517     TInt8 postSampleNeeded(0);
   573 
       
   574     if(!d.iOff)
       
   575         {
       
   576         if (d.iState == ERunning && d.sampleRunning == 0)
       
   577             {
       
   578             // start timer again
       
   579             d.iTimer.Again(d.iPeriod);
       
   580             d.sampleRunning++;
       
   581 
       
   582 #ifdef __SMP__      
       
   583             // print out the sample tick
       
   584             if(d.gppSampler.GetExportData()->sampleNumber% 1000 == 0) 
       
   585                 {
       
   586                 Kern::Printf(("PIPROF SAMPLE TICK, #%d"), d.gppSampler.GetExportData()->sampleNumber);
       
   587                 }
       
   588             
       
   589             // call the actual CPU sampling function for CPU 0 (in NaviEngine), later may be on any of the CPUs
       
   590             Sample(aPtr);
       
   591             
       
   592             /* 
       
   593             This is the master sampler from the watchdog timer, so 
       
   594             send interrupts to the other CPU(s)
       
   595             */
       
   596             TScheduler *theSched = TScheduler::Ptr();
       
   597 //            GicDistributor* gicDist = (GicDistributor* )theSched->i_GicDistAddr;
       
   598             GicDistributor* gicDist = (GicDistributor* )(theSched->iSX.iGicDistAddr);
       
   599             
       
   600             // post-sampling for NTimer interrupted CPU
       
   601             //d.postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
       
   602             
       
   603             if (d.iPlatform == EBridge)
       
   604                 {
       
   605                 /* The Interrupt ID is hardcoded for Bridge to be 108/117, using SPI on ARM GIC
       
   606                  * Programming the GIC Distributor Set-Pending Register to raise an interrupt
       
   607                  * Programming the GIC Distributor Target Register to set an interrupt in CPU 1
       
   608                  */
       
   609             
       
   610                 /* Interrupt Processor Targets Registers (ICDIPTRn)
       
   611                  * target register  ICDIPTR number, M, is given by M = N DIV 4
       
   612                  * so M is 27 for N = 108/117
       
   613                  * NTimer interrupt is always defaulted to CPU 0 so we have to interrupt CPU 1
       
   614                  * setting 0bxxxxxx1x CPU interface 1
       
   615                  */
       
   616 //                gicDist->iTarget[27] |= 0x00000002; 
       
   617 //                gicDist->iTarget[27] &= 0xFE;
       
   618                 gicDist->iTarget[29] |= 0x00000200; 
       
   619                 gicDist->iTarget[29] &= 0xFFFFFEFF;
       
   620 
       
   621                 /* Interrupt Set-Pending Registers (ICDISPRn) 
       
   622                  * the corresponding ICDISPR number, M, is given by M = N DIV 32
       
   623                  * M = 3 for N being 108/117
       
   624                  * the bit number of the required Set-pending bit in this register is N MOD 32
       
   625                  * which in this case is 12
       
   626                  */ 
       
   627 //                gicDist->iPendingSet[3] = 1<<((12));  // N = 108
       
   628                 gicDist->iPendingSet[3] = 1<<((21));    // N = 117
       
   629 
       
   630                 arm_dsb();
       
   631                 
       
   632                 }
       
   633             else if (d.iPlatform == ENaviengine) //naviengine platform
       
   634                 {
       
   635                 for( TInt nCpu(0); nCpu < NKern::NumberOfCpus(); nCpu++ )
       
   636                     {
       
   637                     if( nCpu != currCpu )
       
   638                         {
       
   639                         //Kern::Printf(("DProfile::TimerSampleIsr() > iSoftIrq: to cpu%d, 0x%08X"), nCpu, ( 0x10000 << nCpu ) | (d.iIntNo + nCpu));
       
   640                         gicDist->iSoftIrq = ( 0x10000 << nCpu ) | (d.iIntNo + nCpu);
       
   641                         }
       
   642                     // post-sampling for CPUs with specifically generated interrupts
       
   643                     //d.postSampleNeeded += d.iSamplers[nCpu]->PostSampleNeeded();
       
   644                     }
       
   645                 arm_dsb();
       
   646                
       
   647                 }
       
   648             else
       
   649                 {
       
   650                 Kern::Printf("DGeneralsDriver::NewDoProfilerProfile - SMP Platform not recognised " ); 
       
   651                 }
       
   652 
       
   653 #endif  
       
   654             // then sample the rest of non-cpu samplers
       
   655             for(TInt i(0);i<KSamplerAmount;i++)
       
   656                 {
       
   657                 if(d.iSamplers[i]->iEnabled)
       
   658                     {
       
   659                     d.iSamplers[i]->Sample(aPtr);
       
   660                     if(d.iSamplers[i]->PostSampleNeeded())
       
   661                         {
       
   662                         d.IncrementSampleNeededState(i);
       
   663                         }
       
   664                     }
       
   665                 }
       
   666 
       
   667 //            // check if post sampling is needed for samplers
       
   668 //            for(TInt i(0);i<KSamplerAmount;i++)
       
   669 //                {
       
   670 //                if(d.iSamplers[i]->iEnabled)
       
   671 //                    {
       
   672 //                    if(d.iSamplers[i]->PostSampleNeeded())
       
   673 //                        {
       
   674 //                        d.IncrementSampleNeededState(i);
       
   675 //                        }
       
   676 //                    }
       
   677 //                }
       
   678 
       
   679             if(d.postSampleNeeded > 0 && d.doingDfc == 0)
       
   680             //if(d.postSampleNeeded > 0)
       
   681                 {
       
   682                 LOGSTRING2("DGeneralsDriver::NewDoProfilerProfile - postSampleNeeded count %d ", d.postSampleNeeded );
       
   683                 d.doingDfc++;
       
   684                 d.iNewDfc.Add();
       
   685         
       
   686                 d.sampleRunning--;
       
   687         
       
   688                 return;
       
   689                 }
       
   690             d.sampleRunning--;
       
   691             }   // if (d.iState == ERunning && d.sampleRunning == 0)
       
   692         else if (d.iState == EStopping && d.sampleRunning == 0)
       
   693             {
       
   694             // add a dfc for this final time
       
   695             d.iNewDfc.Add();
       
   696             LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - sampling added to dfc queue");
       
   697             }
       
   698         else
       
   699             {
       
   700             // the previous sample has not finished,
       
   701             Kern::Printf("DGeneralsDriver::NewDoProfilerProfile - Profiler Sampler Error - interrupted before finished sampling!!");
       
   702             }
       
   703         LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - exit");
       
   704         } // iOff
       
   705     else
       
   706         {
       
   707         Kern::Printf("DGeneralsDriver::iOff");
       
   708         }
       
   709 }
       
   710 
       
   711 
       
   712 void DGeneralsDriver::Sample(TAny* aPtr)
       
   713     {
       
   714     LOGSTRING("DGeneralsDriver::Sample - entry");
       
   715 
       
   716 #ifdef __SMP__
   518     DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
   717     DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
   519 
   718 
   520 	if (d.iState == ERunning && d.sampleRunning == 0)
   719     TInt currCpu(NKern::CurrentCpu());
   521 	    {
   720     ++d.iInterruptCounter[currCpu];
   522         // start timer again
   721 
   523 		d.iTimer.Again(d.iPeriod);
   722     d.iSamplers[currCpu]->Sample(aPtr);
   524 		d.sampleRunning++;
       
   525         
       
   526 #ifdef __SMP__      
       
   527         // print out the sample tick
       
   528         if(d.gppSampler.GetExportData()->sampleNumber% 1000 == 0) 
       
   529             {
       
   530             Kern::Printf(("PIPROF SAMPLE TICK, #%d"), d.gppSampler.GetExportData()->sampleNumber);
       
   531             }
       
   532         // call the actual CPU sampling function for CPU 0 (in NaviEngine), later may be on any of the CPUs
       
   533         Sample(aPtr);
       
   534         
       
   535         // post-sampling for NTimer interrupted CPU
       
   536         postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
       
   537         
       
   538         /* 
       
   539         This is the master sampler from the watchdog timer, so 
       
   540         send interrupts to the other CPUs
       
   541         */
       
   542         TScheduler *theSched = TScheduler::Ptr();
       
   543         GicDistributor* gicDist = (GicDistributor* )theSched->i_GicDistAddr;
       
   544             
       
   545         for( TInt nCpu(0); nCpu < d.iMaxCpus; nCpu++ )
       
   546             {
       
   547             if( nCpu != currCpu )
       
   548                 {
       
   549                 gicDist->iSoftIrq = ( 0x10000 << nCpu ) | (KIntProfilerBase + nCpu);
       
   550                 }
       
   551             // post-sampling for CPUs with specifically generated interrupts
       
   552             postSampleNeeded += d.iSamplers[nCpu]->PostSampleNeeded();
       
   553             }
       
   554         arm_dsb();
       
   555 #endif  
       
   556         // then sample the rest of non-cpu samplers
       
   557         for(TInt i(d.iMaxCpus);i<KSamplerAmount;i++)
       
   558             {
       
   559             if(d.iSamplers[i]->iEnabled)
       
   560                 {
       
   561                 d.iSamplers[i]->Sample();
       
   562                 postSampleNeeded += d.iSamplers[i]->PostSampleNeeded();
       
   563                 }
       
   564             }
       
   565 			
       
   566 		if(postSampleNeeded > 0 && d.doingDfc == 0)
       
   567 		    {
       
   568 			d.doingDfc++;
       
   569 			d.iNewDfc.Add();
       
   570 
       
   571 			d.sampleRunning--;
       
   572 			return;
       
   573             }
       
   574 		d.sampleRunning--;
       
   575         }
       
   576 	else if (d.iState == EStopping && d.sampleRunning == 0)
       
   577 	    {
       
   578 		// add a dfc for this final time
       
   579 		d.iNewDfc.Add();
       
   580         Kern::Printf("DGeneralsDriver::Sample - sampling added to dfc queue");
       
   581         }
       
   582 	else
       
   583 	    {
       
   584 		// the previous sample has not finished,
       
   585 		Kern::Printf("DGeneralsDriver::NewDoProfilerProfile - Profiler Sampler Error - interrupted before finished sampling!!");
       
   586         }
       
   587         LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - exit");
       
   588     }
       
   589 
       
   590 
       
   591 
       
   592 void DGeneralsDriver::Sample(TAny* aPtr)
       
   593     {
       
   594     LOGSTRING("DGeneralsDriver::Sample - entry");
       
   595 
       
   596 #ifdef __SMP__
       
   597     DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
       
   598 
       
   599 //    TInt currCpu(NKern::CurrentCpu());
       
   600 
       
   601     // sample the current cpu load
       
   602 //    if(d.iSamplers[currCpu]->iEnabled)
       
   603 //        {
       
   604         d.iSamplers[NKern::CurrentCpu()]->Sample();
       
   605 //        postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
       
   606 //        }
       
   607 #endif
   723 #endif
   608     LOGSTRING("DGeneralsDriver::Sample - exit");
   724     LOGSTRING("DGeneralsDriver::Sample - exit");
   609     }
   725     }
       
   726 
   610 /*
   727 /*
   611  *	This function is run when any of the samplers
   728  *	This function is run when any of the samplers
   612  *	requires post sampling
   729  *	requires post sampling
   613  */
   730  */
   614 void DGeneralsDriver::NewDoDfc(TAny* pointer)
   731 void DGeneralsDriver::NewDoDfc(TAny* pointer)
   623 		    {
   740 		    {
   624 			if(d.iSamplers[i]->iEnabled)
   741 			if(d.iSamplers[i]->iEnabled)
   625 			    {
   742 			    {
   626 				if(d.iSamplers[i]->PostSampleNeeded())
   743 				if(d.iSamplers[i]->PostSampleNeeded())
   627 				    {
   744 				    {
   628 					d.iSamplers[i]->PostSample();
   745                     LOGSTRING3("DGeneralsDriver::NewDoDfc iSamplers[%d] PostSampleNeeded count %d", i, d.postSampleNeeded);
       
   746                     d.iSamplers[i]->PostSample();
       
   747                     d.DecrementSampleNeededState();
       
   748                     LOGSTRING3("DGeneralsDriver::NewDoDfc iSamplers[%d] PostSampleNeeded count %d", i, d.postSampleNeeded);
   629                     }
   749                     }
   630                 }
   750                 }
   631             }
   751             }
   632 		d.doingDfc--;
   752 		d.doingDfc--;
   633         }
   753         }
   634 
   754 
   635 	else if(d.iState == EStopping)
   755 	else if(d.iState == EStopping)
   636 	    {
   756 	    {
       
   757         LOGSTRING("DGeneralsDriver::NewDoDfc state Stopping()");
   637 		// for all enabled samplers,
   758 		// for all enabled samplers,
   638 		// perform end sampling
   759 		// perform end sampling
   639 		TBool releaseBuffer(false);
   760 		TBool releaseBuffer(false);
   640 		for(TInt i(0);i<KSamplerAmount;i++)
   761 		for(TInt i(0);i<KSamplerAmount;i++)
   641 		    {
   762 		    {
   642 			if(d.iSamplers[i]->iEnabled)
   763 			if(d.iSamplers[i]->iEnabled)
   643 			    {
   764 			    {
   644 				LOGSTRING("DGeneralsDriver::NewDoDfc() - ending");
   765                 LOGSTRING("DGeneralsDriver::NewDoDfc() - ending");
       
   766                 if(d.iSamplers[i]->PostSampleNeeded())
       
   767                     {
       
   768                     LOGSTRING2("DGeneralsDriver::NewDoDfc iSamplers[%d] PostSampleNeeded still", i);
       
   769                     d.iSamplers[i]->PostSample();
       
   770                     }
   645 				// perform end sampling for all samplers
   771 				// perform end sampling for all samplers
   646 				// stream mode samplers may be pending, if they
   772 				// stream mode samplers may be pending, if they
   647 				// are still waiting for another client buffer
   773 				// are still waiting for another client buffer
   648 				if(d.iSamplers[i]->EndSampling() == KErrNotReady) 
   774 				if(d.iSamplers[i]->EndSampling() == KErrNotReady) 
   649 				    {
   775 				    {
   650 					LOGSTRING("DGeneralsDriver::NewDoDfc() - stream data pending");
   776                     LOGSTRING("DGeneralsDriver::NewDoDfc() - stream data pending");
   651 					releaseBuffer = true;
   777 					releaseBuffer = true;
   652                     }
   778                     }
   653 				else 
   779 				else 
   654 				    {
   780 				    {
   655 					LOGSTRING("DGeneralsDriver::NewDoDfc() - no data pending");
   781                     LOGSTRING("DGeneralsDriver::NewDoDfc() - no data pending");
   656 					releaseBuffer = true;
   782 					releaseBuffer = true;
   657                     }		
   783                     }		
   658                 }
   784                 }
   659             }
   785             }
   660 
   786 
   661 		// At the end, once all the samplers are gone through, the buffer should be released
   787 		// At the end, once all the samplers are gone through, the buffer should be released
   662 		if (true == releaseBuffer) 
   788 		if (true == releaseBuffer) 
   663 		    {
   789 		    {
   664 			LOGSTRING("DGeneralsDriver::NewDoDfc() - release the buffer");
   790             LOGSTRING("DGeneralsDriver::NewDoDfc() - release the buffer");
   665 			d.iSampleStream.ReleaseIfPending();	
   791 			d.iSampleStream.ReleaseIfPending();	
   666             }
   792             }
   667 		
   793 		
   668 		d.iState = EStopped;
   794 		d.iState = EStopped;
   669 		if(d.iEndRequestStatus != 0 && d.iClient != 0)
   795 		if(d.iEndRequestStatus != 0 && d.iClient != 0)
   670 		    {
   796 		    {
   671 			// sampling has ended
   797 			// sampling has ended
   672 			Kern::RequestComplete(d.iClient,d.iEndRequestStatus,KErrNone);
   798 			Kern::RequestComplete(d.iClient,d.iEndRequestStatus,KErrNone);
       
   799 			LOGSTRING("DGeneralsDriver::NewDoDfc() - request complete, stopped");
   673             }
   800             }
   674         }
   801         }
   675     }
   802     }
   676 
   803 
   677 
   804 
   744 			//r = Sample();  // hack. Original implementation of sample just returned 0
   871 			//r = Sample();  // hack. Original implementation of sample just returned 0
   745 			r = 0;
   872 			r = 0;
   746 			break;
   873 			break;
   747 
   874 
   748 		case RPluginSampler::EStartSampling:
   875 		case RPluginSampler::EStartSampling:
   749 			LOGSTRING("DGeneralsDriver::HandleMsg - EStartSampling");
   876 		    LOGSTRING("DGeneralsDriver::HandleMsg - EStartSampling");
   750 			r = StartSampling();
   877 			iStarted = (TUint8)ETrue;
       
   878 			r=StartSampling(m.Int0(),m.Int1());
       
   879 			//r = StartSampling();
   751 			break;
   880 			break;
   752 
   881 
   753 		case RPluginSampler::EGetSampleTime:
   882 		case RPluginSampler::EGetSampleTime:
   754 			LOGSTRING("DGeneralsDriver::HandleMsg - EGetSampleTime");
   883 			LOGSTRING("DGeneralsDriver::HandleMsg - EGetSampleTime");
   755 			r = GetSampleTime(reinterpret_cast<TUint32*>(m.Ptr0()));
   884 			r = GetSampleTime(reinterpret_cast<TUint32*>(m.Ptr0()));
   768 
   897 
   769 
   898 
   770 		 //	Requests are handled here
   899 		 //	Requests are handled here
   771 
   900 
   772 		case ~RPluginSampler::EStopAndWaitForEnd:
   901 		case ~RPluginSampler::EStopAndWaitForEnd:
   773 			LOGSTRING("DGeneralsDriver::HandleMsg - EStopAndWaitForEnd");
   902             LOGSTRING("DGeneralsDriver::HandleMsg - EStopAndWaitForEnd");
   774 			iEndRequestStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0());
   903 			iEndRequestStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0());
   775 			r = StopSampling();
   904 			r = StopSampling();
   776 #ifdef __SMP__
   905 #ifdef __SMP__
   777 			UnbindInterrupts();
   906 			UnbindInterrupts();
   778 #endif
   907 #endif
   783 			r = ProcessStreamReadRequest(	reinterpret_cast<TBapBuf*>(m.Ptr1()),
   912 			r = ProcessStreamReadRequest(	reinterpret_cast<TBapBuf*>(m.Ptr1()),
   784 											reinterpret_cast<TRequestStatus*>(m.Ptr0()));
   913 											reinterpret_cast<TRequestStatus*>(m.Ptr0()));
   785 			break;
   914 			break;
   786 
   915 
   787 		default:
   916 		default:
   788 			LOGSTRING2("DGeneralsDriver::HandleMsg - ERROR, unknown command %d",id);
   917 			Kern::Printf("DGeneralsDriver::HandleMsg - ERROR, unknown command %d",id);
   789 			r = KErrNotSupported;
   918 			r = KErrNotSupported;
   790 			break;
   919 			break;
   791         }
   920         }
   792 
   921 
   793 	LOGSTRING("DGeneralsDriver::HandleMsg - Completed");
   922 	LOGSTRING("DGeneralsDriver::HandleMsg - Completed");
   796 
   925 
   797 #ifdef __SMP__
   926 #ifdef __SMP__
   798 inline void DGeneralsDriver::UnbindInterrupts()
   927 inline void DGeneralsDriver::UnbindInterrupts()
   799     {
   928     {
   800     TInt err(0);
   929     TInt err(0);
   801 
   930         /*
   802     // disable interrupts when sampling stops, enabled again on start
   931          * Disable and unbind the sampling interrupts associated with each core. 
   803     err = NKern::InterruptDisable(KIntProfilerBase - 32);
   932          */
   804     if(err < 0)
   933         TInt noofCpu(NKern::NumberOfCpus());
   805         Kern::Printf(" InterruptDisable KIntProfilerBase - 32 ret = %d", err );
   934         //Disabling Interrupt(s)
   806     
   935         for( TInt nCpu(0); nCpu < noofCpu; nCpu++ )
   807     err = NKern::InterruptDisable(KIntProfilerBase + 1 - 32);
   936             {
   808     if(err < 0)
   937             err = NKern::InterruptDisable(iIntNo + nCpu - 32);
   809         Kern::Printf(" InterruptDisable KIntProfilerBase + 1 - 32 ret = %d", err );
   938             if(err < 0)
   810 
   939                 {
   811     err = NKern::InterruptDisable(KIntProfilerBase + 2 - 32);
   940                 Kern::Printf(" Interrupt Disable iIntNo + %d - 32 ret = %d", nCpu, err );
   812     if(err < 0)
   941                 }
   813         Kern::Printf(" InterruptDisable KIntProfilerBase + 2 - 32 ret = %d", err );
   942             }
   814 
   943         
   815     err = NKern::InterruptDisable(KIntProfilerBase + 3 - 32);
   944         //UnBinding to the interrupt(s)
   816     if(err < 0)
   945         for( TInt nCpu(0); nCpu < noofCpu; nCpu++ )
   817         Kern::Printf(" InterruptDisable KIntProfilerBase + 3 - 32 ret = %d", err );
   946             {
   818     
   947             LOGSTRING3(" > Interrupt::InterruptUnBind + %d -32 =%d", nCpu, iIntNo + nCpu -32 );
   819 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
   948             err = NKern::InterruptUnbind( (iIntNo + nCpu - 32) );
   820     err = NKern::InterruptUnbind( KIntProfilerBase - 32);
   949             if(err < 0)
   821     if(err < 0)
   950                 {
   822         Kern::Printf(" InterruptUnbind KIntProfilerBase - 32 ret = %d", err );
   951                 Kern::Printf(" InterruptUnBind iIntNo + %d - 32 Error = %d", nCpu, err );
   823     
   952                 }
   824 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
   953             }
   825     err = NKern::InterruptUnbind( KIntProfilerBase + 1 - 32);
       
   826     if(err < 0)
       
   827         Kern::Printf(" InterruptUnbind KIntProfilerBase + 1 - 32 ret = %d", err );
       
   828 
       
   829 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
       
   830     err = NKern::InterruptUnbind(KIntProfilerBase + 2 - 32);
       
   831     if(err < 0)
       
   832         Kern::Printf(" InterruptUnbind KIntProfilerBase + 2 - 32 ret = %d", err );
       
   833 
       
   834 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
       
   835     err = NKern::InterruptUnbind(KIntProfilerBase + 3 - 32);
       
   836     if(err < 0)
       
   837         Kern::Printf(" InterruptUnbind KIntProfilerBase + 3 - 32 ret = %d", err );
       
   838 
       
   839     }
   954     }
   840 #endif
   955 #endif
   841 
   956 
   842 inline TInt DGeneralsDriver::ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus)
   957 inline TInt DGeneralsDriver::ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus)
   843 	{
   958 	{
   863 				// stream mode samplers may be pending, if they
   978 				// stream mode samplers may be pending, if they
   864 				// are still waiting for another client buffer,
   979 				// are still waiting for another client buffer,
   865 				// in that case, the request should be completed already
   980 				// in that case, the request should be completed already
   866 				if(iSamplers[i]->EndSampling() == KErrNotReady) 
   981 				if(iSamplers[i]->EndSampling() == KErrNotReady) 
   867 				    {
   982 				    {
   868 					LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - still data pending");
   983                     LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - still data pending");
   869 					releaseBuffer = true;
   984 					releaseBuffer = false;
   870                     }
   985                     }
   871 				else 
   986 				else 
   872 				    {
   987 				    {
   873 					LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - no data pending");
   988                     LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - no data pending");
   874 					releaseBuffer = true;
   989 					releaseBuffer = true;
   875                     }
   990                     }
   876                 }
   991                 }
   877             }
   992             }
   878 		// At the end, once all the samplers are gone through, the buffer should be released
   993 		// At the end, once all the samplers are gone through, the buffer should be released
   879 		if (true == releaseBuffer) 
   994 		if (true == releaseBuffer) 
   880 		    {
   995 		    {
   881 			LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - all data copied, release the buffer");
   996             LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - all data copied, release the buffer");
   882 			iSampleStream.ReleaseIfPending();
   997 			iSampleStream.ReleaseIfPending();
   883 		    }
   998 		    }
   884         }
   999         }
   885 	LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - exit");
  1000 	LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - exit");
   886 	
  1001 	
   901 #ifdef __SMP__
  1016 #ifdef __SMP__
   902 	cpus = NKern::NumberOfCpus();
  1017 	cpus = NKern::NumberOfCpus();
   903 	if( samplerIdToActivate == PROFILER_GPP_SAMPLER_ID )
  1018 	if( samplerIdToActivate == PROFILER_GPP_SAMPLER_ID )
   904 	    {
  1019 	    {
   905 	    for(TInt cpu(0);cpu<cpus;cpu++)
  1020 	    for(TInt cpu(0);cpu<cpus;cpu++)
   906 	         {
  1021             {
   907 	         Kern::Printf("DGeneralsDriver::MarkTraceActive - activating CPU %d",cpu);
  1022             LOGSTRING2("DGeneralsDriver::MarkTraceActive - activating CPU %d",cpu);
   908 	         iSamplers[cpu]->SetEnabledFlag(true);
  1023             iSamplers[cpu]->SetEnabledFlag(true);
   909 	         }
  1024             }
   910 	    return KErrNone;
  1025 	    return KErrNone;
   911 	    }
  1026 	    }
   912 #endif
  1027 #endif
   913 	for(TInt i(cpus);i<KSamplerAmount;i++)
  1028 	for(TInt i(cpus);i<KSamplerAmount;i++)
   914 	    {
  1029 	    {
   917 			iSamplers[i]->SetEnabledFlag(true);
  1032 			iSamplers[i]->SetEnabledFlag(true);
   918 			return KErrNone;
  1033 			return KErrNone;
   919             }
  1034             }
   920         }
  1035         }
   921 
  1036 
   922 	LOGSTRING2("DGeneralsDriver::MarkTraceActive - %d not supported",samplerIdToActivate);
  1037 	Kern::Printf("DGeneralsDriver::MarkTraceActive - %d not supported",samplerIdToActivate);
   923 	return KErrNotSupported;
  1038 	return KErrNotSupported;
   924 	}
  1039 	}
   925 
  1040 
   926 inline TInt DGeneralsDriver::MarkTraceInactive(TInt samplerIdToDisable)
  1041 inline TInt DGeneralsDriver::MarkTraceInactive(TInt samplerIdToDisable)
   927 	{
  1042 	{
   946 			iSamplers[i]->SetEnabledFlag(false);
  1061 			iSamplers[i]->SetEnabledFlag(false);
   947 			return KErrNone;
  1062 			return KErrNone;
   948             }
  1063             }
   949         }
  1064         }
   950 
  1065 
   951 	LOGSTRING2("DGeneralsDriver::MarkTraceInactive - %d not supported",samplerIdToDisable);
  1066 	Kern::Printf("DGeneralsDriver::MarkTraceInactive - %d not supported",samplerIdToDisable);
   952 	return KErrNotSupported;
  1067 	return KErrNotSupported;
   953 	}
  1068 	}
   954 
  1069 
   955 /*
  1070 /*
   956  *	Set output settings for a trace
  1071  *	Set output settings for a trace
  1075 /*
  1190 /*
  1076  *	Mark traces active or inactive, this can be done
  1191  *	Mark traces active or inactive, this can be done
  1077  *	only if sampling is not running
  1192  *	only if sampling is not running
  1078  */
  1193  */
  1079  
  1194  
  1080 TInt DGeneralsDriver::StartSampling()
  1195 TInt DGeneralsDriver::StartSampling(TInt aRate, TInt aInterruptNumber)
  1081 	{
  1196 	{
  1082 	LOGSTRING("DGeneralsDriver::StartSampling");
  1197 	LOGSTRING("DGeneralsDriver::StartSampling");
  1083 
  1198 
  1084 	if(iState == EStopped)
  1199 	if(iState == EStopped)
  1085 		{
  1200 		{
  1086 		// reset iSampleStartTimeProp property value
  1201 		// reset iSampleStartTimeProp property value
  1087 		iSampleStartTime = NKern::TickCount();	// get the system tick value for sync purposes 
  1202 		iSampleStartTime = NKern::TickCount();	// get the system tick value for sync purposes 
  1088 #ifdef __SMP__
  1203 #ifdef __SMP__
       
  1204 		TInt err;
  1089 		iStartTime = (iSampleStartTime & 0xfffffff0);
  1205 		iStartTime = (iSampleStartTime & 0xfffffff0);
  1090 #endif
  1206 #endif
  1091 		TInt r(iSampleStartTimeProp.Set(iSampleStartTime));
  1207 		TInt r(iSampleStartTimeProp.Set(iSampleStartTime));
  1092 		
  1208 		
  1093 		Kern::Printf(("PIPROF SAMPLE TICK, #0")); // for remote profiling with Profiler Activator
  1209 		Kern::Printf(("PIPROF SAMPLE TICK, #0")); // for remote profiling with Profiler Activator
  1097 			{
  1213 			{
  1098 			if(iSamplers[i]->iEnabled)
  1214 			if(iSamplers[i]->iEnabled)
  1099 				{
  1215 				{
  1100 				// reset with stream option
  1216 				// reset with stream option
  1101 #ifndef __SMP__
  1217 #ifndef __SMP__
  1102                 Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, sync offset %d"), 0);
  1218 				LOGSTRING2(("DGeneralsDriver::StartSampling - stream reset for generals driver, sync offset %d"), 0);
  1103 				iSamplers[i]->Reset(&iSampleStream, 0);
  1219 				iSamplers[i]->Reset(&iSampleStream, 0);
  1104 #else
  1220 #else
  1105                 Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, start time %d"), iStartTime);
  1221 				LOGSTRING2(("DGeneralsDriver::StartSampling - stream reset for generals driver, start time %d"), iStartTime);
  1106                 iSamplers[i]->Reset(&iSampleStream, iStartTime);
  1222                 iSamplers[i]->Reset(&iSampleStream, iStartTime);
  1107 #endif
  1223 #endif
  1108 				}
  1224 				}
  1109 			}
  1225 			}
  1110 
  1226 #ifdef __SMP__
       
  1227 		iRate = aRate;
       
  1228 		iIntNo = aInterruptNumber;
       
  1229 		// use HAL to understand the underlying hardware
       
  1230         // not so elegant but used for two SMP pltaforms Bridge and Naviengine
       
  1231         TVariantInfoV01 info;
       
  1232         TPckg<TVariantInfoV01> infoPckg(info);
       
  1233         err = Kern::HalFunction(EHalGroupVariant, EVariantHalVariantInfo, (TAny*)&infoPckg, NULL);
       
  1234         
       
  1235         if(err != KErrNone)
       
  1236             {
       
  1237             Kern::Printf("Error in reading HAL Entry EVariantHalVariantInfo %r ", err);
       
  1238             }
       
  1239         if (info.iMachineUniqueId.iData[0] == KBridgeMachineUID)
       
  1240             {
       
  1241             iPlatform = EBridge;
       
  1242             LOGSTRING("DGeneralsDriver::StartSampling() - Bridge HW");
       
  1243             }
       
  1244         else if (info.iMachineUniqueId.iData[0] == KNaviengineMachineUID)
       
  1245             {
       
  1246             iPlatform = ENaviengine;
       
  1247             LOGSTRING("DGeneralsDriver::StartSampling() - NaviEngine HW");
       
  1248             }
       
  1249         else
       
  1250             {
       
  1251             Kern::Printf("DGeneralsDriver::StartSampling() - Unknown HW, 0x%x", info.iMachineUniqueId.iData[0]);
       
  1252             }
       
  1253         
       
  1254         //users are restricted to use the default Interrupt Number for Bridge
       
  1255         if ((iPlatform == EBridge) && (aInterruptNumber != KValueZero) && (aInterruptNumber != KBridgeProfilerInterruptId) )
       
  1256             {
       
  1257             Kern::Printf("Invalid Interrupt Number for Bridge used %d interrupt...Please use %d Interrupt Number", iIntNo, KBridgeProfilerInterruptId);
       
  1258             return KErrNotSupported;
       
  1259             }
       
  1260         if (aInterruptNumber == KValueZero)
       
  1261                 iIntNo = KDefaultInterruptNumber;
       
  1262             
       
  1263             if (iPlatform == EBridge)   
       
  1264                 /* By default for Bridge we are using KBridgeProfilerInterruptId */
       
  1265                 iIntNo = KBridgeProfilerInterruptId;
       
  1266 #endif		
  1111 		NewStart(gppSampler.GetPeriod());
  1267 		NewStart(gppSampler.GetPeriod());
  1112 		return KErrNone;
  1268 		return KErrNone;
  1113 		}
  1269 		}
  1114 	else
  1270 	else
  1115 		{
  1271 		{
  1122  *  only if sampling is not running
  1278  *  only if sampling is not running
  1123  */
  1279  */
  1124  
  1280  
  1125 TInt DGeneralsDriver::StopSampling()
  1281 TInt DGeneralsDriver::StopSampling()
  1126     {
  1282     {
  1127     LOGSTRING("DGeneralsDriver::StopSampling");
  1283     LOGSTRING2("DGeneralsDriver::StopSampling - iState %", iState);
       
  1284     TInt noofCpu(NKern::NumberOfCpus());
  1128 
  1285 
  1129     if(iState == ERunning)
  1286     if(iState == ERunning)
  1130         {
  1287         {
  1131         this->iState = EStopping;
  1288         this->iState = EStopping;
  1132         // reset all enabled samplers
  1289         // reset all enabled samplers
  1133         for(TInt i(0);i<KSamplerAmount;i++)
  1290         for(TInt i(0);i<KSamplerAmount;i++)
  1134             {
  1291             {
  1135             // do the reset only for memory sampler
  1292             // do the reset only for memory and itt samplers
  1136             if(iSamplers[i]->iEnabled && iSamplers[i]->iSamplerId == 4)
  1293             if(iSamplers[i]->iEnabled && 
       
  1294                     (iSamplers[i]->iSamplerId == PROFILER_ITT_SAMPLER_ID || 
       
  1295                             iSamplers[i]->iSamplerId == PROFILER_MEM_SAMPLER_ID ))
  1137                 {
  1296                 {
  1138                 // reset with stream option
  1297                 // reset with stream option
  1139                 LOGTEXT(("DGeneralsDriver::StopSampling - stream reset for samplers"));
  1298                 LOGSTRING(("DGeneralsDriver::StopSampling - stream reset for samplers"));
  1140                 iSamplers[i]->Reset(&iSampleStream, 999999);
  1299                 iSamplers[i]->Reset(&iSampleStream, KStateSamplingEnding);
  1141                 }
  1300                 }
  1142             }
  1301             }
       
  1302         LOGSTRING2("\nDGeneralsDriver::StopSampling - Number of times the Timer counter expired on CPU 0 = %d ", iInterruptCounter[0]);
       
  1303         
       
  1304         for(TInt nCpu(1); nCpu < noofCpu; nCpu++)
       
  1305             {
       
  1306             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]));  
       
  1307             Kern::Printf( "\n Number of times CPU sampler[0] accessed: %d", gppSampler.GetExportData()->sampleNumber);
       
  1308 #ifdef __SMP__
       
  1309             Kern::Printf( "\n Number of times CPU sampler[1] accessed: %d", gppSampler2.GetExportData()->sampleNumber);
       
  1310 #endif
       
  1311             }
  1143 
  1312 
  1144         return KErrNone;
  1313         return KErrNone;
  1145         }
  1314         }
  1146     else
  1315     else
  1147         {
  1316         {
  1148         return KErrGeneral;
  1317         return KErrGeneral;
  1149         }
  1318         }
  1150     }
  1319     }
  1151 
  1320 
  1152 
  1321 DSamplerPowerHandler::DSamplerPowerHandler(DGeneralsDriver* aChannel)
       
  1322     :   DPowerHandler(KPluginSamplerName), 
       
  1323         iChannel(aChannel)
       
  1324         {
       
  1325         LOGSTRING("DSamplerPowerHandler::DSamplerPowerHandler\n");
       
  1326         }
       
  1327         
       
  1328 void DSamplerPowerHandler::PowerUp()
       
  1329     {
       
  1330     LOGSTRING("DSamplerPowerHandler::PowerUp()1\n");
       
  1331     iChannel->iOff = (TUint8)EFalse;
       
  1332     if (iChannel->iStarted)
       
  1333         {
       
  1334         LOGSTRING("DSamplerPowerHandler::PowerUp()2\n");
       
  1335         iChannel->StartSampling(iChannel->iRate, iChannel->iIntNo);
       
  1336         }
       
  1337     PowerUpDone();
       
  1338     }
       
  1339     
       
  1340 void DSamplerPowerHandler::PowerDown(TPowerState)
       
  1341     {
       
  1342     LOGSTRING("DSamplerPowerHandler::PowerDown()\n");
       
  1343     iChannel->iOff = (TUint8)ETrue;
       
  1344     //iChannel->iState = EStopped;
       
  1345     iChannel->StopSampling();
       
  1346     PowerDownDone();
       
  1347     }
       
  1348