1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
3 ; SPDX-License-Identifier: BSD-2-Clause-Patent
11 ; Code template of the SMI handler for a particular processor
13 ;-------------------------------------------------------------------------------
15 %include "StuffRsbNasm.inc"
17 %define MSR_IA32_MISC_ENABLE 0x1A0
18 %define MSR_EFER 0xc0000080
19 %define MSR_EFER_XD 0x800
22 ; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR
24 %define DSC_OFFSET 0xfb00
25 %define DSC_GDTPTR 0x48
26 %define DSC_GDTSIZ 0x50
30 %define DSC_OTHERSEG 0x1a
32 %define PROTECT_MODE_CS 0x8
33 %define PROTECT_MODE_DS 0x20
34 %define TSS_SEGMENT 0x40
36 extern ASM_PFX(SmiRendezvous)
37 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
38 extern ASM_PFX(CpuSmmDebugEntry)
39 extern ASM_PFX(CpuSmmDebugExit)
41 global ASM_PFX(gcStmSmiHandlerTemplate)
42 global ASM_PFX(gcStmSmiHandlerSize)
43 global ASM_PFX(gcStmSmiHandlerOffset)
44 global ASM_PFX(gStmSmiCr3)
45 global ASM_PFX(gStmSmiStack)
46 global ASM_PFX(gStmSmbase)
47 global ASM_PFX(gStmXdSupported)
48 extern ASM_PFX(gStmSmiHandlerIdtr)
50 ASM_PFX(gStmSmiCr3) EQU StmSmiCr3Patch - 4
51 ASM_PFX(gStmSmiStack) EQU StmSmiStackPatch - 4
52 ASM_PFX(gStmSmbase) EQU StmSmbasePatch - 4
53 ASM_PFX(gStmXdSupported) EQU StmXdSupportedPatch - 1
58 ASM_PFX(gcStmSmiHandlerTemplate):
60 mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000
61 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
64 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
66 mov ebp, eax ; ebp = GDT base
67 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
68 mov ax, PROTECT_MODE_CS
70 o32 mov edi, strict dword 0
72 lea eax, [edi + (@32bit - _StmSmiEntryPoint) + 0x8000]
85 mov ax, PROTECT_MODE_DS
91 mov esp, strict dword 0
93 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
98 mov eax, strict dword 0
102 ; Need to test for CR4 specific bit support
105 cpuid ; use CPUID to determine if specific CR4 bits are supported
106 xor eax, eax ; Clear EAX
107 test edx, BIT2 ; Check for DE capabilities
111 test edx, BIT6 ; Check for PAE capabilities
115 test edx, BIT7 ; Check for MCE capabilities
119 test edx, BIT24 ; Check for FXSR capabilities
123 test edx, BIT25 ; Check for SSE capabilities
126 .4: ; as cr4.PGE is not set here, refresh cr3
127 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
129 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
132 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag
137 ; enable NXE if supported
138 mov al, strict byte 1
143 ; Check XD disable bit
145 mov ecx, MSR_IA32_MISC_ENABLE
147 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
148 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
150 and dx, 0xFFFB ; clear XD Disable bit if it is set
155 or ax, MSR_EFER_XD ; enable NXE
163 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
165 lea ebx, [edi + DSC_OFFSET]
166 mov ax, [ebx + DSC_DS]
168 mov ax, [ebx + DSC_OTHERSEG]
172 mov ax, [ebx + DSC_SS]
176 mov ebx, [esp + 4] ; CPU Index
178 mov eax, ASM_PFX(CpuSmmDebugEntry)
183 mov eax, ASM_PFX(SmiRendezvous)
188 mov eax, ASM_PFX(CpuSmmDebugExit)
192 mov eax, ASM_PFX(gStmXdSupported)
196 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
199 mov ecx, MSR_IA32_MISC_ENABLE
201 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
211 ; Check XD disable bit
214 mov eax, ASM_PFX(gStmXdSupported)
218 mov ecx, MSR_IA32_MISC_ENABLE
220 mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32]
221 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
223 and dx, 0xFFFB ; clear XD Disable bit if it is set
228 or ax, MSR_EFER_XD ; enable NXE
233 ; below step is needed, because STM does not run above code.
234 ; we have to run below code to set IDT/CR0/CR4
235 mov eax, ASM_PFX(gStmSmiHandlerIdtr)
239 or eax, 0x80010023 ; enable paging + WP + NE + MP + PE
242 ; Need to test for CR4 specific bit support
245 cpuid ; use CPUID to determine if specific CR4 bits are supported
246 mov eax, cr4 ; init EAX
247 test edx, BIT2 ; Check for DE capabilities
251 test edx, BIT6 ; Check for PAE capabilities
255 test edx, BIT7 ; Check for MCE capabilities
259 test edx, BIT24 ; Check for FXSR capabilities
263 test edx, BIT25 ; Check for SSE capabilities
266 .4: ; as cr4.PGE is not set here, refresh cr3
267 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
271 ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint
272 ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint
274 global ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress)
275 ASM_PFX(SmmCpuFeaturesLibStmSmiEntryFixupAddress):