sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\nkern\win32\vectors.cpp sl@0: // sl@0: // sl@0: sl@0: #include "nk_priv.h" sl@0: sl@0: inline TInt Invoke(TLinAddr aHandler,const TInt* aArgs) sl@0: {return (TExecHandler(aHandler))(aArgs[0],aArgs[1],aArgs[2],aArgs[3]);} sl@0: sl@0: /** Executive dispatcher. sl@0: This is hooked by EUSER to handle executive dispatch into the kernel. sl@0: aArgs can be treated as an array of 1 to 4 arguments (depending on the exec call). sl@0: sl@0: @internalTechnology sl@0: */ sl@0: EXPORT_C TInt __fastcall Dispatch(TInt aFunction, TInt* aArgs) sl@0: { sl@0: NThread& me = *static_cast(TheScheduler.iCurrentThread); sl@0: //SL: Can't figure out why this fails at times sl@0: __NK_ASSERT_ALWAYS(!me.iDiverted); sl@0: sl@0: /* sl@0: if (me.iDiverted) sl@0: { sl@0: __KTRACE_OPT(KSCHED,DEBUGPRINT("WARNING: not diverted!")); sl@0: } sl@0: */ sl@0: sl@0: EnterKernel(); sl@0: sl@0: if (aFunction & 0x800000) sl@0: { sl@0: aFunction &= 0x7fffff; sl@0: // fast exec sl@0: const SFastExecTable* table = me.iFastExecTable; sl@0: if (aFunction == 0) sl@0: { sl@0: // special case fast exec call sl@0: NKern::WaitForAnyRequest(); sl@0: LeaveKernel(); sl@0: return 0; sl@0: } sl@0: if (TUint(aFunction)iFastExecCount)) sl@0: { sl@0: NKern::Lock(); sl@0: TInt r = Invoke(table->iFunction[aFunction-1],aArgs); sl@0: NKern::Unlock(); sl@0: LeaveKernel(); sl@0: return r; sl@0: } sl@0: // invalid exec number passed, so ensure we invoke the invalid exec sl@0: // handler by setting an illegal slow exec number sl@0: aFunction = -1; sl@0: } sl@0: sl@0: // slow exec sl@0: sl@0: sl@0: const SSlowExecTable* table = (const SSlowExecTable*)((const TUint8*)me.iSlowExecTable - _FOFF(SSlowExecTable,iEntries)); sl@0: if (TUint(aFunction) >= TUint(table->iSlowExecCount)) sl@0: return Invoke(table->iInvalidExecHandler,aArgs); sl@0: sl@0: const SSlowExecEntry& e = table->iEntries[aFunction]; sl@0: if (e.iFlags & KExecFlagClaim) sl@0: NKern::LockSystem(); sl@0: if (e.iFlags & KExecFlagPreprocess) sl@0: { sl@0: // replace the first argument with the result of preprocessing sl@0: TPreprocessHandler preprocesser = (TPreprocessHandler)table->iPreprocessHandler; sl@0: preprocesser(aArgs, e.iFlags); sl@0: } sl@0: TInt r = Invoke(e.iFunction,aArgs); sl@0: if (e.iFlags & KExecFlagRelease) sl@0: NKern::UnlockSystem(); sl@0: LeaveKernel(); sl@0: return r; sl@0: }