os/kernelhwsrv/kerneltest/e32test/benchmark/bm_mcot_pdd.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// \e32test\benchmark\bm_mcot_pdd.cpp
sl@0
    15
// PDD to provide OS timer services to benchmark programs
sl@0
    16
// 
sl@0
    17
//
sl@0
    18
sl@0
    19
#include <kernel/kernel.h>
sl@0
    20
#include <cotulla.h>
sl@0
    21
sl@0
    22
sl@0
    23
#include "k32bm.h"
sl@0
    24
sl@0
    25
class DBMMcotDevice : public DPhysicalDevice
sl@0
    26
	{
sl@0
    27
public:
sl@0
    28
	DBMMcotDevice();
sl@0
    29
	virtual TInt Install();
sl@0
    30
	virtual void GetCaps(TDes8& aDes) const;
sl@0
    31
	virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
sl@0
    32
	virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
sl@0
    33
	};
sl@0
    34
sl@0
    35
class DBMMcotChannel : public DBMPChannel
sl@0
    36
	{
sl@0
    37
public:
sl@0
    38
	DBMMcotChannel();
sl@0
    39
	~DBMMcotChannel();
sl@0
    40
sl@0
    41
	// Report timing spec
sl@0
    42
	virtual TBMTicks TimerPeriod();
sl@0
    43
	// Get current OST tick time
sl@0
    44
	virtual TBMTicks TimerStamp();
sl@0
    45
	// Tick/nS conversions
sl@0
    46
	virtual TBMNs TimerTicksToNs(TBMTicks);
sl@0
    47
	virtual TBMTicks TimerNsToTicks(TBMNs);
sl@0
    48
	// Pass in client ISRs to invoke 
sl@0
    49
	virtual TInt BindInterrupt(MBMIsr*);
sl@0
    50
	virtual TInt BindInterrupt(MBMInterruptLatencyIsr*);
sl@0
    51
	// Invoke an ISR 
sl@0
    52
	virtual void RequestInterrupt();
sl@0
    53
	virtual void CancelInterrupt();
sl@0
    54
sl@0
    55
private:
sl@0
    56
sl@0
    57
	// Attach to OST interrupt
sl@0
    58
	TInt BindInterrupt();
sl@0
    59
sl@0
    60
	static const TInt		KBMMcotInterruptDelayTicks = KHwOscFreqHz / 1000;	// ie. delay ~ 1 ms timer tick!
sl@0
    61
	static const TBMTicks	KBMMcotPeriod = (((TBMTicks) 1) << 32);
sl@0
    62
	static const TBMNs		KBMMcotNsPerTick = (1000*1000*1000) / KHwOscFreqHz;
sl@0
    63
	
sl@0
    64
	// Real ISR (calls out to client)
sl@0
    65
	static void Isr(TAny*);
sl@0
    66
	
sl@0
    67
	MBMIsr*						iIsr;
sl@0
    68
	MBMInterruptLatencyIsr*		iInterruptLatencyIsr;
sl@0
    69
	};
sl@0
    70
sl@0
    71
// Standard boiler plate PDD factory object 
sl@0
    72
sl@0
    73
DECLARE_STANDARD_PDD()
sl@0
    74
//
sl@0
    75
// Create a new device
sl@0
    76
//
sl@0
    77
	{
sl@0
    78
	__ASSERT_CRITICAL;
sl@0
    79
	return new DBMMcotDevice;
sl@0
    80
	}
sl@0
    81
sl@0
    82
DBMMcotDevice::DBMMcotDevice()
sl@0
    83
//
sl@0
    84
// Constructor
sl@0
    85
//
sl@0
    86
	{
sl@0
    87
	//iUnitsMask=0;
sl@0
    88
	iVersion = TVersion(1,0,1);
sl@0
    89
	}
sl@0
    90
sl@0
    91
TInt DBMMcotDevice::Install()
sl@0
    92
