1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016 - 2018, 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 ;-------------------------------------------------------------------------------
21 %include "StuffRsb.inc"
23 %define MSR_IA32_MISC_ENABLE 0x1A0
24 %define MSR_EFER 0xc0000080
25 %define MSR_EFER_XD 0x800
28 ; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR
30 %define DSC_OFFSET 0xfb00
31 %define DSC_GDTPTR 0x48
32 %define DSC_GDTSIZ 0x50
36 %define DSC_OTHERSEG 0x1a
38 %define PROTECT_MODE_CS 0x8
39 %define PROTECT_MODE_DS 0x20
40 %define TSS_SEGMENT 0x40
42 extern ASM_PFX(SmiRendezvous)
43 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
44 extern ASM_PFX(CpuSmmDebugEntry)
45 extern ASM_PFX(CpuSmmDebugExit)
47 global ASM_PFX(gcStmSmiHandlerTemplate)
48 global ASM_PFX(gcStmSmiHandlerSize)
49 global ASM_PFX(gcStmSmiHandlerOffset)
50 global ASM_PFX(gStmSmiCr3)
51 global ASM_PFX(gStmSmiStack)
52 global ASM_PFX(gStmSmbase)
53 global ASM_PFX(gStmXdSupported)
54 extern ASM_PFX(gStmSmiHandlerIdtr)
56 ASM_PFX(gStmSmiCr3) EQU StmSmiCr3Patch - 4
57 ASM_PFX(gStmSmiStack) EQU StmSmiStackPatch - 4
58 ASM_PFX(gStmSmbase) EQU StmSmbasePatch - 4
59 ASM_PFX(gStmXdSupported) EQU StmXdSupportedPatch - 1
64 ASM_PFX(gcStmSmiHandlerTemplate):
66 mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000
67 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
70 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
72 mov ebp, eax ; ebp = GDT base
73 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
74 mov ax, PROTECT_MODE_CS
76 o32 mov edi, strict dword 0
78 lea eax, [edi + (@32bit - _StmSmiEntryPoint) + 0x8000]
91 mov ax, PROTECT_MODE_DS
97 mov esp, strict dword 0
99 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
104 mov eax, strict dword 0
108 ; Need to test for CR4 specific bit support
111 cpuid ; use CPUID to determine if specific CR4 bits are supported
112 xor eax, eax ; Clear EAX
113 test edx, BIT2 ; Check for DE capabilities
117 test edx, BIT6 ; Check for PAE capabilities
121 test edx, BIT7 ; Check for MCE capabilities
125 test edx, BIT24 ; Check for FXSR capabilities
129 test edx, BIT25 ; Check for SSE capabilities
132 .4: ; as cr4.PGE is not set here, refresh cr3
133 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
135 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
138 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag
143 ; enable NXE if supported
144 mov al, strict byte 1
149 ; Check XD disable bit
151 mov ecx, MSR_IA32_MISC_ENABLE
153 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
154 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
156 and dx, 0xFFFB ; clear XD Disable bit if it is set
161 or ax, MSR_EFER_XD ; enable NXE
169 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
171 lea ebx, [edi + DSC_OFFSET]
172 mov ax, [ebx + DSC_DS]
174 mov ax, [ebx + DSC_OTHERSEG]
178 mov ax, [ebx + DSC_SS]
182 mov ebx, [esp + 4] ; CPU Index
184 mov eax, ASM_PFX(CpuSmmDebugEntry)
189 mov eax, ASM_PFX(SmiRendezvous)
194 mov eax, ASM_PFX(CpuSmmDebugExit)
198 mov eax, ASM_PFX(gStmXdSupported)
202 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
205 mov ecx, MSR_IA32_MISC_ENABLE
207 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
217 ; Check XD disable bit
220 mov eax, ASM_PFX(gStmXdSupported)
224 mov ecx, MSR_IA32_MISC_ENABLE
226 mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32]
227 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
229 and dx, 0xFFFB ; clear XD Disable bit if it is set
234 or ax, MSR_EFER_XD ; enable NXE
239 ; below step is needed, because STM does not run above code.
240 ; we have to run below code to set IDT/CR0/CR4
241 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
245 or eax, 0x80010023 ; enable paging + WP + NE + MP + PE
248 ; Need to test for CR4 specific bit support
251 cpuid ; use CPUID to determine if specific CR4 bits are supported
252 mov eax, cr4 ; init EAX
253 test edx, BIT2 ; Check for DE capabilities
257 test edx, BIT6 ; Check for PAE capabilities
261 test edx, BIT7 ; Check for MCE capabilities
265 test edx, BIT24 ; Check for FXSR capabilities
269 test edx, BIT25 ; Check for SSE capabilities
272 .4: ; as cr4.PGE is not set here, refresh cr3
273 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
277 ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint
278 ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint
280 global ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress)
281 ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress):