os/kernelhwsrv/kerneltest/e32test/system/d_mstim.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32test\system\d_mstim.cpp
sl@0
    15
// LDD for testing millisecond timer
sl@0
    16
// 
sl@0
    17
//
sl@0
    18
sl@0
    19
#include "plat_priv.h"
sl@0
    20
#if defined(__MEIG__)
sl@0
    21
#include <cl7211.h>
sl@0
    22
#elif defined(__MAWD__)
sl@0
    23
#include <windermere.h>
sl@0
    24
#elif defined(__MISA__)
sl@0
    25
#include <sa1100.h>
sl@0
    26
#elif defined(__MCOT__)
sl@0
    27
#include <cotulla.h>
sl@0
    28
#elif defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__) 
sl@0
    29
#include <omap.h>
sl@0
    30
#include <omap_timer.h>
sl@0
    31
#elif defined(__MI920__) || defined(__NI1136__)
sl@0
    32
#ifdef __MI920__
sl@0
    33
#define USE_CM920_FRC
sl@0
    34
#endif
sl@0
    35
#ifdef USE_CM920_FRC
sl@0
    36
#include <iolines.h>
sl@0
    37
#else
sl@0
    38
#include <integratorap.h>
sl@0
    39
#endif
sl@0
    40
#elif defined(__RVEMUBOARD__)
sl@0
    41
#include <rvemuboard.h>
sl@0
    42
#elif defined(__NE1_TB__)
sl@0
    43
#include <upd35001_timer.h>
sl@0
    44
#endif
sl@0
    45
#include "d_mstim.h"
sl@0
    46
#include "../misc/prbs.h"
sl@0
    47
sl@0
    48
#if defined(__WINS__)
sl@0
    49
typedef Int64 TCounter;
sl@0
    50
typedef Int64 TDelta;
sl@0
    51
const TDelta KMaxDelta = 0x7fffffffffffffff;
sl@0
    52
const TDelta KMinDelta = 0x8000000000000000;
sl@0
    53
#else
sl@0
    54
typedef TUint TCounter;
sl@0
    55
typedef TInt TDelta;
sl@0
    56
const TDelta KMaxDelta = KMaxTInt;
sl@0
    57
const TDelta KMinDelta = KMinTInt;
sl@0
    58
#endif
sl@0
    59
sl@0
    60
#ifdef __MISA__
sl@0
    61
inline TCounter TIMER()
sl@0
    62
	{ return *(volatile TUint*)KHwRwOstOscr; }
sl@0
    63
#endif
sl@0
    64
#if defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__) 
sl@0
    65
inline TCounter TIMER()
sl@0
    66
	{ return TOmapTimer::Timer3Value(); }
sl@0
    67
#endif
sl@0
    68
#ifdef __MCOT__
sl@0
    69
inline TCounter TIMER()
sl@0
    70
	{ return *(volatile TUint*)KHwRwOstOscr; }
sl@0
    71
#endif
sl@0
    72
#ifdef __MAWD__
sl@0
    73
inline TCounter TIMER()
sl@0
    74
	{ return *(volatile TUint*)(KWindBaseAddress+KWindTimer1Value16)&0xffff; }
sl@0
    75
#endif
sl@0
    76
#ifdef __MEIG__
sl@0
    77
inline TCounter TIMER()
sl@0
    78
{ return *(volatile TUint*)(KEigerBaseAddress+KEigerTimer1Data16)&0xffff;}
sl@0
    79
#endif
sl@0
    80
#if defined(__MI920__) || defined(__NI1136__)
sl@0
    81
inline TCounter TIMER()
sl@0
    82
#ifdef USE_CM920_FRC
sl@0
    83
	{ return *(volatile TUint*)(KHwRwCoreClkCounter);}		// 32-bit Core module counter inc's at 24MHz
sl@0
    84
#else
sl@0
    85
	{ return *(volatile TUint*)(KHwCounterTimer1+KHoTimerValue)&0xffff;}
sl@0
    86
#endif
sl@0
    87
#endif
sl@0
    88
#if defined(__RVEMUBOARD__)
sl@0
    89
inline TCounter TIMER()
sl@0
    90
	{ return *(volatile TUint*)(KHwCounterTimer1+KHoTimerValue)&0xffff;}
sl@0
    91
#endif
sl@0
    92
#ifdef __NE1_TB__
sl@0
    93
inline TCounter TIMER()
sl@0
    94
	{ return NETimer::Timer(2).iTimerCount; }
sl@0
    95
#endif
sl@0
    96
#if defined(__EPOC32__) && defined(__CPU_X86)
sl@0
    97
TCounter TIMER();
sl@0
    98
void SetUpTimerChannel2();
sl@0
    99
#endif
sl@0
   100
sl@0
   101
#ifdef __WINS__
sl@0
   102
inline TCounter TIMER()
sl@0
   103
	{
sl@0
   104
	LARGE_INTEGER c;
sl@0
   105
	QueryPerformanceCounter(&c);
sl@0
   106
	return c.QuadPart;
sl@0
   107
	}
sl@0
   108
#endif
sl@0
   109
sl@0
   110
#if defined(__MISA__) || (defined(USE_CM920_FRC) && (defined(__MI920__) || defined(__NI1136__)))
sl@0
   111
inline TDelta TimeDelta(TCounter initial, TCounter final)
sl@0
   112
	{ return final-initial; }				// SA1100 timer counts up
sl@0
   113
#endif
sl@0
   114
#if defined(__MCOT__)
sl@0
   115
inline TDelta TimeDelta(TCounter initial, TCounter final)
sl@0
   116
	{ return final-initial; }				// Cotulla timer counts up
sl@0
   117
#endif
sl@0
   118
#if defined(__MAWD__) || defined(__MEIG__) || (!defined(USE_CM920_FRC) && (defined(__MI920__) || defined(__NI1136__))) 
sl@0
   119
inline TDelta TimeDelta(TCounter initial, TCounter final)
sl@0
   120
	{ return (initial-final)&0xffff; }		// Eiger/Windermere/Integrator timer counts down
sl@0
   121
#endif
sl@0
   122
#if defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__)
sl@0
   123
inline TDelta TimeDelta(TCounter initial, TCounter final)
sl@0
   124
	{ return (initial-final);}		// OMAP timer counts down
sl@0
   125
#endif
sl@0
   126
#if defined(__EPOC32__) && defined(__CPU_X86)
sl@0
   127
