kernel/eka/memmodel/epoc/flexible/arm/xipc.cia
changeset 0 a41df078684a
child 109 b3a1d9898418
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1997-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 //
       
    15 
       
    16 #define INCLUDED_FROM_ASM
       
    17 
       
    18 #include <e32cia.h>
       
    19 #include <arm_mem.h>
       
    20 #include "xdefs.h"
       
    21 
       
    22 #ifdef _DEBUG
       
    23 #define ASM_KILL_LINK(rp,rs)	asm("mov "#rs", #0xdf ");\
       
    24 								asm("orr "#rs", "#rs", "#rs", lsl #8 ");\
       
    25 								asm("orr "#rs", "#rs", "#rs", lsl #16 ");\
       
    26 								asm("str "#rs", ["#rp"] ");\
       
    27 								asm("str "#rs", ["#rp", #4] ");
       
    28 #else
       
    29 #define ASM_KILL_LINK(rp,rs)
       
    30 #endif
       
    31 
       
    32 #ifdef _DEBUG
       
    33 extern "C" void __FaultIpcClientNotNull();  // defined in ckernel.cpp
       
    34 #endif
       
    35 
       
    36 
       
    37 __NAKED__ TInt DThread::ReadAndParseDesHeader(const TAny* aSrc, TDesHeader& aDest)
       
    38 	{
       
    39 	ASM_ASSERT_PAGING_SAFE;
       
    40 	// save state including 'this', aSrc and sDest. Double word aligns the stack 
       
    41 	// which is required to call c++ functions.
       
    42 	asm("stmdb sp!, {r0-r2, r4-r8, r10, lr} ");
       
    43 
       
    44 	// Register use this method:
       
    45 	// r0 = 'this' until iIpcClient set.
       
    46 	// r1 = aSrc until read_and_parse_des_header_local.
       
    47 	// r2 = aDest until read_and_parse_des_header_local.
       
    48 	// r4 = target process
       
    49 	// r5 = current nthread
       
    50 	// r6 = scheduler.
       
    51 	// r7 = current process 
       
    52 	// r8 = orig ttbr0
       
    53 	// r10 = os asid of current process.
       
    54 
       
    55 	// Open a reference on the target process's os asid as we will be switching to
       
    56 	// it so it can't be allowed to be freed and/or reused.
       
    57 	asm("ldr r4, [r0, #%a0]" : : "i" _FOFF(DThread,iOwningProcess));		// r4->target process
       
    58 	asm("bl " CSM_ZN5NKern13ThreadEnterCSEv);	// First enter a critical section so can't leak os asid reference.
       
    59 	asm("mov r0, r4");		// r0 = target process ('this' for TryOpenOsAsid() below).
       
    60 	asm("bl " CSM_ZN16DMemModelProcess13TryOpenOsAsidEv);
       
    61 	// Check a reference could be opened on target process's os asid, failed if r0 < 0.
       
    62 	asm("cmp r0, #0");
       
    63 	asm("bmi readParseDesHeader_ExitErr");
       
    64 
       
    65 	asm("mov r10, r0");			// r10 = os asid of current process
       
    66 	asm("ldmia sp!, {r0-r2}");	// r0 = this, r1 = aSrc, r2 = aDest
       
    67 	
       
    68 	__ASM_CLI(); // disable all interrupts
       
    69 #ifdef __SMP__
       
    70 	GET_RWNO_TID(,r6);														// r6->TSubScheduler
       
    71 	asm("ldr r7, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iAddressSpace));	// r7->current process
       
    72 	asm("ldr r5, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iCurrentThread));	// r5->current NThreadBase
       
    73 #else
       
    74 	asm("ldr r6, __TheScheduler ");											// r6->TheScheduler
       
    75 	asm("ldr r7, [r6, #%a0]" : : "i" _FOFF(TScheduler,iAddressSpace));		// r7->current process
       
    76 	asm("ldr r5, [r6, #%a0]" : : "i" _FOFF(TScheduler,iCurrentThread));		// r5->current NThreadBase
       
    77 #endif
       
    78 
       
    79 	// set TheCurrentThread->iIpcClient to this (r0) thread
       
    80 #ifdef _DEBUG
       
    81 	asm("ldr r12, [r5, #%a0] " : : "i" (_FOFF(DThread, iIpcClient) - _FOFF(DThread, iNThread)));
       
    82 	asm("teq r12, #0 ");
       
    83 	asm("bne __FaultIpcClientNotNull ");
       
    84 #endif
       
    85 	asm("str r0, [r5, #%a0] " : : "i" (_FOFF(DThread, iIpcClient) - _FOFF(DThread, iNThread)));
       
    86 
       
    87 	// switch address space to process r4...
       
    88 	asm("mrc p15, 0, r8, c2, c0, 0 ");		// r8 = original TTBR0
       
    89 	asm("ldr r0, [r4, #%a0]" : : "i" _FOFF(DMemModelProcess,iPageDir));		// r0->target process page directory
       
    90 	asm("and lr, r8, #%a0" : : "i" ((TInt)KTTBRExtraBitsMask));	// lr = TTBR0 extra bits
       
    91 	asm("orr r0, r0, lr ");					// r0 = target process page directory + extra bits
       
    92 
       
    93 	__ASM_SET_ADDRESS_SPACE(r10,r0,lr);
       
    94 #ifdef __SMP__
       
    95 	asm("str r4, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iAddressSpace));
       
    96 #else
       
    97 	asm("str r4, [r6, #%a0]" : : "i" _FOFF(TScheduler,iAddressSpace));
       
    98 #endif
       
    99 	asm("str r4, [r5, #%a0]" : : "i" _FOFF(NThread,iAddressSpace));
       
   100 	__ASM_STI(); // enable all interrupts
       
   101 
       
   102 	// read and parse descriptor header, r1=aSrc, r2=aDest
       
   103 	asm("bl read_and_parse_des_header_local");	// defined in e32/kernel/arm/cipc.cia
       
   104 		
       
   105 	// restore address space to process r7...
       
   106 	asm("ldr r12, [r7, #%a0]" : : "i" _FOFF(DMemModelProcess,iOsAsid));		// r12 = current process ASID
       
   107 
       
   108 	__ASM_CLI(); // disable all interrupts
       
   109 	__ASM_SET_ADDRESS_SPACE(r12,r8,lr);
       
   110 #ifdef __SMP__
       
   111 	GET_RWNO_TID(,r6);														// r6->TSubScheduler
       
   112 	asm("str r7, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iAddressSpace));
       
   113 #else
       
   114 	asm("str r7, [r6, #%a0]" : : "i" _FOFF(TScheduler,iAddressSpace));
       
   115 #endif
       
   116 	asm("str r7, [r5, #%a0]" : : "i" _FOFF(NThread,iAddressSpace));
       
   117 	__ASM_STI(); // enable all interrupts
       
   118 
       
   119 	// set TheCurrentThread->iIpcClient to NULL again
       
   120 	asm("mov r12, #0 ");
       
   121 	asm("str r12, [r5, #%a0] " : : "i" (_FOFF(DThread, iIpcClient) - _FOFF(DThread, iNThread)));
       
   122 
       
   123 	// close the reference on the target process's os asid.
       
   124 	asm("mov r6, r0");	// r6 = return value from read_and_parse_des_header_local
       
   125 	asm("mov r0, r4");	// r0 = target process
       
   126 	asm("bl " CSM_ZN16DMemModelProcess11CloseOsAsidEv);
       
   127 	
       
   128 	// finished...
       
   129 	asm("bl " CSM_ZN5NKern13ThreadLeaveCSEv);	// Os asid reference closed so leave critical section.
       
   130 	asm("mov r0, r6");			// r0 = return value from read_and_parse_des_header_local.
       
   131 	__POPRET("r4-r8, r10, ");	// Restore the state and return.
       
   132 
       
   133 	// exit with error...
       
   134 	asm("readParseDesHeader_ExitErr:");
       
   135 	asm("bl " CSM_ZN5NKern13ThreadLeaveCSEv);	// Os asid reference not open so leave critical section.
       
   136 	asm("mov r0, #%a0" : : "i" ((TInt)KErrBadDescriptor));
       
   137 	asm("add sp, sp, #12");	// pop r0-r2 off the stack.
       
   138 	__POPRET("r4-r8, r10, ");	// Restore the state and return.
       
   139 
       
   140 #ifndef __SMP__
       
   141 	asm("__TheScheduler: ");
       
   142 	asm(".word TheScheduler ");
       
   143 #endif
       
   144 	}
       
   145