mirror of
https://github.com/reactos/reactos.git
synced 2025-08-01 18:53:05 +00:00
[REACTOS] Add asm.h containing macros to make assembly code both GAS and ML compatible at the same time.
[NTOS/HAL] Move trap entry points from C into a GAS/ML compatile assembly file (might need fine tuning for ML). The entries are generated by a shared assembly macro TRAP_ENTRY. Removed KiTrapStub, KiIsV8086TrapSafe, KiIsUserTrapSafe, KiSetSaneSegments, removed segment handling from KiEnter*Trap. [NTOS] Make KiFastCallEntryHandler and KiSystemServiceHandler FASTCALL and pass the systemcall number in TrapFrame->Eax [HAL] Use _setjmp/longjmp instead of saving a trapframe in HalpBiosCall svn path=/trunk/; revision=45565
This commit is contained in:
parent
de233c67ef
commit
dd6b443e89
20 changed files with 522 additions and 460 deletions
|
@ -12,6 +12,9 @@
|
|||
#include <hal.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
void HalpTrap0D();
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
|
@ -47,6 +50,9 @@ ULONG_PTR HalpSavedEsp;
|
|||
/* Where the real mode code ends */
|
||||
extern PVOID HalpRealModeEnd;
|
||||
|
||||
/* Context saved for return from v86 mode */
|
||||
jmp_buf HalpSavedContext;
|
||||
|
||||
/* REAL MODE CODE AND STACK START HERE ****************************************/
|
||||
|
||||
VOID
|
||||
|
@ -230,60 +236,44 @@ HalpTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
while (TRUE);
|
||||
}
|
||||
|
||||
KiTrap(HalpTrap0D, 0);
|
||||
|
||||
VOID
|
||||
DECLSPEC_NORETURN
|
||||
HalpTrap06(VOID)
|
||||
HalpTrap06()
|
||||
{
|
||||
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);
|
||||
|
||||
/* Restore the stack */
|
||||
KeGetPcr()->TSS->Esp0 = HalpSavedEsp0;
|
||||
|
||||
/* Return back to where we left */
|
||||
longjmp(HalpSavedContext, 1);
|
||||
UNREACHABLE;
|
||||
}
|
||||
|
||||
/* V8086 ENTER ****************************************************************/
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
DECLSPEC_NORETURN
|
||||
HalpBiosCallHandler(IN PKTRAP_FRAME TrapFrame)
|
||||
NTAPI
|
||||
HalpBiosCall()
|
||||
{
|
||||
/* 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;
|
||||
/* Save the context, check for return */
|
||||
if (_setjmp(HalpSavedContext))
|
||||
{
|
||||
/* Returned from v86 */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Kill alignment faults */
|
||||
__writecr0(__readcr0() & ~CR0_AM);
|
||||
|
||||
/* Set new stack address */
|
||||
KeGetPcr()->TSS->Esp0 = HalpSavedEsp - sizeof(FX_SAVE_AREA);
|
||||
KeGetPcr()->TSS->Esp0 = (ULONG)&V86TrapFrame - 0x20 - sizeof(FX_SAVE_AREA);
|
||||
|
||||
/* Compute segmented IP and SP offsets */
|
||||
StackOffset = (ULONG_PTR)&HalpRealModeEnd - 4 - (ULONG_PTR)HalpRealModeStart;
|
||||
|
@ -304,8 +294,6 @@ HalpBiosCallHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
KiDirectTrapReturn((PKTRAP_FRAME)&V86TrapFrame);
|
||||
}
|
||||
|
||||
KiTrampoline(HalpBiosCall, KI_PUSH_FAKE_ERROR_CODE | KI_NONVOLATILES_ONLY);
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
|
|
|
@ -1335,4 +1335,3 @@ HalpDispatchInterrupt2(VOID)
|
|||
}
|
||||
}
|
||||
|
||||
KiTrap(HalpApcInterrupt, KI_SOFTWARE_TRAP);
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <asm.h>
|
||||
#include <internal/i386/asmmacro.S>
|
||||
.intel_syntax noprefix
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
|
|
@ -161,8 +161,6 @@ HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
KiEoiHelper(TrapFrame);
|
||||
}
|
||||
|
||||
KiTrap(HalpClockInterrupt, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(HalpProfileInterrupt, KI_PUSH_FAKE_ERROR_CODE);
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
|
|
23
reactos/hal/halx86/generic/trap.S
Normal file
23
reactos/hal/halx86/generic/trap.S
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* FILE: ntoskrnl/ke/i386/trap.S
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PURPOSE: System Traps, Entrypoints and Exitpoints
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
* NOTE: See asmmacro.S for the shared entry/exit code.
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <reactos/asm.h>
|
||||
#include <ndk/i386/asm.h>
|
||||
#include <internal/i386/asmmacro.S>
|
||||
|
||||
.code32
|
||||
.text
|
||||
|
||||
TRAP_ENTRY HalpTrap0D, 0
|
||||
TRAP_ENTRY HalpApcInterrupt, KI_SOFTWARE_TRAP
|
||||
TRAP_ENTRY HalpClockInterrupt, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY HalpProfileInterrupt, KI_PUSH_FAKE_ERROR_CODE
|
||||
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
<library>hal_generic</library>
|
||||
<library>hal_generic_up</library>
|
||||
<library>ntoskrnl</library>
|
||||
<library>libcntpr</library>
|
||||
<directory name="up">
|
||||
<file>halinit_up.c</file>
|
||||
<file>halup.rc</file>
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
<file>sysinfo.c</file>
|
||||
<file>systimer.S</file>
|
||||
<file>timer.c</file>
|
||||
<file>trap.S</file>
|
||||
<file>usage.c</file>
|
||||
</directory>
|
||||
<directory name="include">
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<library>hal_generic</library>
|
||||
<library>hal_generic_mp</library>
|
||||
<library>ntoskrnl</library>
|
||||
<library>libcntpr</library>
|
||||
<directory name="mp">
|
||||
<file>mps.S</file>
|
||||
<file>mpsboot.asm</file>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<library>hal_generic</library>
|
||||
<library>hal_generic_up</library>
|
||||
<library>ntoskrnl</library>
|
||||
<library>libcntpr</library>
|
||||
<directory name="xbox">
|
||||
<file>halinit_xbox.c</file>
|
||||
<file>part_xbox.c</file>
|
||||
|
|
|
@ -1110,4 +1110,25 @@ HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack)
|
|||
|
||||
#endif
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
DECLSPEC_NORETURN
|
||||
HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Set up a fake INT Stack */
|
||||
TrapFrame->EFlags = __readeflags();
|
||||
TrapFrame->SegCs = KGDT_R0_CODE;
|
||||
TrapFrame->Eip = TrapFrame->Eax;
|
||||
|
||||
/* Build the trap frame */
|
||||
KiEnterInterruptTrap(TrapFrame);
|
||||
|
||||
/* unimplemented */
|
||||
UNIMPLEMENTED;
|
||||
|
||||
/* Exit the interrupt */
|
||||
KiEoiHelper(TrapFrame);
|
||||
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -248,10 +248,12 @@ Author:
|
|||
#define KINTERRUPT_SERVICE_CONTEXT 0x10
|
||||
#define KINTERRUPT_TICK_COUNT 0x18
|
||||
#define KINTERRUPT_ACTUAL_LOCK 0x1C
|
||||
#define KINTERRUPT_DISPATCH_ADDRESS 0x20
|
||||
#define KINTERRUPT_VECTOR 0x24
|
||||
#define KINTERRUPT_IRQL 0x28
|
||||
#define KINTERRUPT_SYNCHRONIZE_IRQL 0x29
|
||||
#define KINTERRUPT_DISPATCH_COUNT 0x38
|
||||
#define KINTERRUPT_DISPATCH_CODE 0x3C
|
||||
|
||||
//
|
||||
// KGDTENTRY Offsets
|
||||
|
|
190
reactos/include/reactos/asm.h
Normal file
190
reactos/include/reactos/asm.h
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Kernel
|
||||
* FILE: ntoskrnl/include/amd64/asmmacro.S
|
||||
* PURPOSE: ASM macros for for GAS and MASM/ML64
|
||||
* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
/* Allow ".name" identifiers */
|
||||
OPTION DOTNAME
|
||||
|
||||
.586
|
||||
.MODEL FLAT
|
||||
|
||||
/* Hex numbers need to be in 01ABh format */
|
||||
#define HEX(x) 0##x##h
|
||||
|
||||
/* Macro values need to be marked */
|
||||
#define VAL(x) x
|
||||
|
||||
/* MASM/ML doesn't want explicit [rip] addressing */
|
||||
rip = 0
|
||||
|
||||
/* Due to MASM's reverse syntax, we are forced to use a precompiler macro */
|
||||
#define MACRO(name, ...) name MACRO __VA_ARGS__
|
||||
|
||||
/* To avoid reverse syntax we provide a new macro .PROC, replacing PROC... */
|
||||
.PROC MACRO name
|
||||
name PROC FRAME
|
||||
_name:
|
||||
ENDM
|
||||
|
||||
/* ... and .ENDP, replacing ENDP */
|
||||
.ENDP MACRO name
|
||||
name ENDP
|
||||
ENDM
|
||||
|
||||
/* MASM doesn't have an ASCII macro */
|
||||
.ASCII MACRO text
|
||||
DB text
|
||||
ENDM
|
||||
|
||||
/* MASM doesn't have an ASCIZ macro */
|
||||
.ASCIZ MACRO text
|
||||
DB text, 0
|
||||
ENDM
|
||||
|
||||
.text MACRO
|
||||
ENDM
|
||||
|
||||
.code64 MACRO
|
||||
.code
|
||||
ENDM
|
||||
|
||||
.code32 MACRO
|
||||
.code
|
||||
ENDM
|
||||
|
||||
UNIMPLEMENTED MACRO name
|
||||
ENDM
|
||||
|
||||
/* We need this to distinguish repeat from macros */
|
||||
#define ENDR ENDM
|
||||
|
||||
#else /***********************************************************************/
|
||||
|
||||
/* Force intel syntax */
|
||||
.intel_syntax noprefix
|
||||
.code64
|
||||
|
||||
.altmacro
|
||||
|
||||
/* Hex numbers need to be in 0x1AB format */
|
||||
#define HEX(x) 0x##x
|
||||
|
||||
/* Macro values need to be marked */
|
||||
#define VAL(x) \x
|
||||
|
||||
/* Due to MASM's reverse syntax, we are forced to use a precompiler macro */
|
||||
#define MACRO(...) .macro __VA_ARGS__
|
||||
#define ENDM .endm
|
||||
|
||||
/* To avoid reverse syntax we provide a new macro .PROC, replacing PROC... */
|
||||
.macro .PROC name
|
||||
.func \name
|
||||
\name:
|
||||
.cfi_startproc
|
||||
.equ cfa_current_offset, -8
|
||||
.endm
|
||||
|
||||
/* ... and .ENDP, replacing ENDP */
|
||||
.macro .ENDP name
|
||||
.cfi_endproc
|
||||
.endfunc
|
||||
.endm
|
||||
|
||||
/* MASM compatible PUBLIC */
|
||||
.macro PUBLIC symbol
|
||||
.global \symbol
|
||||
.endm
|
||||
|
||||
/* MASM compatible ALIGN */
|
||||
#define ALIGN .align
|
||||
|
||||
/* MASM compatible REPEAT, additional ENDR */
|
||||
#define REPEAT .rept
|
||||
#define ENDR .endr
|
||||
|
||||
/* MASM compatible EXTERN */
|
||||
.macro EXTERN name
|
||||
.endm
|
||||
|
||||
/* MASM needs an END tag */
|
||||
#define END
|
||||
|
||||
.macro .MODEL model
|
||||
.endm
|
||||
|
||||
.macro .code
|
||||
.text
|
||||
.endm
|
||||
|
||||
/* Macros for x64 stack unwind OPs */
|
||||
|
||||
.macro .allocstack size
|
||||
.cfi_adjust_cfa_offset \size
|
||||
.set cfa_current_offset, cfa_current_offset - \size
|
||||
.endm
|
||||
|
||||
code = 1
|
||||
.macro .pushframe param=0
|
||||
.if (\param)
|
||||
.cfi_adjust_cfa_offset 0x30
|
||||
.set cfa_current_offset, cfa_current_offset - 0x30
|
||||
.else
|
||||
.cfi_adjust_cfa_offset 0x28
|
||||
.set cfa_current_offset, cfa_current_offset - 0x28
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro .pushreg reg
|
||||
.cfi_adjust_cfa_offset 8
|
||||
.equ cfa_current_offset, cfa_current_offset - 8
|
||||
.cfi_offset \reg, cfa_current_offset
|
||||
.endm
|
||||
|
||||
.macro .savereg reg, offset
|
||||
// checkme!!!
|
||||
.cfi_offset \reg, \offset
|
||||
.endm
|
||||
|
||||
.macro .savexmm128 reg, offset
|
||||
// checkme!!!
|
||||
.cfi_offset \reg, \offset
|
||||
.endm
|
||||
|
||||
.macro .setframe reg, offset
|
||||
.cfi_def_cfa reg, \offset
|
||||
.equ cfa_current_offset, \offset
|
||||
.endm
|
||||
|
||||
.macro .endprolog
|
||||
.endm
|
||||
|
||||
.macro UNIMPLEMENTED2 file, line, func
|
||||
|
||||
jmp 3f
|
||||
1: .asciz "\func"
|
||||
2: .asciz \file
|
||||
3:
|
||||
sub rsp, 0x20
|
||||
lea rcx, MsgUnimplemented[rip]
|
||||
lea rdx, 1b[rip]
|
||||
lea r8, 2b[rip]
|
||||
mov r9, \line
|
||||
call DbgPrint
|
||||
add rsp, 0x20
|
||||
.endm
|
||||
#define UNIMPLEMENTED UNIMPLEMENTED2 __FILE__, __LINE__,
|
||||
|
||||
/* MASM/ML uses ".if" for runtime conditionals, and "if" for compile time
|
||||
conditionals. We therefore use "if", too. .if shouldn't be used at all */
|
||||
#define if .if
|
||||
#define endif .endif
|
||||
#define else .else
|
||||
#define elseif .elseif
|
||||
|
||||
#endif
|
|
@ -7,12 +7,16 @@
|
|||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <reactos/asm.h>
|
||||
#include <ndk/asm.h>
|
||||
#include <internal/i386/asmmacro.S>
|
||||
.intel_syntax noprefix
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
.code32
|
||||
.text
|
||||
|
||||
/*
|
||||
* NOTE: These functions must obey the following rules:
|
||||
* - Acquire locks only on MP systems.
|
||||
|
|
|
@ -7,12 +7,16 @@
|
|||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <reactos/asm.h>
|
||||
#include <ndk/asm.h>
|
||||
#include <internal/i386/asmmacro.S>
|
||||
.intel_syntax noprefix
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
.code32
|
||||
.text
|
||||
|
||||
/*
|
||||
* NOTE: These functions must obey the following rules:
|
||||
* - Acquire locks only on MP systems.
|
||||
|
|
|
@ -4,17 +4,12 @@
|
|||
* FILE: ntoskrnl/include/i386/asmmacro.S
|
||||
* PURPOSE: Assembly Macros for Spinlocks and common Trap Code
|
||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
||||
* Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ndk/asm.h>
|
||||
|
||||
// Arguments for idt
|
||||
#define INT_32_DPL0 0x8E00
|
||||
#define INT_32_DPL3 0xEE00
|
||||
|
||||
.intel_syntax noprefix
|
||||
#define INT_32_DPL0 HEX(08E00)
|
||||
#define INT_32_DPL3 HEX(0EE00)
|
||||
|
||||
//
|
||||
// These macros are inlined equivalents of KiAcquire/ReleaseSpinlock, that is,
|
||||
|
@ -30,7 +25,7 @@
|
|||
// #IFDEF CONFIG_SMP
|
||||
// .spin
|
||||
// <any necessary steps to be able to jump back safely>
|
||||
/ SPIN_ON_LOCK(reg, .BeginYourFunction)
|
||||
// SPIN_ON_LOCK(reg, .BeginYourFunction)
|
||||
// #ENDIF
|
||||
//
|
||||
#ifdef CONFIG_SMP
|
||||
|
@ -64,74 +59,139 @@
|
|||
//
|
||||
// @remark None.
|
||||
//
|
||||
.macro idt Handler, Bits
|
||||
MACRO(idt, Handler, Bits)
|
||||
.long \Handler
|
||||
.short \Bits
|
||||
.short KGDT_R0_CODE
|
||||
.endm
|
||||
ENDM
|
||||
|
||||
//
|
||||
// @name GENERATE_IDT_STUB
|
||||
//
|
||||
// This macro creates an IDT entry for an unexpected interrupt handler.
|
||||
//
|
||||
// @param None.
|
||||
//
|
||||
// @remark None.
|
||||
//
|
||||
.macro GENERATE_IDT_STUB Number
|
||||
idt _KiUnexpectedInterrupt&Number, INT_32_DPL0
|
||||
.endm
|
||||
|
||||
//
|
||||
// @name GENERATE_IDT_STUBS
|
||||
//
|
||||
// This macro creates unexpected interrupt IDT entries.
|
||||
//
|
||||
// @param None.
|
||||
//
|
||||
// @remark None.
|
||||
//
|
||||
.altmacro
|
||||
.macro GENERATE_IDT_STUBS
|
||||
.set i, 0
|
||||
.rept 208
|
||||
GENERATE_IDT_STUB %i
|
||||
.set i, i + 1
|
||||
.endr
|
||||
.endm
|
||||
KI_PUSH_FAKE_ERROR_CODE = HEX(0001)
|
||||
KI_UNUSED = HEX(0002)
|
||||
KI_NONVOLATILES_ONLY = HEX(0004)
|
||||
KI_FAST_SYSTEM_CALL = HEX(0008)
|
||||
KI_SOFTWARE_TRAP = HEX(0010)
|
||||
KI_HARDWARE_INT = HEX(0020)
|
||||
KI_DONT_SAVE_SEGS = HEX(0100)
|
||||
|
||||
//
|
||||
// @name GENERATE_INT_HANDLER
|
||||
//
|
||||
// This macro creates an unexpected interrupt handler.
|
||||
//
|
||||
// @param None.
|
||||
//
|
||||
// @remark None.
|
||||
//
|
||||
.macro GENERATE_INT_HANDLER Number
|
||||
.func KiUnexpectedInterrupt&Number
|
||||
_KiUnexpectedInterrupt&Number:
|
||||
mov eax, PRIMARY_VECTOR_BASE + Number
|
||||
jmp _KiEndUnexpectedRange@0
|
||||
.endfunc
|
||||
.endm
|
||||
MACRO(KiEnterTrap, Flags)
|
||||
LOCAL kernel_trap
|
||||
LOCAL not_v86_trap
|
||||
LOCAL set_sane_segs
|
||||
|
||||
/* Check what kind of trap frame this trap requires */
|
||||
if (Flags AND KI_FAST_SYSTEM_CALL)
|
||||
|
||||
/* SYSENTER requires us to build a complete ring transition trap frame */
|
||||
FrameSize = KTRAP_FRAME_V86_ES
|
||||
|
||||
/* Fixup fs. cx is free to clobber */
|
||||
mov cx, KGDT_R0_PCR
|
||||
mov fs, cx
|
||||
|
||||
/* Get pointer to the TSS */
|
||||
mov ecx, fs:[KPCR_TSS]
|
||||
|
||||
/* Get a stack pointer */
|
||||
mov esp, [ecx + KTSS_ESP0]
|
||||
|
||||
elseif (Flags AND KI_SOFTWARE_TRAP)
|
||||
|
||||
/* Software traps need a complete non-ring transition trap frame */
|
||||
FrameSize = KTRAP_FRAME_ESP
|
||||
|
||||
/* Software traps need to get their EIP from the caller's frame */
|
||||
pop eax
|
||||
|
||||
elseif (Flags AND KI_PUSH_FAKE_ERROR_CODE)
|
||||
|
||||
/* If the trap doesn't have an error code, we'll make space for it */
|
||||
FrameSize = KTRAP_FRAME_EIP
|
||||
|
||||
else
|
||||
|
||||
/* The trap already has an error code, so just make space for the rest */
|
||||
FrameSize = KTRAP_FRAME_ERROR_CODE
|
||||
|
||||
endif
|
||||
|
||||
/* Save nonvolatile registers */
|
||||
mov [esp - FrameSize + KTRAP_FRAME_EBP], ebp
|
||||
mov [esp - FrameSize + KTRAP_FRAME_EBX], ebx
|
||||
mov [esp - FrameSize + KTRAP_FRAME_ESI], esi
|
||||
mov [esp - FrameSize + KTRAP_FRAME_EDI], edi
|
||||
|
||||
/* Save eax for system calls, for use by the C handler */
|
||||
mov [esp - FrameSize + KTRAP_FRAME_EAX], eax
|
||||
|
||||
/* Does the caller want nonvolatiles only? */
|
||||
if ((Flags AND KI_NONVOLATILES_ONLY) == 0)
|
||||
/* Otherwise, save the volatiles as well */
|
||||
mov [esp - FrameSize + KTRAP_FRAME_ECX], ecx
|
||||
mov [esp - FrameSize + KTRAP_FRAME_EDX], edx
|
||||
endif
|
||||
|
||||
/* Save segment registers? */
|
||||
if ((Flags AND KI_DONT_SAVE_SEGS) == 0)
|
||||
|
||||
/* Check for V86 mode */
|
||||
test byte ptr [esp - FrameSize + KTRAP_FRAME_EFLAGS + 2], (EFLAGS_V86_MASK >> 16)
|
||||
jz not_v86_trap
|
||||
|
||||
/* Restore V8086 segments into Protected Mode segments */
|
||||
mov eax, [esp - FrameSize + KTRAP_FRAME_V86_DS]
|
||||
mov ecx, [esp - FrameSize + KTRAP_FRAME_V86_ES]
|
||||
mov [esp - FrameSize + KTRAP_FRAME_DS], eax
|
||||
mov [esp - FrameSize + KTRAP_FRAME_ES], ecx
|
||||
mov eax, [esp - FrameSize + KTRAP_FRAME_V86_FS]
|
||||
mov ecx, [esp - FrameSize + KTRAP_FRAME_V86_GS]
|
||||
mov [esp - FrameSize + KTRAP_FRAME_FS], eax
|
||||
mov [esp - FrameSize + KTRAP_FRAME_GS], ecx
|
||||
jmp set_sane_segs
|
||||
|
||||
not_v86_trap:
|
||||
|
||||
/* Save segment selectors */
|
||||
mov eax, ds
|
||||
mov ecx, es
|
||||
mov [esp - FrameSize + KTRAP_FRAME_DS], eax
|
||||
mov [esp - FrameSize + KTRAP_FRAME_ES], ecx
|
||||
mov eax, fs
|
||||
mov ecx, gs
|
||||
mov [esp - FrameSize + KTRAP_FRAME_FS], eax
|
||||
mov [esp - FrameSize + KTRAP_FRAME_GS], ecx
|
||||
|
||||
endif
|
||||
|
||||
set_sane_segs:
|
||||
/* Load correct data segments */
|
||||
mov ax, KGDT_R3_DATA OR RPL_MASK
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
|
||||
/* Fast system calls have fs already fixed */
|
||||
if ((Flags AND KI_FAST_SYSTEM_CALL) == 0)
|
||||
/* Otherwise fix fs now */
|
||||
mov ax, KGDT_R0_PCR
|
||||
mov fs, ax
|
||||
endif
|
||||
|
||||
/* Make space for this frame */
|
||||
sub esp, FrameSize
|
||||
|
||||
/* Clear direction flag */
|
||||
cld
|
||||
|
||||
/* Set parameter 1 (ECX) to point to the frame */
|
||||
mov ecx, esp
|
||||
|
||||
ENDM
|
||||
|
||||
MACRO(TRAP_ENTRY, Trap, Flags)
|
||||
EXTERN @&Trap&Handler@4 :PROC
|
||||
PUBLIC _&Trap
|
||||
_&Trap:
|
||||
KiEnterTrap Flags
|
||||
jmp @&Trap&Handler@4
|
||||
ENDM
|
||||
|
||||
//
|
||||
// @name GENERATE_INT_HANDLERS
|
||||
//
|
||||
// This macro creates the unexpected interrupt handlers.
|
||||
//
|
||||
// @param None.
|
||||
//
|
||||
// @remark None.
|
||||
//
|
||||
.altmacro
|
||||
.macro GENERATE_INT_HANDLERS
|
||||
.set i, 0
|
||||
.rept 208
|
||||
GENERATE_INT_HANDLER %i
|
||||
.set i, i + 1
|
||||
.endr
|
||||
.endm
|
||||
|
|
|
@ -196,68 +196,6 @@ KiIssueBop(VOID)
|
|||
asm volatile(".byte 0xC4\n.byte 0xC4\n");
|
||||
}
|
||||
|
||||
//
|
||||
// Returns whether or not this is a V86 trap by checking the EFLAGS field.
|
||||
//
|
||||
// FIXME: GCC 4.5 Can Improve this with "goto labels"
|
||||
//
|
||||
BOOLEAN
|
||||
FORCEINLINE
|
||||
KiIsV8086TrapSafe(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
BOOLEAN Result;
|
||||
|
||||
/*
|
||||
* The check MUST be done this way, as we guarantee that no DS/ES/FS segment
|
||||
* is used (since it might be garbage).
|
||||
*
|
||||
* Instead, we use the SS segment which is guaranteed to be correct. Because
|
||||
* operate in 32-bit flat mode, this works just fine.
|
||||
*/
|
||||
asm volatile
|
||||
(
|
||||
"testl $%c[f], %%ss:%1\n"
|
||||
"setnz %0\n"
|
||||
: "=a"(Result)
|
||||
: "m"(TrapFrame->EFlags),
|
||||
[f] "i"(EFLAGS_V86_MASK)
|
||||
);
|
||||
|
||||
/* If V86 flag was set */
|
||||
return Result;
|
||||
}
|
||||
|
||||
//
|
||||
// Returns whether or not this is a user-mode trap by checking the SegCs field.
|
||||
//
|
||||
// FIXME: GCC 4.5 Can Improve this with "goto labels"
|
||||
//
|
||||
BOOLEAN
|
||||
FORCEINLINE
|
||||
KiIsUserTrapSafe(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
BOOLEAN Result;
|
||||
|
||||
/*
|
||||
* The check MUST be done this way, as we guarantee that no DS/ES/FS segment
|
||||
* is used (since it might be garbage).
|
||||
*
|
||||
* Instead, we use the SS segment which is guaranteed to be correct. Because
|
||||
* operate in 32-bit flat mode, this works just fine.
|
||||
*/
|
||||
asm volatile
|
||||
(
|
||||
"cmp $%c[f], %%ss:%1\n"
|
||||
"setnz %0\n"
|
||||
: "=a"(Result)
|
||||
: "m"(TrapFrame->SegCs),
|
||||
[f] "i"(KGDT_R0_CODE)
|
||||
);
|
||||
|
||||
/* If V86 flag was set */
|
||||
return Result;
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
KiUserSystemCall(IN PKTRAP_FRAME TrapFrame)
|
||||
|
@ -281,30 +219,6 @@ KiUserSystemCall(IN PKTRAP_FRAME TrapFrame)
|
|||
);
|
||||
}
|
||||
|
||||
VOID
|
||||
FORCEINLINE
|
||||
KiSetSaneSegments(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
ULONG Ds, Es;
|
||||
|
||||
/*
|
||||
* We really have to get a good DS/ES first before touching any data.
|
||||
*
|
||||
* These two reads will either go in a register (with optimizations ON) or
|
||||
* a stack variable (which is on SS:ESP, guaranteed to be good/valid).
|
||||
*
|
||||
* Because the assembly is marked volatile, the order of instructions is
|
||||
* as-is, otherwise the optimizer could simply get rid of our DS/ES.
|
||||
*
|
||||
*/
|
||||
Ds = Ke386GetDs();
|
||||
Es = Ke386GetEs();
|
||||
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
||||
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
|
||||
TrapFrame->SegDs = Ds;
|
||||
TrapFrame->SegEs = Es;
|
||||
}
|
||||
|
||||
//
|
||||
// Generates an Exit Epilog Stub for the given name
|
||||
//
|
||||
|
@ -643,17 +557,9 @@ VOID
|
|||
FORCEINLINE
|
||||
KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Load correct registers */
|
||||
Ke386SetFs(KGDT_R0_PCR);
|
||||
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
||||
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
|
||||
|
||||
/* Save exception list */
|
||||
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
|
||||
|
||||
/* Clear direction flag */
|
||||
Ke386ClearDirectionFlag();
|
||||
|
||||
/* Save DR7 and check for debugging */
|
||||
TrapFrame->Dr7 = __readdr(7);
|
||||
if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
|
||||
|
@ -670,40 +576,10 @@ VOID
|
|||
FORCEINLINE
|
||||
KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Check for V86 mode, otherwise check for ring 3 code */
|
||||
if (__builtin_expect(KiIsV8086TrapSafe(TrapFrame), 0))
|
||||
{
|
||||
/* Set correct segments */
|
||||
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
||||
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
|
||||
Ke386SetFs(KGDT_R0_PCR);
|
||||
|
||||
/* Restore V8086 segments into Protected Mode segments */
|
||||
TrapFrame->SegFs = TrapFrame->V86Fs;
|
||||
TrapFrame->SegGs = TrapFrame->V86Gs;
|
||||
TrapFrame->SegDs = TrapFrame->V86Ds;
|
||||
TrapFrame->SegEs = TrapFrame->V86Es;
|
||||
}
|
||||
else if (__builtin_expect(KiIsUserTrapSafe(TrapFrame), 1)) /* Ring 3 is more common */
|
||||
{
|
||||
/* Switch to sane segments */
|
||||
KiSetSaneSegments(TrapFrame);
|
||||
|
||||
/* Save FS/GS */
|
||||
TrapFrame->SegFs = Ke386GetFs();
|
||||
TrapFrame->SegGs = Ke386GetGs();
|
||||
|
||||
/* Set correct FS */
|
||||
Ke386SetFs(KGDT_R0_PCR);
|
||||
}
|
||||
|
||||
/* Save exception list and terminate it */
|
||||
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
|
||||
KeGetPcr()->Tib.ExceptionList = EXCEPTION_CHAIN_END;
|
||||
|
||||
/* Clear direction flag */
|
||||
Ke386ClearDirectionFlag();
|
||||
|
||||
/* Flush DR7 and check for debugging */
|
||||
TrapFrame->Dr7 = 0;
|
||||
if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
|
||||
|
@ -723,30 +599,9 @@ VOID
|
|||
FORCEINLINE
|
||||
KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Switch to sane segments */
|
||||
KiSetSaneSegments(TrapFrame);
|
||||
|
||||
/* Now we can save the other segments and then switch to the correct FS */
|
||||
TrapFrame->SegFs = Ke386GetFs();
|
||||
TrapFrame->SegGs = Ke386GetGs();
|
||||
Ke386SetFs(KGDT_R0_PCR);
|
||||
|
||||
/* Save exception list */
|
||||
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
|
||||
|
||||
/* Check for V86 mode */
|
||||
if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0))
|
||||
{
|
||||
/* Restore V8086 segments into Protected Mode segments */
|
||||
TrapFrame->SegFs = TrapFrame->V86Fs;
|
||||
TrapFrame->SegGs = TrapFrame->V86Gs;
|
||||
TrapFrame->SegDs = TrapFrame->V86Ds;
|
||||
TrapFrame->SegEs = TrapFrame->V86Es;
|
||||
}
|
||||
|
||||
/* Clear direction flag */
|
||||
Ke386ClearDirectionFlag();
|
||||
|
||||
/* Flush DR7 and check for debugging */
|
||||
TrapFrame->Dr7 = 0;
|
||||
if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
|
||||
|
@ -759,130 +614,4 @@ KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
|
|||
KiFillTrapFrameDebug(TrapFrame);
|
||||
}
|
||||
|
||||
//
|
||||
// Generates a Trap Prolog Stub for the given name
|
||||
//
|
||||
#define KI_PUSH_FAKE_ERROR_CODE 0x1
|
||||
#define KI_UNUSED 0x2
|
||||
#define KI_NONVOLATILES_ONLY 0x4
|
||||
#define KI_FAST_SYSTEM_CALL 0x8
|
||||
#define KI_SOFTWARE_TRAP 0x10
|
||||
#define KI_HARDWARE_INT 0x20
|
||||
#define KiTrap(x, y) VOID DECLSPEC_NORETURN x(VOID) { KiTrapStub(y, x##Handler); UNREACHABLE; }
|
||||
#define KiTrampoline(x, y) VOID DECLSPEC_NOINLINE x(VOID) { KiTrapStub(y, x##Handler); }
|
||||
|
||||
//
|
||||
// Trap Prolog Stub
|
||||
//
|
||||
VOID
|
||||
FORCEINLINE
|
||||
KiTrapStub(IN ULONG Flags,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
ULONG FrameSize;
|
||||
|
||||
/* Is this a fast system call? They don't have a stack! */
|
||||
if (Flags & KI_FAST_SYSTEM_CALL) __asm__ __volatile__
|
||||
(
|
||||
"movl %%ss:%c[t], %%esp\n"
|
||||
"movl %c[e](%%esp), %%esp\n"
|
||||
:
|
||||
: [e] "i"(FIELD_OFFSET(KTSS, Esp0)),
|
||||
[t] "i"(&PCR->TSS)
|
||||
: "%esp"
|
||||
);
|
||||
|
||||
/* Check what kind of trap frame this trap requires */
|
||||
if (Flags & KI_SOFTWARE_TRAP)
|
||||
{
|
||||
/* Software traps need a complete non-ring transition trap frame */
|
||||
FrameSize = FIELD_OFFSET(KTRAP_FRAME, HardwareEsp);
|
||||
}
|
||||
else if (Flags & KI_FAST_SYSTEM_CALL)
|
||||
{
|
||||
/* SYSENTER requires us to build a complete ring transition trap frame */
|
||||
FrameSize = FIELD_OFFSET(KTRAP_FRAME, V86Es);
|
||||
|
||||
/* And it only preserves nonvolatile registers */
|
||||
Flags |= KI_NONVOLATILES_ONLY;
|
||||
}
|
||||
else if (Flags & KI_PUSH_FAKE_ERROR_CODE)
|
||||
{
|
||||
/* If the trap doesn't have an error code, we'll make space for it */
|
||||
FrameSize = FIELD_OFFSET(KTRAP_FRAME, Eip);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The trap already has an error code, so just make space for the rest */
|
||||
FrameSize = FIELD_OFFSET(KTRAP_FRAME, ErrCode);
|
||||
}
|
||||
|
||||
/* Software traps need to get their EIP from the caller's frame */
|
||||
if (Flags & KI_SOFTWARE_TRAP) __asm__ __volatile__ ("popl %%eax\n":::"%esp");
|
||||
|
||||
/* Save nonvolatile registers */
|
||||
__asm__ __volatile__
|
||||
(
|
||||
/* EBX, ESI, EDI and EBP are saved */
|
||||
"movl %%ebp, %c[p](%%esp)\n"
|
||||
"movl %%ebx, %c[b](%%esp)\n"
|
||||
"movl %%esi, %c[s](%%esp)\n"
|
||||
"movl %%edi, %c[i](%%esp)\n"
|
||||
:
|
||||
: [b] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Ebx)),
|
||||
[s] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Esi)),
|
||||
[i] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Edi)),
|
||||
[p] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Ebp))
|
||||
: "%esp"
|
||||
);
|
||||
|
||||
/* Does the caller want nonvolatiles only? */
|
||||
if (!(Flags & KI_NONVOLATILES_ONLY)) __asm__ __volatile__
|
||||
(
|
||||
/* Otherwise, save the volatiles as well */
|
||||
"movl %%eax, %c[a](%%esp)\n"
|
||||
"movl %%ecx, %c[c](%%esp)\n"
|
||||
"movl %%edx, %c[d](%%esp)\n"
|
||||
:
|
||||
: [a] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Eax)),
|
||||
[c] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Ecx)),
|
||||
[d] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Edx))
|
||||
: "%esp"
|
||||
);
|
||||
|
||||
/* Now set parameter 1 (ECX) to point to the frame */
|
||||
__asm__ __volatile__ ("movl %%esp, %%ecx\n":::"%esp");
|
||||
|
||||
/* Now go ahead and make space for this frame */
|
||||
__asm__ __volatile__ ("subl $%c[e],%%esp\n":: [e] "i"(FrameSize) : "%esp");
|
||||
__asm__ __volatile__ ("subl $%c[e],%%ecx\n":: [e] "i"(FrameSize) : "%ecx");
|
||||
|
||||
/*
|
||||
* For hardware interrupts, set parameter 2 (EDX) to hold KINTERRUPT.
|
||||
* This code will be dynamically patched when an interrupt is registered!
|
||||
*/
|
||||
if (Flags & KI_HARDWARE_INT) __asm__ __volatile__
|
||||
(
|
||||
".globl _KiInterruptTemplate2ndDispatch\n_KiInterruptTemplate2ndDispatch:\n"
|
||||
"movl $0, %%edx\n"
|
||||
".globl _KiInterruptTemplateObject\n_KiInterruptTemplateObject:\n"
|
||||
::: "%edx"
|
||||
);
|
||||
|
||||
/* Now jump to the C handler */
|
||||
if (Flags & KI_HARDWARE_INT)__asm__ __volatile__
|
||||
(
|
||||
/*
|
||||
* For hardware interrupts, use an absolute JMP instead of a relative JMP
|
||||
* since the position of this code is arbitrary in memory, and therefore
|
||||
* the compiler-generated offset will not be correct.
|
||||
*/
|
||||
"jmp *%0\n"
|
||||
".globl _KiInterruptTemplateDispatch\n_KiInterruptTemplateDispatch:\n"
|
||||
:
|
||||
: "a"(Handler)
|
||||
);
|
||||
else __asm__ __volatile__ ("jmp %c[x]\n":: [x] "i"(Handler));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -233,7 +233,7 @@ KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
|
|||
KIRQL OldIrql;
|
||||
BOOLEAN Handled;
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
|
||||
|
||||
/* Increase interrupt count */
|
||||
KeGetCurrentPrcb()->InterruptCount++;
|
||||
|
||||
|
@ -299,7 +299,7 @@ KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
|
|||
/* Now call the epilogue code */
|
||||
KiExitInterrupt(TrapFrame, OldIrql, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
|
@ -313,8 +313,6 @@ KiInterruptTemplateHandler(IN PKTRAP_FRAME TrapFrame,
|
|||
((PKI_INTERRUPT_DISPATCH*)Interrupt->DispatchAddress)(TrapFrame, Interrupt);
|
||||
}
|
||||
|
||||
KiTrap(KiInterruptTemplate, KI_PUSH_FAKE_ERROR_CODE | KI_HARDWARE_INT);
|
||||
KiTrap(KiUnexpectedInterruptTail, KI_PUSH_FAKE_ERROR_CODE);
|
||||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
|
|
|
@ -3,19 +3,33 @@
|
|||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PURPOSE: System Traps, Entrypoints and Exitpoints
|
||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||
* Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
* NOTE: See asmmacro.S for the shared entry/exit code.
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <asm.h>
|
||||
#include <reactos/asm.h>
|
||||
#include <ndk/i386/asm.h>
|
||||
#include <internal/i386/asmmacro.S>
|
||||
.intel_syntax noprefix
|
||||
|
||||
MACRO(GENERATE_IDT_STUB, Number)
|
||||
idt _KiUnexpectedInterrupt&Number, INT_32_DPL0
|
||||
ENDM
|
||||
|
||||
MACRO(GENERATE_INT_HANDLER, Number)
|
||||
.func KiUnexpectedInterrupt&Number
|
||||
_KiUnexpectedInterrupt&Number:
|
||||
mov eax, PRIMARY_VECTOR_BASE + Number
|
||||
jmp _KiEndUnexpectedRange@0
|
||||
.endfunc
|
||||
ENDM
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
.data
|
||||
.globl _KiIdt
|
||||
|
||||
PUBLIC _KiIdt
|
||||
_KiIdt:
|
||||
/* This is the Software Interrupt Table that we handle in this file: */
|
||||
idt _KiTrap00, INT_32_DPL0 /* INT 00: Divide Error (#DE) */
|
||||
|
@ -47,26 +61,86 @@ idt _KiRaiseAssertion, INT_32_DPL3 /* INT 2C: Debug Assertion Handler */
|
|||
idt _KiDebugService, INT_32_DPL3 /* INT 2D: Debug Service Handler */
|
||||
idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call Service Handler */
|
||||
idt _KiTrap0F, INT_32_DPL0 /* INT 2F: RESERVED */
|
||||
GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */
|
||||
i = 0
|
||||
.rept 208
|
||||
GENERATE_IDT_STUB %i
|
||||
i = i + 1
|
||||
.endr
|
||||
|
||||
.globl _KiIdtDescriptor
|
||||
PUBLIC _KiIdtDescriptor
|
||||
_KiIdtDescriptor:
|
||||
.short 0
|
||||
.short 0x7FF
|
||||
.long _KiIdt
|
||||
|
||||
.globl _KiUnexpectedEntrySize
|
||||
PUBLIC _KiUnexpectedEntrySize
|
||||
_KiUnexpectedEntrySize:
|
||||
.long _KiUnexpectedInterrupt1 - _KiUnexpectedInterrupt0
|
||||
|
||||
/******************************************************************************/
|
||||
.code32
|
||||
.text
|
||||
/* HARDWARE INTERRUPT HANDLERS ************************************************/
|
||||
|
||||
.globl _KiStartUnexpectedRange@0
|
||||
TRAP_ENTRY KiTrap00, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap01, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap03, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap04, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap05, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap06, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap07, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap08, 0
|
||||
TRAP_ENTRY KiTrap09, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap0A, 0
|
||||
TRAP_ENTRY KiTrap0B, 0
|
||||
TRAP_ENTRY KiTrap0C, 0
|
||||
TRAP_ENTRY KiTrap0D, 0
|
||||
TRAP_ENTRY KiTrap0E, 0
|
||||
TRAP_ENTRY KiTrap0F, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap10, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap11, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiTrap13, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiGetTickCount, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiCallbackReturn, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiRaiseAssertion, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiDebugService, KI_PUSH_FAKE_ERROR_CODE
|
||||
TRAP_ENTRY KiUnexpectedInterruptTail, KI_PUSH_FAKE_ERROR_CODE
|
||||
|
||||
ALIGN 4
|
||||
EXTERN @KiInterruptTemplateHandler@8
|
||||
PUBLIC _KiInterruptTemplate
|
||||
_KiInterruptTemplate:
|
||||
KiEnterTrap KI_PUSH_FAKE_ERROR_CODE
|
||||
PUBLIC _KiInterruptTemplate2ndDispatch
|
||||
_KiInterruptTemplate2ndDispatch:
|
||||
mov edx, 0
|
||||
PUBLIC _KiInterruptTemplateObject
|
||||
_KiInterruptTemplateObject:
|
||||
mov eax, offset @KiInterruptTemplateHandler@8
|
||||
jmp eax
|
||||
PUBLIC _KiInterruptTemplateDispatch
|
||||
_KiInterruptTemplateDispatch:
|
||||
|
||||
EXTERN @KiSystemServiceHandler@8:PROC
|
||||
PUBLIC _KiSystemService
|
||||
_KiSystemService:
|
||||
KiEnterTrap (KI_PUSH_FAKE_ERROR_CODE OR KI_NONVOLATILES_ONLY OR KI_DONT_SAVE_SEGS)
|
||||
jmp @KiSystemServiceHandler@8
|
||||
|
||||
EXTERN @KiFastCallEntryHandler@8:PROC
|
||||
PUBLIC _KiFastCallEntry
|
||||
_KiFastCallEntry:
|
||||
KiEnterTrap (KI_FAST_SYSTEM_CALL OR KI_NONVOLATILES_ONLY OR KI_DONT_SAVE_SEGS)
|
||||
jmp @KiFastCallEntryHandler@8
|
||||
|
||||
PUBLIC _KiStartUnexpectedRange@0
|
||||
_KiStartUnexpectedRange@0:
|
||||
|
||||
GENERATE_INT_HANDLERS
|
||||
|
||||
.globl _KiEndUnexpectedRange@0
|
||||
i = 0
|
||||
.rept 208
|
||||
GENERATE_INT_HANDLER %i
|
||||
i = i + 1
|
||||
.endr
|
||||
PUBLIC _KiEndUnexpectedRange@0
|
||||
_KiEndUnexpectedRange@0:
|
||||
jmp _KiUnexpectedInterruptTail
|
||||
|
||||
END
|
||||
|
|
|
@ -53,7 +53,15 @@ KiVdmTrap(IN PKTRAP_FRAME TrapFrame)
|
|||
return ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
|
||||
((KiUserTrap(TrapFrame)) && (PsGetCurrentProcess()->VdmObjects)));
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
FORCEINLINE
|
||||
KiV86Trap(IN PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
/* Check if the V8086 flag is on */
|
||||
return ((TrapFrame->EFlags & EFLAGS_V86_MASK) != 0);
|
||||
}
|
||||
|
||||
/* TRAP EXIT CODE *************************************************************/
|
||||
|
||||
VOID
|
||||
|
@ -223,7 +231,7 @@ KiNpxHandler(IN PKTRAP_FRAME TrapFrame,
|
|||
DataOffset,
|
||||
TrapFrame);
|
||||
}
|
||||
|
||||
|
||||
/* Check for invalid operation */
|
||||
if (Error & FSW_INVALID_OPERATION)
|
||||
{
|
||||
|
@ -540,7 +548,7 @@ KiTrap06Handler(IN PKTRAP_FRAME TrapFrame)
|
|||
KIRQL OldIrql;
|
||||
|
||||
/* Check for V86 GPF */
|
||||
if (__builtin_expect(KiIsV8086TrapSafe(TrapFrame), 1))
|
||||
if (__builtin_expect(KiV86Trap(TrapFrame), 1))
|
||||
{
|
||||
/* Enter V86 trap */
|
||||
KiEnterV86Trap(TrapFrame);
|
||||
|
@ -800,7 +808,7 @@ KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
KIRQL OldIrql;
|
||||
|
||||
/* Check for V86 GPF */
|
||||
if (__builtin_expect(KiIsV8086TrapSafe(TrapFrame), 1))
|
||||
if (__builtin_expect(KiV86Trap(TrapFrame), 1))
|
||||
{
|
||||
/* Enter V86 trap */
|
||||
KiEnterV86Trap(TrapFrame);
|
||||
|
@ -845,7 +853,7 @@ KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
|
||||
/* Check for user-mode GPF */
|
||||
if (KiUserTrap(TrapFrame))
|
||||
{
|
||||
{
|
||||
/* Should not be VDM */
|
||||
ASSERT(KiVdmTrap(TrapFrame) == FALSE);
|
||||
|
||||
|
@ -1502,19 +1510,13 @@ KiSystemCallHandler(IN PKTRAP_FRAME TrapFrame,
|
|||
}
|
||||
|
||||
VOID
|
||||
__attribute__((regparm(3)))
|
||||
FASTCALL
|
||||
DECLSPEC_NORETURN
|
||||
KiFastCallEntryHandler(IN ULONG ServiceNumber,
|
||||
IN PVOID Arguments,
|
||||
IN PKTRAP_FRAME TrapFrame)
|
||||
KiFastCallEntryHandler(IN PKTRAP_FRAME TrapFrame,
|
||||
IN PVOID Arguments)
|
||||
{
|
||||
PKTHREAD Thread;
|
||||
|
||||
/* Fixup segments */
|
||||
Ke386SetFs(KGDT_R0_PCR);
|
||||
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
||||
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
|
||||
|
||||
|
||||
/* Set up a fake INT Stack and enable interrupts */
|
||||
TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK;
|
||||
TrapFrame->HardwareEsp = (ULONG_PTR)Arguments;
|
||||
|
@ -1531,7 +1533,7 @@ KiFastCallEntryHandler(IN ULONG ServiceNumber,
|
|||
|
||||
/* Call the shared handler (inline) */
|
||||
KiSystemCallHandler(TrapFrame,
|
||||
ServiceNumber,
|
||||
TrapFrame->Eax,
|
||||
Arguments,
|
||||
Thread,
|
||||
UserMode,
|
||||
|
@ -1540,65 +1542,29 @@ KiFastCallEntryHandler(IN ULONG ServiceNumber,
|
|||
}
|
||||
|
||||
VOID
|
||||
__attribute__((regparm(3)))
|
||||
FASTCALL
|
||||
DECLSPEC_NORETURN
|
||||
KiSystemServiceHandler(IN ULONG ServiceNumber,
|
||||
IN PVOID Arguments,
|
||||
IN PKTRAP_FRAME TrapFrame)
|
||||
KiSystemServiceHandler(IN PKTRAP_FRAME TrapFrame,
|
||||
IN PVOID Arguments)
|
||||
{
|
||||
USHORT SegFs;
|
||||
PKTHREAD Thread;
|
||||
|
||||
/* Save and fixup FS */
|
||||
SegFs = Ke386GetFs();
|
||||
Ke386SetFs(KGDT_R0_PCR);
|
||||
|
||||
/* Get the current thread */
|
||||
Thread = KeGetCurrentThread();
|
||||
|
||||
/* Chain trap frames */
|
||||
TrapFrame->Edx = (ULONG_PTR)Thread->TrapFrame;
|
||||
|
||||
/* Clear direction flag */
|
||||
Ke386ClearDirectionFlag();
|
||||
|
||||
/* Call the shared handler (inline) */
|
||||
KiSystemCallHandler(TrapFrame,
|
||||
ServiceNumber,
|
||||
TrapFrame->Eax,
|
||||
Arguments,
|
||||
Thread,
|
||||
KiUserTrap(TrapFrame),
|
||||
Thread->PreviousMode,
|
||||
SegFs);
|
||||
TrapFrame->SegFs);
|
||||
}
|
||||
|
||||
/* CPU AND SOFTWARE TRAPS *****************************************************/
|
||||
|
||||
KiTrap(KiTrap00, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap01, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap03, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap04, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap05, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap06, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap07, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap08, 0);
|
||||
KiTrap(KiTrap09, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap0A, 0);
|
||||
KiTrap(KiTrap0B, 0);
|
||||
KiTrap(KiTrap0C, 0);
|
||||
KiTrap(KiTrap0D, 0);
|
||||
KiTrap(KiTrap0E, 0);
|
||||
KiTrap(KiTrap0F, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap10, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap11, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiTrap13, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiGetTickCount, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiCallbackReturn, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiRaiseAssertion, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiDebugService, KI_PUSH_FAKE_ERROR_CODE);
|
||||
KiTrap(KiSystemService, KI_PUSH_FAKE_ERROR_CODE | KI_NONVOLATILES_ONLY);
|
||||
KiTrap(KiFastCallEntry, KI_FAST_SYSTEM_CALL);
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
|
@ -8,12 +8,15 @@
|
|||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <asm.h>
|
||||
#include <reactos/asm.h>
|
||||
#include <ndk/i386/asm.h>
|
||||
#include <internal/i386/asmmacro.S>
|
||||
.intel_syntax noprefix
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
.code32
|
||||
.text
|
||||
|
||||
.globl _KiGetUserModeStackAddress@0
|
||||
.func KiGetUserModeStackAddress@0
|
||||
_KiGetUserModeStackAddress@0:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue