]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.nasm
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiException.nasm
CommitLineData
9f54832f 1;------------------------------------------------------------------------------ ;\r
e21e355e 2; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
0acd8697 3; SPDX-License-Identifier: BSD-2-Clause-Patent\r
9f54832f
LG
4;\r
5; Module Name:\r
6;\r
7; SmiException.nasm\r
8;\r
9; Abstract:\r
10;\r
11; Exception handlers used in SM mode\r
12;\r
13;-------------------------------------------------------------------------------\r
14\r
15extern ASM_PFX(SmiPFHandler)\r
9f54832f
LG
16\r
17global ASM_PFX(gcSmiIdtr)\r
18global ASM_PFX(gcSmiGdtr)\r
19global ASM_PFX(gcPsd)\r
20\r
21 SECTION .data\r
22\r
23NullSeg: DQ 0 ; reserved by architecture\r
24CodeSeg32:\r
25 DW -1 ; LimitLow\r
26 DW 0 ; BaseLow\r
27 DB 0 ; BaseMid\r
28 DB 0x9b\r
29 DB 0xcf ; LimitHigh\r
30 DB 0 ; BaseHigh\r
31ProtModeCodeSeg32:\r
32 DW -1 ; LimitLow\r
33 DW 0 ; BaseLow\r
34 DB 0 ; BaseMid\r
35 DB 0x9b\r
36 DB 0xcf ; LimitHigh\r
37 DB 0 ; BaseHigh\r
38ProtModeSsSeg32:\r
39 DW -1 ; LimitLow\r
40 DW 0 ; BaseLow\r
41 DB 0 ; BaseMid\r
42 DB 0x93\r
43 DB 0xcf ; LimitHigh\r
44 DB 0 ; BaseHigh\r
45DataSeg32:\r
46 DW -1 ; LimitLow\r
47 DW 0 ; BaseLow\r
48 DB 0 ; BaseMid\r
49 DB 0x93\r
50 DB 0xcf ; LimitHigh\r
51 DB 0 ; BaseHigh\r
52CodeSeg16:\r
53 DW -1\r
54 DW 0\r
55 DB 0\r
56 DB 0x9b\r
57 DB 0x8f\r
58 DB 0\r
59DataSeg16:\r
60 DW -1\r
61 DW 0\r
62 DB 0\r
63 DB 0x93\r
64 DB 0x8f\r
65 DB 0\r
66CodeSeg64:\r
67 DW -1 ; LimitLow\r
68 DW 0 ; BaseLow\r
69 DB 0 ; BaseMid\r
70 DB 0x9b\r
71 DB 0xaf ; LimitHigh\r
72 DB 0 ; BaseHigh\r
73; TSS Segment for X64 specially\r
74TssSeg:\r
75 DW TSS_DESC_SIZE ; LimitLow\r
76 DW 0 ; BaseLow\r
77 DB 0 ; BaseMid\r
78 DB 0x89\r
79 DB 0x80 ; LimitHigh\r
80 DB 0 ; BaseHigh\r
81 DD 0 ; BaseUpper\r
82 DD 0 ; Reserved\r
83GDT_SIZE equ $ - NullSeg\r
84\r
85; Create TSS Descriptor just after GDT\r
86TssDescriptor:\r
87 DD 0 ; Reserved\r
88 DQ 0 ; RSP0\r
89 DQ 0 ; RSP1\r
90 DQ 0 ; RSP2\r
91 DD 0 ; Reserved\r
92 DD 0 ; Reserved\r
93 DQ 0 ; IST1\r
94 DQ 0 ; IST2\r
95 DQ 0 ; IST3\r
96 DQ 0 ; IST4\r
97 DQ 0 ; IST5\r
98 DQ 0 ; IST6\r
99 DQ 0 ; IST7\r
100 DD 0 ; Reserved\r
101 DD 0 ; Reserved\r
102 DW 0 ; Reserved\r
103 DW 0 ; I/O Map Base Address\r
104TSS_DESC_SIZE equ $ - TssDescriptor\r
105\r
106;\r
107; This structure serves as a template for all processors.\r
108;\r
109ASM_PFX(gcPsd):\r
110 DB 'PSDSIG '\r
111 DW PSD_SIZE\r
112 DW 2\r
113 DW 1 << 2\r
114 DW CODE_SEL\r
115 DW DATA_SEL\r
116 DW DATA_SEL\r
117 DW DATA_SEL\r
118 DW 0\r
119 DQ 0\r
120 DQ 0\r
121 DQ 0 ; fixed in InitializeMpServiceData()\r
122 DQ NullSeg\r
123 DD GDT_SIZE\r
124 DD 0\r
125 times 24 DB 0\r
854c6b80 126 DQ 0\r
9f54832f
LG
127PSD_SIZE equ $ - ASM_PFX(gcPsd)\r
128\r
129;\r
130; CODE & DATA segments for SMM runtime\r
131;\r
132CODE_SEL equ CodeSeg64 - NullSeg\r
133DATA_SEL equ DataSeg32 - NullSeg\r
134CODE32_SEL equ CodeSeg32 - NullSeg\r
135\r
136ASM_PFX(gcSmiGdtr):\r
137 DW GDT_SIZE - 1\r
138 DQ NullSeg\r
139\r
140ASM_PFX(gcSmiIdtr):\r
717fb604
JY
141 DW 0\r
142 DQ 0\r
9f54832f
LG
143\r
144 DEFAULT REL\r
145 SECTION .text\r
146\r
147;------------------------------------------------------------------------------\r
148; _SmiExceptionEntryPoints is the collection of exception entrypoints followed\r
149; by a common exception handler.\r
150;\r
151; Stack frame would be as follows as specified in IA32 manuals:\r
152;\r
153; +---------------------+ <-- 16-byte aligned ensured by processor\r
154; + Old SS +\r
155; +---------------------+\r
156; + Old RSP +\r
157; +---------------------+\r
158; + RFlags +\r
159; +---------------------+\r
160; + CS +\r
161; +---------------------+\r
162; + RIP +\r
163; +---------------------+\r
164; + Error Code +\r
165; +---------------------+\r
166; + Vector Number +\r
167; +---------------------+\r
168; + RBP +\r
169; +---------------------+ <-- RBP, 16-byte aligned\r
170;\r
171; RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT\r
172;------------------------------------------------------------------------------\r
173global ASM_PFX(PageFaultIdtHandlerSmmProfile)\r
174ASM_PFX(PageFaultIdtHandlerSmmProfile):\r
175 push 0xe ; Page Fault\r
176 test spl, 8 ; odd multiple of 8 => ErrCode present\r
177 jnz .0\r
178 push qword [rsp] ; duplicate INT# if no ErrCode\r
179 mov qword [rsp + 8], 0\r
180.0:\r
181 push rbp\r
182 mov rbp, rsp\r
183\r
184 ;\r
185 ; Since here the stack pointer is 16-byte aligned, so\r
186 ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
187 ; is 16-byte aligned\r
188 ;\r
189\r
190;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
191;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
192 push r15\r
193 push r14\r
194 push r13\r
195 push r12\r
196 push r11\r
197 push r10\r
198 push r9\r
199 push r8\r
200 push rax\r
201 push rcx\r
202 push rdx\r
203 push rbx\r
204 push qword [rbp + 48] ; RSP\r
205 push qword [rbp] ; RBP\r
206 push rsi\r
207 push rdi\r
208\r
209;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
210 movzx rax, word [rbp + 56]\r
211 push rax ; for ss\r
212 movzx rax, word [rbp + 32]\r
213 push rax ; for cs\r
214 mov rax, ds\r
215 push rax\r
216 mov rax, es\r
217 push rax\r
218 mov rax, fs\r
219 push rax\r
220 mov rax, gs\r
221 push rax\r
222\r
223;; UINT64 Rip;\r
224 push qword [rbp + 24]\r
225\r
226;; UINT64 Gdtr[2], Idtr[2];\r
227 sub rsp, 16\r
228 sidt [rsp]\r
229 sub rsp, 16\r
230 sgdt [rsp]\r
231\r
232;; UINT64 Ldtr, Tr;\r
233 xor rax, rax\r
234 str ax\r
235 push rax\r
236 sldt ax\r
237 push rax\r
238\r
239;; UINT64 RFlags;\r
240 push qword [rbp + 40]\r
241\r
242;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
243 mov rax, cr8\r
244 push rax\r
245 mov rax, cr4\r
246 or rax, 0x208\r
247 mov cr4, rax\r
248 push rax\r
249 mov rax, cr3\r
250 push rax\r
251 mov rax, cr2\r
252 push rax\r
253 xor rax, rax\r
254 push rax\r
255 mov rax, cr0\r
256 push rax\r
257\r
258;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
259 mov rax, dr7\r
260 push rax\r
261 mov rax, dr6\r
262 push rax\r
263 mov rax, dr3\r
264 push rax\r
265 mov rax, dr2\r
266 push rax\r
267 mov rax, dr1\r
268 push rax\r
269 mov rax, dr0\r
270 push rax\r
271\r
272;; FX_SAVE_STATE_X64 FxSaveState;\r
273\r
274 sub rsp, 512\r
275 mov rdi, rsp\r
d22c995a 276 fxsave [rdi]\r
9f54832f
LG
277\r
278; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
279 cld\r
280\r
281;; UINT32 ExceptionData;\r
282 push qword [rbp + 16]\r
283\r
284;; call into exception handler\r
285 mov rcx, [rbp + 8]\r
e21e355e 286 lea rax, [ASM_PFX(SmiPFHandler)]\r
9f54832f
LG
287\r
288;; Prepare parameter and call\r
289 mov rdx, rsp\r
290 ;\r
291 ; Per X64 calling convention, allocate maximum parameter stack space\r
292 ; and make sure RSP is 16-byte aligned\r
293 ;\r
294 sub rsp, 4 * 8 + 8\r
295 call rax\r
296 add rsp, 4 * 8 + 8\r
297 jmp .1\r
298\r
299.1:\r
300;; UINT64 ExceptionData;\r
301 add rsp, 8\r
302\r
303;; FX_SAVE_STATE_X64 FxSaveState;\r
304\r
305 mov rsi, rsp\r
d22c995a 306 fxrstor [rsi]\r
9f54832f
LG
307 add rsp, 512\r
308\r
309;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
310;; Skip restoration of DRx registers to support debuggers\r
311;; that set breakpoints in interrupt/exception context\r
312 add rsp, 8 * 6\r
313\r
314;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
315 pop rax\r
316 mov cr0, rax\r
317 add rsp, 8 ; not for Cr1\r
318 pop rax\r
319 mov cr2, rax\r
320 pop rax\r
321 mov cr3, rax\r
322 pop rax\r
323 mov cr4, rax\r
324 pop rax\r
325 mov cr8, rax\r
326\r
327;; UINT64 RFlags;\r
328 pop qword [rbp + 40]\r
329\r
330;; UINT64 Ldtr, Tr;\r
331;; UINT64 Gdtr[2], Idtr[2];\r
332;; Best not let anyone mess with these particular registers...\r
333 add rsp, 48\r
334\r
335;; UINT64 Rip;\r
336 pop qword [rbp + 24]\r
337\r
338;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
339 pop rax\r
340 ; mov gs, rax ; not for gs\r
341 pop rax\r
342 ; mov fs, rax ; not for fs\r
343 ; (X64 will not use fs and gs, so we do not restore it)\r
344 pop rax\r
345 mov es, rax\r
346 pop rax\r
347 mov ds, rax\r
348 pop qword [rbp + 32] ; for cs\r
349 pop qword [rbp + 56] ; for ss\r
350\r
351;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
352;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
353 pop rdi\r
354 pop rsi\r
355 add rsp, 8 ; not for rbp\r
356 pop qword [rbp + 48] ; for rsp\r
357 pop rbx\r
358 pop rdx\r
359 pop rcx\r
360 pop rax\r
361 pop r8\r
362 pop r9\r
363 pop r10\r
364 pop r11\r
365 pop r12\r
366 pop r13\r
367 pop r14\r
368 pop r15\r
369\r
370 mov rsp, rbp\r
371\r
372; Enable TF bit after page fault handler runs\r
373 bts dword [rsp + 40], 8 ;RFLAGS\r
374\r
375 pop rbp\r
376 add rsp, 16 ; skip INT# & ErrCode\r
377 iretq\r
378\r