Author: ros-arm-bringup Date: Fri Jan 1 01:03:52 2010 New Revision: 44843
URL: http://svn.reactos.org/svn/reactos?rev=44843&view=rev Log: NMI Support Patch 3: [HAL]: If the current TSS does not have enough space for an I/O Privilege Map then "borrow" the default TSS while the BIOS Call is in-flight. "Return" it when the BIOS call has ended. Fixes panics during a double fault (since the double fault handler will attempt to clear the display through a Video ROM BIOS Interrupt 10h). Allows NMI panics to do BIOS calls as well (for later).
Modified: trunk/reactos/hal/halx86/generic/bios.c trunk/reactos/hal/halx86/include/halp.h
Modified: trunk/reactos/hal/halx86/generic/bios.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/bios.c?r... ============================================================================== --- trunk/reactos/hal/halx86/generic/bios.c [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/generic/bios.c [iso-8859-1] Fri Jan 1 01:03:52 2010 @@ -19,6 +19,7 @@ ULONG HalpGpfHandler; ULONG HalpBopHandler; ULONG HalpSavedEsp0; +USHORT HalpSavedTss; USHORT HalpSavedIopmBase; PUSHORT HalpSavedIoMap; USHORT HalpSavedIoMapData[32][2]; @@ -28,6 +29,98 @@ #define GetPteAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 12) << 2) + 0xC0000000)
/* FUNCTIONS ******************************************************************/ + +VOID +NTAPI +HalpBorrowTss(VOID) +{ + USHORT Tss; + PKGDTENTRY TssGdt; + ULONG_PTR TssLimit; + PKTSS TssBase; + + // + // Get the current TSS and its GDT entry + // + Tss = Ke386GetTr(); + TssGdt = &((PKIPCR)KeGetPcr())->GDT[Tss / sizeof(KGDTENTRY)]; + + // + // Get the KTSS limit and check if it has IOPM space + // + TssLimit = TssGdt->LimitLow | TssGdt->HighWord.Bits.LimitHi << 16; + + // + // If the KTSS doesn't have enough space this is probably an NMI or DF + // + if (TssLimit > IOPM_SIZE) + { + // + // We are good to go + // + HalpSavedTss = 0; + return; + } + + // + // Get the "real" TSS + // + TssGdt = &((PKIPCR)KeGetPcr())->GDT[KGDT_TSS / sizeof(KGDTENTRY)]; + TssBase = (PKTSS)(ULONG_PTR)(TssGdt->BaseLow | + TssGdt->HighWord.Bytes.BaseMid << 16 | + TssGdt->HighWord.Bytes.BaseHi << 24); + + // + // Switch to it + // + KeGetPcr()->TSS = TssBase; + + // + // Set it up + // + TssGdt->HighWord.Bits.Type = I386_TSS; + TssGdt->HighWord.Bits.Pres = 1; + TssGdt->HighWord.Bits.Dpl = 0; + + // + // Load new TSS and return old one + // + Ke386SetTr(KGDT_TSS); + HalpSavedTss = Tss; +} + +VOID +NTAPI +HalpReturnTss(VOID) +{ + PKGDTENTRY TssGdt; + PKTSS TssBase; + + // + // Get the original TSS + // + TssGdt = &((PKIPCR)KeGetPcr())->GDT[HalpSavedTss / sizeof(KGDTENTRY)]; + TssBase = (PKTSS)(ULONG_PTR)(TssGdt->BaseLow | + TssGdt->HighWord.Bytes.BaseMid << 16 | + TssGdt->HighWord.Bytes.BaseHi << 24); + + // + // Switch to it + // + KeGetPcr()->TSS = TssBase; + + // + // Set it up + // + TssGdt->HighWord.Bits.Type = I386_TSS; + TssGdt->HighWord.Bits.Pres = 1; + TssGdt->HighWord.Bits.Dpl = 0; + + // + // Load old TSS + // + Ke386SetTr(HalpSavedTss); +}
VOID NTAPI @@ -168,6 +261,9 @@ NTAPI HalpSetupRealModeIoPermissionsAndTask(VOID) { + /* Switch to valid TSS */ + HalpBorrowTss(); + /* Save a copy of the I/O Map and delete it */ HalpSavedIoMap = (PUSHORT)&(KeGetPcr()->TSS->IoMaps[0]); HalpStoreAndClearIopm(); @@ -204,7 +300,10 @@ HalpRestoreIopm();
/* Restore the IOPM */ - KeGetPcr()->TSS->IoMapBase = HalpSavedIopmBase; + KeGetPcr()->TSS->IoMapBase = HalpSavedIopmBase; + + /* Restore the TSS */ + if (HalpSavedTss) HalpReturnTss(); }
VOID
Modified: trunk/reactos/hal/halx86/include/halp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/include/halp.h?r... ============================================================================== --- trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] (original) +++ trunk/reactos/hal/halx86/include/halp.h [iso-8859-1] Fri Jan 1 01:03:52 2010 @@ -172,18 +172,6 @@ VOID );
-ULONG -NTAPI -HalpBorrowTss( - VOID -); - -ULONG -NTAPI -HalpReturnTss( - ULONG SavedTss -); - VOID NTAPI HalpBiosCall(