kernel/eka/memmodel/epoc/multiple/x86/xmmu.cia
changeset 0 a41df078684a
--- /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");
+	}
+
+