[HAL]: Rewrite all V8086-related code in C instead of ASM. Delete v86.s. Makes uses of new macros and developments in NTOS, but should now only end up getting called at shutdown and for bugchecks.

svn path=/trunk/; revision=45272
This commit is contained in:
Sir Richard 2010-01-26 19:41:31 +00:00
parent 842d2aa5f9
commit 92df9a6434
4 changed files with 334 additions and 457 deletions

View file

@ -41,6 +41,270 @@ PUSHORT HalpSavedIoMap;
USHORT HalpSavedIoMapData[32][2];
ULONG HalpSavedIoMapEntries;
/* Where the protected mode stack is */
ULONG_PTR HalpSavedEsp;
/* Where the real mode code ends */
extern PVOID HalpRealModeEnd;
/* REAL MODE CODE AND STACK START HERE ****************************************/
VOID
DECLSPEC_NORETURN
HalpRealModeStart(VOID)
{
/* Do the video BIOS interrupt */
HalpCallBiosInterrupt(VIDEO_SERVICES, (SET_VIDEO_MODE << 8) | (GRAPHICS_MODE_12));
/* Issue the BOP */
KiIssueBop();
/* We want the stack to be inside this function so we can map real mode */
HalpRealModeStack(sizeof(ULONG), PAGE_SIZE / 2);
UNREACHABLE;
}
/* REAL MODE CODE AND STACK END HERE ******************************************/
/* V86 OPCODE HANDLERS ********************************************************/
BOOLEAN
FASTCALL
HalpOpcodeInvalid(IN PHAL_BIOS_FRAME BiosFrame)
{
/* Print error message */
DPRINT1("HAL: An invalid V86 opcode was encountered at address %x:%x\n",
BiosFrame->SegCs, BiosFrame->Eip);
/* Break */
DbgBreakPoint();
return FALSE;
}
BOOLEAN
FASTCALL
HalpPushInt(IN PHAL_BIOS_FRAME BiosFrame,
IN ULONG Interrupt)
{
PUSHORT Stack;
ULONG Eip;
/* Calculate stack address (SP) */
Stack = (PUSHORT)(BiosFrame->SsBase + (BiosFrame->Esp & 0xFFFF));
/* Push EFlags */
Stack--;
*Stack = BiosFrame->EFlags & 0xFFFF;
/* Push CS */
Stack--;
*Stack = BiosFrame->SegCs & 0xFFFF;
/* Push IP */
Stack--;
*Stack = BiosFrame->Eip & 0xFFFF;
/* Compute new CS:IP from the IVT address for this interrupt entry */
Eip = *(PULONG)(Interrupt * 4);
BiosFrame->Eip = Eip & 0xFFFF;
BiosFrame->SegCs = Eip >> 16;
/* Update stack address */
BiosFrame->Esp = (ULONG_PTR)Stack & 0xFFFF;
/* Update CS to linear */
BiosFrame->CsBase = BiosFrame->SegCs << 4;
BiosFrame->CsLimit = 0xFFFF;
BiosFrame->CsFlags = 0;
/* We're done */
return TRUE;
}
BOOLEAN
FASTCALL
HalpOpcodeINTnn(IN PHAL_BIOS_FRAME BiosFrame)
{
UCHAR Interrupt;
PKTRAP_FRAME TrapFrame;
/* Convert SS to linear */
BiosFrame->SsBase = BiosFrame->SegSs << 4;
BiosFrame->SsLimit = 0xFFFF;
BiosFrame->SsFlags = 0;
/* Increase EIP and validate */
BiosFrame->Eip++;
if (BiosFrame->Eip > BiosFrame->CsLimit) return FALSE;
/* Read interrupt number */
Interrupt = *(PUCHAR)(BiosFrame->CsBase + BiosFrame->Eip);
/* Increase EIP and push the interrupt */
BiosFrame->Eip++;
if (HalpPushInt(BiosFrame, Interrupt))
{
/* Update the trap frame */
TrapFrame = BiosFrame->TrapFrame;
TrapFrame->HardwareSegSs = BiosFrame->SegSs;
TrapFrame->HardwareEsp = BiosFrame->Esp;
TrapFrame->SegCs = BiosFrame->SegCs;
TrapFrame->EFlags = BiosFrame->EFlags;
/* Success */
return TRUE;
}
/* Failure */
return FALSE;
}
BOOLEAN
FASTCALL
HalpDispatchV86Opcode(IN PKTRAP_FRAME TrapFrame)
{
UCHAR Instruction;
HAL_BIOS_FRAME BiosFrame;
/* Fill out the BIOS frame */
BiosFrame.TrapFrame = TrapFrame;
BiosFrame.SegSs = TrapFrame->HardwareSegSs;
BiosFrame.Esp = TrapFrame->HardwareEsp;
BiosFrame.EFlags = TrapFrame->EFlags;
BiosFrame.SegCs = TrapFrame->SegCs;
BiosFrame.Eip = TrapFrame->Eip;
BiosFrame.Prefix = 0;
/* Convert CS to linear */
BiosFrame.CsBase = BiosFrame.SegCs << 4;
BiosFrame.CsLimit = 0xFFFF;
BiosFrame.CsFlags = 0;
/* Validate IP */
if (BiosFrame.Eip > BiosFrame.CsLimit) return FALSE;
/* Read IP */
Instruction = *(PUCHAR)(BiosFrame.CsBase + BiosFrame.Eip);
if (Instruction != 0xCD)
{
/* We only support INT */
HalpOpcodeInvalid(&BiosFrame);
return FALSE;
}
/* Handle the interrupt */
if (HalpOpcodeINTnn(&BiosFrame))
{
/* Update EIP */
TrapFrame->Eip = BiosFrame.Eip;
/* We're done */
return TRUE;
}
/* Failure */
return FALSE;
}
/* V86 TRAP HANDLERS **********************************************************/
VOID
FASTCALL
DECLSPEC_NORETURN
HalpTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Enter the trap */
KiEnterTrap(TrapFrame);
/* Check if this is a V86 trap */
if (TrapFrame->EFlags & EFLAGS_V86_MASK)
{
/* Dispatch the opcode and exit the trap */
HalpDispatchV86Opcode(TrapFrame);
KiEoiHelper(TrapFrame);
}
/* Strange, it isn't! This can happen during NMI */
DPRINT1("HAL: Trap0D while not in V86 mode\n");
while (TRUE);
}
KiTrap(HalpTrap0D, 0);
VOID
DECLSPEC_NORETURN
HalpTrap06(VOID)
{
PKTRAP_FRAME TrapFrame;
/* Restore ES/DS to known good values first */
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
/* Read trap frame address */
TrapFrame = (PKTRAP_FRAME)HalpSavedEsp;
/* Restore segments from the trap frame */
Ke386SetGs(TrapFrame->SegGs);
Ke386SetFs(TrapFrame->SegFs);
Ke386SetEs(TrapFrame->SegEs);
Ke386SetDs(TrapFrame->SegDs);
/* Restore EFlags */
__writeeflags(TrapFrame->EFlags);
/* Exit the V86 mode trap frame */
KiCallReturn(TrapFrame);
}
/* V8086 ENTER ****************************************************************/
VOID
FASTCALL
DECLSPEC_NORETURN
HalpBiosCallHandler(IN PKTRAP_FRAME TrapFrame)
{
/* Must be volatile so it doesn't get optimized away! */
volatile KTRAP_FRAME V86TrapFrame;
ULONG_PTR StackOffset, CodeOffset;
/* Fill out the quick-n-dirty trap frame */
TrapFrame->EFlags = __readeflags();
TrapFrame->SegGs = Ke386GetGs();
TrapFrame->SegFs = Ke386GetFs();
TrapFrame->SegEs = Ke386GetEs();
TrapFrame->SegDs = Ke386GetDs();
/* Our stack (the frame) */
HalpSavedEsp = (ULONG_PTR)TrapFrame;
/* Kill alignment faults */
__writecr0(__readcr0() & ~CR0_AM);
/* Set new stack address */
KeGetPcr()->TSS->Esp0 = HalpSavedEsp - sizeof(FX_SAVE_AREA);
/* Compute segmented IP and SP offsets */
StackOffset = (ULONG_PTR)&HalpRealModeEnd - 4 - (ULONG_PTR)HalpRealModeStart;
CodeOffset = (ULONG_PTR)HalpRealModeStart & 0xFFF;
/* Now build the V86 trap frame */
V86TrapFrame.V86Es = 0;
V86TrapFrame.V86Ds = 0;
V86TrapFrame.V86Gs = 0;
V86TrapFrame.V86Fs = 0;
V86TrapFrame.HardwareSegSs = 0x2000;
V86TrapFrame.HardwareEsp = StackOffset + CodeOffset;
V86TrapFrame.EFlags = __readeflags() | EFLAGS_V86_MASK | EFLAGS_IOPL;
V86TrapFrame.SegCs = 0x2000;
V86TrapFrame.Eip = CodeOffset;
/* Exit to V86 mode */
KiDirectTrapReturn((PKTRAP_FRAME)&V86TrapFrame);
}
KiTrampoline(HalpBiosCall, KI_PUSH_FAKE_ERROR_CODE | KI_NONVOLATILES_ONLY);
/* FUNCTIONS ******************************************************************/
VOID

