]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm
UefiCpuPkg: PiSmmCpuDxeSmm skip MSR_IA32_MISC_ENABLE manipulation on AMD
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiEntry.nasm
CommitLineData
63a4f460 1;------------------------------------------------------------------------------ ;\r
3eb69b08 2; Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>\r
bdafda8c 3; Copyright (c) 2020, AMD Incorporated. All rights reserved.<BR>\r
0acd8697 4; SPDX-License-Identifier: BSD-2-Clause-Patent\r
63a4f460
LG
5;\r
6; Module Name:\r
7;\r
8; SmiEntry.nasm\r
9;\r
10; Abstract:\r
11;\r
12; Code template of the SMI handler for a particular processor\r
13;\r
14;-------------------------------------------------------------------------------\r
15\r
ada4a003 16%include "StuffRsbNasm.inc"\r
3eb69b08
JY
17%include "Nasm.inc"\r
18\r
19%define MSR_IA32_S_CET 0x6A2\r
20%define MSR_IA32_CET_SH_STK_EN 0x1\r
21%define MSR_IA32_CET_WR_SHSTK_EN 0x2\r
22%define MSR_IA32_CET_ENDBR_EN 0x4\r
23%define MSR_IA32_CET_LEG_IW_EN 0x8\r
24%define MSR_IA32_CET_NO_TRACK_EN 0x10\r
25%define MSR_IA32_CET_SUPPRESS_DIS 0x20\r
26%define MSR_IA32_CET_SUPPRESS 0x400\r
27%define MSR_IA32_CET_TRACKER 0x800\r
28%define MSR_IA32_PL0_SSP 0x6A4\r
29\r
30%define CR4_CET 0x800000\r
02f7fd15 31\r
717fb604
JY
32%define MSR_IA32_MISC_ENABLE 0x1A0\r
33%define MSR_EFER 0xc0000080\r
34%define MSR_EFER_XD 0x800\r
35\r
f12367a0
MK
36;\r
37; Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
38;\r
63a4f460
LG
39%define DSC_OFFSET 0xfb00\r
40%define DSC_GDTPTR 0x30\r
41%define DSC_GDTSIZ 0x38\r
42%define DSC_CS 14\r
43%define DSC_DS 16\r
44%define DSC_SS 18\r
45%define DSC_OTHERSEG 20\r
46\r
47%define PROTECT_MODE_CS 0x8\r
48%define PROTECT_MODE_DS 0x20\r
49%define TSS_SEGMENT 0x40\r
50\r
51extern ASM_PFX(SmiRendezvous)\r
52extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))\r
53extern ASM_PFX(CpuSmmDebugEntry)\r
54extern ASM_PFX(CpuSmmDebugExit)\r
55\r
56global ASM_PFX(gcSmiHandlerTemplate)\r
57global ASM_PFX(gcSmiHandlerSize)\r
c455687f 58global ASM_PFX(gPatchSmiCr3)\r
fc504fde 59global ASM_PFX(gPatchSmiStack)\r
5a1bfda4 60global ASM_PFX(gPatchSmbase)\r
3c5ce64f
LE
61extern ASM_PFX(mXdSupported)\r
62global ASM_PFX(gPatchXdSupported)\r
bdafda8c 63global ASM_PFX(gPatchMsrIa32MiscEnableSupported)\r
63a4f460
LG
64extern ASM_PFX(gSmiHandlerIdtr)\r
65\r
3eb69b08
JY
66extern ASM_PFX(mCetSupported)\r
67global ASM_PFX(mPatchCetSupported)\r
68global ASM_PFX(mPatchCetPl0Ssp)\r
69global ASM_PFX(mPatchCetInterruptSsp)\r
70\r
63a4f460
LG
71 SECTION .text\r
72\r
73BITS 16\r
74ASM_PFX(gcSmiHandlerTemplate):\r
75_SmiEntryPoint:\r
76 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000\r
77 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]\r
78 dec ax\r
79 mov [cs:bx], ax\r
80 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]\r
81 mov [cs:bx + 2], eax\r
82 mov ebp, eax ; ebp = GDT base\r
83o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]\r
84 mov ax, PROTECT_MODE_CS\r
717fb604 85 mov [cs:bx-0x2],ax\r
5a1bfda4
LE
86 mov edi, strict dword 0 ; source operand will be patched\r
87ASM_PFX(gPatchSmbase):\r
63a4f460
LG
88 lea eax, [edi + (@32bit - _SmiEntryPoint) + 0x8000]\r
89 mov [cs:bx-0x6],eax\r
90 mov ebx, cr0\r
91 and ebx, 0x9ffafff3\r
92 or ebx, 0x23\r
93 mov cr0, ebx\r
94 jmp dword 0x0:0x0\r
717fb604 95_GdtDesc:\r
63a4f460
LG
96 DW 0\r
97 DD 0\r
98\r
99BITS 32\r
100@32bit:\r
101 mov ax, PROTECT_MODE_DS\r
102o16 mov ds, ax\r
103o16 mov es, ax\r
104o16 mov fs, ax\r
105o16 mov gs, ax\r
106o16 mov ss, ax\r
fc504fde
LE
107 mov esp, strict dword 0 ; source operand will be patched\r
108ASM_PFX(gPatchSmiStack):\r
63a4f460
LG
109 mov eax, ASM_PFX(gSmiHandlerIdtr)\r
110 lidt [eax]\r
111 jmp ProtFlatMode\r
112\r
113ProtFlatMode:\r
c455687f
LE
114 mov eax, strict dword 0 ; source operand will be patched\r
115ASM_PFX(gPatchSmiCr3):\r
63a4f460
LG
116 mov cr3, eax\r
117;\r
118; Need to test for CR4 specific bit support\r
119;\r
120 mov eax, 1\r
121 cpuid ; use CPUID to determine if specific CR4 bits are supported\r
122 xor eax, eax ; Clear EAX\r
123 test edx, BIT2 ; Check for DE capabilities\r
124 jz .0\r
125 or eax, BIT3\r
126.0:\r
127 test edx, BIT6 ; Check for PAE capabilities\r
128 jz .1\r
129 or eax, BIT5\r
130.1:\r
131 test edx, BIT7 ; Check for MCE capabilities\r
132 jz .2\r
133 or eax, BIT6\r
134.2:\r
135 test edx, BIT24 ; Check for FXSR capabilities\r
136 jz .3\r
137 or eax, BIT9\r
138.3:\r
139 test edx, BIT25 ; Check for SSE capabilities\r
140 jz .4\r
141 or eax, BIT10\r
142.4: ; as cr4.PGE is not set here, refresh cr3\r
143 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.\r
717fb604
JY
144\r
145 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0\r
146 jz .6\r
147; Load TSS\r
148 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag\r
149 mov eax, TSS_SEGMENT\r
150 ltr ax\r
151.6:\r
152\r
153; enable NXE if supported\r
3c5ce64f
LE
154 mov al, strict byte 1 ; source operand may be patched\r
155ASM_PFX(gPatchXdSupported):\r
717fb604
JY
156 cmp al, 0\r
157 jz @SkipXd\r
bdafda8c
KG
158\r
159; If MSR_IA32_MISC_ENABLE is supported, clear XD Disable bit\r
160 mov al, strict byte 1 ; source operand may be patched\r
161ASM_PFX(gPatchMsrIa32MiscEnableSupported):\r
162 cmp al, 1\r
163 jz MsrIa32MiscEnableSupported\r
164\r
165; MSR_IA32_MISC_ENABLE not supported\r
166 xor edx, edx\r
167 push edx ; don't try to restore the XD Disable bit just before RSM\r
168 jmp EnableNxe\r
169\r
717fb604
JY
170;\r
171; Check XD disable bit\r
172;\r
bdafda8c 173MsrIa32MiscEnableSupported:\r
717fb604
JY
174 mov ecx, MSR_IA32_MISC_ENABLE\r
175 rdmsr\r
176 push edx ; save MSR_IA32_MISC_ENABLE[63-32]\r
177 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
bdafda8c 178 jz EnableNxe\r
717fb604
JY
179 and dx, 0xFFFB ; clear XD Disable bit if it is set\r
180 wrmsr\r
bdafda8c 181EnableNxe:\r
717fb604
JY
182 mov ecx, MSR_EFER\r
183 rdmsr\r
184 or ax, MSR_EFER_XD ; enable NXE\r
185 wrmsr\r
186 jmp @XdDone\r
187@SkipXd:\r
188 sub esp, 4\r
189@XdDone:\r
190\r
63a4f460 191 mov ebx, cr0\r
717fb604 192 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE\r
63a4f460
LG
193 mov cr0, ebx\r
194 lea ebx, [edi + DSC_OFFSET]\r
195 mov ax, [ebx + DSC_DS]\r
196 mov ds, eax\r
197 mov ax, [ebx + DSC_OTHERSEG]\r
198 mov es, eax\r
199 mov fs, eax\r
200 mov gs, eax\r
201 mov ax, [ebx + DSC_SS]\r
202 mov ss, eax\r
203\r
3eb69b08
JY
204 mov ebx, [esp + 4] ; ebx <- CpuIndex\r
205\r
206; enable CET if supported\r
207 mov al, strict byte 1 ; source operand may be patched\r
208ASM_PFX(mPatchCetSupported):\r
209 cmp al, 0\r
210 jz CetDone\r
211\r
212 mov ecx, MSR_IA32_S_CET\r
213 rdmsr\r
214 push edx\r
215 push eax\r
216\r
217 mov ecx, MSR_IA32_PL0_SSP\r
218 rdmsr\r
219 push edx\r
220 push eax\r
221\r
222 mov ecx, MSR_IA32_S_CET\r
223 mov eax, MSR_IA32_CET_SH_STK_EN\r
224 xor edx, edx\r
225 wrmsr\r
226\r
227 mov ecx, MSR_IA32_PL0_SSP\r
228 mov eax, strict dword 0 ; source operand will be patched\r
229ASM_PFX(mPatchCetPl0Ssp):\r
230 xor edx, edx\r
231 wrmsr\r
232 mov ecx, cr0\r
233 btr ecx, 16 ; clear WP\r
234 mov cr0, ecx\r
235 mov [eax], eax ; reload SSP, and clear busyflag.\r
236 xor ecx, ecx\r
237 mov [eax + 4], ecx\r
238\r
239 mov eax, strict dword 0 ; source operand will be patched\r
240ASM_PFX(mPatchCetInterruptSsp):\r
241 cmp eax, 0\r
242 jz CetInterruptDone\r
243 mov [eax], eax ; reload SSP, and clear busyflag.\r
244 xor ecx, ecx\r
245 mov [eax + 4], ecx\r
246CetInterruptDone:\r
247\r
248 mov ecx, cr0\r
249 bts ecx, 16 ; set WP\r
250 mov cr0, ecx\r
251\r
252 mov eax, 0x668 | CR4_CET\r
253 mov cr4, eax\r
254\r
255 SETSSBSY\r
256\r
257CetDone:\r
63a4f460 258\r
63a4f460
LG
259 push ebx\r
260 mov eax, ASM_PFX(CpuSmmDebugEntry)\r
261 call eax\r
717fb604 262 add esp, 4\r
63a4f460
LG
263\r
264 push ebx\r
265 mov eax, ASM_PFX(SmiRendezvous)\r
266 call eax\r
717fb604
JY
267 add esp, 4\r
268\r
63a4f460
LG
269 push ebx\r
270 mov eax, ASM_PFX(CpuSmmDebugExit)\r
271 call eax\r
717fb604
JY
272 add esp, 4\r
273\r
3eb69b08
JY
274 mov eax, ASM_PFX(mCetSupported)\r
275 mov al, [eax]\r
276 cmp al, 0\r
277 jz CetDone2\r
278\r
279 mov eax, 0x668\r
280 mov cr4, eax ; disable CET\r
281\r
282 mov ecx, MSR_IA32_PL0_SSP\r
283 pop eax\r
284 pop edx\r
285 wrmsr\r
286\r
287 mov ecx, MSR_IA32_S_CET\r
288 pop eax\r
289 pop edx\r
290 wrmsr\r
291CetDone2:\r
292\r
717fb604
JY
293 mov eax, ASM_PFX(mXdSupported)\r
294 mov al, [eax]\r
295 cmp al, 0\r
296 jz .7\r
297 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
298 test edx, BIT2\r
299 jz .7\r
300 mov ecx, MSR_IA32_MISC_ENABLE\r
301 rdmsr\r
302 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
303 wrmsr\r
304\r
305.7:\r
3eb69b08 306\r
02f7fd15 307 StuffRsb32\r
63a4f460
LG
308 rsm\r
309\r
310ASM_PFX(gcSmiHandlerSize): DW $ - _SmiEntryPoint\r
311\r
e21e355e
LG
312global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)\r
313ASM_PFX(PiSmmCpuSmiEntryFixupAddress):\r
314 ret\r