Author: sir_richard
Date: Tue Jan 26 16:43:13 2010
New Revision: 45266
URL:
http://svn.reactos.org/svn/reactos?rev=45266&view=rev
Log:
[NTOS]: Implement a C/Extended ASM macro for generating trap stubs, removing the need to
do this in ASM. The macro covers all possible entries, from SYSENTER to a fake sotware
interrupt (needed for HAL changes later). By being somewhat in C, it makes the code
cleaner to read and uses C expressions to make its decisions, making the code more
maintanable as well. It also removes the need for separate assembly files.
[NTOS]: Modify the semantics of how a fast system call (SYSENTER) is processed in the
stub, by moving more work in the C handler, such as setting up FS and getting the correct
argument stack. Saves us some cycles too (and allows the trap stub macro to be more
generic).
Modified:
trunk/reactos/ntoskrnl/include/internal/ke.h
trunk/reactos/ntoskrnl/include/internal/trap_x.h
trunk/reactos/ntoskrnl/ke/i386/trap.s
trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Tue Jan 26 16:43:13 2010
@@ -1100,13 +1100,6 @@
);
VOID
-KiSystemService(
- IN PKTHREAD Thread,
- IN PKTRAP_FRAME TrapFrame,
- IN ULONG Instruction
-);
-
-VOID
FASTCALL
KiIdleLoop(
VOID
Modified: trunk/reactos/ntoskrnl/include/internal/trap_x.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] Tue Jan 26 16:43:13
2010
@@ -670,4 +670,120 @@
/* Set debug header */
KiFillTrapFrameDebug(TrapFrame);
}
+
+//
+// Generates a Trap Prolog Stub for the given name
+//
+#define KI_PUSH_FAKE_ERROR_CODE 0x1
+#define KI_FAST_V86_TRAP 0x2
+#define KI_NONVOLATILES_ONLY 0x4
+#define KI_FAST_SYSTEM_CALL 0x8
+#define KI_SOFTWARE_TRAP 0x10
+#define KiTrap(x, y) VOID DECLSPEC_NORETURN x(VOID) { KiTrapStub(y, x##Handler); }
+
+//
+// Trap Prolog Stub
+//
+VOID
+DECLSPEC_NORETURN
+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");
+
+ /* Now go ahead and make space for this frame */
+ __asm__ __volatile__ ("subl $%c[e],%%esp\n":: [e] "i"(FrameSize)
: "%esp");
+
+ /* Does the caller want volatiles only? */
+ if (Flags & KI_NONVOLATILES_ONLY) __asm__ __volatile__
+ (
+ /* Then only EBX, ESI, EDI and EBP are saved */
+ "movl %%ebx, %c[b](%%esp)\n"
+ "movl %%esi, %c[s](%%esp)\n"
+ "movl %%edi, %c[i](%%esp)\n"
+ "movl %%ebp, %c[p](%%esp)\n"
+ :
+ : [b] "i"(FIELD_OFFSET(KTRAP_FRAME, Ebx)),
+ [s] "i"(FIELD_OFFSET(KTRAP_FRAME, Esi)),
+ [i] "i"(FIELD_OFFSET(KTRAP_FRAME, Edi)),
+ [p] "i"(FIELD_OFFSET(KTRAP_FRAME, Ebp))
+ : "%esp"
+ );
+ else __asm__ __volatile__
+ (
+ /* Otherwise, we save all the registers (except ESP) */
+ "movl %%eax, %c[a](%%esp)\n"
+ "movl %%ebx, %c[b](%%esp)\n"
+ "movl %%ecx, %c[c](%%esp)\n"
+ "movl %%edx, %c[d](%%esp)\n"
+ "movl %%esi, %c[s](%%esp)\n"
+ "movl %%edi, %c[i](%%esp)\n"
+ "movl %%ebp, %c[p](%%esp)\n"
+ :
+ : [a] "i"(FIELD_OFFSET(KTRAP_FRAME, Eax)),
+ [b] "i"(FIELD_OFFSET(KTRAP_FRAME, Ebx)),
+ [c] "i"(FIELD_OFFSET(KTRAP_FRAME, Ecx)),
+ [d] "i"(FIELD_OFFSET(KTRAP_FRAME, Edx)),
+ [s] "i"(FIELD_OFFSET(KTRAP_FRAME, Esi)),
+ [i] "i"(FIELD_OFFSET(KTRAP_FRAME, Edi)),
+ [p] "i"(FIELD_OFFSET(KTRAP_FRAME, Ebp))
+ : "%esp"
+ );
+
+ /* Now set parameter 1 (ECX) to point to the frame */
+ __asm__ __volatile__ ("movl %%esp, %%ecx\n":::"%esp");
+
+ /* For Fast-V86 traps, move set parameter 2 (EDX) to hold EFlags */
+ if (Flags & KI_FAST_V86_TRAP) __asm__ __volatile__
+ (
+ "movl %c[f](%%esp), %%edx\n"
+ :
+ : [f] "i"(FIELD_OFFSET(KTRAP_FRAME, EFlags))
+ );
+
+ /* Now jump to the C handler */
+ __asm__ __volatile__ ("jmp %c[x]\n":: [x] "i"(Handler));
+ UNREACHABLE;
+}
+
#endif
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] Tue Jan 26 16:43:13 2010
@@ -53,14 +53,6 @@
idt _KiTrap0F, INT_32_DPL0 /* INT 2F: RESERVED */
GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */
-/* Trap handlers referenced from C code */
-.globl _KiTrap08
-.globl _KiTrap13
-
-/* System call code referenced from C code */
-.globl _CopyParams
-.globl _ReadBatch
-
/* System call entrypoints: */
.globl _KiFastCallEntry
.globl _KiSystemService
@@ -111,49 +103,6 @@
/* SOFTWARE INTERRUPT SERVICES ***********************************************/
.text
-.func KiSystemService
-_KiSystemService:
-
- /* Make space for trap frame on the stack */
- sub esp, KTRAP_FRAME_EIP
-
- /* Save EBP, EBX, ESI, EDI only! */
- mov [esp+KTRAP_FRAME_EBX], ebx
- mov [esp+KTRAP_FRAME_ESI], esi
- mov [esp+KTRAP_FRAME_EDI], edi
- mov [esp+KTRAP_FRAME_EBP], ebp
-
- /* Call C handler -- note that EDX is the caller stack, EAX is the ID */
- mov ecx, esp
- jmp _KiSystemServiceHandler
-.endfunc
-
-.func KiFastCallEntry
-_KiFastCallEntry:
-
- /* Sane FS segment */
- mov ecx, KGDT_R0_PCR
- mov fs, cx
-
- /* Sane stack and frame */
- mov esp, PCR[KPCR_TSS]
- mov esp, [esp+KTSS_ESP0]
-
- /* Make space for trap frame on the stack */
- sub esp, KTRAP_FRAME_V86_ES
-
- /* Save EBP, EBX, ESI, EDI only! */
- mov [esp+KTRAP_FRAME_EBX], ebx
- mov [esp+KTRAP_FRAME_ESI], esi
- mov [esp+KTRAP_FRAME_EDI], edi
- mov [esp+KTRAP_FRAME_EBP], ebp
-
- /* Call C handler -- note that EDX is the user stack, and EAX the syscall */
- mov ecx, esp
- add edx, 8
- jmp _KiFastCallEntryHandler
-.endfunc
-
.func Kei386EoiHelper@0
_Kei386EoiHelper@0:
@@ -191,32 +140,6 @@
AbiosExit:
/* FIXME: TODO */
UNHANDLED_PATH
-
-GENERATE_TRAP_HANDLER KiGetTickCount, 1
-GENERATE_TRAP_HANDLER KiCallbackReturn, 1
-GENERATE_TRAP_HANDLER KiRaiseAssertion, 1
-GENERATE_TRAP_HANDLER KiDebugService, 1
-
-/* HARDWARE TRAP HANDLERS ****************************************************/
-
-GENERATE_TRAP_HANDLER KiTrap00
-GENERATE_TRAP_HANDLER KiTrap01
-GENERATE_TRAP_HANDLER KiTrap03
-GENERATE_TRAP_HANDLER KiTrap04
-GENERATE_TRAP_HANDLER KiTrap05
-GENERATE_TRAP_HANDLER KiTrap06
-GENERATE_TRAP_HANDLER KiTrap07
-GENERATE_TRAP_HANDLER KiTrap08, 0
-GENERATE_TRAP_HANDLER KiTrap09
-GENERATE_TRAP_HANDLER KiTrap0A, 0
-GENERATE_TRAP_HANDLER KiTrap0B, 0
-GENERATE_TRAP_HANDLER KiTrap0C, 0
-GENERATE_TRAP_HANDLER KiTrap0D, 0, 1
-GENERATE_TRAP_HANDLER KiTrap0E, 0
-GENERATE_TRAP_HANDLER KiTrap0F
-GENERATE_TRAP_HANDLER KiTrap10
-GENERATE_TRAP_HANDLER KiTrap11
-GENERATE_TRAP_HANDLER KiTrap13
/* UNEXPECTED INTERRUPT HANDLERS **********************************************/
Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Tue Jan 26 16:43:13 2010
@@ -1489,12 +1489,13 @@
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 - 8; // Stack is 2 frames down
+ TrapFrame->HardwareEsp = (ULONG_PTR)Arguments;
TrapFrame->EFlags = __readeflags() | EFLAGS_INTERRUPT_MASK;
TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
TrapFrame->Eip = SharedUserData->SystemCallReturn;
@@ -1502,6 +1503,9 @@
/* Get the current thread */
Thread = KeGetCurrentThread();
+
+ /* Arguments are actually 2 frames down (because of the double indirection) */
+ Arguments = (PVOID)(TrapFrame->HardwareEsp + 8);
/* Call the shared handler (inline) */
KiSystemCallHandler(TrapFrame,
@@ -1545,6 +1549,33 @@
Thread->PreviousMode,
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, KI_FAST_V86_TRAP);
+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);
/* HARDWARE INTERRUPTS ********************************************************/