mirror of
https://github.com/reactos/reactos.git
synced 2024-08-20 18:35:32 +00:00
[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). svn path=/trunk/; revision=45266
This commit is contained in:
parent
102c63a3b6
commit
12a31f1df7
|
@ -1099,13 +1099,6 @@ KiQuantumEnd(
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
|
||||||
KiSystemService(
|
|
||||||
IN PKTHREAD Thread,
|
|
||||||
IN PKTRAP_FRAME TrapFrame,
|
|
||||||
IN ULONG Instruction
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KiIdleLoop(
|
KiIdleLoop(
|
||||||
|
|
|
@ -670,4 +670,120 @@ KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
|
||||||
/* Set debug header */
|
/* Set debug header */
|
||||||
KiFillTrapFrameDebug(TrapFrame);
|
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
|
#endif
|
||||||
|
|
|
@ -53,14 +53,6 @@ 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 */
|
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: */
|
/* System call entrypoints: */
|
||||||
.globl _KiFastCallEntry
|
.globl _KiFastCallEntry
|
||||||
.globl _KiSystemService
|
.globl _KiSystemService
|
||||||
|
@ -111,49 +103,6 @@ _IsrOverflowMsg:
|
||||||
/* SOFTWARE INTERRUPT SERVICES ***********************************************/
|
/* SOFTWARE INTERRUPT SERVICES ***********************************************/
|
||||||
.text
|
.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
|
.func Kei386EoiHelper@0
|
||||||
_Kei386EoiHelper@0:
|
_Kei386EoiHelper@0:
|
||||||
|
|
||||||
|
@ -192,32 +141,6 @@ AbiosExit:
|
||||||
/* FIXME: TODO */
|
/* FIXME: TODO */
|
||||||
UNHANDLED_PATH
|
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 **********************************************/
|
/* UNEXPECTED INTERRUPT HANDLERS **********************************************/
|
||||||
|
|
||||||
.globl _KiStartUnexpectedRange@0
|
.globl _KiStartUnexpectedRange@0
|
||||||
|
|
|
@ -1489,12 +1489,13 @@ KiFastCallEntryHandler(IN ULONG ServiceNumber,
|
||||||
PKTHREAD Thread;
|
PKTHREAD Thread;
|
||||||
|
|
||||||
/* Fixup segments */
|
/* Fixup segments */
|
||||||
|
Ke386SetFs(KGDT_R0_PCR);
|
||||||
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
||||||
Ke386SetEs(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 - 8; // Stack is 2 frames down
|
TrapFrame->HardwareEsp = (ULONG_PTR)Arguments;
|
||||||
TrapFrame->EFlags = __readeflags() | EFLAGS_INTERRUPT_MASK;
|
TrapFrame->EFlags = __readeflags() | EFLAGS_INTERRUPT_MASK;
|
||||||
TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
|
TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
|
||||||
TrapFrame->Eip = SharedUserData->SystemCallReturn;
|
TrapFrame->Eip = SharedUserData->SystemCallReturn;
|
||||||
|
@ -1502,6 +1503,9 @@ KiFastCallEntryHandler(IN ULONG ServiceNumber,
|
||||||
|
|
||||||
/* Get the current thread */
|
/* Get the current thread */
|
||||||
Thread = KeGetCurrentThread();
|
Thread = KeGetCurrentThread();
|
||||||
|
|
||||||
|
/* Arguments are actually 2 frames down (because of the double indirection) */
|
||||||
|
Arguments = (PVOID)(TrapFrame->HardwareEsp + 8);
|
||||||
|
|
||||||
/* Call the shared handler (inline) */
|
/* Call the shared handler (inline) */
|
||||||
KiSystemCallHandler(TrapFrame,
|
KiSystemCallHandler(TrapFrame,
|
||||||
|
@ -1546,6 +1550,33 @@ KiSystemServiceHandler(IN ULONG ServiceNumber,
|
||||||
SegFs);
|
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 ********************************************************/
|
/* HARDWARE INTERRUPTS ********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue