1 #------------------------------------------------------------------------------ 2 # 3 # Copyright (c) 2010 - 2015, 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 24 ASM_GLOBAL ASM_PFX(InterruptProcess) 25 ASM_GLOBAL ASM_PFX(Exception0Handle) 26 ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize) 27 ASM_GLOBAL ASM_PFX(TimerInterruptHandle) 28 ASM_GLOBAL ASM_PFX(CommonEntry) 29 30 .macro AGENT_HANDLER_SIGNATURE 31 .byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H') 32 .endm 33 34 .data 35 36 ASM_PFX(ExceptionStubHeaderSize): .long ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle) 37 38 .text 39 40 AGENT_HANDLER_SIGNATURE 41 ASM_PFX(Exception0Handle): 42 cli 43 pushl %eax 44 mov $0, %eax 45 jmp ASM_PFX(CommonEntry) 46 AGENT_HANDLER_SIGNATURE 47 ASM_PFX(Exception1Handle): 48 cli 49 pushl %eax 50 mov $1, %eax 51 jmp ASM_PFX(CommonEntry) 52 AGENT_HANDLER_SIGNATURE 53 ASM_PFX(Exception2Handle): 54 cli 55 pushl %eax 56 mov $2, %eax 57 jmp ASM_PFX(CommonEntry) 58 AGENT_HANDLER_SIGNATURE 59 ASM_PFX(Exception3Handle): 60 cli 61 pushl %eax 62 mov $3, %eax 63 jmp ASM_PFX(CommonEntry) 64 AGENT_HANDLER_SIGNATURE 65 ASM_PFX(Exception4Handle): 66 cli 67 pushl %eax 68 mov $4, %eax 69 jmp ASM_PFX(CommonEntry) 70 AGENT_HANDLER_SIGNATURE 71 ASM_PFX(Exception5Handle): 72 cli 73 pushl %eax 74 mov $5, %eax 75 jmp ASM_PFX(CommonEntry) 76 AGENT_HANDLER_SIGNATURE 77 ASM_PFX(Exception6Handle): 78 cli 79 pushl %eax 80 mov $6, %eax 81 jmp ASM_PFX(CommonEntry) 82 AGENT_HANDLER_SIGNATURE 83 ASM_PFX(Exception7Handle): 84 cli 85 pushl %eax 86 mov $7, %eax 87 jmp ASM_PFX(CommonEntry) 88 AGENT_HANDLER_SIGNATURE 89 ASM_PFX(Exception8Handle): 90 cli 91 pushl %eax 92 mov $8, %eax 93 jmp ASM_PFX(CommonEntry) 94 AGENT_HANDLER_SIGNATURE 95 ASM_PFX(Exception9Handle): 96 cli 97 pushl %eax 98 mov $9, %eax 99 jmp ASM_PFX(CommonEntry) 100 AGENT_HANDLER_SIGNATURE 101 ASM_PFX(Exception10Handle): 102 cli 103 pushl %eax 104 mov $10, %eax 105 jmp ASM_PFX(CommonEntry) 106 AGENT_HANDLER_SIGNATURE 107 ASM_PFX(Exception11Handle): 108 cli 109 pushl %eax 110 mov $11, %eax 111 jmp ASM_PFX(CommonEntry) 112 AGENT_HANDLER_SIGNATURE 113 ASM_PFX(Exception12Handle): 114 cli 115 pushl %eax 116 mov $12, %eax 117 jmp ASM_PFX(CommonEntry) 118 AGENT_HANDLER_SIGNATURE 119 ASM_PFX(Exception13Handle): 120 cli 121 pushl %eax 122 mov $13, %eax 123 jmp ASM_PFX(CommonEntry) 124 AGENT_HANDLER_SIGNATURE 125 ASM_PFX(Exception14Handle): 126 cli 127 pushl %eax 128 mov $14, %eax 129 jmp ASM_PFX(CommonEntry) 130 AGENT_HANDLER_SIGNATURE 131 ASM_PFX(Exception15Handle): 132 cli 133 pushl %eax 134 mov $15, %eax 135 jmp ASM_PFX(CommonEntry) 136 AGENT_HANDLER_SIGNATURE 137 ASM_PFX(Exception16Handle): 138 cli 139 pushl %eax 140 mov $16, %eax 141 jmp ASM_PFX(CommonEntry) 142 AGENT_HANDLER_SIGNATURE 143 ASM_PFX(Exception17Handle): 144 cli 145 pushl %eax 146 mov $17, %eax 147 jmp ASM_PFX(CommonEntry) 148 AGENT_HANDLER_SIGNATURE 149 ASM_PFX(Exception18Handle): 150 cli 151 pushl %eax 152 mov $18, %eax 153 jmp ASM_PFX(CommonEntry) 154 AGENT_HANDLER_SIGNATURE 155 ASM_PFX(Exception19Handle): 156 cli 157 pushl %eax 158 mov $19, %eax 159 jmp ASM_PFX(CommonEntry) 160 AGENT_HANDLER_SIGNATURE 161 ASM_PFX(TimerInterruptHandle): 162 cli 163 pushl %eax 164 mov $32, %eax 165 jmp ASM_PFX(CommonEntry) 166 167 168 ASM_PFX(CommonEntry): 169 170 #---------------------------------------; 171 # _CommonEntry ; 172 #----------------------------------------------------------------------------; 173 # The follow algorithm is used for the common interrupt routine. 174 # Entry from each interrupt with a push eax and eax=interrupt number 175 # 176 # +---------------------+ 177 # + EFlags + 178 # +---------------------+ 179 # + CS + 180 # +---------------------+ 181 # + EIP + 182 # +---------------------+ 183 # + Error Code + 184 # +---------------------+ 185 # + EAX / Vector Number + 186 # +---------------------+ 187 # + EBP + 188 # +---------------------+ <-- EBP 189 # 190 191 # We need to determine if any extra data was pushed by the exception 192 cmpl $DEBUG_EXCEPT_DOUBLE_FAULT, %eax 193 je NoExtrPush 194 cmpl $DEBUG_EXCEPT_INVALID_TSS, %eax 195 je NoExtrPush 196 cmpl $DEBUG_EXCEPT_SEG_NOT_PRESENT, %eax 197 je NoExtrPush 198 cmpl $DEBUG_EXCEPT_STACK_FAULT, %eax 199 je NoExtrPush 200 cmpl $DEBUG_EXCEPT_GP_FAULT, %eax 201 je NoExtrPush 202 cmpl $DEBUG_EXCEPT_PAGE_FAULT, %eax 203 je NoExtrPush 204 cmpl $DEBUG_EXCEPT_ALIGNMENT_CHECK, %eax 205 je NoExtrPush 206 207 pushl (%esp) 208 movl $0, 4(%esp) 209 210 NoExtrPush: 211 212 pushl %ebp 213 movl %esp,%ebp 214 215 # 216 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 217 # is 16-byte aligned 218 # 219 andl $0xfffffff0,%esp 220 subl $12,%esp 221 222 ## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; 223 pushl 0x4(%ebp) 224 pushl %ebx 225 pushl %ecx 226 pushl %edx 227 mov %eax, %ebx # save vector in ebx 228 leal 24(%ebp),%ecx 229 pushl %ecx # save original ESP 230 pushl (%ebp) 231 pushl %esi 232 pushl %edi 233 234 ## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; 235 ## insure FXSAVE/FXRSTOR is enabled in CR4... 236 ## ... while we're at it, make sure DE is also enabled... 237 mov $1, %eax 238 pushl %ebx # temporarily save value of ebx on stack 239 cpuid # use CPUID to determine if FXSAVE/FXRESTOR 240 # and DE are supported 241 popl %ebx # retore value of ebx that was overwritten 242 # by CPUID 243 movl %cr4, %eax 244 pushl %eax # push cr4 firstly 245 testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support 246 jz L1 247 orl $BIT9, %eax # Set CR4.OSFXSR 248 L1: 249 testl $BIT2, %edx # Test for Debugging Extensions support 250 jz L2 251 orl $BIT3, %eax # Set CR4.DE 252 L2: 253 movl %eax, %cr4 254 movl %cr3, %eax 255 pushl %eax 256 movl %cr2, %eax 257 pushl %eax 258 xorl %eax,%eax 259 pushl %eax 260 movl %cr0, %eax 261 pushl %eax 262 263 ## UINT32 Gs, Fs, Es, Ds, Cs, Ss; 264 movl %ss,%eax 265 pushl %eax 266 movzwl 16(%ebp), %eax 267 pushl %eax 268 movl %ds,%eax 269 pushl %eax 270 movl %es,%eax 271 pushl %eax 272 movl %fs,%eax 273 pushl %eax 274 movl %gs,%eax 275 pushl %eax 276 277 ## UINT32 Eip; 278 pushl 12(%ebp) 279 280 ## UINT32 Gdtr[2], Idtr[2]; 281 subl $8,%esp 282 sidt (%esp) 283 subl $8,%esp 284 sgdt (%esp) 285 286 ## UINT32 Ldtr, Tr; 287 xorl %eax,%eax 288 strl %eax 289 pushl %eax 290 sldtl %eax 291 pushl %eax 292 293 ## UINT32 EFlags; 294 pushl 20(%ebp) 295 296 ## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; 297 movl %dr7, %eax 298 pushl %eax 299 ## clear Dr7 while executing debugger itself 300 xorl %eax,%eax 301 movl %eax, %dr7 302 303 movl %dr6, %eax 304 pushl %eax 305 ## insure all status bits in dr6 are clear... 306 xorl %eax,%eax 307 movl %eax, %dr6 308 309 movl %dr3, %eax 310 pushl %eax 311 movl %dr2, %eax 312 pushl %eax 313 movl %dr1, %eax 314 pushl %eax 315 movl %dr0, %eax 316 pushl %eax 317 318 ## FX_SAVE_STATE_IA32 FxSaveState; 319 subl $512,%esp 320 movl %esp,%edi 321 testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support. 322 # edx still contains result from CPUID above 323 jz L3 324 .byte 0x0f, 0xae, 0x07 # fxsave [edi] 325 L3: 326 327 ## save the exception data 328 pushl 8(%esp) 329 330 ## Clear Direction Flag 331 cld 332 333 ## Prepare parameter and call C function 334 pushl %esp 335 pushl %ebx 336 call ASM_PFX(InterruptProcess) 337 addl $8,%esp 338 339 ## skip the exception data 340 addl $4,%esp 341 342 ## FX_SAVE_STATE_IA32 FxSaveState; 343 movl %esp,%esi 344 movl $1, %eax 345 cpuid # use CPUID to determine if FXSAVE/FXRESTOR 346 # are supported 347 testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support 348 jz L4 349 .byte 0x0f, 0xae, 0x0e # fxrstor [esi] 350 L4: 351 addl $512,%esp 352 353 ## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; 354 popl %eax 355 movl %eax, %dr0 356 popl %eax 357 movl %eax, %dr1 358 popl %eax 359 movl %eax, %dr2 360 popl %eax 361 movl %eax, %dr3 362 ## skip restore of dr6. We cleared dr6 during the context save. 363 addl $4,%esp 364 popl %eax 365 movl %eax, %dr7 366 367 ## UINT32 EFlags; 368 popl 20(%ebp) 369 370 ## UINT32 Ldtr, Tr; 371 ## UINT32 Gdtr[2], Idtr[2]; 372 ## Best not let anyone mess with these particular registers... 373 addl $24,%esp 374 375 ## UINT32 Eip; 376 pop 12(%ebp) 377 378 ## UINT32 Gs, Fs, Es, Ds, Cs, Ss; 379 ## NOTE - modified segment registers could hang the debugger... We 380 ## could attempt to insulate ourselves against this possibility, 381 ## but that poses risks as well. 382 ## 383 popl %gs 384 popl %fs 385 popl %es 386 popl %ds 387 popl 16(%ebp) 388 popl %ss 389 390 ## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; 391 popl %eax 392 movl %eax, %cr0 393 addl $4,%esp # not for Cr1 394 popl %eax 395 movl %eax, %cr2 396 popl %eax 397 movl %eax, %cr3 398 popl %eax 399 movl %eax, %cr4 400 401 ## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; 402 popl %edi 403 popl %esi 404 addl $4,%esp # not for ebp 405 addl $4,%esp # not for esp 406 popl %edx 407 popl %ecx 408 popl %ebx 409 popl %eax 410 411 movl %ebp,%esp 412 popl %ebp 413 addl $8,%esp # skip eax 414 iretl 415 416