TDelta TimeDelta(TUint initial, TUint final)
sl@0
   128
	{
sl@0
   129
	TUint tickdiff=(initial-final)&0xffff;
sl@0
   130
	TUint msdiff=((final>>16)-(initial>>16))&0xffff;
sl@0
   131
	msdiff=1193*msdiff-tickdiff;
sl@0
   132
	msdiff=(msdiff+32768)&~0xffff;
sl@0
   133
	return msdiff+tickdiff;
sl@0
   134
	}
sl@0
   135
#endif
sl@0
   136
#ifdef __NE1_TB__
sl@0
   137
inline TDelta TimeDelta(TCounter initial, TCounter final)
sl@0
   138
	{ return final - initial; }
sl@0
   139
#endif
sl@0
   140
#ifdef __WINS__
sl@0
   141
inline TDelta TimeDelta(TCounter initial, TCounter final)
sl@0
   142
	{ return final-initial; }		// counts up
sl@0
   143
#endif
sl@0
   144
#if defined(__RVEMUBOARD__)
sl@0
   145
inline TDelta TimeDelta(TCounter initial, TCounter final)
sl@0
   146
	{ return (initial-final)&0xffff; }		// Timer counts down
sl@0
   147
#endif
sl@0
   148
sl@0
   149
const TInt KMajorVersionNumber=0;
sl@0
   150
const TInt KMinorVersionNumber=1;
sl@0
   151
const TInt KBuildVersionNumber=1;
sl@0
   152
sl@0
   153
const TInt KMaxMsTim=9;
sl@0
   154
const TInt KMaxMsTimR=9;
sl@0
   155
sl@0
   156
TInt TicksToMicroseconds(TDelta aTicks)
sl@0
   157
	{
sl@0
   158
#if defined(__MISA__) || defined(__MCOT__)
sl@0
   159
	Int64 ticks(aTicks);
sl@0
   160
	ticks*=(1000000);
sl@0
   161
	ticks+=KHwOscFreqHz/2;		// 3.6864MHz tick
sl@0
   162
	ticks/=KHwOscFreqHz;
sl@0
   163
	return (TInt)ticks;
sl@0
   164
#endif
sl@0
   165
#if defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__) 
sl@0
   166
	// Timer runs at 12Mhz/32 = 375kHz. Each tick is 2.66...us which is 16/6us
sl@0
   167
	aTicks<<=4;		// * 16
sl@0
   168
	aTicks+=3;	    // rounding to the closest number of us
sl@0
   169
	return (TInt)(aTicks/6);	// us = (ticks*16+3)/6
sl@0
   170
#endif
sl@0
   171
#if defined(__MI920__) || defined(__NI1136__)
sl@0
   172
#if defined(USE_CM920_FRC)
sl@0
   173
	Int64 ticks(aTicks);
sl@0
   174
	ticks*=(1000000);
sl@0
   175
	ticks+=24000000/2;
sl@0
   176
	ticks/=24000000;
sl@0
   177
	return (TInt)ticks;
sl@0
   178
#else
sl@0
   179
	aTicks<<=14;	// 1 tick = 32/3 us
sl@0
   180
	aTicks+=768;	// round
sl@0
   181
	return (TInt)(aTicks/1536);
sl@0
   182
#endif
sl@0
   183
#endif
sl@0
   184
#if defined(__RVEMUBOARD__)
sl@0
   185
	return (TInt)(aTicks*256);  // 1 tick = 256 us
sl@0
   186
#endif
sl@0
   187
#if defined(__MAWD__) || defined(__MEIG__)
sl@0
   188
	return aTicks*500;					// 2kHz tick
sl@0
   189
#endif
sl@0
   190
#if defined(__NE1_TB__)
sl@0
   191
	NETimer& T2 = NETimer::Timer(2);
sl@0
   192
	TUint prescale = __e32_find_ms1_32(T2.iPrescaler & 0x3f);
sl@0
   193
	TInt f = 66666667 >> prescale;
sl@0
   194
	TInt64 x = I64LIT(1000000);
sl@0
   195
	x *= TInt64(aTicks);
sl@0
   196
	x += TInt64(f>>1);
sl@0
   197
	x /= TInt64(f);
sl@0
   198
	return (TInt)x;
sl@0
   199
#endif
sl@0
   200
#if defined(__EPOC32__) && defined(__CPU_X86)
sl@0
   201
	TInt x = aTicks;
sl@0
   202
	TInt y = x;
sl@0
   203
	y -= ((3*x)>>4);	// * 0.D
sl@0
   204
	y += (aTicks>>12);	// * 0.D00D
sl@0
   205
	TInt z = (6*x)>>8;	// * 0.06
sl@0
   206
	y += z;				// * 0.D60D
sl@0
   207
	y += (x>>9);		// * 0.D68D
sl@0
   208
	y += (z>>16);		// * 0.D68D6
sl@0
   209
	y += (z>>20);		// * 0.D68D66
sl@0
   210
	return y;
sl@0
   211
#endif
sl@0
   212
#ifdef __WINS__
sl@0
   213
	LARGE_INTEGER f;
sl@0
   214
	QueryPerformanceFrequency(&f);
sl@0
   215
	aTicks*=1000000;
sl@0
   216
	aTicks+=f.QuadPart-1;
sl@0
   217
	aTicks/=f.QuadPart;
sl@0
   218
	return (TInt)aTicks;
sl@0
   219
#endif
sl@0
   220
	}
sl@0
   221
sl@0
   222
sl@0
   223