View file

@ -1,435 +0,0 @@
/*
* FILE: hal/halx86/generic/bios.S
* COPYRIGHT: See COPYING in the top level directory
* PURPOSE: V8086 Real-Mode BIOS Thunking
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES ******************************************************************/
#include <asm.h>
#include <internal/i386/asmmacro.S>
.intel_syntax noprefix
//
// HAL BIOS Frame
//
#define HALP_BIOS_FRAME_SS 0x00
#define HALP_BIOS_FRAME_ESP 0x04
#define HALP_BIOS_FRAME_EFLAGS 0x08
#define HALP_BIOS_FRAME_CS 0x0C
#define HALP_BIOS_FRAME_EIP 0x10
#define HALP_BIOS_FRAME_TRAP_FRAME 0x14
#define HALP_BIOS_FRAME_CS_LIMIT 0x18
#define HALP_BIOS_FRAME_CS_BASE 0x1C
#define HALP_BIOS_FRAME_CS_FLAGS 0x20
#define HALP_BIOS_FRAME_SS_LIMIT 0x24
#define HALP_BIOS_FRAME_SS_BASE 0x28
#define HALP_BIOS_FRAME_SS_FLAGS 0x2C
#define HALP_BIOS_FRAME_PREFIX 0x30
#define HALP_BIOS_FRAME_LENGTH 0x34
/* GLOBALS *******************************************************************/
_HalpSavedEsp:
.long 0
_InvalidMsg:
.asciz "HAL: An invalid V86 opcode was encountered at address %x:%x\n"
_InvalidGpfMsg:
.asciz "HAL: Trap0D while not in V86 mode\n"
_UnhandledMsg:
.asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx [%s]!!!\n"
/* FUNCTIONS *****************************************************************/
.globl _HalpBiosCall@0
.func HalpBiosCall@0
_HalpBiosCall@0:
/* Set up stack pointer */
push ebp
mov ebp, esp
/* Build a trap frame */
pushfd
push edi
push esi
push ebx
push ds
push es
push fs
push gs
push offset _HalpRealModeEnd
/* Save the stack */
mov _HalpSavedEsp, esp
/* Turn off alignment faults */
mov eax, cr0
and eax, ~CR0_AM
mov cr0, eax
/* Setup a new stack */
mov esi, fs:KPCR_TSS
mov eax, esp
sub eax, NPX_FRAME_LENGTH
mov [esi+KTSS_ESP0], eax
/* Save V86 registers */
push 0
push 0
push 0
push 0
push 0x2000
/* Get linear delta between stack and code */
mov eax, offset _HalpRealModeEnd-4
sub eax, offset _HalpRealModeStart
/* Get offset of code */
mov edx, offset _HalpRealModeStart
and edx, 0xFFF
/* Add offset to linear address and save the new V86 SP */
add eax, edx
push eax
/* Start building interrupt frame. Setup V86 EFLAGS and IOPL 3 */
pushfd
or dword ptr [esp], EFLAGS_V86_MASK
or dword ptr [esp], 0x3000
/* Push the CS and IP */
push 0x2000
push edx
/* Do the interrupt return (jump to V86 mode) */
iretd
.globl _HalpRealModeStart
_HalpRealModeStart:
/* Set mode 13 */
mov ax, 0x12
.byte 0
.byte 0
/* Do the interrupt */
int 0x10
/* BOP to exit V86 mode */
.byte 0xC4
.byte 0xC4
/* The stack lives here */
.align 4
.space 2048
.globl _HalpRealModeEnd
_HalpRealModeEnd:
/* We're back, clean up the trap frame */
pop gs
pop fs
pop es
pop ds
pop ebx
pop esi
pop edi
popfd
/* Return to caller */
pop ebp
ret 0
.endfunc
.globl _HalpOpcodeInvalid@0
.func HalpOpcodeInvalid@0
_HalpOpcodeInvalid@0:
/* This should never happen -- is the IOPM damaged? */
push [esi+HALP_BIOS_FRAME_EIP]
push [esi+HALP_BIOS_FRAME_CS]
push offset _InvalidMsg
call _DbgPrint
add esp, 12
/* Break */
int 3
/* Nothing to return */
xor eax, eax
ret 0
.endfunc
.globl _HalpPushInt@0
.func HalpPushInt@0
_HalpPushInt@0:
/* Save EBX */
push ebx
/* Get SS offset and base */
mov edx, [esi+HALP_BIOS_FRAME_ESP]
mov ebx, [esi+HALP_BIOS_FRAME_SS_BASE]
/* Convert to 16-bits */
and edx, 0xFFFF
sub dx, 2
/* Get EFLAGS and write them into the linear address of SP */
mov ax, word ptr [esi+HALP_BIOS_FRAME_EFLAGS]
mov [ebx+edx], ax
sub dx, 2
/* Get CS segment and write it into SP */
mov ax, word ptr [esi+HALP_BIOS_FRAME_CS]
mov [ebx+edx], ax
sub dx, 2
/* Get IP and write it into SP */
mov ax, word ptr [esi+HALP_BIOS_FRAME_EIP]
mov [ebx+edx], ax
/* Get new IP value (the interrupt ID is in ECX, so this is in the IVT) */
mov eax, [ecx*4]
push eax
/* Now save the new IP */
movzx eax, ax
mov [esi+HALP_BIOS_FRAME_EIP], eax
/* Save the new CS of this IP */
pop eax
shr eax, 16
mov [esi+HALP_BIOS_FRAME_CS], eax
/* Update the stack pointer after our manual interrupt frame construction */
mov word ptr [esi+HALP_BIOS_FRAME_ESP], dx
/* Get CS and convert it to linear format */
mov eax, [esi+HALP_BIOS_FRAME_CS]
shl eax, 4
mov [esi+HALP_BIOS_FRAME_CS_BASE], eax
mov dword ptr [esi+HALP_BIOS_FRAME_CS_LIMIT], 0xFFFF
mov dword ptr [esi+HALP_BIOS_FRAME_CS_FLAGS], 0
/* Return success and restore EBX */
mov eax, 1
pop ebx
ret 0
.endfunc
.globl _HalpOpcodeINTnn@0
.func HalpOpcodeINTnn@0
_HalpOpcodeINTnn@0:
/* Save non-volatiles and stack */
push ebp
push esi
push ebx
/* Get SS and convert it to linear format */
mov eax, [esi+HALP_BIOS_FRAME_SS]
shl eax, 4
mov [esi+HALP_BIOS_FRAME_SS_BASE], eax
mov dword ptr [esi+HALP_BIOS_FRAME_SS_LIMIT], 0xFFFF
mov dword ptr [esi+HALP_BIOS_FRAME_SS_FLAGS], 0
/* Increase IP and check if we're past the CS limit */
inc dword ptr [esi+HALP_BIOS_FRAME_EIP]
mov edi, [esi+HALP_BIOS_FRAME_EIP]
cmp edi, [esi+HALP_BIOS_FRAME_CS_LIMIT]
ja EipLimitReached
/* Convert IP to linear address and read the interrupt number */
add edi, [esi+HALP_BIOS_FRAME_CS_BASE]
movzx ecx, byte ptr [edi]
/* Increase EIP and do the interrupt, check for status */
inc dword ptr [esi+HALP_BIOS_FRAME_EIP]
call _HalpPushInt@0
test eax, 0xFFFF
jz Done
/* Update the trap frame */
mov ebp, [esi+HALP_BIOS_FRAME_TRAP_FRAME]
mov eax, [esi+HALP_BIOS_FRAME_SS]
mov [ebp+KTRAP_FRAME_SS], eax
mov eax, [esi+HALP_BIOS_FRAME_ESP]
mov [ebp+KTRAP_FRAME_ESP], eax
mov eax, [esi+HALP_BIOS_FRAME_CS]
mov [ebp+KTRAP_FRAME_CS], eax
mov eax, [esi+HALP_BIOS_FRAME_EFLAGS]
mov [ebp+KTRAP_FRAME_EFLAGS], eax
/* Set success code */
mov eax, 1
Done:
/* Restore volatiles */
pop ebx
pop edi
pop ebp
ret 0
EipLimitReached:
/* Set failure code */
xor eax, eax
jmp Done
.endfunc
.globl _HalpDispatchV86Opcode@0
.func HalpDispatchV86Opcode@0
_HalpDispatchV86Opcode@0:
/* Make space for the HAL BIOS Frame on the stack */
push ebp
mov ebp, esp
sub esp, HALP_BIOS_FRAME_LENGTH
/* Save non-volatiles */
push esi
push edi
/* Save pointer to the trap frame */
mov esi, [ebp]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_TRAP_FRAME], esi
/* Save SS */
movzx eax, word ptr [esi+KTRAP_FRAME_SS]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_SS], eax
/* Save ESP */
mov eax, [esi+KTRAP_FRAME_ESP]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_ESP], eax
/* Save EFLAGS */
mov eax, [esi+KTRAP_FRAME_EFLAGS]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_EFLAGS], eax
/* Save CS */
movzx eax, word ptr [esi+KTRAP_FRAME_CS]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_CS], eax
/* Save EIP */
mov eax, [esi+KTRAP_FRAME_EIP]
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_EIP], eax
/* No prefix */
xor eax, eax
mov [ebp-HALP_BIOS_FRAME_LENGTH+HALP_BIOS_FRAME_PREFIX], eax
/* Set pointer to HAL BIOS Frame */
lea esi, [ebp-HALP_BIOS_FRAME_LENGTH]
/* Convert CS to linear format */
mov eax, [esi+HALP_BIOS_FRAME_CS]
shl eax, 4
mov [esi+HALP_BIOS_FRAME_CS_BASE], eax
mov dword ptr [esi+HALP_BIOS_FRAME_CS_LIMIT], 0xFFFF
mov dword ptr [esi+HALP_BIOS_FRAME_CS_FLAGS], 0
/* Make sure IP is within the CS Limit */
mov edi, [esi+HALP_BIOS_FRAME_EIP]
cmp edi, [esi+HALP_BIOS_FRAME_CS_LIMIT]
ja DispatchError
/* Convert IP to linear address and read the opcode */
add edi, [esi+HALP_BIOS_FRAME_CS_BASE]
mov dl, [edi]
/* We only deal with interrupts */
cmp dl, 0xCD
je DispatchInt
/* Anything else is invalid */
call _HalpOpcodeInvalid@0
jmp DispatchError
DispatchInt:
/* Handle dispatching the interrupt */
call _HalpOpcodeINTnn@0
test eax, 0xFFFF
jz DispatchReturn
/* Update the trap frame EIP */
mov edi, [ebp-0x20]
mov eax, [ebp-0x24]
mov [edi+KTRAP_FRAME_EIP], eax
/* Set success code */
mov eax, 1
DispatchReturn:
/* Restore registers and return */
pop edi
pop esi
mov esp, ebp
pop ebp
ret 0
DispatchError:
/* Set failure code and return */
xor eax, eax
jmp DispatchReturn
.endfunc
.func Ki16BitStackException
_Ki16BitStackException:
/* Save stack */
push ss
push esp
/* Go to kernel mode thread stack */
mov eax, PCR[KPCR_CURRENT_THREAD]
add esp, [eax+KTHREAD_INITIAL_STACK]
/* Switch to good stack segment */
UNHANDLED_PATH "16-Bit Stack"
.endfunc
.globl _HalpTrap0D@0
.func HalpTrap0D@0
TRAP_FIXUPS htd_a, htd_t, DoFixupV86, DoFixupAbios
_HalpTrap0D@0:
/* Enter trap */
TRAP_PROLOG htd_a, htd_t
/* Check if this is a V86 trap */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz DoDispatch
/* This is weird -- but might happen during an NMI */
push offset _InvalidGpfMsg
call _DbgPrint
add esp, 4
/* Loop forever */
jmp $
DoDispatch:
/* Handle the opcode */
call _HalpDispatchV86Opcode@0
/* Exit the interrupt */
jmp _Kei386EoiHelper@0
.endfunc
.globl _HalpTrap06@0
.func HalpTrap06@0
_HalpTrap06@0:
/* Restore DS/ES segments */
mov eax, KGDT_R3_DATA | RPL_MASK
mov ds, ax
mov es, ax
/* Restore ESP and return */
mov esp, _HalpSavedEsp
ret 0
.endfunc

