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