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\include\nkern\win32\nk_plat.h sl@0: // sl@0: // WARNING: This file contains some APIs which are internal and are subject sl@0: // to change without notice. Such APIs should therefore not be used sl@0: // outside the Kernel and Hardware Services package. sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @internalComponent sl@0: */ sl@0: sl@0: #ifndef __NK_WIN32_H__ sl@0: #define __NK_WIN32_H__ sl@0: sl@0: #define _CRTIMP // we want to use the win32 static runtime library sl@0: sl@0: #define WIN32_LEAN_AND_MEAN sl@0: #define _WIN32_WINNT 0x0400 sl@0: #include sl@0: sl@0: typedef void (*TExcHandler)(TAny*,TAny*); sl@0: sl@0: struct TWin32ExcInfo sl@0: { sl@0: enum {EExcInKernel = 0x1}; sl@0: public: sl@0: TExcHandler iHandler; sl@0: TAny* iParam[2]; sl@0: TUint iFlags; sl@0: // ExcType, iExcId, iFaultAddress, iEax, iEcx, iEdx, iEbx, iEsp, iEbp, iEsi, iEdi, sl@0: // iSs, iDs, iEs, iFs, iGs, iEflags, iEip, iCs sl@0: TUint32 iExcType; // filled in by EPOC sl@0: TUint32 iExcCode; sl@0: TUint32 iExcDataAddress; sl@0: TUint32 iEax; sl@0: TUint32 iEcx; sl@0: TUint32 iEdx; sl@0: TUint32 iEbx; sl@0: TUint32 iEsp; sl@0: TUint32 iEsi; sl@0: TUint32 iEdi; sl@0: TUint32 iSs; sl@0: TUint32 iDs; sl@0: TUint32 iEs; sl@0: TUint32 iFs; sl@0: TUint32 iGs; sl@0: TUint32 iEflags; sl@0: TUint32 iCs; sl@0: TUint32 iEbp; sl@0: TUint32 iEip; sl@0: }; sl@0: sl@0: enum TEmulThreadType sl@0: { sl@0: EThreadEvent, // an 'interrupt' thread, interacts with Win32 events sl@0: EThreadNKern // a nKern thread, identified by a NThread control block sl@0: }; sl@0: sl@0: class NThread : public NThreadBase sl@0: { sl@0: public: sl@0: typedef void (*TDivert)(); sl@0: enum TWakeup {ERelease,EResume,EResumeLocked,EIdle,EEscaped,EResumeDiverted}; sl@0: enum TSelectCpu {ECpuAll=-1,ECpuSingle=-2}; sl@0: public: sl@0: TInt Create(SNThreadCreateInfo& aInfo, TBool aInitial); sl@0: void Stillborn(); sl@0: void DoForceExit(); sl@0: // sl@0: IMPORT_C static void Idle(); sl@0: IMPORT_C static void SetProperties(TBool aTrace, TInt aCpu); sl@0: TBool WakeUp(); sl@0: TBool IsSafeToPreempt(); sl@0: void Divert(TDivert aDivert); sl@0: void ApplyDiversion(); sl@0: sl@0: private: sl@0: static DWORD WINAPI StartThread(LPVOID aParam); sl@0: // sl@0: static void ExitSync(); sl@0: static void ExitAsync(); sl@0: // sl@0: static void Exception(); sl@0: static LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS* aExc); sl@0: sl@0: public: sl@0: static void Diverted(); sl@0: // Has to be accessible to code user-side via emulator.lib sl@0: static DWORD ExceptionHandler(EXCEPTION_RECORD* aException, CONTEXT* aContext); sl@0: sl@0: public: sl@0: HANDLE iWinThread; sl@0: DWORD iWinThreadId; sl@0: HANDLE iScheduleLock; // event used for scheduling interlock sl@0: TBool iDiverted; // flag to indicate that the thread is being diverted sl@0: TDivert iDivert; // function to invoke after reschedule, may be null sl@0: TAny* iDivertReturn; // return address from diversion sl@0: TInt iInKernel; // flag to indicate if the thread is running 'in' the kernel sl@0: TWakeup iWakeup; // indicates how to wake up the thread sl@0: TLinAddr iUserStackBase; sl@0: }; sl@0: sl@0: IMPORT_C HANDLE CreateWin32Thread(TEmulThreadType aType, LPTHREAD_START_ROUTINE aThreadFunc, LPVOID aPtr, TBool aRun); sl@0: IMPORT_C void StartOfInterrupt(); sl@0: IMPORT_C void EndOfInterrupt(); sl@0: sl@0: void SchedulerInit(NThread& aInit); sl@0: void SchedulerRegister(NThread& aSelf); sl@0: NThread* SchedulerThread(); sl@0: NThread& CheckedCurrentThread(); sl@0: void SchedulerLock(); sl@0: void SchedulerUnlock(); sl@0: void SchedulerEscape(); sl@0: void SchedulerReenter(); sl@0: void Win32FindNonPreemptibleFunctions(); sl@0: sl@0: inline void EnterKernel(TBool aCheck=TRUE) sl@0: { sl@0: if (++CheckedCurrentThread().iInKernel==1 && aCheck) sl@0: { sl@0: NThread& t = CheckedCurrentThread(); sl@0: __NK_ASSERT_ALWAYS(t.iCsCount==0); sl@0: __NK_ASSERT_ALWAYS(t.iHeldFastMutex==0); sl@0: __NK_ASSERT_ALWAYS(TheScheduler.iKernCSLocked==0); sl@0: } sl@0: } sl@0: sl@0: void LeaveKernel(); sl@0: sl@0: IMPORT_C TInt __fastcall Dispatch(TInt aFunction, TInt* aArgs); sl@0: sl@0: typedef TInt (__cdecl *TExecHandler)(TInt,TInt,TInt,TInt); sl@0: typedef void (__cdecl *TPreprocessHandler)(TInt*,TUint32); sl@0: sl@0: // Emulator nKern scheduling data sl@0: class Win32Interrupt sl@0: { sl@0: public: sl@0: void Init(); sl@0: TInt Mask(); sl@0: void Restore(TInt aLevel); sl@0: void Begin(); sl@0: void End(); sl@0: inline TBool InInterrupt() const sl@0: {return iInterrupted!=0;} sl@0: void ForceReschedule(); sl@0: inline TBool InterruptsStatus(TBool aRequest) const sl@0: {return aRequest?(iLevel==0):(iLevel!=0);} sl@0: private: sl@0: static void Reschedule(TAny*); sl@0: private: sl@0: TInt iLock; sl@0: HANDLE iQ; sl@0: DWORD iOwner; sl@0: TInt iLevel; sl@0: TBool iRescheduleOnExit; sl@0: NThread* iInterrupted; sl@0: NThread iScheduler; sl@0: }; sl@0: sl@0: extern TBool Win32AtomicSOAW; // flag to indicate availability of SignalObjectAndWait() API sl@0: extern TBool Win32TraceThreadId; sl@0: extern TInt Win32SingleCpu; sl@0: extern Win32Interrupt Interrupt; sl@0: sl@0: // Emulator nKern exception data sl@0: extern TAny* Win32ExcAddress; sl@0: extern TAny* Win32ExcDataAddress; sl@0: extern TUint Win32ExcCode; sl@0: sl@0: void FastCounterInit(); sl@0: sl@0: #endif