NMI Support Patch 5:

[HAL]: Do correct TLB flushing for systems with global page support.
    [HAL]: Clean leading whitespace and comments.


svn path=/trunk/; revision=44856
This commit is contained in:
ReactOS Portable Systems Group
2010-01-01 16:37:34 +00:00
parent 61df639e4a
commit 8266b754b6
3 changed files with 192 additions and 51 deletions
+128 -51
View File
@@ -14,12 +14,27 @@
/* GLOBALS ********************************************************************/
//
// PTE Data
//
ULONG HalpSavedPfn;
HARDWARE_PTE HalpSavedPte;
//
// IDT Data
//
PVOID HalpGpfHandler;
PVOID HalpBopHandler;
//
// TSS Data
//
ULONG HalpSavedEsp0;
USHORT HalpSavedTss;
//
// IOPM Data
//
USHORT HalpSavedIopmBase;
PUSHORT HalpSavedIoMap;
USHORT HalpSavedIoMapData[32][2];
@@ -184,47 +199,65 @@ HalpMapRealModeMemory(VOID)
{
PHARDWARE_PTE Pte, V86Pte;
ULONG i;
/* Get the page table directory for the lowest meg of memory */
//
// Get the page table directory for the lowest meg of memory
//
Pte = HalAddressToPde(0);
HalpSavedPfn = Pte->PageFrameNumber;
HalpSavedPte = *Pte;
/* Map it to the HAL reserved region and make it valid */
//
// Map it to the HAL reserved region and make it valid
//
Pte->Valid = 1;
Pte->Write = 1;
Pte->Owner = 1;
Pte->PageFrameNumber = (HalAddressToPde(0xFFC00000))->PageFrameNumber;
/* Flush the TLB by resetting CR3 */
__writecr3(__readcr3());
/* Now loop the first meg of memory */
//
// Flush the TLB
//
HalpFlushTLB();
//
// Now loop the first meg of memory
//
for (i = 0; i < 0x100000; i += PAGE_SIZE)
{
/* Identity map it */
//
// Identity map it
//
Pte = HalAddressToPte(i);
Pte->PageFrameNumber = i >> PAGE_SHIFT;
Pte->Valid = 1;
Pte->Write = 1;
Pte->Owner = 1;
}
/* Now get the entry for our real mode V86 code and the target */
//
// Now get the entry for our real mode V86 code and the target
//
Pte = HalAddressToPte(0x20000);
V86Pte = HalAddressToPte(&HalpRealModeStart);
do
{
/* Map the physical address into our real-mode region */
//
// Map the physical address into our real-mode region
//
Pte->PageFrameNumber = V86Pte->PageFrameNumber;
/* Keep going until we've reached the end of our region */
//
// Keep going until we've reached the end of our region
//
Pte++;
V86Pte++;
} while (V86Pte <= HalAddressToPte(&HalpRealModeEnd));
/* Flush the TLB by resetting CR3 */
__writecr3(__readcr3());
//
// Flush the TLB
//
HalpFlushTLB();
}
VOID
@@ -252,18 +285,26 @@ VOID
NTAPI
HalpSetupRealModeIoPermissionsAndTask(VOID)
{
/* Switch to valid TSS */
//
// Switch to valid TSS
//
HalpBorrowTss();
/* Save a copy of the I/O Map and delete it */
//
// Save a copy of the I/O Map and delete it
//
HalpSavedIoMap = (PUSHORT)&(KeGetPcr()->TSS->IoMaps[0]);
HalpStoreAndClearIopm();
/* Save the IOPM and switch to the real-mode one */
//
// Save the IOPM and switch to the real-mode one
//
HalpSavedIopmBase = KeGetPcr()->TSS->IoMapBase;
KeGetPcr()->TSS->IoMapBase = KiComputeIopmOffset(1);
/* Save our stack pointer */
//
// Save our stack pointer
//
HalpSavedEsp0 = KeGetPcr()->TSS->Esp0;
}
@@ -282,16 +323,24 @@ VOID
NTAPI
HalpRestoreIoPermissionsAndTask(VOID)
{
/* Restore the stack pointer */
//
// Restore the stack pointer
//
KeGetPcr()->TSS->Esp0 = HalpSavedEsp0;
/* Restore the I/O Map */
//
// Restore the I/O Map
//
HalpRestoreIopm();
/* Restore the IOPM */
//
// Restore the IOPM
//
KeGetPcr()->TSS->IoMapBase = HalpSavedIopmBase;
/* Restore the TSS */
//
// Restore the TSS
//
if (HalpSavedTss) HalpReturnTss();
}
@@ -302,24 +351,32 @@ HalpUnmapRealModeMemory(VOID)
ULONG i;
PHARDWARE_PTE Pte;
/* Loop the first meg of memory */
//
// Loop the first meg of memory
//
for (i = 0; i < 0x100000; i += PAGE_SIZE)
{
/* Invalidate each PTE */
//
// Invalidate each PTE
//
Pte = HalAddressToPte(i);
Pte->Valid = 0;
Pte->Write = 0;
Pte->Owner = 0;
Pte->PageFrameNumber = 0;
}
/* Restore the PDE for the lowest megabyte of memory */
//
// Restore the PDE for the lowest megabyte of memory
//
Pte = HalAddressToPde(0);
*Pte = HalpSavedPte;
Pte->PageFrameNumber = HalpSavedPfn;
/* Flush the TLB by resetting CR3 */
__writecr3(__readcr3());
//
// Flush the TLB
//
HalpFlushTLB();
}
BOOLEAN
@@ -330,43 +387,63 @@ HalpBiosDisplayReset(VOID)
PHARDWARE_PTE IdtPte;
BOOLEAN RestoreWriteProtection = FALSE;
/* Disable interrupts */
//
// Disable interrupts
//
Flags = __readeflags();
_disable();
/* Map memory available to the V8086 real-mode code */
//
// Map memory available to the V8086 real-mode code
//
HalpMapRealModeMemory();
/*
* On P5, the first 7 entries of the IDT are write protected to work around
* the cmpxchg8b lock errata. Unprotect them here so we can set our custom
* invalid op-code handler.
*/
//
// On P5, the first 7 entries of the IDT are write protected to work around
// the cmpxchg8b lock errata. Unprotect them here so we can set our custom
// invalid op-code handler.
//
IdtPte = HalAddressToPte(((PKIPCR)KeGetPcr())->IDT);
RestoreWriteProtection = IdtPte->Write;
/* Use special invalid opcode and GPF trap handlers */
//
// Use special invalid opcode and GPF trap handlers
//
HalpSwitchToRealModeTrapHandlers();
/* Configure the IOPM and TSS */
//
// Configure the IOPM and TSS
//
HalpSetupRealModeIoPermissionsAndTask();
/* Now jump to real mode */
//
// Now jump to real mode
//
HalpBiosCall();
/* Restore kernel trap handlers */
//
// Restore kernel trap handlers
//
HalpRestoreTrapHandlers();
/* Restore write permission */
//
// Restore write permission
//
IdtPte->Write = RestoreWriteProtection;
/* Restore TSS and IOPM */
//
// Restore TSS and IOPM
//
HalpRestoreIoPermissionsAndTask();
/* Restore low memory mapping */
//
// Restore low memory mapping
//
HalpUnmapRealModeMemory();
/* Restore interrupts if they were previously enabled */
//
// Restore interrupts if they were previously enabled
//
__writeeflags(Flags);
return TRUE;
}
+60
View File
@@ -43,6 +43,66 @@ HalpUnmapVirtualAddress(IN PVOID VirtualAddress,
MmUnmapIoSpace(VirtualAddress, NumberPages << PAGE_SHIFT);
}
VOID
NTAPI
HalpFlushTLB(VOID)
{
ULONG Flags, Cr4;
INT CpuInfo[4];
ULONG_PTR PageDirectory;
//
// Disable interrupts
//
Flags = __readeflags();
_disable();
//
// Get page table directory base
//
PageDirectory = __readcr3();
//
// Check for CPUID support
//
if (KeGetCurrentPrcb()->CpuID)
{
//
// Check for global bit in CPU features
//
__cpuid(CpuInfo, 1);
if (CpuInfo[3] & 0x2000)
{
//
// Get current CR4 value
//
Cr4 = __readcr4();
//
// Disable global pit
//
__writecr4(Cr4 & ~CR4_PGE);
//
// Flush TLB and re-enable global bit
//
__writecr3(PageDirectory);
__writecr4(Cr4);
//
// Restore interrupts
//
__writeeflags(Flags);
}
}
//
// Legacy: just flush TLB
//
__writecr3(PageDirectory);
__writeeflags(Flags);
}
/* FUNCTIONS *****************************************************************/
/*
+4
View File
@@ -106,6 +106,10 @@ VOID HalpInitPhase1(VOID);
VOID NTAPI HalpClockInterrupt(VOID);
VOID NTAPI HalpProfileInterrupt(VOID);
VOID
NTAPI
HalpFlushTLB(VOID);
//
// KD Support
//