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