3 #------------------------------------------------------------------------------
5 #* Copyright 2008 - 2009, Intel Corporation
6 #* All rights reserved. This program and the accompanying materials
7 #* are licensed and made available under the terms and conditions of the BSD License
8 #* which accompanies this distribution. The full text of the license may be found at
9 #* http://opensource.org/licenses/bsd-license.php
11 #* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 #* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #------------------------------------------------------------------------------
24 #EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
28 # point to the external interrupt vector table
30 ExternalVectorTablePtr:
31 .byte 0, 0, 0, 0, 0, 0, 0, 0
34 ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
35 ASM_PFX(InitializeExternalVectorTablePtr):
36 lea %rax, [%rip+ExternalVectorTablePtr] # save vector number
41 #------------------------------------------------------------------------------
46 #------------------------------------------------------------------------------
48 ASM_GLOBAL ASM_PFX(SetCodeSelector)
49 ASM_PFX(SetCodeSelector):
51 lea %rax, [%rip+setCodeSelectorLongJump]
55 setCodeSelectorLongJump:
59 #------------------------------------------------------------------------------
64 #------------------------------------------------------------------------------
66 ASM_GLOBAL ASM_PFX(SetDataSelectors)
67 ASM_PFX(SetDataSelectors):
75 #---------------------------------------;
76 # CommonInterruptEntry ;
77 #---------------------------------------;
78 # The follow algorithm is used for the common interrupt routine.
81 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
82 ASM_PFX(CommonInterruptEntry):
85 # All interrupt handlers are invoked through interrupt gates, so
86 # IF flag automatically cleared at the entry point
89 # Calculate vector number
91 xchg %rcx, [%rsp] # get the return address of call, actually, it is the address of vector number.
92 movzx %ecx, word ptr [%rcx]
93 cmp %ecx, 32 # Intel reserved vector for exceptions?
96 lea %rax, [%rip+ASM_PFX(mErrorCodeFlag)]
97 bt dword ptr [%rax], %ecx
99 jc CommonInterruptEntry_al_0000
104 # Push a dummy error code on the stack
105 # to maintain coherent stack map
108 mov qword ptr [%rsp + 8], 0
109 CommonInterruptEntry_al_0000:
115 # +---------------------+ <-- 16-byte aligned ensured by processor
117 # +---------------------+
119 # +---------------------+
121 # +---------------------+
123 # +---------------------+
125 # +---------------------+
127 # +---------------------+
128 # + RCX / Vector Number +
129 # +---------------------+
131 # +---------------------+ <-- RBP, 16-byte aligned
136 # Since here the stack pointer is 16-byte aligned, so
137 # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
141 #; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
142 #; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
152 push qword ptr [%rbp + 8] # RCX
155 push qword ptr [%rbp + 48] # RSP
156 push qword ptr [%rbp] # RBP
160 #; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
161 movzx %rax, word ptr [%rbp + 56]
163 movzx %rax, word ptr [%rbp + 32]
174 mov [%rbp + 8], %rcx # save vector number
177 push qword ptr [%rbp + 24]
179 #; UINT64 Gdtr[2], Idtr[2];
184 xchg %rax, [%rsp + 2]
186 xchg %rax, [%rsp + 8]
192 xchg %rax, [%rsp + 2]
194 xchg %rax, [%rsp + 8]
204 push qword ptr [%rbp + 40]
206 #; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
222 #; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
225 #; clear Dr7 while executing debugger itself
231 #; insure all status bits in dr6 are clear...
244 #; FX_SAVE_STATE_X64 FxSaveState;
247 .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]
249 #; UINT32 ExceptionData;
250 push qword ptr [%rbp + 16]
252 #; call into exception handler
254 lea %rax, [%rip+ExternalVectorTablePtr]
256 mov %rax, [%rax + %rcx * 8]
257 or %rax, %rax # NULL?
261 #; Prepare parameter and call
265 # Per X64 calling convention, allocate maximum parameter stack space
266 # and make sure RSP is 16-byte aligned
274 #; UINT64 ExceptionData;
277 #; FX_SAVE_STATE_X64 FxSaveState;
280 .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi]
283 #; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
292 #; skip restore of dr6. We cleared dr6 during the context save.
297 #; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
300 add %rsp, 8 # not for Cr1
311 pop qword ptr [%rbp + 40]
314 #; UINT64 Gdtr[2], Idtr[2];
315 #; Best not let anyone mess with these particular registers...
319 pop qword ptr [%rbp + 24]
321 #; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
323 # mov gs, rax ; not for gs
325 # mov fs, rax ; not for fs
326 # (X64 will not use fs and gs, so we do not restore it)
331 pop qword ptr [%rbp + 32] # for cs
332 pop qword ptr [%rbp + 56] # for ss
334 #; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
335 #; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
338 add %rsp, 8 # not for rbp
339 pop qword ptr [%rbp + 48] # for rsp