1#------------------------------------------------------------------------------ 2# 3# Copyright (c) 2010 - 2013, 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) 25ASM_GLOBAL ASM_PFX(Exception0Handle) 26ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize) 27ASM_GLOBAL ASM_PFX(TimerInterruptHandle) 28ASM_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 36ASM_PFX(ExceptionStubHeaderSize): .long ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle) 37 38.text 39 40AGENT_HANDLER_SIGNATURE 41ASM_PFX(Exception0Handle): 42 cli 43 pushl %eax 44 mov $0, %eax 45 jmp ASM_PFX(CommonEntry) 46AGENT_HANDLER_SIGNATURE 47ASM_PFX(Exception1Handle): 48 cli 49 pushl %eax 50 mov $1, %eax 51 jmp ASM_PFX(CommonEntry) 52AGENT_HANDLER_SIGNATURE 53ASM_PFX(Exception2Handle): 54 cli 55 pushl %eax 56 mov $2, %eax 57 jmp ASM_PFX(CommonEntry) 58AGENT_HANDLER_SIGNATURE 59ASM_PFX(Exception3Handle): 60 cli 61 pushl %eax 62 mov $3, %eax 63 jmp ASM_PFX(CommonEntry) 64AGENT_HANDLER_SIGNATURE 65ASM_PFX(Exception4Handle): 66 cli 67 pushl %eax 68 mov $4, %eax 69 jmp ASM_PFX(CommonEntry) 70AGENT_HANDLER_SIGNATURE 71ASM_PFX(Exception5Handle): 72 cli 73 pushl %eax 74 mov $5, %eax 75 jmp ASM_PFX(CommonEntry) 76AGENT_HANDLER_SIGNATURE 77ASM_PFX(Exception6Handle): 78 cli 79 pushl %eax 80 mov $6, %eax 81 jmp ASM_PFX(CommonEntry) 82AGENT_HANDLER_SIGNATURE 83ASM_PFX(Exception7Handle): 84 cli 85 pushl %eax 86 mov $7, %eax 87 jmp ASM_PFX(CommonEntry) 88AGENT_HANDLER_SIGNATURE 89ASM_PFX(Exception8Handle): 90 cli 91 pushl %eax 92 mov $8, %eax 93 jmp ASM_PFX(CommonEntry) 94AGENT_HANDLER_SIGNATURE 95ASM_PFX(Exception9Handle): 96 cli 97 pushl %eax 98 mov $9, %eax 99 jmp ASM_PFX(CommonEntry) 100AGENT_HANDLER_SIGNATURE 101ASM_PFX(Exception10Handle): 102 cli 103 pushl %eax 104 mov $10, %eax 105 jmp ASM_PFX(CommonEntry) 106AGENT_HANDLER_SIGNATURE 107ASM_PFX(Exception11Handle): 108 cli 109 pushl %eax 110 mov $11, %eax 111 jmp ASM_PFX(CommonEntry) 112AGENT_HANDLER_SIGNATURE 113ASM_PFX(Exception12Handle): 114 cli 115 pushl %eax 116 mov $12, %eax 117 jmp ASM_PFX(CommonEntry) 118AGENT_HANDLER_SIGNATURE 119ASM_PFX(Exception13Handle): 120 cli 121 pushl %eax 122 mov $13, %eax 123 jmp ASM_PFX(CommonEntry) 124AGENT_HANDLER_SIGNATURE 125ASM_PFX(Exception14Handle): 126 cli 127 pushl %eax 128 mov $14, %eax 129 jmp ASM_PFX(CommonEntry) 130AGENT_HANDLER_SIGNATURE 131ASM_PFX(Exception15Handle): 132 cli 133 pushl %eax 134 mov $15, %eax 135 jmp ASM_PFX(CommonEntry) 136AGENT_HANDLER_SIGNATURE 137ASM_PFX(Exception16Handle): 138 cli 139 pushl %eax 140 mov $16, %eax 141 jmp ASM_PFX(CommonEntry) 142AGENT_HANDLER_SIGNATURE 143ASM_PFX(Exception17Handle): 144 cli 145 pushl %eax 146 mov $17, %eax 147 jmp ASM_PFX(CommonEntry) 148AGENT_HANDLER_SIGNATURE 149ASM_PFX(Exception18Handle): 150 cli 151 pushl %eax 152 mov $18, %eax 153 jmp ASM_PFX(CommonEntry) 154AGENT_HANDLER_SIGNATURE 155ASM_PFX(Exception19Handle): 156 cli 157 pushl %eax 158 mov $19, %eax 159 jmp ASM_PFX(CommonEntry) 160AGENT_HANDLER_SIGNATURE 161ASM_PFX(TimerInterruptHandle): 162 cli 163 pushl %eax 164 mov $32, %eax 165 jmp ASM_PFX(CommonEntry) 166 167 168ASM_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 210NoExtrPush: 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 movl %cr4, %eax 236 orl $0x208,%eax 237 movl %eax, %cr4 238 pushl %eax 239 movl %cr3, %eax 240 pushl %eax 241 movl %cr2, %eax 242 pushl %eax 243 xorl %eax,%eax 244 pushl %eax 245 movl %cr0, %eax 246 pushl %eax 247 248## UINT32 Gs, Fs, Es, Ds, Cs, Ss; 249 movl %ss,%eax 250 pushl %eax 251 movzwl 16(%ebp), %eax 252 pushl %eax 253 movl %ds,%eax 254 pushl %eax 255 movl %es,%eax 256 pushl %eax 257 movl %fs,%eax 258 pushl %eax 259 movl %gs,%eax 260 pushl %eax 261 262## UINT32 Eip; 263 pushl 12(%ebp) 264 265## UINT32 Gdtr[2], Idtr[2]; 266 subl $8,%esp 267 sidt (%esp) 268 subl $8,%esp 269 sgdt (%esp) 270 271## UINT32 Ldtr, Tr; 272 xorl %eax,%eax 273 strl %eax 274 pushl %eax 275 sldtl %eax 276 pushl %eax 277 278## UINT32 EFlags; 279 pushl 20(%ebp) 280 281## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; 282 movl %dr7, %eax 283 pushl %eax 284## clear Dr7 while executing debugger itself 285 xorl %eax,%eax 286 movl %eax, %dr7 287 288 movl %dr6, %eax 289 pushl %eax 290## insure all status bits in dr6 are clear... 291 xorl %eax,%eax 292 movl %eax, %dr6 293 294 movl %dr3, %eax 295 pushl %eax 296 movl %dr2, %eax 297 pushl %eax 298 movl %dr1, %eax 299 pushl %eax 300 movl %dr0, %eax 301 pushl %eax 302 303## FX_SAVE_STATE_IA32 FxSaveState; 304 subl $512,%esp 305 movl %esp,%edi 306 .byte 0x0f, 0xae, 0x07 # fxsave [edi] 307 308## save the exception data 309 pushl 8(%esp) 310 311## Clear Direction Flag 312 cld 313 314## Prepare parameter and call C function 315 pushl %esp 316 pushl %ebx 317 call ASM_PFX(InterruptProcess) 318 addl $8,%esp 319 320## skip the exception data 321 addl $4,%esp 322 323## FX_SAVE_STATE_IA32 FxSaveState; 324 movl %esp,%esi 325 .byte 0x0f, 0xae, 0x0e # fxrstor [esi] 326 addl $512,%esp 327 328## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; 329 popl %eax 330 movl %eax, %dr0 331 popl %eax 332 movl %eax, %dr1 333 popl %eax 334 movl %eax, %dr2 335 popl %eax 336 movl %eax, %dr3 337## skip restore of dr6. We cleared dr6 during the context save. 338 addl $4,%esp 339 popl %eax 340 movl %eax, %dr7 341 342## UINT32 EFlags; 343 popl 20(%ebp) 344 345## UINT32 Ldtr, Tr; 346## UINT32 Gdtr[2], Idtr[2]; 347## Best not let anyone mess with these particular registers... 348 addl $24,%esp 349 350## UINT32 Eip; 351 pop 12(%ebp) 352 353## UINT32 Gs, Fs, Es, Ds, Cs, Ss; 354## NOTE - modified segment registers could hang the debugger... We 355## could attempt to insulate ourselves against this possibility, 356## but that poses risks as well. 357## 358 popl %gs 359 popl %fs 360 popl %es 361 popl %ds 362 popl 16(%ebp) 363 popl %ss 364 365## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; 366 popl %eax 367 movl %eax, %cr0 368 addl $4,%esp # not for Cr1 369 popl %eax 370 movl %eax, %cr2 371 popl %eax 372 movl %eax, %cr3 373 popl %eax 374 movl %eax, %cr4 375 376## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; 377 popl %edi 378 popl %esi 379 addl $4,%esp # not for ebp 380 addl $4,%esp # not for esp 381 popl %edx 382 popl %ecx 383 popl %ebx 384 popl %eax 385 386 movl %ebp,%esp 387 popl %ebp 388 addl $8,%esp # skip eax 389 iretl 390 391