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