1 #------------------------------------------------------------------------------
3 # Copyright (c) 2009 - 2015, 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(gSmiMtrrs)
24 ASM_GLOBAL ASM_PFX(gcSmiIdtr)
25 ASM_GLOBAL ASM_PFX(gcSmiGdtr)
26 ASM_GLOBAL ASM_PFX(gcPsd)
30 NullSeg: .quad 0 # reserved by architecture
36 .byte 0xcf # LimitHigh
43 .byte 0xcf # LimitHigh
50 .byte 0xcf # LimitHigh
57 .byte 0xcf # LimitHigh
78 .byte 0xaf # LimitHigh
80 # TSS Segment for X64 specially
82 .word TSS_DESC_SIZE # LimitLow
86 .byte 0xDB # LimitHigh
90 .equ GDT_SIZE, .- NullSeg
94 .equ TSS_DESC_SIZE, .- TssDescriptor
97 # This structure serves as a template for all processors.
111 .quad 0 # fixed in InitializeMpServiceData()
116 .quad ASM_PFX(gSmiMtrrs)
117 .equ PSD_SIZE, . - ASM_PFX(gcPsd)
120 # CODE & DATA segments for SMM runtime
122 .equ CODE_SEL, CodeSeg64 - NullSeg
123 .equ DATA_SEL, DataSeg32 - NullSeg
124 .equ CODE32_SEL, CodeSeg32 - NullSeg
136 # Here is the IDT. There are 32 (not 255) entries in it since only processor
137 # generated exceptions will be handled.
140 # The following segment repeats 32 times:
142 .word 0 # Offset 0:15
145 .byte 0x8e # Interrupt Gate, Present
146 .word 0 # Offset 16:31
147 .quad 0 # Offset 32:63
149 .word 0 # Offset 0:15
152 .byte 0x8e # Interrupt Gate, Present
153 .word 0 # Offset 16:31
154 .quad 0 # Offset 32:63
156 .word 0 # Offset 0:15
159 .byte 0x8e # Interrupt Gate, Present
160 .word 0 # Offset 16:31
161 .quad 0 # Offset 32:63
163 .word 0 # Offset 0:15
166 .byte 0x8e # Interrupt Gate, Present
167 .word 0 # Offset 16:31
168 .quad 0 # Offset 32:63
170 .word 0 # Offset 0:15
173 .byte 0x8e # Interrupt Gate, Present
174 .word 0 # Offset 16:31
175 .quad 0 # Offset 32:63
177 .word 0 # Offset 0:15
180 .byte 0x8e # Interrupt Gate, Present
181 .word 0 # Offset 16:31
182 .quad 0 # Offset 32:63
184 .word 0 # Offset 0:15
187 .byte 0x8e # Interrupt Gate, Present
188 .word 0 # Offset 16:31
189 .quad 0 # Offset 32:63
191 .word 0 # Offset 0:15
194 .byte 0x8e # Interrupt Gate, Present
195 .word 0 # Offset 16:31
196 .quad 0 # Offset 32:63
198 .word 0 # Offset 0:15
201 .byte 0x8e # Interrupt Gate, Present
202 .word 0 # Offset 16:31
203 .quad 0 # Offset 32:63
205 .word 0 # Offset 0:15
208 .byte 0x8e # Interrupt Gate, Present
209 .word 0 # Offset 16:31
210 .quad 0 # Offset 32:63
212 .word 0 # Offset 0:15
215 .byte 0x8e # Interrupt Gate, Present
216 .word 0 # Offset 16:31
217 .quad 0 # Offset 32:63
219 .word 0 # Offset 0:15
222 .byte 0x8e # Interrupt Gate, Present
223 .word 0 # Offset 16:31
224 .quad 0 # Offset 32:63
226 .word 0 # Offset 0:15
229 .byte 0x8e # Interrupt Gate, Present
230 .word 0 # Offset 16:31
231 .quad 0 # Offset 32:63
233 .word 0 # Offset 0:15
236 .byte 0x8e # Interrupt Gate, Present
237 .word 0 # Offset 16:31
238 .quad 0 # Offset 32:63
240 .word 0 # Offset 0:15
243 .byte 0x8e # Interrupt Gate, Present
244 .word 0 # Offset 16:31
245 .quad 0 # Offset 32:63
247 .word 0 # Offset 0:15
250 .byte 0x8e # Interrupt Gate, Present
251 .word 0 # Offset 16:31
252 .quad 0 # Offset 32:63
254 .word 0 # Offset 0:15
257 .byte 0x8e # Interrupt Gate, Present
258 .word 0 # Offset 16:31
259 .quad 0 # Offset 32:63
261 .word 0 # Offset 0:15
264 .byte 0x8e # Interrupt Gate, Present
265 .word 0 # Offset 16:31
266 .quad 0 # Offset 32:63
268 .word 0 # Offset 0:15
271 .byte 0x8e # Interrupt Gate, Present
272 .word 0 # Offset 16:31
273 .quad 0 # Offset 32:63
275 .word 0 # Offset 0:15
278 .byte 0x8e # Interrupt Gate, Present
279 .word 0 # Offset 16:31
280 .quad 0 # Offset 32:63
282 .word 0 # Offset 0:15
285 .byte 0x8e # Interrupt Gate, Present
286 .word 0 # Offset 16:31
287 .quad 0 # Offset 32:63
289 .word 0 # Offset 0:15
292 .byte 0x8e # Interrupt Gate, Present
293 .word 0 # Offset 16:31
294 .quad 0 # Offset 32:63
296 .word 0 # Offset 0:15
299 .byte 0x8e # Interrupt Gate, Present
300 .word 0 # Offset 16:31
301 .quad 0 # Offset 32:63
303 .word 0 # Offset 0:15
306 .byte 0x8e # Interrupt Gate, Present
307 .word 0 # Offset 16:31
308 .quad 0 # Offset 32:63
310 .word 0 # Offset 0:15
313 .byte 0x8e # Interrupt Gate, Present
314 .word 0 # Offset 16:31
315 .quad 0 # Offset 32:63
317 .word 0 # Offset 0:15
320 .byte 0x8e # Interrupt Gate, Present
321 .word 0 # Offset 16:31
322 .quad 0 # Offset 32:63
324 .word 0 # Offset 0:15
327 .byte 0x8e # Interrupt Gate, Present
328 .word 0 # Offset 16:31
329 .quad 0 # Offset 32:63
331 .word 0 # Offset 0:15
334 .byte 0x8e # Interrupt Gate, Present
335 .word 0 # Offset 16:31
336 .quad 0 # Offset 32:63
338 .word 0 # Offset 0:15
341 .byte 0x8e # Interrupt Gate, Present
342 .word 0 # Offset 16:31
343 .quad 0 # Offset 32:63
345 .word 0 # Offset 0:15
348 .byte 0x8e # Interrupt Gate, Present
349 .word 0 # Offset 16:31
350 .quad 0 # Offset 32:63
352 .word 0 # Offset 0:15
355 .byte 0x8e # Interrupt Gate, Present
356 .word 0 # Offset 16:31
357 .quad 0 # Offset 32:63
359 .word 0 # Offset 0:15
362 .byte 0x8e # Interrupt Gate, Present
363 .word 0 # Offset 16:31
364 .quad 0 # Offset 32:63
368 .equ IDT_SIZE, (_SmiIDTEnd - _SmiIDT)
372 #------------------------------------------------------------------------------
373 # _SmiExceptionEntryPoints is the collection of exception entry points followed
374 # by a common exception handler.
376 # Stack frame would be as follows as specified in IA32 manuals:
377 # +---------------------+ <-- 16-byte aligned ensured by processor
379 # +---------------------+
381 # +---------------------+
383 # +---------------------+
385 # +---------------------+
387 # +---------------------+
389 # +---------------------+
391 # +---------------------+
393 # +---------------------+ <-- RBP, 16-byte aligned
395 # RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT
396 #------------------------------------------------------------------------------
397 ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)
398 ASM_PFX(PageFaultIdtHandlerSmmProfile):
399 pushq $0x0e # Page Fault
400 .byte 0x40, 0xf6, 0xc4, 0x08 #test spl, 8
409 # Since here the stack pointer is 16-byte aligned, so
410 # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
414 ## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
415 ## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
433 ## UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
434 movzwq 56(%rbp), %rax
436 movzwq 32(%rbp), %rax
450 ## UINT64 Gdtr[2], Idtr[2];
466 ## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
482 ## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
496 ## FX_SAVE_STATE_X64 FxSaveState;
500 .byte 0xf, 0xae, 0x7 # fxsave [rdi]
502 # UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
505 ## UINT32 ExceptionData;
508 ## call into exception handler
510 movabsq $ASM_PFX(SmiPFHandler), %rax
512 ## Prepare parameter and call
515 # Per X64 calling convention, allocate maximum parameter stack space
516 # and make sure RSP is 16-byte aligned
518 subq $4 * 8 + 8, %rsp
520 addq $4 * 8 + 8, %rsp
524 ## UINT64 ExceptionData;
527 ## FX_SAVE_STATE_X64 FxSaveState;
530 .byte 0xf, 0xae, 0xe # fxrstor [rsi]
533 ## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
534 ## Skip restoration of DRx registers to support debuggers
535 ## that set breakpoints in interrupt/exception context
538 ## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
541 addq $8, %rsp # not for Cr1
555 ## UINT64 Gdtr[2], Idtr[2];
556 ## Best not let anyone mess with these particular registers...
562 ## UINT64 Gs, Fs, Es, Ds, Cs, Ss;
564 # mov gs, rax ; not for gs
566 # mov fs, rax ; not for fs
567 # (X64 will not use fs and gs, so we do not restore it)
572 popq 32(%rbp) # for cs
573 popq 56(%rbp) # for ss
575 ## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
576 ## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
579 addq $8, %rsp # not for rbp
580 popq 48(%rbp) # for rsp
596 # Enable TF bit after page fault handler runs
597 btsl $8, 40(%rsp) #RFLAGS
600 addq $16, %rsp # skip INT# & ErrCode
603 ASM_GLOBAL ASM_PFX(InitializeIDTSmmStackGuard)
604 ASM_PFX(InitializeIDTSmmStackGuard):
605 # If SMM Stack Guard feature is enabled, set the IST field of
606 # the interrupt gate for Page Fault Exception to be 1
608 movabsq $_SmiIDT + 14 * 16, %rax