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
216 ErrorCodeAndVectorOnStack:
222 # +---------------------+
224 # +---------------------+
226 # +---------------------+
228 # +---------------------+
230 # +---------------------+
232 # +---------------------+
234 # +---------------------+ <-- EBP
238 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
241 andl $0x0fffffff0, %esp
244 #; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
255 #; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
258 movzwl 16(%ebp), %eax
273 #; UINT32 Gdtr[2], Idtr[2];
299 #; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
313 #; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
327 #; FX_SAVE_STATE_IA32 FxSaveState;
330 .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]
332 #; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
335 #; UINT32 ExceptionData;
338 #; Prepare parameter and call
345 # Call External Exception Handler
347 call ASM_PFX(CommonExceptionHandler)
351 #; UINT32 ExceptionData;
354 #; FX_SAVE_STATE_IA32 FxSaveState;
356 .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]
359 #; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
360 #; Skip restoration of DRx registers to support in-circuit emualators
361 #; or debuggers set breakpoint in interrupt/exception context
364 #; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
367 addl $4, %esp # not for Cr1
379 #; UINT32 Gdtr[2], Idtr[2];
380 #; Best not let anyone mess with these particular registers...
386 #; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
387 #; NOTE - modified segment registers could hang the debugger... We
388 #; could attempt to insulate ourselves against this possibility,
389 #; but that poses risks as well.
398 #; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
401 addl $4, %esp # not for ebp
402 addl $4, %esp # not for esp
414 #---------------------------------------;
415 # _GetTemplateAddressMap ;
416 #----------------------------------------------------------------------------;
419 # GetTemplateAddressMap (
420 # EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
423 # Routine Description:
425 # Return address map of interrupt handler template so that C code can generate
436 # Input: [ebp][0] = Original ebp
437 # [ebp][4] = Return address
442 #-----------------------------------------------------------------------------;
443 #-------------------------------------------------------------------------------------
444 # AsmGetAddressMap (&AddressMap);
445 #-------------------------------------------------------------------------------------
446 ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)
447 ASM_PFX(GetTemplateAddressMap):
454 movl $Exception0Handle, (%ebx)
455 movl $(Exception1Handle - Exception0Handle), 0x4(%ebx)