From dd6b443e89070a9550d5e8c9b374c17082cca84e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 10 Feb 2010 23:24:59 +0000 Subject: [PATCH] [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 --- reactos/hal/halx86/generic/bios.c | 58 ++-- reactos/hal/halx86/generic/pic.c | 1 - reactos/hal/halx86/generic/systimer.S | 1 - reactos/hal/halx86/generic/timer.c | 2 - reactos/hal/halx86/generic/trap.S | 23 ++ reactos/hal/halx86/hal.rbuild | 1 + reactos/hal/halx86/hal_generic.rbuild | 1 + reactos/hal/halx86/halmps.rbuild | 1 + reactos/hal/halx86/halxbox.rbuild | 1 + reactos/hal/halx86/mp/apic.c | 21 ++ reactos/include/ndk/i386/asm.h | 2 + reactos/include/reactos/asm.h | 190 ++++++++++++ reactos/ntoskrnl/ex/i386/fastinterlck_asm.S | 6 +- reactos/ntoskrnl/ex/i386/interlck_asm.S | 6 +- .../ntoskrnl/include/internal/i386/asmmacro.S | 206 ++++++++----- reactos/ntoskrnl/include/internal/trap_x.h | 271 ------------------ reactos/ntoskrnl/ke/i386/irqobj.c | 6 +- reactos/ntoskrnl/ke/i386/trap.s | 98 ++++++- reactos/ntoskrnl/ke/i386/traphdlr.c | 80 ++---- reactos/ntoskrnl/ke/i386/usercall_asm.S | 7 +- 20 files changed, 522 insertions(+), 460 deletions(-) create mode 100644 reactos/hal/halx86/generic/trap.S create mode 100644 reactos/include/reactos/asm.h diff --git a/reactos/hal/halx86/generic/bios.c b/reactos/hal/halx86/generic/bios.c index 206ca2d3e3d..262fdd17207 100644 --- a/reactos/hal/halx86/generic/bios.c +++ b/reactos/hal/halx86/generic/bios.c @@ -12,6 +12,9 @@ #include #define NDEBUG #include +#include + +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 diff --git a/reactos/hal/halx86/generic/pic.c b/reactos/hal/halx86/generic/pic.c index 17adf0a8765..7197b9d91a8 100644 --- a/reactos/hal/halx86/generic/pic.c +++ b/reactos/hal/halx86/generic/pic.c @@ -1335,4 +1335,3 @@ HalpDispatchInterrupt2(VOID) } } -KiTrap(HalpApcInterrupt, KI_SOFTWARE_TRAP); diff --git a/reactos/hal/halx86/generic/systimer.S b/reactos/hal/halx86/generic/systimer.S index 82825b046ce..167bcf5fefd 100644 --- a/reactos/hal/halx86/generic/systimer.S +++ b/reactos/hal/halx86/generic/systimer.S @@ -8,7 +8,6 @@ /* INCLUDES ******************************************************************/ #include -#include .intel_syntax noprefix /* GLOBALS *******************************************************************/ diff --git a/reactos/hal/halx86/generic/timer.c b/reactos/hal/halx86/generic/timer.c index e44259d010f..360d237443d 100644 --- a/reactos/hal/halx86/generic/timer.c +++ b/reactos/hal/halx86/generic/timer.c @@ -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 ***********************************************************/ diff --git a/reactos/hal/halx86/generic/trap.S b/reactos/hal/halx86/generic/trap.S new file mode 100644 index 00000000000..00fc256387e --- /dev/null +++ b/reactos/hal/halx86/generic/trap.S @@ -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 +#include +#include + +.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 + + diff --git a/reactos/hal/halx86/hal.rbuild b/reactos/hal/halx86/hal.rbuild index e4f7ea6f8da..d87973eb898 100644 --- a/reactos/hal/halx86/hal.rbuild +++ b/reactos/hal/halx86/hal.rbuild @@ -10,6 +10,7 @@ hal_generic hal_generic_up ntoskrnl + libcntpr halinit_up.c halup.rc diff --git a/reactos/hal/halx86/hal_generic.rbuild b/reactos/hal/halx86/hal_generic.rbuild index 9ec3d59bf8e..a8c64ac7bbb 100644 --- a/reactos/hal/halx86/hal_generic.rbuild +++ b/reactos/hal/halx86/hal_generic.rbuild @@ -28,6 +28,7 @@ sysinfo.c systimer.S timer.c + trap.S usage.c diff --git a/reactos/hal/halx86/halmps.rbuild b/reactos/hal/halx86/halmps.rbuild index 74a9f822107..458a58506c1 100644 --- a/reactos/hal/halx86/halmps.rbuild +++ b/reactos/hal/halx86/halmps.rbuild @@ -11,6 +11,7 @@ hal_generic hal_generic_mp ntoskrnl + libcntpr mps.S mpsboot.asm diff --git a/reactos/hal/halx86/halxbox.rbuild b/reactos/hal/halx86/halxbox.rbuild index 7996e653931..3db5216aa71 100644 --- a/reactos/hal/halx86/halxbox.rbuild +++ b/reactos/hal/halx86/halxbox.rbuild @@ -10,6 +10,7 @@ hal_generic hal_generic_up ntoskrnl + libcntpr halinit_xbox.c part_xbox.c diff --git a/reactos/hal/halx86/mp/apic.c b/reactos/hal/halx86/mp/apic.c index 32b5dd51a15..6aea485bbc4 100644 --- a/reactos/hal/halx86/mp/apic.c +++ b/reactos/hal/halx86/mp/apic.c @@ -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 */ diff --git a/reactos/include/ndk/i386/asm.h b/reactos/include/ndk/i386/asm.h index e2dbeb60963..eaaf2ae1bc4 100644 --- a/reactos/include/ndk/i386/asm.h +++ b/reactos/include/ndk/i386/asm.h @@ -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 diff --git a/reactos/include/reactos/asm.h b/reactos/include/reactos/asm.h new file mode 100644 index 00000000000..1005c1f715d --- /dev/null +++ b/reactos/include/reactos/asm.h @@ -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 diff --git a/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S b/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S index 5331162a6a3..f09edfd3b9c 100644 --- a/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S +++ b/reactos/ntoskrnl/ex/i386/fastinterlck_asm.S @@ -7,12 +7,16 @@ */ /* INCLUDES ******************************************************************/ + +#include #include #include -.intel_syntax noprefix /* FUNCTIONS ****************************************************************/ +.code32 +.text + /* * NOTE: These functions must obey the following rules: * - Acquire locks only on MP systems. diff --git a/reactos/ntoskrnl/ex/i386/interlck_asm.S b/reactos/ntoskrnl/ex/i386/interlck_asm.S index f7d602e2c3d..954091cee85 100644 --- a/reactos/ntoskrnl/ex/i386/interlck_asm.S +++ b/reactos/ntoskrnl/ex/i386/interlck_asm.S @@ -7,12 +7,16 @@ */ /* INCLUDES ******************************************************************/ + +#include #include #include -.intel_syntax noprefix /* FUNCTIONS ****************************************************************/ +.code32 +.text + /* * NOTE: These functions must obey the following rules: * - Acquire locks only on MP systems. diff --git a/reactos/ntoskrnl/include/internal/i386/asmmacro.S b/reactos/ntoskrnl/include/internal/i386/asmmacro.S index d0fabe98011..7e0596eaf92 100644 --- a/reactos/ntoskrnl/include/internal/i386/asmmacro.S +++ b/reactos/ntoskrnl/include/internal/i386/asmmacro.S @@ -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 - // 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 // -/ 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 diff --git a/reactos/ntoskrnl/include/internal/trap_x.h b/reactos/ntoskrnl/include/internal/trap_x.h index 205aa54e4e8..d1f9420d258 100644 --- a/reactos/ntoskrnl/include/internal/trap_x.h +++ b/reactos/ntoskrnl/include/internal/trap_x.h @@ -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 diff --git a/reactos/ntoskrnl/ke/i386/irqobj.c b/reactos/ntoskrnl/ke/i386/irqobj.c index 58b66248c30..5543f939170 100644 --- a/reactos/ntoskrnl/ke/i386/irqobj.c +++ b/reactos/ntoskrnl/ke/i386/irqobj.c @@ -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 **********************************************************/ diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 293cd6f8106..07e1161d33a 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -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 +#include +#include #include -.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 diff --git a/reactos/ntoskrnl/ke/i386/traphdlr.c b/reactos/ntoskrnl/ke/i386/traphdlr.c index a6d8052c893..3b2f81b00a4 100644 --- a/reactos/ntoskrnl/ke/i386/traphdlr.c +++ b/reactos/ntoskrnl/ke/i386/traphdlr.c @@ -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 */ diff --git a/reactos/ntoskrnl/ke/i386/usercall_asm.S b/reactos/ntoskrnl/ke/i386/usercall_asm.S index 017a736d1e3..2da726882eb 100644 --- a/reactos/ntoskrnl/ke/i386/usercall_asm.S +++ b/reactos/ntoskrnl/ke/i386/usercall_asm.S @@ -8,12 +8,15 @@ /* INCLUDES ******************************************************************/ -#include +#include +#include #include -.intel_syntax noprefix /* FUNCTIONS ****************************************************************/ +.code32 +.text + .globl _KiGetUserModeStackAddress@0 .func KiGetUserModeStackAddress@0 _KiGetUserModeStackAddress@0: