1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016 - 2019, 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 "StuffRsbNasm.inc"
24 %define MSR_IA32_S_CET 0x6A2
25 %define MSR_IA32_CET_SH_STK_EN 0x1
26 %define MSR_IA32_CET_WR_SHSTK_EN 0x2
27 %define MSR_IA32_CET_ENDBR_EN 0x4
28 %define MSR_IA32_CET_LEG_IW_EN 0x8
29 %define MSR_IA32_CET_NO_TRACK_EN 0x10
30 %define MSR_IA32_CET_SUPPRESS_DIS 0x20
31 %define MSR_IA32_CET_SUPPRESS 0x400
32 %define MSR_IA32_CET_TRACKER 0x800
33 %define MSR_IA32_PL0_SSP 0x6A4
35 %define CR4_CET 0x800000
37 %define MSR_IA32_MISC_ENABLE 0x1A0
38 %define MSR_EFER 0xc0000080
39 %define MSR_EFER_XD 0x800
42 ; Constants relating to PROCESSOR_SMM_DESCRIPTOR
44 %define DSC_OFFSET 0xfb00
45 %define DSC_GDTPTR 0x30
46 %define DSC_GDTSIZ 0x38
50 %define DSC_OTHERSEG 20
52 %define PROTECT_MODE_CS 0x8
53 %define PROTECT_MODE_DS 0x20
54 %define TSS_SEGMENT 0x40
56 extern ASM_PFX(SmiRendezvous)
57 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
58 extern ASM_PFX(CpuSmmDebugEntry)
59 extern ASM_PFX(CpuSmmDebugExit)
61 global ASM_PFX(gcSmiHandlerTemplate)
62 global ASM_PFX(gcSmiHandlerSize)
63 global ASM_PFX(gPatchSmiCr3)
64 global ASM_PFX(gPatchSmiStack)
65 global ASM_PFX(gPatchSmbase)
66 extern ASM_PFX(mXdSupported)
67 global ASM_PFX(gPatchXdSupported)
68 extern ASM_PFX(gSmiHandlerIdtr)
70 extern ASM_PFX(mCetSupported)
71 global ASM_PFX(mPatchCetSupported)
72 global ASM_PFX(mPatchCetPl0Ssp)
73 global ASM_PFX(mPatchCetInterruptSsp)
78 ASM_PFX(gcSmiHandlerTemplate):
80 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000
81 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
84 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
86 mov ebp, eax ; ebp = GDT base
87 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
88 mov ax, PROTECT_MODE_CS
90 mov edi, strict dword 0 ; source operand will be patched
91 ASM_PFX(gPatchSmbase):
92 lea eax, [edi + (@32bit - _SmiEntryPoint) + 0x8000]
105 mov ax, PROTECT_MODE_DS
111 mov esp, strict dword 0 ; source operand will be patched
112 ASM_PFX(gPatchSmiStack):
113 mov eax, ASM_PFX(gSmiHandlerIdtr)
118 mov eax, strict dword 0 ; source operand will be patched
119 ASM_PFX(gPatchSmiCr3):
122 ; Need to test for CR4 specific bit support
125 cpuid ; use CPUID to determine if specific CR4 bits are supported
126 xor eax, eax ; Clear EAX
127 test edx, BIT2 ; Check for DE capabilities
131 test edx, BIT6 ; Check for PAE capabilities
135 test edx, BIT7 ; Check for MCE capabilities
139 test edx, BIT24 ; Check for FXSR capabilities
143 test edx, BIT25 ; Check for SSE capabilities
146 .4: ; as cr4.PGE is not set here, refresh cr3
147 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
149 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
152 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag
157 ; enable NXE if supported
158 mov al, strict byte 1 ; source operand may be patched
159 ASM_PFX(gPatchXdSupported):
163 ; Check XD disable bit
165 mov ecx, MSR_IA32_MISC_ENABLE
167 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
168 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
170 and dx, 0xFFFB ; clear XD Disable bit if it is set
175 or ax, MSR_EFER_XD ; enable NXE
183 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
185 lea ebx, [edi + DSC_OFFSET]
186 mov ax, [ebx + DSC_DS]
188 mov ax, [ebx + DSC_OTHERSEG]
192 mov ax, [ebx + DSC_SS]
195 mov ebx, [esp + 4] ; ebx <- CpuIndex
197 ; enable CET if supported
198 mov al, strict byte 1 ; source operand may be patched
199 ASM_PFX(mPatchCetSupported):
203 mov ecx, MSR_IA32_S_CET
208 mov ecx, MSR_IA32_PL0_SSP
213 mov ecx, MSR_IA32_S_CET
214 mov eax, MSR_IA32_CET_SH_STK_EN
218 mov ecx, MSR_IA32_PL0_SSP
219 mov eax, strict dword 0 ; source operand will be patched
220 ASM_PFX(mPatchCetPl0Ssp):
224 btr ecx, 16 ; clear WP
226 mov [eax], eax ; reload SSP, and clear busyflag.
230 mov eax, strict dword 0 ; source operand will be patched
231 ASM_PFX(mPatchCetInterruptSsp):
234 mov [eax], eax ; reload SSP, and clear busyflag.
243 mov eax, 0x668 | CR4_CET
251 mov eax, ASM_PFX(CpuSmmDebugEntry)
256 mov eax, ASM_PFX(SmiRendezvous)
261 mov eax, ASM_PFX(CpuSmmDebugExit)
265 mov eax, ASM_PFX(mCetSupported)
271 mov cr4, eax ; disable CET
273 mov ecx, MSR_IA32_PL0_SSP
278 mov ecx, MSR_IA32_S_CET
284 mov eax, ASM_PFX(mXdSupported)
288 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
291 mov ecx, MSR_IA32_MISC_ENABLE
293 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
301 ASM_PFX(gcSmiHandlerSize): DW $ - _SmiEntryPoint
303 global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)
304 ASM_PFX(PiSmmCpuSmiEntryFixupAddress):