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

View file

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

View file

@ -582,11 +582,12 @@ KiInitializeTSS2(IN PKTSS Tss,
}
/* 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 */
p = (PUCHAR)(Tss->IoMaps[0].DirectionMap);
RtlZeroMemory(p, 32);
RtlZeroMemory(p, IOPM_DIRECTION_MAP_SIZE);
/* Add DPMI support for interrupts */
p[0] = 4;
@ -595,7 +596,7 @@ KiInitializeTSS2(IN PKTSS Tss,
/* Initialize the default Interrupt Direction Map */
p = Tss->IntDirectionMap;
RtlZeroMemory(Tss->IntDirectionMap, 32);
RtlZeroMemory(Tss->IntDirectionMap, IOPM_DIRECTION_MAP_SIZE);
/* Add DPMI support */
p[0] = 4;