Home | History | Annotate | Download | only in Ia32
      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