1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2009 - 2017, 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.
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.
17 ; Code template of the SMI handler for a particular processor
19 ;-------------------------------------------------------------------------------
25 MSR_IA32_MISC_ENABLE EQU 1A0h
26 MSR_EFER EQU 0c0000080h
30 ; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR
40 PROTECT_MODE_CS EQU 08h
41 PROTECT_MODE_DS EQU 20h
45 CpuSmmDebugEntry PROTO C
46 CpuSmmDebugExit PROTO C
48 EXTERNDEF gcStmSmiHandlerTemplate:BYTE
49 EXTERNDEF gcStmSmiHandlerSize:WORD
50 EXTERNDEF gcStmSmiHandlerOffset:WORD
51 EXTERNDEF gStmSmiCr3:DWORD
52 EXTERNDEF gStmSmiStack:DWORD
53 EXTERNDEF gStmSmbase:DWORD
54 EXTERNDEF gStmXdSupported:BYTE
55 EXTERNDEF FeaturePcdGet (PcdCpuSmmStackGuard):BYTE
56 EXTERNDEF gStmSmiHandlerIdtr:FWORD
60 gcStmSmiHandlerTemplate LABEL BYTE
63 DB 0bbh ; mov bx, imm16
64 DW offset _StmGdtDesc - _StmSmiEntryPoint + 8000h
65 DB 2eh, 0a1h ; mov ax, cs:[offset16]
66 DW DSC_OFFSET + DSC_GDTSIZ
68 mov cs:[edi], eax ; mov cs:[bx], ax
69 DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]
70 DW DSC_OFFSET + DSC_GDTPTR
71 mov cs:[edi + 2], ax ; mov cs:[bx + 2], eax
72 mov bp, ax ; ebp = GDT base
74 lgdt fword ptr cs:[edi] ; lgdt fword ptr cs:[bx]
75 ; Patch ProtectedMode Segment
76 DB 0b8h ; mov ax, imm16
77 DW PROTECT_MODE_CS ; set AX for segment directly
78 mov cs:[edi - 2], eax ; mov cs:[bx - 2], ax
79 ; Patch ProtectedMode entry
80 DB 66h, 0bfh ; mov edi, SMBASE
83 lea ax, [edi + (@32bit - _StmSmiEntryPoint) + 8000h]
84 mov cs:[edi - 6], ax ; mov cs:[bx - 6], eax
97 mov ax, PROTECT_MODE_DS
103 DB 0bch ; mov esp, imm32
105 mov eax, offset gStmSmiHandlerIdtr
110 DB 0b8h ; mov eax, imm32
114 ; Need to test for CR4 specific bit support
117 cpuid ; use CPUID to determine if specific CR4 bits are supported
118 xor eax, eax ; Clear EAX
119 test edx, BIT2 ; Check for DE capabilities
123 test edx, BIT6 ; Check for PAE capabilities
127 test edx, BIT7 ; Check for MCE capabilities
131 test edx, BIT24 ; Check for FXSR capabilities
135 test edx, BIT25 ; Check for SSE capabilities
138 @@: ; as cr4.PGE is not set here, refresh cr3
139 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
141 cmp FeaturePcdGet (PcdCpuSmmStackGuard), 0
144 mov byte ptr [ebp + TSS_SEGMENT + 5], 89h ; clear busy flag
149 ; enable NXE if supported
150 DB 0b0h ; mov al, imm8
155 ; Check XD disable bit
157 mov ecx, MSR_IA32_MISC_ENABLE
159 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
160 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
162 and dx, 0FFFBh ; clear XD Disable bit if it is set
167 or ax, MSR_EFER_XD ; enable NXE
175 or ebx, 080010023h ; enable paging + WP + NE + MP + PE
177 lea ebx, [edi + DSC_OFFSET]
178 mov ax, [ebx + DSC_DS]
180 mov ax, [ebx + DSC_OTHERSEG]
184 mov ax, [ebx + DSC_SS]
188 mov ebx, [esp + 4] ; CPU Index
190 mov eax, CpuSmmDebugEntry
195 mov eax, SmiRendezvous
200 mov eax, CpuSmmDebugExit
204 mov eax, offset gStmXdSupported
208 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
211 mov ecx, MSR_IA32_MISC_ENABLE
213 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
221 ; Check XD disable bit
224 mov eax, offset gStmXdSupported
228 mov ecx, MSR_IA32_MISC_ENABLE
230 mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32]
231 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
233 and dx, 0FFFBh ; clear XD Disable bit if it is set
238 or ax, MSR_EFER_XD ; enable NXE
243 ; below step is needed, because STM does not run above code.
244 ; we have to run below code to set IDT/CR0/CR4
245 mov eax, offset gStmSmiHandlerIdtr
250 or eax, 80010023h ; enable paging + WP + NE + MP + PE
253 ; Need to test for CR4 specific bit support
256 cpuid ; use CPUID to determine if specific CR4 bits are supported
257 mov eax, cr4 ; init EAX
258 test edx, BIT2 ; Check for DE capabilities
262 test edx, BIT6 ; Check for PAE capabilities
266 test edx, BIT7 ; Check for MCE capabilities
270 test edx, BIT24 ; Check for FXSR capabilities
274 test edx, BIT25 ; Check for SSE capabilities
277 @@: ; as cr4.PGE is not set here, refresh cr3
278 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
282 gcStmSmiHandlerSize DW $ - _StmSmiEntryPoint
283 gcStmSmiHandlerOffset DW _StmSmiHandler - _StmSmiEntryPoint