Author: ros-arm-bringup
Date: Fri Jan 1 16:09:14 2010
New Revision: 44855
URL:
http://svn.reactos.org/svn/reactos?rev=44855&view=rev
Log:
NMI Support Patch 4:
[HAL]: Use Mm headers to support PTE/PDE address translation instead of a hardcoded,
homegrown macro. WARNING: The current HAL code is not PAE compatible (as it already
wasn't).
[NTOS]: Define an inline function to set and query an interrupt handler associated
with a given IDT vector. This results in much cleaner code as the uglyness of manually
setting up an IDT handler isn't duplicated 10 times. Additionally, it fixes some
callers which had not been using HalVectorToIDTEntry to make the initial translation.
Modified:
trunk/reactos/hal/halx86/generic/bios.c
trunk/reactos/hal/halx86/include/hal.h
trunk/reactos/hal/halx86/include/halp.h
trunk/reactos/ntoskrnl/include/internal/i386/ke.h
trunk/reactos/ntoskrnl/ke/i386/irqobj.c
Modified: trunk/reactos/hal/halx86/generic/bios.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/bios.c?…
==============================================================================
--- trunk/reactos/hal/halx86/generic/bios.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/generic/bios.c [iso-8859-1] Fri Jan 1 16:09:14 2010
@@ -16,17 +16,14 @@
ULONG HalpSavedPfn;
HARDWARE_PTE HalpSavedPte;
-ULONG HalpGpfHandler;
-ULONG HalpBopHandler;
+PVOID HalpGpfHandler;
+PVOID HalpBopHandler;
ULONG HalpSavedEsp0;
USHORT HalpSavedTss;
USHORT HalpSavedIopmBase;
PUSHORT HalpSavedIoMap;
USHORT HalpSavedIoMapData[32][2];
ULONG HalpSavedIoMapEntries;
-
-#define GetPdeAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 22) << 2) +
0xC0300000)
-#define GetPteAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 12) << 2) +
0xC0000000)
/* FUNCTIONS ******************************************************************/
@@ -189,7 +186,7 @@
ULONG i;
/* Get the page table directory for the lowest meg of memory */
- Pte = GetPdeAddress(0);
+ Pte = HalAddressToPde(0);
HalpSavedPfn = Pte->PageFrameNumber;
HalpSavedPte = *Pte;
@@ -197,7 +194,7 @@
Pte->Valid = 1;
Pte->Write = 1;
Pte->Owner = 1;
- Pte->PageFrameNumber = (GetPdeAddress(0xFFC00000))->PageFrameNumber;
+ Pte->PageFrameNumber = (HalAddressToPde(0xFFC00000))->PageFrameNumber;
/* Flush the TLB by resetting CR3 */
__writecr3(__readcr3());
@@ -206,7 +203,7 @@
for (i = 0; i < 0x100000; i += PAGE_SIZE)
{
/* Identity map it */
- Pte = GetPteAddress((PVOID)i);
+ Pte = HalAddressToPte(i);
Pte->PageFrameNumber = i >> PAGE_SHIFT;
Pte->Valid = 1;
Pte->Write = 1;
@@ -214,8 +211,8 @@
}
/* Now get the entry for our real mode V86 code and the target */
- Pte = GetPteAddress(0x20000);
- V86Pte = GetPteAddress(&HalpRealModeStart);
+ Pte = HalAddressToPte(0x20000);
+ V86Pte = HalAddressToPte(&HalpRealModeStart);
do
{
/* Map the physical address into our real-mode region */
@@ -224,7 +221,7 @@
/* Keep going until we've reached the end of our region */
Pte++;
V86Pte++;
- } while (V86Pte <= GetPteAddress(&HalpRealModeEnd));
+ } while (V86Pte <= HalAddressToPte(&HalpRealModeEnd));
/* Flush the TLB by resetting CR3 */
__writecr3(__readcr3());
@@ -234,27 +231,21 @@
NTAPI
HalpSwitchToRealModeTrapHandlers(VOID)
{
- ULONG Handler;
-
- /* Save the current Invalid Opcode and General Protection Fault Handlers */
- HalpGpfHandler = ((((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset << 16)
&
- 0xFFFF0000) |
- (((PKIPCR)KeGetPcr())->IDT[13].Offset & 0xFFFF);
- HalpBopHandler = ((((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset << 16) &
- 0xFFFF0000) |
- (((PKIPCR)KeGetPcr())->IDT[6].Offset & 0xFFFF);
-
- /* Now set our own GPF handler to handle exceptions while in real mode */
- Handler = (ULONG_PTR)HalpTrap0D;
- ((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset =
- (USHORT)((Handler >> 16) & 0xFFFF);
- ((PKIPCR)KeGetPcr())->IDT[13].Offset = (USHORT)Handler;
-
- /* And our own invalid opcode handler to detect the BOP to get us out */
- Handler = (ULONG_PTR)HalpTrap06;
- ((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset =
- (USHORT)((Handler >> 16) & 0xFFFF);
- ((PKIPCR)KeGetPcr())->IDT[6].Offset = (USHORT)Handler;
+ //
+ // Save the current Invalid Opcode and General Protection Fault Handlers
+ //
+ HalpGpfHandler = KeQueryInterruptHandler(13);
+ HalpBopHandler = KeQueryInterruptHandler(6);
+
+ //
+ // Now set our own GPF handler to handle exceptions while in real mode
+ //
+ KeRegisterInterruptHandler(13, HalpTrap0D);
+
+ //
+ // And our own invalid opcode handler to detect the BOP to get us out
+ //
+ KeRegisterInterruptHandler(6, HalpTrap06);
}
VOID
@@ -280,13 +271,11 @@
NTAPI
HalpRestoreTrapHandlers(VOID)
{
- /* We're back, restore the handlers we over-wrote */
- ((PKIPCR)KeGetPcr())->IDT[13].ExtendedOffset =
- (USHORT)((HalpGpfHandler >> 16) & 0xFFFF);
- ((PKIPCR)KeGetPcr())->IDT[13].Offset = (USHORT)HalpGpfHandler;
- ((PKIPCR)KeGetPcr())->IDT[6].ExtendedOffset =
- (USHORT)((HalpBopHandler >> 16) & 0xFFFF);
- ((PKIPCR)KeGetPcr())->IDT[6].Offset = (USHORT)HalpBopHandler;
+ //
+ // We're back, restore the handlers we over-wrote
+ //
+ KeRegisterInterruptHandler(13, HalpGpfHandler);
+ KeRegisterInterruptHandler(6, HalpBopHandler);
}
VOID
@@ -317,7 +306,7 @@
for (i = 0; i < 0x100000; i += PAGE_SIZE)
{
/* Invalidate each PTE */
- Pte = GetPteAddress((PVOID)i);
+ Pte = HalAddressToPte(i);
Pte->Valid = 0;
Pte->Write = 0;
Pte->Owner = 0;
@@ -325,7 +314,7 @@
}
/* Restore the PDE for the lowest megabyte of memory */
- Pte = GetPdeAddress(0);
+ Pte = HalAddressToPde(0);
*Pte = HalpSavedPte;
Pte->PageFrameNumber = HalpSavedPfn;
@@ -353,7 +342,7 @@
* the cmpxchg8b lock errata. Unprotect them here so we can set our custom
* invalid op-code handler.
*/
- IdtPte = GetPteAddress(((PKIPCR)KeGetPcr())->IDT);
+ IdtPte = HalAddressToPte(((PKIPCR)KeGetPcr())->IDT);
RestoreWriteProtection = IdtPte->Write;
/* Use special invalid opcode and GPF trap handlers */
Modified: trunk/reactos/hal/halx86/include/hal.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/hal.h?r…
==============================================================================
--- trunk/reactos/hal/halx86/include/hal.h [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/include/hal.h [iso-8859-1] Fri Jan 1 16:09:14 2010
@@ -29,6 +29,9 @@
/* Internal kernel headers */
#include "internal/pci.h"
+#define KeGetCurrentThread _KeGetCurrentThread
+#include <internal/i386/ke.h>
+#include <internal/i386/mm.h>
#ifdef _M_AMD64
#include "internal/amd64/intrin_i.h"
#else
Modified: trunk/reactos/hal/halx86/include/halp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/halp.h?…
==============================================================================
--- trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] (original)
+++ trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] Fri Jan 1 16:09:14 2010
@@ -34,7 +34,13 @@
(((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F))
#define INT_BCD(int) \
(UCHAR)(((int / 10) << 4) + (int % 10))
-
+
+//
+// Mm PTE/PDE to Hal PTE/PDE
+//
+#define HalAddressToPde(x) (PHARDWARE_PTE)MiAddressToPde(x)
+#define HalAddressToPte(x) (PHARDWARE_PTE)MiAddressToPte(x)
+
typedef struct _IDTUsageFlags
{
UCHAR Flags;
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] Fri Jan 1 16:09:14
2010
@@ -65,6 +65,53 @@
//
#define KeGetTrapFrameInterruptState(TrapFrame) \
BooleanFlagOn((TrapFrame)->EFlags, EFLAGS_INTERRUPT_MASK)
+
+//
+// Registers an interrupt handler with an IDT vector
+//
+FORCEINLINE
+VOID
+KeRegisterInterruptHandler(IN ULONG Vector,
+ IN PVOID Handler)
+{
+ UCHAR Entry;
+ ULONG_PTR Address;
+ PKIPCR Pcr = (PKIPCR)KeGetPcr();
+
+ //
+ // Get the entry from the HAL
+ //
+ Entry = HalVectorToIDTEntry(Vector);
+ Address = PtrToUlong(Handler);
+
+ //
+ // Now set the data
+ //
+ Pcr->IDT[Entry].ExtendedOffset = (USHORT)(Address >> 16);
+ Pcr->IDT[Entry].Offset = (USHORT)Address;
+}
+
+//
+// Returns the registered interrupt handler for a given IDT vector
+//
+FORCEINLINE
+PVOID
+KeQueryInterruptHandler(IN ULONG Vector)
+{
+ PKIPCR Pcr = (PKIPCR)KeGetPcr();
+ UCHAR Entry;
+
+ //
+ // Get the entry from the HAL
+ //
+ Entry = HalVectorToIDTEntry(Vector);
+
+ //
+ // Read the entry from the IDT
+ //
+ return (PVOID)(((Pcr->IDT[Entry].ExtendedOffset << 16) & 0xFFFF0000) |
+ (Pcr->IDT[Entry].Offset & 0xFFFF));
+}
//
// Invalidates the TLB entry for a specified address
Modified: trunk/reactos/ntoskrnl/ke/i386/irqobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/irqobj.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] Fri Jan 1 16:09:14 2010
@@ -29,7 +29,7 @@
IN PDISPATCH_INFO Dispatch)
{
PKINTERRUPT_ROUTINE Handler;
- ULONG Current;
+ PVOID Current;
UCHAR Type;
UCHAR Entry;
@@ -54,9 +54,7 @@
Dispatch->FlatDispatch = NULL;
/* Get the current handler */
- Current = ((((PKIPCR)KeGetPcr())->IDT[Entry].ExtendedOffset << 16)
- & 0xFFFF0000) |
- (((PKIPCR)KeGetPcr())->IDT[Entry].Offset & 0xFFFF);
+ Current = KeQueryInterruptHandler(Vector);
/* Set the interrupt */
Dispatch->Interrupt = CONTAINING_RECORD(Current,
@@ -100,7 +98,6 @@
DISPATCH_INFO Dispatch;
PKINTERRUPT_ROUTINE Handler;
PULONG Patch = &Interrupt->DispatchCode[0];
- UCHAR Entry;
/* Get vector data */
KiGetVectorDispatch(Interrupt->Vector, &Dispatch);
@@ -135,14 +132,8 @@
Handler = (PVOID)&Interrupt->DispatchCode;
}
- /* Get the IDT entry for this vector */
- Entry = HalVectorToIDTEntry(Interrupt->Vector);
-
- /* Set the pointer in the IDT */
- ((PKIPCR)KeGetPcr())->IDT[Entry].ExtendedOffset =
- (USHORT)(((ULONG_PTR)Handler >> 16) & 0xFFFF);
- ((PKIPCR)KeGetPcr())->IDT[Entry].Offset =
- (USHORT)PtrToUlong(Handler);
+ /* Register the interrupt */
+ KeRegisterInterruptHandler(Interrupt->Vector, Handler);
}
/* PUBLIC FUNCTIONS **********************************************************/