First public contribution.
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // \e32test\benchmark\bm_mcot_pdd.cpp
15 // PDD to provide OS timer services to benchmark programs
19 #include <kernel/kernel.h>
25 class DBMMcotDevice : public DPhysicalDevice
29 virtual TInt Install();
30 virtual void GetCaps(TDes8& aDes) const;
31 virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
32 virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
35 class DBMMcotChannel : public DBMPChannel
42 virtual TBMTicks TimerPeriod();
43 // Get current OST tick time
44 virtual TBMTicks TimerStamp();
45 // Tick/nS conversions
46 virtual TBMNs TimerTicksToNs(TBMTicks);
47 virtual TBMTicks TimerNsToTicks(TBMNs);
48 // Pass in client ISRs to invoke
49 virtual TInt BindInterrupt(MBMIsr*);
50 virtual TInt BindInterrupt(MBMInterruptLatencyIsr*);
52 virtual void RequestInterrupt();
53 virtual void CancelInterrupt();
57 // Attach to OST interrupt
60 static const TInt KBMMcotInterruptDelayTicks = KHwOscFreqHz / 1000; // ie. delay ~ 1 ms timer tick!
61 static const TBMTicks KBMMcotPeriod = (((TBMTicks) 1) << 32);
62 static const TBMNs KBMMcotNsPerTick = (1000*1000*1000) / KHwOscFreqHz;
64 // Real ISR (calls out to client)
65 static void Isr(TAny*);
68 MBMInterruptLatencyIsr* iInterruptLatencyIsr;
71 // Standard boiler plate PDD factory object
73 DECLARE_STANDARD_PDD()
75 // Create a new device
79 return new DBMMcotDevice;
82 DBMMcotDevice::DBMMcotDevice()
88 iVersion = TVersion(1,0,1);
91 TInt DBMMcotDevice::Install()
93 // Install the device driver.
96 TInt r = SetName(&KBMPdName);
100 void DBMMcotDevice::GetCaps(TDes8& aDes) const
102 // Return the Comm capabilities.
107 TInt DBMMcotDevice::Create(DBase*& aChannel, TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
109 // Create a channel on the device.
113 aChannel = new DBMMcotChannel;
114 return aChannel?KErrNone:KErrNoMemory;
117 TInt DBMMcotDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
119 if (!Kern::QueryVersionSupported(iVersion,aVer))
121 return KErrNotSupported;
126 // Actual device channel functions, called by LDD
128 // Clear saved ISR members
129 DBMMcotChannel::DBMMcotChannel()
132 // iInterruptLatencyIsr = NULL;
135 // If we ever initialised the timers to generate ISRs, clear
136 DBMMcotChannel::~DBMMcotChannel()
138 if (iIsr || iInterruptLatencyIsr)
140 TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
141 TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
142 Interrupt::Disable(KIntIdOstMatchGeneral);
143 TCotulla::ModifyIntLevels(KHtIntsOstMatchGeneral,0);
144 Interrupt::Unbind(KIntIdOstMatchGeneral);
148 TBMTicks DBMMcotChannel::TimerPeriod()
150 return KBMMcotPeriod;
153 // Read OST and return tick count
154 TBMTicks DBMMcotChannel::TimerStamp()
156 return TUint(TCotulla::OstData());
159 TBMNs DBMMcotChannel::TimerTicksToNs(TBMTicks ticks)
161 return ticks * KBMMcotNsPerTick;
164 TBMTicks DBMMcotChannel::TimerNsToTicks(TBMNs ns)
166 return ns / KBMMcotNsPerTick;
169 // Actual ISR called when benchmark timer fires
170 void DBMMcotChannel::Isr(TAny* ptr)
172 DBMMcotChannel* mCh = (DBMMcotChannel*) ptr;
173 BM_ASSERT(mCh->iIsr || mCh->iInterruptLatencyIsr);
176 // Call the handler with the current OST time
177 mCh->iIsr->Isr(TUint(TCotulla::OstData()));
181 // Call the handler with the difference between NOW and the time the match timer was set for
182 // ie. the latency between the timer interrupt set and when it was called.
183 mCh->iInterruptLatencyIsr->InterruptLatencyIsr(TCotulla::OstData() - TCotulla::OstMatch(KHwOstMatchGeneral));
185 TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
186 TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
190 // Bind the OST match interrupt to a FIQ ISR - it will interrupt running IRQ service
192 TInt DBMMcotChannel::BindInterrupt()
194 TInt r = Interrupt::Bind(KIntIdOstMatchGeneral, Isr, this);
199 TCotulla::ModifyIntLevels(0, KHtIntsOstMatchGeneral); // route new timer interrupt to FIQ
200 TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
201 Interrupt::Enable(KIntIdOstMatchGeneral);
205 // NB! Only one of these is ever used per channel opening, ie. the
206 // channel must be closed and re-opened between installing client ISR
207 TInt DBMMcotChannel::BindInterrupt(MBMIsr* aIsr)
210 BM_ASSERT(!iInterruptLatencyIsr);
212 return BindInterrupt();
215 TInt DBMMcotChannel::BindInterrupt(MBMInterruptLatencyIsr* aIsr)
218 BM_ASSERT(!iInterruptLatencyIsr);
219 iInterruptLatencyIsr = aIsr;
220 return BindInterrupt();
223 // Called by client to request an interrupt (ISR/latency ISR) invocation in ~1mS.
224 void DBMMcotChannel::RequestInterrupt()
226 BM_ASSERT(iIsr || iInterruptLatencyIsr);
227 TCotulla::SetOstMatch(TCotulla::OstData()+KBMMcotInterruptDelayTicks,KHwOstMatchGeneral);
228 TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
229 TCotulla::EnableOstInterrupt(KHwOstMatchGeneral);
232 // Called to cancel if client dies/killed after ISR scheduled ???
233 void DBMMcotChannel::CancelInterrupt()
235 if (iIsr || iInterruptLatencyIsr)
237 TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
238 TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);