void InitTimer()
sl@0
   224
	{
sl@0
   225
#ifdef __MAWD__
sl@0
   226
	// Set up timer 1 as free running 2kHz clock
sl@0
   227
	TWind::SetBuzzerControl(0);		// disable buzzer
sl@0
   228
	TWind::SetTimer1Control(KWindTimer1ControlTimerEnable);
sl@0
   229
	TWind::SetTimer1Load(0);
sl@0
   230
#endif
sl@0
   231
#ifdef __MEIG__
sl@0
   232
	// Set up timer 1 as free running 2kHz clock
sl@0
   233
	TEiger::ModifyControl21(KEigerControlTimer1PreOrFree|KEigerControlTimer1K512OrK2|
sl@0
   234
							KEigerControlBuzzerToggle|KEigerControlBuzzerTimer1OrToggle,0);
sl@0
   235
	TEiger::SetTimer1Data(0);
sl@0
   236
#endif
sl@0
   237
#if defined(__MISA__)
sl@0
   238
	// MISA free running counter is always active - no initialisation required
sl@0
   239
#endif
sl@0
   240
#if defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__)
sl@0
   241
	// Set up Timer3 as a free-running timer at 12Mhz/32 = 375kHz
sl@0
   242
	TOmapTimer::SetTimer3Ctrl(	TOmapTimer::KHtOSTimer_Cntl_Ar
sl@0
   243
									| TOmapTimer::KHtOSTimer_Cntl_Free
sl@0
   244
									| TOmapTimer::KHtOSTimer_Cntl_ClkEnable );
sl@0
   245
	TOmapTimer::SetTimer3Prescale( TOmapTimer::EPrescaleBy32 );
sl@0
   246
	// Autoreload 0xFFFFFFFF to effectively wrap from zero back to 0xFFFFFFFF
sl@0
   247
	TOmapTimer::SetTimer3LoadTim( 0xFFFFFFFF );
sl@0
   248
	TOmapTimer::StartTimer3();
sl@0
   249
#endif
sl@0
   250
#if defined(__MI920__) || defined(__NI1136__)
sl@0
   251
#if !defined(USE_CM920_FRC)
sl@0
   252
    TIntegratorAP::SetTimerMode(TIntegratorAP::ECounterTimer1, TIntegratorAP::ETimerModeFreeRunning);
sl@0
   253
    TIntegratorAP::SetTimerPreScale(TIntegratorAP::ECounterTimer1, TIntegratorAP::ETimerPreScaleDiv256);	// 93.75kHz wrap 699ms
sl@0
   254
    TIntegratorAP::EnableTimer(TIntegratorAP::ECounterTimer1, TIntegratorAP::EEnable);
sl@0
   255
#endif
sl@0
   256
#endif
sl@0
   257
#if defined(__RVEMUBOARD__)
sl@0
   258
	// Switch timer 1 to a 1MHz clock in the system controller Ctrl register
sl@0
   259
	TRvEmuBoard::SetSCCtrl(KTimer1EnSel);
sl@0
   260
sl@0
   261
	// Set up timer 1 as free running 3.90625kHz clock
sl@0
   262
	TRvEmuBoard::SetTimerMode(KHwCounterTimer1, TRvEmuBoard::ETimerModeFreeRunning);
sl@0
   263
	TRvEmuBoard::SetTimerPreScale(KHwCounterTimer1, TRvEmuBoard::ETimerPreScaleDiv256);// 3.90625kHz wrap 16.777s
sl@0
   264
	TRvEmuBoard::EnableTimer(KHwCounterTimer1, TRvEmuBoard::EEnable);
sl@0
   265
#endif
sl@0
   266
#if defined(__NE1_TB__)
sl@0
   267
	// nothing to do since variant has already set up timer
sl@0
   268
#endif
sl@0
   269
#if defined(__EPOC32__) && defined(__CPU_X86)
sl@0
   270
	// Set up timer channel 2 as free running counter at 14318180/12 Hz
sl@0
   271
	SetUpTimerChannel2();
sl@0
   272
#endif
sl@0
   273
	}
sl@0
   274
sl@0
   275
// global Dfc Que
sl@0
   276
TDynamicDfcQue* gDfcQ;
sl@0
   277
sl@0
   278
class NTimerQTest
sl@0
   279
	{
sl@0
   280
public:
sl@0
   281
	static inline NTimerQ& Timer()
sl@0
   282
		{ return *(NTimerQ*)NTimerQ::TimerAddress(); }
sl@0
   283
	static inline TUint32 MsCount()
sl@0
   284
		{ return Timer().iMsCount; }
sl@0
   285
	static inline void Setup(TAny* aPtr)
sl@0
   286
		{ NTimerQ& m=Timer(); m.iDebugFn=Test; m.iDebugPtr=aPtr; }
sl@0
   287
	static inline void Stop()
sl@0
   288
		{ NTimerQ& m=Timer(); m.iDebugFn=NULL; m.iDebugPtr=NULL; }
sl@0
   289
	static inline TBool XferC()
sl@0
   290
		{ return Timer().iTransferringCancelled; }
sl@0
   291
	static inline TBool CritC()
sl@0
   292
		{ return Timer().iCriticalCancelled; }
sl@0
   293
	static void Test(TAny* aPtr, TInt aPos);
sl@0
   294
	};
sl@0
   295
sl@0
   296
class DMsTim;
sl@0
   297
sl@0
   298
class TMsTim : public NTimer
sl@0
   299
	{
sl@0
   300
public:
sl@0
   301
	enum TMode
sl@0
   302
		{
sl@0
   303
		EIntAfter,
sl@0
   304
		EDfcAfter,
sl@0
   305
		EIntAgain,
sl@0
   306
		EDfcAgain,
sl@0
   307
		EIntCancel,
sl@0
   308
		EDfcCancel,
sl@0
   309
		EUserDfcAfter
sl@0
   310
		};
sl@0
   311
sl@0
   312
	enum TModeX
sl@0
   313
		{
sl@0
   314
		EIntAgainOnce=7,
sl@0
   315
		EUserDfcAgainOnce
sl@0
   316
		};
sl@0
   317
public:
sl@0
   318
	TMsTim();
sl@0
   319
	~TMsTim();
sl@0
   320
	TInt Create();
sl@0
   321
	TInt Start(TInt aMode, TInt aInterval, TInt aParam);
sl@0
   322
	static void MsCallBack(TAny* aPtr);
sl@0
   323
	static void IDfcFn(TAny* aPtr);
sl@0
   324
	static void DfcFn(TAny* aPtr);
sl@0
   325
	void CompleteClient(TInt aValue);
sl@0
   326
public:
sl@0
   327
	TMode iMode;
sl@0
   328
	TInt iInterval;
sl@0
   329
	TInt iParam;
sl@0
   330
	TCounter iStartTime;
sl@0
   331
	TDelta iMin;
sl@0
   332
	TDelta iMax;
sl@0
   333
	Int64 iTotal;
sl@0
   334
	TInt iCount;
sl@0
   335
	DMsTim* iLdd;
sl@0
   336
	TInt iId;
sl@0
   337
	TClientRequest* iRequest;
sl@0
   338
	TDfc iIDfc;
sl@0
   339
	TDfc iCompletionDfc;
sl@0
   340
	};
sl@0
   341
sl@0
   342
class TMsTimRand : public NTimer
sl@0
   343
	{
sl@0
   344
public:
sl@0
   345
	TMsTimRand();
sl@0
   346
#ifdef __SMP__
sl@0
   347
	~TMsTimRand();
sl@0
   348
#endif
sl@0
   349
	TInt Start(TInt aInterval, DMsTim* aLdd, TInt aPos);
sl@0
   350
	static void MsCallBack(TAny* aPtr);
sl@0
   351
	void FillWithGarbage(TUint aFillValue);
sl@0
   352
public:
sl@0
   353
	TInt iInterval;
sl@0
   354
	TCounter iStartTime;
sl@0
   355
	DMsTim* iLdd;
sl@0
   356
	};
sl@0
   357
sl@0
   358
class DMsTimFactory : public DLogicalDevice
sl@0
   359
//
sl@0
   360
// Millisecond timer LDD factory
sl@0
   361
//
sl@0
   362
	{
sl@0
   363
public:
sl@0
   364
	DMsTimFactory();
sl@0
   365
	~DMsTimFactory();
sl@0
   366
	virtual TInt Install();						//overriding pure virtual
sl@0
   367
	virtual void GetCaps(TDes8& aDes) const;	//overriding pure virtual
sl@0
   368
	virtual TInt Create(DLogicalChannelBase*& aChannel);	//overriding pure virtual
sl@0
   369
	};
sl@0
   370
sl@0
   371
class DMsTim : public DLogicalChannel
sl@0
   372
//
sl@0
   373
// Millisecond timer LDD channel
sl@0
   374
//
sl@0
   375
	{
sl@0
   376
public:
sl@0
   377
	DMsTim();
sl@0
   378
	~DMsTim();
sl@0
   379
protected:
sl@0
   380
	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
sl@0
   381
	TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
sl@0
   382
	TInt DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2);
sl@0
   383
	virtual void HandleMsg(TMessageBase* aMsg);
sl@0
   384
public:
sl@0
   385
	void TimerExpired(TInt anId);
sl@0
   386
	inline DThread* Client() { return iThread; }
sl@0
   387
public:
sl@0
   388
	DThread* iThread;
sl@0
   389
	TMsTim iMsTim[KMaxMsTim];
sl@0
   390
	TMsTimRand iMsTimR[KMaxMsTimR];
sl@0
   391
	TInt iRandMin;
sl@0
   392
	TInt iRandMax;
sl@0
   393
	TInt iXferC;
sl@0
   394
	TInt iCritC;
sl@0
   395
	TInt iStartFail;
sl@0
   396
	TInt iCallBacks;
sl@0
   397
	TInt iCompletions;
sl@0
   398
	TUint iSeed[2];
sl@0
   399
	};
sl@0
   400
sl@0
   401
TMsTim::TMsTim()
sl@0
   402
	:	NTimer(MsCallBack,this),
sl@0
   403
		iMode(EIntAfter),
sl@0
   404
		iInterval(0),
sl@0
   405
		iParam(0),
sl@0
   406
		iStartTime(0),
sl@0
   407
		iMin(KMaxDelta),
sl@0
   408
		iMax(KMinDelta),
sl@0
   409
		iTotal(0),
sl@0
   410
		iCount(0),
sl@0
   411
		iRequest(NULL),
sl@0
   412
		iIDfc(IDfcFn,this),
sl@0
   413
		iCompletionDfc(DfcFn,this,gDfcQ,1)
sl@0
   414
	{
sl@0
   415
	}
sl@0
   416
sl@0
   417
TMsTim::~TMsTim()
sl@0
   418
	{
sl@0
   419
	Kern::DestroyClientRequest(iRequest);
sl@0
   420
#ifdef __SMP__
sl@0
   421
	NTimer* nt = STATIC_CAST(NTimer*,this);
sl@0
   422
	new (nt) NTimer(&MsCallBack, this);	// so NTimer destructor doesn't kill us
sl@0
   423
#endif
sl@0
   424
	}
sl@0
   425
sl@0
   426
TInt TMsTim::Create()
sl@0
   427
	{
sl@0
   428
	return Kern::CreateClientRequest(iRequest);
sl@0
   429
	}
sl@0
   430
sl@0
   431
void TMsTim::IDfcFn(TAny* aPtr)
sl@0
   432
	{
sl@0
   433
	TMsTim& m=*(TMsTim*)aPtr;
sl@0
   434
	TInt c = NKern::CurrentContext();
sl@0
   435
	__NK_ASSERT_ALWAYS(c == NKern::EIDFC);
sl@0
   436
	__NK_ASSERT_ALWAYS(NKern::KernelLocked(1));
sl@0
   437
	m.iCompletionDfc.DoEnque();
sl@0
   438
	}
sl@0
   439
sl@0
   440
void TMsTim::DfcFn(TAny* aPtr)
sl@0
   441
	{
sl@0
   442
	TMsTim& m=*(TMsTim*)aPtr;
sl@0
   443
	if (m.iMode==EUserDfcAfter)
sl@0
   444
		{
sl@0
   445
		TCounter timer_val=TIMER();
sl@0
   446
		TDelta time=TimeDelta(m.iStartTime, timer_val);
sl@0
   447
		++m.iCount;
sl@0
   448
		if (time<m.iMin)
sl@0
   449
			m.iMin=time;
sl@0
   450
		if (time>m.iMax)
sl@0
   451
			m.iMax=time;
sl@0
   452
		m.iTotal+=time;
sl@0
   453
		}
sl@0
   454
	m.iLdd->TimerExpired(m.iId);
sl@0
   455
	}
sl@0
   456
sl@0
   457
void TestThreadContext()
sl@0
   458
	{
sl@0
   459
	TInt c1 = NKern::CurrentContext();
sl@0
   460
	NKern::Lock();
sl@0
   461
	TInt c2 = NKern::CurrentContext();
sl@0
   462
	NKern::Unlock();
sl@0
   463
	__NK_ASSERT_ALWAYS((c1 == NKern::EThread) && (c2 == NKern::EThread));
sl@0
   464
	}
sl@0
   465
sl@0
   466
