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