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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\euser\epoc\win32\uc_exec.cpp
18 #define __GEN_USER_EXEC_CODE__
24 typedef TInt (__fastcall *TDispatcher)(TInt, TInt*);
25 TInt __fastcall LazyDispatch(TInt aFunction, TInt* aArgs);
27 #pragma data_seg(".data2")
29 #pragma bss_seg(".data2")
31 static TDispatcher TheDispatcher = &LazyDispatch;
37 TInt __fastcall LazyDispatch(TInt aFunction, TInt* aArgs)
40 HINSTANCE kernel = GetModuleHandleA("ekern.dll");
41 //HINSTANCE kernel = GetModuleHandleA("ekern.exe");
44 TDispatcher dispatcher = (TDispatcher)Emulator::GetProcAddress(kernel, (LPCSTR)1);
47 TheDispatcher = dispatcher;
48 return dispatcher(aFunction, aArgs);
57 /******************************************************************************
58 * Slow executive calls with preprocessing or extra arguments
59 ******************************************************************************/
61 __NAKED__ TInt Exec::SessionSend(TInt /*aHandle*/, TInt /*aFunction*/, TAny* /*aPtr*/, TRequestStatus* /*aStatus*/)
63 // Send a blind message to the server.
66 __DISPATCH(EExecSessionSend|EXECUTIVE_SLOW)
69 __NAKED__ TInt Exec::SessionSendSync(TInt /*aHandle*/, TInt /*aFunction*/, TAny* /*aPtr*/, TRequestStatus* /*aStatus*/)
71 // Send a blind message to the server using thread's dedicated message slot.
74 __DISPATCH(EExecSessionSendSync|EXECUTIVE_SLOW)
78 __NAKED__ TInt Exec::MessageIpcCopy(TInt /*aHandle*/, TInt /*aParam*/, SIpcCopyInfo& /*aInfo*/, TInt /*anOffset*/)
80 // Perform a descriptor-to-descriptor IPC copy
84 __DISPATCH(EExecMessageIpcCopy|EXECUTIVE_SLOW)
87 __NAKED__ TInt Exec::BTraceOut(TUint32 /*a0*/, TUint32 /*a1*/, const BTrace::SExecExtension& /*aExtension*/, TInt /*aDataSize*/)
89 __DISPATCH(EExecBTraceOut|EXECUTIVE_SLOW)
92 __NAKED__ TInt Exec::BTraceOutBig(TUint32 /*a0*/, TUint32 /*a1*/, const BTrace::SExecExtension& /*aExtension*/, TInt /*aDataSize*/)
94 __DISPATCH(EExecBTraceOutBig|EXECUTIVE_SLOW)
97 __NAKED__ TInt Exec::UTraceOut(TUint32 /*a0*/, TUint32 /*a1*/, const BTrace::SExecExtension& /*aExtension*/, TInt /*aDataSize*/)
99 __DISPATCH(EExecUTraceOut|EXECUTIVE_SLOW)
102 EXPORT_C TBool BTrace::Out(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
104 BTrace::SExecExtension ext;
107 ext.iPc = (&a0)[-1]; // return address on X86
108 return Exec::BTraceOut(a0,a1,ext,0);
111 EXPORT_C TBool BTrace::OutX(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
113 BTrace::SExecExtension ext;
116 ext.iPc = (&a0)[-1]; // return address on X86
117 return Exec::BTraceOut(a0,a1,ext,0);
120 EXPORT_C TBool BTrace::OutN(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
122 BTrace::SExecExtension ext;
124 ext.iA3 = (TUint32)aData;
125 ext.iPc = (&a0)[-1]; // return address on X86
126 return Exec::BTraceOut(a0,a1,ext,aDataSize);
129 EXPORT_C TBool BTrace::OutNX(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
131 BTrace::SExecExtension ext;
133 ext.iA3 = (TUint32)aData;
134 ext.iPc = (&a0)[-1]; // return address on X86
135 return Exec::BTraceOut(a0,a1,ext,aDataSize);
138 EXPORT_C TBool BTrace::OutBig(TUint32 a0, TUint32 a1, const TAny* aData, TInt aDataSize)
140 BTrace::SExecExtension ext;
142 ext.iA3 = (TUint32)aData;
143 ext.iPc = (&a0)[-1]; // return address on X86
145 if((TUint)aDataSize>8u)
147 if((TUint)aDataSize>KMaxBTraceDataArray+4u)
148 return Exec::BTraceOutBig(a0,a1,ext,aDataSize);
151 ext.iA2 = *((TUint32*&)aData)++;
152 ext.iA3 = (TUint32)aData;
153 return Exec::BTraceOut(a0,a1,ext,aDataSize);
156 if((TUint)aDataSize>4u)
157 ext.iA3 = ((TUint32*)aData)[1];
159 ext.iA2 = ((TUint32*)aData)[0];
162 return Exec::BTraceOut(a0,a1,ext,aDataSize);
165 EXPORT_C TBool BTrace::OutFiltered(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
167 BTrace::SExecExtension ext;
168 a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
171 ext.iPc = (&a0)[-1]; // return address on X86
172 return Exec::BTraceOut(a0,a1,ext,0);
175 EXPORT_C TBool BTrace::OutFilteredX(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
177 BTrace::SExecExtension ext;
178 a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
181 ext.iPc = (&a0)[-1]; // return address on X86
182 return Exec::BTraceOut(a0,a1,ext,0);
185 EXPORT_C TBool BTrace::OutFilteredN(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
187 BTrace::SExecExtension ext;
188 a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
190 ext.iA3 = (TUint32)aData;
191 ext.iPc = (&a0)[-1]; // return address on X86
192 return Exec::BTraceOut(a0,a1,ext,aDataSize);
195 EXPORT_C TBool BTrace::OutFilteredNX(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
197 BTrace::SExecExtension ext;
198 a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
200 ext.iA3 = (TUint32)aData;
201 ext.iPc = (&a0)[-1]; // return address on X86
202 return Exec::BTraceOut(a0,a1,ext,aDataSize);
205 EXPORT_C TBool BTrace::OutFilteredBig(TUint32 a0, TUint32 a1, const TAny* aData, TInt aDataSize)
207 BTrace::SExecExtension ext;
208 a0 |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
210 ext.iA3 = (TUint32)aData;
211 ext.iPc = (&a0)[-1]; // return address on X86
213 if((TUint)aDataSize>8u)
215 if((TUint)aDataSize>KMaxBTraceDataArray+4u)
216 return Exec::BTraceOutBig(a0,a1,ext,aDataSize);
219 ext.iA2 = *((TUint32*&)aData)++;
220 ext.iA3 = (TUint32)aData;
221 return Exec::BTraceOut(a0,a1,ext,aDataSize);
224 if((TUint)aDataSize>4u)
225 ext.iA3 = ((TUint32*)aData)[1];
227 ext.iA2 = ((TUint32*)aData)[0];
230 return Exec::BTraceOut(a0,a1,ext,aDataSize);
233 EXPORT_C TBool BTrace::OutFilteredPcFormatBig(TUint32 aHeader, TUint32 aModuleUid, TUint32 aPc, TUint16 aFormatId, const TAny* aData, TInt aDataSize)
235 BTrace::SExecExtension ext;
236 aHeader |= EMissingRecord<<BTrace::EFlagsIndex*8; // overload meaning of this flag to indicate filtered trace
238 ext.iA3 = (TUint32)aData;
241 if((TUint)aDataSize>KMaxBTraceDataArray)
242 return Exec::UTraceOut(aHeader,aModuleUid,ext,aDataSize);
244 return Exec::BTraceOut(aHeader,aModuleUid,ext,aDataSize);
247 __NAKED__ void ExecRequestComplete(TInt /*aHandle*/, TRequestStatus*& /*aStatus*/, TInt /*aReason*/)
249 _asm mov ecx, [esp+8] // ecx = TRequestStatus**
251 _asm lock xchg eax, [ecx] // eax=TRequestStatus*, zero TRequestStatus*
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
263 EXPORT_C void RThread::RequestComplete(TRequestStatus*& aStatus, TInt aReason) const
265 Signals this thread that an asynchronous request originating from this thread,
268 The request is associated with the specified request status object supplied
271 Typically, the caller of this function is the service provider responsible
272 for satisfying the request made by this thread.
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.
278 The meaning of the completion code is a matter of convention to be decided
279 between the service provider and this thread.
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
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).
288 Setting the pointer to the request status to NULL is a convenience, not all
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.
297 @param aReason The completion code of this request.
300 ExecRequestComplete(iHandle,aStatus,aReason);
306 Signal this threads request semaphore.
308 This is similar to RThread::RequestComplete() except that no TRequestStatus object
311 May only be used to signal a thread in the same process as the callers.
313 @panic KERN-EXEC 46 if the thread is not in the same process as the callers
315 EXPORT_C void RThread::RequestSignal() const
317 Exec::ThreadRequestSignal(iHandle);
322 void ExitCurrentThread(TExitType aType, TInt aReason, const TDesC8* aCategory)
324 Exec::ThreadKill(KCurrentThreadHandle, aType, aReason, aCategory);