mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 12:26:09 +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>
|
#include <hal.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
void HalpTrap0D();
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
@ -47,6 +50,9 @@ ULONG_PTR HalpSavedEsp;
|
||||||
/* Where the real mode code ends */
|
/* Where the real mode code ends */
|
||||||
extern PVOID HalpRealModeEnd;
|
extern PVOID HalpRealModeEnd;
|
||||||
|
|
||||||
|
/* Context saved for return from v86 mode */
|
||||||
|
jmp_buf HalpSavedContext;
|
||||||
|
|
||||||
/* REAL MODE CODE AND STACK START HERE ****************************************/
|
/* REAL MODE CODE AND STACK START HERE ****************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -230,60 +236,44 @@ HalpTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
while (TRUE);
|
while (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
KiTrap(HalpTrap0D, 0);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
DECLSPEC_NORETURN
|
DECLSPEC_NORETURN
|
||||||
HalpTrap06(VOID)
|
HalpTrap06()
|
||||||
{
|
{
|
||||||
PKTRAP_FRAME TrapFrame;
|
|
||||||
|
|
||||||
/* Restore ES/DS to known good values first */
|
/* Restore ES/DS to known good values first */
|
||||||
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
|
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
|
||||||
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
||||||
|
|
||||||
/* Read trap frame address */
|
/* Restore the stack */
|
||||||
TrapFrame = (PKTRAP_FRAME)HalpSavedEsp;
|
KeGetPcr()->TSS->Esp0 = HalpSavedEsp0;
|
||||||
|
|
||||||
/* Restore segments from the trap frame */
|
/* Return back to where we left */
|
||||||
Ke386SetGs(TrapFrame->SegGs);
|
longjmp(HalpSavedContext, 1);
|
||||||
Ke386SetFs(TrapFrame->SegFs);
|
UNREACHABLE;
|
||||||
Ke386SetEs(TrapFrame->SegEs);
|
|
||||||
Ke386SetDs(TrapFrame->SegDs);
|
|
||||||
|
|
||||||
/* Restore EFlags */
|
|
||||||
__writeeflags(TrapFrame->EFlags);
|
|
||||||
|
|
||||||
/* Exit the V86 mode trap frame */
|
|
||||||
KiCallReturn(TrapFrame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* V8086 ENTER ****************************************************************/
|
/* V8086 ENTER ****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
NTAPI
|
||||||
DECLSPEC_NORETURN
|
HalpBiosCall()
|
||||||
HalpBiosCallHandler(IN PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
{
|
||||||
/* Must be volatile so it doesn't get optimized away! */
|
/* Must be volatile so it doesn't get optimized away! */
|
||||||
volatile KTRAP_FRAME V86TrapFrame;
|
volatile KTRAP_FRAME V86TrapFrame;
|
||||||
ULONG_PTR StackOffset, CodeOffset;
|
ULONG_PTR StackOffset, CodeOffset;
|
||||||
|
|
||||||
/* Fill out the quick-n-dirty trap frame */
|
/* Save the context, check for return */
|
||||||
TrapFrame->EFlags = __readeflags();
|
if (_setjmp(HalpSavedContext))
|
||||||
TrapFrame->SegGs = Ke386GetGs();
|
{
|
||||||
TrapFrame->SegFs = Ke386GetFs();
|
/* Returned from v86 */
|
||||||
TrapFrame->SegEs = Ke386GetEs();
|
return;
|
||||||
TrapFrame->SegDs = Ke386GetDs();
|
}
|
||||||
|
|
||||||
/* Our stack (the frame) */
|
|
||||||
HalpSavedEsp = (ULONG_PTR)TrapFrame;
|
|
||||||
|
|
||||||
/* Kill alignment faults */
|
/* Kill alignment faults */
|
||||||
__writecr0(__readcr0() & ~CR0_AM);
|
__writecr0(__readcr0() & ~CR0_AM);
|
||||||
|
|
||||||
/* Set new stack address */
|
/* 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 */
|
/* Compute segmented IP and SP offsets */
|
||||||
StackOffset = (ULONG_PTR)&HalpRealModeEnd - 4 - (ULONG_PTR)HalpRealModeStart;
|
StackOffset = (ULONG_PTR)&HalpRealModeEnd - 4 - (ULONG_PTR)HalpRealModeStart;
|
||||||
|
@ -304,8 +294,6 @@ HalpBiosCallHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
KiDirectTrapReturn((PKTRAP_FRAME)&V86TrapFrame);
|
KiDirectTrapReturn((PKTRAP_FRAME)&V86TrapFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
KiTrampoline(HalpBiosCall, KI_PUSH_FAKE_ERROR_CODE | KI_NONVOLATILES_ONLY);
|
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -1335,4 +1335,3 @@ HalpDispatchInterrupt2(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KiTrap(HalpApcInterrupt, KI_SOFTWARE_TRAP);
|
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <asm.h>
|
#include <asm.h>
|
||||||
#include <internal/i386/asmmacro.S>
|
|
||||||
.intel_syntax noprefix
|
.intel_syntax noprefix
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
|
@ -161,8 +161,6 @@ HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
KiEoiHelper(TrapFrame);
|
KiEoiHelper(TrapFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
KiTrap(HalpClockInterrupt, KI_PUSH_FAKE_ERROR_CODE);
|
|
||||||
KiTrap(HalpProfileInterrupt, KI_PUSH_FAKE_ERROR_CODE);
|
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* 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</library>
|
||||||
<library>hal_generic_up</library>
|
<library>hal_generic_up</library>
|
||||||
<library>ntoskrnl</library>
|
<library>ntoskrnl</library>
|
||||||
|
<library>libcntpr</library>
|
||||||
<directory name="up">
|
<directory name="up">
|
||||||
<file>halinit_up.c</file>
|
<file>halinit_up.c</file>
|
||||||
<file>halup.rc</file>
|
<file>halup.rc</file>
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
<file>sysinfo.c</file>
|
<file>sysinfo.c</file>
|
||||||
<file>systimer.S</file>
|
<file>systimer.S</file>
|
||||||
<file>timer.c</file>
|
<file>timer.c</file>
|
||||||
|
<file>trap.S</file>
|
||||||
<file>usage.c</file>
|
<file>usage.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
<directory name="include">
|
<directory name="include">
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<library>hal_generic</library>
|
<library>hal_generic</library>
|
||||||
<library>hal_generic_mp</library>
|
<library>hal_generic_mp</library>
|
||||||
<library>ntoskrnl</library>
|
<library>ntoskrnl</library>
|
||||||
|
<library>libcntpr</library>
|
||||||
<directory name="mp">
|
<directory name="mp">
|
||||||
<file>mps.S</file>
|
<file>mps.S</file>
|
||||||
<file>mpsboot.asm</file>
|
<file>mpsboot.asm</file>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<library>hal_generic</library>
|
<library>hal_generic</library>
|
||||||
<library>hal_generic_up</library>
|
<library>hal_generic_up</library>
|
||||||
<library>ntoskrnl</library>
|
<library>ntoskrnl</library>
|
||||||
|
<library>libcntpr</library>
|
||||||
<directory name="xbox">
|
<directory name="xbox">
|
||||||
<file>halinit_xbox.c</file>
|
<file>halinit_xbox.c</file>
|
||||||
<file>part_xbox.c</file>
|
<file>part_xbox.c</file>
|
||||||
|
|
|
@ -1110,4 +1110,25 @@ HaliStartApplicationProcessor(ULONG Cpu, ULONG Stack)
|
||||||
|
|
||||||
#endif
|
#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 */
|
/* EOF */
|
||||||
|
|
|
@ -248,10 +248,12 @@ Author:
|
||||||
#define KINTERRUPT_SERVICE_CONTEXT 0x10
|
#define KINTERRUPT_SERVICE_CONTEXT 0x10
|
||||||
#define KINTERRUPT_TICK_COUNT 0x18
|
#define KINTERRUPT_TICK_COUNT 0x18
|
||||||
#define KINTERRUPT_ACTUAL_LOCK 0x1C
|
#define KINTERRUPT_ACTUAL_LOCK 0x1C
|
||||||
|
#define KINTERRUPT_DISPATCH_ADDRESS 0x20
|
||||||
#define KINTERRUPT_VECTOR 0x24
|
#define KINTERRUPT_VECTOR 0x24
|
||||||
#define KINTERRUPT_IRQL 0x28
|
#define KINTERRUPT_IRQL 0x28
|
||||||
#define KINTERRUPT_SYNCHRONIZE_IRQL 0x29
|
#define KINTERRUPT_SYNCHRONIZE_IRQL 0x29
|
||||||
#define KINTERRUPT_DISPATCH_COUNT 0x38
|
#define KINTERRUPT_DISPATCH_COUNT 0x38
|
||||||
|
#define KINTERRUPT_DISPATCH_CODE 0x3C
|
||||||
|
|
||||||
//
|
//
|
||||||
// KGDTENTRY Offsets
|
// 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 ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <reactos/asm.h>
|
||||||
#include <ndk/asm.h>
|
#include <ndk/asm.h>
|
||||||
#include <internal/i386/asmmacro.S>
|
#include <internal/i386/asmmacro.S>
|
||||||
.intel_syntax noprefix
|
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
.code32
|
||||||
|
.text
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: These functions must obey the following rules:
|
* NOTE: These functions must obey the following rules:
|
||||||
* - Acquire locks only on MP systems.
|
* - Acquire locks only on MP systems.
|
||||||
|
|
|
@ -7,12 +7,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <reactos/asm.h>
|
||||||
#include <ndk/asm.h>
|
#include <ndk/asm.h>
|
||||||
#include <internal/i386/asmmacro.S>
|
#include <internal/i386/asmmacro.S>
|
||||||
.intel_syntax noprefix
|
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
.code32
|
||||||
|
.text
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: These functions must obey the following rules:
|
* NOTE: These functions must obey the following rules:
|
||||||
* - Acquire locks only on MP systems.
|
* - Acquire locks only on MP systems.
|
||||||
|
|
|
@ -4,17 +4,12 @@
|
||||||
* FILE: ntoskrnl/include/i386/asmmacro.S
|
* FILE: ntoskrnl/include/i386/asmmacro.S
|
||||||
* PURPOSE: Assembly Macros for Spinlocks and common Trap Code
|
* PURPOSE: Assembly Macros for Spinlocks and common Trap Code
|
||||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
||||||
|
* Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
|
||||||
|
|
||||||
#include <ndk/asm.h>
|
|
||||||
|
|
||||||
// Arguments for idt
|
// Arguments for idt
|
||||||
#define INT_32_DPL0 0x8E00
|
#define INT_32_DPL0 HEX(08E00)
|
||||||
#define INT_32_DPL3 0xEE00
|
#define INT_32_DPL3 HEX(0EE00)
|
||||||
|
|
||||||
.intel_syntax noprefix
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// These macros are inlined equivalents of KiAcquire/ReleaseSpinlock, that is,
|
// These macros are inlined equivalents of KiAcquire/ReleaseSpinlock, that is,
|
||||||
|
@ -30,7 +25,7 @@
|
||||||
// #IFDEF CONFIG_SMP
|
// #IFDEF CONFIG_SMP
|
||||||
// .spin
|
// .spin
|
||||||
// <any necessary steps to be able to jump back safely>
|
// <any necessary steps to be able to jump back safely>
|
||||||
/ SPIN_ON_LOCK(reg, .BeginYourFunction)
|
// SPIN_ON_LOCK(reg, .BeginYourFunction)
|
||||||
// #ENDIF
|
// #ENDIF
|
||||||
//
|
//
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
@ -64,74 +59,139 @@
|
||||||
//
|
//
|
||||||
// @remark None.
|
// @remark None.
|
||||||
//
|
//
|
||||||
.macro idt Handler, Bits
|
MACRO(idt, Handler, Bits)
|
||||||
.long \Handler
|
.long \Handler
|
||||||
.short \Bits
|
.short \Bits
|
||||||
.short KGDT_R0_CODE
|
.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
|
|
||||||
|
|
||||||
//
|
KI_PUSH_FAKE_ERROR_CODE = HEX(0001)
|
||||||
// @name GENERATE_IDT_STUBS
|
KI_UNUSED = HEX(0002)
|
||||||
//
|
KI_NONVOLATILES_ONLY = HEX(0004)
|
||||||
// This macro creates unexpected interrupt IDT entries.
|
KI_FAST_SYSTEM_CALL = HEX(0008)
|
||||||
//
|
KI_SOFTWARE_TRAP = HEX(0010)
|
||||||
// @param None.
|
KI_HARDWARE_INT = HEX(0020)
|
||||||
//
|
KI_DONT_SAVE_SEGS = HEX(0100)
|
||||||
// @remark None.
|
|
||||||
//
|
|
||||||
.altmacro
|
|
||||||
.macro GENERATE_IDT_STUBS
|
|
||||||
.set i, 0
|
|
||||||
.rept 208
|
|
||||||
GENERATE_IDT_STUB %i
|
|
||||||
.set i, i + 1
|
|
||||||
.endr
|
|
||||||
.endm
|
|
||||||
|
|
||||||
//
|
MACRO(KiEnterTrap, Flags)
|
||||||
// @name GENERATE_INT_HANDLER
|
LOCAL kernel_trap
|
||||||
//
|
LOCAL not_v86_trap
|
||||||
// This macro creates an unexpected interrupt handler.
|
LOCAL set_sane_segs
|
||||||
//
|
|
||||||
// @param None.
|
/* Check what kind of trap frame this trap requires */
|
||||||
//
|
if (Flags AND KI_FAST_SYSTEM_CALL)
|
||||||
// @remark None.
|
|
||||||
//
|
/* SYSENTER requires us to build a complete ring transition trap frame */
|
||||||
.macro GENERATE_INT_HANDLER Number
|
FrameSize = KTRAP_FRAME_V86_ES
|
||||||
.func KiUnexpectedInterrupt&Number
|
|
||||||
_KiUnexpectedInterrupt&Number:
|
/* Fixup fs. cx is free to clobber */
|
||||||
mov eax, PRIMARY_VECTOR_BASE + Number
|
mov cx, KGDT_R0_PCR
|
||||||
jmp _KiEndUnexpectedRange@0
|
mov fs, cx
|
||||||
.endfunc
|
|
||||||
.endm
|
/* 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");
|
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
|
VOID
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
KiUserSystemCall(IN PKTRAP_FRAME TrapFrame)
|
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
|
// Generates an Exit Epilog Stub for the given name
|
||||||
//
|
//
|
||||||
|
@ -643,17 +557,9 @@ VOID
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
|
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 */
|
/* Save exception list */
|
||||||
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
|
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
|
||||||
|
|
||||||
/* Clear direction flag */
|
|
||||||
Ke386ClearDirectionFlag();
|
|
||||||
|
|
||||||
/* Save DR7 and check for debugging */
|
/* Save DR7 and check for debugging */
|
||||||
TrapFrame->Dr7 = __readdr(7);
|
TrapFrame->Dr7 = __readdr(7);
|
||||||
if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
|
if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
|
||||||
|
@ -670,40 +576,10 @@ VOID
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
|
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 */
|
/* Save exception list and terminate it */
|
||||||
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
|
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
|
||||||
KeGetPcr()->Tib.ExceptionList = EXCEPTION_CHAIN_END;
|
KeGetPcr()->Tib.ExceptionList = EXCEPTION_CHAIN_END;
|
||||||
|
|
||||||
/* Clear direction flag */
|
|
||||||
Ke386ClearDirectionFlag();
|
|
||||||
|
|
||||||
/* Flush DR7 and check for debugging */
|
/* Flush DR7 and check for debugging */
|
||||||
TrapFrame->Dr7 = 0;
|
TrapFrame->Dr7 = 0;
|
||||||
if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
|
if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
|
||||||
|
@ -723,30 +599,9 @@ VOID
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
|
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 */
|
/* Save exception list */
|
||||||
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
|
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 */
|
/* Flush DR7 and check for debugging */
|
||||||
TrapFrame->Dr7 = 0;
|
TrapFrame->Dr7 = 0;
|
||||||
if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
|
if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader.DebugActive & 0xFF, 0))
|
||||||
|
@ -759,130 +614,4 @@ KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
|
||||||
KiFillTrapFrameDebug(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
|
#endif
|
||||||
|
|
|
@ -233,7 +233,7 @@ KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
BOOLEAN Handled;
|
BOOLEAN Handled;
|
||||||
PLIST_ENTRY NextEntry, ListHead;
|
PLIST_ENTRY NextEntry, ListHead;
|
||||||
|
|
||||||
/* Increase interrupt count */
|
/* Increase interrupt count */
|
||||||
KeGetCurrentPrcb()->InterruptCount++;
|
KeGetCurrentPrcb()->InterruptCount++;
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ KiChainedDispatch(IN PKTRAP_FRAME TrapFrame,
|
||||||
/* Now call the epilogue code */
|
/* Now call the epilogue code */
|
||||||
KiExitInterrupt(TrapFrame, OldIrql, TRUE);
|
KiExitInterrupt(TrapFrame, OldIrql, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
|
@ -313,8 +313,6 @@ KiInterruptTemplateHandler(IN PKTRAP_FRAME TrapFrame,
|
||||||
((PKI_INTERRUPT_DISPATCH*)Interrupt->DispatchAddress)(TrapFrame, Interrupt);
|
((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 **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,33 @@
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PURPOSE: System Traps, Entrypoints and Exitpoints
|
* PURPOSE: System Traps, Entrypoints and Exitpoints
|
||||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||||
|
* Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||||
* NOTE: See asmmacro.S for the shared entry/exit code.
|
* NOTE: See asmmacro.S for the shared entry/exit code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <asm.h>
|
#include <reactos/asm.h>
|
||||||
|
#include <ndk/i386/asm.h>
|
||||||
#include <internal/i386/asmmacro.S>
|
#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 *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
.data
|
.data
|
||||||
.globl _KiIdt
|
|
||||||
|
PUBLIC _KiIdt
|
||||||
_KiIdt:
|
_KiIdt:
|
||||||
/* This is the Software Interrupt Table that we handle in this file: */
|
/* This is the Software Interrupt Table that we handle in this file: */
|
||||||
idt _KiTrap00, INT_32_DPL0 /* INT 00: Divide Error (#DE) */
|
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 _KiDebugService, INT_32_DPL3 /* INT 2D: Debug Service Handler */
|
||||||
idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call Service Handler */
|
idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call Service Handler */
|
||||||
idt _KiTrap0F, INT_32_DPL0 /* INT 2F: RESERVED */
|
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:
|
_KiIdtDescriptor:
|
||||||
.short 0
|
.short 0
|
||||||
.short 0x7FF
|
.short 0x7FF
|
||||||
.long _KiIdt
|
.long _KiIdt
|
||||||
|
|
||||||
.globl _KiUnexpectedEntrySize
|
PUBLIC _KiUnexpectedEntrySize
|
||||||
_KiUnexpectedEntrySize:
|
_KiUnexpectedEntrySize:
|
||||||
.long _KiUnexpectedInterrupt1 - _KiUnexpectedInterrupt0
|
.long _KiUnexpectedInterrupt1 - _KiUnexpectedInterrupt0
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
.code32
|
||||||
.text
|
.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:
|
_KiStartUnexpectedRange@0:
|
||||||
|
i = 0
|
||||||
GENERATE_INT_HANDLERS
|
.rept 208
|
||||||
|
GENERATE_INT_HANDLER %i
|
||||||
.globl _KiEndUnexpectedRange@0
|
i = i + 1
|
||||||
|
.endr
|
||||||
|
PUBLIC _KiEndUnexpectedRange@0
|
||||||
_KiEndUnexpectedRange@0:
|
_KiEndUnexpectedRange@0:
|
||||||
jmp _KiUnexpectedInterruptTail
|
jmp _KiUnexpectedInterruptTail
|
||||||
|
|
||||||
|
END
|
||||||
|
|
|
@ -53,7 +53,15 @@ KiVdmTrap(IN PKTRAP_FRAME TrapFrame)
|
||||||
return ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
|
return ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
|
||||||
((KiUserTrap(TrapFrame)) && (PsGetCurrentProcess()->VdmObjects)));
|
((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 *************************************************************/
|
/* TRAP EXIT CODE *************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -223,7 +231,7 @@ KiNpxHandler(IN PKTRAP_FRAME TrapFrame,
|
||||||
DataOffset,
|
DataOffset,
|
||||||
TrapFrame);
|
TrapFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for invalid operation */
|
/* Check for invalid operation */
|
||||||
if (Error & FSW_INVALID_OPERATION)
|
if (Error & FSW_INVALID_OPERATION)
|
||||||
{
|
{
|
||||||
|
@ -540,7 +548,7 @@ KiTrap06Handler(IN PKTRAP_FRAME TrapFrame)
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
|
||||||
/* Check for V86 GPF */
|
/* Check for V86 GPF */
|
||||||
if (__builtin_expect(KiIsV8086TrapSafe(TrapFrame), 1))
|
if (__builtin_expect(KiV86Trap(TrapFrame), 1))
|
||||||
{
|
{
|
||||||
/* Enter V86 trap */
|
/* Enter V86 trap */
|
||||||
KiEnterV86Trap(TrapFrame);
|
KiEnterV86Trap(TrapFrame);
|
||||||
|
@ -800,7 +808,7 @@ KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
|
||||||
/* Check for V86 GPF */
|
/* Check for V86 GPF */
|
||||||
if (__builtin_expect(KiIsV8086TrapSafe(TrapFrame), 1))
|
if (__builtin_expect(KiV86Trap(TrapFrame), 1))
|
||||||
{
|
{
|
||||||
/* Enter V86 trap */
|
/* Enter V86 trap */
|
||||||
KiEnterV86Trap(TrapFrame);
|
KiEnterV86Trap(TrapFrame);
|
||||||
|
@ -845,7 +853,7 @@ KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
|
||||||
/* Check for user-mode GPF */
|
/* Check for user-mode GPF */
|
||||||
if (KiUserTrap(TrapFrame))
|
if (KiUserTrap(TrapFrame))
|
||||||
{
|
{
|
||||||
/* Should not be VDM */
|
/* Should not be VDM */
|
||||||
ASSERT(KiVdmTrap(TrapFrame) == FALSE);
|
ASSERT(KiVdmTrap(TrapFrame) == FALSE);
|
||||||
|
|
||||||
|
@ -1502,19 +1510,13 @@ KiSystemCallHandler(IN PKTRAP_FRAME TrapFrame,
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
__attribute__((regparm(3)))
|
FASTCALL
|
||||||
DECLSPEC_NORETURN
|
DECLSPEC_NORETURN
|
||||||
KiFastCallEntryHandler(IN ULONG ServiceNumber,
|
KiFastCallEntryHandler(IN PKTRAP_FRAME TrapFrame,
|
||||||
IN PVOID Arguments,
|
IN PVOID Arguments)
|
||||||
IN PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
{
|
||||||
PKTHREAD Thread;
|
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 */
|
/* Set up a fake INT Stack and enable interrupts */
|
||||||
TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK;
|
TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK;
|
||||||
TrapFrame->HardwareEsp = (ULONG_PTR)Arguments;
|
TrapFrame->HardwareEsp = (ULONG_PTR)Arguments;
|
||||||
|
@ -1531,7 +1533,7 @@ KiFastCallEntryHandler(IN ULONG ServiceNumber,
|
||||||
|
|
||||||
/* Call the shared handler (inline) */
|
/* Call the shared handler (inline) */
|
||||||
KiSystemCallHandler(TrapFrame,
|
KiSystemCallHandler(TrapFrame,
|
||||||
ServiceNumber,
|
TrapFrame->Eax,
|
||||||
Arguments,
|
Arguments,
|
||||||
Thread,
|
Thread,
|
||||||
UserMode,
|
UserMode,
|
||||||
|
@ -1540,65 +1542,29 @@ KiFastCallEntryHandler(IN ULONG ServiceNumber,
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
__attribute__((regparm(3)))
|
FASTCALL
|
||||||
DECLSPEC_NORETURN
|
DECLSPEC_NORETURN
|
||||||
KiSystemServiceHandler(IN ULONG ServiceNumber,
|
KiSystemServiceHandler(IN PKTRAP_FRAME TrapFrame,
|
||||||
IN PVOID Arguments,
|
IN PVOID Arguments)
|
||||||
IN PKTRAP_FRAME TrapFrame)
|
|
||||||
{
|
{
|
||||||
USHORT SegFs;
|
|
||||||
PKTHREAD Thread;
|
PKTHREAD Thread;
|
||||||
|
|
||||||
/* Save and fixup FS */
|
|
||||||
SegFs = Ke386GetFs();
|
|
||||||
Ke386SetFs(KGDT_R0_PCR);
|
|
||||||
|
|
||||||
/* Get the current thread */
|
/* Get the current thread */
|
||||||
Thread = KeGetCurrentThread();
|
Thread = KeGetCurrentThread();
|
||||||
|
|
||||||
/* Chain trap frames */
|
/* Chain trap frames */
|
||||||
TrapFrame->Edx = (ULONG_PTR)Thread->TrapFrame;
|
TrapFrame->Edx = (ULONG_PTR)Thread->TrapFrame;
|
||||||
|
|
||||||
/* Clear direction flag */
|
|
||||||
Ke386ClearDirectionFlag();
|
|
||||||
|
|
||||||
/* Call the shared handler (inline) */
|
/* Call the shared handler (inline) */
|
||||||
KiSystemCallHandler(TrapFrame,
|
KiSystemCallHandler(TrapFrame,
|
||||||
ServiceNumber,
|
TrapFrame->Eax,
|
||||||
Arguments,
|
Arguments,
|
||||||
Thread,
|
Thread,
|
||||||
KiUserTrap(TrapFrame),
|
KiUserTrap(TrapFrame),
|
||||||
Thread->PreviousMode,
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,12 +8,15 @@
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <asm.h>
|
#include <reactos/asm.h>
|
||||||
|
#include <ndk/i386/asm.h>
|
||||||
#include <internal/i386/asmmacro.S>
|
#include <internal/i386/asmmacro.S>
|
||||||
.intel_syntax noprefix
|
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
.code32
|
||||||
|
.text
|
||||||
|
|
||||||
.globl _KiGetUserModeStackAddress@0
|
.globl _KiGetUserModeStackAddress@0
|
||||||
.func KiGetUserModeStackAddress@0
|
.func KiGetUserModeStackAddress@0
|
||||||
_KiGetUserModeStackAddress@0:
|
_KiGetUserModeStackAddress@0:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue