1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/benchmark/bm_mcot_pdd.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,241 @@
1.4 +// Copyright (c) 2003-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\benchmark\bm_mcot_pdd.cpp
1.18 +// PDD to provide OS timer services to benchmark programs
1.19 +//
1.20 +//
1.21 +
1.22 +#include <kernel/kernel.h>
1.23 +#include <cotulla.h>
1.24 +
1.25 +
1.26 +#include "k32bm.h"
1.27 +
1.28 +class DBMMcotDevice : public DPhysicalDevice
1.29 + {
1.30 +public:
1.31 + DBMMcotDevice();
1.32 + virtual TInt Install();
1.33 + virtual void GetCaps(TDes8& aDes) const;
1.34 + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.35 + virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.36 + };
1.37 +
1.38 +class DBMMcotChannel : public DBMPChannel
1.39 + {
1.40 +public:
1.41 + DBMMcotChannel();
1.42 + ~DBMMcotChannel();
1.43 +
1.44 + // Report timing spec
1.45 + virtual TBMTicks TimerPeriod();
1.46 + // Get current OST tick time
1.47 + virtual TBMTicks TimerStamp();
1.48 + // Tick/nS conversions
1.49 + virtual TBMNs TimerTicksToNs(TBMTicks);
1.50 + virtual TBMTicks TimerNsToTicks(TBMNs);
1.51 + // Pass in client ISRs to invoke
1.52 + virtual TInt BindInterrupt(MBMIsr*);
1.53 + virtual TInt BindInterrupt(MBMInterruptLatencyIsr*);
1.54 + // Invoke an ISR
1.55 + virtual void RequestInterrupt();
1.56 + virtual void CancelInterrupt();
1.57 +
1.58 +private:
1.59 +
1.60 + // Attach to OST interrupt
1.61 + TInt BindInterrupt();
1.62 +
1.63 + static const TInt KBMMcotInterruptDelayTicks = KHwOscFreqHz / 1000; // ie. delay ~ 1 ms timer tick!
1.64 + static const TBMTicks KBMMcotPeriod = (((TBMTicks) 1) << 32);
1.65 + static const TBMNs KBMMcotNsPerTick = (1000*1000*1000) / KHwOscFreqHz;
1.66 +
1.67 + // Real ISR (calls out to client)
1.68 + static void Isr(TAny*);
1.69 +
1.70 + MBMIsr* iIsr;
1.71 + MBMInterruptLatencyIsr* iInterruptLatencyIsr;
1.72 + };
1.73 +
1.74 +// Standard boiler plate PDD factory object
1.75 +
1.76 +DECLARE_STANDARD_PDD()
1.77 +//
1.78 +// Create a new device
1.79 +//
1.80 + {
1.81 + __ASSERT_CRITICAL;
1.82 + return new DBMMcotDevice;
1.83 + }
1.84 +
1.85 +DBMMcotDevice::DBMMcotDevice()
1.86 +//
1.87 +// Constructor
1.88 +//
1.89 + {
1.90 + //iUnitsMask=0;
1.91 + iVersion = TVersion(1,0,1);
1.92 + }
1.93 +
1.94 +TInt DBMMcotDevice::Install()
1.95 +//
1.96 +// Install the device driver.
1.97 +//
1.98 + {
1.99 + TInt r = SetName(&KBMPdName);
1.100 + return r;
1.101 + }
1.102 +
1.103 +void DBMMcotDevice::GetCaps(TDes8& aDes) const
1.104 +//
1.105 +// Return the Comm capabilities.
1.106 +//
1.107 + {
1.108 + }
1.109 +
1.110 +TInt DBMMcotDevice::Create(DBase*& aChannel, TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
1.111 +//
1.112 +// Create a channel on the device.
1.113 +//
1.114 + {
1.115 + __ASSERT_CRITICAL;
1.116 + aChannel = new DBMMcotChannel;
1.117 + return aChannel?KErrNone:KErrNoMemory;
1.118 + }
1.119 +
1.120 +TInt DBMMcotDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
1.121 + {
1.122 + if (!Kern::QueryVersionSupported(iVersion,aVer))
1.123 + {
1.124 + return KErrNotSupported;
1.125 + }
1.126 + return KErrNone;
1.127 + }
1.128 +
1.129 +// Actual device channel functions, called by LDD
1.130 +
1.131 +// Clear saved ISR members
1.132 +DBMMcotChannel::DBMMcotChannel()
1.133 + {
1.134 + // iIsr = NULL;
1.135 + // iInterruptLatencyIsr = NULL;
1.136 + }
1.137 +
1.138 +// If we ever initialised the timers to generate ISRs, clear
1.139 +DBMMcotChannel::~DBMMcotChannel()
1.140 + {
1.141 + if (iIsr || iInterruptLatencyIsr)
1.142 + {
1.143 + TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
1.144 + TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
1.145 + Interrupt::Disable(KIntIdOstMatchGeneral);
1.146 + TCotulla::ModifyIntLevels(KHtIntsOstMatchGeneral,0);
1.147 + Interrupt::Unbind(KIntIdOstMatchGeneral);
1.148 + }
1.149 + }
1.150 +
1.151 +TBMTicks DBMMcotChannel::TimerPeriod()
1.152 + {
1.153 + return KBMMcotPeriod;
1.154 + }
1.155 +
1.156 +// Read OST and return tick count
1.157 +TBMTicks DBMMcotChannel::TimerStamp()
1.158 + {
1.159 + return TUint(TCotulla::OstData());
1.160 + }
1.161 +
1.162 +TBMNs DBMMcotChannel::TimerTicksToNs(TBMTicks ticks)
1.163 + {
1.164 + return ticks * KBMMcotNsPerTick;
1.165 + }
1.166 +
1.167 +TBMTicks DBMMcotChannel::TimerNsToTicks(TBMNs ns)
1.168 + {
1.169 + return ns / KBMMcotNsPerTick;
1.170 + }
1.171 +
1.172 +// Actual ISR called when benchmark timer fires
1.173 +void DBMMcotChannel::Isr(TAny* ptr)
1.174 + {
1.175 + DBMMcotChannel* mCh = (DBMMcotChannel*) ptr;
1.176 + BM_ASSERT(mCh->iIsr || mCh->iInterruptLatencyIsr);
1.177 + if (mCh->iIsr)
1.178 + {
1.179 + // Call the handler with the current OST time
1.180 + mCh->iIsr->Isr(TUint(TCotulla::OstData()));
1.181 + }
1.182 + else
1.183 + {
1.184 + // Call the handler with the difference between NOW and the time the match timer was set for
1.185 + // ie. the latency between the timer interrupt set and when it was called.
1.186 + mCh->iInterruptLatencyIsr->InterruptLatencyIsr(TCotulla::OstData() - TCotulla::OstMatch(KHwOstMatchGeneral));
1.187 + }
1.188 + TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
1.189 + TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
1.190 + }
1.191 +
1.192 +
1.193 +// Bind the OST match interrupt to a FIQ ISR - it will interrupt running IRQ service
1.194 +// routines.
1.195 +TInt DBMMcotChannel::BindInterrupt()
1.196 + {
1.197 + TInt r = Interrupt::Bind(KIntIdOstMatchGeneral, Isr, this);
1.198 + if (r != KErrNone)
1.199 + {
1.200 + return r;
1.201 + }
1.202 + TCotulla::ModifyIntLevels(0, KHtIntsOstMatchGeneral); // route new timer interrupt to FIQ
1.203 + TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
1.204 + Interrupt::Enable(KIntIdOstMatchGeneral);
1.205 + return KErrNone;
1.206 + }
1.207 +
1.208 +// NB! Only one of these is ever used per channel opening, ie. the
1.209 +// channel must be closed and re-opened between installing client ISR
1.210 +TInt DBMMcotChannel::BindInterrupt(MBMIsr* aIsr)
1.211 + {
1.212 + BM_ASSERT(!iIsr);
1.213 + BM_ASSERT(!iInterruptLatencyIsr);
1.214 + iIsr = aIsr;
1.215 + return BindInterrupt();
1.216 + }
1.217 +
1.218 +TInt DBMMcotChannel::BindInterrupt(MBMInterruptLatencyIsr* aIsr)
1.219 + {
1.220 + BM_ASSERT(!iIsr);
1.221 + BM_ASSERT(!iInterruptLatencyIsr);
1.222 + iInterruptLatencyIsr = aIsr;
1.223 + return BindInterrupt();
1.224 + }
1.225 +
1.226 +// Called by client to request an interrupt (ISR/latency ISR) invocation in ~1mS.
1.227 +void DBMMcotChannel::RequestInterrupt()
1.228 + {
1.229 + BM_ASSERT(iIsr || iInterruptLatencyIsr);
1.230 + TCotulla::SetOstMatch(TCotulla::OstData()+KBMMcotInterruptDelayTicks,KHwOstMatchGeneral);
1.231 + TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
1.232 + TCotulla::EnableOstInterrupt(KHwOstMatchGeneral);
1.233 + }
1.234 +
1.235 +// Called to cancel if client dies/killed after ISR scheduled ???
1.236 +void DBMMcotChannel::CancelInterrupt()
1.237 + {
1.238 + if (iIsr || iInterruptLatencyIsr)
1.239 + {
1.240 + TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
1.241 + TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
1.242 + }
1.243 + }
1.244 +