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