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 +