1 #------------------------------------------------------------------------------ ;
2 # Copyright (c) 2012, 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.
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.
13 # ExceptionHandlerAsm.S
17 # x64 CPU Exception Handler
21 #------------------------------------------------------------------------------
24 #EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
26 ASM_GLOBAL ASM_PFX(CommonExceptionHandler)
27 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
33 # point to the external interrupt vector table
37 jmp ASM_PFX(CommonInterruptEntry)
40 jmp ASM_PFX(CommonInterruptEntry)
43 jmp ASM_PFX(CommonInterruptEntry)
46 jmp ASM_PFX(CommonInterruptEntry)
49 jmp ASM_PFX(CommonInterruptEntry)
52 jmp ASM_PFX(CommonInterruptEntry)
55 jmp ASM_PFX(CommonInterruptEntry)
58 jmp ASM_PFX(CommonInterruptEntry)
61 jmp ASM_PFX(CommonInterruptEntry)
64 jmp ASM_PFX(CommonInterruptEntry)
67 jmp ASM_PFX(CommonInterruptEntry)
70 jmp ASM_PFX(CommonInterruptEntry)
73 jmp ASM_PFX(CommonInterruptEntry)
76 jmp ASM_PFX(CommonInterruptEntry)
79 jmp ASM_PFX(CommonInterruptEntry)
82 jmp ASM_PFX(CommonInterruptEntry)
85 jmp ASM_PFX(CommonInterruptEntry)
88 jmp ASM_PFX(CommonInterruptEntry)
91 jmp ASM_PFX(CommonInterruptEntry)
94 jmp ASM_PFX(CommonInterruptEntry)
97 jmp ASM_PFX(CommonInterruptEntry)
100 jmp ASM_PFX(CommonInterruptEntry)
103 jmp ASM_PFX(CommonInterruptEntry)
106 jmp ASM_PFX(CommonInterruptEntry)
109 jmp ASM_PFX(CommonInterruptEntry)
112 jmp ASM_PFX(CommonInterruptEntry)
115 jmp ASM_PFX(CommonInterruptEntry)
118 jmp ASM_PFX(CommonInterruptEntry)
121 jmp ASM_PFX(CommonInterruptEntry)
124 jmp ASM_PFX(CommonInterruptEntry)
127 jmp ASM_PFX(CommonInterruptEntry)
130 jmp ASM_PFX(CommonInterruptEntry)
133 #---------------------------------------;
134 # CommonInterruptEntry ;
135 #---------------------------------------;
136 # The follow algorithm is used for the common interrupt routine.
138 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
139 ASM_PFX(CommonInterruptEntry):
142 # All interrupt handlers are invoked through interrupt gates, so
143 # IF flag automatically cleared at the entry point
146 # Calculate vector number
148 xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.
149 cmp $32, %ecx # Intel reserved vector for exceptions?
152 leaq ASM_PFX(mErrorCodeFlag)(%rip), %rax
155 jc CommonInterruptEntry_al_0000
160 # Push a dummy error code on the stack
161 # to maintain coherent stack map
165 CommonInterruptEntry_al_0000:
171 # +---------------------+ <-- 16-byte aligned ensured by processor
173 # +---------------------+
175 # +---------------------+
177 # +---------------------+
179 # +---------------------+
181 # +---------------------+
183 # +---------------------+
184 # + RCX / Vector Number +
185 # +---------------------+
187 # +---------------------+ <-- RBP, 16-byte aligned
192 # Since here the stack pointer is 16-byte aligned, so
193 # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
197 #; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
198 #; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
216 #; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
217 movzwq 56(%rbp), %rax
219 movzwq 32(%rbp), %rax
230 movq %rcx, 8(%rbp) # save vector number
235 #; UINT64 Gdtr[2], Idtr[2];
262 #; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
278 #; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
292 #; FX_SAVE_STATE_X64 FxSaveState;
295 .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]
297 #; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
300 #; UINT32 ExceptionData;
303 #; Prepare parameter and call
307 # Per X64 calling convention, allocate maximum parameter stack space
308 # and make sure RSP is 16-byte aligned
311 call ASM_PFX(CommonExceptionHandler)
315 #; UINT64 ExceptionData;
318 #; FX_SAVE_STATE_X64 FxSaveState;
321 .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi]
324 #; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
325 #; Skip restoration of DRx registers to support in-circuit emualators
326 #; or debuggers set breakpoint in interrupt/exception context
329 #; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
332 addq $8, %rsp # not for Cr1
346 #; UINT64 Gdtr[2], Idtr[2];
347 #; Best not let anyone mess with these particular registers...
353 #; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
355 # mov %rax, %gs ; not for gs
357 # mov %rax, %fs ; not for fs
358 # (X64 will not use fs and gs, so we do not restore it)
363 popq 32(%rbp) # for cs
364 popq 56(%rbp) # for ss
366 #; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
367 #; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
370 addq $8, %rsp # not for rbp
371 popq 48(%rbp) # for rsp
391 #-------------------------------------------------------------------------------------
392 # AsmGetAddressMap (&AddressMap);
393 #-------------------------------------------------------------------------------------
394 # comments here for definition of address map
395 ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)
396 ASM_PFX(GetTemplateAddressMap):
398 movabsq $Exception0Handle, %rax
400 movq $(Exception1Handle - Exception0Handle), 0x08(%rcx)