kerneltest/e32test/power/d_frqchg.cpp
author hgs
Wed, 23 Jun 2010 12:58:21 +0100
changeset 177 a232af6b0b1f
permissions -rw-r--r--
201023_15
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
177
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
     1
// Copyright (c) 2010-2010 Nokia Corporation and/or its subsidiary(-ies).
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
     2
// All rights reserved.
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
     4
// under the terms of the License "Eclipse Public License v1.0"
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
     7
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
     8
// Initial Contributors:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    10
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    11
// Contributors:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    12
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    13
// Description:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    14
// e32test\power\d_frqchg.cpp
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    15
// LDD for testing frequency changing
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    16
// 
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    17
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    18
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    19
#include <kernel/kernel.h>
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    20
#include "d_frqchg.h"
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    21
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    22
#if defined(__EPOC32__) && defined(__SMP__) && defined(__MARM__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    23
#define __SUPPORT_LOCAL_TIMER_PRESCALE__
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    24
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    25
#include <nk_priv.h>
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    26
#include <arm_tmr.h>
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    27
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    28
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    29
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    30
#ifdef __PLATFORM_SUPPORTS_DVFS__
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    31
/**
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    32
  Baseport needs to supply this function to disable DVFS whilst test is running. 
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    33
  The test relies on changing prescalers in local and global timer directly rather than
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    34
  actually changing frequency. Consequently DVFS must be disabled when the test is running
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    35
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    36
  This function when driver is loaded. 
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    37
  @return KErrNone if succesful
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    38
 */
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    39
extern TInt DisableDvfs();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    40
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    41
/**
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    42
   if plaftorm supports DVFS this function will be called when the driver is unloaded
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    43
 */
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    44
extern void RestoreDvfs();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    45
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    46
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    47
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    48
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    49
#if defined(__SUPPORT_LOCAL_TIMER_PRESCALE__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    50
TInt Multiply(SRatio& aDest, const SRatio& aSrc)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    51
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    52
	TUint64 x = aDest.iM;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    53
	TUint64 y = aSrc.iM;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    54
	x *= y;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    55
	if (x==0)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    56
		{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    57
		aDest.iM = 0;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    58
		aDest.iX = 0;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    59
		return KErrNone;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    60
		}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    61
	TInt exp = aDest.iX + aSrc.iX + 32;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    62
	if (TInt64(x) >= 0)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    63
		x<<=1, --exp;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    64
	aDest.iM = I64HIGH(x);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    65
	if (I64LOW(x) & 0x80000000u)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    66
		{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    67
		if (++aDest.iM == 0)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    68
			aDest.iM = 0x80000000u, ++exp;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    69
		}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    70
	if (exp > 32767)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    71
		{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    72
		aDest.iM = 0xffffffffu;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    73
		aDest.iX = 32767;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    74
		return KErrOverflow;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    75
		}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    76
	if (exp < -32768)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    77
		{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    78
		aDest.iM = 0;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    79
		aDest.iX = 0;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    80
		return KErrUnderflow;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    81
		}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    82
	aDest.iX = (TInt16)exp;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    83
	return KErrNone;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    84
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    85
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    86
// Calculate frequency ratio for specified prescale value
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    87
// Ratio = (default+1)/(current+1)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    88
void PrescaleRatio(SRatio& aR, TInt aDefault, TInt aCurrent)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    89
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    90
	SRatio df;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    91
	df.Set(TUint32(aDefault+1));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    92
	aR.Set(TUint32(aCurrent+1));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    93
	aR.Reciprocal();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    94
	Multiply(aR, df);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    95
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    96
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    97
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    98
class DFrqChgFactory : public DLogicalDevice
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
    99
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   100
// Test LDD factory
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   101
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   102
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   103
public:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   104
	DFrqChgFactory();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   105
	virtual ~DFrqChgFactory();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   106
	virtual TInt Install(); 					//overriding pure virtual
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   107
	virtual void GetCaps(TDes8& aDes) const;	//overriding pure virtual
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   108
	virtual TInt Create(DLogicalChannelBase*& aChannel); 	//overriding pure virtual
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   109
	};
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   110
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   111
class DFrqChg : public DLogicalChannelBase
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   112
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   113
// Test logical channel
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   114
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   115
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   116
public:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   117
	virtual ~DFrqChg();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   118
protected:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   119
	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   120
	virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   121
