sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\memmodel\epoc\multiple\x86\xmmu.cia sl@0: // sl@0: // sl@0: sl@0: #include sl@0: sl@0: #if defined(KMMU) sl@0: extern "C" void __DebugMsgFlushTLB(); sl@0: extern "C" void __DebugMsgLocalFlushTLB(); sl@0: extern "C" void __DebugMsgTotalFlushTLB(); sl@0: extern "C" void __DebugMsgINVLPG(int a); sl@0: #endif sl@0: sl@0: sl@0: extern "C" sl@0: { sl@0: sl@0: sl@0: __NAKED__ void __fastcall DoInvalidateTLBForPage(TLinAddr /*aLinAddr*/) sl@0: // sl@0: // Flush a specified virtual address from the TLB. sl@0: // sl@0: { sl@0: ASM_DEBUG1(INVLPG,ecx) sl@0: asm("invlpg [ecx]"); sl@0: asm("ret"); sl@0: } sl@0: sl@0: // On 486 and Pentium this invalidates all TLB entries. sl@0: // On P6 and later CPUs it only invalidates non-global TLB entries. sl@0: __NAKED__ void DoLocalInvalidateTLB() sl@0: { sl@0: ASM_DEBUG0(LocalFlushTLB) sl@0: asm("mov eax, cr3"); sl@0: asm("mov cr3, eax"); sl@0: asm("ret"); sl@0: } sl@0: sl@0: // This function is only used on P6 and later CPUs. sl@0: // It invalidates all TLB entries, including global ones. sl@0: extern "C" __NAKED__ void DoTotalInvalidateTLB() sl@0: { sl@0: ASM_DEBUG0(TotalFlushTLB) sl@0: asm("pushfd"); sl@0: asm("mov eax, cr3"); sl@0: MOV_ECX_CR4; sl@0: asm("mov edx, ecx"); sl@0: asm("and dl, 0x7f"); sl@0: asm("cli"); sl@0: MOV_CR4_EDX; sl@0: asm("mov cr3, eax"); sl@0: MOV_CR4_ECX; sl@0: asm("popfd"); sl@0: asm("ret"); sl@0: } sl@0: sl@0: // Invalidate all TLB entries regardless of CPU type. sl@0: __NAKED__ void DoInvalidateTLB() sl@0: { sl@0: ASM_DEBUG0(FlushTLB) sl@0: asm("mov edx, [%a0]": : "i"(&X86_UseGlobalPTEs)); sl@0: asm("mov eax, cr3"); sl@0: asm("cmp edx, 0"); sl@0: asm("jz no_global_pages"); sl@0: MOV_ECX_CR4; sl@0: asm("mov edx, ecx"); sl@0: asm("and dl, 0x7f"); sl@0: asm("pushfd"); sl@0: asm("cli"); sl@0: MOV_CR4_EDX; sl@0: asm("mov cr3, eax"); sl@0: MOV_CR4_ECX; sl@0: asm("popfd"); sl@0: asm("ret"); sl@0: asm("no_global_pages:"); sl@0: asm("mov cr3, eax"); sl@0: asm("ret"); sl@0: } sl@0: } sl@0: sl@0: __NAKED__ void DMemModelThread::RestoreAddressSpace() sl@0: { sl@0: #ifndef __SMP__ sl@0: //SMP FIXME sl@0: asm("mov eax, [%a0]": : "i"(&TheScheduler.iCurrentThread)); sl@0: sl@0: // edx = current thread owning process... sl@0: asm("mov edx, 0"); sl@0: asm("lea edx, [edx+%0]": : "i"_FOFF(DThread,iNThread)); sl@0: asm("neg edx"); sl@0: asm("mov edx, [eax+edx+%0]": : "i"_FOFF(DThread,iOwningProcess)); sl@0: sl@0: // update page directory and address space values... sl@0: asm("cli"); sl@0: asm("mov [%a0], edx": :"i"(&TheScheduler.iAddressSpace)); sl@0: asm("mov [eax+%0], edx": : "i"_FOFF(NThreadBase,iAddressSpace)); sl@0: asm("mov edx, [edx+%0]": : "i"_FOFF(DMemModelProcess,iGlobalPageDir)); sl@0: asm("mov cr3, edx"); sl@0: asm("sti"); sl@0: #endif sl@0: asm("ret"); sl@0: } sl@0: sl@0: