os/kernelhwsrv/kernel/eka/euser/epoc/arm/uc_exec.cia
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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\arm\uc_exec.cia
    15 // 
    16 //
    17 
    18 #define __GEN_USER_EXEC_CODE__
    19 
    20 #include "uc_std.h"
    21 #include <e32svr.h>
    22 #include <u32exec.h>
    23 
    24 /******************************************************************************
    25  * Slow executive calls with preprocessing or extra arguments
    26  ******************************************************************************/
    27 
    28 __NAKED__ TInt Exec::SessionSend(TInt /*aHandle*/, TInt /*aFunction*/, TAny* /*aPtr*/, TRequestStatus* /*aStatus*/)
    29 //
    30 // Send a blind message to the server.
    31 //
    32 	{
    33 	asm("stmfd sp!, {r4-r8,lr} ");
    34 	asm("movs r8, r2 ");				// test for aPtr==NULL, set iArgFlags=0 if so
    35 	asm("ldmneia r2, {r4-r8} ");		// else get args into r4-r8
    36 	asm("swi	%a0" : : "i" (EExecSessionSend|EXECUTIVE_SLOW));
    37 	__POPRET("r4-r8,");
    38 	}
    39 
    40 __NAKED__ TInt Exec::SessionSendSync(TInt /*aHandle*/, TInt /*aFunction*/, TAny* /*aPtr*/, TRequestStatus* /*aStatus*/)
    41 //
    42 // Send a blind message to the server using thread's dedicated message slot.
    43 //
    44 	{
    45 	asm("stmfd sp!, {r4-r8,lr} ");
    46 	asm("movs r8, r2 ");				// test for aPtr==NULL, set iArgFlags=0 if so
    47 	asm("ldmneia r2, {r4-r8} ");		// else get args into r4-r8
    48 	asm("swi	%a0" : : "i" (EExecSessionSendSync|EXECUTIVE_SLOW));
    49 	__POPRET("r4-r8,");
    50 	}
    51 
    52 __NAKED__ TInt Exec::MessageIpcCopy(TInt /*aHandle*/, TInt /*aParam*/, SIpcCopyInfo& /*aInfo*/, TInt /*anOffset*/)
    53 //
    54 // IPC transfer using message handle
    55 //
    56 	{
    57 	asm("stmfd sp!, {r4-r6,lr} ");
    58 	asm("ldmia r2, {r4-r6} ");		// load SIpcCopyInfo into r4-r6
    59 	asm("swi	%a0" : : "i" (EExecMessageIpcCopy|EXECUTIVE_SLOW));
    60 	__POPRET("r4-r6,");
    61 	}
    62 
    63 __NAKED__ EXPORT_C TBool BTrace::Out(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
    64 	{
    65 	// fall through...
    66 	}
    67 
    68 __NAKED__ EXPORT_C TBool BTrace::OutX(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
    69 	{
    70 	asm("stmfd sp!, {r4-r6,lr}");
    71 	asm("mov r4, r2");
    72 	asm("mov r5, r3");
    73 	asm("mov r6, lr");
    74 	asm("mov r3, #0");
    75 	asm("swi %a0" : : "i" (EExecBTraceOut|EXECUTIVE_SLOW));
    76 	__POPRET("r4-r6,");
    77 	}
    78 
    79 __NAKED__ EXPORT_C TBool BTrace::OutN(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
    80 	{
    81 	// fall through...
    82 	}
    83 
    84 __NAKED__ EXPORT_C TBool BTrace::OutNX(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
    85 	{
    86 	asm("stmfd sp!, {r4-r6,lr}");
    87 	asm("mov r4, r2");
    88 	asm("mov r5, r3");
    89 	asm("ldr r3, [sp,#16]");
    90 	asm("mov r6, lr");
    91 	asm("swi %a0" : : "i" (EExecBTraceOut|EXECUTIVE_SLOW));
    92 	__POPRET("r4-r6,");
    93 	}
    94 
    95 __NAKED__ EXPORT_C TBool BTrace::OutBig(TUint32 a0, TUint32 a1, const TAny* aData, TInt aDataSize)
    96 	{
    97 	asm("stmfd sp!, {r4-r6,lr}");
    98 	asm("mov r4, #0");
    99 	asm("mov r5, r2");
   100 	asm("mov r6, lr");
   101 
   102 	asm("cmp r3, #8");
   103 	asm("bls 0f");
   104 	asm("cmp r3, #%a0" : : "i" (KMaxBTraceDataArray+4u));
   105 	asm("bls 1f");
   106 	asm("swi %a0" : : "i" (EExecBTraceOutBig|EXECUTIVE_SLOW));
   107 	__POPRET("r4-r6,");
   108 
   109 	asm("1:");
   110 	asm("add r0, r0, #4");
   111 	asm("sub r3, r3, #4");
   112 	asm("ldr r4, [r5] ,#4");
   113 	asm("swi %a0" : : "i" (EExecBTraceOut|EXECUTIVE_SLOW));
   114 	__POPRET("r4-r6,");
   115 
   116 	asm("0:");
   117 	asm("cmp r3, #0");
   118 	asm("ldrne r4, [r2]");
   119 	asm("cmp r3, #4");
   120 	asm("ldrhi r5, [r2, #4]");
   121 	asm("add r0, r0, r3");
   122 	asm("mov r3, #0");
   123 	asm("swi %a0" : : "i" (EExecBTraceOut|EXECUTIVE_SLOW));
   124 	__POPRET("r4-r6,");
   125 	}
   126 
   127 __NAKED__ EXPORT_C TBool BTrace::OutFiltered(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
   128 	{
   129 	// fall through...
   130 	}
   131 
   132 __NAKED__ EXPORT_C TBool BTrace::OutFilteredX(TUint32 a0, TUint32 a1, TUint32 a2, TUint32 a3)
   133 	{
   134 	asm("stmfd sp!, {r4-r6,lr}");
   135 	asm("orr r0, r0, #%a0" : : "i" (EMissingRecord<<BTrace::EFlagsIndex*8)); // overload meaning of this flag to indicate filtered trace
   136 	asm("mov r4, r2");
   137 	asm("mov r5, r3");
   138 	asm("mov r6, lr");
   139 	asm("mov r3, #0");
   140 	asm("swi %a0" : : "i" (EExecBTraceOut|EXECUTIVE_SLOW));
   141 	__POPRET("r4-r6,");
   142 	}
   143 
   144 __NAKED__ EXPORT_C TBool BTrace::OutFilteredN(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
   145 	{
   146 	// fall through...
   147 	}
   148 
   149 __NAKED__ EXPORT_C TBool BTrace::OutFilteredNX(TUint32 a0, TUint32 a1, TUint32 a2, const TAny* aData, TInt aDataSize)
   150 	{
   151 	asm("stmfd sp!, {r4-r6,lr}");
   152 	asm("orr r0, r0, #%a0" : : "i" (EMissingRecord<<BTrace::EFlagsIndex*8)); // overload meaning of this flag to indicate filtered trace
   153 	asm("mov r4, r2");
   154 	asm("mov r5, r3");
   155 	asm("ldr r3, [sp,#16]");
   156 	asm("mov r6, lr");
   157 	asm("swi %a0" : : "i" (EExecBTraceOut|EXECUTIVE_SLOW));
   158 	__POPRET("r4-r6,");
   159 	}
   160 
   161 __NAKED__ EXPORT_C TBool BTrace::OutFilteredBig(TUint32 a0, TUint32 a1, const TAny* aData, TInt aDataSize)
   162 	{
   163 	asm("stmfd sp!, {r4-r6,lr}");
   164 	asm("orr r0, r0, #%a0" : : "i" (EMissingRecord<<BTrace::EFlagsIndex*8)); // overload meaning of this flag to indicate filtered trace
   165 	asm("mov r4, #0");
   166 	asm("mov r5, r2");
   167 	asm("mov r6, lr");
   168 
   169 	asm("cmp r3, #8");
   170 	asm("bls 0f");
   171 	asm("cmp r3, #%a0" : : "i" (KMaxBTraceDataArray+4u));
   172 	asm("bls 1f");
   173 	asm("swi %a0" : : "i" (EExecBTraceOutBig|EXECUTIVE_SLOW));
   174 	__POPRET("r4-r6,");
   175 
   176 	asm("1:");
   177 	asm("add r0, r0, #4");
   178 	asm("sub r3, r3, #4");
   179 	asm("ldr r4, [r5] ,#4");
   180 	asm("swi %a0" : : "i" (EExecBTraceOut|EXECUTIVE_SLOW));
   181 	__POPRET("r4-r6,");
   182 
   183 	asm("0:");
   184 	asm("cmp r3, #0");
   185 	asm("ldrne r4, [r2]");
   186 	asm("cmp r3, #4");
   187 	asm("ldrhi r5, [r2, #4]");
   188 	asm("add r0, r0, r3");
   189 	asm("mov r3, #0");
   190 	asm("swi %a0" : : "i" (EExecBTraceOut|EXECUTIVE_SLOW));
   191 	__POPRET("r4-r6,");
   192 	}
   193 
   194 __NAKED__ EXPORT_C TBool BTrace::OutFilteredPcFormatBig(TUint32 a0, TUint32 aModuleUid, TUint32 aPc, TUint16 aFormatId, const TAny* aData, TInt aDataSize)
   195 	{
   196 	asm("stmfd sp!, {r4-r6,lr}");
   197 	asm("orr r0, r0, #%a0" : : "i" (EMissingRecord<<BTrace::EFlagsIndex*8)); // overload meaning of this flag to indicate filtered trace
   198 	asm("mov r4, r3"); 		
   199 	asm("ldr r5, [sp, #16]");	
   200 	asm("mov r6, r2"); 		
   201 	asm("ldr r3, [sp, #20]");	
   202 	
   203 	asm("cmp r3, #%a0" : : "i" (KMaxBTraceDataArray+0u));
   204 	asm("bls 0f"); 
   205 	asm("swi %a0" : : "i" (EExecUTraceOut|EXECUTIVE_SLOW));
   206 	__POPRET("r4-r6,");
   207 	
   208 	asm("0:");
   209 	asm("add r0, r0, #4");	
   210 	asm("swi %a0" : : "i" (EExecBTraceOut|EXECUTIVE_SLOW));
   211 	__POPRET("r4-r6,");
   212 	}
   213 
   214 EXPORT_C __NAKED__ void RThread::RequestComplete(TRequestStatus*& aStatus, TInt aReason) const
   215 /**
   216 Signals this thread that an asynchronous request originating from this thread, 
   217 is complete.
   218 	
   219 The request is associated with the specified request status object supplied 
   220 by this thread.
   221 	
   222 Typically, the caller of this function is the service provider responsible 
   223 for satisfying the request made by this thread.
   224 	
   225 The request is completed with the completion code passed in aReason. This 
   226 value is copied into this thread's request status, *aStatus, before signalling 
   227 this thread's request semaphore.
   228 	
   229 The meaning of the completion code is a matter of convention to be decided 
   230 between the service provider and this thread.
   231 	
   232 In a client-server situation, completion of a request takes place in the context 
   233 of the server thread, but the pointer is interpreted in the address space 
   234 of the client.
   235 	
   236 It is often the case in client-server situations that the client and the server 
   237 are in the same address space (i.e. the same process).
   238 	
   239 Setting the pointer to the request status to NULL is a convenience, not all 
   240 servers need it.
   241 	
   242 @param aStatus A reference to a pointer to the request status originally
   243                supplied by this thread. This is a pointer into this thread's
   244                address space, which may be different to the thread currently
   245                executing (this code). On return, the pointer to the request
   246                status is set to NULL.
   247                
   248 @param aReason The completion code of this request.
   249 */
   250 //
   251 // Signal a request completion.
   252 //
   253 	{
   254 	asm("mov r3, #0 ");
   255 #ifdef __CPU_ARM_HAS_LDREX_STREX
   256 #ifdef __SMP__
   257 	__DATA_MEMORY_BARRIER__(r3);			// release semantics
   258 #endif
   259 	asm("		   str	 r14, [sp, #-4]! ");
   260 	asm("tryagain: ");
   261 	LDREX(12, 1);							// read
   262 	STREX(14, 3, 1);						// write
   263 	asm("          teq   r14, #0 ");		// success?
   264 	asm("          bne   tryagain ");		// no!
   265 	asm("		   cmp   r12, #0 ");		// if pointer not null...
   266 	asm("		   ldrne r0, [r0] ");
   267 	asm("		   strne r2, [r12] ");		// store aReason into request status
   268 	asm("		   swine %a0" : : "i" (EExecThreadRequestSignal|EXECUTIVE_SLOW));
   269 	asm("		   ldr	 pc,  [sp], #4 ");	// return
   270 #else
   271 	asm("swp r3, r3, [r1] ");	// clear TRequestStatus pointer, pointer into r3
   272 	asm("ldr r0, [r0] ");
   273 	asm("cmp r3, #0 ");			// if pointer not null...
   274 	asm("strne r2, [r3] ");		// store aReason into request status
   275 	asm("swine %a0" : : "i" (EExecThreadRequestSignal|EXECUTIVE_SLOW));
   276 	__JUMP(,lr);
   277 #endif
   278 	}
   279 
   280 /**
   281 Signal this threads request semaphore.
   282 
   283 This is similar to RThread::RequestComplete() except that no TRequestStatus object
   284 is modified.
   285 
   286 May only be used to signal a thread in the same process as the callers.
   287 
   288 @panic KERN-EXEC 46 if the thread is not in the same process as the callers
   289 */
   290 EXPORT_C __NAKED__ void RThread::RequestSignal() const
   291 	{
   292 	asm("ldr r0, [r0] ");
   293 	asm("swi %a0" : : "i" (EExecThreadRequestSignal|EXECUTIVE_SLOW));
   294 	__JUMP(,lr);
   295 	}
   296 
   297 
   298 
   299 __NAKED__ void ExitCurrentThread(TExitType /*aType*/, TInt /*aReason*/, const TDesC8* /*aCategory*/)
   300 	{
   301 	asm("mov r3, r2 ");
   302 	asm("mov r2, r1 ");
   303 	asm("mov r1, r0 ");
   304 	asm("mvn r0, #0xfe ");			// r0=0xffffff01
   305 	asm("bic r0, r0, #0x7f00 ");	// r0=0xffff8001=KCurrentThreadHandle
   306 	asm("swi	%a0" : : "i" (EExecThreadKill|EXECUTIVE_SLOW));
   307 	__JUMP(,lr);
   308 	}