]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm
MdePkg/BaseLib: add PatchInstructionX86()
[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
7947da3c
MK
26EXTERNDEF gcSmiIdtr:FWORD\r
27EXTERNDEF gcSmiGdtr:FWORD\r
717fb604 28EXTERNDEF gTaskGateDescriptor:QWORD\r
7947da3c
MK
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
854c6b80 247 DQ 0\r
7947da3c
MK
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
717fb604
JY
255 DW 0\r
256 DD 0\r
257\r
258gTaskGateDescriptor LABEL QWORD\r
7947da3c
MK
259 DW 0 ; Reserved\r
260 DW EXCEPTION_TSS_SEL ; TSS Segment selector\r
261 DB 0 ; Reserved\r
262 DB 85h ; Task Gate, present, DPL = 0\r
263 DW 0 ; Reserved\r
264\r
265\r
266 .code\r
267;------------------------------------------------------------------------------\r
268; PageFaultIdtHandlerSmmProfile is the entry point page fault only\r
269;\r
270;\r
271; Stack:\r
272; +---------------------+\r
273; + EFlags +\r
274; +---------------------+\r
275; + CS +\r
276; +---------------------+\r
277; + EIP +\r
278; +---------------------+\r
279; + Error Code +\r
280; +---------------------+\r
281; + Vector Number +\r
282; +---------------------+\r
283; + EBP +\r
284; +---------------------+ <-- EBP\r
285;\r
286;\r
287;------------------------------------------------------------------------------\r
288PageFaultIdtHandlerSmmProfile PROC\r
289 push 0eh ; Page Fault\r
290\r
291 push ebp\r
292 mov ebp, esp\r
293\r
294\r
295 ;\r
296 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
297 ; is 16-byte aligned\r
298 ;\r
299 and esp, 0fffffff0h\r
300 sub esp, 12\r
301\r
302;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
303 push eax\r
304 push ecx\r
305 push edx\r
306 push ebx\r
307 lea ecx, [ebp + 6 * 4]\r
308 push ecx ; ESP\r
309 push dword ptr [ebp] ; EBP\r
310 push esi\r
311 push edi\r
312\r
313;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
314 mov eax, ss\r
315 push eax\r
316 movzx eax, word ptr [ebp + 4 * 4]\r
317 push eax\r
318 mov eax, ds\r
319 push eax\r
320 mov eax, es\r
321 push eax\r
322 mov eax, fs\r
323 push eax\r
324 mov eax, gs\r
325 push eax\r
326\r
327;; UINT32 Eip;\r
328 mov eax, [ebp + 3 * 4]\r
329 push eax\r
330\r
331;; UINT32 Gdtr[2], Idtr[2];\r
332 sub esp, 8\r
333 sidt [esp]\r
334 mov eax, [esp + 2]\r
335 xchg eax, [esp]\r
336 and eax, 0FFFFh\r
337 mov [esp+4], eax\r
338\r
339 sub esp, 8\r
340 sgdt [esp]\r
341 mov eax, [esp + 2]\r
342 xchg eax, [esp]\r
343 and eax, 0FFFFh\r
344 mov [esp+4], eax\r
345\r
346;; UINT32 Ldtr, Tr;\r
347 xor eax, eax\r
348 str ax\r
349 push eax\r
350 sldt ax\r
351 push eax\r
352\r
353;; UINT32 EFlags;\r
354 mov eax, [ebp + 5 * 4]\r
355 push eax\r
356\r
357;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
358 mov eax, cr4\r
359 or eax, 208h\r
360 mov cr4, eax\r
361 push eax\r
362 mov eax, cr3\r
363 push eax\r
364 mov eax, cr2\r
365 push eax\r
366 xor eax, eax\r
367 push eax\r
368 mov eax, cr0\r
369 push eax\r
370\r
371;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
372 mov eax, dr7\r
373 push eax\r
374 mov eax, dr6\r
375 push eax\r
376 mov eax, dr3\r
377 push eax\r
378 mov eax, dr2\r
379 push eax\r
380 mov eax, dr1\r
381 push eax\r
382 mov eax, dr0\r
383 push eax\r
384\r
385;; FX_SAVE_STATE_IA32 FxSaveState;\r
386 sub esp, 512\r
387 mov edi, esp\r
388 db 0fh, 0aeh, 07h ;fxsave [edi]\r
389\r
390; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
391 cld\r
392\r
393;; UINT32 ExceptionData;\r
394 push dword ptr [ebp + 2 * 4]\r
395\r
396;; call into exception handler\r
397\r
398;; Prepare parameter and call\r
399 mov edx, esp\r
400 push edx\r
401 mov edx, dword ptr [ebp + 1 * 4]\r
402 push edx\r
403\r
404 ;\r
405 ; Call External Exception Handler\r
406 ;\r
407 mov eax, SmiPFHandler\r
408 call eax\r
409 add esp, 8\r
410\r
411;; UINT32 ExceptionData;\r
412 add esp, 4\r
413\r
414;; FX_SAVE_STATE_IA32 FxSaveState;\r
415 mov esi, esp\r
416 db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
417 add esp, 512\r
418\r
419;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
420;; Skip restoration of DRx registers to support debuggers\r
421;; that set breakpoint in interrupt/exception context\r
422 add esp, 4 * 6\r
423\r
424;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
425 pop eax\r
426 mov cr0, eax\r
427 add esp, 4 ; not for Cr1\r
428 pop eax\r
429 mov cr2, eax\r
430 pop eax\r
431 mov cr3, eax\r
432 pop eax\r
433 mov cr4, eax\r
434\r
435;; UINT32 EFlags;\r
436 pop dword ptr [ebp + 5 * 4]\r
437\r
438;; UINT32 Ldtr, Tr;\r
439;; UINT32 Gdtr[2], Idtr[2];\r
440;; Best not let anyone mess with these particular registers...\r
441 add esp, 24\r
442\r
443;; UINT32 Eip;\r
444 pop dword ptr [ebp + 3 * 4]\r
445\r
446;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
447;; NOTE - modified segment registers could hang the debugger... We\r
448;; could attempt to insulate ourselves against this possibility,\r
449;; but that poses risks as well.\r
450;;\r
451 pop gs\r
452 pop fs\r
453 pop es\r
454 pop ds\r
455 pop dword ptr [ebp + 4 * 4]\r
456 pop ss\r
457\r
458;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
459 pop edi\r
460 pop esi\r
461 add esp, 4 ; not for ebp\r
462 add esp, 4 ; not for esp\r
463 pop ebx\r
464 pop edx\r
465 pop ecx\r
466 pop eax\r
467\r
468 mov esp, ebp\r
469 pop ebp\r
470\r
471; Enable TF bit after page fault handler runs\r
472 bts dword ptr [esp + 16], 8 ; EFLAGS\r
473\r
474 add esp, 8 ; skip INT# & ErrCode\r
475Return:\r
476 iretd\r
477;\r
478; Page Fault Exception Handler entry when SMM Stack Guard is enabled\r
479; Executiot starts here after a task switch\r
480;\r
481PFHandlerEntry::\r
482;\r
483; Get this processor's TSS\r
484;\r
485 sub esp, 8\r
486 sgdt [esp + 2]\r
487 mov eax, [esp + 4] ; GDT base\r
488 add esp, 8\r
489 mov ecx, [eax + TSS_SEL + 2]\r
490 shl ecx, 8\r
491 mov cl, [eax + TSS_SEL + 7]\r
492 ror ecx, 8 ; ecx = TSS base\r
493\r
494 mov ebp, esp\r
495\r
496 ;\r
497 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
498 ; is 16-byte aligned\r
499 ;\r
500 and esp, 0fffffff0h\r
501 sub esp, 12\r
502\r
503;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
504 push (IA32_TSS ptr [ecx])._EAX\r
505 push (IA32_TSS ptr [ecx])._ECX\r
506 push (IA32_TSS ptr [ecx])._EDX\r
507 push (IA32_TSS ptr [ecx])._EBX\r
508 push (IA32_TSS ptr [ecx])._ESP\r
509 push (IA32_TSS ptr [ecx])._EBP\r
510 push (IA32_TSS ptr [ecx])._ESI\r
511 push (IA32_TSS ptr [ecx])._EDI\r
512\r
513;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
514 movzx eax, (IA32_TSS ptr [ecx])._SS\r
515 push eax\r
516 movzx eax, (IA32_TSS ptr [ecx])._CS\r
517 push eax\r
518 movzx eax, (IA32_TSS ptr [ecx])._DS\r
519 push eax\r
520 movzx eax, (IA32_TSS ptr [ecx])._ES\r
521 push eax\r
522 movzx eax, (IA32_TSS ptr [ecx])._FS\r
523 push eax\r
524 movzx eax, (IA32_TSS ptr [ecx])._GS\r
525 push eax\r
526\r
527;; UINT32 Eip;\r
528 push (IA32_TSS ptr [ecx]).EIP\r
529\r
530;; UINT32 Gdtr[2], Idtr[2];\r
531 sub esp, 8\r
532 sidt [esp]\r
533 mov eax, [esp + 2]\r
534 xchg eax, [esp]\r
535 and eax, 0FFFFh\r
536 mov [esp+4], eax\r
537\r
538 sub esp, 8\r
539 sgdt [esp]\r
540 mov eax, [esp + 2]\r
541 xchg eax, [esp]\r
542 and eax, 0FFFFh\r
543 mov [esp+4], eax\r
544\r
545;; UINT32 Ldtr, Tr;\r
546 mov eax, TSS_SEL\r
547 push eax\r
548 movzx eax, (IA32_TSS ptr [ecx]).LDT\r
549 push eax\r
550\r
551;; UINT32 EFlags;\r
552 push (IA32_TSS ptr [ecx]).EFLAGS\r
553\r
554;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
555 mov eax, cr4\r
556 or eax, 208h\r
557 mov cr4, eax\r
558 push eax\r
559 mov eax, cr3\r
560 push eax\r
561 mov eax, cr2\r
562 push eax\r
563 xor eax, eax\r
564 push eax\r
565 mov eax, cr0\r
566 push eax\r
567\r
568;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
569 mov eax, dr7\r
570 push eax\r
571 mov eax, dr6\r
572 push eax\r
573 mov eax, dr3\r
574 push eax\r
575 mov eax, dr2\r
576 push eax\r
577 mov eax, dr1\r
578 push eax\r
579 mov eax, dr0\r
580 push eax\r
581\r
582;; FX_SAVE_STATE_IA32 FxSaveState;\r
583;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)\r
584;; when executing fxsave/fxrstor instruction\r
585 clts\r
586 sub esp, 512\r
587 mov edi, esp\r
588 db 0fh, 0aeh, 07h ;fxsave [edi]\r
589\r
590; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
591 cld\r
592\r
593;; UINT32 ExceptionData;\r
594 push dword ptr [ebp]\r
595\r
596;; call into exception handler\r
597 mov ebx, ecx\r
598 mov eax, SmiPFHandler\r
599\r
600;; Prepare parameter and call\r
601 mov edx, esp\r
602 push edx\r
603 mov edx, 14\r
604 push edx\r
605\r
606 ;\r
607 ; Call External Exception Handler\r
608 ;\r
609 call eax\r
610 add esp, 8\r
611\r
612 mov ecx, ebx\r
613;; UINT32 ExceptionData;\r
614 add esp, 4\r
615\r
616;; FX_SAVE_STATE_IA32 FxSaveState;\r
617 mov esi, esp\r
618 db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
619 add esp, 512\r
620\r
621;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
622;; Skip restoration of DRx registers to support debuggers\r
623;; that set breakpoints in interrupt/exception context\r
624 add esp, 4 * 6\r
625\r
626;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
627 pop eax\r
628 mov cr0, eax\r
629 add esp, 4 ; not for Cr1\r
630 pop eax\r
631 mov cr2, eax\r
632 pop eax\r
633 mov (IA32_TSS ptr [ecx])._CR3, eax\r
634 pop eax\r
635 mov cr4, eax\r
636\r
637;; UINT32 EFlags;\r
638 pop (IA32_TSS ptr [ecx]).EFLAGS\r
639\r
640;; UINT32 Ldtr, Tr;\r
641;; UINT32 Gdtr[2], Idtr[2];\r
642;; Best not let anyone mess with these particular registers...\r
643 add esp, 24\r
644\r
645;; UINT32 Eip;\r
646 pop (IA32_TSS ptr [ecx]).EIP\r
647\r
648;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
649;; NOTE - modified segment registers could hang the debugger... We\r
650;; could attempt to insulate ourselves against this possibility,\r
651;; but that poses risks as well.\r
652;;\r
653 pop eax\r
654 mov (IA32_TSS ptr [ecx])._GS, ax\r
655 pop eax\r
656 mov (IA32_TSS ptr [ecx])._FS, ax\r
657 pop eax\r
658 mov (IA32_TSS ptr [ecx])._ES, ax\r
659 pop eax\r
660 mov (IA32_TSS ptr [ecx])._DS, ax\r
661 pop eax\r
662 mov (IA32_TSS ptr [ecx])._CS, ax\r
663 pop eax\r
664 mov (IA32_TSS ptr [ecx])._SS, ax\r
665\r
666;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
667 pop (IA32_TSS ptr [ecx])._EDI\r
668 pop (IA32_TSS ptr [ecx])._ESI\r
669 add esp, 4 ; not for ebp\r
670 add esp, 4 ; not for esp\r
671 pop (IA32_TSS ptr [ecx])._EBX\r
672 pop (IA32_TSS ptr [ecx])._EDX\r
673 pop (IA32_TSS ptr [ecx])._ECX\r
674 pop (IA32_TSS ptr [ecx])._EAX\r
675\r
676 mov esp, ebp\r
677\r
678; Set single step DB# if SMM profile is enabled and page fault exception happens\r
679 cmp FeaturePcdGet (PcdCpuSmmProfileEnable), 0\r
680 jz @Done2\r
681\r
682; Create return context for iretd in stub function\r
683 mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer\r
684 mov ebx, (IA32_TSS ptr [ecx]).EIP\r
685 mov [eax - 0ch], ebx ; create EIP in old stack\r
686 movzx ebx, (IA32_TSS ptr [ecx])._CS\r
687 mov [eax - 08h], ebx ; create CS in old stack\r
688 mov ebx, (IA32_TSS ptr [ecx]).EFLAGS\r
689 bts ebx, 8\r
690 mov [eax - 04h], ebx ; create eflags in old stack\r
691 mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer\r
692 sub eax, 0ch ; minus 12 byte\r
693 mov (IA32_TSS ptr [ecx])._ESP, eax ; Set new stack pointer\r
694; Replace the EIP of interrupted task with stub function\r
695 mov eax, PageFaultStubFunction\r
696 mov (IA32_TSS ptr [ecx]).EIP, eax\r
697; Jump to the iretd so next page fault handler as a task will start again after iretd.\r
698@Done2:\r
699 add esp, 4 ; skip ErrCode\r
700\r
701 jmp Return\r
702PageFaultIdtHandlerSmmProfile ENDP\r
703\r
704PageFaultStubFunction PROC\r
705;\r
706; we need clean TS bit in CR0 to execute\r
707; x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.\r
708;\r
709 clts\r
710 iretd\r
711PageFaultStubFunction ENDP\r
712\r
7947da3c 713 END\r