VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm@ 80721

Last change on this file since 80721 was 80721, checked in by vboxsync, 5 years ago

Devices/EFI/FirmwareNew: Start upgrade process to edk2-stable201908 (compiles on Windows and works to some extent), bugref:4643

  • Property svn:eol-style set to native
File size: 9.7 KB
Line 
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;
19; Variables referrenced by C code
20;
21
22%define MSR_IA32_S_CET 0x6A2
23%define MSR_IA32_CET_SH_STK_EN 0x1
24%define MSR_IA32_CET_WR_SHSTK_EN 0x2
25%define MSR_IA32_CET_ENDBR_EN 0x4
26%define MSR_IA32_CET_LEG_IW_EN 0x8
27%define MSR_IA32_CET_NO_TRACK_EN 0x10
28%define MSR_IA32_CET_SUPPRESS_DIS 0x20
29%define MSR_IA32_CET_SUPPRESS 0x400
30%define MSR_IA32_CET_TRACKER 0x800
31%define MSR_IA32_PL0_SSP 0x6A4
32%define MSR_IA32_INTERRUPT_SSP_TABLE_ADDR 0x6A8
33
34%define CR4_CET 0x800000
35
36%define MSR_IA32_MISC_ENABLE 0x1A0
37%define MSR_EFER 0xc0000080
38%define MSR_EFER_XD 0x800
39
40;
41; Constants relating to PROCESSOR_SMM_DESCRIPTOR
42;
43%define DSC_OFFSET 0xfb00
44%define DSC_GDTPTR 0x30
45%define DSC_GDTSIZ 0x38
46%define DSC_CS 14
47%define DSC_DS 16
48%define DSC_SS 18
49%define DSC_OTHERSEG 20
50;
51; Constants relating to CPU State Save Area
52;
53%define SSM_DR6 0xffd0
54%define SSM_DR7 0xffc8
55
56%define PROTECT_MODE_CS 0x8
57%define PROTECT_MODE_DS 0x20
58%define LONG_MODE_CS 0x38
59%define TSS_SEGMENT 0x40
60%define GDT_SIZE 0x50
61
62extern ASM_PFX(SmiRendezvous)
63extern ASM_PFX(gSmiHandlerIdtr)
64extern ASM_PFX(CpuSmmDebugEntry)
65extern ASM_PFX(CpuSmmDebugExit)
66
67global ASM_PFX(gPatchSmbase)
68extern ASM_PFX(mXdSupported)
69global ASM_PFX(gPatchXdSupported)
70global ASM_PFX(gPatchSmiStack)
71global ASM_PFX(gPatchSmiCr3)
72global ASM_PFX(gPatch5LevelPagingSupport)
73global ASM_PFX(gcSmiHandlerTemplate)
74global ASM_PFX(gcSmiHandlerSize)
75
76extern ASM_PFX(mCetSupported)
77global ASM_PFX(mPatchCetSupported)
78global ASM_PFX(mPatchCetPl0Ssp)
79global ASM_PFX(mPatchCetInterruptSsp)
80global ASM_PFX(mPatchCetInterruptSspTable)
81
82 DEFAULT REL
83 SECTION .text
84
85BITS 16
86ASM_PFX(gcSmiHandlerTemplate):
87_SmiEntryPoint:
88 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000
89 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
90 dec ax
91 mov [cs:bx], ax
92 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
93 mov [cs:bx + 2], eax
94o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
95 mov ax, PROTECT_MODE_CS
96 mov [cs:bx-0x2],ax
97 mov edi, strict dword 0 ; source operand will be patched
98ASM_PFX(gPatchSmbase):
99 lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000]
100 mov [cs:bx-0x6],eax
101 mov ebx, cr0
102 and ebx, 0x9ffafff3
103 or ebx, 0x23
104 mov cr0, ebx
105 jmp dword 0x0:0x0
106_GdtDesc:
107 DW 0
108 DD 0
109
110BITS 32
111@ProtectedMode:
112 mov ax, PROTECT_MODE_DS
113o16 mov ds, ax
114o16 mov es, ax
115o16 mov fs, ax
116o16 mov gs, ax
117o16 mov ss, ax
118 mov esp, strict dword 0 ; source operand will be patched
119ASM_PFX(gPatchSmiStack):
120 jmp ProtFlatMode
121
122BITS 64
123ProtFlatMode:
124 mov eax, strict dword 0 ; source operand will be patched
125ASM_PFX(gPatchSmiCr3):
126 mov cr3, rax
127 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3
128
129 mov cl, strict byte 0 ; source operand will be patched
130ASM_PFX(gPatch5LevelPagingSupport):
131 cmp cl, 0
132 je SkipEnable5LevelPaging
133 ;
134 ; Enable 5-Level Paging bit
135 ;
136 bts eax, 12 ; Set LA57 bit (bit #12)
137SkipEnable5LevelPaging:
138
139 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
140; Load TSS
141 sub esp, 8 ; reserve room in stack
142 sgdt [rsp]
143 mov eax, [rsp + 2] ; eax = GDT base
144 add esp, 8
145 mov dl, 0x89
146 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag
147 mov eax, TSS_SEGMENT
148 ltr ax
149
150; enable NXE if supported
151 mov al, strict byte 1 ; source operand may be patched
152ASM_PFX(gPatchXdSupported):
153 cmp al, 0
154 jz @SkipXd
155;
156; Check XD disable bit
157;
158 mov ecx, MSR_IA32_MISC_ENABLE
159 rdmsr
160 sub esp, 4
161 push rdx ; save MSR_IA32_MISC_ENABLE[63-32]
162 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
163 jz .0
164 and dx, 0xFFFB ; clear XD Disable bit if it is set
165 wrmsr
166.0:
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, 8
174@XdDone:
175
176; Switch into @LongMode
177 push LONG_MODE_CS ; push cs hardcore here
178 call Base ; push return address for retf later
179Base:
180 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
181
182 mov ecx, MSR_EFER
183 rdmsr
184 or ah, 1 ; enable LME
185 wrmsr
186 mov rbx, cr0
187 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
188 mov cr0, rbx
189 retf
190@LongMode: ; long mode (64-bit code) starts here
191 mov rax, strict qword 0 ; mov rax, ASM_PFX(gSmiHandlerIdtr)
192SmiHandlerIdtrAbsAddr:
193 lidt [rax]
194 lea ebx, [rdi + DSC_OFFSET]
195 mov ax, [rbx + DSC_DS]
196 mov ds, eax
197 mov ax, [rbx + DSC_OTHERSEG]
198 mov es, eax
199 mov fs, eax
200 mov gs, eax
201 mov ax, [rbx + DSC_SS]
202 mov ss, eax
203
204 mov rbx, [rsp + 0x8] ; rbx <- CpuIndex
205
206; enable CET if supported
207 mov al, strict byte 1 ; source operand may be patched
208ASM_PFX(mPatchCetSupported):
209 cmp al, 0
210 jz CetDone
211
212 mov ecx, MSR_IA32_S_CET
213 rdmsr
214 push rdx
215 push rax
216
217 mov ecx, MSR_IA32_PL0_SSP
218 rdmsr
219 push rdx
220 push rax
221
222 mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR
223 rdmsr
224 push rdx
225 push rax
226
227 mov ecx, MSR_IA32_S_CET
228 mov eax, MSR_IA32_CET_SH_STK_EN
229 xor edx, edx
230 wrmsr
231
232 mov ecx, MSR_IA32_PL0_SSP
233 mov eax, strict dword 0 ; source operand will be patched
234ASM_PFX(mPatchCetPl0Ssp):
235 xor edx, edx
236 wrmsr
237 mov rcx, cr0
238 btr ecx, 16 ; clear WP
239 mov cr0, rcx
240 mov [eax], eax ; reload SSP, and clear busyflag.
241 xor ecx, ecx
242 mov [eax + 4], ecx
243
244 mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR
245 mov eax, strict dword 0 ; source operand will be patched
246ASM_PFX(mPatchCetInterruptSspTable):
247 xor edx, edx
248 wrmsr
249
250 mov eax, strict dword 0 ; source operand will be patched
251ASM_PFX(mPatchCetInterruptSsp):
252 cmp eax, 0
253 jz CetInterruptDone
254 mov [eax], eax ; reload SSP, and clear busyflag.
255 xor ecx, ecx
256 mov [eax + 4], ecx
257CetInterruptDone:
258
259 mov rcx, cr0
260 bts ecx, 16 ; set WP
261 mov cr0, rcx
262
263 mov eax, 0x668 | CR4_CET
264 mov cr4, rax
265
266 SETSSBSY
267
268CetDone:
269
270 ;
271 ; Save FP registers
272 ;
273 sub rsp, 0x200
274 fxsave64 [rsp]
275
276 add rsp, -0x20
277
278 mov rcx, rbx
279 mov rax, strict qword 0 ; call ASM_PFX(CpuSmmDebugEntry)
280CpuSmmDebugEntryAbsAddr:
281 call rax
282
283 mov rcx, rbx
284 mov rax, strict qword 0 ; call ASM_PFX(SmiRendezvous)
285SmiRendezvousAbsAddr:
286 call rax
287
288 mov rcx, rbx
289 mov rax, strict qword 0 ; call ASM_PFX(CpuSmmDebugExit)
290CpuSmmDebugExitAbsAddr:
291 call rax
292
293 add rsp, 0x20
294
295 ;
296 ; Restore FP registers
297 ;
298 fxrstor64 [rsp]
299
300 add rsp, 0x200
301
302 mov rax, strict qword 0 ; mov rax, ASM_PFX(mCetSupported)
303mCetSupportedAbsAddr:
304 mov al, [rax]
305 cmp al, 0
306 jz CetDone2
307
308 mov eax, 0x668
309 mov cr4, rax ; disable CET
310
311 mov ecx, MSR_IA32_INTERRUPT_SSP_TABLE_ADDR
312 pop rax
313 pop rdx
314 wrmsr
315
316 mov ecx, MSR_IA32_PL0_SSP
317 pop rax
318 pop rdx
319 wrmsr
320
321 mov ecx, MSR_IA32_S_CET
322 pop rax
323 pop rdx
324 wrmsr
325CetDone2:
326
327 mov rax, strict qword 0 ; lea rax, [ASM_PFX(mXdSupported)]
328mXdSupportedAbsAddr:
329 mov al, [rax]
330 cmp al, 0
331 jz .1
332 pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]
333 test edx, BIT2
334 jz .1
335 mov ecx, MSR_IA32_MISC_ENABLE
336 rdmsr
337 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
338 wrmsr
339
340.1:
341
342 StuffRsb64
343 rsm
344
345ASM_PFX(gcSmiHandlerSize) DW $ - _SmiEntryPoint
346
347;
348; Retrieve the address and fill it into mov opcode.
349;
350; It is called in the driver entry point first.
351; It is used to fix up the real address in mov opcode.
352; Then, after the code logic is copied to the different location,
353; the code can also run.
354;
355global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)
356ASM_PFX(PiSmmCpuSmiEntryFixupAddress):
357 lea rax, [ASM_PFX(gSmiHandlerIdtr)]
358 lea rcx, [SmiHandlerIdtrAbsAddr]
359 mov qword [rcx - 8], rax
360
361 lea rax, [ASM_PFX(CpuSmmDebugEntry)]
362 lea rcx, [CpuSmmDebugEntryAbsAddr]
363 mov qword [rcx - 8], rax
364
365 lea rax, [ASM_PFX(SmiRendezvous)]
366 lea rcx, [SmiRendezvousAbsAddr]
367 mov qword [rcx - 8], rax
368
369 lea rax, [ASM_PFX(CpuSmmDebugExit)]
370 lea rcx, [CpuSmmDebugExitAbsAddr]
371 mov qword [rcx - 8], rax
372
373 lea rax, [ASM_PFX(mXdSupported)]
374 lea rcx, [mXdSupportedAbsAddr]
375 mov qword [rcx - 8], rax
376
377 lea rax, [ASM_PFX(mCetSupported)]
378 lea rcx, [mCetSupportedAbsAddr]
379 mov qword [rcx - 8], rax
380 ret
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette