Fix for Bug 3159 - #include <rom\include\compsupp.iby> breaks linux GCCE builds in user.iby
// 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");
}