#------------------------------------------------------------------------------\r
#*\r
-#* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+#* Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
#* This program and the accompanying materials\r
#* are licensed and made available under the terms and conditions of the BSD License\r
#* which accompanies this distribution. The full text of the license may be found at\r
#.MMX\r
#.XMM\r
\r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
-\r
-\r
-#\r
-# point to the external interrupt vector table\r
-#\r
-ExternalVectorTablePtr:\r
- .byte 0, 0, 0, 0\r
-\r
-ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)\r
-ASM_PFX(InitializeExternalVectorTablePtr):\r
- movl 4(%esp), %eax\r
- movl %eax, ExternalVectorTablePtr\r
- ret\r
-\r
#------------------------------------------------------------------------------\r
# VOID\r
# SetCodeSelector (\r
movw %cx, %gs\r
ret\r
\r
-#---------------------------------------;\r
-# CommonInterruptEntry ;\r
-#---------------------------------------;\r
-# The follow algorithm is used for the common interrupt routine.\r
-\r
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
-ASM_PFX(CommonInterruptEntry):\r
- cli\r
- #\r
- # All interrupt handlers are invoked through interrupt gates, so\r
- # IF flag automatically cleared at the entry point\r
- #\r
-\r
- #\r
- # Calculate vector number\r
- #\r
- # Get the return address of call, actually, it is the\r
- # address of vector number.\r
- #\r
- xchgl (%esp), %ecx\r
- movw (%ecx), %cx\r
- andl $0x0FFFF, %ecx\r
- cmpl $32, %ecx # Intel reserved vector for exceptions?\r
- jae NoErrorCode\r
- bt %ecx, ASM_PFX(mErrorCodeFlag)\r
- jc HasErrorCode\r
-\r
-NoErrorCode:\r
-\r
- #\r
- # Stack:\r
- # +---------------------+\r
- # + EFlags +\r
- # +---------------------+\r
- # + CS +\r
- # +---------------------+\r
- # + EIP +\r
- # +---------------------+\r
- # + ECX +\r
- # +---------------------+ <-- ESP\r
- #\r
- # Registers:\r
- # ECX - Vector Number\r
- #\r
-\r
- #\r
- # Put Vector Number on stack\r
- #\r
- pushl %ecx\r
-\r
- #\r
- # Put 0 (dummy) error code on stack, and restore ECX\r
- #\r
- xorl %ecx, %ecx # ECX = 0\r
- xchgl 4(%esp), %ecx\r
-\r
- jmp ErrorCodeAndVectorOnStack\r
-\r
-HasErrorCode:\r
-\r
- #\r
- # Stack:\r
- # +---------------------+\r
- # + EFlags +\r
- # +---------------------+\r
- # + CS +\r
- # +---------------------+\r
- # + EIP +\r
- # +---------------------+\r
- # + Error Code +\r
- # +---------------------+\r
- # + ECX +\r
- # +---------------------+ <-- ESP\r
- #\r
- # Registers:\r
- # ECX - Vector Number\r
- #\r
-\r
- #\r
- # Put Vector Number on stack and restore ECX\r
- #\r
- xchgl (%esp), %ecx \r
-\r
-ErrorCodeAndVectorOnStack:\r
- pushl %ebp\r
- movl %esp, %ebp\r
-\r
- #\r
- # Stack:\r
- # +---------------------+\r
- # + EFlags +\r
- # +---------------------+\r
- # + CS +\r
- # +---------------------+\r
- # + EIP +\r
- # +---------------------+\r
- # + Error Code +\r
- # +---------------------+\r
- # + Vector Number +\r
- # +---------------------+\r
- # + EBP +\r
- # +---------------------+ <-- EBP\r
- #\r
-\r
- #\r
- # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
- # is 16-byte aligned\r
- #\r
- andl $0x0fffffff0, %esp \r
- subl $12, %esp\r
-\r
-#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pushl %eax\r
- pushl %ecx\r
- pushl %edx\r
- pushl %ebx\r
- leal 24(%ebp), %ecx\r
- pushl %ecx # ESP\r
- pushl (%ebp) # EBP\r
- pushl %esi\r
- pushl %edi\r
-\r
-#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
- movl %ss, %eax\r
- pushl %eax\r
- movzwl 16(%ebp), %eax \r
- pushl %eax\r
- movl %ds, %eax\r
- pushl %eax\r
- movl %es, %eax\r
- pushl %eax\r
- movl %fs, %eax\r
- pushl %eax\r
- movl %gs, %eax\r
- pushl %eax\r
-\r
-#; UINT32 Eip;\r
- movl 12(%ebp), %eax\r
- pushl %eax\r
-\r
-#; UINT32 Gdtr[2], Idtr[2];\r
- subl $8, %esp\r
- sidt (%esp)\r
- movl 2(%esp), %eax\r
- xchgl (%esp), %eax\r
- andl $0x0FFFF, %eax \r
- movl %eax, 4(%esp)\r
-\r
- subl $8, %esp\r
- sgdt (%esp)\r
- movl 2(%esp), %eax\r
- xchgl (%esp), %eax\r
- andl $0x0FFFF, %eax \r
- movl %eax, 4(%esp)\r
-\r
-#; UINT32 Ldtr, Tr;\r
- xorl %eax, %eax\r
- str %ax\r
- pushl %eax\r
- sldt %ax\r
- pushl %eax\r
-\r
-#; UINT32 EFlags;\r
- movl 20(%ebp), %eax\r
- pushl %eax\r
-\r
-#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- movl %cr4, %eax\r
- orl $0x208, %eax\r
- movl %eax, %cr4\r
- pushl %eax\r
- movl %cr3, %eax\r
- pushl %eax\r
- movl %cr2, %eax\r
- pushl %eax\r
- xorl %eax, %eax\r
- pushl %eax\r
- movl %cr0, %eax\r
- pushl %eax\r
-\r
-#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- movl %dr7, %eax\r
- pushl %eax\r
- movl %dr6, %eax\r
- pushl %eax\r
- movl %dr3, %eax\r
- pushl %eax\r
- movl %dr2, %eax\r
- pushl %eax\r
- movl %dr1, %eax\r
- pushl %eax\r
- movl %dr0, %eax\r
- pushl %eax\r
-\r
-#; FX_SAVE_STATE_IA32 FxSaveState;\r
- subl $512, %esp\r
- movl %esp, %edi\r
- .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]\r
-\r
-#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-#; UINT32 ExceptionData;\r
- pushl 8(%ebp)\r
-\r
-#; call into exception handler\r
- movl ExternalVectorTablePtr, %eax # get the interrupt vectors base\r
- orl %eax, %eax # NULL?\r
- jz nullExternalExceptionHandler\r
-\r
- mov 4(%ebp), %ecx\r
- movl (%eax,%ecx,4), %eax\r
- orl %eax, %eax # NULL?\r
- jz nullExternalExceptionHandler\r
-\r
-#; Prepare parameter and call\r
- movl %esp, %edx\r
- pushl %edx\r
- movl 4(%ebp), %edx\r
- pushl %edx\r
-\r
- #\r
- # Call External Exception Handler\r
- #\r
- call *%eax\r
- addl $8, %esp\r
-\r
-nullExternalExceptionHandler:\r
-\r
- cli\r
-#; UINT32 ExceptionData;\r
- addl $4, %esp\r
-\r
-#; FX_SAVE_STATE_IA32 FxSaveState;\r
- movl %esp, %esi\r
- .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]\r
- addl $512, %esp\r
-\r
-#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-#; Skip restoration of DRx registers to support in-circuit emualators\r
-#; or debuggers set breakpoint in interrupt/exception context\r
- addl $24, %esp\r
-\r
-#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- popl %eax\r
- movl %eax, %cr0\r
- addl $4, %esp # not for Cr1\r
- popl %eax\r
- movl %eax, %cr2\r
- popl %eax\r
- movl %eax, %cr3\r
- popl %eax\r
- movl %eax, %cr4\r
-\r
-#; UINT32 EFlags;\r
- popl 20(%ebp)\r
-\r
-#; UINT32 Ldtr, Tr;\r
-#; UINT32 Gdtr[2], Idtr[2];\r
-#; Best not let anyone mess with these particular registers...\r
- addl $24, %esp\r
-\r
-#; UINT32 Eip;\r
- popl 12(%ebp)\r
-\r
-#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-#; NOTE - modified segment registers could hang the debugger... We\r
-#; could attempt to insulate ourselves against this possibility,\r
-#; but that poses risks as well.\r
-#;\r
- popl %gs\r
- popl %fs\r
- popl %es\r
- popl %ds\r
- popl 16(%ebp)\r
- popl %ss\r
-\r
-#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- popl %edi\r
- popl %esi\r
- addl $4, %esp # not for ebp\r
- addl $4, %esp # not for esp\r
- popl %ebx\r
- popl %edx\r
- popl %ecx\r
- popl %eax\r
-\r
- movl %ebp, %esp\r
- popl %ebp\r
- addl $8, %esp\r
- iretl\r
-\r
-\r
#END\r
\r