--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/memmodel/epoc/multiple/x86/xmmu.cia Mon Oct 19 15:55:17 2009 +0100
@@ -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 <x86_mem.h>
+
+#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");
+ }
+
+