View file

@ -29,7 +29,6 @@
<file>systimer.S</file>
<file>timer.c</file>
<file>usage.c</file>
<file>v86.s</file>
</directory>
<directory name="include">
<pch>hal.h</pch>

View file

@ -5,6 +5,23 @@
#ifndef __INTERNAL_HAL_HAL_H
#define __INTERNAL_HAL_HAL_H
typedef struct _HAL_BIOS_FRAME
{
ULONG SegSs;
ULONG Esp;
ULONG EFlags;
ULONG SegCs;
ULONG Eip;
PKTRAP_FRAME TrapFrame;
ULONG CsLimit;
ULONG CsBase;
ULONG CsFlags;
ULONG SsLimit;
ULONG SsBase;
ULONG SsFlags;
ULONG Prefix;
} HAL_BIOS_FRAME, *PHAL_BIOS_FRAME;
#define HAL_APC_REQUEST 0
#define HAL_DPC_REQUEST 1
@ -28,6 +45,59 @@
#define INT_BCD(int) \
(UCHAR)(((int / 10) << 4) + (int % 10))
//
// BIOS Interrupts
//
#define VIDEO_SERVICES 0x10
//
// Operations for INT 10h (in AH)
//
#define SET_VIDEO_MODE 0x00
//
// Video Modes for INT10h AH=00 (in AL)
//
#define GRAPHICS_MODE_12 0x12 /* 80x30 8x16 640x480 16/256K */
//
// Generates a 16-bit (real-mode or Virtual 8086) BIOS interrupt with a given AX */
//
VOID
FORCEINLINE
HalpCallBiosInterrupt(IN ULONG Interrupt,
IN ULONG Ax)
{
__asm__ __volatile__
(
".byte 0x66\n"
"movl $%c[v], %%eax\n"
"int $%c[i]\n"
:
: [v] "i"(Ax),
[i] "i"(Interrupt)
);
}
//
// Constructs a stack of the given size and alignment in the real-mode .text region */
//
VOID
FORCEINLINE
HalpRealModeStack(IN ULONG Alignment,
IN ULONG Size)
{
__asm__ __volatile__
(
".align %c[v]\n"
".space %c[i]\n"
".globl _HalpRealModeEnd\n_HalpRealModeEnd:\n"
:
: [v] "i"(Alignment),
[i] "i"(Size)
);
}
//
// Commonly stated as being 1.19318MHz
//
@ -557,24 +627,6 @@ HalpBiosDisplayReset(
VOID
);
VOID
NTAPI
HalpBiosCall(
VOID
);
VOID
NTAPI
HalpTrap0D(
VOID
);
VOID
NTAPI
HalpTrap06(
VOID
);
//
// Processor Halt Routine
//
@ -716,9 +768,6 @@ KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
extern BOOLEAN HalpNMIInProgress;
extern PVOID HalpRealModeStart;
extern PVOID HalpRealModeEnd;
extern ADDRESS_USAGE HalpDefaultIoSpace;
extern KSPIN_LOCK HalpSystemHardwareLock;