First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
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] ");
26 #define ASM_KILL_LINK(rp,rs)
30 __NAKED__ TInt ThreadDoReadAndParseDesHeader(DThread* aThread, const TAny* aSrc, TUint32* aDest)
32 asm("stmdb sp!, {r4-r7, lr} "); // stack unaligned, but we only call assembler
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
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
46 // set TheCurrentThread->iIpcClient to this thread
48 asm("ldr r12, [r5, #%a0] " : : "i" (_FOFF(DThread, iIpcClient) - _FOFF(DThread, iNThread)));
50 asm("bne __FaultIpcClientNotNull ");
52 asm("str r0, [r5, #%a0] " : : "i" (_FOFF(DThread, iIpcClient) - _FOFF(DThread, iNThread)));
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
61 CPSIDIF; // disable all interrupts
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
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
76 asm("str r3, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iAddressSpace));
78 asm("str r3, [r6, #%a0]" : : "i" _FOFF(TScheduler,iAddressSpace));
80 asm("str r3, [r5, #%a0]" : : "i" _FOFF(NThread,iAddressSpace));
84 CPSIEIF; // enable all interrupts
86 // read and parse the descriptor header
87 asm("bl read_and_parse_des_header_local"); // defined in e32/kernel/arm/cipc.cia
89 // restore address space to process r4...
90 asm("ldr r12, [r4, #%a0]" : : "i" _FOFF(DMemModelProcess,iOsAsid)); // r12 = current process ASID
94 CPSIDIF; // disable all interrupts
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
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
107 asm("str r4, [r6, #%a0]" : : "i" _FOFF(TSubScheduler,iAddressSpace));
109 asm("str r4, [r6, #%a0]" : : "i" _FOFF(TScheduler,iAddressSpace));
111 asm("str r4, [r5, #%a0]" : : "i" _FOFF(NThread,iAddressSpace));
115 CPSIEIF; // enable all interrupts
118 // set TheCurrentThread->iIpcClient to NULL again
120 asm("str r12, [r5, #%a0] " : : "i" (_FOFF(DThread, iIpcClient) - _FOFF(DThread, iNThread)));
126 asm("__TheScheduler: ");
127 asm(".word TheScheduler ");