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