1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/nkern/arm/ncutils.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,179 @@
1.4 +// Copyright (c) 1994-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 +// e32\nkern\arm\ncutils.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include <arm.h>
1.22 +#include "../../include/kernel/kernboot.h"
1.23 +
1.24 +extern "C" {
1.25 +SFullArmRegSet ArmRegs;
1.26 +}
1.27 +
1.28 +#ifdef _DEBUG
1.29 +void FastMutexNestAttempt()
1.30 + {
1.31 + FAULT();
1.32 + }
1.33 +
1.34 +void FastMutexSignalError()
1.35 + {
1.36 + FAULT();
1.37 + }
1.38 +#endif
1.39 +
1.40 +void NKern::Init0(TAny*)
1.41 + {
1.42 + ArmRegs.iExcCode = -1;
1.43 + TheScheduler.i_Regs = &ArmRegs;
1.44 + }
1.45 +
1.46 +GLDEF_C TUint32 IrqReturnAddress()
1.47 + {
1.48 + TStackInfo& stackInfo = ((SSuperPageBase*)::SuperPageAddress)->iStackInfo;
1.49 + return ((TUint32)stackInfo.iIrqStackBase) + stackInfo.iIrqStackSize - sizeof(TUint32);
1.50 + }
1.51 +
1.52 +/** Register the global IRQ handler
1.53 + Called by the base port at boot time to bind the top level IRQ dispatcher
1.54 + to the ARM IRQ vector. Should not be called at any other time.
1.55 +
1.56 + The handler specified will be called in mode_irq with IRQs disabled and
1.57 + FIQs enabled. R0-R3, R12 and the return address from the interrupt will
1.58 + be on the top of the mode_irq stack. R14_irq will point to the kernel's
1.59 + IRQ postamble routine, which will run IDFCs and reschedule if necessary.
1.60 + R13_irq will point to the top of the mode_irq stack and will be 8-byte aligned.
1.61 + The handler should preserve all registers other than R0-R3, R12, R14_irq
1.62 + and should return to the address in R14_irq.
1.63 +
1.64 + @param aHandler The address of the top level IRQ dispatcher routine
1.65 + */
1.66 +EXPORT_C void Arm::SetIrqHandler(TLinAddr aHandler)
1.67 + {
1.68 + ArmInterruptInfo.iIrqHandler=aHandler;
1.69 + }
1.70 +
1.71 +/** Register the global FIQ handler
1.72 + Called by the base port at boot time to bind the top level FIQ dispatcher
1.73 + to the ARM FIQ vector. Should not be called at any other time.
1.74 +
1.75 + The handler specified will be called in mode_fiq with both IRQs and FIQs
1.76 + disabled. The return address from the interrupt will be on the top of the
1.77 + mode_fiq stack. R14_fiq will point to the kernel's FIQ postamble routine,
1.78 + which will run IDFCs and reschedule if necessary.
1.79 + R13_fiq will point to the top of the mode_fiq stack and will be 4 modulo 8.
1.80 + The handler should preserve all registers other than R8_fiq-R12_fiq and
1.81 + R14_fiq and should return to the address in R14_fiq.
1.82 +
1.83 + @param aHandler The address of the top level FIQ dispatcher routine
1.84 + */
1.85 +EXPORT_C void Arm::SetFiqHandler(TLinAddr aHandler)
1.86 + {
1.87 + ArmInterruptInfo.iFiqHandler=aHandler;
1.88 + }
1.89 +
1.90 +extern void initialiseState();
1.91 +void Arm::Init1Interrupts()
1.92 +//
1.93 +// Initialise the interrupt and exception vector handlers.
1.94 +//
1.95 + {
1.96 +// TheIrqHandler=0; // done by placing TheIrqHandler, TheFiqHandler in .bss
1.97 +// TheFiqHandler=0;
1.98 +
1.99 + initialiseState();
1.100 + }
1.101 +
1.102 +extern "C" void __ArmVectorReset()
1.103 +//
1.104 +// Reset
1.105 +//
1.106 + {
1.107 +
1.108 + FAULT();
1.109 + }
1.110 +
1.111 +extern "C" void __ArmVectorReserved()
1.112 +//
1.113 +// Reserved
1.114 +//
1.115 + {
1.116 +
1.117 + FAULT();
1.118 + }
1.119 +
1.120 +
1.121 +TInt BTraceDefaultControl(BTrace::TControl /*aFunction*/, TAny* /*aArg1*/, TAny* /*aArg2*/)
1.122 + {
1.123 + return KErrNotSupported;
1.124 + }
1.125 +
1.126 +
1.127 +EXPORT_C void BTrace::SetHandlers(BTrace::THandler aNewHandler, BTrace::TControlFunction aNewControl, BTrace::THandler& aOldHandler, BTrace::TControlFunction& aOldControl)
1.128 + {
1.129 + TUint irq = NKern::DisableAllInterrupts();
1.130 +
1.131 + aOldHandler = BTraceData.iHandler;
1.132 + BTraceData.iHandler = aNewHandler;
1.133 + ArmInterruptInfo.iBTraceHandler = aNewHandler;
1.134 + TheScheduler.iBTraceHandler = aNewHandler;
1.135 +
1.136 + aOldControl = BTraceData.iControl;
1.137 + BTraceData.iControl = aNewControl ? aNewControl : BTraceDefaultControl;
1.138 +
1.139 + NKern::RestoreInterrupts(irq);
1.140 + }
1.141 +
1.142 +
1.143 +EXPORT_C TInt BTrace::SetFilter(TUint aCategory, TInt aValue)
1.144 + {
1.145 + if(!IsSupported(aCategory))
1.146 + return KErrNotSupported;
1.147 + TUint irq = NKern::DisableAllInterrupts();
1.148 + TUint8* filter = BTraceData.iFilter+aCategory;
1.149 + TUint oldValue = *filter;
1.150 + if(TUint(aValue)<=1u)
1.151 + {
1.152 + *filter = (TUint8)aValue;
1.153 + BTraceContext4(BTrace::EMetaTrace, BTrace::EMetaTraceFilterChange, (TUint8)aCategory | (aValue<<8));
1.154 + if(aCategory==ECpuUsage)
1.155 + {
1.156 + ArmInterruptInfo.iCpuUsageFilter = aValue;
1.157 + TheScheduler.iCpuUsageFilter = aValue;
1.158 + }
1.159 + if (aCategory == EFastMutex)
1.160 + {
1.161 + // This is done because of the optimization in ncsched.cia for
1.162 + // ARMv5 (check if lock is free (cmp) && filter is enabled (cmpeq))
1.163 + TheScheduler.iFastMutexFilter = aValue ? 1 : 0;
1.164 + }
1.165 + }
1.166 + NKern::RestoreInterrupts(irq);
1.167 + return oldValue;
1.168 + }
1.169 +
1.170 +EXPORT_C SCpuIdleHandler* NKern::CpuIdleHandler()
1.171 + {
1.172 + return &ArmInterruptInfo.iCpuIdleHandler;
1.173 + }
1.174 +
1.175 +EXPORT_C TUint32 NKern::CpuTimeMeasFreq()
1.176 + {
1.177 +#ifdef MONITOR_THREAD_CPU_TIME
1.178 + return NKern::FastCounterFrequency();
1.179 +#else
1.180 + return 0;
1.181 +#endif
1.182 + }