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