1 #------------------------------------------------------------------------------
3 # Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
4 # This program and the accompanying materials
5 # are licensed and made available under the terms and conditions of the BSD License
6 # which accompanies this distribution. The full text of the license may be found at
7 # http://opensource.org/licenses/bsd-license.php.
9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 # Exception handlers used in SM mode
20 #------------------------------------------------------------------------------
22 ASM_GLOBAL ASM_PFX(SmiPFHandler)
23 ASM_GLOBAL ASM_PFX(gcSmiIdtr)
24 ASM_GLOBAL ASM_PFX(gcSmiGdtr)
25 ASM_GLOBAL ASM_PFX(gcPsd)
29 NullSeg: .quad 0 # reserved by architecture
35 .byte 0xcf # LimitHigh
42 .byte 0xcf # LimitHigh
49 .byte 0xcf # LimitHigh
56 .byte 0xcf # LimitHigh
77 .byte 0xaf # LimitHigh
79 # TSS Segment for X64 specially
81 .word TSS_DESC_SIZE - 1 # LimitLow
85 .byte 0x00 # LimitHigh
89 .equ GDT_SIZE, .- NullSeg
93 .equ TSS_DESC_SIZE, .- TssDescriptor
96 # This structure serves as a template for all processors.
110 .quad 0 # fixed in InitializeMpServiceData()
116 .equ PSD_SIZE, . - ASM_PFX(gcPsd)
119 # CODE & DATA segments for SMM runtime
121 .equ CODE_SEL, CodeSeg64 - NullSeg
122 .equ DATA_SEL, DataSeg32 - NullSeg
123 .equ CODE32_SEL, CodeSeg32 - NullSeg
135 #------------------------------------------------------------------------------
136 # _SmiExceptionEntryPoints is the collection of exception entry points followed
137 # by a common exception handler.
139 # Stack frame would be as follows as specified in IA32 manuals:
140 # +---------------------+ <-- 16-byte aligned ensured by processor
142 # +---------------------+
144 # +---------------------+
146 # +---------------------+
148 # +---------------------+
150 # +---------------------+
152 # +---------------------+
154 # +---------------------+
156 # +---------------------+ <-- RBP, 16-byte aligned
158 # RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT
159 #------------------------------------------------------------------------------
160 ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)
161 ASM_PFX(PageFaultIdtHandlerSmmProfile):
162 pushq $0x0e # Page Fault
163 .byte 0x40, 0xf6, 0xc4, 0x08 #test spl, 8
172 # Since here the stack pointer is 16-byte aligned, so
173 # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
177 ## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
178 ## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
196 ## UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
197 movzwq 56(%rbp), %rax
199 movzwq 32(%rbp), %rax
213 ## UINT64 Gdtr[2], Idtr[2];
229 ## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
245 ## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
259 ## FX_SAVE_STATE_X64 FxSaveState;
263 .byte 0xf, 0xae, 0x7 # fxsave [rdi]
265 # UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
268 ## UINT32 ExceptionData;
271 ## call into exception handler
273 movabsq $ASM_PFX(SmiPFHandler), %rax
275 ## Prepare parameter and call
278 # Per X64 calling convention, allocate maximum parameter stack space
279 # and make sure RSP is 16-byte aligned
281 subq $4 * 8 + 8, %rsp
283 addq $4 * 8 + 8, %rsp
287 ## UINT64 ExceptionData;
290 ## FX_SAVE_STATE_X64 FxSaveState;
293 .byte 0xf, 0xae, 0xe # fxrstor [rsi]
296 ## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
297 ## Skip restoration of DRx registers to support debuggers
298 ## that set breakpoints in interrupt/exception context
301 ## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
304 addq $8, %rsp # not for Cr1
318 ## UINT64 Gdtr[2], Idtr[2];
319 ## Best not let anyone mess with these particular registers...
325 ## UINT64 Gs, Fs, Es, Ds, Cs, Ss;
327 # mov gs, rax ; not for gs
329 # mov fs, rax ; not for fs
330 # (X64 will not use fs and gs, so we do not restore it)
335 popq 32(%rbp) # for cs
336 popq 56(%rbp) # for ss
338 ## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
339 ## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
342 addq $8, %rsp # not for rbp
343 popq 48(%rbp) # for rsp
359 # Enable TF bit after page fault handler runs
360 btsl $8, 40(%rsp) #RFLAGS
363 addq $16, %rsp # skip INT# & ErrCode