kernel/eka/memmodel/epoc/multiple/arm/xipc.cia
changeset 9 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     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 #include <e32cia.h>
       
    17 #include <arm_mem.h>
       
    18 
       
    19 #ifdef _DEBUG
       
    20 #define ASM_KILL_LINK(rp,rs)	asm("mov "#rs", #0xdf ");\
       
    21 								asm("orr "#rs", "#rs", "#rs", lsl #8 ");\
       
    22 								asm("orr "#rs", "#rs", "#rs", lsl #16 ");\
       
    23 								asm("str "#rs", ["#rp"] ");\
       
    24 								asm("str "#rs", ["#rp", #4] ");
       
    25 #else
       
    26 #define ASM_KILL_LINK(rp,rs)
       
    27 #endif
       
    28 
       
    29 
       
    30 __NAKED__ TInt ThreadDoReadAndParseDesHeader(DThread* aThread, const TAny* aSrc, TUint32* aDest)
       
    31 	{
       
    32 	asm("stmdb sp!, {r4-r7, lr} ");	// stack unaligned, but we only call assembler
       
    33 
       
    34 #ifdef __SMP__
       
    35 	GET_RWNO_TID(,r6);														// r6->TSubScheduler - can't migrate since we hold system lock
       
    36 	asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(DThread,iOwningProcess));		// r3->target process
       
    37 	asm("ldr r4, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iAddressSpace));	// r4->current process
       
    38 	asm("ldr r5, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iCurrentThread));	// r5->current NThread
       
    39 #else
       
    40 	asm("ldr r6, __TheScheduler ");											// r6->TheScheduler
       
    41 	asm("ldr r3, [r0, #%a0]" : : "i" _FOFF(DThread,iOwningProcess));		// r3->target process
       
    42 	asm("ldr r4, [r6, #%a0]" : : "i" _FOFF(TScheduler,iAddressSpace));		// r4->current process
       
    43 	asm("ldr r5, [r6, #%a0]" : : "i" _FOFF(TScheduler,iCurrentThread));		// r5->current NThread
       
    44 #endif
       
    45 	
       
    46 	// set TheCurrentThread->iIpcClient to this thread
       
    47 #ifdef _DEBUG
       
    48 	asm("ldr r12, [r5, #%a0] " : : "i" (_FOFF(DThread, iIpcClient) - _FOFF(DThread, iNThread)));
       
    49 	asm("teq r12, #0 ");
       
    50 	asm("bne __FaultIpcClientNotNull ");
       
    51 #endif
       
    52 	asm("str r0, [r5, #%a0] " : : "i" (_FOFF(DThread, iIpcClient) - _FOFF(DThread, iNThread)));
       
    53 
       
    54 	// switch address space to process r3...
       
    55 	asm("mrc p15, 0, r7, c2, c0, 0 ");		// r7 = original TTBR0
       
    56 	asm("ldr r0, [r3, #%a0]" : : "i" _FOFF(DMemModelProcess,iLocalPageDir));	// r0->target process page directory
       
    57 	asm("ldr r12, [r3, #%a0]" : : "i" _FOFF(DMemModelProcess,iOsAsid));			// r12 = target ASID
       
    58 #ifdef __SMP__
       
    59 	__ASM_CLI();
       
    60 #else
       
    61 	CPSIDIF;								// disable all interrupts
       
    62 #endif
       
    63 	asm("mcr p15, 0, r12, c7, c10, 4 ");	// drain write buffer before changing MMU registers (see ARMv6 specs)
       
    64 	asm("and lr, r7, #%a0" : : "i" ((TInt)KTTBRExtraBitsMask));	// lr = TTBR0 extra bits
       
    65 	asm("orr lr, lr, r0 ");					// target process page directory + extra bits
       
    66 	UPDATE_PW_CACHING_ATTRIBUTES(,lr);		// ERRATUM 1136_317041
       
    67 	asm("mcr p15, 0, lr, c2, c0, 0 ");		// change TTBR0
       
    68 	asm("mcr p15, 0, r12, c13, c0, 1 ");	// change ASID
       
    69 
       
    70 #if defined(__CPU_ARM11MP__)
       
    71 	// On other platforms, tha ASID change above has already flushed the branch prediction buffers 
       
    72 	asm("mcr p15, 0, r12, c7, c5, 6 ");		// flush BTAC
       
    73 #endif
       
    74 
       
    75 #ifdef __SMP__
       
    76 	asm("str r3, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iAddressSpace));
       
    77 #else
       
    78 	asm("str r3, [r6, #%a0]" : : "i" _FOFF(TScheduler,iAddressSpace));
       
    79 #endif
       
    80 	asm("str r3, [r5, #%a0]" : : "i" _FOFF(NThread,iAddressSpace));
       
    81 #ifdef __SMP__
       
    82 	__ASM_STI();
       
    83 #else
       
    84 	CPSIEIF;								// enable all interrupts
       
    85 #endif
       
    86 	// read and parse the descriptor header
       
    87 	asm("bl read_and_parse_des_header_local");	// defined in e32/kernel/arm/cipc.cia
       
    88 		
       
    89 	// restore address space to process r4...
       
    90 	asm("ldr r12, [r4, #%a0]" : : "i" _FOFF(DMemModelProcess,iOsAsid));		// r12 = current process ASID
       
    91 #ifdef __SMP__
       
    92 	__ASM_CLI();
       
    93 #else
       
    94 	CPSIDIF;								// disable all interrupts
       
    95 #endif
       
    96 	asm("mcr p15, 0, r12, c7, c10, 4 ");	// drain write buffer before changing MMU registers (see ARMv6 specs)
       
    97 	UPDATE_PW_CACHING_ATTRIBUTES(,r7);		// ERRATUM 1136_317041
       
    98 	asm("mcr p15, 0, r7, c2, c0, 0 ");		// restore TTBR0
       
    99 	asm("mcr p15, 0, r12, c13, c0, 1 ");	// restore ASID
       
   100 
       
   101 #if defined(__CPU_ARM11MP__)
       
   102 	// On other platforms, the ASID change above has already flushed the branch prediction buffers 
       
   103 	asm("mcr p15, 0, r12, c7, c5, 6 ");		// flush BTAC
       
   104 #endif
       
   105 
       
   106 #ifdef __SMP__
       
   107 	asm("str r4, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iAddressSpace));
       
   108 #else
       
   109 	asm("str r4, [r6, #%a0]" : : "i" _FOFF(TScheduler,iAddressSpace));
       
   110 #endif
       
   111 	asm("str r4, [r5, #%a0]" : : "i" _FOFF(NThread,iAddressSpace));
       
   112 #ifdef __SMP__
       
   113 	__ASM_STI();
       
   114 #else
       
   115 	CPSIEIF;								// enable all interrupts
       
   116 #endif
       
   117 
       
   118 	// set TheCurrentThread->iIpcClient to NULL again
       
   119 	asm("mov r12, #0 ");
       
   120 	asm("str r12, [r5, #%a0] " : : "i" (_FOFF(DThread, iIpcClient) - _FOFF(DThread, iNThread)));
       
   121 	
       
   122 	// finished...
       
   123 	__POPRET("r4-r7,");
       
   124 
       
   125 #ifndef __SMP__
       
   126 	asm("__TheScheduler: ");
       
   127 	asm(".word TheScheduler ");
       
   128 #endif
       
   129 	}
       
   130