kernel/eka/kernel/arm/cipc.cia
branchRCL_3
changeset 110 c734af59ce98
parent 0 a41df078684a
equal deleted inserted replaced
97:41f0cfe18c80 110:c734af59ce98
    55 extern "C" void __PanicMesAlreadyPending();
    55 extern "C" void __PanicMesAlreadyPending();
    56 extern "C" void __SendDiscMsg(DSession*);
    56 extern "C" void __SendDiscMsg(DSession*);
    57 
    57 
    58 __NAKED__ void ExecHandler::MessageComplete(RMessageK* /*aMsg*/, TInt /*aReason*/)
    58 __NAKED__ void ExecHandler::MessageComplete(RMessageK* /*aMsg*/, TInt /*aReason*/)
    59 	{
    59 	{
    60 	asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(RMessageK, iFunction));		// get iFunction, as per preprocessor
    60 	asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(RMessageK, iFunction));				// get iFunction, as per preprocessor
    61 
    61 
    62 	// Subroutine MessageComplete
    62 	// Subroutine MessageComplete
    63 	// Complete an IPC message
    63 	// Complete an IPC message
    64 	// Enter with r0=message handle, r1=completion code, ip=RMessageK::iFunction
    64 	// Enter with r0=message handle, r1=completion code, ip=RMessageK::iFunction
    65 	// Preserve r4-r11
    65 	// Preserve r4-r11
    67 	asm(".global _asm_exec_MessageComplete ");
    67 	asm(".global _asm_exec_MessageComplete ");
    68 	asm("_asm_exec_MessageComplete: ");
    68 	asm("_asm_exec_MessageComplete: ");
    69 
    69 
    70 #ifdef BTRACE_CLIENT_SERVER
    70 #ifdef BTRACE_CLIENT_SERVER
    71 	asm("stmfd sp!,{r0,r1,ip,lr}");
    71 	asm("stmfd sp!,{r0,r1,ip,lr}");
    72 	asm("mov r2,r1");							// arg2 = aReason
    72 	asm("mov r2,r1");															// arg2 = aReason
    73 	asm("mov r1,r0");							// arg1 = aMsg
    73 	asm("mov r1,r0");															// arg1 = aMsg
    74 	asm("ldr r0,_messageCompleteTraceHeader");	// arg0 = header
    74 	asm("ldr r0,_messageCompleteTraceHeader");									// arg0 = header
    75 	asm("bl " CSM_ZN6BTrace4OutXEmmmm);
    75 	asm("bl " CSM_ZN6BTrace4OutXEmmmm);
    76 	asm("ldmfd sp!,{r0,r1,ip,lr}");
    76 	asm("ldmfd sp!,{r0,r1,ip,lr}");
    77 #endif
    77 #endif
    78 
    78 
    79 	asm("cmp ip, #%a0" : : "i" (RMessage2::EDisConnect));
    79 	asm("cmp ip, #%a0" : : "i" (RMessage2::EDisConnect));
    80 	asm("ldreq r0, [r0, #%a0]" : : "i" _FOFF(RMessageK,iSession));
    80 	asm("ldreq r0, [r0, #%a0]" : : "i" _FOFF(RMessageK,iSession));
    81 	asm("beq " CSM_ZN8DSession19CloseFromDisconnectEv );	// if disconnect, do it in C++
    81 	asm("beq " CSM_ZN8DSession19CloseFromDisconnectEv );						// if disconnect, do it in C++
    82 	asm("mov r2, r1 ");					// r2=aReason
    82 
       
    83 	asm("mov r2, r1 ");															// r2 = aReason
    83 	ASM_DEBUG2(Complete,r0,r2);
    84 	ASM_DEBUG2(Complete,r0,r2);
    84 	asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(RMessageK, iSession)); 	// r3=iSession
    85 	asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(RMessageK, iSession)); 				// r3 = iSession
    85 	
    86 	asm("subs r1, ip, #%a0" : : "i" (RMessage2::EConnect));						// (m.iFunction == RMessage2::EConnect)?
    86 	asm("subs r1, ip, #%a0" : : "i" (RMessage2::EConnect));		// (m.iFunction == RMessage2::EConnect)?
    87 	asm("streq r1, [r3, #%a0] " : : "i" _FOFF(DSession, iConnectMsgPtr));		// iSession->iConnectMsgPtr = NULL
    87 	asm("streq r1, [r3, #%a0] " : : "i" _FOFF(DSession, iConnectMsgPtr));	// iSession->iConnectMsgPtr = NULL
    88 	asm("ldr r1, [r3, #%a0]" : : "i" _FOFF(DSession,iAccessCount));				// r1 = iSession->iAccessCount	
    88 
    89 	asm("cmp r1, #0 ");															// iAccessCount = 0?
    89 	asm("ldr r1, [r3, #%a0]" : : "i" _FOFF(DSession,iAccessCount));	// r1=iSession->iAccessCount	
       
    90 	asm("cmp r1, #0 ");					// iAccessCount = 0?
       
    91 	asm("beq 2f ");
    90 	asm("beq 2f ");
    92 
    91 
    93 	// if (!s->IsClosing())
    92 	// !s->IsClosing()
    94 	asm("mov r1, r0");					// r1 = RMessageK ptr
    93 	asm("mov r1, r0");															// r1 = RMessageK ptr
    95 	asm("ldr r0, [r0, #%a0] " : : "i" _FOFF(RMessageK,iClient));    // r0=iClient
    94 	asm("ldr r0, [r0, #%a0] " : : "i" _FOFF(RMessageK,iClient));    			// r0 = iClient
       
    95 	asm("ldrb ip, [r0, #%a0] " : : "i" _FOFF(DThread,iMState));    				// ip = iClient->iMState
       
    96 	asm("cmp ip, #%a0" : : "i" (DThread::EDead));								// (iMState == EDead)?
       
    97 	asm("beq 1f ");
       
    98 
       
    99 	// if (!s->IsClosing() && m.iClient->iMState != DThread::EDead)
    96 	asm("mov ip, #1");
   100 	asm("mov ip, #1");
    97 	asm("str ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iServerLink.iNext));	// iServerLink.iNext=1
   101 	asm("str ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iServerLink.iNext));		// iServerLink.iNext=1
    98 	asm("b " CSM_ZN4Kern20QueueRequestCompleteEP7DThreadP14TClientRequesti);
   102 	asm("b " CSM_ZN4Kern20QueueRequestCompleteEP7DThreadP14TClientRequesti);	// tail call
    99 
   103 
   100 	// if (s->IsClosing())
   104 	// m.iClient->iMState == DThread::EDead
       
   105 	asm("1: ");																	// shuffle RMessageK and iFunction back to expected registers
       
   106 	asm("ldr ip, [r1, #%a0]" : : "i" _FOFF(RMessageK, iFunction));				// refetch iFunction
       
   107 	asm("mov r0, r1");															// r0 = RMessageK ptr
       
   108 
       
   109 	// else (closing or dead)
   101 	asm("2: ");
   110 	asm("2: ");
   102 	asm("cmp ip, #%a0" : : "i" (RMessage2::EConnect));	// (m.iFunction == RMessage2::EConnect)?
   111 	asm("cmp ip, #%a0" : : "i" (RMessage2::EConnect));							// (m.iFunction == RMessage2::EConnect)?
   103 	asm("beq 4f ");
   112 	asm("bne 3f ");
   104 	asm("3: ");
   113 
   105 	asm("stmfd sp!, {r0,lr} ");
   114 	// (closing or dead) and it's a connect msg
   106 	asm("bl " CSM_ZN14TClientRequest5ResetEv);
   115 	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));			// r2=iSession->iSessionCookie
   107 	asm("ldmfd sp!, {r0,lr} ");
       
   108 	asm("b " CSM_ZN9RMessageK8CloseRefEv);
       
   109 
       
   110 	asm("4: ");
       
   111 	// if closing & connect msg
       
   112 	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));	// r2=iSession->iSessionCookie
       
   113 	asm("teq r2, #0");
   116 	asm("teq r2, #0");
   114 #ifdef _DEBUG
   117 #ifdef _DEBUG
   115 	asm("beq nosession ");
   118 	asm("beq nosession ");
   116 	asm("ldr r1, [r3, #%a0] " : : "i" _FOFF(DSession, iServer));		// r1=iSession->iServer
   119 	asm("ldr r1, [r3, #%a0] " : : "i" _FOFF(DSession, iServer));				// r1=iSession->iServer
   117 	asm("cmp r1, #0 ");
   120 	asm("cmp r1, #0 ");
   118  	asm("beq noserver ");
   121  	asm("beq noserver ");
   119 	asm("ldr r2, [r3, #%a0] " : : "i" (_FOFF(DSession, iDisconnectMsgPtr)));  // r2=iSession->iDisconnectMsgPtr
   122 	asm("ldr r2, [r3, #%a0] " : : "i" (_FOFF(DSession, iDisconnectMsgPtr)));	// r2=iSession->iDisconnectMsgPtr
   120 	asm("ldr r2, [r2, #%a0] " : : "i" (_FOFF(RMessageK, iServerLink.iNext)));	// r2=iDisconnectMsgPtr->iServerLink.iNext
   123 	asm("ldr r2, [r2, #%a0] " : : "i" (_FOFF(RMessageK, iServerLink.iNext)));	// r2=iDisconnectMsgPtr->iServerLink.iNext
   121 	asm("cmp r2, #0 ");
   124 	asm("cmp r2, #0 ");
   122 	asm("beq __FaultMsgCompleteDiscNotSent ");	// die if a session has been created and no disc msg sent
   125 	asm("beq __FaultMsgCompleteDiscNotSent ");									// tail call to die if a session has been created and no disc msg sent
   123 	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));	// r2=iSession->iSessionCookie
   126 	asm("ldr r2, [r3, #%a0] " : : "i" _FOFF(DSession, iSessionCookie));			// r2=iSession->iSessionCookie
   124 	asm("noserver: ");
   127 	asm("noserver: ");
   125 	asm("teq r2, #0");
   128 	asm("teq r2, #0");
   126 	asm("nosession: ");
   129 	asm("nosession: ");
   127 #endif //_DEBUG
   130 #endif //_DEBUG
   128 	asm("moveq r0, r3 ");
   131 	asm("moveq r0, r3 ");
   129 	asm("beq __SendDiscMsg ");	// if no session object to clean up, send disc msg in C++
   132 	asm("beq __SendDiscMsg ");													// if no session object to clean up, tail call to send disc msg in C++
   130 	asm("b 3b ");				// return
   133 
       
   134 	asm("3: ");
       
   135 	asm("stmfd sp!, {r0,lr} ");
       
   136 	asm("bl " CSM_ZN14TClientRequest5ResetEv);
       
   137 	asm("ldmfd sp!, {r0,lr} ");
       
   138 	asm("b " CSM_ZN9RMessageK8CloseRefEv);										// tail call
   131 
   139 
   132 #ifdef BTRACE_CLIENT_SERVER
   140 #ifdef BTRACE_CLIENT_SERVER
   133 	asm("_messageCompleteTraceHeader:");
   141 	asm("_messageCompleteTraceHeader:");
   134 	asm(".word %a0" : : "i" (BTRACE_HEADER_C(12,BTrace::EClientServer,BTrace::EMessageComplete)));
   142 	asm(".word %a0" : : "i" (BTRACE_HEADER_C(12,BTrace::EClientServer,BTrace::EMessageComplete)));
   135 	asm("_messageDeliverTraceHeader:");
   143 	asm("_messageDeliverTraceHeader:");
   356 #else
   364 #else
   357 	asm("ldr r1, [r1, #%a0]" : : "i" _FOFF(TScheduler,iCurrentThread));
   365 	asm("ldr r1, [r1, #%a0]" : : "i" _FOFF(TScheduler,iCurrentThread));
   358 #endif
   366 #endif
   359 	asm("ldr r1, [r1, #%a0]" : : "i" (_FOFF(DThread,iOwningProcess)-_FOFF(DThread,iNThread)));	// r1->process to check
   367 	asm("ldr r1, [r1, #%a0]" : : "i" (_FOFF(DThread,iOwningProcess)-_FOFF(DThread,iNThread)));	// r1->process to check
   360 	asm("bl do_messagek ");
   368 	asm("bl do_messagek ");
       
   369 	asm("bcc 0f ");														// if bad handle, panic
   361 	asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(RMessageK,iFunction));		// ip = function
   370 	asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(RMessageK,iFunction));		// ip = function
   362 	asm("bcc 0f ");														// if bad handle, panic
       
   363 	asm("cmp ip, #%a0" : : "i" ((TInt)RMessage2::EDisConnect));			// check iFunction != RMessage2::EDisConnect
   371 	asm("cmp ip, #%a0" : : "i" ((TInt)RMessage2::EDisConnect));			// check iFunction != RMessage2::EDisConnect
   364 	asm("ldmnefd sp!, {r4,pc} ");										// if not, return OK
   372 	asm("ldmnefd sp!, {r4,pc} ");										// if not, return OK
   365 	asm("0: ");
   373 	asm("0: ");
   366 	asm("mov r0, #%a0" : : "i" (EBadMessageHandle));					// panic, disconnect not allowed
   374 	asm("mov r0, #%a0" : : "i" (EBadMessageHandle));					// panic, disconnect not allowed
   367 	asm("b  " CSM_ZN1K18PanicCurrentThreadEi);
   375 	asm("b  " CSM_ZN1K18PanicCurrentThreadEi);