//
sl@0
    93
// Install the device driver.
sl@0
    94
//
sl@0
    95
	{
sl@0
    96
	TInt r = SetName(&KBMPdName);
sl@0
    97
	return r;
sl@0
    98
	}
sl@0
    99
sl@0
   100
void DBMMcotDevice::GetCaps(TDes8& aDes) const
sl@0
   101
//
sl@0
   102
// Return the Comm capabilities.
sl@0
   103
//
sl@0
   104
	{
sl@0
   105
	}
sl@0
   106
sl@0
   107
TInt DBMMcotDevice::Create(DBase*& aChannel, TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
sl@0
   108
//
sl@0
   109
// Create a channel on the device.
sl@0
   110
//
sl@0
   111
	{
sl@0
   112
	__ASSERT_CRITICAL;
sl@0
   113
	aChannel = new DBMMcotChannel;
sl@0
   114
	return aChannel?KErrNone:KErrNoMemory;
sl@0
   115
	}
sl@0
   116
sl@0
   117
TInt DBMMcotDevice::Validate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
sl@0
   118
	{
sl@0
   119
	if (!Kern::QueryVersionSupported(iVersion,aVer))
sl@0
   120
		{
sl@0
   121
		return KErrNotSupported;
sl@0
   122
		}
sl@0
   123
	return KErrNone;
sl@0
   124
	}
sl@0
   125
sl@0
   126
// Actual device channel functions, called by LDD
sl@0
   127
sl@0
   128
// Clear saved ISR members
sl@0
   129
DBMMcotChannel::DBMMcotChannel()
sl@0
   130
	{
sl@0
   131
	//	iIsr = NULL;
sl@0
   132
	//	iInterruptLatencyIsr = NULL;
sl@0
   133
	}
sl@0
   134
sl@0
   135
// If we ever initialised the timers to generate ISRs, clear 
sl@0
   136
DBMMcotChannel::~DBMMcotChannel()
sl@0
   137
	{
sl@0
   138
	if (iIsr || iInterruptLatencyIsr)
sl@0
   139
		{
sl@0
   140
		TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
sl@0
   141
		TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   142
		Interrupt::Disable(KIntIdOstMatchGeneral);
sl@0
   143
		TCotulla::ModifyIntLevels(KHtIntsOstMatchGeneral,0);
sl@0
   144
		Interrupt::Unbind(KIntIdOstMatchGeneral);
sl@0
   145
		}
sl@0
   146
	}
sl@0
   147
sl@0
   148
TBMTicks DBMMcotChannel::TimerPeriod()
sl@0
   149
	{
sl@0
   150
	return KBMMcotPeriod;
sl@0
   151
	}
sl@0
   152
sl@0
   153
// Read OST and return tick count
sl@0
   154
TBMTicks DBMMcotChannel::TimerStamp()
sl@0
   155
	{
sl@0
   156
	return TUint(TCotulla::OstData());
sl@0
   157
	}
sl@0
   158
sl@0
   159
TBMNs DBMMcotChannel::TimerTicksToNs(TBMTicks ticks)
sl@0
   160
	{
sl@0
   161
	return ticks * KBMMcotNsPerTick;
sl@0
   162
	}
sl@0
   163
sl@0
   164
TBMTicks DBMMcotChannel::TimerNsToTicks(TBMNs ns)
sl@0
   165
	{
sl@0
   166
	return ns / KBMMcotNsPerTick;
sl@0
   167
	}
sl@0
   168
sl@0
   169
// Actual ISR called when benchmark timer fires
sl@0
   170
void DBMMcotChannel::Isr(TAny* ptr)
sl@0
   171
	{
sl@0
   172
	DBMMcotChannel* mCh = (DBMMcotChannel*) ptr;
sl@0
   173
	BM_ASSERT(mCh->iIsr || mCh->iInterruptLatencyIsr);
sl@0
   174
	if (mCh->iIsr)
sl@0
   175
		{
sl@0
   176
		// Call the handler with the current OST time
sl@0
   177
		mCh->iIsr->Isr(TUint(TCotulla::OstData()));
sl@0
   178
		}
sl@0
   179
	else
sl@0
   180
		{
sl@0
   181
		// Call the handler with the difference between NOW and the time the match timer was set for
sl@0
   182
		// ie. the latency between the timer interrupt set and when it was called.
sl@0
   183
		mCh->iInterruptLatencyIsr->InterruptLatencyIsr(TCotulla::OstData() - TCotulla::OstMatch(KHwOstMatchGeneral));
sl@0
   184
		}
sl@0
   185
	TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
sl@0
   186
	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   187
	}
sl@0
   188
sl@0
   189
sl@0
   190
// Bind the OST match interrupt to a FIQ ISR - it will interrupt running IRQ service
sl@0
   191
// routines. 
sl@0
   192
TInt DBMMcotChannel::BindInterrupt()
sl@0
   193
	{
sl@0
   194
	TInt r = Interrupt::Bind(KIntIdOstMatchGeneral, Isr, this);
sl@0
   195
	if (r != KErrNone)
sl@0
   196
		{
sl@0
   197
		return r;
sl@0
   198
		}
sl@0
   199
	TCotulla::ModifyIntLevels(0, KHtIntsOstMatchGeneral);	// route new timer interrupt to FIQ
sl@0
   200
	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   201
	Interrupt::Enable(KIntIdOstMatchGeneral);
sl@0
   202
	return KErrNone;
sl@0
   203
	}
sl@0
   204
sl@0
   205
// NB! Only one of these is ever used per channel opening, ie. the 
sl@0
   206
// channel must be closed and re-opened between installing client ISR
sl@0
   207
TInt DBMMcotChannel::BindInterrupt(MBMIsr* aIsr)
sl@0
   208
	{
sl@0
   209
	BM_ASSERT(!iIsr);
sl@0
   210
	BM_ASSERT(!iInterruptLatencyIsr);
sl@0
   211
	iIsr = aIsr;
sl@0
   212
	return BindInterrupt();
sl@0
   213
	}
sl@0
   214
sl@0
   215
TInt DBMMcotChannel::BindInterrupt(MBMInterruptLatencyIsr* aIsr)
sl@0
   216
	{
sl@0
   217
	BM_ASSERT(!iIsr);
sl@0
   218
	BM_ASSERT(!iInterruptLatencyIsr);
sl@0
   219
	iInterruptLatencyIsr = aIsr;
sl@0
   220
	return BindInterrupt();
sl@0
   221
	}
sl@0
   222
sl@0
   223
// Called by client to request an interrupt (ISR/latency ISR) invocation in ~1mS.
sl@0
   224
void DBMMcotChannel::RequestInterrupt()
sl@0
   225
	{
sl@0
   226
	BM_ASSERT(iIsr || iInterruptLatencyIsr);
sl@0
   227
	TCotulla::SetOstMatch(TCotulla::OstData()+KBMMcotInterruptDelayTicks,KHwOstMatchGeneral);
sl@0
   228
	TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   229
	TCotulla::EnableOstInterrupt(KHwOstMatchGeneral);
sl@0
   230
	}
sl@0
   231
sl@0
   232
// Called to cancel if client dies/killed after ISR scheduled ???
sl@0
   233
void DBMMcotChannel::CancelInterrupt()
sl@0
   234
	{	
sl@0
   235
	if (iIsr || iInterruptLatencyIsr)
sl@0
   236
		{
sl@0
   237
		TCotulla::DisableOstInterrupt(KHwOstMatchGeneral);
sl@0
   238
		TCotulla::SetOstMatchEOI(KHwOstMatchGeneral);
sl@0
   239
		}
sl@0
   240
	}
sl@0
   241