os/kernelhwsrv/kerneltest/e32test/benchmark/bm_mcot_pdd.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // \e32test\benchmark\bm_mcot_pdd.cpp
    15 // PDD to provide OS timer services to benchmark programs
    16 // 
    17 //
    18 
    19 #include <kernel/kernel.h>
    20 #include <cotulla.h>
    21 
    22 
    23 #include "k32bm.h"
    24 
    25 class DBMMcotDevice : public DPhysicalDevice
    26 	{
    27 public:
    28 	DBMMcotDevice();
    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);
    33 	};
    34 
    35 class DBMMcotChannel : public DBMPChannel
    36 	{
    37 public:
    38 	DBMMcotChannel();
    39 	~DBMMcotChannel();
    40 
    41 	// Report timing spec
    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*);
    51 	// Invoke an ISR 
    52 	virtual void RequestInterrupt();
    53 	virtual void CancelInterrupt();
    54 
    55 private:
    56 
    57 	// Attach to OST interrupt
    58 	TInt BindInterrupt();
    59 
    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;
    63 	
    64 	// Real ISR (calls out to client)
    65 	static void Isr(TAny*);
    66 	
    67 	MBMIsr*						iIsr;
    68 	MBMInterruptLatencyIsr*		iInterruptLatencyIsr;
    69 	};
    70 
    71 // Standard boiler plate PDD factory object 
    72 
    73 DECLARE_STANDARD_PDD()
    74 //
    75 // Create a new device
    76 //
    77 	{
    78 	__ASSERT_CRITICAL;
    79 	return new DBMMcotDevice;
    80 	}
    81 
    82 DBMMcotDevice::DBMMcotDevice()
    83 //
    84 // Constructor
    85 //
    86 	{
    87 	//iUnitsMask=0;
    88 	iVersion = TVersion(1,0,1);
    89 	}
    90 
    91 TInt DBMMcotDevice::Install()
    92 //
    93 // Install the device driver.
    94 //
    95 	{
    96 	TInt r = SetName(&KBMPdName);
    97 	return r;
    98 	}
    99 
   100 void DBMMcotDevice::GetCaps(TDes8& aDes) const
   101 //
   102 // Return the Comm capabilities.
   103 //
   104 	{
   105 	}
   106 
   107 TInt DBMMcotDevice::Create(DBase*& aChannel, TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
   108 //
   109 // Create a channel on the device.
   110 //
   111 	{
   112 	__ASSERT_CRITICAL;
   113 	aChannel = new DBMMcotChannel;
   114 	return aChannel?KErrNone:KErrNoMemory;
   115 	}
   116 
   117 TInt DBMMcotDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
   118 	{
   119 	if (!Kern::QueryVersionSupported(iVersion,aVer))
   120 		{
   121 		return KErrNotSupported;
   122 		}
   123 	return KErrNone;
   124 	}
   125 
   126 // Actual device channel functions, called by LDD
   127 
   128 // Clear saved ISR members
   129 DBMMcotChannel::DBMMcotChannel()
   130 	{
   131 	//	iIsr = NULL;
   132 	//	iInterruptLatencyIsr = NULL;
   133 	}
   134 
   135 // If we ever initialised the timers to generate ISRs, clear 
   136 DBMMcotChannel::~DBMMcotChannel()
   137 	{
   138 	if (iIsr || iInterruptLatencyIsr)
   139 		{
   140 		TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
   141 		TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
   142 		Interrupt::Disable(KIntIdOstMatchGeneral);
   143 		TCotulla::ModifyIntLevels(KHtIntsOstMatchGeneral,0);
   144 		Interrupt::Unbind(KIntIdOstMatchGeneral);
   145 		}
   146 	}
   147 
   148 TBMTicks DBMMcotChannel::TimerPeriod()
   149 	{
   150 	return KBMMcotPeriod;
   151 	}
   152 
   153 // Read OST and return tick count
   154 TBMTicks DBMMcotChannel::TimerStamp()
   155 	{
   156 	return TUint(TCotulla::OstData());
   157 	}
   158 
   159 TBMNs DBMMcotChannel::TimerTicksToNs(TBMTicks ticks)
   160 	{
   161 	return ticks * KBMMcotNsPerTick;
   162 	}
   163 
   164 TBMTicks DBMMcotChannel::TimerNsToTicks(TBMNs ns)
   165 	{
   166 	return ns / KBMMcotNsPerTick;
   167 	}
   168 
   169 // Actual ISR called when benchmark timer fires
   170 void DBMMcotChannel::Isr(TAny* ptr)
   171 	{
   172 	DBMMcotChannel* mCh = (DBMMcotChannel*) ptr;
   173 	BM_ASSERT(mCh->iIsr || mCh->iInterruptLatencyIsr);
   174 	if (mCh->iIsr)
   175 		{
   176 		// Call the handler with the current OST time
   177 		mCh->iIsr->Isr(TUint(TCotulla::OstData()));
   178 		}
   179 	else
   180 		{
   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));
   184 		}
   185 	TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
   186 	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
   187 	}
   188 
   189 
   190 // Bind the OST match interrupt to a FIQ ISR - it will interrupt running IRQ service
   191 // routines. 
   192 TInt DBMMcotChannel::BindInterrupt()
   193 	{
   194 	TInt r = Interrupt::Bind(KIntIdOstMatchGeneral, Isr, this);
   195 	if (r != KErrNone)
   196 		{
   197 		return r;
   198 		}
   199 	TCotulla::ModifyIntLevels(0, KHtIntsOstMatchGeneral);	// route new timer interrupt to FIQ
   200 	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
   201 	Interrupt::Enable(KIntIdOstMatchGeneral);
   202 	return KErrNone;
   203 	}
   204 
   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)
   208 	{
   209 	BM_ASSERT(!iIsr);
   210 	BM_ASSERT(!iInterruptLatencyIsr);
   211 	iIsr = aIsr;
   212 	return BindInterrupt();
   213 	}
   214 
   215 TInt DBMMcotChannel::BindInterrupt(MBMInterruptLatencyIsr* aIsr)
   216 	{
   217 	BM_ASSERT(!iIsr);
   218 	BM_ASSERT(!iInterruptLatencyIsr);
   219 	iInterruptLatencyIsr = aIsr;
   220 	return BindInterrupt();
   221 	}
   222 
   223 // Called by client to request an interrupt (ISR/latency ISR) invocation in ~1mS.
   224 void DBMMcotChannel::RequestInterrupt()
   225 	{
   226 	BM_ASSERT(iIsr || iInterruptLatencyIsr);
   227 	TCotulla::SetOstMatch(TCotulla::OstData()+KBMMcotInterruptDelayTicks,KHwOstMatchGeneral);
   228 	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
   229 	TCotulla::EnableOstInterrupt(KHwOstMatchGeneral);
   230 	}
   231 
   232 // Called to cancel if client dies/killed after ISR scheduled ???
   233 void DBMMcotChannel::CancelInterrupt()
   234 	{	
   235 	if (iIsr || iInterruptLatencyIsr)
   236 		{
   237 		TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
   238 		TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
   239 		}
   240 	}
   241