1;------------------------------------------------------------------------------ ;
2; Copyright (c) 2009 - 2015, 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.asm
14;
15; Abstract:
16;
17;   Code template of the SMI handler for a particular processor
18;
19;-------------------------------------------------------------------------------
20
21    .686p
22    .model  flat,C
23    .xmm
24
25DSC_OFFSET    EQU     0fb00h
26DSC_GDTPTR    EQU     30h
27DSC_GDTSIZ    EQU     38h
28DSC_CS        EQU     14
29DSC_DS        EQU     16
30DSC_SS        EQU     18
31DSC_OTHERSEG  EQU     20
32
33PROTECT_MODE_CS EQU   08h
34PROTECT_MODE_DS EQU   20h
35TSS_SEGMENT     EQU   40h
36
37SmiRendezvous      PROTO   C
38CpuSmmDebugEntry   PROTO   C
39CpuSmmDebugExit    PROTO   C
40
41EXTERNDEF   gcSmiHandlerTemplate:BYTE
42EXTERNDEF   gcSmiHandlerSize:WORD
43EXTERNDEF   gSmiCr3:DWORD
44EXTERNDEF   gSmiStack:DWORD
45EXTERNDEF   gSmbase:DWORD
46EXTERNDEF   FeaturePcdGet (PcdCpuSmmStackGuard):BYTE
47EXTERNDEF   gSmiHandlerIdtr:FWORD
48
49    .code
50
51gcSmiHandlerTemplate    LABEL   BYTE
52
53_SmiEntryPoint:
54    DB      0bbh                        ; mov bx, imm16
55    DW      offset _GdtDesc - _SmiEntryPoint + 8000h
56    DB      2eh, 0a1h                   ; mov ax, cs:[offset16]
57    DW      DSC_OFFSET + DSC_GDTSIZ
58    dec     eax
59    mov     cs:[edi], eax               ; mov cs:[bx], ax
60    DB      66h, 2eh, 0a1h              ; mov eax, cs:[offset16]
61    DW      DSC_OFFSET + DSC_GDTPTR
62    mov     cs:[edi + 2], ax            ; mov cs:[bx + 2], eax
63    mov     bp, ax                      ; ebp = GDT base
64    DB      66h
65    lgdt    fword ptr cs:[edi]          ; lgdt fword ptr cs:[bx]
66; Patch ProtectedMode Segment
67    DB      0b8h                        ; mov ax, imm16
68    DW      PROTECT_MODE_CS             ; set AX for segment directly
69    mov     cs:[edi - 2], eax           ; mov cs:[bx - 2], ax
70; Patch ProtectedMode entry
71    DB      66h, 0bfh                   ; mov edi, SMBASE
72gSmbase    DD    ?
73    DB      67h
74    lea     ax, [edi + (@32bit - _SmiEntryPoint) + 8000h]
75    mov     cs:[edi - 6], ax            ; mov cs:[bx - 6], eax
76    mov     ebx, cr0
77    DB      66h
78    and     ebx, 9ffafff3h
79    DB      66h
80    or      ebx, 23h
81    mov     cr0, ebx
82    DB      66h, 0eah
83    DD      ?
84    DW      ?
85_GdtDesc    FWORD   ?
86
87@32bit:
88    mov     ax, PROTECT_MODE_DS
89    mov     ds, ax
90    mov     es, ax
91    mov     fs, ax
92    mov     gs, ax
93    mov     ss, ax
94    DB      0bch                   ; mov esp, imm32
95gSmiStack   DD      ?
96    mov     eax, offset gSmiHandlerIdtr
97    lidt    fword ptr [eax]
98    jmp     ProtFlatMode
99
100ProtFlatMode:
101    DB      0b8h                        ; mov eax, imm32
102gSmiCr3     DD      ?
103    mov     cr3, eax
104;
105; Need to test for CR4 specific bit support
106;
107    mov     eax, 1
108    cpuid                               ; use CPUID to determine if specific CR4 bits are supported
109    xor     eax, eax                    ; Clear EAX
110    test    edx, BIT2                   ; Check for DE capabilities
111    jz      @f
112    or      eax, BIT3
113@@:
114    test    edx, BIT6                   ; Check for PAE capabilities
115    jz      @f
116    or      eax, BIT5
117@@:
118    test    edx, BIT7                   ; Check for MCE capabilities
119    jz      @f
120    or      eax, BIT6
121@@:
122    test    edx, BIT24                  ; Check for FXSR capabilities
123    jz      @f
124    or      eax, BIT9
125@@:
126    test    edx, BIT25                  ; Check for SSE capabilities
127    jz      @f
128    or      eax, BIT10
129@@:                                     ; as cr4.PGE is not set here, refresh cr3
130    mov     cr4, eax                    ; in PreModifyMtrrs() to flush TLB.
131    mov     ebx, cr0
132    or      ebx, 080010000h             ; enable paging + WP
133    mov     cr0, ebx
134    lea     ebx, [edi + DSC_OFFSET]
135    mov     ax, [ebx + DSC_DS]
136    mov     ds, eax
137    mov     ax, [ebx + DSC_OTHERSEG]
138    mov     es, eax
139    mov     fs, eax
140    mov     gs, eax
141    mov     ax, [ebx + DSC_SS]
142    mov     ss, eax
143
144    cmp     FeaturePcdGet (PcdCpuSmmStackGuard), 0
145    jz      @F
146
147; Load TSS
148    mov     byte ptr [ebp + TSS_SEGMENT + 5], 89h ; clear busy flag
149    mov     eax, TSS_SEGMENT
150    ltr     ax
151@@:
152;   jmp     _SmiHandler                 ; instruction is not needed
153
154_SmiHandler PROC
155    mov     ebx, [esp]                  ; CPU Index
156
157    push    ebx
158    mov     eax, CpuSmmDebugEntry
159    call    eax
160    pop     ecx
161
162    push    ebx
163    mov     eax, SmiRendezvous
164    call    eax
165    pop     ecx
166
167    push    ebx
168    mov     eax, CpuSmmDebugExit
169    call    eax
170    pop     ecx
171
172    rsm
173_SmiHandler ENDP
174
175gcSmiHandlerSize    DW      $ - _SmiEntryPoint
176
177    END
178