mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 *****************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
@@ -106,6 +106,10 @@ VOID HalpInitPhase1(VOID);
|
||||
VOID NTAPI HalpClockInterrupt(VOID);
|
||||
VOID NTAPI HalpProfileInterrupt(VOID);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
HalpFlushTLB(VOID);
|
||||
|
||||
//
|
||||
// KD Support
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user