]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.S
UefiCpuPkg/dec: Add PcdCpuSmmStaticPageTable.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiException.S
CommitLineData
7947da3c
MK
1#------------------------------------------------------------------------------\r
2#\r
3# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
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
27ASM_GLOBAL ASM_PFX(gcPsd)\r
28ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))\r
29\r
30 .data\r
31\r
32NullSeg: .quad 0 # reserved by architecture\r
33CodeSeg32:\r
34 .word -1 # LimitLow\r
35 .word 0 # BaseLow\r
36 .byte 0 # BaseMid\r
37 .byte 0x9b\r
38 .byte 0xcf # LimitHigh\r
39 .byte 0 # BaseHigh\r
40ProtModeCodeSeg32:\r
41 .word -1 # LimitLow\r
42 .word 0 # BaseLow\r
43 .byte 0 # BaseMid\r
44 .byte 0x9b\r
45 .byte 0xcf # LimitHigh\r
46 .byte 0 # BaseHigh\r
47ProtModeSsSeg32:\r
48 .word -1 # LimitLow\r
49 .word 0 # BaseLow\r
50 .byte 0 # BaseMid\r
51 .byte 0x93\r
52 .byte 0xcf # LimitHigh\r
53 .byte 0 # BaseHigh\r
54DataSeg32:\r
55 .word -1 # LimitLow\r
56 .word 0 # BaseLow\r
57 .byte 0 # BaseMid\r
58 .byte 0x93\r
59 .byte 0xcf # LimitHigh\r
60 .byte 0 # BaseHigh\r
61CodeSeg16:\r
62 .word -1\r
63 .word 0\r
64 .byte 0\r
65 .byte 0x9b\r
66 .byte 0x8f\r
67 .byte 0\r
68DataSeg16:\r
69 .word -1\r
70 .word 0\r
71 .byte 0\r
72 .byte 0x93\r
73 .byte 0x8f\r
74 .byte 0\r
75CodeSeg64:\r
76 .word -1 # LimitLow\r
77 .word 0 # BaseLow\r
78 .byte 0 # BaseMid\r
79 .byte 0x9b\r
80 .byte 0xaf # LimitHigh\r
81 .byte 0 # BaseHigh\r
82.equ GDT_SIZE, .- NullSeg\r
83\r
84TssSeg:\r
20ab3269 85 .word TSS_DESC_SIZE -1 # LimitLow\r
7947da3c
MK
86 .word 0 # BaseLow\r
87 .byte 0 # BaseMid\r
88 .byte 0x89\r
20ab3269 89 .byte 0x00 # LimitHigh\r
7947da3c
MK
90 .byte 0 # BaseHigh\r
91ExceptionTssSeg:\r
20ab3269 92 .word TSS_DESC_SIZE - 1 # LimitLow\r
7947da3c
MK
93 .word 0 # BaseLow\r
94 .byte 0 # BaseMid\r
95 .byte 0x89\r
20ab3269 96 .byte 0x00 # LimitHigh\r
7947da3c
MK
97 .byte 0 # BaseHigh\r
98\r
99.equ CODE_SEL, CodeSeg32 - NullSeg\r
100.equ DATA_SEL, DataSeg32 - NullSeg\r
101.equ TSS_SEL, TssSeg - NullSeg\r
102.equ EXCEPTION_TSS_SEL, ExceptionTssSeg - NullSeg\r
103\r
104# IA32 TSS fields\r
105.equ TSS_ESP0, 4\r
106.equ TSS_SS0, 8\r
107.equ TSS_ESP1, 12\r
108.equ TSS_SS1, 16\r
109.equ TSS_ESP2, 20\r
110.equ TSS_SS2, 24\r
111.equ TSS_CR3, 28\r
112.equ TSS_EIP, 32\r
113.equ TSS_EFLAGS, 36\r
114.equ TSS_EAX, 40\r
115.equ TSS_ECX, 44\r
116.equ TSS_EDX, 48\r
117.equ TSS_EBX, 52\r
118.equ TSS_ESP, 56\r
119.equ TSS_EBP, 60\r
120.equ TSS_ESI, 64\r
121.equ TSS_EDI, 68\r
122.equ TSS_ES, 72\r
123.equ TSS_CS, 76\r
124.equ TSS_SS, 80\r
125.equ TSS_DS, 84\r
126.equ TSS_FS, 88\r
127.equ TSS_GS, 92\r
128.equ TSS_LDT, 96\r
129\r
130# Create 2 TSS segments just after GDT\r
131TssDescriptor:\r
132 .word 0 # PreviousTaskLink\r
133 .word 0 # Reserved\r
134 .long 0 # ESP0\r
135 .word 0 # SS0\r
136 .word 0 # Reserved\r
137 .long 0 # ESP1\r
138 .word 0 # SS1\r
139 .word 0 # Reserved\r
140 .long 0 # ESP2\r
141 .word 0 # SS2\r
142 .word 0 # Reserved\r
143 .long 0 # CR3\r
144 .long 0 # EIP\r
145 .long 0 # EFLAGS\r
146 .long 0 # EAX\r
147 .long 0 # ECX\r
148 .long 0 # EDX\r
149 .long 0 # EBX\r
150 .long 0 # ESP\r
151 .long 0 # EBP\r
152 .long 0 # ESI\r
153 .long 0 # EDI\r
154 .word 0 # ES\r
155 .word 0 # Reserved\r
156 .word 0 # CS\r
157 .word 0 # Reserved\r
158 .word 0 # SS\r
159 .word 0 # Reserved\r
160 .word 0 # DS\r
161 .word 0 # Reserved\r
162 .word 0 # FS\r
163 .word 0 # Reserved\r
164 .word 0 # GS\r
165 .word 0 # Reserved\r
166 .word 0 # LDT Selector\r
167 .word 0 # Reserved\r
168 .word 0 # T\r
169 .word 0 # I/O Map Base\r
170.equ TSS_DESC_SIZE, . - TssDescriptor\r
171\r
172ExceptionTssDescriptor:\r
173 .word 0 # PreviousTaskLink\r
174 .word 0 # Reserved\r
175 .long 0 # ESP0\r
176 .word 0 # SS0\r
177 .word 0 # Reserved\r
178 .long 0 # ESP1\r
179 .word 0 # SS1\r
180 .word 0 # Reserved\r
181 .long 0 # ESP2\r
182 .word 0 # SS2\r
183 .word 0 # Reserved\r
184 .long 0 # CR3\r
185 .long PFHandlerEntry # EIP\r
186 .long 00000002 # EFLAGS\r
187 .long 0 # EAX\r
188 .long 0 # ECX\r
189 .long 0 # EDX\r
190 .long 0 # EBX\r
191 .long 0 # ESP\r
192 .long 0 # EBP\r
193 .long 0 # ESI\r
194 .long 0 # EDI\r
195 .word DATA_SEL # ES\r
196 .word 0 # Reserved\r
197 .word CODE_SEL # CS\r
198 .word 0 # Reserved\r
199 .word DATA_SEL # SS\r
200 .word 0 # Reserved\r
201 .word DATA_SEL # DS\r
202 .word 0 # Reserved\r
203 .word DATA_SEL # FS\r
204 .word 0 # Reserved\r
205 .word DATA_SEL # GS\r
206 .word 0 # Reserved\r
207 .word 0 # LDT Selector\r
208 .word 0 # Reserved\r
209 .word 0 # T\r
210 .word 0 # I/O Map Base\r
211\r
212ASM_PFX(gcPsd):\r
213 .ascii "PSDSIG "\r
214 .word PSD_SIZE\r
215 .word 2\r
216 .word 1 << 2\r
217 .word CODE_SEL\r
218 .word DATA_SEL\r
219 .word DATA_SEL\r
220 .word DATA_SEL\r
221 .word 0\r
222 .long 0\r
223 .long 0\r
224 .long 0\r
225 .long 0\r
226 .quad 0\r
227 .long NullSeg\r
228 .long 0\r
229 .long GDT_SIZE\r
230 .long 0\r
231 .space 24, 0\r
232 .long ASM_PFX(gSmiMtrrs)\r
233 .long 0\r
234.equ PSD_SIZE, . - ASM_PFX(gcPsd)\r
235\r
236ASM_PFX(gcSmiGdtr): .word GDT_SIZE - 1\r
237 .long NullSeg\r
238\r
239ASM_PFX(gcSmiIdtr): .word IDT_SIZE - 1\r
240 .long _SmiIDT\r
241\r
242_SmiIDT:\r
243# The following segment repeats 32 times:\r
244# No. 1\r
245 .word 0 # Offset 0:15\r
246 .word CODE_SEL\r
247 .byte 0 # Unused\r
248 .byte 0x8e # Interrupt Gate, Present\r
249 .word 0 # Offset 16:31\r
250# No. 2\r
251 .word 0 # Offset 0:15\r
252 .word CODE_SEL\r
253 .byte 0 # Unused\r
254 .byte 0x8e # Interrupt Gate, Present\r
255 .word 0 # Offset 16:31\r
256# No. 3\r
257 .word 0 # Offset 0:15\r
258 .word CODE_SEL\r
259 .byte 0 # Unused\r
260 .byte 0x8e # Interrupt Gate, Present\r
261 .word 0 # Offset 16:31\r
262# No. 4\r
263 .word 0 # Offset 0:15\r
264 .word CODE_SEL\r
265 .byte 0 # Unused\r
266 .byte 0x8e # Interrupt Gate, Present\r
267 .word 0 # Offset 16:31\r
268# No. 5\r
269 .word 0 # Offset 0:15\r
270 .word CODE_SEL\r
271 .byte 0 # Unused\r
272 .byte 0x8e # Interrupt Gate, Present\r
273 .word 0 # Offset 16:31\r
274# No. 6\r
275 .word 0 # Offset 0:15\r
276 .word CODE_SEL\r
277 .byte 0 # Unused\r
278 .byte 0x8e # Interrupt Gate, Present\r
279 .word 0 # Offset 16:31\r
280# No. 7\r
281 .word 0 # Offset 0:15\r
282 .word CODE_SEL\r
283 .byte 0 # Unused\r
284 .byte 0x8e # Interrupt Gate, Present\r
285 .word 0 # Offset 16:31\r
286# No. 8\r
287 .word 0 # Offset 0:15\r
288 .word CODE_SEL\r
289 .byte 0 # Unused\r
290 .byte 0x8e # Interrupt Gate, Present\r
291 .word 0 # Offset 16:31\r
292# No. 9\r
293 .word 0 # Offset 0:15\r
294 .word CODE_SEL\r
295 .byte 0 # Unused\r
296 .byte 0x8e # Interrupt Gate, Present\r
297 .word 0 # Offset 16:31\r
298# No. 10\r
299 .word 0 # Offset 0:15\r
300 .word CODE_SEL\r
301 .byte 0 # Unused\r
302 .byte 0x8e # Interrupt Gate, Present\r
303 .word 0 # Offset 16:31\r
304# No. 11\r
305 .word 0 # Offset 0:15\r
306 .word CODE_SEL\r
307 .byte 0 # Unused\r
308 .byte 0x8e # Interrupt Gate, Present\r
309 .word 0 # Offset 16:31\r
310# No. 12\r
311 .word 0 # Offset 0:15\r
312 .word CODE_SEL\r
313 .byte 0 # Unused\r
314 .byte 0x8e # Interrupt Gate, Present\r
315 .word 0 # Offset 16:31\r
316# No. 13\r
317 .word 0 # Offset 0:15\r
318 .word CODE_SEL\r
319 .byte 0 # Unused\r
320 .byte 0x8e # Interrupt Gate, Present\r
321 .word 0 # Offset 16:31\r
322# No. 14\r
323 .word 0 # Offset 0:15\r
324 .word CODE_SEL\r
325 .byte 0 # Unused\r
326 .byte 0x8e # Interrupt Gate, Present\r
327 .word 0 # Offset 16:31\r
328# No. 15\r
329 .word 0 # Offset 0:15\r
330 .word CODE_SEL\r
331 .byte 0 # Unused\r
332 .byte 0x8e # Interrupt Gate, Present\r
333 .word 0 # Offset 16:31\r
334# No. 16\r
335 .word 0 # Offset 0:15\r
336 .word CODE_SEL\r
337 .byte 0 # Unused\r
338 .byte 0x8e # Interrupt Gate, Present\r
339 .word 0 # Offset 16:31\r
340# No. 17\r
341 .word 0 # Offset 0:15\r
342 .word CODE_SEL\r
343 .byte 0 # Unused\r
344 .byte 0x8e # Interrupt Gate, Present\r
345 .word 0 # Offset 16:31\r
346# No. 18\r
347 .word 0 # Offset 0:15\r
348 .word CODE_SEL\r
349 .byte 0 # Unused\r
350 .byte 0x8e # Interrupt Gate, Present\r
351 .word 0 # Offset 16:31\r
352# No. 19\r
353 .word 0 # Offset 0:15\r
354 .word CODE_SEL\r
355 .byte 0 # Unused\r
356 .byte 0x8e # Interrupt Gate, Present\r
357 .word 0 # Offset 16:31\r
358# No. 20\r
359 .word 0 # Offset 0:15\r
360 .word CODE_SEL\r
361 .byte 0 # Unused\r
362 .byte 0x8e # Interrupt Gate, Present\r
363 .word 0 # Offset 16:31\r
364# No. 21\r
365 .word 0 # Offset 0:15\r
366 .word CODE_SEL\r
367 .byte 0 # Unused\r
368 .byte 0x8e # Interrupt Gate, Present\r
369 .word 0 # Offset 16:31\r
370# No. 22\r
371 .word 0 # Offset 0:15\r
372 .word CODE_SEL\r
373 .byte 0 # Unused\r
374 .byte 0x8e # Interrupt Gate, Present\r
375 .word 0 # Offset 16:31\r
376# No. 23\r
377 .word 0 # Offset 0:15\r
378 .word CODE_SEL\r
379 .byte 0 # Unused\r
380 .byte 0x8e # Interrupt Gate, Present\r
381 .word 0 # Offset 16:31\r
382# No. 24\r
383 .word 0 # Offset 0:15\r
384 .word CODE_SEL\r
385 .byte 0 # Unused\r
386 .byte 0x8e # Interrupt Gate, Present\r
387 .word 0 # Offset 16:31\r
388# No. 25\r
389 .word 0 # Offset 0:15\r
390 .word CODE_SEL\r
391 .byte 0 # Unused\r
392 .byte 0x8e # Interrupt Gate, Present\r
393 .word 0 # Offset 16:31\r
394# No. 26\r
395 .word 0 # Offset 0:15\r
396 .word CODE_SEL\r
397 .byte 0 # Unused\r
398 .byte 0x8e # Interrupt Gate, Present\r
399 .word 0 # Offset 16:31\r
400# No. 27\r
401 .word 0 # Offset 0:15\r
402 .word CODE_SEL\r
403 .byte 0 # Unused\r
404 .byte 0x8e # Interrupt Gate, Present\r
405 .word 0 # Offset 16:31\r
406# No. 28\r
407 .word 0 # Offset 0:15\r
408 .word CODE_SEL\r
409 .byte 0 # Unused\r
410 .byte 0x8e # Interrupt Gate, Present\r
411 .word 0 # Offset 16:31\r
412# No. 29\r
413 .word 0 # Offset 0:15\r
414 .word CODE_SEL\r
415 .byte 0 # Unused\r
416 .byte 0x8e # Interrupt Gate, Present\r
417 .word 0 # Offset 16:31\r
418# No. 30\r
419 .word 0 # Offset 0:15\r
420 .word CODE_SEL\r
421 .byte 0 # Unused\r
422 .byte 0x8e # Interrupt Gate, Present\r
423 .word 0 # Offset 16:31\r
424# No. 31\r
425 .word 0 # Offset 0:15\r
426 .word CODE_SEL\r
427 .byte 0 # Unused\r
428 .byte 0x8e # Interrupt Gate, Present\r
429 .word 0 # Offset 16:31\r
430# No. 32\r
431 .word 0 # Offset 0:15\r
432 .word CODE_SEL\r
433 .byte 0 # Unused\r
434 .byte 0x8e # Interrupt Gate, Present\r
435 .word 0 # Offset 16:31\r
436\r
437.equ IDT_SIZE, . - _SmiIDT\r
438\r
439TaskGateDescriptor:\r
440 .word 0 # Reserved\r
441 .word EXCEPTION_TSS_SEL # TSS Segment selector\r
442 .byte 0 # Reserved\r
443 .byte 0x85 # Task Gate, present, DPL = 0\r
444 .word 0 # Reserved\r
445\r
446 .text\r
447\r
448#------------------------------------------------------------------------------\r
449# PageFaultIdtHandlerSmmProfile is the entry point for all exceptions\r
450#\r
451# Stack:\r
452#+---------------------+\r
453#+ EFlags +\r
454#+---------------------+\r
455#+ CS +\r
456#+---------------------+\r
457#+ EIP +\r
458#+---------------------+\r
459#+ Error Code +\r
460#+---------------------+\r
461#+ Vector Number +\r
462#+---------------------+\r
463#+ EBP +\r
464#+---------------------+ <-- EBP\r
465#\r
466# RSP set to odd multiple of 8 means ErrCode PRESENT\r
467#------------------------------------------------------------------------------\r
468ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)\r
469ASM_PFX(PageFaultIdtHandlerSmmProfile):\r
470 pushl $0x0e # Page Fault\r
471 pushl %ebp\r
472 movl %esp, %ebp\r
473\r
474\r
475 #\r
476 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
477 # is 16-byte aligned\r
478 #\r
479 andl $0xfffffff0, %esp\r
480 subl $12, %esp\r
481\r
482## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
483 pushl %eax\r
484 pushl %ecx\r
485 pushl %edx\r
486 pushl %ebx\r
487 leal (6*4)(%ebp), %ecx\r
488 pushl %ecx # ESP\r
489 pushl (%ebp) # EBP\r
490 pushl %esi\r
491 pushl %edi\r
492\r
493## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
494 movl %ss, %eax\r
495 pushl %eax\r
496 movzwl (4*4)(%ebp), %eax\r
497 pushl %eax\r
498 movl %ds, %eax\r
499 pushl %eax\r
500 movl %es, %eax\r
501 pushl %eax\r
502 movl %fs, %eax\r
503 pushl %eax\r
504 movl %gs, %eax\r
505 pushl %eax\r
506\r
507## UINT32 Eip;\r
508 movl (3*4)(%ebp), %eax\r
509 pushl %eax\r
510\r
511## UINT32 Gdtr[2], Idtr[2];\r
512 subl $8, %esp\r
513 sidt (%esp)\r
514 movl 2(%esp), %eax\r
515 xchgl (%esp), %eax\r
516 andl $0xffff, %eax\r
517 movl %eax, 4(%esp)\r
518\r
519 subl $8, %esp\r
520 sgdt (%esp)\r
521 movl 2(%esp), %eax\r
522 xchgl (%esp), %eax\r
523 andl $0xffff, %eax\r
524 movl %eax, 4(%esp)\r
525\r
526## UINT32 Ldtr, Tr;\r
527 xorl %eax, %eax\r
528 strw %ax\r
529 pushl %eax\r
530 sldtw %ax\r
531 pushl %eax\r
532\r
533## UINT32 EFlags;\r
534 movl (5*4)(%ebp), %eax\r
535 pushl %eax\r
536\r
537## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
538 movl %cr4, %eax\r
539 orl $0x208, %eax\r
540 movl %eax, %cr4\r
541 pushl %eax\r
542 movl %cr3, %eax\r
543 pushl %eax\r
544 movl %cr2, %eax\r
545 pushl %eax\r
546 xorl %eax, %eax\r
547 pushl %eax\r
548 movl %cr0, %eax\r
549 pushl %eax\r
550\r
551## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
552 movl %dr7, %eax\r
553 pushl %eax\r
554 movl %dr6, %eax\r
555 pushl %eax\r
556 movl %dr3, %eax\r
557 pushl %eax\r
558 movl %dr2, %eax\r
559 pushl %eax\r
560 movl %dr1, %eax\r
561 pushl %eax\r
562 movl %dr0, %eax\r
563 pushl %eax\r
564\r
565## FX_SAVE_STATE_IA32 FxSaveState;\r
566 subl $512, %esp\r
567 movl %esp, %edi\r
568 .byte 0x0f, 0xae, 0x07 #fxsave [edi]\r
569\r
570# UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
571 cld\r
572\r
573## UINT32 ExceptionData;\r
574 pushl (2*4)(%ebp)\r
575\r
576## call into exception handler\r
577\r
578## Prepare parameter and call\r
579 movl %esp, %edx\r
580 pushl %edx\r
581 movl (1*4)(%ebp), %edx\r
582 pushl %edx\r
583\r
584 #\r
585 # Call External Exception Handler\r
586 #\r
587 movl $ASM_PFX(SmiPFHandler), %eax\r
588 call *%eax\r
589 addl $8, %esp\r
590 jmp L4\r
591\r
592L4:\r
593## UINT32 ExceptionData;\r
594 addl $4, %esp\r
595\r
596## FX_SAVE_STATE_IA32 FxSaveState;\r
597 movl %esp, %esi\r
598 .byte 0xf, 0xae, 0xe # fxrstor [esi]\r
599 addl $512, %esp\r
600\r
601## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
602## Skip restoration of DRx registers to support debuggers\r
603## that set breakpoints in interrupt/exception context\r
604 addl $4*6, %esp\r
605\r
606## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
607 popl %eax\r
608 movl %eax, %cr0\r
609 addl $4, %esp # not for Cr1\r
610 popl %eax\r
611 movl %eax, %cr2\r
612 popl %eax\r
613 movl %eax, %cr3\r
614 popl %eax\r
615 movl %eax, %cr4\r
616\r
617## UINT32 EFlags;\r
618 popl (5*4)(%ebp)\r
619\r
620## UINT32 Ldtr, Tr;\r
621## UINT32 Gdtr[2], Idtr[2];\r
622## Best not let anyone mess with these particular registers...\r
623 addl $24, %esp\r
624\r
625## UINT32 Eip;\r
626 popl (3*4)(%ebp)\r
627\r
628## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
629## NOTE - modified segment registers could hang the debugger... We\r
630## could attempt to insulate ourselves against this possibility,\r
631## but that poses risks as well.\r
632##\r
633 popl %gs\r
634 popl %fs\r
635 popl %es\r
636 popl %ds\r
637 popl (4*4)(%ebp)\r
638 popl %ss\r
639\r
640## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
641 popl %edi\r
642 popl %esi\r
643 addl $4, %esp # not for ebp\r
644 addl $4, %esp # not for esp\r
645 popl %ebx\r
646 popl %edx\r
647 popl %ecx\r
648 popl %eax\r
649\r
650 movl %ebp, %esp\r
651 popl %ebp\r
652\r
653# Enable TF bit after page fault handler runs\r
654 btsl $8, 16(%esp) # EFLAGS\r
655\r
656 addl $8, %esp # skip INT# & ErrCode\r
657Return:\r
658 iret\r
659#\r
660# Page Fault Exception Handler entry when SMM Stack Guard is enabled\r
661# Executiot starts here after a task switch\r
662#\r
663PFHandlerEntry:\r
664#\r
665# Get this processor's TSS\r
666#\r
667 subl $8, %esp\r
668 sgdt 2(%esp)\r
669 movl 4(%esp), %eax # GDT base\r
670 addl $8, %esp\r
671 movl (TSS_SEL+2)(%eax), %ecx\r
672 shll $8, %ecx\r
673 movb (TSS_SEL+7)(%eax), %cl\r
674 rorl $8, %ecx # ecx = TSS base\r
675\r
676 movl %esp, %ebp\r
677\r
678 #\r
679 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
680 # is 16-byte aligned\r
681 #\r
682 andl $0xfffffff0, %esp\r
683 subl $12, %esp\r
684\r
685## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
686 pushl TSS_EAX(%ecx)\r
687 pushl TSS_ECX(%ecx)\r
688 pushl TSS_EDX(%ecx)\r
689 pushl TSS_EBX(%ecx)\r
690 pushl TSS_ESP(%ecx)\r
691 pushl TSS_EBP(%ecx)\r
692 pushl TSS_ESI(%ecx)\r
693 pushl TSS_EDI(%ecx)\r
694\r
695## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
696 movzwl TSS_SS(%ecx), %eax\r
697 pushl %eax\r
698 movzwl TSS_CS(%ecx), %eax\r
699 pushl %eax\r
700 movzwl TSS_DS(%ecx), %eax\r
701 pushl %eax\r
702 movzwl TSS_ES(%ecx), %eax\r
703 pushl %eax\r
704 movzwl TSS_FS(%ecx), %eax\r
705 pushl %eax\r
706 movzwl TSS_GS(%ecx), %eax\r
707 pushl %eax\r
708\r
709## UINT32 Eip;\r
710 pushl TSS_EIP(%ecx)\r
711\r
712## UINT32 Gdtr[2], Idtr[2];\r
713 subl $8, %esp\r
714 sidt (%esp)\r
715 movl 2(%esp), %eax\r
716 xchgl (%esp), %eax\r
717 andl $0xFFFF, %eax\r
718 movl %eax, 4(%esp)\r
719\r
720 subl $8, %esp\r
721 sgdt (%esp)\r
722 movl 2(%esp), %eax\r
723 xchgl (%esp), %eax\r
724 andl $0xFFFF, %eax\r
725 movl %eax, 4(%esp)\r
726\r
727## UINT32 Ldtr, Tr;\r
728 movl $TSS_SEL, %eax\r
729 pushl %eax\r
730 movzwl TSS_LDT(%ecx), %eax\r
731 pushl %eax\r
732\r
733## UINT32 EFlags;\r
734 pushl TSS_EFLAGS(%ecx)\r
735\r
736## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
737 movl %cr4, %eax\r
738 orl $0x208, %eax\r
739 movl %eax, %cr4\r
740 pushl %eax\r
741 movl %cr3, %eax\r
742 pushl %eax\r
743 movl %cr2, %eax\r
744 pushl %eax\r
745 xorl %eax, %eax\r
746 pushl %eax\r
747 movl %cr0, %eax\r
748 pushl %eax\r
749\r
750## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
751 movl %dr7, %eax\r
752 pushl %eax\r
753 movl %dr6, %eax\r
754 pushl %eax\r
755 movl %dr3, %eax\r
756 pushl %eax\r
757 movl %dr2, %eax\r
758 pushl %eax\r
759 movl %dr1, %eax\r
760 pushl %eax\r
761 movl %dr0, %eax\r
762 pushl %eax\r
763\r
764## FX_SAVE_STATE_IA32 FxSaveState;\r
765## Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)\r
766## when executing fxsave/fxrstor instruction\r
767 clts\r
768 subl $512, %esp\r
769 movl %esp, %edi\r
770 .byte 0x0f, 0xae, 0x07 #fxsave [edi]\r
771\r
772# UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
773 cld\r
774\r
775## UINT32 ExceptionData;\r
776 pushl (%ebp)\r
777\r
778## call into exception handler\r
779 movl %ecx, %ebx\r
780 movl $ASM_PFX(SmiPFHandler), %eax\r
781\r
782## Prepare parameter and call\r
783 movl %esp, %edx\r
784 pushl %edx\r
785 movl $14, %edx\r
786 pushl %edx\r
787\r
788 #\r
789 # Call External Exception Handler\r
790 #\r
791 call *%eax\r
792 addl $8, %esp\r
793\r
794 movl %ebx, %ecx\r
795## UINT32 ExceptionData;\r
796 addl $4, %esp\r
797\r
798## FX_SAVE_STATE_IA32 FxSaveState;\r
799 movl %esp, %esi\r
800 .byte 0xf, 0xae, 0xe # fxrstor [esi]\r
801 addl $512, %esp\r
802\r
803## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
804## Skip restoration of DRx registers to support debuggers\r
805## that set breakpoints in interrupt/exception context\r
806 addl $4*6, %esp\r
807\r
808## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
809 popl %eax\r
810 movl %eax, %cr0\r
811 addl $4, %esp # not for Cr1\r
812 popl %eax\r
813 movl %eax, %cr2\r
814 popl %eax\r
815 movl %eax, TSS_CR3(%ecx)\r
816 popl %eax\r
817 movl %eax, %cr4\r
818\r
819## UINT32 EFlags;\r
820 popl TSS_EFLAGS(%ecx)\r
821\r
822## UINT32 Ldtr, Tr;\r
823## UINT32 Gdtr[2], Idtr[2];\r
824## Best not let anyone mess with these particular registers...\r
825 addl $24, %esp\r
826\r
827## UINT32 Eip;\r
828 popl TSS_EIP(%ecx)\r
829\r
830## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
831## NOTE - modified segment registers could hang the debugger... We\r
832## could attempt to insulate ourselves against this possibility,\r
833## but that poses risks as well.\r
834##\r
835 popl %eax\r
836 movw %ax, TSS_GS(%ecx)\r
837 popl %eax\r
838 movw %ax, TSS_FS(%ecx)\r
839 popl %eax\r
840 movw %ax, TSS_ES(%ecx)\r
841 popl %eax\r
842 movw %ax, TSS_DS(%ecx)\r
843 popl %eax\r
844 movw %ax, TSS_CS(%ecx)\r
845 popl %eax\r
846 movw %ax, TSS_SS(%ecx)\r
847\r
848## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
849 popl TSS_EDI(%ecx)\r
850 popl TSS_ESI(%ecx)\r
851 addl $4, %esp # not for ebp\r
852 addl $4, %esp # not for esp\r
853 popl TSS_EBX(%ecx)\r
854 popl TSS_EDX(%ecx)\r
855 popl TSS_ECX(%ecx)\r
856 popl TSS_EAX(%ecx)\r
857\r
858 movl %ebp, %esp\r
859\r
860# Set single step DB# if SMM profile is enabled and page fault exception happens\r
861 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))\r
862 jz Done2\r
863# Create return context for iret in stub function\r
864 movl TSS_ESP(%ecx), %eax # Get old stack pointer\r
865 movl TSS_EIP(%ecx), %ebx\r
866 movl %ebx, -0xc(%eax) # create EIP in old stack\r
867 movzwl TSS_CS(%ecx), %ebx\r
868 movl %ebx, -0x8(%eax) # create CS in old stack\r
869 movl TSS_EFLAGS(%ecx), %ebx\r
870 btsl $8,%ebx\r
871 movl %ebx, -0x4(%eax) # create eflags in old stack\r
872 movl TSS_ESP(%ecx), %eax # Get old stack pointer\r
873 subl $12, %eax # minus 12 byte\r
874 movl %eax, TSS_ESP(%ecx) # Set new stack pointer\r
875\r
876# Replace the EIP of interrupted task with stub function\r
877 movl $ASM_PFX(PageFaultStubFunction), %eax\r
878 movl %eax, TSS_EIP(%ecx)\r
879# Jump to the iret so next page fault handler as a task will start again after iret.\r
880\r
881Done2:\r
882\r
883 addl $4, %esp # skip ErrCode\r
884\r
885 jmp Return\r
886\r
887ASM_PFX(PageFaultStubFunction):\r
888#\r
889# we need clean TS bit in CR0 to execute\r
890# x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.\r
891#\r
892 clts\r
893 iret\r
894\r
895ASM_GLOBAL ASM_PFX(InitializeIDTSmmStackGuard)\r
896ASM_PFX(InitializeIDTSmmStackGuard):\r
897 pushl %ebx\r
898#\r
899# If SMM Stack Guard feature is enabled, the Page Fault Exception entry in IDT\r
900# is a Task Gate Descriptor so that when a Page Fault Exception occurs,\r
901# the processors can use a known good stack in case stack ran out.\r
902#\r
903 leal _SmiIDT + 14 * 8, %ebx\r
904 leal TaskGateDescriptor, %edx\r
905 movl (%edx), %eax\r
906 movl %eax, (%ebx)\r
907 movl 4(%edx), %eax\r
908 movl %eax, 4(%ebx)\r
909\r
910 popl %ebx\r
911 ret\r