.nasm file has been added for X86 arch. .S assembly code is not required any more. https://bugzilla.tianocore.org/show_bug.cgi?id=1594
Cc: Eric Dong <eric.d...@intel.com> Cc: Ray Ni <ray...@intel.com> Cc: Laszlo Ersek <ler...@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Shenglei Zhang <shenglei.zh...@intel.com> --- .../DxeCpuExceptionHandlerLib.inf | 2 - .../Ia32/ExceptionHandlerAsm.S | 667 ------------------ .../PeiCpuExceptionHandlerLib.inf | 2 - .../SecPeiCpuExceptionHandlerLib.inf | 2 - .../SmmCpuExceptionHandlerLib.inf | 2 - .../X64/ExceptionHandlerAsm.S | 434 ------------ 6 files changed, 1109 deletions(-) delete mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S delete mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf index a480890165..391e49f077 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf @@ -30,13 +30,11 @@ [Sources.Ia32] Ia32/ExceptionHandlerAsm.nasm Ia32/ExceptionTssEntryAsm.nasm - Ia32/ExceptionHandlerAsm.S Ia32/ArchExceptionHandler.c Ia32/ArchInterruptDefs.h [Sources.X64] X64/ExceptionHandlerAsm.nasm - X64/ExceptionHandlerAsm.S X64/ArchExceptionHandler.c X64/ArchInterruptDefs.h diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S deleted file mode 100644 index c134257d9d..0000000000 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S +++ /dev/null @@ -1,667 +0,0 @@ -#------------------------------------------------------------------------------ -#* -#* Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR> -#* This program and the accompanying materials -#* are licensed and made available under the terms and conditions of the BSD License -#* which accompanies this distribution. The full text of the license may be found at -#* http://opensource.org/licenses/bsd-license.php -#* -#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -#* -#* ExceptionHandlerAsm.S -#* -#* Abstract: -#* -#* IA32 CPU Exception Handler -# -#------------------------------------------------------------------------------ - - -#.MMX -#.XMM - -ASM_GLOBAL ASM_PFX(CommonExceptionHandler) -ASM_GLOBAL ASM_PFX(CommonInterruptEntry) -ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd) - -#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions -#EXTRN ASM_PFX(mDoFarReturnFlag):DWORD # Do far return flag - -.text - -# -# exception handler stub table -# -Exception0Handle: - .byte 0x6a # push #VectorNum - .byte 0 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception1Handle: - .byte 0x6a # push #VectorNum - .byte 1 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception2Handle: - .byte 0x6a # push #VectorNum - .byte 2 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception3Handle: - .byte 0x6a # push #VectorNum - .byte 3 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception4Handle: - .byte 0x6a # push #VectorNum - .byte 4 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception5Handle: - .byte 0x6a # push #VectorNum - .byte 5 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception6Handle: - .byte 0x6a # push #VectorNum - .byte 6 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception7Handle: - .byte 0x6a # push #VectorNum - .byte 7 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception8Handle: - .byte 0x6a # push #VectorNum - .byte 8 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception9Handle: - .byte 0x6a # push #VectorNum - .byte 9 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception10Handle: - .byte 0x6a # push #VectorNum - .byte 10 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception11Handle: - .byte 0x6a # push #VectorNum - .byte 11 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception12Handle: - .byte 0x6a # push #VectorNum - .byte 12 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception13Handle: - .byte 0x6a # push #VectorNum - .byte 13 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception14Handle: - .byte 0x6a # push #VectorNum - .byte 14 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception15Handle: - .byte 0x6a # push #VectorNum - .byte 15 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception16Handle: - .byte 0x6a # push #VectorNum - .byte 16 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception17Handle: - .byte 0x6a # push #VectorNum - .byte 17 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception18Handle: - .byte 0x6a # push #VectorNum - .byte 18 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception19Handle: - .byte 0x6a # push #VectorNum - .byte 19 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception20Handle: - .byte 0x6a # push #VectorNum - .byte 20 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception21Handle: - .byte 0x6a # push #VectorNum - .byte 21 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception22Handle: - .byte 0x6a # push #VectorNum - .byte 22 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception23Handle: - .byte 0x6a # push #VectorNum - .byte 23 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception24Handle: - .byte 0x6a # push #VectorNum - .byte 24 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception25Handle: - .byte 0x6a # push #VectorNum - .byte 25 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception26Handle: - .byte 0x6a # push #VectorNum - .byte 26 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception27Handle: - .byte 0x6a # push #VectorNum - .byte 27 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception28Handle: - .byte 0x6a # push #VectorNum - .byte 28 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception29Handle: - .byte 0x6a # push #VectorNum - .byte 29 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception30Handle: - .byte 0x6a # push #VectorNum - .byte 30 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax -Exception31Handle: - .byte 0x6a # push #VectorNum - .byte 31 - pushl %eax - .byte 0xB8 - .long ASM_PFX(CommonInterruptEntry) - jmp *%eax - -HookAfterStubBegin: - .byte 0x6a # push -VectorNum: - .byte 0 # 0 will be fixed - pushl %eax - .byte 0xB8 # movl ASM_PFX(HookAfterStubHeaderEnd), %eax - .long ASM_PFX(HookAfterStubHeaderEnd) - jmp *%eax -ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd) -ASM_PFX(HookAfterStubHeaderEnd): - popl %eax - subl $8, %esp # reserve room for filling exception data later - pushl 8(%esp) - xchgl (%esp), %ecx # get vector number - bt %ecx, ASM_PFX(mErrorCodeFlag) - jnc NoErrorData - pushl (%esp) # addition push if exception data needed -NoErrorData: - xchg (%esp), %ecx # restore ecx - pushl %eax - -#---------------------------------------; -# CommonInterruptEntry ; -#---------------------------------------; -# The follow algorithm is used for the common interrupt routine. - -ASM_GLOBAL ASM_PFX(CommonInterruptEntry) -ASM_PFX(CommonInterruptEntry): - cli - popl %eax - # - # All interrupt handlers are invoked through interrupt gates, so - # IF flag automatically cleared at the entry point - # - - # - # Get vector number from top of stack - # - xchgl (%esp), %ecx - andl $0x0FF, %ecx # Vector number should be less than 256 - cmpl $32, %ecx # Intel reserved vector for exceptions? - jae NoErrorCode - bt %ecx, ASM_PFX(mErrorCodeFlag) - jc HasErrorCode - -NoErrorCode: - - # - # Stack: - # +---------------------+ - # + EFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + EIP + - # +---------------------+ - # + ECX + - # +---------------------+ <-- ESP - # - # Registers: - # ECX - Vector Number - # - - # - # Put Vector Number on stack - # - pushl %ecx - - # - # Put 0 (dummy) error code on stack, and restore ECX - # - xorl %ecx, %ecx # ECX = 0 - xchgl 4(%esp), %ecx - - jmp ErrorCodeAndVectorOnStack - -HasErrorCode: - - # - # Stack: - # +---------------------+ - # + EFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + EIP + - # +---------------------+ - # + Error Code + - # +---------------------+ - # + ECX + - # +---------------------+ <-- ESP - # - # Registers: - # ECX - Vector Number - # - - # - # Put Vector Number on stack and restore ECX - # - xchgl (%esp), %ecx - -ErrorCodeAndVectorOnStack: - pushl %ebp - movl %esp, %ebp - - # - # Stack: - # +---------------------+ - # + EFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + EIP + - # +---------------------+ - # + Error Code + - # +---------------------+ - # + Vector Number + - # +---------------------+ - # + EBP + - # +---------------------+ <-- EBP - # - - # - # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32 - # is 16-byte aligned - # - andl $0x0fffffff0, %esp - subl $12, %esp - - subl $8, %esp - pushl $0 # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - pushl $0 # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - -#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - pushl %eax - pushl %ecx - pushl %edx - pushl %ebx - leal 24(%ebp), %ecx - pushl %ecx # ESP - pushl (%ebp) # EBP - pushl %esi - pushl %edi - -#; UINT32 Gs, Fs, Es, Ds, Cs, Ss; - movl %ss, %eax - pushl %eax - movzwl 16(%ebp), %eax - pushl %eax - movl %ds, %eax - pushl %eax - movl %es, %eax - pushl %eax - movl %fs, %eax - pushl %eax - movl %gs, %eax - pushl %eax - -#; UINT32 Eip; - movl 12(%ebp), %eax - pushl %eax - -#; UINT32 Gdtr[2], Idtr[2]; - subl $8, %esp - sidt (%esp) - movl 2(%esp), %eax - xchgl (%esp), %eax - andl $0x0FFFF, %eax - movl %eax, 4(%esp) - - subl $8, %esp - sgdt (%esp) - movl 2(%esp), %eax - xchgl (%esp), %eax - andl $0x0FFFF, %eax - movl %eax, 4(%esp) - -#; UINT32 Ldtr, Tr; - xorl %eax, %eax - str %ax - pushl %eax - sldt %ax - pushl %eax - -#; UINT32 EFlags; - movl 20(%ebp), %eax - pushl %eax - -#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; -## insure FXSAVE/FXRSTOR is enabled in CR4... -## ... while we're at it, make sure DE is also enabled... - mov $1, %eax - pushl %ebx # temporarily save value of ebx on stack - cpuid # use CPUID to determine if FXSAVE/FXRESTOR - # and DE are supported - popl %ebx # retore value of ebx that was overwritten - # by CPUID - movl %cr4, %eax - pushl %eax # push cr4 firstly - testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support - jz L1 - orl $BIT9, %eax # Set CR4.OSFXSR -L1: - testl $BIT2, %edx # Test for Debugging Extensions support - jz L2 - orl $BIT3, %eax # Set CR4.DE -L2: - movl %eax, %cr4 - movl %cr3, %eax - pushl %eax - movl %cr2, %eax - pushl %eax - xorl %eax, %eax - pushl %eax - movl %cr0, %eax - pushl %eax - -#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - movl %dr7, %eax - pushl %eax - movl %dr6, %eax - pushl %eax - movl %dr3, %eax - pushl %eax - movl %dr2, %eax - pushl %eax - movl %dr1, %eax - pushl %eax - movl %dr0, %eax - pushl %eax - -#; FX_SAVE_STATE_IA32 FxSaveState; - subl $512, %esp - movl %esp, %edi - testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support. - # edx still contains result from CPUID above - jz L3 - .byte 0x0f, 0x0ae, 0x07 #fxsave [edi] -L3: - -#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear - cld - -#; UINT32 ExceptionData; - pushl 8(%ebp) - -#; Prepare parameter and call - movl %esp, %edx - pushl %edx - movl 4(%ebp), %edx - pushl %edx - - # - # Call External Exception Handler - # - call ASM_PFX(CommonExceptionHandler) - addl $8, %esp - - cli -#; UINT32 ExceptionData; - addl $4, %esp - -#; FX_SAVE_STATE_IA32 FxSaveState; - movl %esp, %esi - movl $1, %eax - cpuid # use CPUID to determine if FXSAVE/FXRESTOR - # are supported - testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support - jz L4 - .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi] -L4: - addl $512, %esp - -#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -#; Skip restoration of DRx registers to support in-circuit emualators -#; or debuggers set breakpoint in interrupt/exception context - addl $24, %esp - -#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - popl %eax - movl %eax, %cr0 - addl $4, %esp # not for Cr1 - popl %eax - movl %eax, %cr2 - popl %eax - movl %eax, %cr3 - popl %eax - movl %eax, %cr4 - -#; UINT32 EFlags; - popl 20(%ebp) - -#; UINT32 Ldtr, Tr; -#; UINT32 Gdtr[2], Idtr[2]; -#; Best not let anyone mess with these particular registers... - addl $24, %esp - -#; UINT32 Eip; - popl 12(%ebp) - -#; UINT32 Gs, Fs, Es, Ds, Cs, Ss; -#; NOTE - modified segment registers could hang the debugger... We -#; could attempt to insulate ourselves against this possibility, -#; but that poses risks as well. -#; - popl %gs - popl %fs - popl %es - popl %ds - popl 16(%ebp) - popl %ss - -#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popl %edi - popl %esi - addl $4, %esp # not for ebp - addl $4, %esp # not for esp - popl %ebx - popl %edx - popl %ecx - popl %eax - - popl -8(%ebp) - popl -4(%ebp) - movl %ebp, %esp - popl %ebp - addl $8, %esp - cmpl $0, -16(%esp) # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - jz DoReturn - cmpl $1, -20(%esp) # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - jz ErrorCode - jmp *-16(%esp) -ErrorCode: - subl $4, %esp - jmp *-12(%esp) - -DoReturn: - cmpl $0, ASM_PFX(mDoFarReturnFlag) - jz DoIret - pushl 8(%esp) # save EFLAGS - addl $16, %esp - pushl -8(%esp) # save CS in new location - pushl -8(%esp) # save EIP in new location - pushl -8(%esp) # save EFLAGS in new location - popfl # restore EFLAGS - lret # far return - -DoIret: - iretl - - -#---------------------------------------; -# _AsmGetTemplateAddressMap ; -#---------------------------------------; -# -# Protocol prototype -# AsmGetTemplateAddressMap ( -# EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap -# ); -# -# Routine Description: -# -# Return address map of interrupt handler template so that C code can generate -# interrupt table. -# -# Arguments: -# -# -# Returns: -# -# Nothing -# -# -# Input: [ebp][0] = Original ebp -# [ebp][4] = Return address -# -# Output: Nothing -# -# Destroys: Nothing -#-----------------------------------------------------------------------------; -#------------------------------------------------------------------------------------- -# AsmGetAddressMap (&AddressMap); -#------------------------------------------------------------------------------------- -ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap) -ASM_PFX(AsmGetTemplateAddressMap): - - pushl %ebp - movl %esp,%ebp - pushal - - movl 0x8(%ebp), %ebx - movl $Exception0Handle, (%ebx) - movl $(Exception1Handle - Exception0Handle), 0x4(%ebx) - movl $(HookAfterStubBegin), 0x8(%ebx) - - popal - popl %ebp - ret -#------------------------------------------------------------------------------------- -# AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr); -#------------------------------------------------------------------------------------- -ASM_GLOBAL ASM_PFX(AsmVectorNumFixup) -ASM_PFX(AsmVectorNumFixup): - movl 8(%esp), %eax - movl 4(%esp), %ecx - movb %al, (VectorNum - HookAfterStubBegin)(%ecx) - ret diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf index e192641db2..f0ad1050d5 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf @@ -30,13 +30,11 @@ [Sources.Ia32] Ia32/ExceptionHandlerAsm.nasm Ia32/ExceptionTssEntryAsm.nasm - Ia32/ExceptionHandlerAsm.S Ia32/ArchExceptionHandler.c Ia32/ArchInterruptDefs.h [Sources.X64] X64/ExceptionHandlerAsm.nasm - X64/ExceptionHandlerAsm.S X64/ArchExceptionHandler.c X64/ArchInterruptDefs.h diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf index 76b8fe8222..1caaf92da4 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf @@ -30,13 +30,11 @@ [Sources.Ia32] Ia32/ExceptionHandlerAsm.nasm Ia32/ExceptionTssEntryAsm.nasm - Ia32/ExceptionHandlerAsm.S Ia32/ArchExceptionHandler.c Ia32/ArchInterruptDefs.h [Sources.X64] X64/ExceptionHandlerAsm.nasm - X64/ExceptionHandlerAsm.S X64/ArchExceptionHandler.c X64/ArchInterruptDefs.h diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf index 6f90302204..feeefcfd8b 100644 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf @@ -30,13 +30,11 @@ [Sources.Ia32] Ia32/ExceptionHandlerAsm.nasm Ia32/ExceptionTssEntryAsm.nasm - Ia32/ExceptionHandlerAsm.S Ia32/ArchExceptionHandler.c Ia32/ArchInterruptDefs.h [Sources.X64] X64/ExceptionHandlerAsm.nasm - X64/ExceptionHandlerAsm.S X64/ArchExceptionHandler.c X64/ArchInterruptDefs.h diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S deleted file mode 100644 index edd363cdaa..0000000000 --- a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S +++ /dev/null @@ -1,434 +0,0 @@ -#------------------------------------------------------------------------------ ; -# Copyright (c) 2012 - 2017, Intel Corporation. All rights reserved.<BR> -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# Module Name: -# -# ExceptionHandlerAsm.S -# -# Abstract: -# -# x64 CPU Exception Handler -# -# Notes: -# -#------------------------------------------------------------------------------ - - - -ASM_GLOBAL ASM_PFX(CommonExceptionHandler) - -#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions -#EXTRN ASM_PFX(mDoFarReturnFlag):QWORD # Do far return flag -.text - -#ifdef __APPLE__ -# macros are different between GNU and Xcode as. -.macro IDT_MACRO - push $0 -#else -.macro IDT_MACRO arg - push \arg -#endif - .byte 0xe9 # jmp ASM_PFX(CommonInterruptEntry) - .long ASM_PFX(CommonInterruptEntry) - . - 4 -.endm - -AsmIdtVectorBegin: - IDT_MACRO $0 - IDT_MACRO $1 - IDT_MACRO $2 - IDT_MACRO $3 - IDT_MACRO $4 - IDT_MACRO $5 - IDT_MACRO $6 - IDT_MACRO $7 - IDT_MACRO $8 - IDT_MACRO $9 - IDT_MACRO $10 - IDT_MACRO $11 - IDT_MACRO $12 - IDT_MACRO $13 - IDT_MACRO $14 - IDT_MACRO $15 - IDT_MACRO $16 - IDT_MACRO $17 - IDT_MACRO $18 - IDT_MACRO $19 - IDT_MACRO $20 - IDT_MACRO $21 - IDT_MACRO $22 - IDT_MACRO $23 - IDT_MACRO $24 - IDT_MACRO $25 - IDT_MACRO $26 - IDT_MACRO $27 - IDT_MACRO $28 - IDT_MACRO $29 - IDT_MACRO $30 - IDT_MACRO $31 -AsmIdtVectorEnd: - -HookAfterStubHeaderBegin: - .byte 0x6a # push -PatchVectorNum: - .byte 0 # 0 will be fixed - .byte 0xe9 # jmp ASM_PFX(HookAfterStubHeaderEnd) -PatchFuncAddress: - .set HOOK_ADDRESS, ASM_PFX(HookAfterStubHeaderEnd) - . - 4 - .long HOOK_ADDRESS # will be fixed -ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd) -ASM_PFX(HookAfterStubHeaderEnd): - pushq %rax - movq %rsp, %rax - andl $0x0fffffff0, %esp # make sure 16-byte aligned for exception context - subq $0x18, %rsp # reserve room for filling exception data later - pushq %rcx - movq 8(%rax), %rcx - bt %ecx, ASM_PFX(mErrorCodeFlag)(%rip) - jnc NoErrorData - pushq (%rsp) # push additional rcx to make stack alignment -NoErrorData: - xchgq (%rsp), %rcx # restore rcx, save Exception Number in stack - movq (%rax), %rax # restore rax - -#---------------------------------------; -# CommonInterruptEntry ; -#---------------------------------------; -# The follow algorithm is used for the common interrupt routine. - -ASM_GLOBAL ASM_PFX(CommonInterruptEntry) -ASM_PFX(CommonInterruptEntry): - cli - # - # All interrupt handlers are invoked through interrupt gates, so - # IF flag automatically cleared at the entry point - # - # - # Calculate vector number - # - xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number. - andq $0x0FF, %rcx - cmp $32, %ecx # Intel reserved vector for exceptions? - jae NoErrorCode - pushq %rax - movl ASM_PFX(mErrorCodeFlag)(%rip), %eax - bt %ecx, %eax - popq %rax - jc CommonInterruptEntry_al_0000 - -NoErrorCode: - - # - # Push a dummy error code on the stack - # to maintain coherent stack map - # - pushq (%rsp) - movq $0, 8(%rsp) -CommonInterruptEntry_al_0000: - pushq %rbp - movq %rsp, %rbp - pushq $0 # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - pushq $0 # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - - # - # Stack: - # +---------------------+ <-- 16-byte aligned ensured by processor - # + Old SS + - # +---------------------+ - # + Old RSP + - # +---------------------+ - # + RFlags + - # +---------------------+ - # + CS + - # +---------------------+ - # + RIP + - # +---------------------+ - # + Error Code + - # +---------------------+ - # + RCX / Vector Number + - # +---------------------+ - # + RBP + - # +---------------------+ <-- RBP, 16-byte aligned - # - - - # - # Since here the stack pointer is 16-byte aligned, so - # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64 - # is 16-byte aligned - # - -#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - pushq %r15 - pushq %r14 - pushq %r13 - pushq %r12 - pushq %r11 - pushq %r10 - pushq %r9 - pushq %r8 - pushq %rax - pushq 8(%rbp) # RCX - pushq %rdx - pushq %rbx - pushq 48(%rbp) # RSP - pushq (%rbp) # RBP - pushq %rsi - pushq %rdi - -#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - movzwq 56(%rbp), %rax - pushq %rax # for ss - movzwq 32(%rbp), %rax - pushq %rax # for cs - mov %ds, %rax - pushq %rax - mov %es, %rax - pushq %rax - mov %fs, %rax - pushq %rax - mov %gs, %rax - pushq %rax - - movq %rcx, 8(%rbp) # save vector number - -#; UINT64 Rip; - pushq 24(%rbp) - -#; UINT64 Gdtr[2], Idtr[2]; - xorq %rax, %rax - pushq %rax - pushq %rax - sidt (%rsp) - xchgq 2(%rsp), %rax - xchgq (%rsp), %rax - xchgq 8(%rsp), %rax - - xorq %rax, %rax - pushq %rax - pushq %rax - sgdt (%rsp) - xchgq 2(%rsp), %rax - xchgq (%rsp), %rax - xchgq 8(%rsp), %rax - -#; UINT64 Ldtr, Tr; - xorq %rax, %rax - str %ax - pushq %rax - sldt %ax - pushq %rax - -#; UINT64 RFlags; - pushq 40(%rbp) - -#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - movq %cr8, %rax - pushq %rax - movq %cr4, %rax - orq $0x208, %rax - movq %rax, %cr4 - pushq %rax - mov %cr3, %rax - pushq %rax - mov %cr2, %rax - pushq %rax - xorq %rax, %rax - pushq %rax - mov %cr0, %rax - pushq %rax - -#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - movq %dr7, %rax - pushq %rax - movq %dr6, %rax - pushq %rax - movq %dr3, %rax - pushq %rax - movq %dr2, %rax - pushq %rax - movq %dr1, %rax - pushq %rax - movq %dr0, %rax - pushq %rax - -#; FX_SAVE_STATE_X64 FxSaveState; - subq $512, %rsp - movq %rsp, %rdi - .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi] - -#; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear - cld - -#; UINT32 ExceptionData; - pushq 16(%rbp) - -#; Prepare parameter and call - mov 8(%rbp), %rcx - mov %rsp, %rdx - # - # Per X64 calling convention, allocate maximum parameter stack space - # and make sure RSP is 16-byte aligned - # - subq $40, %rsp - call ASM_PFX(CommonExceptionHandler) - addq $40, %rsp - - cli -#; UINT64 ExceptionData; - addq $8, %rsp - -#; FX_SAVE_STATE_X64 FxSaveState; - - movq %rsp, %rsi - .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi] - addq $512, %rsp - -#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -#; Skip restoration of DRx registers to support in-circuit emualators -#; or debuggers set breakpoint in interrupt/exception context - addq $48, %rsp - -#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - popq %rax - movq %rax, %cr0 - addq $8, %rsp # not for Cr1 - popq %rax - movq %rax, %cr2 - popq %rax - movq %rax, %cr3 - popq %rax - movq %rax, %cr4 - popq %rax - movq %rax, %cr8 - -#; UINT64 RFlags; - popq 40(%rbp) - -#; UINT64 Ldtr, Tr; -#; UINT64 Gdtr[2], Idtr[2]; -#; Best not let anyone mess with these particular registers... - addq $48, %rsp - -#; UINT64 Rip; - popq 24(%rbp) - -#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; - popq %rax - # mov %rax, %gs ; not for gs - popq %rax - # mov %rax, %fs ; not for fs - # (X64 will not use fs and gs, so we do not restore it) - popq %rax - mov %rax, %es - popq %rax - mov %rax, %ds - popq 32(%rbp) # for cs - popq 56(%rbp) # for ss - -#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - popq %rdi - popq %rsi - addq $8, %rsp # not for rbp - popq 48(%rbp) # for rsp - popq %rbx - popq %rdx - popq %rcx - popq %rax - popq %r8 - popq %r9 - popq %r10 - popq %r11 - popq %r12 - popq %r13 - popq %r14 - popq %r15 - - movq %rbp, %rsp - popq %rbp - addq $16, %rsp - cmpq $0, -32(%rsp) # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler - jz DoReturn # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag - cmpb $1, -40(%rsp) - jz ErrorCode - jmp *-32(%rsp) -ErrorCode: - subq $8, %rsp - jmp *-24(%rsp) - -DoReturn: - pushq %rax - movq ASM_PFX(mDoFarReturnFlag)(%rip), %rax - cmpq $0, %rax # Check if need to do far return instead of IRET - popq %rax - jz DoIret - pushq %rax - movq %rsp, %rax # save old RSP to rax - movq 0x20(%rsp), %rsp - pushq 0x10(%rax) # save CS in new location - pushq 0x8(%rax) # save EIP in new location - pushq 0x18(%rax) # save EFLAGS in new location - movq (%rax), %rax # restore rax - popfq # restore EFLAGS - lretq # far return -DoIret: - iretq - - -#------------------------------------------------------------------------------------- -# AsmGetTemplateAddressMap (&AddressMap); -#------------------------------------------------------------------------------------- -# comments here for definition of address map -ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap) -ASM_PFX(AsmGetTemplateAddressMap): - pushq %rbp - movq %rsp, %rbp - - leaq AsmIdtVectorBegin(%rip), %rax - movq %rax, (%rcx) - .set ENTRY_SIZE, ASM_PFX(HookAfterStubHeaderEnd) - HookAfterStubHeaderBegin - movq $(ENTRY_SIZE), 0x08(%rcx) - leaq HookAfterStubHeaderBegin(%rip), %rax - movq %rax, 0x10(%rcx) - - popq %rbp - ret - -#------------------------------------------------------------------------------------- -# VOID -# EFIAPI -# AsmVectorNumFixup ( -# IN VOID *NewVectorAddr, // RCX -# IN UINT8 VectorNum // RDX -# IN VOID *OldVectorAddr, // R8 -# ); -#------------------------------------------------------------------------------------- -ASM_GLOBAL ASM_PFX(AsmVectorNumFixup) -ASM_PFX(AsmVectorNumFixup): - pushq %rbp - movq %rsp, %rbp - -# Patch vector # - movb %dl, (PatchVectorNum - HookAfterStubHeaderBegin)(%rcx) - -# Patch Function address - subq %rcx, %r8 # Calculate the offset value - movl (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx), %eax - addq %r8, %rax - movl %eax, (PatchFuncAddress - HookAfterStubHeaderBegin)(%rcx) - - popq %rbp - ret - -#END - - -- 2.18.0.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel