os/kernelhwsrv/kernel/eka/memmodel/epoc/flexible/mmu/x86/xmmu.cia
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200 (2012-06-15)
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <x86_mem.h>
sl@0
    17
sl@0
    18
#if defined(KMMU)
sl@0
    19
extern "C" void __DebugMsgFlushTLB();
sl@0
    20
extern "C" void __DebugMsgLocalFlushTLB();
sl@0
    21
extern "C" void __DebugMsgTotalFlushTLB();
sl@0
    22
extern "C" void __DebugMsgINVLPG(int a);
sl@0
    23
#endif
sl@0
    24
sl@0
    25
sl@0
    26
__NAKED__ void __fastcall DoInvalidateTLBForPage(TLinAddr /*aLinAddr*/)
sl@0
    27
//
sl@0
    28
// Flush a specified virtual address from the TLB.
sl@0
    29
//
sl@0
    30
	{
sl@0
    31
	ASM_DEBUG1(INVLPG,ecx)
sl@0
    32
	asm("invlpg [ecx]");
sl@0
    33
	asm("ret");
sl@0
    34
	}
sl@0
    35
sl@0
    36
// On 486 and Pentium this invalidates all TLB entries.
sl@0
    37
// On P6 and later CPUs it only invalidates non-global TLB entries.
sl@0
    38
__NAKED__ void DoLocalInvalidateTLB()
sl@0
    39
	{
sl@0
    40
	ASM_DEBUG0(LocalFlushTLB)
sl@0
    41
	asm("mov eax, cr3");
sl@0
    42
	asm("mov cr3, eax");
sl@0
    43
	asm("ret");
sl@0
    44
	}
sl@0
    45
sl@0
    46
// Invalidate all TLB entries regardless of CPU type.
sl@0
    47
__NAKED__ void DoInvalidateTLB()
sl@0
    48
	{
sl@0
    49
	ASM_DEBUG0(FlushTLB)
sl@0
    50
	asm("mov edx, [%a0]": : "i"(&X86_UseGlobalPTEs));
sl@0
    51
	asm("mov eax, cr3");
sl@0
    52
	asm("cmp edx, 0");
sl@0
    53
	asm("jz no_global_pages");
sl@0
    54
	MOV_ECX_CR4;
sl@0
    55
	asm("mov edx, ecx");
sl@0
    56
	asm("and dl, 0x7f");
sl@0
    57
	asm("pushfd");
sl@0
    58
	asm("cli");
sl@0
    59
	MOV_CR4_EDX;
sl@0
    60
	asm("mov cr3, eax");
sl@0
    61
	MOV_CR4_ECX;
sl@0
    62
	asm("popfd");
sl@0
    63
	asm("ret");
sl@0
    64
	asm("no_global_pages:");
sl@0
    65
	asm("mov cr3, eax");
sl@0
    66
	asm("ret");
sl@0
    67
	}
sl@0
    68
sl@0
    69
__NAKED__ void __fastcall UserWriteFault(TLinAddr /*aAddr*/)
sl@0
    70
	{
sl@0
    71
	// must use ES for writes because IpcExcHandler expects this...
sl@0
    72
	asm("push es");
sl@0
    73
	asm("mov eax, %0" : : "i"(RING3_DS));
sl@0
    74
	asm("mov es, ax");
sl@0
    75
	asm("mov es:[ecx], ecx");
sl@0
    76
	asm("pop es");
sl@0
    77
	asm("ret");
sl@0
    78
	}
sl@0
    79
sl@0
    80
__NAKED__ void __fastcall UserReadFault(TLinAddr /*aAddr*/)
sl@0
    81
	{	
sl@0
    82
	// must use DS for reads because IpcExcHandler expects this...
sl@0
    83
	asm("push ds");
sl@0
    84
	asm("mov eax, %0" : : "i"(RING3_DS));
sl@0
    85
	asm("mov ds, ax");
sl@0
    86
	asm("mov eax, [ecx]");
sl@0
    87
	asm("pop ds");
sl@0
    88
	asm("ret");
sl@0
    89
	}
sl@0
    90
sl@0
    91
#ifdef __SMP__
sl@0
    92
extern "C" __NAKED__ void __e32_instruction_barrier()
sl@0
    93
	{
sl@0
    94
	asm("push ebx ");
sl@0
    95
	asm("cpuid ");		// fully serializing instruction
sl@0
    96
	asm("pop ebx ");
sl@0
    97
	asm("ret ");
sl@0
    98
	}
sl@0
    99
#endif
sl@0
   100