1 2APIC_EOI = HEX(0FFFFFFFFFFFE00B0) 3 4TF_VOLATILES = HEX(01) 5TF_NONVOLATILES = HEX(02) 6TF_XMM = HEX(04) 7TF_SEGMENTS = HEX(08) 8TF_DEBUG = HEX(10) 9TF_IRQL = HEX(20) 10TF_SAVE_ALL = (TF_VOLATILES OR TF_NONVOLATILES OR TF_XMM OR TF_SEGMENTS) 11TF_HAS_ERROR_CODE = HEX(40) 12TF_SEND_EOI = HEX(80) 13//TF_SYSTEMSERVICE = (TRAPFLAG_VOLATILES or TRAPFLAG_DEBUG) 14TF_CHECKUSERAPC = HEX(100) 15 16/* 17 * Stack Layout: 18 * |-------------------| 19 * | KTRAP_FRAME | 20 * |-------------------| <- rbp 21 * | EXCEPTION_RECORD | 22 * |-------------------| 23 * | KEXCEPTION_FRAME | 24 * |-------------------| <- rsp 25 * 26 */ 27 28/* 29 * EnterTrap - Allocate KTRAP_FRAME_LENGTH and save registers to it 30 */ 31MACRO(EnterTrap, Flags) 32 LOCAL kernel_mode_entry 33 34 /* Save the trap flags for this trap */ 35 CurrentTrapFlags = VAL(Flags) 36 37 /* Size of hardware trap frame */ 38 if (Flags AND TF_HAS_ERROR_CODE) 39 .pushframe code 40 SIZE_INITIAL_FRAME = 6 * 8 41 else 42 .pushframe 43 SIZE_INITIAL_FRAME = 5 * 8 44 endif 45 46 /* Make room for a KTRAP_FRAME */ 47 sub rsp, (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME) 48 .allocstack (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME) 49 50 /* Save rbp and rax */ 51 mov [rsp + KTRAP_FRAME_Rbp], rbp 52 .savereg rbp, KTRAP_FRAME_Rbp 53 mov [rsp + KTRAP_FRAME_Rax], rax 54 .savereg rax, KTRAP_FRAME_Rax 55 56 /* Point rbp to the KTRAP_FRAME */ 57 lea rbp, [rsp] 58 .setframe rbp, 0 59 60 if (Flags AND TF_NONVOLATILES) 61 /* Save non-volatile registers */ 62 mov [rbp + KTRAP_FRAME_Rbx], rbx 63 .savereg rbx, KTRAP_FRAME_Rbx 64 mov [rbp + KTRAP_FRAME_Rdi], rdi 65 .savereg rdi, KTRAP_FRAME_Rdi 66 mov [rbp + KTRAP_FRAME_Rsi], rsi 67 .savereg rsi, KTRAP_FRAME_Rsi 68 endif 69 70 .endprolog 71 72 if (Flags AND TF_VOLATILES) 73 /* Save volatile registers */ 74 mov [rbp + KTRAP_FRAME_Rcx], rcx 75 mov [rbp + KTRAP_FRAME_Rdx], rdx 76 mov [rbp + KTRAP_FRAME_R8], r8 77 mov [rbp + KTRAP_FRAME_R9], r9 78 mov [rbp + KTRAP_FRAME_R10], r10 79 mov [rbp + KTRAP_FRAME_R11], r11 80 endif 81 82 if (Flags AND TF_XMM) 83 /* Save xmm registers */ 84 movdqa [rbp + KTRAP_FRAME_Xmm0], xmm0 85 movdqa [rbp + KTRAP_FRAME_Xmm1], xmm1 86 movdqa [rbp + KTRAP_FRAME_Xmm2], xmm2 87 movdqa [rbp + KTRAP_FRAME_Xmm3], xmm3 88 movdqa [rbp + KTRAP_FRAME_Xmm4], xmm4 89 movdqa [rbp + KTRAP_FRAME_Xmm5], xmm5 90 endif 91 92 if (Flags AND TF_SEGMENTS) 93 /* Save segment selectors */ 94 mov [rbp + KTRAP_FRAME_SegDs], ds 95 mov [rbp + KTRAP_FRAME_SegEs], es 96 mov [rbp + KTRAP_FRAME_SegFs], fs 97 mov [rbp + KTRAP_FRAME_SegGs], gs 98 endif 99 100#if DBG 101 mov ecx, MSR_GS_BASE 102 rdmsr 103 mov [rbp + KTRAP_FRAME_GsBase], eax 104 mov [rbp + KTRAP_FRAME_GsBase + 4], edx 105#endif 106 107 /* Save previous mode and check if it was user mode */ 108 mov ax, [rbp + KTRAP_FRAME_SegCs] 109 and al, 1 110 mov [rbp + KTRAP_FRAME_PreviousMode], al 111 jz kernel_mode_entry 112 113 /* Set sane segments */ 114 mov ax, (KGDT64_R3_DATA or RPL_MASK) 115 mov ds, ax 116 mov es, ax 117 swapgs 118 119kernel_mode_entry: 120 121// if (Flags AND TF_IRQL) 122 /* Save previous irql */ 123 mov rax, cr8 124 mov [rbp + KTRAP_FRAME_PreviousIrql], al 125// endif 126 127 if (Flags AND TF_DEBUG) 128 /* Save debug registers */ 129 mov rax, dr0 130 mov [rbp + KTRAP_FRAME_Dr0], rax 131 mov rax, dr1 132 mov [rbp + KTRAP_FRAME_Dr1], rax 133 mov rax, dr2 134 mov [rbp + KTRAP_FRAME_Dr2], rax 135 mov rax, dr3 136 mov [rbp + KTRAP_FRAME_Dr3], rax 137 mov rax, dr6 138 mov [rbp + KTRAP_FRAME_Dr6], rax 139 mov rax, dr7 140 mov [rbp + KTRAP_FRAME_Dr7], rax 141 endif 142 143 /* Make sure the direction flag is cleared */ 144 cld 145ENDM 146 147/* 148 * ExitTrap - Restore registers and free stack space 149 */ 150MACRO(ExitTrap, Flags) 151 LOCAL kernel_mode_return 152 LOCAL IntsEnabled 153 LOCAL NoUserApc 154 155#if DBG 156 /* Check previous irql */ 157 mov rax, cr8 158 cmp [rbp + KTRAP_FRAME_PreviousIrql], al 159 je .irql_ok 160 int 3 161 .irql_ok: 162#endif 163 164 if (Flags AND TF_SEGMENTS) 165 /* Restore segment selectors */ 166 mov ds, [rbp + KTRAP_FRAME_SegDs] 167 mov es, [rbp + KTRAP_FRAME_SegEs] 168 mov fs, [rbp + KTRAP_FRAME_SegFs] 169 endif 170 171 if (Flags AND TF_IRQL) 172 /* Restore previous irql */ 173 movzx rax, byte ptr [rbp + KTRAP_FRAME_PreviousIrql] 174 mov cr8, rax 175 endif 176 177 /* Check if we came from user mode */ 178 test byte ptr [rbp + KTRAP_FRAME_SegCs], 1 179 jz kernel_mode_return 180 181 if (Flags AND TF_CHECKUSERAPC) 182 /* Load current thread into r10 */ 183 mov r10, gs:[PcCurrentThread] 184 cmp byte ptr [r10 + KTHREAD_UserApcPending], 0 185 je NoUserApc 186 call KiInitiateUserApc 187 NoUserApc: 188 endif 189 190#if DBG 191 /*Make sure interrupts are enabled */ 192 test dword ptr [rbp + KTRAP_FRAME_EFlags], HEX(200) 193 jnz IntsEnabled 194 int HEX(2c) 195IntsEnabled: 196#endif 197 198 /* Swap gs to user mode */ 199 swapgs 200 201kernel_mode_return: 202 203 if (Flags AND TF_NONVOLATILES) 204 /* Restore non-volatile registers */ 205 mov rbx, [rbp + KTRAP_FRAME_Rbx] 206 mov rdi, [rbp + KTRAP_FRAME_Rdi] 207 mov rsi, [rbp + KTRAP_FRAME_Rsi] 208 endif 209 210 if (Flags AND TF_VOLATILES) 211 /* Restore volatile registers */ 212 mov rax, [rbp + KTRAP_FRAME_Rax] 213 mov rcx, [rbp + KTRAP_FRAME_Rcx] 214 mov rdx, [rbp + KTRAP_FRAME_Rdx] 215 mov r8, [rbp + KTRAP_FRAME_R8] 216 mov r9, [rbp + KTRAP_FRAME_R9] 217 mov r10, [rbp + KTRAP_FRAME_R10] 218 mov r11, [rbp + KTRAP_FRAME_R11] 219 endif 220 221 if (Flags AND TF_XMM) 222 /* Restore xmm registers */ 223 movdqa xmm0, [rbp + KTRAP_FRAME_Xmm0] 224 movdqa xmm1, [rbp + KTRAP_FRAME_Xmm1] 225 movdqa xmm2, [rbp + KTRAP_FRAME_Xmm2] 226 movdqa xmm3, [rbp + KTRAP_FRAME_Xmm3] 227 movdqa xmm4, [rbp + KTRAP_FRAME_Xmm4] 228 movdqa xmm5, [rbp + KTRAP_FRAME_Xmm5] 229 endif 230 231 /* Restore rbp */ 232 mov rbp, [rbp + KTRAP_FRAME_Rbp] 233 234 /* Adjust stack pointer */ 235 add rsp, KTRAP_FRAME_Rip 236 237 if (Flags AND TF_SEND_EOI) 238 /* Write 0 to the local APIC EOI register */ 239 mov dword ptr [APIC_EOI], 0 240 endif 241 242 /* Return from the trap */ 243 iretq 244ENDM 245 246 247MACRO(TRAP_ENTRY, Trap, Flags) 248 EXTERN Trap&Handler :PROC 249 PUBLIC &Trap 250 FUNC &Trap 251 /* Common code to create the trap frame */ 252 EnterTrap Flags 253 254 /* Call the C handler */ 255 mov rcx, rbp 256 call Trap&Handler 257 258 /* Leave */ 259 ExitTrap Flags 260 ENDFUNC 261ENDM 262 263