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