+++ /dev/null
-#------------------------------------------------------------------------------\r
-#*\r
-#* Copyright (c) 2012 - 2015, 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
-#* http://opensource.org/licenses/bsd-license.php\r
-#*\r
-#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#*\r
-#* ExceptionHandlerAsm.S\r
-#*\r
-#* Abstract:\r
-#*\r
-#* IA32 CPU Exception Handler\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-\r
-#.MMX\r
-#.XMM\r
-\r
-ASM_GLOBAL ASM_PFX(CommonExceptionHandler)\r
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
-ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
-\r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
-#EXTRN ASM_PFX(mDoFarReturnFlag):DWORD # Do far return flag\r
-\r
-.text\r
-\r
-#\r
-# exception handler stub table\r
-#\r
-Exception0Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 0\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception1Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 1\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception2Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 2\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception3Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 3\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception4Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 4\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception5Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 5\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception6Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 6\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception7Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 7\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception8Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 8\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception9Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 9\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception10Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 10\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception11Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 11\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception12Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 12\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception13Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 13\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception14Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 14\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception15Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 15\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception16Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 16\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception17Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 17\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception18Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 18\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception19Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 19\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception20Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 20\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception21Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 21\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception22Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 22\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception23Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 23\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception24Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 24\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception25Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 25\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception26Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 26\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception27Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 27\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception28Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 28\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception29Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 29\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception30Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 30\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-Exception31Handle:\r
- .byte 0x6a # push #VectorNum\r
- .byte 31\r
- pushl %eax\r
- .byte 0xB8\r
- .long ASM_PFX(CommonInterruptEntry)\r
- jmp *%eax\r
-\r
-HookAfterStubBegin:\r
- .byte 0x6a # push\r
-VectorNum:\r
- .byte 0 # 0 will be fixed\r
- pushl %eax\r
- .byte 0xB8 # movl ASM_PFX(HookAfterStubHeaderEnd), %eax\r
- .long ASM_PFX(HookAfterStubHeaderEnd)\r
- jmp *%eax\r
-ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
-ASM_PFX(HookAfterStubHeaderEnd):\r
- popl %eax\r
- subl $8, %esp # reserve room for filling exception data later\r
- pushl 8(%esp)\r
- xchgl (%esp), %ecx # get vector number\r
- bt %ecx, ASM_PFX(mErrorCodeFlag)\r
- jnc NoErrorData\r
- pushl (%esp) # addition push if exception data needed\r
-NoErrorData:\r
- xchg (%esp), %ecx # restore ecx\r
- pushl %eax\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
- popl %eax\r
- #\r
- # All interrupt handlers are invoked through interrupt gates, so\r
- # IF flag automatically cleared at the entry point\r
- #\r
-\r
- #\r
- # Get vector number from top of stack\r
- #\r
- xchgl (%esp), %ecx\r
- andl $0x0FF, %ecx # Vector number should be less than 256\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
- subl $8, %esp\r
- pushl $0 # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
- pushl $0 # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\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
-## insure FXSAVE/FXRSTOR is enabled in CR4...\r
-## ... while we're at it, make sure DE is also enabled...\r
- mov $1, %eax\r
- pushl %ebx # temporarily save value of ebx on stack\r
- cpuid # use CPUID to determine if FXSAVE/FXRESTOR\r
- # and DE are supported\r
- popl %ebx # retore value of ebx that was overwritten\r
- # by CPUID\r
- movl %cr4, %eax\r
- pushl %eax # push cr4 firstly\r
- testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support\r
- jz L1\r
- orl $BIT9, %eax # Set CR4.OSFXSR\r
-L1:\r
- testl $BIT2, %edx # Test for Debugging Extensions support\r
- jz L2\r
- orl $BIT3, %eax # Set CR4.DE\r
-L2:\r
- movl %eax, %cr4\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
- testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support.\r
- # edx still contains result from CPUID above\r
- jz L3\r
- .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]\r
-L3:\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
-#; 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 ASM_PFX(CommonExceptionHandler)\r
- addl $8, %esp\r
-\r
- cli\r
-#; UINT32 ExceptionData;\r
- addl $4, %esp\r
-\r
-#; FX_SAVE_STATE_IA32 FxSaveState;\r
- movl %esp, %esi\r
- movl $1, %eax\r
- cpuid # use CPUID to determine if FXSAVE/FXRESTOR\r
- # are supported\r
- testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support\r
- jz L4\r
- .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]\r
-L4:\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
- popl -8(%ebp)\r
- popl -4(%ebp)\r
- movl %ebp, %esp\r
- popl %ebp\r
- addl $8, %esp\r
- cmpl $0, -16(%esp) # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
- jz DoReturn\r
- cmpl $1, -20(%esp) # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
- jz ErrorCode\r
- jmp *-16(%esp)\r
-ErrorCode:\r
- subl $4, %esp\r
- jmp *-12(%esp)\r
-\r
-DoReturn:\r
- cmpl $0, ASM_PFX(mDoFarReturnFlag)\r
- jz DoIret\r
- pushl 8(%esp) # save EFLAGS\r
- addl $16, %esp\r
- pushl -8(%esp) # save CS in new location\r
- pushl -8(%esp) # save EIP in new location\r
- pushl -8(%esp) # save EFLAGS in new location\r
- popfl # restore EFLAGS\r
- lret # far return\r
-\r
-DoIret:\r
- iretl\r
-\r
-\r
-#---------------------------------------;\r
-# _AsmGetTemplateAddressMap ;\r
-#---------------------------------------;\r
-#\r
-# Protocol prototype\r
-# AsmGetTemplateAddressMap (\r
-# EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
-# );\r
-#\r
-# Routine Description:\r
-#\r
-# Return address map of interrupt handler template so that C code can generate\r
-# interrupt table.\r
-#\r
-# Arguments:\r
-#\r
-#\r
-# Returns:\r
-#\r
-# Nothing\r
-#\r
-#\r
-# Input: [ebp][0] = Original ebp\r
-# [ebp][4] = Return address\r
-#\r
-# Output: Nothing\r
-#\r
-# Destroys: Nothing\r
-#-----------------------------------------------------------------------------;\r
-#-------------------------------------------------------------------------------------\r
-# AsmGetAddressMap (&AddressMap);\r
-#-------------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)\r
-ASM_PFX(AsmGetTemplateAddressMap):\r
-\r
- pushl %ebp\r
- movl %esp,%ebp\r
- pushal\r
-\r
- movl 0x8(%ebp), %ebx\r
- movl $Exception0Handle, (%ebx)\r
- movl $(Exception1Handle - Exception0Handle), 0x4(%ebx)\r
- movl $(HookAfterStubBegin), 0x8(%ebx)\r
-\r
- popal\r
- popl %ebp\r
- ret\r
-#-------------------------------------------------------------------------------------\r
-# AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);\r
-#-------------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)\r
-ASM_PFX(AsmVectorNumFixup):\r
- movl 8(%esp), %eax\r
- movl 4(%esp), %ecx\r
- movb %al, (VectorNum - HookAfterStubBegin)(%ecx)\r
- ret\r
+++ /dev/null
-#------------------------------------------------------------------------------ ;\r
-# Copyright (c) 2012 - 2017, 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
-# http://opensource.org/licenses/bsd-license.php.\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-# ExceptionHandlerAsm.S\r
-#\r
-# Abstract:\r
-#\r
-# x64 CPU Exception Handler\r
-#\r
-# Notes:\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-\r
-\r
-ASM_GLOBAL ASM_PFX(CommonExceptionHandler)\r
-\r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
-#EXTRN ASM_PFX(mDoFarReturnFlag):QWORD # Do far return flag\r
-.text\r
-\r
-#ifdef __APPLE__\r
-# macros are different between GNU and Xcode as.\r
-.macro IDT_MACRO\r
- push $0\r
-#else\r
-.macro IDT_MACRO arg\r
- push \arg\r
-#endif\r
- .byte 0xe9 # jmp ASM_PFX(CommonInterruptEntry)\r
- .long ASM_PFX(CommonInterruptEntry) - . - 4\r
-.endm\r
-\r
-AsmIdtVectorBegin:\r
- IDT_MACRO $0\r
- IDT_MACRO $1\r
- IDT_MACRO $2\r
- IDT_MACRO $3\r
- IDT_MACRO $4\r
- IDT_MACRO $5\r
- IDT_MACRO $6\r
- IDT_MACRO $7\r
- IDT_MACRO $8\r
- IDT_MACRO $9\r
- IDT_MACRO $10\r
- IDT_MACRO $11\r
- IDT_MACRO $12\r
- IDT_MACRO $13\r
- IDT_MACRO $14\r
- IDT_MACRO $15\r
- IDT_MACRO $16\r
- IDT_MACRO $17\r
- IDT_MACRO $18\r
- IDT_MACRO $19\r
- IDT_MACRO $20\r
- IDT_MACRO $21\r
- IDT_MACRO $22\r
- IDT_MACRO $23\r
- IDT_MACRO $24\r
- IDT_MACRO $25\r
- IDT_MACRO $26\r
- IDT_MACRO $27\r
- IDT_MACRO $28\r
- IDT_MACRO $29\r
- IDT_MACRO $30\r
- IDT_MACRO $31\r
-AsmIdtVectorEnd:\r
-\r
-HookAfterStubHeaderBegin:\r
- .byte 0x6a # push\r
-PatchVectorNum:\r
- .byte 0 # 0 will be fixed\r
- .byte 0xe9 # jmp ASM_PFX(HookAfterStubHeaderEnd)\r
-PatchFuncAddress:\r
- .set HOOK_ADDRESS, ASM_PFX(HookAfterStubHeaderEnd) - . - 4\r
- .long HOOK_ADDRESS # will be fixed\r
-ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
-ASM_PFX(HookAfterStubHeaderEnd):\r
- pushq %rax\r
- movq %rsp, %rax\r
- andl $0x0fffffff0, %esp # make sure 16-byte aligned for exception context\r
- subq $0x18, %rsp # reserve room for filling exception data later\r
- pushq %rcx\r
- movq 8(%rax), %rcx\r
- bt %ecx, ASM_PFX(mErrorCodeFlag)(%rip)\r
- jnc NoErrorData\r
- pushq (%rsp) # push additional rcx to make stack alignment\r
-NoErrorData:\r
- xchgq (%rsp), %rcx # restore rcx, save Exception Number in stack\r
- movq (%rax), %rax # restore rax\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
- # Calculate vector number\r
- #\r
- xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.\r
- andq $0x0FF, %rcx\r
- cmp $32, %ecx # Intel reserved vector for exceptions?\r
- jae NoErrorCode\r
- pushq %rax\r
- movl ASM_PFX(mErrorCodeFlag)(%rip), %eax\r
- bt %ecx, %eax\r
- popq %rax\r
- jc CommonInterruptEntry_al_0000\r
-\r
-NoErrorCode:\r
-\r
- #\r
- # Push a dummy error code on the stack\r
- # to maintain coherent stack map\r
- #\r
- pushq (%rsp)\r
- movq $0, 8(%rsp)\r
-CommonInterruptEntry_al_0000:\r
- pushq %rbp\r
- movq %rsp, %rbp\r
- pushq $0 # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
- pushq $0 # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
-\r
- #\r
- # Stack:\r
- # +---------------------+ <-- 16-byte aligned ensured by processor\r
- # + Old SS +\r
- # +---------------------+\r
- # + Old RSP +\r
- # +---------------------+\r
- # + RFlags +\r
- # +---------------------+\r
- # + CS +\r
- # +---------------------+\r
- # + RIP +\r
- # +---------------------+\r
- # + Error Code +\r
- # +---------------------+\r
- # + RCX / Vector Number +\r
- # +---------------------+\r
- # + RBP +\r
- # +---------------------+ <-- RBP, 16-byte aligned\r
- #\r
-\r
-\r
- #\r
- # Since here the stack pointer is 16-byte aligned, so\r
- # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
- # is 16-byte aligned\r
- #\r
-\r
-#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- pushq %r15\r
- pushq %r14\r
- pushq %r13\r
- pushq %r12\r
- pushq %r11\r
- pushq %r10\r
- pushq %r9\r
- pushq %r8\r
- pushq %rax\r
- pushq 8(%rbp) # RCX\r
- pushq %rdx\r
- pushq %rbx\r
- pushq 48(%rbp) # RSP\r
- pushq (%rbp) # RBP\r
- pushq %rsi\r
- pushq %rdi\r
-\r
-#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
- movzwq 56(%rbp), %rax\r
- pushq %rax # for ss\r
- movzwq 32(%rbp), %rax\r
- pushq %rax # for cs\r
- mov %ds, %rax\r
- pushq %rax\r
- mov %es, %rax\r
- pushq %rax\r
- mov %fs, %rax\r
- pushq %rax\r
- mov %gs, %rax\r
- pushq %rax\r
-\r
- movq %rcx, 8(%rbp) # save vector number\r
-\r
-#; UINT64 Rip;\r
- pushq 24(%rbp)\r
-\r
-#; UINT64 Gdtr[2], Idtr[2];\r
- xorq %rax, %rax\r
- pushq %rax\r
- pushq %rax\r
- sidt (%rsp)\r
- xchgq 2(%rsp), %rax\r
- xchgq (%rsp), %rax\r
- xchgq 8(%rsp), %rax\r
-\r
- xorq %rax, %rax\r
- pushq %rax\r
- pushq %rax\r
- sgdt (%rsp)\r
- xchgq 2(%rsp), %rax\r
- xchgq (%rsp), %rax\r
- xchgq 8(%rsp), %rax\r
-\r
-#; UINT64 Ldtr, Tr;\r
- xorq %rax, %rax\r
- str %ax\r
- pushq %rax\r
- sldt %ax\r
- pushq %rax\r
-\r
-#; UINT64 RFlags;\r
- pushq 40(%rbp)\r
-\r
-#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- movq %cr8, %rax\r
- pushq %rax\r
- movq %cr4, %rax\r
- orq $0x208, %rax\r
- movq %rax, %cr4\r
- pushq %rax\r
- mov %cr3, %rax\r
- pushq %rax\r
- mov %cr2, %rax\r
- pushq %rax\r
- xorq %rax, %rax\r
- pushq %rax\r
- mov %cr0, %rax\r
- pushq %rax\r
-\r
-#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- movq %dr7, %rax\r
- pushq %rax\r
- movq %dr6, %rax\r
- pushq %rax\r
- movq %dr3, %rax\r
- pushq %rax\r
- movq %dr2, %rax\r
- pushq %rax\r
- movq %dr1, %rax\r
- pushq %rax\r
- movq %dr0, %rax\r
- pushq %rax\r
-\r
-#; FX_SAVE_STATE_X64 FxSaveState;\r
- subq $512, %rsp\r
- movq %rsp, %rdi\r
- .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]\r
-\r
-#; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-#; UINT32 ExceptionData;\r
- pushq 16(%rbp)\r
-\r
-#; Prepare parameter and call\r
- mov 8(%rbp), %rcx\r
- mov %rsp, %rdx\r
- #\r
- # Per X64 calling convention, allocate maximum parameter stack space\r
- # and make sure RSP is 16-byte aligned\r
- #\r
- subq $40, %rsp\r
- call ASM_PFX(CommonExceptionHandler)\r
- addq $40, %rsp\r
-\r
- cli\r
-#; UINT64 ExceptionData;\r
- addq $8, %rsp\r
-\r
-#; FX_SAVE_STATE_X64 FxSaveState;\r
-\r
- movq %rsp, %rsi\r
- .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi]\r
- addq $512, %rsp\r
-\r
-#; UINT64 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
- addq $48, %rsp\r
-\r
-#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- popq %rax\r
- movq %rax, %cr0\r
- addq $8, %rsp # not for Cr1\r
- popq %rax\r
- movq %rax, %cr2\r
- popq %rax\r
- movq %rax, %cr3\r
- popq %rax\r
- movq %rax, %cr4\r
- popq %rax\r
- movq %rax, %cr8\r
-\r
-#; UINT64 RFlags;\r
- popq 40(%rbp)\r
-\r
-#; UINT64 Ldtr, Tr;\r
-#; UINT64 Gdtr[2], Idtr[2];\r
-#; Best not let anyone mess with these particular registers...\r
- addq $48, %rsp\r
-\r
-#; UINT64 Rip;\r
- popq 24(%rbp)\r
-\r
-#; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
- popq %rax\r
- # mov %rax, %gs ; not for gs\r
- popq %rax\r
- # mov %rax, %fs ; not for fs\r
- # (X64 will not use fs and gs, so we do not restore it)\r
- popq %rax\r
- mov %rax, %es\r
- popq %rax\r
- mov %rax, %ds\r
- popq 32(%rbp) # for cs\r
- popq 56(%rbp) # for ss\r
-\r
-#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- popq %rdi\r
- popq %rsi\r
- addq $8, %rsp # not for rbp\r
- popq 48(%rbp) # for rsp\r
- popq %rbx\r
- popq %rdx\r
- popq %rcx\r
- popq %rax\r
- popq %r8\r
- popq %r9\r
- popq %r10\r
- popq %r11\r
- popq %r12\r
- popq %r13\r
- popq %r14\r
- popq %r15\r
-\r
- movq %rbp, %rsp\r
- popq %rbp\r
- addq $16, %rsp\r
- cmpq $0, -32(%rsp) # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
- jz DoReturn # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
- cmpb $1, -40(%rsp)\r
- jz ErrorCode\r
- jmp *-32(%rsp)\r
-ErrorCode:\r
- subq $8, %rsp\r
- jmp *-24(%rsp)\r
-\r
-DoReturn:\r
- pushq %rax\r
- movq ASM_PFX(mDoFarReturnFlag)(%rip), %rax\r
- cmpq $0, %rax # Check if need to do far return instead of IRET\r
- popq %rax\r
- jz DoIret\r
- pushq %rax\r
- movq %rsp, %rax # save old RSP to rax\r
- movq 0x20(%rsp), %rsp\r
- pushq 0x10(%rax) # save CS in new location\r
- pushq 0x8(%rax) # save EIP in new location\r
- pushq 0x18(%rax) # save EFLAGS in new location\r
- movq (%rax), %rax # restore rax\r
- popfq # restore EFLAGS\r
- lretq # far return\r
-DoIret:\r
- iretq\r
-\r
-\r
-#-------------------------------------------------------------------------------------\r
-# AsmGetTemplateAddressMap (&AddressMap);\r
-#-------------------------------------------------------------------------------------\r
-# comments here for definition of address map\r
-ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)\r
-ASM_PFX(AsmGetTemplateAddressMap):\r
- pushq %rbp\r
- movq %rsp, %rbp\r
-\r
- leaq AsmIdtVectorBegin(%rip), %rax\r
- movq %rax, (%rcx)\r
- .set ENTRY_SIZE, ASM_PFX(HookAfterStubHeaderEnd) - HookAfterStubHeaderBegin\r
- movq $(ENTRY_SIZE), 0x08(%rcx)\r
- leaq HookAfterStubHeaderBegin(%rip), %rax\r
- movq %rax, 0x10(%rcx)\r
-\r
- popq %rbp\r
- ret\r
-\r
-#-------------------------------------------------------------------------------------\r
-# VOID\r
-# EFIAPI\r
-# AsmVectorNumFixup (\r
-# IN VOID *NewVectorAddr, // RCX\r
-# IN UINT8 VectorNum // RDX\r
-# IN VOID *OldVectorAddr, // R8\r
-# );\r
-#-------------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)\r
-ASM_PFX(AsmVectorNumFixup):\r
- pushq %rbp\r
- movq %rsp, %rbp\r
-\r
-# Patch vector #\r
- movb %dl, (PatchVectorNum - HookAfterStubHeaderBegin)(%rcx)\r
-\r
-# Patch Function address\r
- subq %rcx, %r8 # Calculate the offset value\r
- movl (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx), %eax\r
- addq %r8, %rax\r
- movl %eax, (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx)\r
-\r
- popq %rbp\r
- ret\r
-\r
-#END\r
-\r
-\r