#if defined(__SUPPORT_LOCAL_TIMER_PRESCALE__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   122
	void PopulateDefaultPrescaleList();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   123
	void SetLocalTimerPrescaler(TUint32 aCpus, TInt aPrescale);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   124
	TScheduler* iS;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   125
	TInt iDefaultPrescale[KMaxCpus];
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   126
#if defined(__CPU_ARM_HAS_GLOBAL_TIMER_BLOCK) && defined( __NKERN_TIMESTAMP_USE_SCU_GLOBAL_TIMER__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   127
	void SetGlobalTimerPrescaler(TInt aPrescale);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   128
	TInt iDefaultGTPrescale;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   129
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   130
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   131
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   132
	};
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   133
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   134
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   135
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   136
DECLARE_STANDARD_LDD()
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   137
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   138
	return new DFrqChgFactory;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   139
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   140
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   141
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   142
// Constructor
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   143
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   144
DFrqChgFactory::DFrqChgFactory()
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   145
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   146
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   147
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   148
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   149
// Destructor, called on unload
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   150
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   151
DFrqChgFactory::~DFrqChgFactory()
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   152
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   153
#ifdef __PLATFORM_SUPPORTS_DVFS__
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   154
	RestoreDvfs();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   155
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   156
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   157
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   158
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   159
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   160
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   161
// Create new channel
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   162
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   163
TInt DFrqChgFactory::Create(DLogicalChannelBase*& aChannel)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   164
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   165
	aChannel=new DFrqChg;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   166
	return aChannel?KErrNone:KErrNoMemory;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   167
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   168
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   169
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   170
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   171
// Install the LDD - overriding pure virtual
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   172
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   173
TInt DFrqChgFactory::Install()
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   174
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   175
#ifdef __PLATFORM_SUPPORTS_DVFS__
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   176
	TInt r = DisableDvfs();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   177
	if (KErrNone != r) return r;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   178
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   179
	return SetName(&KLddName);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   180
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   181
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   182
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   183
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   184
// Get capabilities - overriding pure virtual
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   185
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   186
void DFrqChgFactory::GetCaps(TDes8& /*aDes*/) const
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   187
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   188
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   189
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   190
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   191
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   192
// Create channel
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   193
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   194
TInt DFrqChg::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   195
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   196
#if defined(__SUPPORT_LOCAL_TIMER_PRESCALE__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   197
	iS = (TScheduler*)TScheduler::Ptr();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   198
	PopulateDefaultPrescaleList();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   199
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   200
	return KErrNone;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   201
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   202
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   203
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   204
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   205
// Destructor
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   206
//
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   207
DFrqChg::~DFrqChg()
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   208
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   209
#if defined(__SUPPORT_LOCAL_TIMER_PRESCALE__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   210
	// restore prescalers
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   211
	SetLocalTimerPrescaler((TUint32) -1, -1);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   212
#if defined(__CPU_ARM_HAS_GLOBAL_TIMER_BLOCK) && defined( __NKERN_TIMESTAMP_USE_SCU_GLOBAL_TIMER__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   213
	SetGlobalTimerPrescaler(-1);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   214
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   215
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   216
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   217
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   218
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   219
TInt DFrqChg::Request(TInt aReqNo, TAny* a1, TAny* a2)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   220
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   221
	SRatioInv ri;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   222
	TInt r = KErrNone;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   223
	switch (aReqNo)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   224
		{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   225
		case RFrqChg::EControl_RatioSet:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   226
			{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   227
			kumemget32(&ri.iR, a1, sizeof(SRatio));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   228
			ri.iR.Set(ri.iR.iM, (TUint32)a2);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   229
			kumemput32(a1, &ri.iR, sizeof(SRatio));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   230
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   231
			}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   232
		case RFrqChg::EControl_RatioReciprocal:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   233
			{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   234
			kumemget32(&ri.iR, a1, sizeof(SRatio));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   235
			r = ri.iR.Reciprocal();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   236
			kumemput32(a1, &ri.iR, sizeof(SRatio));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   237
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   238
			}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   239
		case RFrqChg::EControl_RatioMult:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   240
			{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   241
			kumemget32(&ri.iR, a1, sizeof(SRatio));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   242
			kumemget32(&ri.iI.iM, a2, sizeof(TUint32));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   243
			r = ri.iR.Mult(ri.iI.iM);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   244
			kumemput32(a2, &ri.iI.iM, sizeof(TUint32));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   245
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   246
			}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   247
		case RFrqChg::EControl_RatioInvSet:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   248
			{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   249
			SRatio ratio;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   250
			const SRatio* p = 0;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   251
			if (a2)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   252
				{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   253
				kumemget32(&ratio, a2, sizeof(SRatio));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   254
				p = &ratio;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   255
				}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   256
			ri.Set(p);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   257
			kumemput32(a1, &ri, sizeof(SRatioInv));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   258
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   259
			}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   260
#if defined(__EPOC32__) && defined(__SMP__) && defined(__MARM__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   261
		case RFrqChg::EControl_FrqChgTestPresent:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   262
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   263
		case RFrqChg::EControl_SetCurrentThreadPriority:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   264
			NKern::ThreadSetPriority(NKern::CurrentThread(), (TInt)a1);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   265
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   266
		case RFrqChg::EControl_SetCurrentThreadCpu:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   267
			{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   268
			TUint32 old = 0;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   269
			old =  NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), (TUint32)a1);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   270
			if (a2) 
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   271
				{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   272
				kumemput32(a2, &old, sizeof(TUint32));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   273
				}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   274
			
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   275
			old =  NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), (TUint32)a1);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   276
			}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   277
			
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   278
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   279
		case RFrqChg::EControl_SetCurrentThreadTimeslice:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   280
			{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   281
			TInt ts = NKern::TimesliceTicks((TUint32)a1);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   282
			NKern::ThreadSetTimeslice(NKern::CurrentThread(), ts);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   283
			NKern::YieldTimeslice();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   284
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   285
			}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   286
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   287
#if defined(__SUPPORT_LOCAL_TIMER_PRESCALE__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   288
		case RFrqChg::EControl_SetLocalTimerPrescaler:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   289
			{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   290
			TUint32 cpus = (TUint32)a1;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   291
			TInt prescale = (TInt)a2;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   292
			SetLocalTimerPrescaler(cpus, prescale);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   293
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   294
			}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   295
#if defined(__CPU_ARM_HAS_GLOBAL_TIMER_BLOCK) && defined( __NKERN_TIMESTAMP_USE_SCU_GLOBAL_TIMER__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   296
	case RFrqChg::EControl_ReadGlobalTimerAndTimestamp:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   297
		    {
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   298
			ArmGlobalTimer* tmr = iS->iSX.iGlobalTimerAddr;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   299
			TUint32 highlow[2];
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   300
			do
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   301
				{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   302
				highlow[1] = tmr->iTimerCountHigh;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   303
				highlow[0] = tmr->iTimerCountLow;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   304
				} while(highlow[1]!=tmr->iTimerCountHigh);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   305
			TUint64 ts = NKern::Timestamp();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   306
			kumemput32(a1,&highlow[0],sizeof(TUint64));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   307
			kumemput32(a2,&ts,sizeof(TUint64));
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   308
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   309
		 }
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   310
	case RFrqChg::EControl_SetGlobalTimerPrescaler:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   311
		    {
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   312
			SetGlobalTimerPrescaler((TInt)a1);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   313
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   314
		 }
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   315
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   316
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   317
		default:
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   318
			r = KErrNotSupported;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   319
			break;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   320
		}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   321
	return r;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   322
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   323
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   324
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   325
#if defined(__SUPPORT_LOCAL_TIMER_PRESCALE__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   326
void DFrqChg::PopulateDefaultPrescaleList()
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   327
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   328
	TInt nc = NKern::NumberOfCpus();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   329
	NThread* nt = NKern::CurrentThread();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   330
	TUint32 aff0 = NKern::ThreadSetCpuAffinity(nt, 0);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   331
	TInt i;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   332
	for (i=0; i<nc; ++i)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   333
		{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   334
		NKern::ThreadSetCpuAffinity(nt, i);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   335
		ArmLocalTimer* tmr = (ArmLocalTimer*)iS->iSX.iLocalTimerAddr;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   336
		TInt pv = (tmr->iTimerCtrl & E_ArmTmrCtrl_PrescaleMask) >> E_ArmTmrCtrl_PrescaleShift;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   337
		iDefaultPrescale[i] = pv;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   338
		}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   339
	NKern::ThreadSetCpuAffinity(nt, aff0);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   340
