|         |      1 /* | 
|         |      2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).  | 
|         |      3 * All rights reserved. | 
|         |      4 * This component and the accompanying materials are made available | 
|         |      5 * under the terms of "Eclipse Public License v1.0" | 
|         |      6 * which accompanies this distribution, and is available | 
|         |      7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". | 
|         |      8 * | 
|         |      9 * Initial Contributors: | 
|         |     10 * Nokia Corporation - initial contribution. | 
|         |     11 * | 
|         |     12 * Contributors: | 
|         |     13 * | 
|         |     14 * Description:   | 
|         |     15 * | 
|         |     16 */ | 
|         |     17  | 
|         |     18  | 
|         |     19 // | 
|         |     20 // LDD for thread time profiling | 
|         |     21 // | 
|         |     22  | 
|         |     23 #include <kern_priv.h> | 
|         |     24 #include <platform.h> | 
|         |     25 #include <arm.h> | 
|         |     26  | 
|         |     27 #ifdef __SMP__ | 
|         |     28 #include <assp/naviengine/naviengine.h>  | 
|         |     29 #include <nkernsmp/arm/arm_gic.h> | 
|         |     30 #include <nkernsmp/arm/arm_tmr.h> | 
|         |     31 #endif | 
|         |     32  | 
|         |     33 #include "GeneralsDriver.h" | 
|         |     34 #include <piprofiler/PluginDriver.h> | 
|         |     35 #include <piprofiler/PluginSampler.h> | 
|         |     36 #include <piprofiler/ProfilerTraces.h> | 
|         |     37  | 
|         |     38 #include "GppSamplerImpl.h" | 
|         |     39 #include "GfcSamplerImpl.h" | 
|         |     40 #include "IttSamplerImpl.h" | 
|         |     41 #include "MemSamplerImpl.h" | 
|         |     42 #include "PriSamplerImpl.h" | 
|         |     43  | 
|         |     44  | 
|         |     45 #ifndef __SMP__ | 
|         |     46 extern TUint* IntStackPtr(); | 
|         |     47 extern void UsrModLr(TUint32*); | 
|         |     48 #endif | 
|         |     49 // for security check | 
|         |     50 #define KProfilerExeSecurUid 0x2001E5AD | 
|         |     51 static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy); | 
|         |     52 static _LIT_SECURITY_POLICY_FAIL( KDenyAllPolicy ); | 
|         |     53  | 
|         |     54 #define SEPARATE_DFC_QUEUE | 
|         |     55 // CONSTANTS | 
|         |     56  | 
|         |     57 //_LIT(DProfilerThread,"DProfilerThread"); | 
|         |     58 //const TInt KDProfilerThreadPriority = 27; | 
|         |     59  | 
|         |     60 #ifdef SEPARATE_DFC_QUEUE | 
|         |     61 const TInt KGeneralsDriverThreadPriority = 24; | 
|         |     62 _LIT(KGeneralsDriverThread, "PIGeneralsDriver"); | 
|         |     63  | 
|         |     64 #endif | 
|         |     65  | 
|         |     66 // global Dfc Que | 
|         |     67 //TDynamicDfcQue* gDfcQ; | 
|         |     68  | 
|         |     69 //#ifdef __SMP__ | 
|         |     70 // | 
|         |     71 //enum  TNaviEngineAsspInterruptIdExtension | 
|         |     72 //{ | 
|         |     73 //    KIntProfilerBase = 99      //  Sampling profiler interrupt base.  | 
|         |     74 //    //  Each CPU is assigned a sampling interrupt from this base | 
|         |     75 //    //  CPU-0's sampling interrupt is KIntIdSamplingBase + 0 | 
|         |     76 //    //  CPU-n's sampling interrupt is KIntIdSamplingBase + n | 
|         |     77 //}; | 
|         |     78 //#endif | 
|         |     79  | 
|         |     80 /* | 
|         |     81  * | 
|         |     82  * | 
|         |     83  *	Class DGfcProfilerFactory definition | 
|         |     84  * | 
|         |     85  * | 
|         |     86  */ | 
|         |     87  | 
|         |     88 class DGeneralsProfilerFactory : public DLogicalDevice | 
|         |     89 { | 
|         |     90 	public: | 
|         |     91 		DGeneralsProfilerFactory(); | 
|         |     92 		~DGeneralsProfilerFactory(); | 
|         |     93  | 
|         |     94 	public: | 
|         |     95 		virtual TInt Install(); | 
|         |     96 		virtual void GetCaps(TDes8& aDes) const; | 
|         |     97 		virtual TInt Create(DLogicalChannelBase*& aChannel); | 
|         |     98 }; | 
|         |     99  | 
|         |    100 /* | 
|         |    101  * | 
|         |    102  * | 
|         |    103  *	Class DGfcDriver definition | 
|         |    104  * | 
|         |    105  * | 
|         |    106  */ | 
|         |    107 class DPluginDriver; | 
|         |    108  | 
|         |    109 class DGeneralsDriver : public DPluginDriver | 
|         |    110 { | 
|         |    111  | 
|         |    112 public: | 
|         |    113 	DGeneralsDriver(); | 
|         |    114 	~DGeneralsDriver(); | 
|         |    115  | 
|         |    116 private: | 
|         |    117 	TInt					NewStart(TInt aRate); | 
|         |    118 	static void				NewDoProfilerProfile(TAny*); | 
|         |    119 	static void				NewDoDfc(TAny*); | 
|         |    120 	 | 
|         |    121 	// called by each core | 
|         |    122 	static void				Sample(TAny*); | 
|         |    123  | 
|         |    124 	TInt					GetSampleTime(TUint32* time); | 
|         |    125 	//TInt					Test(TUint32 testCase);  | 
|         |    126  | 
|         |    127 	TInt					StartSampling(); | 
|         |    128 	TInt                    StopSampling(); | 
|         |    129  | 
|         |    130 	void					InitialiseSamplerList();  | 
|         |    131  | 
|         |    132 	DProfilerSamplerBase*	GetSamplerForId(TInt samplerId); | 
|         |    133 	TInt					GetSamplerVersion(TDes* aDes); | 
|         |    134 	 | 
|         |    135 #ifdef __SMP__ | 
|         |    136 	void                    UnbindInterrupts(); | 
|         |    137 #endif | 
|         |    138 	TInt					ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus); | 
|         |    139  | 
|         |    140 	TInt					MarkTraceActive(TInt samplerIdToActivate); | 
|         |    141 	TInt					MarkTraceInactive(TInt samplerIdToDisable); | 
|         |    142 	TInt					OutputSettingsForTrace(TInt samplerId,TInt settings); | 
|         |    143 	TInt					AdditionalTraceSettings(TInt samplerId,TInt settings); | 
|         |    144 	TInt					AdditionalTraceSettings2(TInt samplerId,TInt settings); | 
|         |    145 	TInt					SetSamplingPeriod(TInt /*samplerId*/,TInt settings); | 
|         |    146 private: | 
|         |    147 	// create the driver in EKA-2 version | 
|         |    148 	TInt			        DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); | 
|         |    149  | 
|         |    150 	// receive commands and control in EKA-2 version | 
|         |    151 	void					HandleMsg(TMessageBase* aMsg); | 
|         |    152 private: | 
|         |    153 	// timer mechanism in EKA-2 version | 
|         |    154 	NTimer						iTimer; | 
|         |    155 	TDfc						iNewDfc; | 
|         |    156 	TInt						iCount; | 
|         |    157 	TInt						iLastPcVal;					 | 
|         |    158 	TInt						iPeriod; | 
|         |    159 	 | 
|         |    160 	// sync sample number property for synchronizing other samplers | 
|         |    161 	RPropertyRef 				iSampleStartTimeProp; | 
|         |    162 	TInt						iSampleStartTime; | 
|         |    163 	 | 
|         |    164 	DProfilerGppSampler<10000> 	gppSampler; | 
|         |    165 #ifdef __SMP__ | 
|         |    166 	DProfilerGppSampler<10000>  gppSampler2; | 
|         |    167     DProfilerGppSampler<10000>  gppSampler3; | 
|         |    168     DProfilerGppSampler<10000>  gppSampler4; | 
|         |    169 #endif | 
|         |    170 	DProfilerGfcSampler<10000> 	gfcSampler; | 
|         |    171 	DProfilerIttSampler<10000> 	ittSampler; | 
|         |    172 	DProfilerMemSampler<40000> 	memSampler; | 
|         |    173 	DProfilerPriSampler<10000> 	priSampler; | 
|         |    174 #ifdef __SMP__ | 
|         |    175 //    DProfilerPriSampler<10000>  priSampler2; | 
|         |    176 //    DProfilerPriSampler<10000>  priSampler3; | 
|         |    177 //    DProfilerPriSampler<10000>  priSampler4; | 
|         |    178 #endif | 
|         |    179 	 | 
|         |    180 #ifndef __SMP__ | 
|         |    181 	static const TInt			KSamplerAmount = 5; | 
|         |    182 #else | 
|         |    183     static const TInt           KSamplerAmount = 8; | 
|         |    184 #endif | 
|         |    185 	DProfilerSamplerBase*		iSamplers[KSamplerAmount]; | 
|         |    186     TInt                        iMaxCpus; | 
|         |    187     TUint32                     iStartTime;  | 
|         |    188 	 | 
|         |    189 #ifdef SEPARATE_DFC_QUEUE | 
|         |    190 	TDynamicDfcQue*             iDfcQ; | 
|         |    191 #endif | 
|         |    192 }; | 
|         |    193  | 
|         |    194 /* | 
|         |    195  * | 
|         |    196  * | 
|         |    197  *	Class DGeneralsProfilerFactory implementation | 
|         |    198  * | 
|         |    199  * | 
|         |    200  */ | 
|         |    201  | 
|         |    202 DECLARE_STANDARD_LDD() | 
|         |    203     { | 
|         |    204 	return new DGeneralsProfilerFactory(); | 
|         |    205     } | 
|         |    206  | 
|         |    207 TInt DGeneralsProfilerFactory::Create(DLogicalChannelBase*& aChannel) | 
|         |    208     { | 
|         |    209 	aChannel = new DGeneralsDriver; | 
|         |    210 	return aChannel?KErrNone:KErrNoMemory; | 
|         |    211     } | 
|         |    212  | 
|         |    213  | 
|         |    214 DGeneralsProfilerFactory::DGeneralsProfilerFactory() | 
|         |    215     { | 
|         |    216 	// major, minor, and build version number | 
|         |    217     iVersion=TVersion(1,0,1); | 
|         |    218     } | 
|         |    219  | 
|         |    220 DGeneralsProfilerFactory::~DGeneralsProfilerFactory() | 
|         |    221     { | 
|         |    222 //    if (gDfcQ) | 
|         |    223 //        { | 
|         |    224 //        gDfcQ->Destroy(); | 
|         |    225 //        } | 
|         |    226     } | 
|         |    227  | 
|         |    228 TInt DGeneralsProfilerFactory::Install() | 
|         |    229     { | 
|         |    230     return(SetName(&KPluginSamplerName)); | 
|         |    231     } | 
|         |    232  | 
|         |    233 void DGeneralsProfilerFactory::GetCaps(TDes8& aDes) const | 
|         |    234     { | 
|         |    235     TCapsSamplerV01 b; | 
|         |    236      | 
|         |    237     b.iVersion=TVersion(1,0,1); | 
|         |    238      | 
|         |    239     aDes.FillZ(aDes.MaxLength()); | 
|         |    240     aDes.Copy((TUint8*)&b,Min(aDes.MaxLength(),sizeof(b))); | 
|         |    241     } | 
|         |    242  | 
|         |    243 /* | 
|         |    244  * | 
|         |    245  * | 
|         |    246  *	Class DGeneralsDriver implementation | 
|         |    247  * | 
|         |    248  * | 
|         |    249  */ | 
|         |    250   | 
|         |    251 DGeneralsDriver::DGeneralsDriver() : | 
|         |    252 	iTimer(NewDoProfilerProfile,this), | 
|         |    253 	iNewDfc(NewDoDfc,this,NULL,7), | 
|         |    254 #ifdef __SMP__ | 
|         |    255 	gppSampler(0), | 
|         |    256 	gppSampler2(1), | 
|         |    257     gppSampler3(2), | 
|         |    258     gppSampler4(3), | 
|         |    259 #endif | 
|         |    260 	gfcSampler(gppSampler.GetExportData()), | 
|         |    261 	ittSampler(gppSampler.GetExportData()), | 
|         |    262 	memSampler(gppSampler.GetExportData(), PROFILER_MEM_SAMPLER_ID), | 
|         |    263 	priSampler(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID) | 
|         |    264 #ifdef __SMP__ | 
|         |    265 //    ,priSampler2(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID), | 
|         |    266 //    priSampler3(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID), | 
|         |    267 //    priSampler4(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID) | 
|         |    268 #endif | 
|         |    269     { | 
|         |    270 	LOGSTRING("DGeneralsDriver::DGeneralsDriver()"); | 
|         |    271  | 
|         |    272 	iState = EStopped; | 
|         |    273 	iEndRequestStatus = 0; | 
|         |    274 	doingDfc = 0; | 
|         |    275 	sampleRunning = 0; | 
|         |    276 	iSyncOffset = 0; | 
|         |    277 	iStartTime = 0; | 
|         |    278 	InitialiseSamplerList(); | 
|         |    279     } | 
|         |    280  | 
|         |    281 /* | 
|         |    282  * | 
|         |    283  *	This method has to be changed for each new sampler | 
|         |    284  * | 
|         |    285  */  | 
|         |    286 void DGeneralsDriver::InitialiseSamplerList() | 
|         |    287 	{ | 
|         |    288 	// initialize all samplers to zero | 
|         |    289 	for(TInt i(0);i<KSamplerAmount;i++) | 
|         |    290 		{ | 
|         |    291 		iSamplers[i] = 0; | 
|         |    292 		} | 
|         |    293  | 
|         |    294 	TInt i(0); | 
|         |    295 	iSamplers[i] = &gppSampler;i++; | 
|         |    296 #ifdef __SMP__ | 
|         |    297 	iSamplers[i] = &gppSampler2;i++; | 
|         |    298     iSamplers[i] = &gppSampler3;i++; | 
|         |    299     iSamplers[i] = &gppSampler4;i++; | 
|         |    300 #endif | 
|         |    301 	iSamplers[i] = &gfcSampler;i++; | 
|         |    302 	iSamplers[i] = &ittSampler;i++; | 
|         |    303 	iSamplers[i] = &memSampler;i++; | 
|         |    304 	iSamplers[i] = &priSampler;i++; | 
|         |    305 	 | 
|         |    306 #ifdef __SMP__ | 
|         |    307     // get the number of cpus | 
|         |    308     iMaxCpus = NKern::NumberOfCpus(); | 
|         |    309 #else | 
|         |    310     iMaxCpus = 0; | 
|         |    311 #endif | 
|         |    312      | 
|         |    313 	// initialize synchronizing property | 
|         |    314 	LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - initializing property"); | 
|         |    315 	TInt r(iSampleStartTimeProp.Attach(KGppPropertyCat, EGppPropertySyncSampleNumber)); | 
|         |    316     if (r!=KErrNone) | 
|         |    317         { | 
|         |    318         LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in attaching counter property, error %d", r); | 
|         |    319         } | 
|         |    320     LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - defining properties"); | 
|         |    321     r = iSampleStartTimeProp.Define(RProperty::EInt, KAllowAllPolicy, KDenyAllPolicy, 0, NULL); | 
|         |    322     if (r!=KErrNone) | 
|         |    323         { | 
|         |    324         LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in defining counter property, error %d", r); | 
|         |    325         }	 | 
|         |    326 	} | 
|         |    327  | 
|         |    328  | 
|         |    329 DProfilerSamplerBase* DGeneralsDriver::GetSamplerForId(TInt samplerIdToGet) | 
|         |    330     { | 
|         |    331 	for(TInt i(0);i<KSamplerAmount;i++) | 
|         |    332 	    { | 
|         |    333 		if(iSamplers[i]->iSamplerId == samplerIdToGet) | 
|         |    334 		    { | 
|         |    335 			return iSamplers[i]; | 
|         |    336 		    } | 
|         |    337 	    } | 
|         |    338 	return (DProfilerSamplerBase*)0; | 
|         |    339     } | 
|         |    340  | 
|         |    341 TInt DGeneralsDriver::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer) | 
|         |    342     { | 
|         |    343     TUint8 err(KErrNone); | 
|         |    344      | 
|         |    345     if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer)) | 
|         |    346 	   	return KErrNotSupported; | 
|         |    347      | 
|         |    348     // just for testing  | 
|         |    349 #ifndef __SMP__ | 
|         |    350     LOGTEXT("Initializing the stack pointer"); | 
|         |    351     stackTop=(TUint32*)IntStackPtr(); | 
|         |    352     LOGSTRING2("Got stack pointer 0x%x",(TUint32)stackTop); | 
|         |    353 #endif | 
|         |    354  | 
|         |    355     iClient = &Kern::CurrentThread(); | 
|         |    356     err = iClient->Open(); | 
|         |    357 	 | 
|         |    358     DProcess* clientProcess(iClient->iOwningProcess); | 
|         |    359     if (clientProcess) | 
|         |    360         { | 
|         |    361         //Require Power Management and All Files to use this driver | 
|         |    362         // Not ideal, but better than nothing | 
|         |    363         if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd"))) | 
|         |    364             return KErrPermissionDenied; | 
|         |    365         if(!Kern::CurrentThreadHasCapability(ECapabilityAllFiles,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd"))) | 
|         |    366             return KErrPermissionDenied;   | 
|         |    367          | 
|         |    368         SSecurityInfo secureInfo = clientProcess->iS; | 
|         |    369         if (secureInfo.iSecureId != KProfilerExeSecurUid) | 
|         |    370             { | 
|         |    371             return KErrPermissionDenied; | 
|         |    372             } | 
|         |    373         } | 
|         |    374      | 
|         |    375     // initiate sample stream ready for collecting the trace data | 
|         |    376 	iSampleStream.InsertCurrentClient(iClient); | 
|         |    377 	 | 
|         |    378 	iTimer.Cancel(); | 
|         |    379 	iNewDfc.Cancel(); | 
|         |    380  | 
|         |    381 	Kern::SetThreadPriority(24); | 
|         |    382  | 
|         |    383 #ifdef SEPARATE_DFC_QUEUE | 
|         |    384 	err = Kern::DynamicDfcQCreate(iDfcQ, KGeneralsDriverThreadPriority, TBuf8<32>( KGeneralsDriverThread )); | 
|         |    385 	if (KErrNone == err) | 
|         |    386         { | 
|         |    387         SetDfcQ(iDfcQ); | 
|         |    388         iNewDfc.SetDfcQ(iDfcQ); | 
|         |    389         iMsgQ.Receive(); | 
|         |    390         return err; | 
|         |    391         } | 
|         |    392 #else | 
|         |    393 	SetDfcQ(Kern::DfcQue0()); | 
|         |    394 	iNewDfc.SetDfcQ(iDfcQ); | 
|         |    395 	iMsgQ.Receive(); | 
|         |    396 #endif | 
|         |    397 	return err; | 
|         |    398     } | 
|         |    399  | 
|         |    400 DGeneralsDriver::~DGeneralsDriver() | 
|         |    401     { | 
|         |    402 	if (iState!=EStopped) | 
|         |    403 	    iTimer.Cancel(); | 
|         |    404 	iNewDfc.Cancel(); | 
|         |    405 	 | 
|         |    406 #ifdef SEPARATE_DFC_QUEUE | 
|         |    407 	if(iDfcQ) | 
|         |    408 	    iDfcQ->Destroy(); | 
|         |    409 #endif | 
|         |    410 	 | 
|         |    411 	iSampleStartTimeProp.Close(); | 
|         |    412 	Kern::SafeClose((DObject*&)iClient,NULL); | 
|         |    413     } | 
|         |    414  | 
|         |    415  | 
|         |    416 TInt DGeneralsDriver::GetSampleTime(TUint32* time) | 
|         |    417     { | 
|         |    418 	LOGSTRING("DGeneralsDriver::GetSampleTime - entry"); | 
|         |    419  | 
|         |    420 	Kern::ThreadRawWrite(	iClient,(TAny*)time,  | 
|         |    421 							(TAny*)&gppSampler.GetExportData()->sampleNumber,  | 
|         |    422 							4, iClient); | 
|         |    423  | 
|         |    424 	LOGSTRING("DGeneralsDriver::GetSampleTime - exit"); | 
|         |    425  | 
|         |    426 	return KErrNone; | 
|         |    427     } | 
|         |    428  | 
|         |    429  | 
|         |    430 TInt DGeneralsDriver::GetSamplerVersion(TDes* aDes) | 
|         |    431     { | 
|         |    432 	LOGSTRING2("DGeneralsDriver::GetSamplerVersion - 0x%x",aDes); | 
|         |    433 	 | 
|         |    434 	TBuf8<16> aBuf; | 
|         |    435 	aBuf.Append(PROFILER_SAMPLER_VERSION); | 
|         |    436 	Kern::ThreadDesWrite(iClient,aDes,aBuf,0,KChunkShiftBy0,iClient); | 
|         |    437 	LOGSTRING("DGeneralsDriver::GetSamplerVersion - written client descriptor"); | 
|         |    438 	return KErrNone; | 
|         |    439     } | 
|         |    440  | 
|         |    441 TInt DGeneralsDriver::NewStart(TInt aDelay) | 
|         |    442     {	 | 
|         |    443 	LOGSTRING("DGeneralsDriver::NewStart"); | 
|         |    444 	iEndRequestStatus = 0; | 
|         |    445 	 | 
|         |    446 	aDelay = Min(KMaxDelay, Max(KMinDelay, aDelay)); | 
|         |    447  | 
|         |    448 	// always use this rate | 
|         |    449 	iPeriod = aDelay; | 
|         |    450 	 | 
|         |    451 #ifdef __SMP__ | 
|         |    452     /* | 
|         |    453      * Bind and enable the sampling interupts associated with each core.  | 
|         |    454      */ | 
|         |    455     TInt err(0); | 
|         |    456      | 
|         |    457     TUint32 flags = NKern::EIrqBind_Count; | 
|         |    458  | 
|         |    459 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 ); | 
|         |    460     err = NKern::InterruptBind( KIntProfilerBase - 32 , DGeneralsDriver::Sample, this, flags, 0); | 
|         |    461     if(err < 0) | 
|         |    462         Kern::Printf(" InterruptBind KIntProfilerBase - 32 ret = %d", err ); | 
|         |    463      | 
|         |    464 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 ); | 
|         |    465     err = NKern::InterruptBind( KIntProfilerBase + 1 - 32 , DGeneralsDriver::Sample, this, flags, 0); | 
|         |    466     if(err < 0) | 
|         |    467         Kern::Printf(" InterruptBind KIntProfilerBase + 1 - 32 ret = %d", err ); | 
|         |    468  | 
|         |    469 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 ); | 
|         |    470     err = NKern::InterruptBind(KIntProfilerBase + 2 - 32 , DGeneralsDriver::Sample, this, flags, 0); | 
|         |    471     if(err < 0) | 
|         |    472         Kern::Printf(" InterruptBind KIntProfilerBase + 2 - 32 ret = %d", err ); | 
|         |    473  | 
|         |    474 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 ); | 
|         |    475     err = NKern::InterruptBind(KIntProfilerBase + 3 - 32 , DGeneralsDriver::Sample, this, flags, 0); | 
|         |    476     if(err < 0) | 
|         |    477         Kern::Printf(" InterruptBind KIntProfilerBase + 3 - 32 ret = %d", err ); | 
|         |    478  | 
|         |    479  | 
|         |    480     err = NKern::InterruptEnable(KIntProfilerBase - 32); | 
|         |    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          | 
|         |    496 #endif | 
|         |    497 	 | 
|         |    498 	iTimer.OneShot(aDelay); | 
|         |    499 	 | 
|         |    500 	iState = ERunning; | 
|         |    501  | 
|         |    502 	return KErrNone; | 
|         |    503     } | 
|         |    504  | 
|         |    505 /* | 
|         |    506  *	This function is run in each interrupt | 
|         |    507  */ | 
|         |    508 // EKA-2 implementation of the sampler method | 
|         |    509  | 
|         |    510 void DGeneralsDriver::NewDoProfilerProfile(TAny* aPtr) | 
|         |    511     { | 
|         |    512     LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - entry"); | 
|         |    513      | 
|         |    514 #ifdef __SMP__       | 
|         |    515     TInt currCpu(NKern::CurrentCpu()); | 
|         |    516 #endif | 
|         |    517     TInt8 postSampleNeeded(0); | 
|         |    518     DGeneralsDriver& d=*(DGeneralsDriver*)aPtr; | 
|         |    519  | 
|         |    520 	if (d.iState == ERunning && d.sampleRunning == 0) | 
|         |    521 	    { | 
|         |    522         // start timer again | 
|         |    523 		d.iTimer.Again(d.iPeriod); | 
|         |    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 | 
|         |    608     LOGSTRING("DGeneralsDriver::Sample - exit"); | 
|         |    609     } | 
|         |    610 /* | 
|         |    611  *	This function is run when any of the samplers | 
|         |    612  *	requires post sampling | 
|         |    613  */ | 
|         |    614 void DGeneralsDriver::NewDoDfc(TAny* pointer) | 
|         |    615     { | 
|         |    616 	DGeneralsDriver& d(*((DGeneralsDriver*)pointer)); | 
|         |    617 	 | 
|         |    618 	if(d.iState == ERunning) | 
|         |    619 	    { | 
|         |    620 		// for all enabled samplers, perform | 
|         |    621 		// post sample if needed | 
|         |    622 		for(TInt i(0);i<KSamplerAmount;i++) | 
|         |    623 		    { | 
|         |    624 			if(d.iSamplers[i]->iEnabled) | 
|         |    625 			    { | 
|         |    626 				if(d.iSamplers[i]->PostSampleNeeded()) | 
|         |    627 				    { | 
|         |    628 					d.iSamplers[i]->PostSample(); | 
|         |    629                     } | 
|         |    630                 } | 
|         |    631             } | 
|         |    632 		d.doingDfc--; | 
|         |    633         } | 
|         |    634  | 
|         |    635 	else if(d.iState == EStopping) | 
|         |    636 	    { | 
|         |    637 		// for all enabled samplers, | 
|         |    638 		// perform end sampling | 
|         |    639 		TBool releaseBuffer(false); | 
|         |    640 		for(TInt i(0);i<KSamplerAmount;i++) | 
|         |    641 		    { | 
|         |    642 			if(d.iSamplers[i]->iEnabled) | 
|         |    643 			    { | 
|         |    644 				LOGSTRING("DGeneralsDriver::NewDoDfc() - ending"); | 
|         |    645 				// perform end sampling for all samplers | 
|         |    646 				// stream mode samplers may be pending, if they | 
|         |    647 				// are still waiting for another client buffer | 
|         |    648 				if(d.iSamplers[i]->EndSampling() == KErrNotReady)  | 
|         |    649 				    { | 
|         |    650 					LOGSTRING("DGeneralsDriver::NewDoDfc() - stream data pending"); | 
|         |    651 					releaseBuffer = true; | 
|         |    652                     } | 
|         |    653 				else  | 
|         |    654 				    { | 
|         |    655 					LOGSTRING("DGeneralsDriver::NewDoDfc() - no data pending"); | 
|         |    656 					releaseBuffer = true; | 
|         |    657                     }		 | 
|         |    658                 } | 
|         |    659             } | 
|         |    660  | 
|         |    661 		// At the end, once all the samplers are gone through, the buffer should be released | 
|         |    662 		if (true == releaseBuffer)  | 
|         |    663 		    { | 
|         |    664 			LOGSTRING("DGeneralsDriver::NewDoDfc() - release the buffer"); | 
|         |    665 			d.iSampleStream.ReleaseIfPending();	 | 
|         |    666             } | 
|         |    667 		 | 
|         |    668 		d.iState = EStopped; | 
|         |    669 		if(d.iEndRequestStatus != 0 && d.iClient != 0) | 
|         |    670 		    { | 
|         |    671 			// sampling has ended | 
|         |    672 			Kern::RequestComplete(d.iClient,d.iEndRequestStatus,KErrNone); | 
|         |    673             } | 
|         |    674         } | 
|         |    675     } | 
|         |    676  | 
|         |    677  | 
|         |    678 /* | 
|         |    679  *	All controls are handled here | 
|         |    680  */ | 
|         |    681   | 
|         |    682 void DGeneralsDriver::HandleMsg(TMessageBase* aMsg) | 
|         |    683     { | 
|         |    684 	TInt r(KErrNone); | 
|         |    685 	TThreadMessage& m(*(TThreadMessage*)aMsg); | 
|         |    686  | 
|         |    687 	LOGSTRING5("DGeneralsDriver::HandleMsg 0x%x 0x%x 0x%x 0x%x",m.Int0(),m.Int1(),m.Int2(),m.Int3()); | 
|         |    688 	 | 
|         |    689 	if(m.iValue == (TInt)ECloseMsg) | 
|         |    690 	    { | 
|         |    691 		LOGSTRING("DGeneralsDriver::HandleMsg - received close message"); | 
|         |    692 		iTimer.Cancel(); | 
|         |    693 		iNewDfc.Cancel(); | 
|         |    694  | 
|         |    695 		m.Complete(KErrNone,EFalse); | 
|         |    696 		iMsgQ.CompleteAll(KErrServerTerminated); | 
|         |    697 		LOGSTRING("DGeneralsDriver::HandleMsg - cleaned up the driver!"); | 
|         |    698 		return; | 
|         |    699         } | 
|         |    700  | 
|         |    701 	if (m.Client()!=iClient) | 
|         |    702 	    { | 
|         |    703 		LOGSTRING("DGeneralsDriver::HandleMsg - ERROR, wrong client"); | 
|         |    704 		m.PanicClient(_L("GENERALSSAMPLER"),EAccessDenied); | 
|         |    705 		return; | 
|         |    706         } | 
|         |    707  | 
|         |    708 	TInt id(m.iValue); | 
|         |    709 	switch(id) | 
|         |    710 	    { | 
|         |    711 		 //Controls are handled here | 
|         |    712 		case RPluginSampler::EMarkTraceActive: | 
|         |    713 			LOGSTRING("DGeneralsDriver::HandleMsg - EMarkTraceActive"); | 
|         |    714 			r = MarkTraceActive((TInt)m.Int0()); | 
|         |    715 			break; | 
|         |    716  | 
|         |    717 		case RPluginSampler::EOutputSettingsForTrace: | 
|         |    718 			LOGSTRING("DGeneralsDriver::HandleMsg - EOutputSettingsForTrace"); | 
|         |    719 			r = OutputSettingsForTrace((TInt)m.Int0(),(TInt)m.Int1()); | 
|         |    720 			break; | 
|         |    721  | 
|         |    722 		case RPluginSampler::EAdditionalTraceSettings: | 
|         |    723 			LOGSTRING("DGeneralsDriver::HandleMsg - EAdditionalTraceSettings"); | 
|         |    724 			r = AdditionalTraceSettings((TInt)m.Int0(),(TInt)m.Int1()); | 
|         |    725 			break; | 
|         |    726  | 
|         |    727 		case RPluginSampler::EAdditionalTraceSettings2: | 
|         |    728 			LOGSTRING("DGeneralsDriver::HandleMsg - EAdditionalTraceSettings2"); | 
|         |    729 			r = AdditionalTraceSettings2((TInt)m.Int0(),(TInt)m.Int1()); | 
|         |    730 			break; | 
|         |    731 			 | 
|         |    732 		case RPluginSampler::ESetSamplingPeriod: | 
|         |    733 		    LOGSTRING2("DGeneralsDriver::HandleMsg - ESetSamplingPeriod %d", (TInt)m.Int1()); | 
|         |    734 			r = SetSamplingPeriod((TInt)m.Int0(),(TInt)m.Int1()); | 
|         |    735 			break; | 
|         |    736 			 | 
|         |    737 		case RPluginSampler::EMarkTraceInactive: | 
|         |    738 			LOGSTRING("DGeneralsDriver::HandleMsg - EMarkTraceInactive"); | 
|         |    739 			r = MarkTraceInactive((TInt)m.Int0()); | 
|         |    740 			break; | 
|         |    741  | 
|         |    742 		case RPluginSampler::ESample: | 
|         |    743 			LOGSTRING("DGeneralsDriver::HandleMsg - ESample"); | 
|         |    744 			//r = Sample();  // hack. Original implementation of sample just returned 0 | 
|         |    745 			r = 0; | 
|         |    746 			break; | 
|         |    747  | 
|         |    748 		case RPluginSampler::EStartSampling: | 
|         |    749 			LOGSTRING("DGeneralsDriver::HandleMsg - EStartSampling"); | 
|         |    750 			r = StartSampling(); | 
|         |    751 			break; | 
|         |    752  | 
|         |    753 		case RPluginSampler::EGetSampleTime: | 
|         |    754 			LOGSTRING("DGeneralsDriver::HandleMsg - EGetSampleTime"); | 
|         |    755 			r = GetSampleTime(reinterpret_cast<TUint32*>(m.Ptr0())); | 
|         |    756 			break; | 
|         |    757  | 
|         |    758 		case RPluginSampler::EGetSamplerVersion: | 
|         |    759 			LOGSTRING("DGeneralsDriver::HandleMsg - EGetSamplerVersion"); | 
|         |    760 			r = GetSamplerVersion(reinterpret_cast<TDes*>(m.Ptr0())); | 
|         |    761 			break; | 
|         |    762 		 | 
|         |    763 		case RPluginSampler::ECancelStreamRead: | 
|         |    764 			LOGSTRING("DGeneralsDriver::HandleMsg - ECancelStreamRead"); | 
|         |    765 			iStreamReadCancelStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0()); | 
|         |    766 			r = ProcessStreamReadCancel(); | 
|         |    767 			break; | 
|         |    768  | 
|         |    769  | 
|         |    770 		 //	Requests are handled here | 
|         |    771  | 
|         |    772 		case ~RPluginSampler::EStopAndWaitForEnd: | 
|         |    773 			LOGSTRING("DGeneralsDriver::HandleMsg - EStopAndWaitForEnd"); | 
|         |    774 			iEndRequestStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0()); | 
|         |    775 			r = StopSampling(); | 
|         |    776 #ifdef __SMP__ | 
|         |    777 			UnbindInterrupts(); | 
|         |    778 #endif | 
|         |    779 			break; | 
|         |    780  | 
|         |    781 		case ~RPluginSampler::ERequestFillThisStreamBuffer: | 
|         |    782 			LOGSTRING("DGeneralsDriver::HandleMsg - ERequestFillThisStreamBuffer");			 | 
|         |    783 			r = ProcessStreamReadRequest(	reinterpret_cast<TBapBuf*>(m.Ptr1()), | 
|         |    784 											reinterpret_cast<TRequestStatus*>(m.Ptr0())); | 
|         |    785 			break; | 
|         |    786  | 
|         |    787 		default: | 
|         |    788 			LOGSTRING2("DGeneralsDriver::HandleMsg - ERROR, unknown command %d",id); | 
|         |    789 			r = KErrNotSupported; | 
|         |    790 			break; | 
|         |    791         } | 
|         |    792  | 
|         |    793 	LOGSTRING("DGeneralsDriver::HandleMsg - Completed"); | 
|         |    794 	m.Complete(r,ETrue); | 
|         |    795     } | 
|         |    796  | 
|         |    797 #ifdef __SMP__ | 
|         |    798 inline void DGeneralsDriver::UnbindInterrupts() | 
|         |    799     { | 
|         |    800     TInt err(0); | 
|         |    801  | 
|         |    802     // disable interrupts when sampling stops, enabled again on start | 
|         |    803     err = NKern::InterruptDisable(KIntProfilerBase - 32); | 
|         |    804     if(err < 0) | 
|         |    805         Kern::Printf(" InterruptDisable KIntProfilerBase - 32 ret = %d", err ); | 
|         |    806      | 
|         |    807     err = NKern::InterruptDisable(KIntProfilerBase + 1 - 32); | 
|         |    808     if(err < 0) | 
|         |    809         Kern::Printf(" InterruptDisable KIntProfilerBase + 1 - 32 ret = %d", err ); | 
|         |    810  | 
|         |    811     err = NKern::InterruptDisable(KIntProfilerBase + 2 - 32); | 
|         |    812     if(err < 0) | 
|         |    813         Kern::Printf(" InterruptDisable KIntProfilerBase + 2 - 32 ret = %d", err ); | 
|         |    814  | 
|         |    815     err = NKern::InterruptDisable(KIntProfilerBase + 3 - 32); | 
|         |    816     if(err < 0) | 
|         |    817         Kern::Printf(" InterruptDisable KIntProfilerBase + 3 - 32 ret = %d", err ); | 
|         |    818      | 
|         |    819 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 ); | 
|         |    820     err = NKern::InterruptUnbind( KIntProfilerBase - 32); | 
|         |    821     if(err < 0) | 
|         |    822         Kern::Printf(" InterruptUnbind KIntProfilerBase - 32 ret = %d", err ); | 
|         |    823      | 
|         |    824 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 ); | 
|         |    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     } | 
|         |    840 #endif | 
|         |    841  | 
|         |    842 inline TInt DGeneralsDriver::ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus) | 
|         |    843 	{ | 
|         |    844 	LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - entry"); | 
|         |    845 	 | 
|         |    846 	// a new sample buffer has been received from the client | 
|         |    847 	iSampleStream.AddSampleBuffer(aBuf,aStatus); | 
|         |    848 	 | 
|         |    849 	// check if we are waiting for the last data to be written to the client | 
|         |    850 	if(iState == EStopped) | 
|         |    851 	    { | 
|         |    852 		LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest state = EStopped"); | 
|         |    853 	 | 
|         |    854 		// sampling has stopped and stream read cancel is pending | 
|         |    855 		// try to perform the end sampling procedure again | 
|         |    856 		TBool releaseBuffer(false); | 
|         |    857 		for(TInt i(0);i<KSamplerAmount;i++) | 
|         |    858 		    { | 
|         |    859 			// only for all enabled samplers that have stream output mode | 
|         |    860 			if(iSamplers[i]->iEnabled /*&& samplers[i]->outputMode == 2*/) | 
|         |    861 			    { | 
|         |    862 				//TInt pending = 0; | 
|         |    863 				// stream mode samplers may be pending, if they | 
|         |    864 				// are still waiting for another client buffer, | 
|         |    865 				// in that case, the request should be completed already | 
|         |    866 				if(iSamplers[i]->EndSampling() == KErrNotReady)  | 
|         |    867 				    { | 
|         |    868 					LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - still data pending"); | 
|         |    869 					releaseBuffer = true; | 
|         |    870                     } | 
|         |    871 				else  | 
|         |    872 				    { | 
|         |    873 					LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - no data pending"); | 
|         |    874 					releaseBuffer = true; | 
|         |    875                     } | 
|         |    876                 } | 
|         |    877             } | 
|         |    878 		// At the end, once all the samplers are gone through, the buffer should be released | 
|         |    879 		if (true == releaseBuffer)  | 
|         |    880 		    { | 
|         |    881 			LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - all data copied, release the buffer"); | 
|         |    882 			iSampleStream.ReleaseIfPending(); | 
|         |    883 		    } | 
|         |    884         } | 
|         |    885 	LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - exit"); | 
|         |    886 	 | 
|         |    887 	return KErrNone; | 
|         |    888 	} | 
|         |    889  | 
|         |    890  | 
|         |    891 /* | 
|         |    892  *	Mark traces active or inactive, this can be done | 
|         |    893  *	only if sampling is not running | 
|         |    894  */ | 
|         |    895  | 
|         |    896 inline TInt DGeneralsDriver::MarkTraceActive(TInt samplerIdToActivate) | 
|         |    897 	{ | 
|         |    898 	LOGSTRING2("DGeneralsDriver::MarkTraceActive %d",samplerIdToActivate); | 
|         |    899  | 
|         |    900 	TInt cpus(0); | 
|         |    901 #ifdef __SMP__ | 
|         |    902 	cpus = NKern::NumberOfCpus(); | 
|         |    903 	if( samplerIdToActivate == PROFILER_GPP_SAMPLER_ID ) | 
|         |    904 	    { | 
|         |    905 	    for(TInt cpu(0);cpu<cpus;cpu++) | 
|         |    906 	         { | 
|         |    907 	         Kern::Printf("DGeneralsDriver::MarkTraceActive - activating CPU %d",cpu); | 
|         |    908 	         iSamplers[cpu]->SetEnabledFlag(true); | 
|         |    909 	         } | 
|         |    910 	    return KErrNone; | 
|         |    911 	    } | 
|         |    912 #endif | 
|         |    913 	for(TInt i(cpus);i<KSamplerAmount;i++) | 
|         |    914 	    { | 
|         |    915 		if(iSamplers[i]->iSamplerId == samplerIdToActivate) | 
|         |    916 		    { | 
|         |    917 			iSamplers[i]->SetEnabledFlag(true); | 
|         |    918 			return KErrNone; | 
|         |    919             } | 
|         |    920         } | 
|         |    921  | 
|         |    922 	LOGSTRING2("DGeneralsDriver::MarkTraceActive - %d not supported",samplerIdToActivate); | 
|         |    923 	return KErrNotSupported; | 
|         |    924 	} | 
|         |    925  | 
|         |    926 inline TInt DGeneralsDriver::MarkTraceInactive(TInt samplerIdToDisable) | 
|         |    927 	{ | 
|         |    928 	LOGSTRING2("DGeneralsDriver::MarkTraceInactive %d",samplerIdToDisable); | 
|         |    929  | 
|         |    930     TInt cpus(0); | 
|         |    931 #ifdef __SMP__ | 
|         |    932     cpus = NKern::NumberOfCpus(); | 
|         |    933     if( samplerIdToDisable == PROFILER_GPP_SAMPLER_ID ) | 
|         |    934         { | 
|         |    935         for(TInt cpu(0);cpu<cpus;cpu++) | 
|         |    936              { | 
|         |    937              iSamplers[cpu]->SetEnabledFlag(false); | 
|         |    938              } | 
|         |    939         return KErrNone; | 
|         |    940         } | 
|         |    941 #endif | 
|         |    942     for(TInt i(cpus);i<KSamplerAmount;i++) | 
|         |    943 	    { | 
|         |    944 		if(iSamplers[i]->iSamplerId == samplerIdToDisable) | 
|         |    945 		    { | 
|         |    946 			iSamplers[i]->SetEnabledFlag(false); | 
|         |    947 			return KErrNone; | 
|         |    948             } | 
|         |    949         } | 
|         |    950  | 
|         |    951 	LOGSTRING2("DGeneralsDriver::MarkTraceInactive - %d not supported",samplerIdToDisable); | 
|         |    952 	return KErrNotSupported; | 
|         |    953 	} | 
|         |    954  | 
|         |    955 /* | 
|         |    956  *	Set output settings for a trace | 
|         |    957  */ | 
|         |    958   | 
|         |    959 inline TInt DGeneralsDriver::OutputSettingsForTrace(TInt samplerId,TInt settings) | 
|         |    960 	{ | 
|         |    961 	LOGSTRING3("DGeneralsDriver::OutputSettingsForTrace id:%d set:%d",samplerId,settings); | 
|         |    962  | 
|         |    963     TInt cpus(0); | 
|         |    964 #ifdef __SMP__ | 
|         |    965     cpus = NKern::NumberOfCpus(); | 
|         |    966     if( samplerId == PROFILER_GPP_SAMPLER_ID ) | 
|         |    967         { | 
|         |    968         for(TInt cpu(0);cpu<cpus;cpu++) | 
|         |    969              { | 
|         |    970              iSamplers[cpu]->SetOutputCombination(settings); | 
|         |    971              } | 
|         |    972         return KErrNone; | 
|         |    973         } | 
|         |    974 #endif | 
|         |    975     for(TInt i(cpus);i<KSamplerAmount;i++) | 
|         |    976 	    { | 
|         |    977 		if(iSamplers[i]->iSamplerId == samplerId) | 
|         |    978 		    { | 
|         |    979 			iSamplers[i]->SetOutputCombination(settings); | 
|         |    980 			return KErrNone; | 
|         |    981 		    } | 
|         |    982 	    } | 
|         |    983  | 
|         |    984 	return KErrNotSupported;	 | 
|         |    985 	} | 
|         |    986  | 
|         |    987 /* | 
|         |    988  *	Set additional settings for a trace | 
|         |    989  */ | 
|         |    990  | 
|         |    991 inline TInt DGeneralsDriver::AdditionalTraceSettings(TInt samplerId,TInt settings) | 
|         |    992 	{ | 
|         |    993 	LOGSTRING3("DGeneralsDriver::SetAdditionalTraceSettings id:%d set:%d",samplerId,settings); | 
|         |    994  | 
|         |    995     TInt cpus(0); | 
|         |    996 #ifdef __SMP__ | 
|         |    997     cpus = NKern::NumberOfCpus(); | 
|         |    998     if( samplerId == PROFILER_GPP_SAMPLER_ID ) | 
|         |    999         { | 
|         |   1000         for(TInt cpu(0);cpu<cpus;cpu++) | 
|         |   1001              { | 
|         |   1002              iSamplers[cpu]->SetAdditionalSettings(settings); | 
|         |   1003              } | 
|         |   1004         return KErrNone; | 
|         |   1005         } | 
|         |   1006 #endif | 
|         |   1007     for(TInt i(cpus);i<KSamplerAmount;i++) | 
|         |   1008 	    { | 
|         |   1009 		if(iSamplers[i]->iSamplerId == samplerId) | 
|         |   1010 		    { | 
|         |   1011 			iSamplers[i]->SetAdditionalSettings(settings); | 
|         |   1012 			return KErrNone; | 
|         |   1013             } | 
|         |   1014         } | 
|         |   1015  | 
|         |   1016 	return KErrNotSupported;	 | 
|         |   1017 	} | 
|         |   1018  | 
|         |   1019 inline TInt DGeneralsDriver::AdditionalTraceSettings2(TInt samplerId,TInt settings) | 
|         |   1020 	{ | 
|         |   1021 	LOGSTRING3("DGeneralsDriver::SetAdditionalTraceSettings id:%d set:%d",samplerId,settings); | 
|         |   1022  | 
|         |   1023     TInt cpus(0); | 
|         |   1024 #ifdef __SMP__ | 
|         |   1025     cpus = NKern::NumberOfCpus(); | 
|         |   1026     if( samplerId == PROFILER_GPP_SAMPLER_ID ) | 
|         |   1027         { | 
|         |   1028         for(TInt cpu(0);cpu<cpus;cpu++) | 
|         |   1029              { | 
|         |   1030              iSamplers[cpu]->SetAdditionalSettings2(settings); | 
|         |   1031              } | 
|         |   1032         return KErrNone; | 
|         |   1033         } | 
|         |   1034 #endif | 
|         |   1035     for(TInt i(cpus);i<KSamplerAmount;i++) | 
|         |   1036 	    { | 
|         |   1037 		if(iSamplers[i]->iSamplerId == samplerId) | 
|         |   1038 		    { | 
|         |   1039 			iSamplers[i]->SetAdditionalSettings2(settings); | 
|         |   1040 			return KErrNone; | 
|         |   1041 		    } | 
|         |   1042         } | 
|         |   1043  | 
|         |   1044 	return KErrNotSupported;	 | 
|         |   1045 	} | 
|         |   1046  | 
|         |   1047 inline TInt DGeneralsDriver::SetSamplingPeriod(TInt samplerId,TInt settings) | 
|         |   1048 	{ | 
|         |   1049 	LOGSTRING2("DGeneralsDriver::SetSamplingPeriod - set:%d",settings); | 
|         |   1050  | 
|         |   1051 	TInt cpus(0); | 
|         |   1052 #ifdef __SMP__ | 
|         |   1053     cpus = NKern::NumberOfCpus(); | 
|         |   1054     if( samplerId == PROFILER_GPP_SAMPLER_ID ) | 
|         |   1055         { | 
|         |   1056         for(TInt cpu(0);cpu<cpus;cpu++) | 
|         |   1057              { | 
|         |   1058              iSamplers[cpu]->SetSamplingPeriod(settings); | 
|         |   1059              } | 
|         |   1060         return KErrNone; | 
|         |   1061         } | 
|         |   1062 #endif | 
|         |   1063     for(TInt i(cpus);i<KSamplerAmount;i++) | 
|         |   1064 	    { | 
|         |   1065 		if(iSamplers[i]->iSamplerId == samplerId) | 
|         |   1066 		    { | 
|         |   1067 			iSamplers[i]->SetSamplingPeriod(settings); | 
|         |   1068 			return KErrNone; | 
|         |   1069 		    } | 
|         |   1070 	    } | 
|         |   1071  | 
|         |   1072 	return KErrNotSupported;	 | 
|         |   1073 	} | 
|         |   1074  | 
|         |   1075 /* | 
|         |   1076  *	Mark traces active or inactive, this can be done | 
|         |   1077  *	only if sampling is not running | 
|         |   1078  */ | 
|         |   1079   | 
|         |   1080 TInt DGeneralsDriver::StartSampling() | 
|         |   1081 	{ | 
|         |   1082 	LOGSTRING("DGeneralsDriver::StartSampling"); | 
|         |   1083  | 
|         |   1084 	if(iState == EStopped) | 
|         |   1085 		{ | 
|         |   1086 		// reset iSampleStartTimeProp property value | 
|         |   1087 		iSampleStartTime = NKern::TickCount();	// get the system tick value for sync purposes  | 
|         |   1088 #ifdef __SMP__ | 
|         |   1089 		iStartTime = (iSampleStartTime & 0xfffffff0); | 
|         |   1090 #endif | 
|         |   1091 		TInt r(iSampleStartTimeProp.Set(iSampleStartTime)); | 
|         |   1092 		 | 
|         |   1093 		Kern::Printf(("PIPROF SAMPLE TICK, #0")); // for remote profiling with Profiler Activator | 
|         |   1094 		 | 
|         |   1095 		// reset all enabled samplers | 
|         |   1096 		for(TInt i(0);i<KSamplerAmount;i++) | 
|         |   1097 			{ | 
|         |   1098 			if(iSamplers[i]->iEnabled) | 
|         |   1099 				{ | 
|         |   1100 				// reset with stream option | 
|         |   1101 #ifndef __SMP__ | 
|         |   1102                 Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, sync offset %d"), 0); | 
|         |   1103 				iSamplers[i]->Reset(&iSampleStream, 0); | 
|         |   1104 #else | 
|         |   1105                 Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, start time %d"), iStartTime); | 
|         |   1106                 iSamplers[i]->Reset(&iSampleStream, iStartTime); | 
|         |   1107 #endif | 
|         |   1108 				} | 
|         |   1109 			} | 
|         |   1110  | 
|         |   1111 		NewStart(gppSampler.GetPeriod()); | 
|         |   1112 		return KErrNone; | 
|         |   1113 		} | 
|         |   1114 	else | 
|         |   1115 		{ | 
|         |   1116 		return KErrGeneral; | 
|         |   1117 		} | 
|         |   1118 	} | 
|         |   1119  | 
|         |   1120 /* | 
|         |   1121  *  Mark traces active or inactive, this can be done | 
|         |   1122  *  only if sampling is not running | 
|         |   1123  */ | 
|         |   1124   | 
|         |   1125 TInt DGeneralsDriver::StopSampling() | 
|         |   1126     { | 
|         |   1127     LOGSTRING("DGeneralsDriver::StopSampling"); | 
|         |   1128  | 
|         |   1129     if(iState == ERunning) | 
|         |   1130         { | 
|         |   1131         this->iState = EStopping; | 
|         |   1132         // reset all enabled samplers | 
|         |   1133         for(TInt i(0);i<KSamplerAmount;i++) | 
|         |   1134             { | 
|         |   1135             // do the reset only for memory sampler | 
|         |   1136             if(iSamplers[i]->iEnabled && iSamplers[i]->iSamplerId == 4) | 
|         |   1137                 { | 
|         |   1138                 // reset with stream option | 
|         |   1139                 LOGTEXT(("DGeneralsDriver::StopSampling - stream reset for samplers")); | 
|         |   1140                 iSamplers[i]->Reset(&iSampleStream, 999999); | 
|         |   1141                 } | 
|         |   1142             } | 
|         |   1143  | 
|         |   1144         return KErrNone; | 
|         |   1145         } | 
|         |   1146     else | 
|         |   1147         { | 
|         |   1148         return KErrGeneral; | 
|         |   1149         } | 
|         |   1150     } | 
|         |   1151  | 
|         |   1152  |