]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm
UefiCpuPkg/dec: Add PcdCpuSmmStaticPageTable.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiException.asm
CommitLineData
7947da3c
MK
1;------------------------------------------------------------------------------ ;\r
2; Copyright (c) 2009 - 2015, 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.asm\r
14;\r
15; Abstract:\r
16;\r
17; Exception handlers used in SM mode\r
18;\r
19;-------------------------------------------------------------------------------\r
20\r
21 .686p\r
22 .model flat,C\r
23\r
24EXTERNDEF SmiPFHandler:PROC\r
25EXTERNDEF PageFaultStubFunction:PROC\r
26EXTERNDEF gSmiMtrrs:QWORD\r
27EXTERNDEF gcSmiIdtr:FWORD\r
28EXTERNDEF gcSmiGdtr:FWORD\r
29EXTERNDEF gcPsd:BYTE\r
30EXTERNDEF FeaturePcdGet (PcdCpuSmmProfileEnable):BYTE\r
31\r
32\r
33 .data\r
34\r
35NullSeg DQ 0 ; reserved by architecture\r
36CodeSeg32 LABEL QWORD\r
37 DW -1 ; LimitLow\r
38 DW 0 ; BaseLow\r
39 DB 0 ; BaseMid\r
40 DB 9bh\r
41 DB 0cfh ; LimitHigh\r
42 DB 0 ; BaseHigh\r
43ProtModeCodeSeg32 LABEL QWORD\r
44 DW -1 ; LimitLow\r
45 DW 0 ; BaseLow\r
46 DB 0 ; BaseMid\r
47 DB 9bh\r
48 DB 0cfh ; LimitHigh\r
49 DB 0 ; BaseHigh\r
50ProtModeSsSeg32 LABEL QWORD\r
51 DW -1 ; LimitLow\r
52 DW 0 ; BaseLow\r
53 DB 0 ; BaseMid\r
54 DB 93h\r
55 DB 0cfh ; LimitHigh\r
56 DB 0 ; BaseHigh\r
57DataSeg32 LABEL QWORD\r
58 DW -1 ; LimitLow\r
59 DW 0 ; BaseLow\r
60 DB 0 ; BaseMid\r
61 DB 93h\r
62 DB 0cfh ; LimitHigh\r
63 DB 0 ; BaseHigh\r
64CodeSeg16 LABEL QWORD\r
65 DW -1\r
66 DW 0\r
67 DB 0\r
68 DB 9bh\r
69 DB 8fh\r
70 DB 0\r
71DataSeg16 LABEL QWORD\r
72 DW -1\r
73 DW 0\r
74 DB 0\r
75 DB 93h\r
76 DB 8fh\r
77 DB 0\r
78CodeSeg64 LABEL QWORD\r
79 DW -1 ; LimitLow\r
80 DW 0 ; BaseLow\r
81 DB 0 ; BaseMid\r
82 DB 9bh\r
83 DB 0afh ; LimitHigh\r
84 DB 0 ; BaseHigh\r
85GDT_SIZE = $ - offset NullSeg\r
86\r
87TssSeg LABEL QWORD\r
20ab3269 88 DW TSS_DESC_SIZE - 1 ; LimitLow\r
7947da3c
MK
89 DW 0 ; BaseLow\r
90 DB 0 ; BaseMid\r
91 DB 89h\r
20ab3269 92 DB 00h ; LimitHigh\r
7947da3c
MK
93 DB 0 ; BaseHigh\r
94ExceptionTssSeg LABEL QWORD\r
20ab3269 95 DW TSS_DESC_SIZE - 1 ; LimitLow\r
7947da3c
MK
96 DW 0 ; BaseLow\r
97 DB 0 ; BaseMid\r
98 DB 89h\r
20ab3269 99 DB 00h ; LimitHigh\r
7947da3c
MK
100 DB 0 ; BaseHigh\r
101\r
102CODE_SEL = offset CodeSeg32 - offset NullSeg\r
103DATA_SEL = offset DataSeg32 - offset NullSeg\r
104TSS_SEL = offset TssSeg - offset NullSeg\r
105EXCEPTION_TSS_SEL = offset ExceptionTssSeg - offset NullSeg\r
106\r
107IA32_TSS STRUC\r
108 DW ?\r
109 DW ?\r
110 ESP0 DD ?\r
111 SS0 DW ?\r
112 DW ?\r
113 ESP1 DD ?\r
114 SS1 DW ?\r
115 DW ?\r
116 ESP2 DD ?\r
117 SS2 DW ?\r
118 DW ?\r
119 _CR3 DD ?\r
120 EIP DD ?\r
121 EFLAGS DD ?\r
122 _EAX DD ?\r
123 _ECX DD ?\r
124 _EDX DD ?\r
125 _EBX DD ?\r
126 _ESP DD ?\r
127 _EBP DD ?\r
128 _ESI DD ?\r
129 _EDI DD ?\r
130 _ES DW ?\r
131 DW ?\r
132 _CS DW ?\r
133 DW ?\r
134 _SS DW ?\r
135 DW ?\r
136 _DS DW ?\r
137 DW ?\r
138 _FS DW ?\r
139 DW ?\r
140 _GS DW ?\r
141 DW ?\r
142 LDT DW ?\r
143 DW ?\r
144 DW ?\r
145 DW ?\r
146IA32_TSS ENDS\r
147\r
148; Create 2 TSS segments just after GDT\r
149TssDescriptor LABEL BYTE\r
150 DW 0 ; PreviousTaskLink\r
151 DW 0 ; Reserved\r
152 DD 0 ; ESP0\r
153 DW 0 ; SS0\r
154 DW 0 ; Reserved\r
155 DD 0 ; ESP1\r
156 DW 0 ; SS1\r
157 DW 0 ; Reserved\r
158 DD 0 ; ESP2\r
159 DW 0 ; SS2\r
160 DW 0 ; Reserved\r
161 DD 0 ; CR3\r
162 DD 0 ; EIP\r
163 DD 0 ; EFLAGS\r
164 DD 0 ; EAX\r
165 DD 0 ; ECX\r
166 DD 0 ; EDX\r
167 DD 0 ; EBX\r
168 DD 0 ; ESP\r
169 DD 0 ; EBP\r
170 DD 0 ; ESI\r
171 DD 0 ; EDI\r
172 DW 0 ; ES\r
173 DW 0 ; Reserved\r
174 DW 0 ; CS\r
175 DW 0 ; Reserved\r
176 DW 0 ; SS\r
177 DW 0 ; Reserved\r
178 DW 0 ; DS\r
179 DW 0 ; Reserved\r
180 DW 0 ; FS\r
181 DW 0 ; Reserved\r
182 DW 0 ; GS\r
183 DW 0 ; Reserved\r
184 DW 0 ; LDT Selector\r
185 DW 0 ; Reserved\r
186 DW 0 ; T\r
187 DW 0 ; I/O Map Base\r
188TSS_DESC_SIZE = $ - offset TssDescriptor\r
189\r
190ExceptionTssDescriptor LABEL BYTE\r
191 DW 0 ; PreviousTaskLink\r
192 DW 0 ; Reserved\r
193 DD 0 ; ESP0\r
194 DW 0 ; SS0\r
195 DW 0 ; Reserved\r
196 DD 0 ; ESP1\r
197 DW 0 ; SS1\r
198 DW 0 ; Reserved\r
199 DD 0 ; ESP2\r
200 DW 0 ; SS2\r
201 DW 0 ; Reserved\r
202 DD 0 ; CR3\r
203 DD offset PFHandlerEntry ; EIP\r
204 DD 00000002 ; EFLAGS\r
205 DD 0 ; EAX\r
206 DD 0 ; ECX\r
207 DD 0 ; EDX\r
208 DD 0 ; EBX\r
209 DD 0 ; ESP\r
210 DD 0 ; EBP\r
211 DD 0 ; ESI\r
212 DD 0 ; EDI\r
213 DW DATA_SEL ; ES\r
214 DW 0 ; Reserved\r
215 DW CODE_SEL ; CS\r
216 DW 0 ; Reserved\r
217 DW DATA_SEL ; SS\r
218 DW 0 ; Reserved\r
219 DW DATA_SEL ; DS\r
220 DW 0 ; Reserved\r
221 DW DATA_SEL ; FS\r
222 DW 0 ; Reserved\r
223 DW DATA_SEL ; GS\r
224 DW 0 ; Reserved\r
225 DW 0 ; LDT Selector\r
226 DW 0 ; Reserved\r
227 DW 0 ; T\r
228 DW 0 ; I/O Map Base\r
229\r
230gcPsd LABEL BYTE\r
231 DB 'PSDSIG '\r
232 DW PSD_SIZE\r
233 DW 2\r
234 DW 1 SHL 2\r
235 DW CODE_SEL\r
236 DW DATA_SEL\r
237 DW DATA_SEL\r
238 DW DATA_SEL\r
239 DW 0\r
240 DQ 0\r
241 DQ 0\r
242 DQ 0\r
243 DQ offset NullSeg\r
244 DD GDT_SIZE\r
245 DD 0\r
246 DB 24 dup (0)\r
247 DQ offset gSmiMtrrs\r
248PSD_SIZE = $ - offset gcPsd\r
249\r
250gcSmiGdtr LABEL FWORD\r
251 DW GDT_SIZE - 1\r
252 DD offset NullSeg\r
253\r
254gcSmiIdtr LABEL FWORD\r
255 DW IDT_SIZE - 1\r
256 DD offset _SmiIDT\r
257\r
258_SmiIDT LABEL QWORD\r
259REPEAT 32\r
260 DW 0 ; Offset 0:15\r
261 DW CODE_SEL ; Segment selector\r
262 DB 0 ; Unused\r
263 DB 8eh ; Interrupt Gate, Present\r
264 DW 0 ; Offset 16:31\r
265 ENDM\r
266IDT_SIZE = $ - offset _SmiIDT\r
267\r
268TaskGateDescriptor LABEL DWORD\r
269 DW 0 ; Reserved\r
270 DW EXCEPTION_TSS_SEL ; TSS Segment selector\r
271 DB 0 ; Reserved\r
272 DB 85h ; Task Gate, present, DPL = 0\r
273 DW 0 ; Reserved\r
274\r
275\r
276 .code\r
277;------------------------------------------------------------------------------\r
278; PageFaultIdtHandlerSmmProfile is the entry point page fault only\r
279;\r
280;\r
281; Stack:\r
282; +---------------------+\r
283; + EFlags +\r
284; +---------------------+\r
285; + CS +\r
286; +---------------------+\r
287; + EIP +\r
288; +---------------------+\r
289; + Error Code +\r
290; +---------------------+\r
291; + Vector Number +\r
292; +---------------------+\r
293; + EBP +\r
294; +---------------------+ <-- EBP\r
295;\r
296;\r
297;------------------------------------------------------------------------------\r
298PageFaultIdtHandlerSmmProfile PROC\r
299 push 0eh ; Page Fault\r
300\r
301 push ebp\r
302 mov ebp, esp\r
303\r
304\r
305 ;\r
306 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
307 ; is 16-byte aligned\r
308 ;\r
309 and esp, 0fffffff0h\r
310 sub esp, 12\r
311\r
312;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
313 push eax\r
314 push ecx\r
315 push edx\r
316 push ebx\r
317 lea ecx, [ebp + 6 * 4]\r
318 push ecx ; ESP\r
319 push dword ptr [ebp] ; EBP\r
320 push esi\r
321 push edi\r
322\r
323;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
324 mov eax, ss\r
325 push eax\r
326 movzx eax, word ptr [ebp + 4 * 4]\r
327 push eax\r
328 mov eax, ds\r
329 push eax\r
330 mov eax, es\r
331 push eax\r
332 mov eax, fs\r
333 push eax\r
334 mov eax, gs\r
335 push eax\r
336\r
337;; UINT32 Eip;\r
338 mov eax, [ebp + 3 * 4]\r
339 push eax\r
340\r
341;; UINT32 Gdtr[2], Idtr[2];\r
342 sub esp, 8\r
343 sidt [esp]\r
344 mov eax, [esp + 2]\r
345 xchg eax, [esp]\r
346 and eax, 0FFFFh\r
347 mov [esp+4], eax\r
348\r
349 sub esp, 8\r
350 sgdt [esp]\r
351 mov eax, [esp + 2]\r
352 xchg eax, [esp]\r
353 and eax, 0FFFFh\r
354 mov [esp+4], eax\r
355\r
356;; UINT32 Ldtr, Tr;\r
357 xor eax, eax\r
358 str ax\r
359 push eax\r
360 sldt ax\r
361 push eax\r
362\r
363;; UINT32 EFlags;\r
364 mov eax, [ebp + 5 * 4]\r
365 push eax\r
366\r
367;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
368 mov eax, cr4\r
369 or eax, 208h\r
370 mov cr4, eax\r
371 push eax\r
372 mov eax, cr3\r
373 push eax\r
374 mov eax, cr2\r
375 push eax\r
376 xor eax, eax\r
377 push eax\r
378 mov eax, cr0\r
379 push eax\r
380\r
381;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
382 mov eax, dr7\r
383 push eax\r
384 mov eax, dr6\r
385 push eax\r
386 mov eax, dr3\r
387 push eax\r
388 mov eax, dr2\r
389 push eax\r
390 mov eax, dr1\r
391 push eax\r
392 mov eax, dr0\r
393 push eax\r
394\r
395;; FX_SAVE_STATE_IA32 FxSaveState;\r
396 sub esp, 512\r
397 mov edi, esp\r
398 db 0fh, 0aeh, 07h ;fxsave [edi]\r
399\r
400; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
401 cld\r
402\r
403;; UINT32 ExceptionData;\r
404 push dword ptr [ebp + 2 * 4]\r
405\r
406;; call into exception handler\r
407\r
408;; Prepare parameter and call\r
409 mov edx, esp\r
410 push edx\r
411 mov edx, dword ptr [ebp + 1 * 4]\r
412 push edx\r
413\r
414 ;\r
415 ; Call External Exception Handler\r
416 ;\r
417 mov eax, SmiPFHandler\r
418 call eax\r
419 add esp, 8\r
420\r
421;; UINT32 ExceptionData;\r
422 add esp, 4\r
423\r
424;; FX_SAVE_STATE_IA32 FxSaveState;\r
425 mov esi, esp\r
426 db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
427 add esp, 512\r
428\r
429;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
430;; Skip restoration of DRx registers to support debuggers\r
431;; that set breakpoint in interrupt/exception context\r
432 add esp, 4 * 6\r
433\r
434;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
435 pop eax\r
436 mov cr0, eax\r
437 add esp, 4 ; not for Cr1\r
438 pop eax\r
439 mov cr2, eax\r
440 pop eax\r
441 mov cr3, eax\r
442 pop eax\r
443 mov cr4, eax\r
444\r
445;; UINT32 EFlags;\r
446 pop dword ptr [ebp + 5 * 4]\r
447\r
448;; UINT32 Ldtr, Tr;\r
449;; UINT32 Gdtr[2], Idtr[2];\r
450;; Best not let anyone mess with these particular registers...\r
451 add esp, 24\r
452\r
453;; UINT32 Eip;\r
454 pop dword ptr [ebp + 3 * 4]\r
455\r
456;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
457;; NOTE - modified segment registers could hang the debugger... We\r
458;; could attempt to insulate ourselves against this possibility,\r
459;; but that poses risks as well.\r
460;;\r
461 pop gs\r
462 pop fs\r
463 pop es\r
464 pop ds\r
465 pop dword ptr [ebp + 4 * 4]\r
466 pop ss\r
467\r
468;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
469 pop edi\r
470 pop esi\r
471 add esp, 4 ; not for ebp\r
472 add esp, 4 ; not for esp\r
473 pop ebx\r
474 pop edx\r
475 pop ecx\r
476 pop eax\r
477\r
478 mov esp, ebp\r
479 pop ebp\r
480\r
481; Enable TF bit after page fault handler runs\r
482 bts dword ptr [esp + 16], 8 ; EFLAGS\r
483\r
484 add esp, 8 ; skip INT# & ErrCode\r
485Return:\r
486 iretd\r
487;\r
488; Page Fault Exception Handler entry when SMM Stack Guard is enabled\r
489; Executiot starts here after a task switch\r
490;\r
491PFHandlerEntry::\r
492;\r
493; Get this processor's TSS\r
494;\r
495 sub esp, 8\r
496 sgdt [esp + 2]\r
497 mov eax, [esp + 4] ; GDT base\r
498 add esp, 8\r
499 mov ecx, [eax + TSS_SEL + 2]\r
500 shl ecx, 8\r
501 mov cl, [eax + TSS_SEL + 7]\r
502 ror ecx, 8 ; ecx = TSS base\r
503\r
504 mov ebp, esp\r
505\r
506 ;\r
507 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
508 ; is 16-byte aligned\r
509 ;\r
510 and esp, 0fffffff0h\r
511 sub esp, 12\r
512\r
513;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
514 push (IA32_TSS ptr [ecx])._EAX\r
515 push (IA32_TSS ptr [ecx])._ECX\r
516 push (IA32_TSS ptr [ecx])._EDX\r
517 push (IA32_TSS ptr [ecx])._EBX\r
518 push (IA32_TSS ptr [ecx])._ESP\r
519 push (IA32_TSS ptr [ecx])._EBP\r
520 push (IA32_TSS ptr [ecx])._ESI\r
521 push (IA32_TSS ptr [ecx])._EDI\r
522\r
523;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
524 movzx eax, (IA32_TSS ptr [ecx])._SS\r
525 push eax\r
526 movzx eax, (IA32_TSS ptr [ecx])._CS\r
527 push eax\r
528 movzx eax, (IA32_TSS ptr [ecx])._DS\r
529 push eax\r
530 movzx eax, (IA32_TSS ptr [ecx])._ES\r
531 push eax\r
532 movzx eax, (IA32_TSS ptr [ecx])._FS\r
533 push eax\r
534 movzx eax, (IA32_TSS ptr [ecx])._GS\r
535 push eax\r
536\r
537;; UINT32 Eip;\r
538 push (IA32_TSS ptr [ecx]).EIP\r
539\r
540;; UINT32 Gdtr[2], Idtr[2];\r
541 sub esp, 8\r
542 sidt [esp]\r
543 mov eax, [esp + 2]\r
544 xchg eax, [esp]\r
545 and eax, 0FFFFh\r
546 mov [esp+4], eax\r
547\r
548 sub esp, 8\r
549 sgdt [esp]\r
550 mov eax, [esp + 2]\r
551 xchg eax, [esp]\r
552 and eax, 0FFFFh\r
553 mov [esp+4], eax\r
554\r
555;; UINT32 Ldtr, Tr;\r
556 mov eax, TSS_SEL\r
557 push eax\r
558 movzx eax, (IA32_TSS ptr [ecx]).LDT\r
559 push eax\r
560\r
561;; UINT32 EFlags;\r
562 push (IA32_TSS ptr [ecx]).EFLAGS\r
563\r
564;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
565 mov eax, cr4\r
566 or eax, 208h\r
567 mov cr4, eax\r
568 push eax\r
569 mov eax, cr3\r
570 push eax\r
571 mov eax, cr2\r
572 push eax\r
573 xor eax, eax\r
574 push eax\r
575 mov eax, cr0\r
576 push eax\r
577\r
578;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
579 mov eax, dr7\r
580 push eax\r
581 mov eax, dr6\r
582 push eax\r
583 mov eax, dr3\r
584 push eax\r
585 mov eax, dr2\r
586 push eax\r
587 mov eax, dr1\r
588 push eax\r
589 mov eax, dr0\r
590 push eax\r
591\r
592;; FX_SAVE_STATE_IA32 FxSaveState;\r
593;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)\r
594;; when executing fxsave/fxrstor instruction\r
595 clts\r
596 sub esp, 512\r
597 mov edi, esp\r
598 db 0fh, 0aeh, 07h ;fxsave [edi]\r
599\r
600; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
601 cld\r
602\r
603;; UINT32 ExceptionData;\r
604 push dword ptr [ebp]\r
605\r
606;; call into exception handler\r
607 mov ebx, ecx\r
608 mov eax, SmiPFHandler\r
609\r
610;; Prepare parameter and call\r
611 mov edx, esp\r
612 push edx\r
613 mov edx, 14\r
614 push edx\r
615\r
616 ;\r
617 ; Call External Exception Handler\r
618 ;\r
619 call eax\r
620 add esp, 8\r
621\r
622 mov ecx, ebx\r
623;; UINT32 ExceptionData;\r
624 add esp, 4\r
625\r
626;; FX_SAVE_STATE_IA32 FxSaveState;\r
627 mov esi, esp\r
628 db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
629 add esp, 512\r
630\r
631;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
632;; Skip restoration of DRx registers to support debuggers\r
633;; that set breakpoints in interrupt/exception context\r
634 add esp, 4 * 6\r
635\r
636;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
637 pop eax\r
638 mov cr0, eax\r
639 add esp, 4 ; not for Cr1\r
640 pop eax\r
641 mov cr2, eax\r
642 pop eax\r
643 mov (IA32_TSS ptr [ecx])._CR3, eax\r
644 pop eax\r
645 mov cr4, eax\r
646\r
647;; UINT32 EFlags;\r
648 pop (IA32_TSS ptr [ecx]).EFLAGS\r
649\r
650;; UINT32 Ldtr, Tr;\r
651;; UINT32 Gdtr[2], Idtr[2];\r
652;; Best not let anyone mess with these particular registers...\r
653 add esp, 24\r
654\r
655;; UINT32 Eip;\r
656 pop (IA32_TSS ptr [ecx]).EIP\r
657\r
658;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
659;; NOTE - modified segment registers could hang the debugger... We\r
660;; could attempt to insulate ourselves against this possibility,\r
661;; but that poses risks as well.\r
662;;\r
663 pop eax\r
664 mov (IA32_TSS ptr [ecx])._GS, ax\r
665 pop eax\r
666 mov (IA32_TSS ptr [ecx])._FS, ax\r
667 pop eax\r
668 mov (IA32_TSS ptr [ecx])._ES, ax\r
669 pop eax\r
670 mov (IA32_TSS ptr [ecx])._DS, ax\r
671 pop eax\r
672 mov (IA32_TSS ptr [ecx])._CS, ax\r
673 pop eax\r
674 mov (IA32_TSS ptr [ecx])._SS, ax\r
675\r
676;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
677 pop (IA32_TSS ptr [ecx])._EDI\r
678 pop (IA32_TSS ptr [ecx])._ESI\r
679 add esp, 4 ; not for ebp\r
680 add esp, 4 ; not for esp\r
681 pop (IA32_TSS ptr [ecx])._EBX\r
682 pop (IA32_TSS ptr [ecx])._EDX\r
683 pop (IA32_TSS ptr [ecx])._ECX\r
684 pop (IA32_TSS ptr [ecx])._EAX\r
685\r
686 mov esp, ebp\r
687\r
688; Set single step DB# if SMM profile is enabled and page fault exception happens\r
689 cmp FeaturePcdGet (PcdCpuSmmProfileEnable), 0\r
690 jz @Done2\r
691\r
692; Create return context for iretd in stub function\r
693 mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer\r
694 mov ebx, (IA32_TSS ptr [ecx]).EIP\r
695 mov [eax - 0ch], ebx ; create EIP in old stack\r
696 movzx ebx, (IA32_TSS ptr [ecx])._CS\r
697 mov [eax - 08h], ebx ; create CS in old stack\r
698 mov ebx, (IA32_TSS ptr [ecx]).EFLAGS\r
699 bts ebx, 8\r
700 mov [eax - 04h], ebx ; create eflags in old stack\r
701 mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer\r
702 sub eax, 0ch ; minus 12 byte\r
703 mov (IA32_TSS ptr [ecx])._ESP, eax ; Set new stack pointer\r
704; Replace the EIP of interrupted task with stub function\r
705 mov eax, PageFaultStubFunction\r
706 mov (IA32_TSS ptr [ecx]).EIP, eax\r
707; Jump to the iretd so next page fault handler as a task will start again after iretd.\r
708@Done2:\r
709 add esp, 4 ; skip ErrCode\r
710\r
711 jmp Return\r
712PageFaultIdtHandlerSmmProfile ENDP\r
713\r
714PageFaultStubFunction PROC\r
715;\r
716; we need clean TS bit in CR0 to execute\r
717; x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.\r
718;\r
719 clts\r
720 iretd\r
721PageFaultStubFunction ENDP\r
722\r
723InitializeIDTSmmStackGuard PROC USES ebx\r
724;\r
725; If SMM Stack Guard feature is enabled, the Page Fault Exception entry in IDT\r
726; is a Task Gate Descriptor so that when a Page Fault Exception occurs,\r
727; the processors can use a known good stack in case stack is ran out.\r
728;\r
729 lea ebx, _SmiIDT + 14 * 8\r
730 lea edx, TaskGateDescriptor\r
731 mov eax, [edx]\r
732 mov [ebx], eax\r
733 mov eax, [edx + 4]\r
734 mov [ebx + 4], eax\r
735 ret\r
736InitializeIDTSmmStackGuard ENDP\r
737\r
738 END\r