Home | History | Annotate | Download | only in Ia32
      1 ;------------------------------------------------------------------------------ ;
      2 ; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
      3 ; This program and the accompanying materials
      4 ; are licensed and made available under the terms and conditions of the BSD License
      5 ; which accompanies this distribution.  The full text of the license may be found at
      6 ; http://opensource.org/licenses/bsd-license.php.
      7 ;
      8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
      9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     10 ;
     11 ; Module Name:
     12 ;
     13 ;   SmiEntry.nasm
     14 ;
     15 ; Abstract:
     16 ;
     17 ;   Code template of the SMI handler for a particular processor
     18 ;
     19 ;-------------------------------------------------------------------------------
     20 
     21 %define MSR_IA32_MISC_ENABLE 0x1A0
     22 %define MSR_EFER      0xc0000080
     23 %define MSR_EFER_XD   0x800
     24 
     25 ;
     26 ; Constants relating to PROCESSOR_SMM_DESCRIPTOR
     27 ;
     28 %define DSC_OFFSET 0xfb00
     29 %define DSC_GDTPTR 0x30
     30 %define DSC_GDTSIZ 0x38
     31 %define DSC_CS 14
     32 %define DSC_DS 16
     33 %define DSC_SS 18
     34 %define DSC_OTHERSEG 20
     35 
     36 %define PROTECT_MODE_CS 0x8
     37 %define PROTECT_MODE_DS 0x20
     38 %define TSS_SEGMENT 0x40
     39 
     40 extern ASM_PFX(SmiRendezvous)
     41 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
     42 extern ASM_PFX(CpuSmmDebugEntry)
     43 extern ASM_PFX(CpuSmmDebugExit)
     44 
     45 global ASM_PFX(gcSmiHandlerTemplate)
     46 global ASM_PFX(gcSmiHandlerSize)
     47 global ASM_PFX(gSmiCr3)
     48 global ASM_PFX(gSmiStack)
     49 global ASM_PFX(gSmbase)
     50 global ASM_PFX(mXdSupported)
     51 extern ASM_PFX(gSmiHandlerIdtr)
     52 
     53     SECTION .text
     54 
     55 BITS 16
     56 ASM_PFX(gcSmiHandlerTemplate):
     57 _SmiEntryPoint:
     58     mov     bx, _GdtDesc - _SmiEntryPoint + 0x8000
     59     mov     ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
     60     dec     ax
     61     mov     [cs:bx], ax
     62     mov     eax, [cs:DSC_OFFSET + DSC_GDTPTR]
     63     mov     [cs:bx + 2], eax
     64     mov     ebp, eax                      ; ebp = GDT base
     65 o32 lgdt    [cs:bx]                       ; lgdt fword ptr cs:[bx]
     66     mov     ax, PROTECT_MODE_CS
     67     mov     [cs:bx-0x2],ax
     68     DB      0x66, 0xbf                   ; mov edi, SMBASE
     69 ASM_PFX(gSmbase): DD 0
     70     lea     eax, [edi + (@32bit - _SmiEntryPoint) + 0x8000]
     71     mov     [cs:bx-0x6],eax
     72     mov     ebx, cr0
     73     and     ebx, 0x9ffafff3
     74     or      ebx, 0x23
     75     mov     cr0, ebx
     76     jmp     dword 0x0:0x0
     77 _GdtDesc:
     78     DW 0
     79     DD 0
     80 
     81 BITS 32
     82 @32bit:
     83     mov     ax, PROTECT_MODE_DS
     84 o16 mov     ds, ax
     85 o16 mov     es, ax
     86 o16 mov     fs, ax
     87 o16 mov     gs, ax
     88 o16 mov     ss, ax
     89     DB      0xbc                   ; mov esp, imm32
     90 ASM_PFX(gSmiStack): DD 0
     91     mov     eax, ASM_PFX(gSmiHandlerIdtr)
     92     lidt    [eax]
     93     jmp     ProtFlatMode
     94 
     95 ProtFlatMode:
     96     DB      0xb8                        ; mov eax, imm32
     97 ASM_PFX(gSmiCr3): DD 0
     98     mov     cr3, eax
     99 ;
    100 ; Need to test for CR4 specific bit support
    101 ;
    102     mov     eax, 1
    103     cpuid                               ; use CPUID to determine if specific CR4 bits are supported
    104     xor     eax, eax                    ; Clear EAX
    105     test    edx, BIT2                   ; Check for DE capabilities
    106     jz      .0
    107     or      eax, BIT3
    108 .0:
    109     test    edx, BIT6                   ; Check for PAE capabilities
    110     jz      .1
    111     or      eax, BIT5
    112 .1:
    113     test    edx, BIT7                   ; Check for MCE capabilities
    114     jz      .2
    115     or      eax, BIT6
    116 .2:
    117     test    edx, BIT24                  ; Check for FXSR capabilities
    118     jz      .3
    119     or      eax, BIT9
    120 .3:
    121     test    edx, BIT25                  ; Check for SSE capabilities
    122     jz      .4
    123     or      eax, BIT10
    124 .4:                                     ; as cr4.PGE is not set here, refresh cr3
    125     mov     cr4, eax                    ; in PreModifyMtrrs() to flush TLB.
    126 
    127     cmp     byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
    128     jz      .6
    129 ; Load TSS
    130     mov     byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag
    131     mov     eax, TSS_SEGMENT
    132     ltr     ax
    133 .6:
    134 
    135 ; enable NXE if supported
    136     DB      0b0h                        ; mov al, imm8
    137 ASM_PFX(mXdSupported):     DB      1
    138     cmp     al, 0
    139     jz      @SkipXd
    140 ;
    141 ; Check XD disable bit
    142 ;
    143     mov     ecx, MSR_IA32_MISC_ENABLE
    144     rdmsr
    145     push    edx                        ; save MSR_IA32_MISC_ENABLE[63-32]
    146     test    edx, BIT2                  ; MSR_IA32_MISC_ENABLE[34]
    147     jz      .5
    148     and     dx, 0xFFFB                 ; clear XD Disable bit if it is set
    149     wrmsr
    150 .5:
    151     mov     ecx, MSR_EFER
    152     rdmsr
    153     or      ax, MSR_EFER_XD             ; enable NXE
    154     wrmsr
    155     jmp     @XdDone
    156 @SkipXd:
    157     sub     esp, 4
    158 @XdDone:
    159 
    160     mov     ebx, cr0
    161     or      ebx, 0x80010023             ; enable paging + WP + NE + MP + PE
    162     mov     cr0, ebx
    163     lea     ebx, [edi + DSC_OFFSET]
    164     mov     ax, [ebx + DSC_DS]
    165     mov     ds, eax
    166     mov     ax, [ebx + DSC_OTHERSEG]
    167     mov     es, eax
    168     mov     fs, eax
    169     mov     gs, eax
    170     mov     ax, [ebx + DSC_SS]
    171     mov     ss, eax
    172 
    173 ;   jmp     _SmiHandler                 ; instruction is not needed
    174 
    175 global ASM_PFX(SmiHandler)
    176 ASM_PFX(SmiHandler):
    177     mov     ebx, [esp + 4]                  ; CPU Index
    178     push    ebx
    179     mov     eax, ASM_PFX(CpuSmmDebugEntry)
    180     call    eax
    181     add     esp, 4
    182 
    183     push    ebx
    184     mov     eax, ASM_PFX(SmiRendezvous)
    185     call    eax
    186     add     esp, 4
    187 
    188     push    ebx
    189     mov     eax, ASM_PFX(CpuSmmDebugExit)
    190     call    eax
    191     add     esp, 4
    192 
    193     mov     eax, ASM_PFX(mXdSupported)
    194     mov     al, [eax]
    195     cmp     al, 0
    196     jz      .7
    197     pop     edx                       ; get saved MSR_IA32_MISC_ENABLE[63-32]
    198     test    edx, BIT2
    199     jz      .7
    200     mov     ecx, MSR_IA32_MISC_ENABLE
    201     rdmsr
    202     or      dx, BIT2                  ; set XD Disable bit if it was set before entering into SMM
    203     wrmsr
    204 
    205 .7:
    206     rsm
    207 
    208 ASM_PFX(gcSmiHandlerSize): DW $ - _SmiEntryPoint
    209 
    210