Home | History | Annotate | Download | only in X64
      1 #------------------------------------------------------------------------------
      2 #
      3 # Copyright (c) 2009 - 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 #   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(gSmiMtrrs)
     24 ASM_GLOBAL  ASM_PFX(gcSmiIdtr)
     25 ASM_GLOBAL  ASM_PFX(gcSmiGdtr)
     26 ASM_GLOBAL  ASM_PFX(gcPsd)
     27 
     28     .data
     29 
     30 NullSeg:    .quad 0                     # reserved by architecture
     31 CodeSeg32:
     32             .word -1                    # LimitLow
     33             .word 0                     # BaseLow
     34             .byte 0                     # BaseMid
     35             .byte 0x9b
     36             .byte 0xcf                  # LimitHigh
     37             .byte 0                     # BaseHigh
     38 ProtModeCodeSeg32:
     39             .word -1                    # LimitLow
     40             .word 0                     # BaseLow
     41             .byte 0                     # BaseMid
     42             .byte 0x9b
     43             .byte 0xcf                  # LimitHigh
     44             .byte 0                     # BaseHigh
     45 ProtModeSsSeg32:
     46             .word -1                    # LimitLow
     47             .word 0                     # BaseLow
     48             .byte 0                     # BaseMid
     49             .byte 0x93
     50             .byte 0xcf                  # LimitHigh
     51             .byte 0                     # BaseHigh
     52 DataSeg32:
     53             .word -1                    # LimitLow
     54             .word 0                     # BaseLow
     55             .byte 0                     # BaseMid
     56             .byte 0x93
     57             .byte 0xcf                  # LimitHigh
     58             .byte 0                     # BaseHigh
     59 CodeSeg16:
     60             .word -1
     61             .word 0
     62             .byte 0
     63             .byte 0x9b
     64             .byte 0x8f
     65             .byte 0
     66 DataSeg16:
     67             .word -1
     68             .word 0
     69             .byte 0
     70             .byte 0x93
     71             .byte 0x8f
     72             .byte 0
     73 CodeSeg64:
     74             .word -1                    # LimitLow
     75             .word 0                     # BaseLow
     76             .byte 0                     # BaseMid
     77             .byte 0x9b
     78             .byte 0xaf                  # LimitHigh
     79             .byte 0                     # BaseHigh
     80 # TSS Segment for X64 specially
     81 TssSeg:
     82             .word TSS_DESC_SIZE - 1     # LimitLow
     83             .word 0                     # BaseLow
     84             .byte 0                     # BaseMid
     85             .byte 0x89
     86             .byte 0x00                  # LimitHigh
     87             .byte 0                     # BaseHigh
     88             .long 0                     # BaseUpper
     89             .long 0                     # Reserved
     90 .equ  GDT_SIZE, .- NullSeg
     91 
     92 TssDescriptor:
     93             .space 104, 0
     94 .equ  TSS_DESC_SIZE, .- TssDescriptor
     95 
     96 #
     97 # This structure serves as a template for all processors.
     98 #
     99 ASM_PFX(gcPsd):
    100             .ascii  "PSDSIG  "
    101             .word      PSD_SIZE
    102             .word 2
    103             .word      1 << 2
    104             .word      CODE_SEL
    105             .word      DATA_SEL
    106             .word      DATA_SEL
    107             .word      DATA_SEL
    108             .word 0
    109             .quad 0
    110             .quad 0
    111             .quad 0                     # fixed in InitializeMpServiceData()
    112             .quad      NullSeg
    113             .long      GDT_SIZE
    114             .long 0
    115             .space 24, 0
    116             .quad      ASM_PFX(gSmiMtrrs)
    117 .equ  PSD_SIZE,  . - ASM_PFX(gcPsd)
    118 
    119 #
    120 # CODE & DATA segments for SMM runtime
    121 #
    122 .equ  CODE_SEL,    CodeSeg64 - NullSeg
    123 .equ  DATA_SEL,    DataSeg32 - NullSeg
    124 .equ  CODE32_SEL,  CodeSeg32 - NullSeg
    125 
    126 ASM_PFX(gcSmiGdtr):
    127     .word      GDT_SIZE - 1
    128     .quad      NullSeg
    129 
    130 ASM_PFX(gcSmiIdtr):
    131     .word      IDT_SIZE - 1
    132     .quad      _SmiIDT
    133 
    134 
    135 #
    136 # Here is the IDT. There are 32 (not 255) entries in it since only processor
    137 # generated exceptions will be handled.
    138 #
    139 _SmiIDT:
    140 # The following segment repeats 32 times:
    141 # No. 1
    142     .word 0                             # Offset 0:15
    143     .word CODE_SEL
    144     .byte 0                             # Unused
    145     .byte 0x8e                          # Interrupt Gate, Present
    146     .word 0                             # Offset 16:31
    147     .quad 0                             # Offset 32:63
    148 # No. 2
    149     .word 0                             # Offset 0:15
    150     .word CODE_SEL
    151     .byte 0                             # Unused
    152     .byte 0x8e                          # Interrupt Gate, Present
    153     .word 0                             # Offset 16:31
    154     .quad 0                             # Offset 32:63
    155 # No. 3
    156     .word 0                             # Offset 0:15
    157     .word CODE_SEL
    158     .byte 0                             # Unused
    159     .byte 0x8e                          # Interrupt Gate, Present
    160     .word 0                             # Offset 16:31
    161     .quad 0                             # Offset 32:63
    162 # No. 4
    163     .word 0                             # Offset 0:15
    164     .word CODE_SEL
    165     .byte 0                             # Unused
    166     .byte 0x8e                          # Interrupt Gate, Present
    167     .word 0                             # Offset 16:31
    168     .quad 0                             # Offset 32:63
    169 # No. 5
    170     .word 0                             # Offset 0:15
    171     .word CODE_SEL
    172     .byte 0                             # Unused
    173     .byte 0x8e                          # Interrupt Gate, Present
    174     .word 0                             # Offset 16:31
    175     .quad 0                             # Offset 32:63
    176 # No. 6
    177     .word 0                             # Offset 0:15
    178     .word CODE_SEL
    179     .byte 0                             # Unused
    180     .byte 0x8e                          # Interrupt Gate, Present
    181     .word 0                             # Offset 16:31
    182     .quad 0                             # Offset 32:63
    183 # No. 7
    184     .word 0                             # Offset 0:15
    185     .word CODE_SEL
    186     .byte 0                             # Unused
    187     .byte 0x8e                          # Interrupt Gate, Present
    188     .word 0                             # Offset 16:31
    189     .quad 0                             # Offset 32:63
    190 # No. 8
    191     .word 0                             # Offset 0:15
    192     .word CODE_SEL
    193     .byte 0                             # Unused
    194     .byte 0x8e                          # Interrupt Gate, Present
    195     .word 0                             # Offset 16:31
    196     .quad 0                             # Offset 32:63
    197 # No. 9
    198     .word 0                             # Offset 0:15
    199     .word CODE_SEL
    200     .byte 0                             # Unused
    201     .byte 0x8e                          # Interrupt Gate, Present
    202     .word 0                             # Offset 16:31
    203     .quad 0                             # Offset 32:63
    204 # No. 10
    205     .word 0                             # Offset 0:15
    206     .word CODE_SEL
    207     .byte 0                             # Unused
    208     .byte 0x8e                          # Interrupt Gate, Present
    209     .word 0                             # Offset 16:31
    210     .quad 0                             # Offset 32:63
    211 # No. 11
    212     .word 0                             # Offset 0:15
    213     .word CODE_SEL
    214     .byte 0                             # Unused
    215     .byte 0x8e                          # Interrupt Gate, Present
    216     .word 0                             # Offset 16:31
    217     .quad 0                             # Offset 32:63
    218 # No. 12
    219     .word 0                             # Offset 0:15
    220     .word CODE_SEL
    221     .byte 0                             # Unused
    222     .byte 0x8e                          # Interrupt Gate, Present
    223     .word 0                             # Offset 16:31
    224     .quad 0                             # Offset 32:63
    225 # No. 13
    226     .word 0                             # Offset 0:15
    227     .word CODE_SEL
    228     .byte 0                             # Unused
    229     .byte 0x8e                          # Interrupt Gate, Present
    230     .word 0                             # Offset 16:31
    231     .quad 0                             # Offset 32:63
    232 # No. 14
    233     .word 0                             # Offset 0:15
    234     .word CODE_SEL
    235     .byte 0                             # Unused
    236     .byte 0x8e                          # Interrupt Gate, Present
    237     .word 0                             # Offset 16:31
    238     .quad 0                             # Offset 32:63
    239 # No. 15
    240     .word 0                             # Offset 0:15
    241     .word CODE_SEL
    242     .byte 0                             # Unused
    243     .byte 0x8e                          # Interrupt Gate, Present
    244     .word 0                             # Offset 16:31
    245     .quad 0                             # Offset 32:63
    246 # No. 16
    247     .word 0                             # Offset 0:15
    248     .word CODE_SEL
    249     .byte 0                             # Unused
    250     .byte 0x8e                          # Interrupt Gate, Present
    251     .word 0                             # Offset 16:31
    252     .quad 0                             # Offset 32:63
    253 # No. 17
    254     .word 0                             # Offset 0:15
    255     .word CODE_SEL
    256     .byte 0                             # Unused
    257     .byte 0x8e                          # Interrupt Gate, Present
    258     .word 0                             # Offset 16:31
    259     .quad 0                             # Offset 32:63
    260 # No. 18
    261     .word 0                             # Offset 0:15
    262     .word CODE_SEL
    263     .byte 0                             # Unused
    264     .byte 0x8e                          # Interrupt Gate, Present
    265     .word 0                             # Offset 16:31
    266     .quad 0                             # Offset 32:63
    267 # No. 19
    268     .word 0                             # Offset 0:15
    269     .word CODE_SEL
    270     .byte 0                             # Unused
    271     .byte 0x8e                          # Interrupt Gate, Present
    272     .word 0                             # Offset 16:31
    273     .quad 0                             # Offset 32:63
    274 # No. 20
    275     .word 0                             # Offset 0:15
    276     .word CODE_SEL
    277     .byte 0                             # Unused
    278     .byte 0x8e                          # Interrupt Gate, Present
    279     .word 0                             # Offset 16:31
    280     .quad 0                             # Offset 32:63
    281 # No. 21
    282     .word 0                             # Offset 0:15
    283     .word CODE_SEL
    284     .byte 0                             # Unused
    285     .byte 0x8e                          # Interrupt Gate, Present
    286     .word 0                             # Offset 16:31
    287     .quad 0                             # Offset 32:63
    288 # No. 22
    289     .word 0                             # Offset 0:15
    290     .word CODE_SEL
    291     .byte 0                             # Unused
    292     .byte 0x8e                          # Interrupt Gate, Present
    293     .word 0                             # Offset 16:31
    294     .quad 0                             # Offset 32:63
    295 # No. 23
    296     .word 0                             # Offset 0:15
    297     .word CODE_SEL
    298     .byte 0                             # Unused
    299     .byte 0x8e                          # Interrupt Gate, Present
    300     .word 0                             # Offset 16:31
    301     .quad 0                             # Offset 32:63
    302 # No. 24
    303     .word 0                             # Offset 0:15
    304     .word CODE_SEL
    305     .byte 0                             # Unused
    306     .byte 0x8e                          # Interrupt Gate, Present
    307     .word 0                             # Offset 16:31
    308     .quad 0                             # Offset 32:63
    309 # No. 25
    310     .word 0                             # Offset 0:15
    311     .word CODE_SEL
    312     .byte 0                             # Unused
    313     .byte 0x8e                          # Interrupt Gate, Present
    314     .word 0                             # Offset 16:31
    315     .quad 0                             # Offset 32:63
    316 # No. 26
    317     .word 0                             # Offset 0:15
    318     .word CODE_SEL
    319     .byte 0                             # Unused
    320     .byte 0x8e                          # Interrupt Gate, Present
    321     .word 0                             # Offset 16:31
    322     .quad 0                             # Offset 32:63
    323 # No. 27
    324     .word 0                             # Offset 0:15
    325     .word CODE_SEL
    326     .byte 0                             # Unused
    327     .byte 0x8e                          # Interrupt Gate, Present
    328     .word 0                             # Offset 16:31
    329     .quad 0                             # Offset 32:63
    330 # No. 28
    331     .word 0                             # Offset 0:15
    332     .word CODE_SEL
    333     .byte 0                             # Unused
    334     .byte 0x8e                          # Interrupt Gate, Present
    335     .word 0                             # Offset 16:31
    336     .quad 0                             # Offset 32:63
    337 # No. 29
    338     .word 0                             # Offset 0:15
    339     .word CODE_SEL
    340     .byte 0                             # Unused
    341     .byte 0x8e                          # Interrupt Gate, Present
    342     .word 0                             # Offset 16:31
    343     .quad 0                             # Offset 32:63
    344 # No. 30
    345     .word 0                             # Offset 0:15
    346     .word CODE_SEL
    347     .byte 0                             # Unused
    348     .byte 0x8e                          # Interrupt Gate, Present
    349     .word 0                             # Offset 16:31
    350     .quad 0                             # Offset 32:63
    351 # No. 31
    352     .word 0                             # Offset 0:15
    353     .word CODE_SEL
    354     .byte 0                             # Unused
    355     .byte 0x8e                          # Interrupt Gate, Present
    356     .word 0                             # Offset 16:31
    357     .quad 0                             # Offset 32:63
    358 # No. 32
    359     .word 0                             # Offset 0:15
    360     .word CODE_SEL
    361     .byte 0                             # Unused
    362     .byte 0x8e                          # Interrupt Gate, Present
    363     .word 0                             # Offset 16:31
    364     .quad 0                             # Offset 32:63
    365 
    366 _SmiIDTEnd:
    367 
    368 .equ  IDT_SIZE, (_SmiIDTEnd - _SmiIDT)
    369 
    370     .text
    371 
    372 #------------------------------------------------------------------------------
    373 # _SmiExceptionEntryPoints is the collection of exception entry points followed
    374 # by a common exception handler.
    375 #
    376 # Stack frame would be as follows as specified in IA32 manuals:
    377 # +---------------------+ <-- 16-byte aligned ensured by processor
    378 # +    Old SS           +
    379 # +---------------------+
    380 # +    Old RSP          +
    381 # +---------------------+
    382 # +    RFlags           +
    383 # +---------------------+
    384 # +    CS               +
    385 # +---------------------+
    386 # +    RIP              +
    387 # +---------------------+
    388 # +    Error Code       +
    389 # +---------------------+
    390 # +   Vector Number     +
    391 # +---------------------+
    392 # +    RBP              +
    393 # +---------------------+ <-- RBP, 16-byte aligned
    394 #
    395 # RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT
    396 #------------------------------------------------------------------------------
    397 ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)
    398 ASM_PFX(PageFaultIdtHandlerSmmProfile):
    399     pushq   $0x0e                    # Page Fault
    400     .byte   0x40, 0xf6, 0xc4, 0x08    #test    spl, 8
    401     jnz     L1
    402     pushq   (%rsp)
    403     movq    $0, 8(%rsp)
    404 L1:
    405     pushq   %rbp
    406     movq    %rsp, %rbp
    407 
    408     #
    409     # Since here the stack pointer is 16-byte aligned, so
    410     # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
    411     # is 16-byte aligned
    412     #
    413 
    414 ## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
    415 ## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
    416     pushq   %r15
    417     pushq   %r14
    418     pushq   %r13
    419     pushq   %r12
    420     pushq   %r11
    421     pushq   %r10
    422     pushq   %r9
    423     pushq   %r8
    424     pushq   %rax
    425     pushq   %rcx
    426     pushq   %rdx
    427     pushq   %rbx
    428     pushq   48(%rbp)                   # RSP
    429     pushq   (%rbp)                     # RBP
    430     pushq   %rsi
    431     pushq   %rdi
    432 
    433 ## UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero
    434     movzwq 56(%rbp), %rax
    435     pushq   %rax                       # for ss
    436     movzwq  32(%rbp), %rax
    437     pushq   %rax                       # for cs
    438     movq    %ds, %rax
    439     pushq   %rax
    440     movq    %es, %rax
    441     pushq   %rax
    442     movq    %fs, %rax
    443     pushq   %rax
    444     movq    %gs, %rax
    445     pushq   %rax
    446 
    447 ## UINT64  Rip;
    448     pushq   24(%rbp)
    449 
    450 ## UINT64  Gdtr[2], Idtr[2];
    451     subq    $16, %rsp
    452     sidt    (%rsp)
    453     subq    $16, %rsp
    454     sgdt    (%rsp)
    455 
    456 ## UINT64  Ldtr, Tr;
    457     xorq    %rax, %rax
    458     strw    %ax
    459     pushq   %rax
    460     sldtw   %ax
    461     pushq   %rax
    462 
    463 ## UINT64  RFlags;
    464     pushq   40(%rbp)
    465 
    466 ## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
    467     movq    %cr8, %rax
    468     pushq   %rax
    469     movq    %cr4, %rax
    470     orq     $0x208, %rax
    471     movq    %rax, %cr4
    472     pushq   %rax
    473     movq    %cr3, %rax
    474     pushq   %rax
    475     movq    %cr2, %rax
    476     pushq   %rax
    477     xorq    %rax, %rax
    478     pushq   %rax
    479     movq    %cr0, %rax
    480     pushq   %rax
    481 
    482 ## UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
    483     movq    %dr7, %rax
    484     pushq   %rax
    485     movq    %dr6, %rax
    486     pushq   %rax
    487     movq    %dr3, %rax
    488     pushq   %rax
    489     movq    %dr2, %rax
    490     pushq   %rax
    491     movq    %dr1, %rax
    492     pushq   %rax
    493     movq    %dr0, %rax
    494     pushq   %rax
    495 
    496 ## FX_SAVE_STATE_X64 FxSaveState;
    497 
    498     subq    $512, %rsp
    499     movq    %rsp, %rdi
    500     .byte   0xf, 0xae, 0x7                  # fxsave [rdi]
    501 
    502 # UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
    503     cld
    504 
    505 ## UINT32  ExceptionData;
    506     pushq   16(%rbp)
    507 
    508 ## call into exception handler
    509     movq    8(%rbp), %rcx
    510     movabsq $ASM_PFX(SmiPFHandler), %rax
    511 
    512 ## Prepare parameter and call
    513     movq    %rsp, %rdx
    514     #
    515     # Per X64 calling convention, allocate maximum parameter stack space
    516     # and make sure RSP is 16-byte aligned
    517     #
    518     subq    $4 * 8 + 8, %rsp
    519     call    *%rax
    520     addq    $4 * 8 + 8, %rsp
    521     jmp     L5
    522 
    523 L5:
    524 ## UINT64  ExceptionData;
    525     addq    $8, %rsp
    526 
    527 ## FX_SAVE_STATE_X64 FxSaveState;
    528 
    529     movq    %rsp, %rsi
    530     .byte   0xf, 0xae, 0xe                 # fxrstor [rsi]
    531     addq    $512, %rsp
    532 
    533 ## UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
    534 ## Skip restoration of DRx registers to support debuggers
    535 ## that set breakpoints in interrupt/exception context
    536     addq    $8 * 6, %rsp
    537 
    538 ## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
    539     popq    %rax
    540     movq    %rax, %cr0
    541     addq    $8, %rsp                      # not for Cr1
    542     popq    %rax
    543     movq    %rax, %cr2
    544     popq    %rax
    545     movq    %rax, %cr3
    546     popq    %rax
    547     movq    %rax, %cr4
    548     popq    %rax
    549     movq    %rax, %cr8
    550 
    551 ## UINT64  RFlags;
    552     popq    40(%rbp)
    553 
    554 ## UINT64  Ldtr, Tr;
    555 ## UINT64  Gdtr[2], Idtr[2];
    556 ## Best not let anyone mess with these particular registers...
    557     addq    $48, %rsp
    558 
    559 ## UINT64  Rip;
    560     popq    24(%rbp)
    561 
    562 ## UINT64  Gs, Fs, Es, Ds, Cs, Ss;
    563     popq    %rax
    564     # mov   gs, rax ; not for gs
    565     popq    %rax
    566     # mov   fs, rax ; not for fs
    567     # (X64 will not use fs and gs, so we do not restore it)
    568     popq    %rax
    569     movq    %rax, %es
    570     popq    %rax
    571     movq    %rax, %ds
    572     popq    32(%rbp)                      # for cs
    573     popq    56(%rbp)                      # for ss
    574 
    575 ## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
    576 ## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
    577     popq    %rdi
    578     popq    %rsi
    579     addq    $8, %rsp                      # not for rbp
    580     popq    48(%rbp)                      # for rsp
    581     popq    %rbx
    582     popq    %rdx
    583     popq    %rcx
    584     popq    %rax
    585     popq    %r8
    586     popq    %r9
    587     popq    %r10
    588     popq    %r11
    589     popq    %r12
    590     popq    %r13
    591     popq    %r14
    592     popq    %r15
    593 
    594     movq    %rbp, %rsp
    595 
    596 # Enable TF bit after page fault handler runs
    597     btsl    $8, 40(%rsp)                 #RFLAGS
    598 
    599     popq    %rbp
    600     addq    $16, %rsp                    # skip INT# & ErrCode
    601     iretq
    602 
    603 ASM_GLOBAL ASM_PFX(InitializeIDTSmmStackGuard)
    604 ASM_PFX(InitializeIDTSmmStackGuard):
    605 # If SMM Stack Guard feature is enabled, set the IST field of
    606 # the interrupt gate for Page Fault Exception to be 1
    607 #
    608     movabsq  $_SmiIDT + 14 * 16, %rax
    609     movb     $1, 4(%rax)
    610     ret
    611