os/kernelhwsrv/kernel/eka/euser/epoc/win32/uc_exec.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.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\euser\epoc\win32\uc_exec.cpp
    15 // 
    16 //
    17 
    18 #define __GEN_USER_EXEC_CODE__
    19 
    20 #include "uc_std.h"
    21 #include <e32svr.h>
    22 #include <emulator.h>
    23 
    24 typedef TInt (__fastcall *TDispatcher)(TInt, TInt*);
    25 TInt __fastcall LazyDispatch(TInt aFunction, TInt* aArgs);
    26 
    27 #pragma data_seg(".data2")
    28 #ifdef __VC32__
    29 #pragma bss_seg(".data2")
    30 #endif
    31 static TDispatcher TheDispatcher = &LazyDispatch;
    32 #pragma data_seg()
    33 #ifdef __VC32__
    34 #pragma bss_seg()
    35 #endif
    36 
    37 TInt __fastcall LazyDispatch(TInt aFunction, TInt* aArgs)
    38 	{
    39 	//SL:
    40 	HINSTANCE kernel = GetModuleHandleA("ekern.dll");
    41 	//HINSTANCE kernel = GetModuleHandleA("ekern.exe");
    42 	if (kernel)
    43 		{
    44 		TDispatcher dispatcher = (TDispatcher)Emulator::GetProcAddress(kernel, (LPCSTR)1);
    45 		if (dispatcher)
    46 			{
    47 			TheDispatcher = dispatcher;
    48 			return dispatcher(aFunction, aArgs);
    49 			}
    50 		}
    51 	ExitProcess(101);
    52 	return 0;
    53 	}
    54 
    55 #include <u32exec.h>
    56 
    57 /******************************************************************************
    58  * Slow executive calls with preprocessing or extra arguments
    59  ******************************************************************************/
    60 
    61 __NAKED__ TInt Exec::SessionSend(TInt /*aHandle*/, TInt /*aFunction*/, TAny* /*aPtr*/, TRequestStatus* /*aStatus*/)
    62 //
    63 // Send a blind message to the server.
    64 //
    65 	{
    66 	__DISPATCH(EExecSessionSend|EXECUTIVE_SLOW)
    67 	}
    68 
    69 __NAKED__ TInt Exec::SessionSendSync(TInt /*aHandle*/, TInt /*aFunction*/, TAny* /*aPtr*/, TRequestStatus* /*aStatus*/)
    70 //
    71 // Send a blind message to the server using thread's dedicated message slot.
    72 //
    73 	{
    74 	__DISPATCH(EExecSessionSendSync|EXECUTIVE_SLOW)
    75 	}
    76 
    77 
    78 __NAKED__ TInt Exec::MessageIpcCopy(TInt /*aHandle*/, TInt /*aParam*/, SIpcCopyInfo& /*aInfo*/, TInt /*anOffset*/)
    79 //
    80 // Perform a descriptor-to-descriptor IPC copy
    81 //
    82 	{
    83 
    84 	__DISPATCH(EExecMessageIpcCopy|EXECUTIVE_SLOW)
    85 	}
    86 
    87 __NAKED__ TInt Exec::BTraceOut(TUint32 /*a0*/, TUint32 /*a1*/, const BTrace::SExecExtension& /*aExtension*/, TInt /*aDataSize*/)
    88 	{
    89 	__DISPATCH(EExecBTraceOut|EXECUTIVE_SLOW)
    90 	}
    91 
    92 __NAKED__ TInt Exec::BTraceOutBig(TUint32 /*a0*/, TUint32 /*a1*/, const BTrace::SExecExtension& /*aExtension*/, TInt /*aDataSize*/)
    93 	{
    94 	__DISPATCH(EExecBTraceOutBig|EXECUTIVE_SLOW)
    95 	}
    96 
    97 __NAKED__ TInt Exec::UTraceOut(TUint32 /*a0*/, TUint32 /*a1*/, const BTrace::SExecExtension& /*aExtension*/, TInt /*aDataSize*/)
    98 	{
    99 	__DISPATCH(EExecUTraceOut|EXECUTIVE_SLOW)
   100 	}
   101 
   102 EXPORT_C TBool BTrace::Out(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
   103 	{
   104 	BTrace::SExecExtension ext;
   105 	ext.iA2 = a2;
   106 	ext.iA3 = a3;
   107 	ext.iPc = (&a0)[-1]; // return address on X86
   108 	return Exec::BTraceOut(a0,a1,ext,0);
   109 	}
   110 
   111 EXPORT_C TBool BTrace::OutX(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
   112 	{
   113 	BTrace::SExecExtension ext;
   114 	ext.iA2 = a2;
   115 	ext.iA3 = a3;
   116 	ext.iPc = (&a0)[-1]; // return address on X86
   117 	return Exec::BTraceOut(a0,a1,ext,0);
   118 	}
   119 
   120 EXPORT_C TBool BTrace::OutN(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
   121 	{
   122 	BTrace::SExecExtension ext;
   123 	ext.iA2 = a2;
   124 	ext.iA3 = (TUint32)aData;
   125 	ext.iPc = (&a0)[-1]; // return address on X86
   126 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
   127 	}
   128 
   129 EXPORT_C TBool BTrace::OutNX(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
   130 	{
   131 	BTrace::SExecExtension ext;
   132 	ext.iA2 = a2;
   133 	ext.iA3 = (TUint32)aData;
   134 	ext.iPc = (&a0)[-1]; // return address on X86
   135 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
   136 	}
   137 
   138 EXPORT_C TBool BTrace::OutBig(TUint32 a0, TUint32 a1, const TAny* aData, TInt aDataSize)
   139 	{
   140 	BTrace::SExecExtension ext;
   141 	ext.iA2 = 0;
   142 	ext.iA3 = (TUint32)aData;
   143 	ext.iPc = (&a0)[-1]; // return address on X86
   144 
   145 	if((TUint)aDataSize>8u)
   146 		{
   147 		if((TUint)aDataSize>KMaxBTraceDataArray+4u)
   148 			return Exec::BTraceOutBig(a0,a1,ext,aDataSize);
   149 		a0 += 4;
   150 		aDataSize -= 4;
   151 		ext.iA2 = *((TUint32*&)aData)++;
   152 		ext.iA3 = (TUint32)aData;
   153 		return Exec::BTraceOut(a0,a1,ext,aDataSize);
   154 		}
   155 
   156 	if((TUint)aDataSize>4u)
   157 		ext.iA3 = ((TUint32*)aData)[1];
   158 	if(aDataSize)
   159 		ext.iA2 = ((TUint32*)aData)[0];
   160 	a0 += aDataSize;
   161 	aDataSize = 0;
   162 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
   163 	}
   164 
   165 EXPORT_C TBool BTrace::OutFiltered(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
   166 	{
   167 	BTrace::SExecExtension ext;
   168 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
   169 	ext.iA2 = a2;
   170 	ext.iA3 = a3;
   171 	ext.iPc = (&a0)[-1]; // return address on X86
   172 	return Exec::BTraceOut(a0,a1,ext,0);
   173 	}
   174 
   175 EXPORT_C TBool BTrace::OutFilteredX(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
   176 	{
   177 	BTrace::SExecExtension ext;
   178 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
   179 	ext.iA2 = a2;
   180 	ext.iA3 = a3;
   181 	ext.iPc = (&a0)[-1]; // return address on X86
   182 	return Exec::BTraceOut(a0,a1,ext,0);
   183 	}
   184 
   185 EXPORT_C TBool BTrace::OutFilteredN(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
   186 	{
   187 	BTrace::SExecExtension ext;
   188 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
   189 	ext.iA2 = a2;
   190 	ext.iA3 = (TUint32)aData;
   191 	ext.iPc = (&a0)[-1]; // return address on X86
   192 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
   193 	}
   194 
   195 EXPORT_C TBool BTrace::OutFilteredNX(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
   196 	{
   197 	BTrace::SExecExtension ext;
   198 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
   199 	ext.iA2 = a2;
   200 	ext.iA3 = (TUint32)aData;
   201 	ext.iPc = (&a0)[-1]; // return address on X86
   202 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
   203 	}
   204 
   205 EXPORT_C TBool BTrace::OutFilteredBig(TUint32 a0, TUint32 a1, const TAny* aData, TInt aDataSize)
   206 	{
   207 	BTrace::SExecExtension ext;
   208 	a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
   209 	ext.iA2 = 0;
   210 	ext.iA3 = (TUint32)aData;
   211 	ext.iPc = (&a0)[-1]; // return address on X86
   212 
   213 	if((TUint)aDataSize>8u)
   214 		{
   215 		if((TUint)aDataSize>KMaxBTraceDataArray+4u)
   216 			return Exec::BTraceOutBig(a0,a1,ext,aDataSize);
   217 		a0 += 4;
   218 		aDataSize -= 4;
   219 		ext.iA2 = *((TUint32*&)aData)++;
   220 		ext.iA3 = (TUint32)aData;
   221 		return Exec::BTraceOut(a0,a1,ext,aDataSize);
   222 		}
   223 
   224 	if((TUint)aDataSize>4u)
   225 		ext.iA3 = ((TUint32*)aData)[1];
   226 	if(aDataSize)
   227 		ext.iA2 = ((TUint32*)aData)[0];
   228 	a0 += aDataSize;
   229 	aDataSize = 0;
   230 	return Exec::BTraceOut(a0,a1,ext,aDataSize);
   231 	}
   232 
   233 EXPORT_C TBool BTrace::OutFilteredPcFormatBig(TUint32 aHeader, TUint32 aModuleUid, TUint32 aPc, TUint16 aFormatId, const TAny* aData, TInt aDataSize)
   234 	{
   235  	BTrace::SExecExtension ext;
   236 	aHeader |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
   237 	ext.iA2 = aFormatId;
   238 	ext.iA3 = (TUint32)aData;
   239 	ext.iPc = aPc;
   240 
   241 	if((TUint)aDataSize>KMaxBTraceDataArray)
   242 		return Exec::UTraceOut(aHeader,aModuleUid,ext,aDataSize);
   243 	aHeader += 4;
   244 	return Exec::BTraceOut(aHeader,aModuleUid,ext,aDataSize);
   245 	}
   246 
   247 __NAKED__ void ExecRequestComplete(TInt /*aHandle*/, TRequestStatus*& /*aStatus*/, TInt /*aReason*/)
   248 	{
   249 	_asm mov ecx, [esp+8]			// ecx = TRequestStatus**
   250 	_asm xor eax, eax				//
   251 	_asm lock xchg eax, [ecx]		// eax=TRequestStatus*, zero TRequestStatus*
   252 	_asm cmp eax, 0					//
   253 	_asm je ExecRequestComplete_ret
   254 	_asm mov ecx, [esp+12]			// ecx = aReason
   255 	_asm mov [eax], ecx				// store aReason in request status
   256 	__DISPATCH(EExecThreadRequestSignal|EXECUTIVE_SLOW)
   257 	_asm ExecRequestComplete_ret: ret
   258 	}
   259 
   260 
   261 
   262 
   263 EXPORT_C void RThread::RequestComplete(TRequestStatus*& aStatus, TInt aReason) const
   264 /**
   265 Signals this thread that an asynchronous request originating from this thread,
   266 is complete.
   267 
   268 The request is associated with the specified request status object supplied
   269 by this thread.
   270 
   271 Typically, the caller of this function is the service provider responsible
   272 for satisfying the request made by this thread.
   273 
   274 The request is completed with the completion code passed in aReason. This
   275 value is copied into this thread's request status, *aStatus, before signalling
   276 this thread's request semaphore.
   277 
   278 The meaning of the completion code is a matter of convention to be decided
   279 between the service provider and this thread.
   280 
   281 In a client-server situation, completion of a request takes place in the context
   282 of the server thread, but the pointer is interpreted in the address space
   283 of the client.
   284 
   285 It is often the case in client-server situations that the client and the server
   286 are in the same address space (i.e. the same process).
   287 
   288 Setting the pointer to the request status to NULL is a convenience, not all
   289 servers need it.
   290 
   291 @param aStatus A reference to a pointer to the request status originally
   292                supplied by this thread. This is a pointer into this thread's
   293                address space, which may be different to the thread currently
   294                executing (this code). On return, the pointer to the request
   295                status is set to NULL.
   296 
   297 @param aReason The completion code of this request.
   298 */
   299 	{
   300 	ExecRequestComplete(iHandle,aStatus,aReason);
   301 	}
   302 
   303 
   304 
   305 /**
   306 Signal this threads request semaphore.
   307 
   308 This is similar to RThread::RequestComplete() except that no TRequestStatus object
   309 is modified.
   310 
   311 May only be used to signal a thread in the same process as the callers.
   312 
   313 @panic KERN-EXEC 46 if the thread is not in the same process as the callers
   314 */
   315 EXPORT_C void RThread::RequestSignal() const
   316 	{
   317 	Exec::ThreadRequestSignal(iHandle);
   318 	}
   319 
   320 
   321 
   322 void ExitCurrentThread(TExitType aType, TInt aReason, const TDesC8* aCategory)
   323 	{
   324 	Exec::ThreadKill(KCurrentThreadHandle, aType, aReason, aCategory);
   325 	}
   326