Home | History | Annotate | Download | only in X64
      1 #------------------------------------------------------------------------------
      2 #
      3 # Copyright (c) 2009 - 2016, 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 #   SmiException.S
     15 #
     16 # Abstract:
     17 #
     18 #   Exception handlers used in SM mode
     19 #
     20 #------------------------------------------------------------------------------
     21 
     22 ASM_GLOBAL  ASM_PFX(SmiPFHandler)
     23 ASM_GLOBAL  ASM_PFX(gcSmiIdtr)
     24 ASM_GLOBAL  ASM_PFX(gcSmiGdtr)
     25 ASM_GLOBAL  ASM_PFX(gcPsd)
     26 
     27     .data
     28 
     29 NullSeg:    .quad 0                     # reserved by architecture
     30 CodeSeg32:
     31             .word -1                    # LimitLow
     32             .word 0                     # BaseLow
     33             .byte 0                     # BaseMid
     34             .byte 0x9b
     35             .byte 0xcf                  # LimitHigh
     36             .byte 0                     # BaseHigh
     37 ProtModeCodeSeg32:
     38             .word -1                    # LimitLow
     39             .word 0                     # BaseLow
     40             .byte 0                     # BaseMid
     41             .byte 0x9b
     42             .byte 0xcf                  # LimitHigh
     43             .byte 0                     # BaseHigh
     44 ProtModeSsSeg32:
     45             .word -1                    # LimitLow
     46             .word 0                     # BaseLow
     47             .byte 0                     # BaseMid
     48             .byte 0x93
     49             .byte 0xcf                  # LimitHigh
     50             .byte 0                     # BaseHigh
     51 DataSeg32:
     52             .word -1                    # LimitLow
     53             .word 0                     # BaseLow
     54             .byte 0                     # BaseMid
     55             .byte 0x93
     56             .byte 0xcf                  # LimitHigh
     57             .byte 0                     # BaseHigh
     58 CodeSeg16:
     59             .word -1
     60             .word 0
     61             .byte 0
     62             .byte 0x9b
     63             .byte 0x8f
     64             .byte 0
     65 DataSeg16:
     66             .word -1
     67             .word 0
     68             .byte 0
     69             .byte 0x93
     70             .byte 0x8f
     71             .byte 0
     72 CodeSeg64:
     73             .word -1                    # LimitLow
     74             .word 0                     # BaseLow
     75             .byte 0                     # BaseMid
     76             .byte 0x9b
     77             .byte 0xaf                  # LimitHigh
     78             .byte 0                     # BaseHigh
     79 # TSS Segment for X64 specially
     80 TssSeg:
     81             .word TSS_DESC_SIZE - 1     # LimitLow
     82             .word 0                     # BaseLow
     83             .byte 0                     # BaseMid
     84             .byte 0x89
     85             .byte 0x00                  # LimitHigh
     86             .byte 0                     # BaseHigh
     87             .long 0                     # BaseUpper
     88             .long 0                     # Reserved
     89 .equ  GDT_SIZE, .- NullSeg
     90 
     91 TssDescriptor:
     92             .space 104, 0
     93 .equ  TSS_DESC_SIZE, .- TssDescriptor
     94 
     95 #
     96 # This structure serves as a template for all processors.
     97 #
     98 ASM_PFX(gcPsd):
     99             .ascii  "PSDSIG  "
    100             .word      PSD_SIZE
    101             .word 2
    102             .word      1 << 2
    103             .word      CODE_SEL
    104             .word      DATA_SEL
    105             .word      DATA_SEL
    106             .word      DATA_SEL
    107             .word 0
    108             .quad 0
    109             .quad 0
    110             .quad 0                     # fixed in InitializeMpServiceData()
    111             .quad      NullSeg
    112             .long      GDT_SIZE
    113             .long 0
    114             .space 24, 0
    115             .quad      0
    116 .equ  PSD_SIZE,  . - ASM_PFX(gcPsd)
    117 
    118 #
    119 # CODE & DATA segments for SMM runtime
    120 #
    121 .equ  CODE_SEL,    CodeSeg64 - NullSeg
    122 .equ  DATA_SEL,    DataSeg32 - NullSeg
    123 .equ  CODE32_SEL,  CodeSeg32 - NullSeg
    124 
    125 ASM_PFX(gcSmiGdtr):
    126     .word      GDT_SIZE - 1
    127     .quad      NullSeg
    128 
    129 ASM_PFX(gcSmiIdtr):
    130     .word      0
    131     .quad      0
    132 
    133     .text
    134 
    135 #------------------------------------------------------------------------------
    136 # _SmiExceptionEntryPoints is the collection of exception entry points followed
    137 # by a common exception handler.
    138 #
    139 # Stack frame would be as follows as specified in IA32 manuals:
    140 # +---------------------+ <-- 16-byte aligned ensured by processor
    141 # +    Old SS           +
    142 # +---------------------+
    143 # +    Old RSP          +
    144 # +---------------------+
    145 # +    RFlags           +
    146 # +---------------------+
    147 # +    CS               +
    148 # +---------------------+
    149 # +    RIP              +
    150 # +---------------------+
    151 # +    Error Code       +
    152 # +---------------------+
    153 # +   Vector Number     +
    154 # +---------------------+
    155 # +    RBP              +
    156 # +---------------------+ <-- RBP, 16-byte aligned
    157 #
    158 # RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT
    159 #------------------------------------------------------------------------------
    160 ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)
    161 ASM_PFX(PageFaultIdtHandlerSmmProfile):
    162     pushq   $0x0e                    # Page Fault
    163     .byte   0x40, 0xf6, 0xc4, 0x08    #test    spl, 8
    164     jnz     L1
    165     pushq   (%rsp)
    166     movq    $0, 8(%rsp)
    167 L1:
    168     pushq   %rbp
    169     movq    %rsp, %rbp
    170 
    171     #
    172     # Since here the stack pointer is 16-byte aligned, so
    173     # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
    174     # is 16-byte aligned
    175     #
    176 
    177 ## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
    178 ## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
    179     pushq   %r15
    180     pushq   %r14
    181     pushq   %r13
    182     pushq   %r12
    183     pushq   %r11
    184     pushq   %r10
    185     pushq   %r9
    186     pushq   %r8
    187     pushq   %rax
    188     pushq   %rcx
    189     pushq   %rdx
    190     pushq   %rbx
    191     pushq   48(%rbp)                   # RSP
    192     pushq   (%rbp)                     # RBP
    193     pushq   %rsi
    194     pushq   %rdi
    195 
    196 ## UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero
    197     movzwq 56(%rbp), %rax
    198     pushq   %rax                       # for ss
    199     movzwq  32(%rbp), %rax
    200     pushq   %rax                       # for cs
    201     movq    %ds, %rax
    202     pushq   %rax
    203     movq    %es, %rax
    204     pushq   %rax
    205     movq    %fs, %rax
    206     pushq   %rax
    207     movq    %gs, %rax
    208     pushq   %rax
    209 
    210 ## UINT64  Rip;
    211     pushq   24(%rbp)
    212 
    213 ## UINT64  Gdtr[2], Idtr[2];
    214     subq    $16, %rsp
    215     sidt    (%rsp)
    216     subq    $16, %rsp
    217     sgdt    (%rsp)
    218 
    219 ## UINT64  Ldtr, Tr;
    220     xorq    %rax, %rax
    221     strw    %ax
    222     pushq   %rax
    223     sldtw   %ax
    224     pushq   %rax
    225 
    226 ## UINT64  RFlags;
    227     pushq   40(%rbp)
    228 
    229 ## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
    230     movq    %cr8, %rax
    231     pushq   %rax
    232     movq    %cr4, %rax
    233     orq     $0x208, %rax
    234     movq    %rax, %cr4
    235     pushq   %rax
    236     movq    %cr3, %rax
    237     pushq   %rax
    238     movq    %cr2, %rax
    239     pushq   %rax
    240     xorq    %rax, %rax
    241     pushq   %rax
    242     movq    %cr0, %rax
    243     pushq   %rax
    244 
    245 ## UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
    246     movq    %dr7, %rax
    247     pushq   %rax
    248     movq    %dr6, %rax
    249     pushq   %rax
    250     movq    %dr3, %rax
    251     pushq   %rax
    252     movq    %dr2, %rax
    253     pushq   %rax
    254     movq    %dr1, %rax
    255     pushq   %rax
    256     movq    %dr0, %rax
    257     pushq   %rax
    258 
    259 ## FX_SAVE_STATE_X64 FxSaveState;
    260 
    261     subq    $512, %rsp
    262     movq    %rsp, %rdi
    263     .byte   0xf, 0xae, 0x7                  # fxsave [rdi]
    264 
    265 # UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
    266     cld
    267 
    268 ## UINT32  ExceptionData;
    269     pushq   16(%rbp)
    270 
    271 ## call into exception handler
    272     movq    8(%rbp), %rcx
    273     movabsq $ASM_PFX(SmiPFHandler), %rax
    274 
    275 ## Prepare parameter and call
    276     movq    %rsp, %rdx
    277     #
    278     # Per X64 calling convention, allocate maximum parameter stack space
    279     # and make sure RSP is 16-byte aligned
    280     #
    281     subq    $4 * 8 + 8, %rsp
    282     call    *%rax
    283     addq    $4 * 8 + 8, %rsp
    284     jmp     L5
    285 
    286 L5:
    287 ## UINT64  ExceptionData;
    288     addq    $8, %rsp
    289 
    290 ## FX_SAVE_STATE_X64 FxSaveState;
    291 
    292     movq    %rsp, %rsi
    293     .byte   0xf, 0xae, 0xe                 # fxrstor [rsi]
    294     addq    $512, %rsp
    295 
    296 ## UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
    297 ## Skip restoration of DRx registers to support debuggers
    298 ## that set breakpoints in interrupt/exception context
    299     addq    $8 * 6, %rsp
    300 
    301 ## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
    302     popq    %rax
    303     movq    %rax, %cr0
    304     addq    $8, %rsp                      # not for Cr1
    305     popq    %rax
    306     movq    %rax, %cr2
    307     popq    %rax
    308     movq    %rax, %cr3
    309     popq    %rax
    310     movq    %rax, %cr4
    311     popq    %rax
    312     movq    %rax, %cr8
    313 
    314 ## UINT64  RFlags;
    315     popq    40(%rbp)
    316 
    317 ## UINT64  Ldtr, Tr;
    318 ## UINT64  Gdtr[2], Idtr[2];
    319 ## Best not let anyone mess with these particular registers...
    320     addq    $48, %rsp
    321 
    322 ## UINT64  Rip;
    323     popq    24(%rbp)
    324 
    325 ## UINT64  Gs, Fs, Es, Ds, Cs, Ss;
    326     popq    %rax
    327     # mov   gs, rax ; not for gs
    328     popq    %rax
    329     # mov   fs, rax ; not for fs
    330     # (X64 will not use fs and gs, so we do not restore it)
    331     popq    %rax
    332     movq    %rax, %es
    333     popq    %rax
    334     movq    %rax, %ds
    335     popq    32(%rbp)                      # for cs
    336     popq    56(%rbp)                      # for ss
    337 
    338 ## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
    339 ## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
    340     popq    %rdi
    341     popq    %rsi
    342     addq    $8, %rsp                      # not for rbp
    343     popq    48(%rbp)                      # for rsp
    344     popq    %rbx
    345     popq    %rdx
    346     popq    %rcx
    347     popq    %rax
    348     popq    %r8
    349     popq    %r9
    350     popq    %r10
    351     popq    %r11
    352     popq    %r12
    353     popq    %r13
    354     popq    %r14
    355     popq    %r15
    356 
    357     movq    %rbp, %rsp
    358 
    359 # Enable TF bit after page fault handler runs
    360     btsl    $8, 40(%rsp)                 #RFLAGS
    361 
    362     popq    %rbp
    363     addq    $16, %rsp                    # skip INT# & ErrCode
    364     iretq
    365 
    366