void TMsTim::MsCallBack(TAny* aPtr)
sl@0
   467
	{
sl@0
   468
	TInt c = NKern::CurrentContext();
sl@0
   469
	TCounter timer_val=TIMER();
sl@0
   470
	TMsTim& m=*(TMsTim*)aPtr;
sl@0
   471
	TDelta time=TimeDelta(m.iStartTime, timer_val);
sl@0
   472
	if (++m.iCount>0 || (m.iMode!=EIntAgain && m.iMode!=EDfcAgain))
sl@0
   473
		{
sl@0
   474
		if (time<m.iMin)
sl@0
   475
			m.iMin=time;
sl@0
   476
		if (time>m.iMax)
sl@0
   477
			m.iMax=time;
sl@0
   478
		m.iTotal+=time;
sl@0
   479
		}
sl@0
   480
	switch (m.iMode)
sl@0
   481
		{
sl@0
   482
		case EIntAfter:
sl@0
   483
			__NK_ASSERT_ALWAYS(c == NKern::EInterrupt);
sl@0
   484
			m.iIDfc.Add();
sl@0
   485
			break;
sl@0
   486
		case EDfcAfter:
sl@0
   487
			TestThreadContext();
sl@0
   488
			m.iCompletionDfc.Enque();
sl@0
   489
			break;
sl@0
   490
		case EIntAgain:
sl@0
   491
			__NK_ASSERT_ALWAYS(c == NKern::EInterrupt);
sl@0
   492
			m.iStartTime=TIMER();
sl@0
   493
			m.Again(m.iInterval);
sl@0
   494
			break;
sl@0
   495
		case EDfcAgain:
sl@0
   496
			TestThreadContext();
sl@0
   497
			m.iStartTime=TIMER();
sl@0
   498
			m.Again(m.iInterval);
sl@0
   499
			break;
sl@0
   500
		case EIntCancel:
sl@0
   501
			__NK_ASSERT_ALWAYS(c == NKern::EInterrupt);
sl@0
   502
			m.iLdd->iMsTim[m.iParam].Cancel();
sl@0
   503
			m.iIDfc.Add();
sl@0
   504
			break;
sl@0
   505
		case EDfcCancel:
sl@0
   506
			TestThreadContext();
sl@0
   507
			m.iLdd->iMsTim[m.iParam].Cancel();
sl@0
   508
			m.iCompletionDfc.Enque();
sl@0
   509
			break;
sl@0
   510
		case EUserDfcAfter:
sl@0
   511
			__NK_ASSERT_ALWAYS(EFalse);
sl@0
   512
			break;
sl@0
   513
		}
sl@0
   514
	}
sl@0
   515
sl@0
   516
TInt TMsTim::Start(TInt aMode, TInt aInterval, TInt aParam)
sl@0
   517
	{
sl@0
   518
	TInt r=KErrGeneral;
sl@0
   519
	TInt c=0;
sl@0
   520
	TCounter holder=TIMER();		// holds the start value of timer
sl@0
   521
	switch (aMode)
sl@0
   522
		{
sl@0
   523
		case EIntAgain:
sl@0
   524
			c=-1;
sl@0
   525
		case EIntAfter:
sl@0
   526
		case EIntCancel:
sl@0
   527
			r=OneShot(aInterval);
sl@0
   528
			break;
sl@0
   529
		case EDfcAgain:
sl@0
   530
			c=-1;
sl@0
   531
		case EDfcAfter:
sl@0
   532
		case EDfcCancel:
sl@0
   533
			r=OneShot(aInterval,ETrue);
sl@0
   534
			break;
sl@0
   535
		case EIntAgainOnce:
sl@0
   536
		case EUserDfcAgainOnce:
sl@0
   537
#ifdef __SMP__
sl@0
   538
			i8888.iHState2=FALSE;
sl@0
   539
#else
sl@0
   540
			iCompleteInDfc=FALSE;
sl@0
   541
#endif
sl@0
   542
			r=Again(aInterval);
sl@0
   543
			if (aMode==EUserDfcAgainOnce)
sl@0
   544
				aMode=EUserDfcAfter;
sl@0
   545
			else
sl@0
   546
				aMode=EIntAfter;
sl@0
   547
			break;
sl@0
   548
		case EUserDfcAfter:
sl@0
   549
			r=OneShot(aInterval, iCompletionDfc);
sl@0
   550
			break;
sl@0
   551
		}
sl@0
   552
	if (r!=KErrNone)
sl@0
   553
		return r;
sl@0
   554
	iStartTime=holder;
sl@0
   555
	iMode=TMode(aMode);
sl@0
   556
	iInterval=aInterval;
sl@0
   557
	iParam=aParam;
sl@0
   558
	iMin=KMaxDelta;
sl@0
   559
	iMax=KMinDelta;
sl@0
   560
	iTotal=0;
sl@0
   561
	iCount=c;
sl@0
   562
	return KErrNone;
sl@0
   563
	}
sl@0
   564
sl@0
   565
void TMsTim::CompleteClient(TInt aValue)
sl@0
   566
	{
sl@0
   567
	Kern::QueueRequestComplete(iLdd->Client(),iRequest,aValue);
sl@0
   568
	}
sl@0
   569
sl@0
   570
TMsTimRand::TMsTimRand()
sl@0
   571
	:	NTimer(&MsCallBack,this)
sl@0
   572
	{
sl@0
   573
	memset(this,0,sizeof(TMsTimRand));
sl@0
   574
#ifdef __SMP__
sl@0
   575
	NTimer* nt = STATIC_CAST(NTimer*,this);
sl@0
   576
	new (nt) NTimer(&MsCallBack,this);
sl@0
   577
#else
sl@0
   578
	iFunction=MsCallBack;	// avoid triggering assertion in NTimer::OneShot()
sl@0
   579
#endif
sl@0
   580
	}
sl@0
   581
sl@0
   582
#ifdef __SMP__
sl@0
   583
TMsTimRand::~TMsTimRand()
sl@0
   584
	{
sl@0
   585
	NTimer* nt = STATIC_CAST(NTimer*,this);
sl@0
   586
	new (nt) NTimer(&MsCallBack, this);	// so NTimer destructor doesn't kill us
sl@0
   587
	}
sl@0
   588
#endif
sl@0
   589
sl@0
   590
void TMsTimRand::FillWithGarbage(TUint aFill)
sl@0
   591
	{
sl@0
   592
#ifdef __SMP__
sl@0
   593
	TUint32 f = aFill;
sl@0
   594
	f |= (f<<8);
sl@0
   595
	f |= (f<<16);
sl@0
   596
	iNext = (SDblQueLink*)f;
sl@0
   597
	iPrev = (SDblQueLink*)f;
sl@0
   598
	iDfcQ = (TDfcQue*)f;
sl@0
   599
	iPtr = (TAny*)f;
sl@0
   600
	iFn = (NEventFn)f;
sl@0
   601
	iTiedLink.iNext = (SDblQueLink*)f;
sl@0
   602
	iTiedLink.iPrev = (SDblQueLink*)f;
sl@0
   603
#else
sl@0
   604
	memset(this, (TUint8)aFill, 16);
sl@0
   605
#endif
sl@0
   606
	}
sl@0
   607
sl@0
   608
TInt TMsTimRand::Start(TInt aInterval, DMsTim* aLdd, TInt aPos)
sl@0
   609
	{
sl@0
   610
	iLdd=aLdd;
sl@0
   611
#ifdef __SMP__
sl@0
   612
	TUint fill=(aPos<<5)|(i8888.iHState1<<2)|3;
sl@0
   613
#else
sl@0
   614
	TUint fill=(aPos<<5)|(iState<<2)|3;
sl@0
   615
	iPad1 = (TUint8)fill;
sl@0
   616
#endif
sl@0
   617
	TInt r=OneShot(aInterval,ETrue);
sl@0
   618
	if (r==KErrNone)
sl@0
   619
		{
sl@0
   620
		iPtr=this;
sl@0
   621
		iInterval=aInterval;
sl@0
   622
		iStartTime=TIMER();
sl@0
   623
#ifdef __SMP__
sl@0
   624
		iFn=MsCallBack;
sl@0
   625
		i8888.iHState0 = (TUint8)fill;
sl@0
   626
		if (i8888.iHState1!=EHolding)
sl@0
   627
			*(TUint*)0xfcd1fcd1=i8888.iHState1;
sl@0
   628
#else
sl@0
   629
		iFunction=MsCallBack;
sl@0
   630
		iUserFlags = (TUint8)fill;
sl@0
   631
		if (iState!=EHolding)
sl@0
   632
			*(TUint*)0xfcd1fcd1=iState;
sl@0
   633
#endif
sl@0
   634
		}
sl@0
   635
	return r;
sl@0
   636
	}
sl@0
   637
sl@0
   638
void TMsTimRand::MsCallBack(TAny* aPtr)
sl@0
   639
	{
sl@0
   640
	TMsTimRand& m=*(TMsTimRand*)aPtr;
sl@0
   641
	TCounter time=TIMER();
sl@0
   642
	TDelta elapsed=TimeDelta(m.iStartTime,time);
sl@0
   643
	TInt error=TicksToMicroseconds(elapsed)-m.iInterval*1000;
sl@0
   644
	if (error<m.iLdd->iRandMin)
sl@0
   645
		m.iLdd->iRandMin=error;
sl@0
   646
	if (error>m.iLdd->iRandMax)
sl@0
   647
		m.iLdd->iRandMax=error;
sl@0
   648
	++m.iLdd->iCompletions;
sl@0
   649
	m.FillWithGarbage(0xd9);
sl@0
   650
	}
sl@0
   651
sl@0
   652
void NTimerQTest::Test(TAny* aPtr, TInt aPos)
sl@0
   653
	{
sl@0
   654
	DMsTim& ldd=*(DMsTim*)aPtr;
sl@0
   655
	++ldd.iCallBacks;
sl@0
   656
	if (aPos==7)
sl@0
   657
		return;
sl@0
   658
	TUint action=Random(ldd.iSeed)&31;
sl@0
   659
	TMsTimRand& m=ldd.iMsTimR[action&7];
sl@0
   660
	if (action<8)
sl@0
   661
		{
sl@0
   662
#ifdef __SMP__
sl@0
   663
		TUint fill=(aPos<<5)|(m.i8888.iHState1<<2)|3;
sl@0
   664
#else
sl@0
   665
		TUint fill=(aPos<<5)|(m.iState<<2)|3;
sl@0
   666
#endif
sl@0
   667
		m.Cancel();
sl@0
   668
		m.FillWithGarbage(fill);
sl@0
   669
		}
sl@0
   670
	else if (action<16)
sl@0
   671
		{
sl@0
   672
		TUint iv=(Random(ldd.iSeed)&31)+32;
sl@0
   673
		TInt r=m.Start(iv,&ldd,aPos);
sl@0
   674
		if (r!=KErrNone)
sl@0
   675
			++ldd.iStartFail;
sl@0
   676
		}
sl@0
   677
	if (XferC())
sl@0
   678
		++ldd.iXferC;
sl@0
   679
	if (CritC())
sl@0
   680
		++ldd.iCritC;
sl@0
   681
	}
sl@0
   682
sl@0
   683
DECLARE_STANDARD_LDD()
sl@0
   684
	{
sl@0
   685
    return new DMsTimFactory;
sl@0
   686
    }
sl@0
   687
sl@0
   688
DMsTimFactory::DMsTimFactory()
sl@0
   689
//
sl@0
   690
// Constructor
sl@0
   691
//
sl@0
   692
    {
sl@0
   693
    iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
   694
    //iParseMask=0;//No units, no info, no PDD
sl@0
   695
    //iUnitsMask=0;//Only one thing
sl@0
   696
    }
sl@0
   697
sl@0
   698
TInt DMsTimFactory::Create(DLogicalChannelBase*& aChannel)
sl@0
   699
//
sl@0
   700
// Create a new DMsTim on this logical device
sl@0
   701
//
sl@0
   702
    {
sl@0
   703
	aChannel=new DMsTim;
sl@0
   704
	return aChannel?KErrNone:KErrNoMemory;
sl@0
   705
    }
sl@0
   706
sl@0
   707
const TInt KDMsTimThreadPriority = 27;
sl@0
   708
_LIT(KDMsTimThread,"DMsTimThread");
sl@0
   709
sl@0
   710
TInt DMsTimFactory::Install()
sl@0
   711
//
sl@0
   712
// Install the LDD - overriding pure virtual
sl@0
   713
//
sl@0
   714
    {
sl@0
   715
	// Allocate a kernel thread to run the DFC 
sl@0
   716
	TInt r = Kern::DynamicDfcQCreate(gDfcQ, KDMsTimThreadPriority, KDMsTimThread);
sl@0
   717
sl@0
   718
#ifdef CPU_AFFINITY_ANY
sl@0
   719
			NKern::ThreadSetCpuAffinity((NThread*)(gDfcQ->iThread), KCpuAffinityAny);			
sl@0
   720
#endif
sl@0
   721
sl@0
   722
	if (r != KErrNone)
sl@0
   723
		return r; 	
sl@0
   724
sl@0
   725
    return SetName(&KMsTimerLddName);
sl@0
   726
    }
sl@0
   727
sl@0
   728
void DMsTimFactory::GetCaps(TDes8& aDes) const
sl@0
   729
//
sl@0
   730
// Get capabilities - overriding pure virtual
sl@0
   731
//
sl@0
   732
    {
sl@0
   733
    TCapsMsTimV01 b;
sl@0
   734
    b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
   735
    Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
sl@0
   736
    }
sl@0
   737
sl@0
   738
/**
sl@0
   739
  Destructor
sl@0
   740
*/
sl@0
   741
DMsTimFactory::~DMsTimFactory()
sl@0
   742
	{
sl@0
   743
	if (gDfcQ)
sl@0
   744
		gDfcQ->Destroy();
sl@0
   745
	}
sl@0
   746
sl@0
   747
DMsTim::DMsTim()
sl@0
   748
//
sl@0
   749
// Constructor
sl@0
   750
//
sl@0
   751
    {
sl@0
   752
	iThread=&Kern::CurrentThread();
sl@0
   753
	iThread->Open();
sl@0
   754
	TInt i;
sl@0
   755
	for (i=0; i<KMaxMsTim; i++)
sl@0
   756
		{
sl@0
   757
		iMsTim[i].iLdd=this;
sl@0
   758
		iMsTim[i].iId=i;
sl@0
   759
		}
sl@0
   760
	for (i=0; i<KMaxMsTimR; i++)
sl@0
   761
		{
sl@0
   762
		iMsTimR[i].iLdd=this;
sl@0
   763
		}
sl@0
   764
	iSeed[0]=NTimerQTest::MsCount();
sl@0
   765
	iSeed[1]=0;
sl@0
   766
    }
sl@0
   767
sl@0
   768
TInt DMsTim::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
sl@0
   769
//
sl@0
   770
// Create channel
sl@0
   771
//
sl@0
   772
    {
sl@0
   773
    if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
sl@0
   774
    	return KErrNotSupported;
sl@0
   775
	InitTimer();
sl@0
   776
	SetDfcQ(gDfcQ);
sl@0
   777
	for (TInt i = 0 ; i < KMaxMsTim ; ++i)
sl@0
   778
		{
sl@0
   779
		TInt r = iMsTim[i].Create();
sl@0
   780
		if (r != KErrNone)
sl@0
   781
			return r;
sl@0
   782
		}
sl@0
   783
	iMsgQ.Receive();
sl@0
   784
#ifdef __SMP__
sl@0
   785
	NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), NKern::NumberOfCpus() - 1); // Try and avoid the cpu the test app is running on
sl@0
   786
#endif
sl@0
   787
	return KErrNone;
sl@0
   788
	}
sl@0
   789
sl@0
   790
DMsTim::~DMsTim()
sl@0
   791
//
sl@0
   792
// Destructor
sl@0
   793
//
sl@0
   794
    {
sl@0
   795
#if defined(__MI920__) || defined(__NI1136__)
sl@0
   796
#if !defined(USE_CM920_FRC)
sl@0
   797
	TIntegratorAP::EnableTimer(TIntegratorAP::ECounterTimer1, TIntegratorAP::EDisable);
sl@0
   798
#endif
sl@0
   799
#endif
sl@0
   800
#if defined(__IS_OMAP1510__) || defined(__IS_OMAP1610__) 
sl@0
   801
	TOmapTimer::SetTimer3Ctrl( 0 );	// disable the timer
sl@0
   802
#endif
sl@0
   803
	Kern::SafeClose((DObject*&)iThread, NULL);
sl@0
   804
    }
sl@0
   805
sl@0
   806
void DMsTim::HandleMsg(TMessageBase* aMsg)
sl@0
   807
	{
sl@0
   808
	TInt r=KErrNone;
sl@0
   809
	TThreadMessage& m=*(TThreadMessage*)aMsg;
sl@0
   810
	TInt id=m.iValue;
sl@0
   811
	if (id==(TInt)ECloseMsg)
sl@0
   812
		{
sl@0
   813
		NTimerQTest::Stop();
sl@0
   814
		TInt i;
sl@0
   815
		for (i=0; i<KMaxMsTim; i++)
sl@0
   816
			{
sl@0
   817
			iMsTim[i].Cancel();
sl@0
   818
			iMsTim[i].iCompletionDfc.Cancel();
sl@0
   819
			iMsTim[i].CompleteClient(KErrCancel);
sl@0
   820
			}
sl@0
   821
		for (i=0; i<KMaxMsTimR; i++)
sl@0
   822
			{
sl@0
   823
			iMsTimR[i].Cancel();
sl@0
   824
			iMsTimR[i].FillWithGarbage(0x01);
sl@0
   825
			}
sl@0
   826
		m.Complete(KErrNone,EFalse);
sl@0
   827
		iMsgQ.CompleteAll(KErrServerTerminated);
sl@0
   828
		return;
sl@0
   829
		}
sl@0
   830
	else if (id<0)
sl@0
   831
		{
sl@0
   832
		TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
sl@0
   833
		r=DoRequest(~id,pS,m.Ptr1(),m.Ptr2());
sl@0
   834
		}
sl@0
   835
	else
sl@0
   836
		{
sl@0
   837
		r=DoControl(id,m.Ptr0(),m.Ptr1());
sl@0
   838
		}
sl@0
   839
	m.Complete(r,ETrue);
sl@0
   840
	}
sl@0
   841
sl@0
   842
TInt DMsTim::DoControl(TInt aFunction, TAny* a1, TAny* a2)
sl@0
   843
	{
sl@0
   844
	TInt r=KErrNone;
sl@0
   845
	TInt id=(TInt)a1;
sl@0
   846
	TMsTim& m=iMsTim[id];
sl@0
   847
	TInt interval=(TInt)a2;
sl@0
   848
	switch (aFunction)
sl@0
   849
		{
sl@0
   850
		case RMsTim::EControlStartPeriodicInt:
sl@0
   851
			r=m.Start(TMsTim::EIntAgain,interval,0);
sl@0
   852
			break;
sl@0
   853
		case RMsTim::EControlStartPeriodicDfc:
sl@0
   854
			r=m.Start(TMsTim::EDfcAgain,interval,0);
sl@0
   855
			break;
sl@0
   856
		case RMsTim::EControlStopPeriodic:
sl@0
   857
			m.Cancel();
sl@0
   858
			m.iCompletionDfc.Cancel();
sl@0
   859
			break;
sl@0
   860
		case RMsTim::EControlGetInfo:
sl@0
   861
			{
sl@0
   862
			SMsTimerInfo info;
sl@0
   863
			info.iCount=m.iCount;
sl@0
   864
			Int64 avg=m.iTotal/m.iCount;
sl@0
   865
			info.iAvg=TicksToMicroseconds((TInt)avg);
sl@0
   866
#ifdef __SMP__
sl@0
   867
			info.iMin=info.iAvg;
sl@0
   868
			info.iMax=info.iAvg;
sl@0
   869
#else
sl@0
   870
			info.iMin=TicksToMicroseconds(m.iMin);
sl@0
   871
			info.iMax=TicksToMicroseconds(m.iMax);
sl@0
   872
#endif
sl@0
   873
sl@0
   874
			r=Kern::ThreadRawWrite(iThread,a2,&info,sizeof(info));
sl@0
   875
			break;
sl@0
   876
			}
sl@0
   877
		case RMsTim::EControlBeginRandomTest:
sl@0
   878
			{
sl@0
   879
			iRandMin=KMaxTInt;
sl@0
   880
			iRandMax=KMinTInt;
sl@0
   881
			iXferC=0;
sl@0
   882
			iCritC=0;
sl@0
   883
			iStartFail=0;
sl@0
   884
			iCallBacks=0;
sl@0
   885
			iCompletions=0;
sl@0
   886
			NTimerQTest::Setup(this);
sl@0
   887
			break;
sl@0
   888
			}
sl@0
   889
		case RMsTim::EControlEndRandomTest:
sl@0
   890
			{
sl@0
   891
			NTimerQTest::Stop();
sl@0
   892
			TInt i;
sl@0
   893
			for (i=0; i<KMaxMsTimR; i++)
sl@0
   894
				{
sl@0
   895
				iMsTimR[i].Cancel();
sl@0
   896
				iMsTimR[i].FillWithGarbage(0x35);
sl@0
   897
				}
sl@0
   898
			break;
sl@0
   899
			}
sl@0
   900
		case RMsTim::EControlGetRandomTestInfo:
sl@0
   901
			{
sl@0
   902
			SRandomTestInfo info;
sl@0
   903
			info.iMin=iRandMin;
sl@0
   904
			info.iMax=iRandMax;
sl@0
   905
			info.iXferC=iXferC;
sl@0
   906
			info.iCritC=iCritC;
sl@0
   907
			info.iStartFail=iStartFail;
sl@0
   908
			info.iCallBacks=iCallBacks;
sl@0
   909
			info.iCompletions=iCompletions;
sl@0
   910
			r=Kern::ThreadRawWrite(iThread,a1,&info,sizeof(info));
sl@0
   911
			break;
sl@0
   912
			}
sl@0
   913
		case RMsTim::EControlGetIdleTime:
sl@0
   914
			{
sl@0
   915
			TInt irq=NKern::DisableAllInterrupts();
sl@0
   916
			r=NTimerQ::IdleTime();
sl@0
   917
			NKern::RestoreInterrupts(irq);
sl@0
   918
			break;
sl@0
   919
			}
sl@0
   920
		default:
sl@0
   921
			r=KErrNotSupported;
sl@0
   922
			break;
sl@0
   923
		}
sl@0
   924
	return r;
sl@0
   925
	}
sl@0
   926
sl@0
   927
TInt DMsTim::DoRequest(TInt aFunction, TRequestStatus* aStatus, TAny* a1, TAny* a2)
sl@0
   928
	{
sl@0
   929
	TInt id=(TInt)a1;
sl@0
   930
	TMsTim& m=iMsTim[aFunction == RMsTim::ERequestIntCancel ? 7 : id];
sl@0
   931
	TInt interval=(TInt)a2;
sl@0
   932
	TInt r=KErrNone;
sl@0
   933
	switch (aFunction)
sl@0
   934
		{
sl@0
   935
		case RMsTim::ERequestOneShotInt:
sl@0
   936
			r=m.Start(TMsTim::EIntAfter,interval,0);
sl@0
   937
			break;
sl@0
   938
		case RMsTim::ERequestOneShotDfc:
sl@0
   939
			r=m.Start(TMsTim::EDfcAfter,interval,0);
sl@0
   940
			break;
sl@0
   941
		case RMsTim::ERequestIntCancel:
sl@0
   942
			r=m.Start(TMsTim::EIntCancel,interval,id);
sl@0
   943
			break;
sl@0
   944
		case RMsTim::ERequestOneShotIntAgain:
sl@0
   945
			r=m.Start(TMsTim::EIntAgainOnce,interval,0);
sl@0
   946
			break;
sl@0
   947
		case RMsTim::ERequestOneShotUserDfc:
sl@0
   948
			r=m.Start(TMsTim::EUserDfcAfter,interval,0);
sl@0
   949
			break;
sl@0
   950
		case RMsTim::ERequestOneShotUserDfcAgain:
sl@0
   951
			r=m.Start(TMsTim::EUserDfcAgainOnce,interval,0);
sl@0
   952
			break;
sl@0
   953
		default:
sl@0
   954
			r=KErrNotSupported;
sl@0
   955
			break;
sl@0
   956
		}
sl@0
   957
	m.iRequest->SetStatus(aStatus);
sl@0
   958
	if (r!=KErrNone)
sl@0
   959
		Kern::QueueRequestComplete(iThread,m.iRequest,r);
sl@0
   960
	return r;
sl@0
   961
	}
sl@0
   962
sl@0
   963
void DMsTim::TimerExpired(TInt anId)
sl@0
   964
	{
sl@0
   965
	TMsTim& m=iMsTim[anId];
sl@0
   966
	switch (m.iMode)
sl@0
   967
		{
sl@0
   968
		case TMsTim::EIntAfter:
sl@0
   969
		case TMsTim::EDfcAfter:
sl@0
   970
		case TMsTim::EUserDfcAfter:
sl@0
   971
			m.CompleteClient(KErrNone);
sl@0
   972
			break;
sl@0
   973
		case TMsTim::EIntAgain:
sl@0
   974
		case TMsTim::EDfcAgain:
sl@0
   975
			break;
sl@0
   976
		case TMsTim::EIntCancel:
sl@0
   977
		case TMsTim::EDfcCancel:
sl@0
   978
			{
sl@0
   979
			TMsTim& cancelled=iMsTim[m.iParam];
sl@0
   980
			cancelled.CompleteClient(KErrAbort);
sl@0
   981
			m.CompleteClient(KErrNone);
sl@0
   982
			break;
sl@0
   983
			}
sl@0
   984
		}
sl@0
   985
	}
sl@0
   986