1 #------------------------------------------------------------------------------
3 #* Copyright (c) 2012, 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.
12 #* ExceptionHandlerAsm.S
16 #* IA32 CPU Exception Handler
18 #------------------------------------------------------------------------------
27 ASM_GLOBAL ASM_PFX(CommonExceptionHandler)
28 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
30 #EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
35 # exception handler stub table
39 jmp ASM_PFX(CommonInterruptEntry)
42 jmp ASM_PFX(CommonInterruptEntry)
45 jmp ASM_PFX(CommonInterruptEntry)
48 jmp ASM_PFX(CommonInterruptEntry)
51 jmp ASM_PFX(CommonInterruptEntry)
54 jmp ASM_PFX(CommonInterruptEntry)
57 jmp ASM_PFX(CommonInterruptEntry)
60 jmp ASM_PFX(CommonInterruptEntry)
63 jmp ASM_PFX(CommonInterruptEntry)
66 jmp ASM_PFX(CommonInterruptEntry)
69 jmp ASM_PFX(CommonInterruptEntry)
72 jmp ASM_PFX(CommonInterruptEntry)
75 jmp ASM_PFX(CommonInterruptEntry)
78 jmp ASM_PFX(CommonInterruptEntry)
81 jmp ASM_PFX(CommonInterruptEntry)
84 jmp ASM_PFX(CommonInterruptEntry)
87 jmp ASM_PFX(CommonInterruptEntry)
90 jmp ASM_PFX(CommonInterruptEntry)
93 jmp ASM_PFX(CommonInterruptEntry)
96 jmp ASM_PFX(CommonInterruptEntry)
99 jmp ASM_PFX(CommonInterruptEntry)
102 jmp ASM_PFX(CommonInterruptEntry)
105 jmp ASM_PFX(CommonInterruptEntry)
108 jmp ASM_PFX(CommonInterruptEntry)
111 jmp ASM_PFX(CommonInterruptEntry)
114 jmp ASM_PFX(CommonInterruptEntry)
117 jmp ASM_PFX(CommonInterruptEntry)
120 jmp ASM_PFX(CommonInterruptEntry)
123 jmp ASM_PFX(CommonInterruptEntry)
126 jmp ASM_PFX(CommonInterruptEntry)
129 jmp ASM_PFX(CommonInterruptEntry)
132 jmp ASM_PFX(CommonInterruptEntry)
134 #---------------------------------------;
135 # CommonInterruptEntry ;
136 #---------------------------------------;
137 # The follow algorithm is used for the common interrupt routine.
139 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
140 ASM_PFX(CommonInterruptEntry):
143 # All interrupt handlers are invoked through interrupt gates, so
144 # IF flag automatically cleared at the entry point
148 # Calculate vector number
150 # Get the return address of call, actually, it is the
151 # address of vector number.
155 cmpl $32, %ecx # Intel reserved vector for exceptions?
157 bt %ecx, ASM_PFX(mErrorCodeFlag)
164 # +---------------------+
166 # +---------------------+
168 # +---------------------+
170 # +---------------------+
172 # +---------------------+ <-- ESP
175 # ECX - Vector Number
179 # Put Vector Number on stack
184 # Put 0 (dummy) error code on stack, and restore ECX
186 xorl %ecx, %ecx # ECX = 0
189 jmp ErrorCodeAndVectorOnStack
195 # +---------------------+
197 # +---------------------+
199 # +---------------------+
201 # +---------------------+
203 # +---------------------+
205 # +---------------------+ <-- ESP
208 # ECX - Vector Number
212 # Put Vector Number on stack and restore ECX
217 # Fall through to join main routine code
218 # at ErrorCodeAndVectorOnStack
220 CommonInterruptEntry_al_0000:
221 jmp CommonInterruptEntry_al_0000
223 ErrorCodeAndVectorOnStack:
229 # +---------------------+
231 # +---------------------+
233 # +---------------------+
235 # +---------------------+
237 # +---------------------+
239 # +---------------------+
241 # +---------------------+ <-- EBP
245 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
248 andl $0x0fffffff0, %esp
251 #; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
262 #; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
265 movzwl 16(%ebp), %eax
280 #; UINT32 Gdtr[2], Idtr[2];
306 #; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
320 #; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
334 #; FX_SAVE_STATE_IA32 FxSaveState;
337 .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]
339 #; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
342 #; UINT32 ExceptionData;
345 #; Prepare parameter and call
352 # Call External Exception Handler
354 call ASM_PFX(CommonExceptionHandler)
358 #; UINT32 ExceptionData;
361 #; FX_SAVE_STATE_IA32 FxSaveState;
363 .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]
366 #; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
367 #; Skip restoration of DRx registers to support in-circuit emualators
368 #; or debuggers set breakpoint in interrupt/exception context
371 #; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
374 addl $4, %esp # not for Cr1
386 #; UINT32 Gdtr[2], Idtr[2];
387 #; Best not let anyone mess with these particular registers...
393 #; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
394 #; NOTE - modified segment registers could hang the debugger... We
395 #; could attempt to insulate ourselves against this possibility,
396 #; but that poses risks as well.
405 #; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
408 addl $4, %esp # not for ebp
409 addl $4, %esp # not for esp
421 #---------------------------------------;
422 # _GetTemplateAddressMap ;
423 #----------------------------------------------------------------------------;
426 # GetTemplateAddressMap (
427 # EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
430 # Routine Description:
432 # Return address map of interrupt handler template so that C code can generate
443 # Input: [ebp][0] = Original ebp
444 # [ebp][4] = Return address
449 #-----------------------------------------------------------------------------;
450 #-------------------------------------------------------------------------------------
451 # AsmGetAddressMap (&AddressMap);
452 #-------------------------------------------------------------------------------------
453 ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)
454 ASM_PFX(GetTemplateAddressMap):
461 movl $Exception0Handle, (%ebx)
462 movl $(Exception1Handle - Exception0Handle), 0x4(%ebx)