NMI Support Patch 1:

[HAL]:  The I/O Permissions Map on a typical Privileged Mode x86 OS is all 0xFF's, so it's quite wasteful to copy-in/out the entire map each single BIOS Call. As an optimization, only save and restore non-0xFF entries.
    [NTOS]: Define and use constants for different IOPM values, instead of using hardcoded values.


svn path=/trunk/; revision=44841
This commit is contained in:
ReactOS Portable Systems Group 2009-12-31 23:51:26 +00:00
parent e426bf896f
commit 2e1b82cf72
3 changed files with 70 additions and 30 deletions

View file

@ -1,9 +1,9 @@
/* /*
* PROJECT: ReactOS HAL * PROJECT: ReactOS Hardware Abstraction Layer (HAL)
* LICENSE: GPL - See COPYING in the top level directory * LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: hal/halx86/generic/bios.c * FILE: halx86/generic/bios.c
* PURPOSE: BIOS Access Routines * PURPOSE: BIOS Access Routines
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: ReactOS Portable Systems Group
*/ */
/* INCLUDES *******************************************************************/ /* INCLUDES *******************************************************************/
@ -14,14 +14,15 @@
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
UCHAR HalpIopmSaveBuffer[0x2000];
ULONG HalpSavedPfn; ULONG HalpSavedPfn;
HARDWARE_PTE HalpSavedPte; HARDWARE_PTE HalpSavedPte;
ULONG HalpGpfHandler; ULONG HalpGpfHandler;
ULONG HalpBopHandler; ULONG HalpBopHandler;
USHORT HalpSavedIopmBase;
PUCHAR HalpSavedIoMap;
ULONG HalpSavedEsp0; ULONG HalpSavedEsp0;
USHORT HalpSavedIopmBase;
PUSHORT HalpSavedIoMap;
USHORT HalpSavedIoMapData[32][2];
ULONG HalpSavedIoMapEntries;
#define GetPdeAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 22) << 2) + 0xC0300000) #define GetPdeAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 22) << 2) + 0xC0300000)
#define GetPteAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 12) << 2) + 0xC0000000) #define GetPteAddress(x) (PHARDWARE_PTE)(((((ULONG_PTR)(x)) >> 12) << 2) + 0xC0000000)
@ -30,27 +31,61 @@ ULONG HalpSavedEsp0;
VOID VOID
NTAPI NTAPI
HalpStoreAndClearIopm(IN PUCHAR IoMap) HalpStoreAndClearIopm(VOID)
{ {
ULONG i; ULONG i, j;
PUSHORT Entry = HalpSavedIoMap;
/* Backup the old I/O Map */
RtlCopyMemory(HalpIopmSaveBuffer, IoMap, 0x2000);
/* Erase the current one */ //
for (i = 0; i < 0x2000; i++) IoMap[i] = 0; // Loop the I/O Map
for (i = 0x2000; i < 0x2004; i++) IoMap[i] = 0xFF; //
for (i = j = 0; i < (IOPM_SIZE) / 2; i++)
{
//
// Check for non-FFFF entry
//
if (*Entry != 0xFFFF)
{
//
// Save it
//
ASSERT(j < 32);
HalpSavedIoMapData[j][0] = i;
HalpSavedIoMapData[j][1] = *Entry;
}
//
// Clear it
//
*Entry++ = 0;
}
//
// Terminate it
//
while (i++ < (IOPM_FULL_SIZE / 2)) *Entry++ = 0xFFFF;
//
// Return the entries we saved
//
HalpSavedIoMapEntries = j;
} }
VOID VOID
NTAPI NTAPI
HalpRestoreIopm(IN PUCHAR IoMap) HalpRestoreIopm(VOID)
{ {
ULONG i; ULONG i = HalpSavedIoMapEntries;
/* Restore the backed up copy, and initialize it */ //
RtlCopyMemory(IoMap, HalpIopmSaveBuffer, 0x2000); // Set default state
for (i = 0x2000; i < 0x2004; i++) IoMap[i] = 0xFF; //
RtlFillMemory(HalpSavedIoMap, 0xFF, IOPM_FULL_SIZE);
//
// Restore the backed up copy, and initialize it
//
while (i--) HalpSavedIoMap[HalpSavedIoMapData[i][0]] = HalpSavedIoMapData[i][1];
} }
VOID VOID
@ -134,8 +169,8 @@ NTAPI
HalpSetupRealModeIoPermissionsAndTask(VOID) HalpSetupRealModeIoPermissionsAndTask(VOID)
{ {
/* Save a copy of the I/O Map and delete it */ /* Save a copy of the I/O Map and delete it */
HalpSavedIoMap = (PUCHAR)&(KeGetPcr()->TSS->IoMaps[0]); HalpSavedIoMap = (PUSHORT)&(KeGetPcr()->TSS->IoMaps[0]);
HalpStoreAndClearIopm(HalpSavedIoMap); 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; HalpSavedIopmBase = KeGetPcr()->TSS->IoMapBase;
@ -166,7 +201,7 @@ HalpRestoreIoPermissionsAndTask(VOID)
KeGetPcr()->TSS->Esp0 = HalpSavedEsp0; KeGetPcr()->TSS->Esp0 = HalpSavedEsp0;
/* Restore the I/O Map */ /* Restore the I/O Map */
HalpRestoreIopm(HalpSavedIoMap); HalpRestoreIopm();
/* Restore the IOPM */ /* Restore the IOPM */
KeGetPcr()->TSS->IoMapBase = HalpSavedIopmBase; KeGetPcr()->TSS->IoMapBase = HalpSavedIopmBase;

View file

@ -129,7 +129,11 @@ Author:
// //
// IOPM Definitions // IOPM Definitions
// //
#define IOPM_COUNT 1
#define IOPM_SIZE 8192
#define IOPM_FULL_SIZE 8196
#define IO_ACCESS_MAP_NONE 0 #define IO_ACCESS_MAP_NONE 0
#define IOPM_DIRECTION_MAP_SIZE 32
#define IOPM_OFFSET FIELD_OFFSET(KTSS, IoMaps[0].IoMap) #define IOPM_OFFSET FIELD_OFFSET(KTSS, IoMaps[0].IoMap)
#define KiComputeIopmOffset(MapNumber) \ #define KiComputeIopmOffset(MapNumber) \
(MapNumber == IO_ACCESS_MAP_NONE) ? \ (MapNumber == IO_ACCESS_MAP_NONE) ? \
@ -708,8 +712,8 @@ typedef struct _KIPCR
// //
typedef struct _KiIoAccessMap typedef struct _KiIoAccessMap
{ {
UCHAR DirectionMap[32]; UCHAR DirectionMap[IOPM_DIRECTION_MAP_SIZE];
UCHAR IoMap[8196]; UCHAR IoMap[IOPM_FULL_SIZE];
} KIIO_ACCESS_MAP; } KIIO_ACCESS_MAP;
typedef struct _KTSS typedef struct _KTSS
@ -747,8 +751,8 @@ typedef struct _KTSS
USHORT Reserved8; USHORT Reserved8;
USHORT Flags; USHORT Flags;
USHORT IoMapBase; USHORT IoMapBase;
KIIO_ACCESS_MAP IoMaps[1]; KIIO_ACCESS_MAP IoMaps[IOPM_COUNT];
UCHAR IntDirectionMap[32]; UCHAR IntDirectionMap[IOPM_DIRECTION_MAP_SIZE];
} KTSS, *PKTSS; } KTSS, *PKTSS;
// //

View file

@ -582,11 +582,12 @@ KiInitializeTSS2(IN PKTSS Tss,
} }
/* Now clear the I/O Map */ /* Now clear the I/O Map */
RtlFillMemory(Tss->IoMaps[0].IoMap, 8096, -1); ASSERT(IOPM_COUNT == 1);
RtlFillMemory(Tss->IoMaps[0].IoMap, IOPM_FULL_SIZE, 0xFF);
/* Initialize Interrupt Direction Maps */ /* Initialize Interrupt Direction Maps */
p = (PUCHAR)(Tss->IoMaps[0].DirectionMap); p = (PUCHAR)(Tss->IoMaps[0].DirectionMap);
RtlZeroMemory(p, 32); RtlZeroMemory(p, IOPM_DIRECTION_MAP_SIZE);
/* Add DPMI support for interrupts */ /* Add DPMI support for interrupts */
p[0] = 4; p[0] = 4;
@ -595,7 +596,7 @@ KiInitializeTSS2(IN PKTSS Tss,
/* Initialize the default Interrupt Direction Map */ /* Initialize the default Interrupt Direction Map */
p = Tss->IntDirectionMap; p = Tss->IntDirectionMap;
RtlZeroMemory(Tss->IntDirectionMap, 32); RtlZeroMemory(Tss->IntDirectionMap, IOPM_DIRECTION_MAP_SIZE);
/* Add DPMI support */ /* Add DPMI support */
p[0] = 4; p[0] = 4;