1/* 2 * FILE: ntoskrnl/ke/i386/trap.s 3 * COPYRIGHT: See COPYING in the top level directory 4 * PURPOSE: System Traps, Entrypoints and Exitpoints 5 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 6 * Timo Kreuzer (timo.kreuzer@reactos.org) 7 * NOTE: See asmmacro.S for the shared entry/exit code. 8 */ 9 10/* INCLUDES ******************************************************************/ 11 12#include <asm.inc> 13#include <ks386.inc> 14#include <internal/i386/asmmacro.S> 15 16MACRO(GENERATE_IDT_STUB, Vector) 17idt _KiUnexpectedInterrupt&Vector, INT_32_DPL0 18ENDM 19 20MACRO(GENERATE_INT_HANDLER, Vector) 21//.func KiUnexpectedInterrupt&Vector 22_KiUnexpectedInterrupt&Vector: 23 /* This is a push instruction with 8bit operand. Since the instruction 24 sign extends the value to 32 bits, we need to offset it */ 25 push (Vector - 128) 26 jmp _KiEndUnexpectedRange@0 27//.endfunc 28ENDM 29 30/* GLOBALS *******************************************************************/ 31 32.data 33ASSUME CS:nothing 34 35.align 16 36 37PUBLIC _KiIdt 38_KiIdt: 39/* This is the Software Interrupt Table that we handle in this file: */ 40idt _KiTrap00, INT_32_DPL0 /* INT 00: Divide Error (#DE) */ 41idt _KiTrap01, INT_32_DPL0 /* INT 01: Debug Exception (#DB) */ 42idt _KiTrap02, INT_32_DPL0 /* INT 02: NMI Interrupt */ 43idt _KiTrap03, INT_32_DPL3 /* INT 03: Breakpoint Exception (#BP) */ 44idt _KiTrap04, INT_32_DPL3 /* INT 04: Overflow Exception (#OF) */ 45idt _KiTrap05, INT_32_DPL0 /* INT 05: BOUND Range Exceeded (#BR) */ 46idt _KiTrap06, INT_32_DPL0 /* INT 06: Invalid Opcode Code (#UD) */ 47idt _KiTrap07, INT_32_DPL0 /* INT 07: Device Not Available (#NM) */ 48idt _KiTrap08, INT_32_DPL0 /* INT 08: Double Fault Exception (#DF) */ 49idt _KiTrap09, INT_32_DPL0 /* INT 09: RESERVED */ 50idt _KiTrap0A, INT_32_DPL0 /* INT 0A: Invalid TSS Exception (#TS) */ 51idt _KiTrap0B, INT_32_DPL0 /* INT 0B: Segment Not Present (#NP) */ 52idt _KiTrap0C, INT_32_DPL0 /* INT 0C: Stack Fault Exception (#SS) */ 53idt _KiTrap0D, INT_32_DPL0 /* INT 0D: General Protection (#GP) */ 54idt _KiTrap0E, INT_32_DPL0 /* INT 0E: Page-Fault Exception (#PF) */ 55idt _KiTrap0F, INT_32_DPL0 /* INT 0F: RESERVED */ 56idt _KiTrap10, INT_32_DPL0 /* INT 10: x87 FPU Error (#MF) */ 57idt _KiTrap11, INT_32_DPL0 /* INT 11: Align Check Exception (#AC) */ 58idt _KiTrap0F, INT_32_DPL0 /* INT 12: Machine Check Exception (#MC)*/ 59idt _KiTrap0F, INT_32_DPL0 /* INT 13: SIMD FPU Exception (#XF) */ 60REPEAT 21 61idt _KiTrap0F, INT_32_DPL0 /* INT 14-28: UNDEFINED INTERRUPTS */ 62ENDR 63idt _KiRaiseSecurityCheckFailure, INT_32_DPL3 64 /* INT 29: Handler for __fastfail */ 65idt _KiGetTickCount, INT_32_DPL3 /* INT 2A: Get Tick Count Handler */ 66idt _KiCallbackReturn, INT_32_DPL3 /* INT 2B: User-Mode Callback Return */ 67idt _KiRaiseAssertion, INT_32_DPL3 /* INT 2C: Debug Assertion Handler */ 68idt _KiDebugService, INT_32_DPL3 /* INT 2D: Debug Service Handler */ 69idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call Service Handler */ 70idt _KiTrap0F, INT_32_DPL0 /* INT 2F: RESERVED */ 71i = HEX(30) 72REPEAT 208 73 GENERATE_IDT_STUB %i 74 i = i + 1 75ENDR 76 77PUBLIC _KiIdtDescriptor 78_KiIdtDescriptor: 79 .short 0 80 .short HEX(7FF) 81 .long _KiIdt 82 83PUBLIC _KiUnexpectedEntrySize 84_KiUnexpectedEntrySize: 85 .long _KiUnexpectedInterrupt49 - _KiUnexpectedInterrupt48 86 87/******************************************************************************/ 88.code 89 90PUBLIC _KiStartUnexpectedRange@0 91_KiStartUnexpectedRange@0: 92i = HEX(30) 93REPEAT 208 94 GENERATE_INT_HANDLER %i 95 i = i + 1 96ENDR 97 98TRAP_ENTRY KiTrap00, KI_PUSH_FAKE_ERROR_CODE 99TRAP_ENTRY KiTrap01, KI_PUSH_FAKE_ERROR_CODE 100TASK_ENTRY KiTrap02, KI_NMI 101TRAP_ENTRY KiTrap03, KI_PUSH_FAKE_ERROR_CODE 102TRAP_ENTRY KiTrap04, KI_PUSH_FAKE_ERROR_CODE 103TRAP_ENTRY KiTrap05, KI_PUSH_FAKE_ERROR_CODE 104TRAP_ENTRY KiTrap06, KI_PUSH_FAKE_ERROR_CODE 105TRAP_ENTRY KiTrap07, KI_PUSH_FAKE_ERROR_CODE 106TASK_ENTRY KiTrap08, 0 107TRAP_ENTRY KiTrap09, KI_PUSH_FAKE_ERROR_CODE 108TRAP_ENTRY KiTrap0A, 0 109TRAP_ENTRY KiTrap0B, 0 110TRAP_ENTRY KiTrap0C, 0 111TRAP_ENTRY KiTrap0D, 0 112TRAP_ENTRY KiTrap0E, 0 113TRAP_ENTRY KiTrap0F, KI_PUSH_FAKE_ERROR_CODE 114TRAP_ENTRY KiTrap10, KI_PUSH_FAKE_ERROR_CODE 115TRAP_ENTRY KiTrap11, KI_PUSH_FAKE_ERROR_CODE 116TRAP_ENTRY KiTrap13, KI_PUSH_FAKE_ERROR_CODE 117TRAP_ENTRY KiRaiseSecurityCheckFailure, KI_PUSH_FAKE_ERROR_CODE 118TRAP_ENTRY KiGetTickCount, KI_PUSH_FAKE_ERROR_CODE 119TRAP_ENTRY KiCallbackReturn, KI_PUSH_FAKE_ERROR_CODE 120TRAP_ENTRY KiRaiseAssertion, KI_PUSH_FAKE_ERROR_CODE 121TRAP_ENTRY KiDebugService, KI_PUSH_FAKE_ERROR_CODE 122TRAP_ENTRY KiUnexpectedInterruptTail, 0 123 124ALIGN 4 125EXTERN @KiInterruptTemplateHandler@8:PROC 126PUBLIC _KiInterruptTemplate 127_KiInterruptTemplate: 128 CFI_STARTPROC 129 KiEnterTrap KI_PUSH_FAKE_ERROR_CODE 130PUBLIC _KiInterruptTemplate2ndDispatch 131_KiInterruptTemplate2ndDispatch: 132 mov edx, 0 133PUBLIC _KiInterruptTemplateObject 134_KiInterruptTemplateObject: 135 mov eax, offset @KiInterruptTemplateHandler@8 136 jmp eax 137PUBLIC _KiInterruptTemplateDispatch 138_KiInterruptTemplateDispatch: 139 CFI_ENDPROC 140 141EXTERN @KiSystemServiceHandler@8:PROC 142PUBLIC _KiSystemService 143.PROC _KiSystemService 144 FPO 0, 0, 0, 0, 1, FRAME_TRAP 145 KiEnterTrap (KI_PUSH_FAKE_ERROR_CODE OR KI_NONVOLATILES_ONLY OR KI_DONT_SAVE_SEGS) 146 KiCallHandler @KiSystemServiceHandler@8 147.ENDP 148 149PUBLIC _KiFastCallEntry 150.PROC _KiFastCallEntry 151 FPO 0, 0, 0, 0, 1, FRAME_TRAP 152 KiEnterTrap (KI_FAST_SYSTEM_CALL OR KI_NONVOLATILES_ONLY OR KI_DONT_SAVE_SEGS) 153 KiCallHandler @KiSystemServiceHandler@8 154.ENDP 155 156PUBLIC _KiFastCallEntryWithSingleStep 157.PROC _KiFastCallEntryWithSingleStep 158 FPO 0, 0, 0, 0, 1, FRAME_TRAP 159 KiEnterTrap (KI_FAST_SYSTEM_CALL OR KI_NONVOLATILES_ONLY OR KI_DONT_SAVE_SEGS) 160 or dword ptr [ecx + KTRAP_FRAME_EFLAGS], EFLAGS_TF 161 KiCallHandler @KiSystemServiceHandler@8 162.ENDP 163 164PUBLIC _KiEndUnexpectedRange@0 165_KiEndUnexpectedRange@0: 166 add dword ptr[esp], 128 167 jmp _KiUnexpectedInterruptTail 168 169 170/* EXIT CODE *****************************************************************/ 171 172KiTrapExitStub KiSystemCallReturn, (KI_RESTORE_EAX OR KI_RESTORE_EFLAGS OR KI_EXIT_JMP) 173KiTrapExitStub KiSystemCallSysExitReturn, (KI_RESTORE_EAX OR KI_RESTORE_FS OR KI_RESTORE_EFLAGS OR KI_EXIT_SYSCALL) 174KiTrapExitStub KiSystemCallTrapReturn, (KI_RESTORE_EAX OR KI_RESTORE_FS OR KI_EXIT_IRET) 175 176KiTrapExitStub KiEditedTrapReturn, (KI_RESTORE_VOLATILES OR KI_RESTORE_EFLAGS OR KI_EDITED_FRAME OR KI_EXIT_RET) 177KiTrapExitStub KiTrapReturn, (KI_RESTORE_VOLATILES OR KI_RESTORE_SEGMENTS OR KI_EXIT_IRET) 178KiTrapExitStub KiTrapReturnNoSegments, (KI_RESTORE_VOLATILES OR KI_EXIT_IRET) 179KiTrapExitStub KiTrapReturnNoSegmentsRet8,(KI_RESTORE_VOLATILES OR KI_RESTORE_EFLAGS OR KI_EXIT_RET8) 180 181EXTERN _PsConvertToGuiThread@0:PROC 182 183PUBLIC _KiConvertToGuiThread@0 184_KiConvertToGuiThread@0: 185 186 /* 187 * Converting to a GUI thread safely updates ESP in-place as well as the 188 * current Thread->TrapFrame and EBP when KeSwitchKernelStack is called. 189 * 190 * However, PsConvertToGuiThread "helpfully" restores EBP to the original 191 * caller's value, since it is considered a nonvolatile register. As such, 192 * as soon as we're back after the conversion and we try to store the result 193 * which will probably be in some stack variable (EBP-based), we'll crash as 194 * we are touching the de-allocated non-expanded stack. 195 * 196 * Thus we need a way to update our EBP before EBP is touched, and the only 197 * way to guarantee this is to do the call itself in assembly, use the EAX 198 * register to store the result, fixup EBP, and then let the C code continue 199 * on its merry way. 200 * 201 */ 202 203 /* Save ebx */ 204 push ebx 205 206 /* Calculate the stack frame offset in ebx */ 207 mov ebx, ebp 208 sub ebx, esp 209 210 /* Call the worker function */ 211 call _PsConvertToGuiThread@0 212 213 /* Adjust ebp to the new stack */ 214 mov ebp, esp 215 add ebp, ebx 216 217 /* Restore ebx */ 218 pop ebx 219 220 /* return to the caller */ 221 ret 222 223/* 224NTSTATUS 225NTAPI 226KiSystemCallTrampoline(IN PVOID Handler, 227 IN PVOID Arguments, 228 IN ULONG StackBytes); 229*/ 230PUBLIC _KiSystemCallTrampoline@12 231_KiSystemCallTrampoline@12: 232 push ebp 233 mov ebp, esp 234 push esi 235 push edi 236 237 /* Get handler */ 238 mov eax, [ebp + 8] 239 /* Get arguments */ 240 mov esi, [ebp + 12] 241 /* Get stack bytes */ 242 mov ecx, [ebp + 16] 243 244 /* Copy args to the stack */ 245 sub esp, ecx 246 mov edi, esp 247 shr ecx, 2 248 rep movsd 249 250 call eax 251 252 pop edi 253 pop esi 254 leave 255 256 ret 12 257END 258