os/kernelhwsrv/kernel/eka/nkern/arm/ncutils.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) 1994-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
// e32\nkern\arm\ncutils.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <arm.h>
sl@0
    19
#include "../../include/kernel/kernboot.h"
sl@0
    20
sl@0
    21
extern "C" {
sl@0
    22
SFullArmRegSet ArmRegs;
sl@0
    23
}
sl@0
    24
sl@0
    25
#ifdef _DEBUG
sl@0
    26
void FastMutexNestAttempt()
sl@0
    27
	{
sl@0
    28
	FAULT();
sl@0
    29
	}
sl@0
    30
sl@0
    31
void FastMutexSignalError()
sl@0
    32
	{
sl@0
    33
	FAULT();
sl@0
    34
	}
sl@0
    35
#endif
sl@0
    36
sl@0
    37
void NKern::Init0(TAny*)
sl@0
    38
	{
sl@0
    39
	ArmRegs.iExcCode = -1;
sl@0
    40
	TheScheduler.i_Regs = &ArmRegs;
sl@0
    41
	}
sl@0
    42
sl@0
    43
GLDEF_C TUint32 IrqReturnAddress()
sl@0
    44
	{
sl@0
    45
	TStackInfo& stackInfo =  ((SSuperPageBase*)::SuperPageAddress)->iStackInfo;
sl@0
    46
	return ((TUint32)stackInfo.iIrqStackBase) + stackInfo.iIrqStackSize  - sizeof(TUint32);
sl@0
    47
	}
sl@0
    48
sl@0
    49
/** Register the global IRQ handler
sl@0
    50
	Called by the base port at boot time to bind the top level IRQ dispatcher
sl@0
    51
	to the ARM IRQ vector. Should not be called at any other time.
sl@0
    52
sl@0
    53
	The handler specified will be called in mode_irq with IRQs disabled and
sl@0
    54
	FIQs enabled. R0-R3, R12 and the return address from the interrupt will
sl@0
    55
	be on the top of the mode_irq stack. R14_irq will point to the kernel's
sl@0
    56
	IRQ postamble routine, which will run IDFCs and reschedule if necessary.
sl@0
    57
	R13_irq will point to the top of the mode_irq stack and will be 8-byte aligned.
sl@0
    58
	The handler should preserve all registers other than R0-R3, R12, R14_irq
sl@0
    59
	and should return to the address in R14_irq.
sl@0
    60
sl@0
    61
	@param	aHandler The address of the top level IRQ dispatcher routine
sl@0
    62
 */
sl@0
    63
EXPORT_C void Arm::SetIrqHandler(TLinAddr aHandler)
sl@0
    64
	{
sl@0
    65
	ArmInterruptInfo.iIrqHandler=aHandler;
sl@0
    66
	}
sl@0
    67
sl@0
    68
/** Register the global FIQ handler
sl@0
    69
	Called by the base port at boot time to bind the top level FIQ dispatcher
sl@0
    70
	to the ARM FIQ vector. Should not be called at any other time.
sl@0
    71
sl@0
    72
	The handler specified will be called in mode_fiq with both IRQs and FIQs
sl@0
    73
	disabled. The return address from the interrupt will be on the top of the
sl@0
    74
	mode_fiq stack. R14_fiq will point to the kernel's FIQ postamble routine,
sl@0
    75
	which will run IDFCs and reschedule if necessary.
sl@0
    76
	R13_fiq will point to the top of the mode_fiq stack and will be 4 modulo 8.
sl@0
    77
	The handler should preserve all registers other than R8_fiq-R12_fiq and
sl@0
    78
	R14_fiq	and should return to the address in R14_fiq.
sl@0
    79
sl@0
    80
	@param	aHandler The address of the top level FIQ dispatcher routine
sl@0
    81
 */
sl@0
    82
EXPORT_C void Arm::SetFiqHandler(TLinAddr aHandler)
sl@0
    83
	{
sl@0
    84
	ArmInterruptInfo.iFiqHandler=aHandler;
sl@0
    85
	}
sl@0
    86
sl@0
    87
extern void initialiseState();
sl@0
    88
void Arm::Init1Interrupts()
sl@0
    89
//
sl@0
    90
// Initialise the interrupt and exception vector handlers.
sl@0
    91
//
sl@0
    92
	{
sl@0
    93
//	TheIrqHandler=0;	// done by placing TheIrqHandler, TheFiqHandler in .bss
sl@0
    94
//	TheFiqHandler=0;
sl@0
    95
	
sl@0
    96
	initialiseState();
sl@0
    97
	}
sl@0
    98
sl@0
    99
extern "C" void __ArmVectorReset()
sl@0
   100
//
sl@0
   101
// Reset
sl@0
   102
//
sl@0
   103
	{
sl@0
   104
sl@0
   105
	FAULT();
sl@0
   106
	}
sl@0
   107
sl@0
   108
extern "C" void __ArmVectorReserved()
sl@0
   109
//
sl@0
   110
// Reserved
sl@0
   111
//
sl@0
   112
	{
sl@0
   113
sl@0
   114
	FAULT();
sl@0
   115
	}
sl@0
   116
sl@0
   117
sl@0
   118
TInt BTraceDefaultControl(BTrace::TControl /*aFunction*/, TAny* /*aArg1*/, TAny* /*aArg2*/)
sl@0
   119
	{
sl@0
   120
	return KErrNotSupported;
sl@0
   121
	}
sl@0
   122
sl@0
   123
sl@0
   124
EXPORT_C void BTrace::SetHandlers(BTrace::THandler aNewHandler, BTrace::TControlFunction aNewControl, BTrace::THandler& aOldHandler, BTrace::TControlFunction& aOldControl)
sl@0
   125
	{
sl@0
   126
	TUint irq = NKern::DisableAllInterrupts();
sl@0
   127
	
sl@0
   128
	aOldHandler = BTraceData.iHandler;
sl@0
   129
	BTraceData.iHandler = aNewHandler;
sl@0
   130
	ArmInterruptInfo.iBTraceHandler = aNewHandler;
sl@0
   131
	TheScheduler.iBTraceHandler = aNewHandler;
sl@0
   132
	
sl@0
   133
	aOldControl = BTraceData.iControl;
sl@0
   134
	BTraceData.iControl = aNewControl ? aNewControl : BTraceDefaultControl;
sl@0
   135
	
sl@0
   136
	NKern::RestoreInterrupts(irq);
sl@0
   137
	}
sl@0
   138
sl@0
   139
sl@0
   140
EXPORT_C TInt BTrace::SetFilter(TUint aCategory, TInt aValue)
sl@0
   141
	{
sl@0
   142
	if(!IsSupported(aCategory))
sl@0
   143
		return KErrNotSupported;
sl@0
   144
	TUint irq = NKern::DisableAllInterrupts();
sl@0
   145
	TUint8* filter = BTraceData.iFilter+aCategory;
sl@0
   146
	TUint oldValue = *filter;
sl@0
   147
	if(TUint(aValue)<=1u)
sl@0
   148
		{
sl@0
   149
		*filter = (TUint8)aValue;
sl@0
   150
		BTraceContext4(BTrace::EMetaTrace, BTrace::EMetaTraceFilterChange, (TUint8)aCategory | (aValue<<8));
sl@0
   151
		if(aCategory==ECpuUsage)
sl@0
   152
			{
sl@0
   153
			ArmInterruptInfo.iCpuUsageFilter = aValue;
sl@0
   154
			TheScheduler.iCpuUsageFilter = aValue;
sl@0
   155
			}
sl@0
   156
		if (aCategory == EFastMutex)
sl@0
   157
			{
sl@0
   158
			// This is done because of the optimization in ncsched.cia for
sl@0
   159
			// ARMv5 (check if lock is free (cmp) && filter is enabled (cmpeq))
sl@0
   160
			TheScheduler.iFastMutexFilter = aValue ? 1 : 0;
sl@0
   161
			}
sl@0
   162
		}
sl@0
   163
	NKern::RestoreInterrupts(irq);
sl@0
   164
	return oldValue;
sl@0
   165
	}
sl@0
   166
sl@0
   167
EXPORT_C SCpuIdleHandler* NKern::CpuIdleHandler()
sl@0
   168
	{
sl@0
   169
	return &ArmInterruptInfo.iCpuIdleHandler;
sl@0
   170
	}
sl@0
   171
sl@0
   172
EXPORT_C TUint32 NKern::CpuTimeMeasFreq()
sl@0
   173
	{
sl@0
   174
#ifdef MONITOR_THREAD_CPU_TIME
sl@0
   175
	return NKern::FastCounterFrequency();
sl@0
   176
#else
sl@0
   177
	return 0;
sl@0
   178
#endif
sl@0
   179
	}