1#------------------------------------------------------------------------------ 2# 3# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> 4# This program and the accompanying materials 5# are licensed and made available under the terms and conditions of the BSD License 6# which accompanies this distribution. The full text of the license may be found at 7# http://opensource.org/licenses/bsd-license.php. 8# 9# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11# 12# Module Name: 13# 14# AsmFuncs.S 15# 16# Abstract: 17# 18# Debug interrupt handle functions. 19# 20#------------------------------------------------------------------------------ 21 22#include "DebugException.h" 23 24ASM_GLOBAL ASM_PFX(InterruptProcess) 25 26ASM_GLOBAL ASM_PFX(Exception0Handle) 27ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize) 28ASM_GLOBAL ASM_PFX(TimerInterruptHandle) 29ASM_GLOBAL ASM_PFX(CommonEntry) 30 31.macro AGENT_HANDLER_SIGNATURE 32 .byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H') 33.endm 34 35.data 36 37ASM_PFX(ExceptionStubHeaderSize): .long ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle) 38 39 40.text 41 42AGENT_HANDLER_SIGNATURE 43ASM_PFX(Exception0Handle): 44 cli 45 pushq %rcx 46 mov $0, %rcx 47 jmp ASM_PFX(CommonEntry) 48AGENT_HANDLER_SIGNATURE 49ASM_PFX(Exception1Handle): 50 cli 51 pushq %rcx 52 mov $1, %rcx 53 jmp ASM_PFX(CommonEntry) 54AGENT_HANDLER_SIGNATURE 55ASM_PFX(Exception2Handle): 56 cli 57 pushq %rcx 58 mov $2, %rcx 59 jmp ASM_PFX(CommonEntry) 60AGENT_HANDLER_SIGNATURE 61ASM_PFX(Exception3Handle): 62 cli 63 pushq %rcx 64 mov $3, %rcx 65 jmp ASM_PFX(CommonEntry) 66AGENT_HANDLER_SIGNATURE 67ASM_PFX(Exception4Handle): 68 cli 69 pushq %rcx 70 mov $4, %rcx 71 jmp ASM_PFX(CommonEntry) 72AGENT_HANDLER_SIGNATURE 73ASM_PFX(Exception5Handle): 74 cli 75 pushq %rcx 76 mov $5, %rcx 77 jmp ASM_PFX(CommonEntry) 78AGENT_HANDLER_SIGNATURE 79ASM_PFX(Exception6Handle): 80 cli 81 pushq %rcx 82 mov $6, %rcx 83 jmp ASM_PFX(CommonEntry) 84AGENT_HANDLER_SIGNATURE 85ASM_PFX(Exception7Handle): 86 cli 87 pushq %rcx 88 mov $7, %rcx 89 jmp ASM_PFX(CommonEntry) 90AGENT_HANDLER_SIGNATURE 91ASM_PFX(Exception8Handle): 92 cli 93 pushq %rcx 94 mov $8, %rcx 95 jmp ASM_PFX(CommonEntry) 96AGENT_HANDLER_SIGNATURE 97ASM_PFX(Exception9Handle): 98 cli 99 pushq %rcx 100 mov $9, %rcx 101 jmp ASM_PFX(CommonEntry) 102AGENT_HANDLER_SIGNATURE 103ASM_PFX(Exception10Handle): 104 cli 105 pushq %rcx 106 mov $10, %rcx 107 jmp ASM_PFX(CommonEntry) 108AGENT_HANDLER_SIGNATURE 109ASM_PFX(Exception11Handle): 110 cli 111 pushq %rcx 112 mov $11, %rcx 113 jmp ASM_PFX(CommonEntry) 114AGENT_HANDLER_SIGNATURE 115ASM_PFX(Exception12Handle): 116 cli 117 pushq %rcx 118 mov $12, %rcx 119 jmp ASM_PFX(CommonEntry) 120AGENT_HANDLER_SIGNATURE 121ASM_PFX(Exception13Handle): 122 cli 123 pushq %rcx 124 mov $13, %rcx 125 jmp ASM_PFX(CommonEntry) 126AGENT_HANDLER_SIGNATURE 127ASM_PFX(Exception14Handle): 128 cli 129 pushq %rcx 130 mov $14, %rcx 131 jmp ASM_PFX(CommonEntry) 132AGENT_HANDLER_SIGNATURE 133ASM_PFX(Exception15Handle): 134 cli 135 pushq %rcx 136 mov $15, %rcx 137 jmp ASM_PFX(CommonEntry) 138AGENT_HANDLER_SIGNATURE 139ASM_PFX(Exception16Handle): 140 cli 141 pushq %rcx 142 mov $16, %rcx 143 jmp ASM_PFX(CommonEntry) 144AGENT_HANDLER_SIGNATURE 145ASM_PFX(Exception17Handle): 146 cli 147 pushq %rcx 148 mov $17, %rcx 149 jmp ASM_PFX(CommonEntry) 150AGENT_HANDLER_SIGNATURE 151ASM_PFX(Exception18Handle): 152 cli 153 pushq %rcx 154 mov $18, %rcx 155 jmp ASM_PFX(CommonEntry) 156AGENT_HANDLER_SIGNATURE 157ASM_PFX(Exception19Handle): 158 cli 159 pushq %rcx 160 mov $19, %rcx 161 jmp ASM_PFX(CommonEntry) 162AGENT_HANDLER_SIGNATURE 163ASM_PFX(TimerInterruptHandle): 164 cli 165 pushq %rcx 166 mov $32, %rcx 167 jmp ASM_PFX(CommonEntry) 168 169 170ASM_PFX(CommonEntry): 171 172#---------------------------------------; 173# CommonInterruptEntry ; 174#---------------------------------------; 175# The follow algorithm is used for the common interrupt routine. 176 177# 178# +---------------------+ <-- 16-byte aligned ensured by processor 179# + Old SS + 180# +---------------------+ 181# + Old RSP + 182# +---------------------+ 183# + RFlags + 184# +---------------------+ 185# + CS + 186# +---------------------+ 187# + RIP + 188# +---------------------+ 189# + Error Code + 190# +---------------------+ 191# + RCX / Vector Number + 192# +---------------------+ 193# + RBP + 194# +---------------------+ <-- RBP, 16-byte aligned 195# 196 197# We need to determine if any extra data was pushed by the exception 198 cmpq $DEBUG_EXCEPT_DOUBLE_FAULT, %rcx 199 je NoExtrPush 200 cmpq $DEBUG_EXCEPT_INVALID_TSS, %rcx 201 je NoExtrPush 202 cmpq $DEBUG_EXCEPT_SEG_NOT_PRESENT, %rcx 203 je NoExtrPush 204 cmpq $DEBUG_EXCEPT_STACK_FAULT, %rcx 205 je NoExtrPush 206 cmpq $DEBUG_EXCEPT_GP_FAULT, %rcx 207 je NoExtrPush 208 cmpq $DEBUG_EXCEPT_PAGE_FAULT, %rcx 209 je NoExtrPush 210 cmpq $DEBUG_EXCEPT_ALIGNMENT_CHECK, %rcx 211 je NoExtrPush 212 213 pushq (%rsp) 214 movq $0, 8(%rsp) 215 216NoExtrPush: 217 # 218 # All interrupt handlers are invoked through interrupt gates, so 219 # IF flag automatically cleared at the entry point 220 pushq %rbp 221 movq %rsp, %rbp 222 223 # 224 # Since here the stack pointer is 16-byte aligned, so 225 # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 226 # is 16-byte aligned 227 # 228 229## UINT64 R8, R9, R10, R11, R12, R13, R14, R15; 230 pushq %r15 231 pushq %r14 232 pushq %r13 233 pushq %r12 234 pushq %r11 235 pushq %r10 236 pushq %r9 237 pushq %r8 238 239 movq %cr8, %r8 240 pushq %r8 241 242## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; 243 pushq %rax 244 pushq %rbx 245 pushq 8(%rbp) # original rcx 246 pushq %rdx 247 pushq 48(%rbp) # original rsp 248 pushq (%rbp) # original rbp 249 pushq %rsi 250 pushq %rdi 251 252## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4; 253 movq %cr4, %rax 254 orq $0x208, %rax 255 movq %rax, %cr4 256 pushq %rax 257 movq %cr3, %rax 258 pushq %rax 259 movq %cr2, %rax 260 pushq %rax 261 xorq %rax, %rax 262 pushq %rax 263 movq %cr0, %rax 264 pushq %rax 265 266## UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero 267 xorq %rax, %rax # set rax to 0 268 movzwq 56(%rbp), %rax 269# movq %ss, %rax 270 pushq %rax 271 movzwq 32(%rbp), %rax 272# movq %cs, %rax 273 pushq %rax 274 mov %ds, %rax 275 pushq %rax 276 mov %es, %rax 277 pushq %rax 278 mov %fs, %rax 279 pushq %rax 280 mov %gs, %rax 281 pushq %rax 282 283## UINT64 Rip; 284 pushq 24(%rbp) 285 286## UINT64 Gdtr[2], Idtr[2]; 287 subq $16, %rsp 288 sidt (%rsp) 289 subq $16, %rsp 290 sgdt (%rsp) 291 292## UINT64 Ldtr, Tr; 293 xorq %rax, %rax 294 strw %ax 295 pushq %rax 296 sldtw %ax 297 pushq %rax 298 299## UINT64 RFlags; 300 pushq 40(%rbp) 301 302## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; 303 movq %dr7, %rax 304 pushq %rax 305## clear Dr7 while executing debugger itself 306 xorq %rax, %rax 307 movq %rax, %dr7 308 309 movq %dr6, %rax 310 pushq %rax 311## insure all status bits in dr6 are clear... 312 xorq %rax, %rax 313 movq %rax, %dr6 314 315 movq %dr3, %rax 316 pushq %rax 317 movq %dr2, %rax 318 pushq %rax 319 movq %dr1, %rax 320 pushq %rax 321 movq %dr0, %rax 322 pushq %rax 323 324## FX_SAVE_STATE_X64 FxSaveState; 325 subq $512, %rsp 326 movq %rsp, %rdi 327 .byte 0x0f, 0xae, 0b00000111 328 329## save the exception data; 330 pushq 16(%rbp) 331 332## Clear Direction Flag 333 cld 334 335## Prepare parameter and call 336# movq 8(%rbp), %rcx 337 movq %rsp, %rdx 338 movq %rcx, %r15 # save vector in r15 339 # 340 # Per X64 calling convention, allocate maximum parameter stack space 341 # and make sure RSP is 16-byte aligned 342 # 343 subq $(32 + 8), %rsp 344 call ASM_PFX(InterruptProcess) 345 addq $(32 + 8), %rsp 346 347## skip the exception data; 348 addq $8, %rsp 349 350## FX_SAVE_STATE_X64 FxSaveState; 351 352 movq %rsp, %rsi 353 .byte 0x0f, 0xae, 0b00001110 354 addq $512, %rsp 355 356## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; 357 popq %rax 358 movq %rax, %dr0 359 popq %rax 360 movq %rax, %dr1 361 popq %rax 362 movq %rax, %dr2 363 popq %rax 364 movq %rax, %dr3 365## skip restore of dr6. We cleared dr6 during the context save. 366 addq $8, %rsp 367 popq %rax 368 movq %rax, %dr7 369 370## UINT64 RFlags; 371 popq 40(%rbp) 372 373## UINT64 Ldtr, Tr; 374## UINT64 Gdtr[2], Idtr[2]; 375## Best not let anyone mess with these particular registers... 376 addq $48, %rsp 377 378## UINT64 Rip; 379 popq 24(%rbp) 380 381## UINT64 Gs, Fs, Es, Ds, Cs, Ss; 382 popq %rax 383 # mov gs, rax ; not for gs 384 popq %rax 385 # mov fs, rax ; not for fs 386 # (X64 will not use fs and gs, so we do not restore it) 387 popq %rax 388 mov %rax, %es 389 popq %rax 390 mov %rax, %ds 391 popq 32(%rbp) 392 popq 56(%rbp) 393 394## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; 395 popq %rax 396 movq %rax, %cr0 397 addq $8, %rsp 398 popq %rax 399 movq %rax, %cr2 400 popq %rax 401 movq %rax, %cr3 402 popq %rax 403 movq %rax, %cr4 404 405## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; 406## UINT64 R8, R9, R10, R11, R12, R13, R14, R15; 407 popq %rdi 408 popq %rsi 409 addq $8, %rsp 410 addq $8, %rsp 411 popq %rdx 412 popq %rcx 413 popq %rbx 414 popq %rax 415 416 popq %r8 417 movq %r8, %cr8 418 419 popq %r8 420 popq %r9 421 popq %r10 422 popq %r11 423 popq %r12 424 popq %r13 425 popq %r14 426 popq %r15 427 428 movq %rbp, %rsp 429 popq %rbp 430 addq $16, %rsp 431 iretq 432