os/kernelhwsrv/kerneltest/e32test/realtime/d_latncy.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/realtime/d_latncy.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,569 @@
     1.4 +// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32test\realtime\d_latncy.cpp
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include "platform.h"
    1.22 +
    1.23 +#if defined(__MEIG__)
    1.24 +#include <cl7211.h>
    1.25 +#elif defined(__MAWD__)
    1.26 +#include <windermere.h>
    1.27 +#elif defined(__MISA__)
    1.28 +#include <sa1100.h>
    1.29 +#elif defined(__MCOT__)
    1.30 +#include <cotulla.h>
    1.31 +#elif defined(__MI920__) || defined(__NI1136__)
    1.32 +#include <integratorap.h>
    1.33 +//#define FREE_RUNNING_MODE			// runs the millisecond timer in free running mode
    1.34 +#elif defined(__IS_OMAP1610__)
    1.35 +#include <omap_timer.h>
    1.36 +#include <omap_plat.h>
    1.37 +#elif defined(__IS_OMAP2420__) || defined(__WAKEUP_3430__)
    1.38 +#include <omap_hw.h>
    1.39 +#include <shared_instrtimer.h>
    1.40 +#elif defined(__EPOC32__) && defined(__CPU_X86)
    1.41 +#include <x86.h>
    1.42 +#include <x86pc.h>
    1.43 +#elif defined(__RVEMUBOARD__)
    1.44 +#include <rvemuboard.h>
    1.45 +#elif defined(__NE1_TB__)
    1.46 +#include <upd35001_timer.h>
    1.47 +#endif
    1.48 +
    1.49 +#ifdef __CPU_ARM
    1.50 +#include <arm.h>
    1.51 +#endif
    1.52 +
    1.53 +#include <kernel/kern_priv.h>		//temporary
    1.54 +#include "d_latncy.h"
    1.55 +
    1.56 +_LIT(KLddName,"Latency");
    1.57 +_LIT(KThreadName,"LatencyThreadK");
    1.58 +
    1.59 +#if defined(__MEIG__)
    1.60 +const TInt KTickPeriodMs=2;
    1.61 +const TInt KTicksPerMillisecond=512;
    1.62 +#elif defined(__MAWD__)
    1.63 +const TInt KTickPeriodMs=1;
    1.64 +const TInt KTicksPerMillisecond=512;
    1.65 +#elif defined(__MISA__) || defined(__MCOT__)
    1.66 +const TInt KTicksPerMillisecond=3686;
    1.67 +const TInt KOstTicks=3685;	// not quite 1ms, so it goes in and out of phase with ms timer
    1.68 +TUint TriggerTime;
    1.69 +#elif defined(__MI920__) || defined(__NI1136__)
    1.70 +const TInt KTickPeriodMs=1;
    1.71 +#if defined(__MI920__) || defined(__NI1136__)
    1.72 +#ifdef FREE_RUNNING_MODE	
    1.73 +const TInt KTicksPerMillisecond=1500;
    1.74 +#else
    1.75 +const TInt KTicksPerMillisecond=24000;
    1.76 +#endif
    1.77 +#endif
    1.78 +#elif defined(__IS_OMAP1610__)
    1.79 +const TInt KTickPeriodMs=1;
    1.80 +TInt KTicksPerMillisecond = TOmapPlat::GetInputClk()/32000;
    1.81 +#elif defined(__IS_OMAP2420__) || defined(__WAKEUP_3430__)
    1.82 +const TInt KTickPeriodMs=1;					// defined for compatibility but not used (ignored)
    1.83 +const TInt KTicksPerMillisecond = 12000; 	// Hard coded (12Mhz)
    1.84 +#elif defined(__EPOC32__) && defined(__CPU_X86)
    1.85 +const TInt KTickPeriodMs=1;
    1.86 +const TInt KTicksPerMillisecond=1193;
    1.87 +#elif defined(__RVEMUBOARD__)
    1.88 +const TInt KTickPeriodMs=1;
    1.89 +const TInt KTicksPerMillisecond=1000;
    1.90 +#elif defined(__NE1_TB__)
    1.91 +const TInt KTickPeriodMs=1;
    1.92 +const TInt KTicksPerMillisecond=66667;
    1.93 +#endif
    1.94 +
    1.95 +#ifdef _DEBUG
    1.96 +const TInt KFudgeFactor=1;
    1.97 +#else
    1.98 +const TInt KFudgeFactor=1;
    1.99 +#endif
   1.100 +
   1.101 +class DDeviceLatency : public DLogicalDevice
   1.102 +	{
   1.103 +public:
   1.104 +	DDeviceLatency();
   1.105 +	virtual TInt Install();
   1.106 +	virtual void GetCaps(TDes8& aDes) const;
   1.107 +	virtual TInt Create(DLogicalChannelBase*& aChannel);
   1.108 +	};
   1.109 +
   1.110 +class DLatencyPowerHandler : public DPowerHandler
   1.111 +	{
   1.112 +public: // from DPOwerHandler
   1.113 +	void PowerUp();
   1.114 +	void PowerDown(TPowerState);
   1.115 +public:
   1.116 +	DLatencyPowerHandler(DLatency* aChannel);
   1.117 +public:
   1.118 +	DLatency* iChannel;
   1.119 +	};
   1.120 +
   1.121 +
   1.122 +
   1.123 +inline TUint DLatency::Ticks()
   1.124 +	{
   1.125 +#if defined(__MEIG__)
   1.126 +	return KTicksPerMillisecond-(*(volatile TUint*)(KEigerTimer2Data16+KEigerBaseAddress)&0xffff);
   1.127 +#elif defined(__MAWD__)
   1.128 +	return KTicksPerMillisecond-(*(volatile TUint*)(KWindTimer2Value16+KWindBaseAddress)&0xffff);
   1.129 +#elif defined(__MISA__) || defined(__MCOT__)
   1.130 +	return *(volatile TUint*)KHwRwOstOscr-iTriggerTime;
   1.131 +#elif defined(__MI920__) || defined(__NI1136__)
   1.132 +	return KTicksPerMillisecond-(*(volatile TUint*)(KHwCounterTimer2+KHoTimerValue)&0xffff);
   1.133 +#elif defined(__IS_OMAP1610__)
   1.134 +	return KTicksPerMillisecond - *(volatile TUint*)(KHwBaseOSTimer1Reg+KHoOSTimer_READ_TIM);
   1.135 +#elif defined(__IS_OMAP2420__) || defined(__WAKEUP_3430__)
   1.136 +	return (*(volatile TUint*)(iTimerInfo.iAddress + KHoGpTimer_TCRR)) - iTimerLoadValue;
   1.137 +#elif defined(__X86PC__)
   1.138 +	return 1194 - __HwTimer();
   1.139 +#elif defined(__RVEMUBOARD__)
   1.140 +	return KTicksPerMillisecond-(*(volatile TUint*)(KHwCounterTimer1+KHoTimerValue)&0xffff);
   1.141 +#elif defined(__NE1_TB__)
   1.142 +	return NETimer::Timer(0).iTimerCount;	// counts up, reset timer + interrupt on match
   1.143 +#endif
   1.144 +	}
   1.145 +
   1.146 +#if !defined(__SMP__)
   1.147 +#if !defined(__EPOC32__) || !defined(__CPU_X86)
   1.148 +extern TUint IntStackPtr();
   1.149 +#endif
   1.150 +#endif
   1.151 +
   1.152 +DECLARE_STANDARD_LDD()
   1.153 +	{
   1.154 +	return new DDeviceLatency;
   1.155 +	}
   1.156 +
   1.157 +DDeviceLatency::DDeviceLatency()
   1.158 +//
   1.159 +// Constructor
   1.160 +//
   1.161 +	{
   1.162 +	//iParseMask=0;
   1.163 +	//iUnitsMask=0;
   1.164 +	iVersion=TVersion(1,0,1);
   1.165 +	}
   1.166 +
   1.167 +TInt DDeviceLatency::Install()
   1.168 +//
   1.169 +// Install the device driver.
   1.170 +//
   1.171 +	{
   1.172 +	TInt r=SetName(&KLddName);
   1.173 +	return r;
   1.174 +	}
   1.175 +
   1.176 +void DDeviceLatency::GetCaps(TDes8& aDes) const
   1.177 +//
   1.178 +// Return the Comm capabilities.
   1.179 +//
   1.180 +	{
   1.181 +	}
   1.182 +
   1.183 +TInt DDeviceLatency::Create(DLogicalChannelBase*& aChannel)
   1.184 +//
   1.185 +// Create a channel on the device.
   1.186 +//
   1.187 +	{
   1.188 +	aChannel=new DLatency;
   1.189 +	return aChannel?KErrNone:KErrNoMemory;
   1.190 +	}
   1.191 +
   1.192 +DLatency::DLatency()
   1.193 +	:	iMsCallBack(MsCallBack,this),
   1.194 +		iMsDfc(MsDfc,this,NULL,1)
   1.195 +//
   1.196 +// Constructor
   1.197 +//
   1.198 +	{
   1.199 +#if !defined(__SMP__)
   1.200 +#if !defined(__EPOC32__) || !defined(__CPU_X86)
   1.201 +	iIntStackTop=(TUint*)IntStackPtr();
   1.202 +#endif
   1.203 +#endif
   1.204 +#if defined(__MISA__) || defined(__MCOT__)
   1.205 +	iTickIncrement=KOstTicks*KFudgeFactor;
   1.206 +#endif
   1.207 +#if defined(__IS_OMAP2420__) || defined(__WAKEUP_3430__)
   1.208 +	iTimerInfo.iAddress = 0;
   1.209 +#endif
   1.210 +	}
   1.211 +
   1.212 +DLatency::~DLatency()
   1.213 +//
   1.214 +// Destructor
   1.215 +//
   1.216 +	{
   1.217 +	iOff = (TUint8)ETrue;
   1.218 +	StopTimer();
   1.219 +	iMsDfc.Cancel();
   1.220 +
   1.221 +	if (iRtDfcQ)
   1.222 +		iRtDfcQ->Destroy();
   1.223 +
   1.224 +	if (iPowerHandler)
   1.225 +		{
   1.226 +		iPowerHandler->Remove();
   1.227 +		delete iPowerHandler;
   1.228 +		}
   1.229 +
   1.230 +	Kern::SafeClose((DObject*&)iClient, NULL);
   1.231 +	}
   1.232 +
   1.233 +TInt DLatency::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
   1.234 +//
   1.235 +// Create the channel from the passed info.
   1.236 +//
   1.237 +	{
   1.238 +	if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
   1.239 +		return KErrNotSupported;
   1.240 +
   1.241 +	// create the power handler
   1.242 +	iPowerHandler = new DLatencyPowerHandler(this);
   1.243 +	if (!iPowerHandler)
   1.244 +		return KErrNoMemory;
   1.245 +	iPowerHandler->Add();
   1.246 +
   1.247 +	// Allocate a kernel thread to run the DFC 
   1.248 +	TInt r = Kern::DynamicDfcQCreate(iRtDfcQ, KNumPriorities-1,KThreadName);
   1.249 +
   1.250 +	if (r != KErrNone)
   1.251 +		return r;
   1.252 +	
   1.253 +#ifdef CPU_AFFINITY_ANY
   1.254 +	NKern::ThreadSetCpuAffinity((NThread*)(iRtDfcQ->iThread), KCpuAffinityAny);			
   1.255 +#endif
   1.256 +
   1.257 +	iMsDfc.SetDfcQ(iRtDfcQ);
   1.258 +	iClient=&Kern::CurrentThread();
   1.259 +	iClient->Open();
   1.260 +	Kern::SetThreadPriority(KNumPriorities-2);
   1.261 +	return KErrNone;
   1.262 +	}
   1.263 +
   1.264 +#if defined(__MISA__) 
   1.265 +// For SA1100/SA1110 use a separate timer on a FIQ interrupt (OST match 0)
   1.266 +TInt DLatency::StartTimer()
   1.267 +	{
   1.268 +	TInt r=Interrupt::Bind(KIntIdOstMatchGeneral,MsCallBack,this);
   1.269 +	if (r==KErrNone)
   1.270 +		{
   1.271 +		TSa1100::ModifyIntLevels(0,KHtIntsOstMatchGeneral);	// route new timer interrupt to FIQ
   1.272 +		TSa1100::SetOstMatchEOI(KHwOstMatchGeneral);
   1.273 +		TUint oscr=TSa1100::OstData();
   1.274 +		iTriggerTime=oscr+KOstTicks*KFudgeFactor;
   1.275 +		TSa1100::SetOstMatch(KHwOstMatchGeneral,iTriggerTime);
   1.276 +		TSa1100::EnableOstInterrupt(KHwOstMatchGeneral);
   1.277 +		Interrupt::Enable(KIntIdOstMatchGeneral);
   1.278 +		}
   1.279 +	return r;
   1.280 +	}
   1.281 +#elif defined(__MCOT__)
   1.282 +// For Cotulla use a separate timer on a FIQ interrupt (OST match 0)
   1.283 +TInt DLatency::StartTimer()
   1.284 +	{
   1.285 +	TInt r=Interrupt::Bind(KIntIdOstMatchGeneral,MsCallBack,this);
   1.286 +	if (r==KErrNone)
   1.287 +		{
   1.288 +		TCotulla::ModifyIntLevels(0,KHtIntsOstMatchGeneral);	// route new timer interrupt to FIQ
   1.289 +		TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
   1.290 +		TUint oscr=TCotulla::OstData();
   1.291 +		iTriggerTime=oscr+KOstTicks*KFudgeFactor;
   1.292 +		TCotulla::SetOstMatch(iTriggerTime,KHwOstMatchGeneral);
   1.293 +		TCotulla::EnableOstInterrupt(KHwOstMatchGeneral);
   1.294 +		Interrupt::Enable(KIntIdOstMatchGeneral);
   1.295 +		}
   1.296 +	return r;
   1.297 +	}
   1.298 +#elif defined(__IS_OMAP2420__) || defined(__WAKEUP_3430__)
   1.299 +TInt DLatency::StartTimer()
   1.300 +/* 
   1.301 + *  For OMAP2420 initialise a new timer to generate an interrupt every 1ms
   1.302 + */
   1.303 +	{
   1.304 +	__ASSERT_ALWAYS(!iTimerInfo.iAddress, Kern::Fault("D_Latncy: timer allocated twice.",
   1.305 +													 iTimerInfo.iAddress));
   1.306 +
   1.307 +	// Get an available Timer from the system
   1.308 +    TInt r = OmapTimerMgr::GetTimer(iGPTimerId, iTimerInfo);
   1.309 +    if (KErrNone != r)
   1.310 +    	{
   1.311 +    	return r;
   1.312 +    	}
   1.313 +    	
   1.314 +    // Configure the timer
   1.315 +    r = ConfigureTimer();
   1.316 +    if (KErrNone != r)
   1.317 +    	{
   1.318 +    	DisableTimer();
   1.319 +    	return r;
   1.320 +    	}
   1.321 +    
   1.322 +    // Bind to timer interrupt
   1.323 +    r = Interrupt::Bind(iTimerInfo.iInterruptId, MsCallBack, this);
   1.324 +    if (KErrNone != r)
   1.325 +        {
   1.326 +        DisableTimer();
   1.327 +        return r;
   1.328 +        }
   1.329 +              
   1.330 +    // Unmask timer IT in interrupt controller
   1.331 +    r = Interrupt::Enable(iTimerInfo.iInterruptId);
   1.332 +    if (KErrNone != r)
   1.333 +		{
   1.334 +		Interrupt::Unbind(iTimerInfo.iInterruptId);
   1.335 +		DisableTimer();
   1.336 +    	return r;
   1.337 +    	}
   1.338 +    
   1.339 +    // Start timer
   1.340 +    TOmap::ModifyRegister32(iTimerInfo.iAddress + KHoGpTimer_TCLR, KClear32,
   1.341 +                        KHtGpTimer_TCLR_St);
   1.342 +        
   1.343 +    return KErrNone;
   1.344 +	}
   1.345 +
   1.346 +void DLatency::DisableTimer()
   1.347 +/*
   1.348 + *	Disable the interface and functional clock and mark the timer as available 
   1.349 + */
   1.350 +	{
   1.351 +	  // Stop timer
   1.352 +    TOmap::ModifyRegister32(iTimerInfo.iAddress + KHoGpTimer_TCLR,
   1.353 +                        KHtGpTimer_TCLR_St, KClear32);
   1.354 +
   1.355 +#if defined(__WAKEUP_3430__)
   1.356 +    // Disable Timer clocks using Timer framework instead of using TPRcm direct calls for 3430
   1.357 +    TInt r = OmapTimerMgr::DisableClocks(iGPTimerId);
   1.358 +    if (r != KErrNone)
   1.359 +        __ASSERT_ALWAYS(r, Kern::Fault("Timer clocks disable failed", 0)) ;
   1.360 +#else
   1.361 +	// Disable timer interface clock in PRCM
   1.362 +	TPrcm::InterfaceClkCtrl(iTimerInfo.iPrcmDeviceId, EFalse);
   1.363 +	
   1.364 +	// Disable timer functional clock in PRCM
   1.365 +	TPrcm::FunctionalClkCtrl(iTimerInfo.iPrcmDeviceId, EFalse);
   1.366 +#endif
   1.367 +
   1.368 +	// Release the timer
   1.369 +	OmapTimerMgr::ReleaseTimer(iGPTimerId);
   1.370 +	
   1.371 +	iTimerInfo.iAddress = 0;
   1.372 +	}
   1.373 +
   1.374 +
   1.375 +TInt DLatency::ConfigureTimer()
   1.376 +/*
   1.377 + *	This method will configure a timer to:
   1.378 + *		-	run at the system clock (12Mhz)
   1.379 + *		-	no prescaler (disable TCLR[PRE])
   1.380 + *		-   autoreload and overflow interrupt enabled (TLDR will contain a
   1.381 + *			value to generate an interrupt every 1000microsec)
   1.382 + */
   1.383 +	{
   1.384 +
   1.385 +#if defined(__WAKEUP_3430__)
   1.386 +	// Enable Timer clocks using timer framework instead of TPrcm direct calls for 3430
   1.387 +    TInt r = OmapTimerMgr::EnableClocks(iGPTimerId);
   1.388 +    if (r != KErrNone)
   1.389 +        __ASSERT_ALWAYS(r, Kern::Fault("Timer Clocks enable failed", 0)) ;
   1.390 +
   1.391 +	// Select the input clock to be system clock 
   1.392 +    r = OmapTimerMgr::SetTimerClkSrc(iGPTimerId, ESysClk);
   1.393 +#else
   1.394 +	// Enable timer interface clock in PRCM  
   1.395 +	TPrcm::InterfaceClkCtrl(iTimerInfo.iPrcmDeviceId, ETrue, ETrue);
   1.396 +	// Enable timer functional clock in PRCM
   1.397 +	TPrcm::FunctionalClkCtrl(iTimerInfo.iPrcmDeviceId, ETrue, ETrue);
   1.398 +
   1.399 +	// Select the input clock to be system clock 
   1.400 +    TInt r = OmapTimerMgr::SetTimerClkSrc(iGPTimerId, ESysClk);
   1.401 +#endif
   1.402 +
   1.403 +    if (KErrNone != r)	
   1.404 +    	return r;
   1.405 +
   1.406 +    // Timer OCP configuration: - software reset
   1.407 +    TOmap::SetRegister32( iTimerInfo.iAddress + KHoGpTimerTIOCP_CFG,
   1.408 +                          KHtGpTimer_TIOCP_CFG_SoftReset);
   1.409 +
   1.410 +    // Wait for reset to be complete
   1.411 +    TUint16 timeOut = 1000;
   1.412 +    while ( !(TOmap::Register32(iTimerInfo.iAddress + KHoGpTimer_TISTAT) & 
   1.413 +    			KHtGpTimer_TISTAT_ResetComplete)
   1.414 +    			&& --timeOut);
   1.415 +    
   1.416 +   // Check if the timer has been reset or we hit the timeout
   1.417 +   __ASSERT_ALWAYS((TOmap::Register32(iTimerInfo.iAddress + KHoGpTimer_TISTAT) & 
   1.418 +    			KHtGpTimer_TISTAT_ResetComplete), Kern::Fault("D_Latncy: failed to reset timer.",
   1.419 +													 iGPTimerId));
   1.420 +	
   1.421 +    // Set PRE to be 0, PTV value is ignored, AutoReload is enabled
   1.422 +    TOmap::SetRegister32(iTimerInfo.iAddress + KHoGpTimer_TCLR, KHtGpTimer_TCLR_AR );
   1.423 +
   1.424 +	//PTV argument is 0 because of TCLR[PRE] = 0 (prescaling disabled)
   1.425 +	TInt timerPTV = 0;
   1.426 +	
   1.427 +	// Calculate clock frequence from the ticks per ms
   1.428 +	TInt timerClkSrcFreq = KTicksPerMillisecond * 1000;
   1.429 +    
   1.430 +    iTimerLoadValue = OmapTimerMgr::TimerLoadValue(/*microsecs*/1000, timerClkSrcFreq, timerPTV);                          
   1.431 +
   1.432 +	// First, load value in TCRR and TLDR registers
   1.433 +    TOmap::SetRegister32(iTimerInfo.iAddress + KHoGpTimer_TCRR, iTimerLoadValue);
   1.434 +    TOmap::SetRegister32(iTimerInfo.iAddress + KHoGpTimer_TLDR, iTimerLoadValue);
   1.435 +
   1.436 +    // Enable overflow interrupt
   1.437 +    TOmap::SetRegister32(iTimerInfo.iAddress + KHoGpTimer_TIER,
   1.438 +                         KHtGpTimer_TIER_OverFlow);
   1.439 +
   1.440 +    return KErrNone;
   1.441 +	}
   1.442 +#else
   1.443 +TInt DLatency::StartTimer()
   1.444 +	{
   1.445 +	iMsCallBack.OneShot(KTickPeriodMs*KFudgeFactor);
   1.446 +	return KErrNone;
   1.447 +	}
   1.448 +#endif
   1.449 +
   1.450 +#if defined(__MISA__) 
   1.451 +// For SA1100/SA1110 use a separate timer on a FIQ interrupt (OST match 0)
   1.452 +void DLatency::StopTimer()
   1.453 +	{
   1.454 +	TSa1100::ModifyIntLevels(KHtIntsOstMatchGeneral,0);
   1.455 +	TSa1100::DisableOstInterrupt(KHwOstMatchGeneral);
   1.456 +	Interrupt::Disable(KIntIdOstMatchGeneral);
   1.457 +	Interrupt::Unbind(KIntIdOstMatchGeneral);
   1.458 +	TSa1100::SetOstMatchEOI(KHwOstMatchGeneral);
   1.459 +	}
   1.460 +#elif defined(__MCOT__)
   1.461 +// For Cotulla use a separate timer on a FIQ interrupt (OST match 0)
   1.462 +void DLatency::StopTimer()
   1.463 +	{
   1.464 +	TCotulla::ModifyIntLevels(KHtIntsOstMatchGeneral,0);
   1.465 +	TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
   1.466 +	Interrupt::Disable(KIntIdOstMatchGeneral);
   1.467 +	Interrupt::Unbind(KIntIdOstMatchGeneral);
   1.468 +	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
   1.469 +	}
   1.470 +#elif defined(__IS_OMAP2420__) || defined(__WAKEUP_3430__)
   1.471 +void DLatency::StopTimer()
   1.472 +	{
   1.473 +	Interrupt::Disable(iTimerInfo.iInterruptId);
   1.474 +	Interrupt::Unbind(iTimerInfo.iInterruptId);
   1.475 +	DisableTimer();
   1.476 +	}
   1.477 +#else
   1.478 +void DLatency::StopTimer()
   1.479 +	{
   1.480 +	iMsCallBack.Cancel();
   1.481 +	}
   1.482 +#endif
   1.483 +
   1.484 +TInt DLatency::Request(TInt aFunction, TAny* a1, TAny* a2)
   1.485 +//
   1.486 +// Client requests
   1.487 +//
   1.488 +	{
   1.489 +	// Kern::Printf("DLatency::Request() 0x%x)\n", aFunction);
   1.490 +	TInt r=KErrNone;
   1.491 +	switch (aFunction)
   1.492 +		{
   1.493 +		case RLatency::EControlStart:
   1.494 +			iStarted = (TUint8)ETrue;
   1.495 +			StartTimer();
   1.496 +			break;
   1.497 +		case RLatency::EControlTicksPerMs:
   1.498 +			r=KTicksPerMillisecond;
   1.499 +			break;
   1.500 +		case RLatency::EControlGetResults:
   1.501 +			iResults.iUserThreadTicks = Ticks();
   1.502 +			kumemput32(a1, &iResults, sizeof(SLatencyResults));
   1.503 +			break;
   1.504 +		default:
   1.505 +			r = KErrNotSupported;
   1.506 +			break;
   1.507 +		}
   1.508 +	return(r);
   1.509 +	}
   1.510 +
   1.511 +#ifdef __CAPTURE_EXTRAS
   1.512 +extern void CaptureExtras(SLatencyResults&);
   1.513 +#endif
   1.514 +
   1.515 +#if !defined(__MISA__) && !defined(__MCOT__)
   1.516 +void DLatency::MsCallBack(TAny* aPtr)
   1.517 +	{
   1.518 +	DLatency* pL = (DLatency*)aPtr;
   1.519 +#if defined(__IS_OMAP2420__) || defined(__WAKEUP_3430__)
   1.520 +	pL->iResults.iIntTicks = pL->Ticks();
   1.521 +	TOmap::SetRegister32(pL->iTimerInfo.iAddress + KHoGpTimer_TISR, KHtGpTimer_TISR_OverFlow);
   1.522 +#else
   1.523 +	pL->iResults.iIntTicks = Ticks();
   1.524 +#endif
   1.525 +#ifdef __CAPTURE_EXTRAS
   1.526 +	CaptureExtras(pL->iResults);
   1.527 +#endif
   1.528 +#if defined(__EPOC32__) && defined(__CPU_X86)
   1.529 +	pL->iResults.iIntRetAddr = X86::IrqReturnAddress();
   1.530 +#elif defined(__CPU_ARM) && defined(__SMP__)
   1.531 +	pL->iResults.iIntRetAddr = Arm::IrqReturnAddress();
   1.532 +#else
   1.533 +	pL->iResults.iIntRetAddr=(pL->iIntStackTop)[-1];
   1.534 +#endif
   1.535 +	if (!pL->iOff)
   1.536 +		{
   1.537 +		pL->iMsCallBack.Again(KTickPeriodMs*KFudgeFactor);
   1.538 +		pL->iMsDfc.Add();
   1.539 +		}
   1.540 +	}
   1.541 +#endif
   1.542 +
   1.543 +void DLatency::MsDfc(TAny* aPtr)
   1.544 +	{
   1.545 +	DLatency* pL = (DLatency*)aPtr;
   1.546 +	pL->iResults.iKernThreadTicks=pL->Ticks();
   1.547 +	NKern::ThreadRequestSignal(&pL->iClient->iNThread);
   1.548 +	}
   1.549 +
   1.550 +DLatencyPowerHandler::DLatencyPowerHandler(DLatency* aChannel)
   1.551 +	:	DPowerHandler(KLddName), 
   1.552 +		iChannel(aChannel)
   1.553 +	{
   1.554 +	}
   1.555 +
   1.556 +void DLatencyPowerHandler::PowerUp()
   1.557 +	{
   1.558 +	iChannel->iOff = (TUint8)EFalse;
   1.559 +	if (iChannel->iStarted)
   1.560 +		iChannel->StartTimer();
   1.561 +	PowerUpDone();
   1.562 +	}
   1.563 +
   1.564 +void DLatencyPowerHandler::PowerDown(TPowerState)
   1.565 +	{
   1.566 +	iChannel->iOff = (TUint8)ETrue;
   1.567 +	iChannel->StopTimer();
   1.568 +	PowerDownDone();
   1.569 +	}
   1.570 +
   1.571 +
   1.572 +