1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016 - 2019, 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"
18 %define MSR_IA32_S_CET 0x6A2
19 %define MSR_IA32_CET_SH_STK_EN 0x1
20 %define MSR_IA32_CET_WR_SHSTK_EN 0x2
21 %define MSR_IA32_CET_ENDBR_EN 0x4
22 %define MSR_IA32_CET_LEG_IW_EN 0x8
23 %define MSR_IA32_CET_NO_TRACK_EN 0x10
24 %define MSR_IA32_CET_SUPPRESS_DIS 0x20
25 %define MSR_IA32_CET_SUPPRESS 0x400
26 %define MSR_IA32_CET_TRACKER 0x800
27 %define MSR_IA32_PL0_SSP 0x6A4
29 %define CR4_CET 0x800000
31 %define MSR_IA32_MISC_ENABLE 0x1A0
32 %define MSR_EFER 0xc0000080
33 %define MSR_EFER_XD 0x800
36 ; Constants relating to PROCESSOR_SMM_DESCRIPTOR
38 %define DSC_OFFSET 0xfb00
39 %define DSC_GDTPTR 0x30
40 %define DSC_GDTSIZ 0x38
44 %define DSC_OTHERSEG 20
46 %define PROTECT_MODE_CS 0x8
47 %define PROTECT_MODE_DS 0x20
48 %define TSS_SEGMENT 0x40
50 extern ASM_PFX(SmiRendezvous)
51 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
52 extern ASM_PFX(CpuSmmDebugEntry)
53 extern ASM_PFX(CpuSmmDebugExit)
55 global ASM_PFX(gcSmiHandlerTemplate)
56 global ASM_PFX(gcSmiHandlerSize)
57 global ASM_PFX(gPatchSmiCr3)
58 global ASM_PFX(gPatchSmiStack)
59 global ASM_PFX(gPatchSmbase)
60 extern ASM_PFX(mXdSupported)
61 global ASM_PFX(gPatchXdSupported)
62 extern ASM_PFX(gSmiHandlerIdtr)
64 extern ASM_PFX(mCetSupported)
65 global ASM_PFX(mPatchCetSupported)
66 global ASM_PFX(mPatchCetPl0Ssp)
67 global ASM_PFX(mPatchCetInterruptSsp)
72 ASM_PFX(gcSmiHandlerTemplate):
74 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000
75 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
78 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
80 mov ebp, eax ; ebp = GDT base
81 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
82 mov ax, PROTECT_MODE_CS
84 mov edi, strict dword 0 ; source operand will be patched
85 ASM_PFX(gPatchSmbase):
86 lea eax, [edi + (@32bit - _SmiEntryPoint) + 0x8000]
99 mov ax, PROTECT_MODE_DS
105 mov esp, strict dword 0 ; source operand will be patched
106 ASM_PFX(gPatchSmiStack):
107 mov eax, ASM_PFX(gSmiHandlerIdtr)
112 mov eax, strict dword 0 ; source operand will be patched
113 ASM_PFX(gPatchSmiCr3):
116 ; Need to test for CR4 specific bit support
119 cpuid ; use CPUID to determine if specific CR4 bits are supported
120 xor eax, eax ; Clear EAX
121 test edx, BIT2 ; Check for DE capabilities
125 test edx, BIT6 ; Check for PAE capabilities
129 test edx, BIT7 ; Check for MCE capabilities
133 test edx, BIT24 ; Check for FXSR capabilities
137 test edx, BIT25 ; Check for SSE capabilities
140 .4: ; as cr4.PGE is not set here, refresh cr3
141 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
143 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
146 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag
151 ; enable NXE if supported
152 mov al, strict byte 1 ; source operand may be patched
153 ASM_PFX(gPatchXdSupported):
157 ; Check XD disable bit
159 mov ecx, MSR_IA32_MISC_ENABLE
161 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
162 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
164 and dx, 0xFFFB ; clear XD Disable bit if it is set
169 or ax, MSR_EFER_XD ; enable NXE
177 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
179 lea ebx, [edi + DSC_OFFSET]
180 mov ax, [ebx + DSC_DS]
182 mov ax, [ebx + DSC_OTHERSEG]
186 mov ax, [ebx + DSC_SS]
189 mov ebx, [esp + 4] ; ebx <- CpuIndex
191 ; enable CET if supported
192 mov al, strict byte 1 ; source operand may be patched
193 ASM_PFX(mPatchCetSupported):
197 mov ecx, MSR_IA32_S_CET
202 mov ecx, MSR_IA32_PL0_SSP
207 mov ecx, MSR_IA32_S_CET
208 mov eax, MSR_IA32_CET_SH_STK_EN
212 mov ecx, MSR_IA32_PL0_SSP
213 mov eax, strict dword 0 ; source operand will be patched
214 ASM_PFX(mPatchCetPl0Ssp):
218 btr ecx, 16 ; clear WP
220 mov [eax], eax ; reload SSP, and clear busyflag.
224 mov eax, strict dword 0 ; source operand will be patched
225 ASM_PFX(mPatchCetInterruptSsp):
228 mov [eax], eax ; reload SSP, and clear busyflag.
237 mov eax, 0x668 | CR4_CET
245 mov eax, ASM_PFX(CpuSmmDebugEntry)
250 mov eax, ASM_PFX(SmiRendezvous)
255 mov eax, ASM_PFX(CpuSmmDebugExit)
259 mov eax, ASM_PFX(mCetSupported)
265 mov cr4, eax ; disable CET
267 mov ecx, MSR_IA32_PL0_SSP
272 mov ecx, MSR_IA32_S_CET
278 mov eax, ASM_PFX(mXdSupported)
282 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
285 mov ecx, MSR_IA32_MISC_ENABLE
287 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
295 ASM_PFX(gcSmiHandlerSize): DW $ - _SmiEntryPoint
297 global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)
298 ASM_PFX(PiSmmCpuSmiEntryFixupAddress):