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