#if defined(__CPU_ARM_HAS_GLOBAL_TIMER_BLOCK) && defined( __NKERN_TIMESTAMP_USE_SCU_GLOBAL_TIMER__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   341
	ArmGlobalTimer* tmr = iS->iSX.iGlobalTimerAddr;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   342
	TInt pv = (tmr->iTimerCtrl & E_ArmGTmrCtrl_PrescaleMask) >> E_ArmGTmrCtrl_PrescaleShift;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   343
	iDefaultGTPrescale = pv;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   344
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   345
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   346
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   347
void DFrqChg::SetLocalTimerPrescaler(TUint32 aCpus, TInt aPrescale)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   348
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   349
	TInt nc = NKern::NumberOfCpus();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   350
	NThread* nt = NKern::CurrentThread();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   351
	TUint32 aff0 = NKern::ThreadSetCpuAffinity(nt, 0);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   352
	TInt i;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   353
	for (i=0; i<nc; ++i)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   354
		{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   355
		NKern::ThreadSetCpuAffinity(nt, i);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   356
		}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   357
	for (i=0; i<nc; ++i)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   358
		{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   359
		NKern::ThreadSetCpuAffinity(nt, i);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   360
		TInt pv = aPrescale;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   361
		if (pv < 0)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   362
			pv = iDefaultPrescale[i];
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   363
		if (aCpus & (1u<<i))
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   364
			{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   365
			TInt irq = NKern::DisableAllInterrupts();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   366
			ArmLocalTimer* tmr = (ArmLocalTimer*)iS->iSX.iLocalTimerAddr;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   367
			tmr->iTimerCtrl = (tmr->iTimerCtrl &~ E_ArmTmrCtrl_PrescaleMask) | ((pv << E_ArmTmrCtrl_PrescaleShift) & E_ArmTmrCtrl_PrescaleMask);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   368
			__e32_io_completion_barrier();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   369
			NKern::RestoreInterrupts(irq);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   370
			}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   371
		}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   372
	NKern::ThreadSetCpuAffinity(nt, aff0);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   373
	if (aCpus & 0x80000000u)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   374
		{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   375
		// notify nanokernel of frequency changes
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   376
		SVariantInterfaceBlock* vib = iS->iVIB;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   377
		SRatio ratio[KMaxCpus];
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   378
		for (i=0; i<nc; ++i)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   379
			{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   380
			if (aCpus & (1u<<i))
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   381
				{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   382
				if (aPrescale<0)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   383
					ratio[i].Set(1);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   384
				else
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   385
					PrescaleRatio(ratio[i], iDefaultPrescale[i], aPrescale);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   386
				vib->iTimerFreqR[i] = &ratio[i];
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   387
				}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   388
			}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   389
		(*vib->iFrqChgFn)();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   390
		}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   391
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   392
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   393
#if defined(__CPU_ARM_HAS_GLOBAL_TIMER_BLOCK) && defined( __NKERN_TIMESTAMP_USE_SCU_GLOBAL_TIMER__)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   394
void DFrqChg::SetGlobalTimerPrescaler(TInt aPrescale)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   395
	{
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   396
	TInt pv = aPrescale;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   397
	if (pv <= 0)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   398
		pv = iDefaultGTPrescale;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   399
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   400
	ArmGlobalTimer* tmr = iS->iSX.iGlobalTimerAddr;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   401
	// TInt irq = NKern::DisableAllInterrupts(); 
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   402
	tmr->iTimerCtrl = (tmr->iTimerCtrl &~ E_ArmGTmrCtrl_PrescaleMask) | ((pv << E_ArmGTmrCtrl_PrescaleShift) & E_ArmGTmrCtrl_PrescaleMask);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   403
	__e32_io_completion_barrier();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   404
	// NKern::RestoreInterrupts(irq);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   405
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   406
	// notify nanokernel of frequency changes
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   407
	SVariantInterfaceBlock* vib = iS->iVIB;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   408
	SRatio ratio;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   409
	
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   410
	if (aPrescale<=0)
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   411
		ratio.Set(1);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   412
	else
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   413
		PrescaleRatio(ratio, iDefaultGTPrescale, aPrescale);
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   414
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   415
	vib->iGTimerFreqR = &ratio;
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   416
	(*vib->iFrqChgFn)();
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   417
	}
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   418
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   419
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   420
#endif
a232af6b0b1f 201023_15
hgs
parents:
diff changeset
   421