]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.S
Correct TSS segment.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiException.S
CommitLineData
427e3573
MK
1#------------------------------------------------------------------------------\r
2#\r
3# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
4# This program and the accompanying materials\r
5# are licensed and made available under the terms and conditions of the BSD License\r
6# which accompanies this distribution. The full text of the license may be found at\r
7# http://opensource.org/licenses/bsd-license.php.\r
8#\r
9# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11#\r
12# Module Name:\r
13#\r
14# SmiException.S\r
15#\r
16# Abstract:\r
17#\r
18# Exception handlers used in SM mode\r
19#\r
20#------------------------------------------------------------------------------\r
21\r
22ASM_GLOBAL ASM_PFX(SmiPFHandler)\r
23ASM_GLOBAL ASM_PFX(gSmiMtrrs)\r
24ASM_GLOBAL ASM_PFX(gcSmiIdtr)\r
25ASM_GLOBAL ASM_PFX(gcSmiGdtr)\r
26ASM_GLOBAL ASM_PFX(gcPsd)\r
27\r
28 .data\r
29\r
30NullSeg: .quad 0 # reserved by architecture\r
31CodeSeg32:\r
32 .word -1 # LimitLow\r
33 .word 0 # BaseLow\r
34 .byte 0 # BaseMid\r
35 .byte 0x9b\r
36 .byte 0xcf # LimitHigh\r
37 .byte 0 # BaseHigh\r
38ProtModeCodeSeg32:\r
39 .word -1 # LimitLow\r
40 .word 0 # BaseLow\r
41 .byte 0 # BaseMid\r
42 .byte 0x9b\r
43 .byte 0xcf # LimitHigh\r
44 .byte 0 # BaseHigh\r
45ProtModeSsSeg32:\r
46 .word -1 # LimitLow\r
47 .word 0 # BaseLow\r
48 .byte 0 # BaseMid\r
49 .byte 0x93\r
50 .byte 0xcf # LimitHigh\r
51 .byte 0 # BaseHigh\r
52DataSeg32:\r
53 .word -1 # LimitLow\r
54 .word 0 # BaseLow\r
55 .byte 0 # BaseMid\r
56 .byte 0x93\r
57 .byte 0xcf # LimitHigh\r
58 .byte 0 # BaseHigh\r
59CodeSeg16:\r
60 .word -1\r
61 .word 0\r
62 .byte 0\r
63 .byte 0x9b\r
64 .byte 0x8f\r
65 .byte 0\r
66DataSeg16:\r
67 .word -1\r
68 .word 0\r
69 .byte 0\r
70 .byte 0x93\r
71 .byte 0x8f\r
72 .byte 0\r
73CodeSeg64:\r
74 .word -1 # LimitLow\r
75 .word 0 # BaseLow\r
76 .byte 0 # BaseMid\r
77 .byte 0x9b\r
78 .byte 0xaf # LimitHigh\r
79 .byte 0 # BaseHigh\r
80# TSS Segment for X64 specially\r
81TssSeg:\r
20ab3269 82 .word TSS_DESC_SIZE - 1 # LimitLow\r
427e3573
MK
83 .word 0 # BaseLow\r
84 .byte 0 # BaseMid\r
85 .byte 0x89\r
20ab3269 86 .byte 0x00 # LimitHigh\r
427e3573
MK
87 .byte 0 # BaseHigh\r
88 .long 0 # BaseUpper\r
89 .long 0 # Reserved\r
90.equ GDT_SIZE, .- NullSeg\r
91\r
92TssDescriptor:\r
93 .space 104, 0\r
94.equ TSS_DESC_SIZE, .- TssDescriptor\r
95\r
96#\r
97# This structure serves as a template for all processors.\r
98#\r
99ASM_PFX(gcPsd):\r
100 .ascii "PSDSIG "\r
101 .word PSD_SIZE\r
102 .word 2\r
103 .word 1 << 2\r
104 .word CODE_SEL\r
105 .word DATA_SEL\r
106 .word DATA_SEL\r
107 .word DATA_SEL\r
108 .word 0\r
109 .quad 0\r
110 .quad 0\r
111 .quad 0 # fixed in InitializeMpServiceData()\r
112 .quad NullSeg\r
113 .long GDT_SIZE\r
114 .long 0\r
115 .space 24, 0\r
116 .quad ASM_PFX(gSmiMtrrs)\r
117.equ PSD_SIZE, . - ASM_PFX(gcPsd)\r
118\r
119#\r
120# CODE & DATA segments for SMM runtime\r
121#\r
122.equ CODE_SEL, CodeSeg64 - NullSeg\r
123.equ DATA_SEL, DataSeg32 - NullSeg\r
124.equ CODE32_SEL, CodeSeg32 - NullSeg\r
125\r
126ASM_PFX(gcSmiGdtr):\r
127 .word GDT_SIZE - 1\r
128 .quad NullSeg\r
129\r
130ASM_PFX(gcSmiIdtr):\r
131 .word IDT_SIZE - 1\r
132 .quad _SmiIDT\r
133\r
134\r
135#\r
136# Here is the IDT. There are 32 (not 255) entries in it since only processor\r
137# generated exceptions will be handled.\r
138#\r
139_SmiIDT:\r
140# The following segment repeats 32 times:\r
141# No. 1\r
142 .word 0 # Offset 0:15\r
143 .word CODE_SEL\r
144 .byte 0 # Unused\r
145 .byte 0x8e # Interrupt Gate, Present\r
146 .word 0 # Offset 16:31\r
147 .quad 0 # Offset 32:63\r
148# No. 2\r
149 .word 0 # Offset 0:15\r
150 .word CODE_SEL\r
151 .byte 0 # Unused\r
152 .byte 0x8e # Interrupt Gate, Present\r
153 .word 0 # Offset 16:31\r
154 .quad 0 # Offset 32:63\r
155# No. 3\r
156 .word 0 # Offset 0:15\r
157 .word CODE_SEL\r
158 .byte 0 # Unused\r
159 .byte 0x8e # Interrupt Gate, Present\r
160 .word 0 # Offset 16:31\r
161 .quad 0 # Offset 32:63\r
162# No. 4\r
163 .word 0 # Offset 0:15\r
164 .word CODE_SEL\r
165 .byte 0 # Unused\r
166 .byte 0x8e # Interrupt Gate, Present\r
167 .word 0 # Offset 16:31\r
168 .quad 0 # Offset 32:63\r
169# No. 5\r
170 .word 0 # Offset 0:15\r
171 .word CODE_SEL\r
172 .byte 0 # Unused\r
173 .byte 0x8e # Interrupt Gate, Present\r
174 .word 0 # Offset 16:31\r
175 .quad 0 # Offset 32:63\r
176# No. 6\r
177 .word 0 # Offset 0:15\r
178 .word CODE_SEL\r
179 .byte 0 # Unused\r
180 .byte 0x8e # Interrupt Gate, Present\r
181 .word 0 # Offset 16:31\r
182 .quad 0 # Offset 32:63\r
183# No. 7\r
184 .word 0 # Offset 0:15\r
185 .word CODE_SEL\r
186 .byte 0 # Unused\r
187 .byte 0x8e # Interrupt Gate, Present\r
188 .word 0 # Offset 16:31\r
189 .quad 0 # Offset 32:63\r
190# No. 8\r
191 .word 0 # Offset 0:15\r
192 .word CODE_SEL\r
193 .byte 0 # Unused\r
194 .byte 0x8e # Interrupt Gate, Present\r
195 .word 0 # Offset 16:31\r
196 .quad 0 # Offset 32:63\r
197# No. 9\r
198 .word 0 # Offset 0:15\r
199 .word CODE_SEL\r
200 .byte 0 # Unused\r
201 .byte 0x8e # Interrupt Gate, Present\r
202 .word 0 # Offset 16:31\r
203 .quad 0 # Offset 32:63\r
204# No. 10\r
205 .word 0 # Offset 0:15\r
206 .word CODE_SEL\r
207 .byte 0 # Unused\r
208 .byte 0x8e # Interrupt Gate, Present\r
209 .word 0 # Offset 16:31\r
210 .quad 0 # Offset 32:63\r
211# No. 11\r
212 .word 0 # Offset 0:15\r
213 .word CODE_SEL\r
214 .byte 0 # Unused\r
215 .byte 0x8e # Interrupt Gate, Present\r
216 .word 0 # Offset 16:31\r
217 .quad 0 # Offset 32:63\r
218# No. 12\r
219 .word 0 # Offset 0:15\r
220 .word CODE_SEL\r
221 .byte 0 # Unused\r
222 .byte 0x8e # Interrupt Gate, Present\r
223 .word 0 # Offset 16:31\r
224 .quad 0 # Offset 32:63\r
225# No. 13\r
226 .word 0 # Offset 0:15\r
227 .word CODE_SEL\r
228 .byte 0 # Unused\r
229 .byte 0x8e # Interrupt Gate, Present\r
230 .word 0 # Offset 16:31\r
231 .quad 0 # Offset 32:63\r
232# No. 14\r
233 .word 0 # Offset 0:15\r
234 .word CODE_SEL\r
235 .byte 0 # Unused\r
236 .byte 0x8e # Interrupt Gate, Present\r
237 .word 0 # Offset 16:31\r
238 .quad 0 # Offset 32:63\r
239# No. 15\r
240 .word 0 # Offset 0:15\r
241 .word CODE_SEL\r
242 .byte 0 # Unused\r
243 .byte 0x8e # Interrupt Gate, Present\r
244 .word 0 # Offset 16:31\r
245 .quad 0 # Offset 32:63\r
246# No. 16\r
247 .word 0 # Offset 0:15\r
248 .word CODE_SEL\r
249 .byte 0 # Unused\r
250 .byte 0x8e # Interrupt Gate, Present\r
251 .word 0 # Offset 16:31\r
252 .quad 0 # Offset 32:63\r
253# No. 17\r
254 .word 0 # Offset 0:15\r
255 .word CODE_SEL\r
256 .byte 0 # Unused\r
257 .byte 0x8e # Interrupt Gate, Present\r
258 .word 0 # Offset 16:31\r
259 .quad 0 # Offset 32:63\r
260# No. 18\r
261 .word 0 # Offset 0:15\r
262 .word CODE_SEL\r
263 .byte 0 # Unused\r
264 .byte 0x8e # Interrupt Gate, Present\r
265 .word 0 # Offset 16:31\r
266 .quad 0 # Offset 32:63\r
267# No. 19\r
268 .word 0 # Offset 0:15\r
269 .word CODE_SEL\r
270 .byte 0 # Unused\r
271 .byte 0x8e # Interrupt Gate, Present\r
272 .word 0 # Offset 16:31\r
273 .quad 0 # Offset 32:63\r
274# No. 20\r
275 .word 0 # Offset 0:15\r
276 .word CODE_SEL\r
277 .byte 0 # Unused\r
278 .byte 0x8e # Interrupt Gate, Present\r
279 .word 0 # Offset 16:31\r
280 .quad 0 # Offset 32:63\r
281# No. 21\r
282 .word 0 # Offset 0:15\r
283 .word CODE_SEL\r
284 .byte 0 # Unused\r
285 .byte 0x8e # Interrupt Gate, Present\r
286 .word 0 # Offset 16:31\r
287 .quad 0 # Offset 32:63\r
288# No. 22\r
289 .word 0 # Offset 0:15\r
290 .word CODE_SEL\r
291 .byte 0 # Unused\r
292 .byte 0x8e # Interrupt Gate, Present\r
293 .word 0 # Offset 16:31\r
294 .quad 0 # Offset 32:63\r
295# No. 23\r
296 .word 0 # Offset 0:15\r
297 .word CODE_SEL\r
298 .byte 0 # Unused\r
299 .byte 0x8e # Interrupt Gate, Present\r
300 .word 0 # Offset 16:31\r
301 .quad 0 # Offset 32:63\r
302# No. 24\r
303 .word 0 # Offset 0:15\r
304 .word CODE_SEL\r
305 .byte 0 # Unused\r
306 .byte 0x8e # Interrupt Gate, Present\r
307 .word 0 # Offset 16:31\r
308 .quad 0 # Offset 32:63\r
309# No. 25\r
310 .word 0 # Offset 0:15\r
311 .word CODE_SEL\r
312 .byte 0 # Unused\r
313 .byte 0x8e # Interrupt Gate, Present\r
314 .word 0 # Offset 16:31\r
315 .quad 0 # Offset 32:63\r
316# No. 26\r
317 .word 0 # Offset 0:15\r
318 .word CODE_SEL\r
319 .byte 0 # Unused\r
320 .byte 0x8e # Interrupt Gate, Present\r
321 .word 0 # Offset 16:31\r
322 .quad 0 # Offset 32:63\r
323# No. 27\r
324 .word 0 # Offset 0:15\r
325 .word CODE_SEL\r
326 .byte 0 # Unused\r
327 .byte 0x8e # Interrupt Gate, Present\r
328 .word 0 # Offset 16:31\r
329 .quad 0 # Offset 32:63\r
330# No. 28\r
331 .word 0 # Offset 0:15\r
332 .word CODE_SEL\r
333 .byte 0 # Unused\r
334 .byte 0x8e # Interrupt Gate, Present\r
335 .word 0 # Offset 16:31\r
336 .quad 0 # Offset 32:63\r
337# No. 29\r
338 .word 0 # Offset 0:15\r
339 .word CODE_SEL\r
340 .byte 0 # Unused\r
341 .byte 0x8e # Interrupt Gate, Present\r
342 .word 0 # Offset 16:31\r
343 .quad 0 # Offset 32:63\r
344# No. 30\r
345 .word 0 # Offset 0:15\r
346 .word CODE_SEL\r
347 .byte 0 # Unused\r
348 .byte 0x8e # Interrupt Gate, Present\r
349 .word 0 # Offset 16:31\r
350 .quad 0 # Offset 32:63\r
351# No. 31\r
352 .word 0 # Offset 0:15\r
353 .word CODE_SEL\r
354 .byte 0 # Unused\r
355 .byte 0x8e # Interrupt Gate, Present\r
356 .word 0 # Offset 16:31\r
357 .quad 0 # Offset 32:63\r
358# No. 32\r
359 .word 0 # Offset 0:15\r
360 .word CODE_SEL\r
361 .byte 0 # Unused\r
362 .byte 0x8e # Interrupt Gate, Present\r
363 .word 0 # Offset 16:31\r
364 .quad 0 # Offset 32:63\r
365\r
366_SmiIDTEnd:\r
367\r
368.equ IDT_SIZE, (_SmiIDTEnd - _SmiIDT)\r
369\r
370 .text\r
371\r
372#------------------------------------------------------------------------------\r
373# _SmiExceptionEntryPoints is the collection of exception entry points followed\r
374# by a common exception handler.\r
375#\r
376# Stack frame would be as follows as specified in IA32 manuals:\r
377# +---------------------+ <-- 16-byte aligned ensured by processor\r
378# + Old SS +\r
379# +---------------------+\r
380# + Old RSP +\r
381# +---------------------+\r
382# + RFlags +\r
383# +---------------------+\r
384# + CS +\r
385# +---------------------+\r
386# + RIP +\r
387# +---------------------+\r
388# + Error Code +\r
389# +---------------------+\r
390# + Vector Number +\r
391# +---------------------+\r
392# + RBP +\r
393# +---------------------+ <-- RBP, 16-byte aligned\r
394#\r
395# RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT\r
396#------------------------------------------------------------------------------\r
397ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)\r
398ASM_PFX(PageFaultIdtHandlerSmmProfile):\r
399 pushq $0x0e # Page Fault\r
400 .byte 0x40, 0xf6, 0xc4, 0x08 #test spl, 8\r
401 jnz L1\r
402 pushq (%rsp)\r
403 movq $0, 8(%rsp)\r
404L1:\r
405 pushq %rbp\r
406 movq %rsp, %rbp\r
407\r
408 #\r
409 # Since here the stack pointer is 16-byte aligned, so\r
410 # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
411 # is 16-byte aligned\r
412 #\r
413\r
414## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
415## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
416 pushq %r15\r
417 pushq %r14\r
418 pushq %r13\r
419 pushq %r12\r
420 pushq %r11\r
421 pushq %r10\r
422 pushq %r9\r
423 pushq %r8\r
424 pushq %rax\r
425 pushq %rcx\r
426 pushq %rdx\r
427 pushq %rbx\r
428 pushq 48(%rbp) # RSP\r
429 pushq (%rbp) # RBP\r
430 pushq %rsi\r
431 pushq %rdi\r
432\r
433## UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
434 movzwq 56(%rbp), %rax\r
435 pushq %rax # for ss\r
436 movzwq 32(%rbp), %rax\r
437 pushq %rax # for cs\r
438 movq %ds, %rax\r
439 pushq %rax\r
440 movq %es, %rax\r
441 pushq %rax\r
442 movq %fs, %rax\r
443 pushq %rax\r
444 movq %gs, %rax\r
445 pushq %rax\r
446\r
447## UINT64 Rip;\r
448 pushq 24(%rbp)\r
449\r
450## UINT64 Gdtr[2], Idtr[2];\r
451 subq $16, %rsp\r
452 sidt (%rsp)\r
453 subq $16, %rsp\r
454 sgdt (%rsp)\r
455\r
456## UINT64 Ldtr, Tr;\r
457 xorq %rax, %rax\r
458 strw %ax\r
459 pushq %rax\r
460 sldtw %ax\r
461 pushq %rax\r
462\r
463## UINT64 RFlags;\r
464 pushq 40(%rbp)\r
465\r
466## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
467 movq %cr8, %rax\r
468 pushq %rax\r
469 movq %cr4, %rax\r
470 orq $0x208, %rax\r
471 movq %rax, %cr4\r
472 pushq %rax\r
473 movq %cr3, %rax\r
474 pushq %rax\r
475 movq %cr2, %rax\r
476 pushq %rax\r
477 xorq %rax, %rax\r
478 pushq %rax\r
479 movq %cr0, %rax\r
480 pushq %rax\r
481\r
482## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
483 movq %dr7, %rax\r
484 pushq %rax\r
485 movq %dr6, %rax\r
486 pushq %rax\r
487 movq %dr3, %rax\r
488 pushq %rax\r
489 movq %dr2, %rax\r
490 pushq %rax\r
491 movq %dr1, %rax\r
492 pushq %rax\r
493 movq %dr0, %rax\r
494 pushq %rax\r
495\r
496## FX_SAVE_STATE_X64 FxSaveState;\r
497\r
498 subq $512, %rsp\r
499 movq %rsp, %rdi\r
500 .byte 0xf, 0xae, 0x7 # fxsave [rdi]\r
501\r
502# UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
503 cld\r
504\r
505## UINT32 ExceptionData;\r
506 pushq 16(%rbp)\r
507\r
508## call into exception handler\r
509 movq 8(%rbp), %rcx\r
510 movabsq $ASM_PFX(SmiPFHandler), %rax\r
511\r
512## Prepare parameter and call\r
513 movq %rsp, %rdx\r
514 #\r
515 # Per X64 calling convention, allocate maximum parameter stack space\r
516 # and make sure RSP is 16-byte aligned\r
517 #\r
518 subq $4 * 8 + 8, %rsp\r
519 call *%rax\r
520 addq $4 * 8 + 8, %rsp\r
521 jmp L5\r
522\r
523L5:\r
524## UINT64 ExceptionData;\r
525 addq $8, %rsp\r
526\r
527## FX_SAVE_STATE_X64 FxSaveState;\r
528\r
529 movq %rsp, %rsi\r
530 .byte 0xf, 0xae, 0xe # fxrstor [rsi]\r
531 addq $512, %rsp\r
532\r
533## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
534## Skip restoration of DRx registers to support debuggers\r
535## that set breakpoints in interrupt/exception context\r
536 addq $8 * 6, %rsp\r
537\r
538## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
539 popq %rax\r
540 movq %rax, %cr0\r
541 addq $8, %rsp # not for Cr1\r
542 popq %rax\r
543 movq %rax, %cr2\r
544 popq %rax\r
545 movq %rax, %cr3\r
546 popq %rax\r
547 movq %rax, %cr4\r
548 popq %rax\r
549 movq %rax, %cr8\r
550\r
551## UINT64 RFlags;\r
552 popq 40(%rbp)\r
553\r
554## UINT64 Ldtr, Tr;\r
555## UINT64 Gdtr[2], Idtr[2];\r
556## Best not let anyone mess with these particular registers...\r
557 addq $48, %rsp\r
558\r
559## UINT64 Rip;\r
560 popq 24(%rbp)\r
561\r
562## UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
563 popq %rax\r
564 # mov gs, rax ; not for gs\r
565 popq %rax\r
566 # mov fs, rax ; not for fs\r
567 # (X64 will not use fs and gs, so we do not restore it)\r
568 popq %rax\r
569 movq %rax, %es\r
570 popq %rax\r
571 movq %rax, %ds\r
572 popq 32(%rbp) # for cs\r
573 popq 56(%rbp) # for ss\r
574\r
575## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
576## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
577 popq %rdi\r
578 popq %rsi\r
579 addq $8, %rsp # not for rbp\r
580 popq 48(%rbp) # for rsp\r
581 popq %rbx\r
582 popq %rdx\r
583 popq %rcx\r
584 popq %rax\r
585 popq %r8\r
586 popq %r9\r
587 popq %r10\r
588 popq %r11\r
589 popq %r12\r
590 popq %r13\r
591 popq %r14\r
592 popq %r15\r
593\r
594 movq %rbp, %rsp\r
595\r
596# Enable TF bit after page fault handler runs\r
597 btsl $8, 40(%rsp) #RFLAGS\r
598\r
599 popq %rbp\r
600 addq $16, %rsp # skip INT# & ErrCode\r
601 iretq\r
602\r
603ASM_GLOBAL ASM_PFX(InitializeIDTSmmStackGuard)\r
604ASM_PFX(InitializeIDTSmmStackGuard):\r
605# If SMM Stack Guard feature is enabled, set the IST field of\r
606# the interrupt gate for Page Fault Exception to be 1\r
607#\r
608 movabsq $_SmiIDT + 14 * 16, %rax\r
609 movb $1, 4(%rax)\r
610 ret\r