From 8f07f895fb03800e54c23225639116f34d2ce7b1 Mon Sep 17 00:00:00 2001 From: vanjeff Date: Thu, 15 Mar 2012 05:24:07 +0000 Subject: Import two CPU Exception Handler Library instances: SecPeiCpuExceptionHandler.inf and DxeSmmCpuExceptionHandler.inf. Signed-off-by: vanjeff Reviewed-by: jyao1 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13098 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Ia32/ExceptionHandlerAsm.S | 467 +++++++++++++++++++++ 1 file changed, 467 insertions(+) create mode 100644 UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S (limited to 'UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S') diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S new file mode 100644 index 0000000000..8b3f6319b6 --- /dev/null +++ b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S @@ -0,0 +1,467 @@ +#------------------------------------------------------------------------------ +#* +#* Copyright (c) 2012, Intel Corporation. All rights reserved.
+#* 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) + +#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions + +.text + +# +# exception handler stub table +# +Exception0Handle: + pushl $0 + jmp ASM_PFX(CommonInterruptEntry) +Exception1Handle: + pushl $1 + jmp ASM_PFX(CommonInterruptEntry) +Exception2Handle: + pushl $2 + jmp ASM_PFX(CommonInterruptEntry) +Exception3Handle: + pushl $3 + jmp ASM_PFX(CommonInterruptEntry) +Exception4Handle: + pushl $4 + jmp ASM_PFX(CommonInterruptEntry) +Exception5Handle: + pushl $5 + jmp ASM_PFX(CommonInterruptEntry) +Exception6Handle: + pushl $6 + jmp ASM_PFX(CommonInterruptEntry) +Exception7Handle: + pushl $7 + jmp ASM_PFX(CommonInterruptEntry) +Exception8Handle: + pushl $8 + jmp ASM_PFX(CommonInterruptEntry) +Exception9Handle: + pushl $9 + jmp ASM_PFX(CommonInterruptEntry) +Exception10Handle: + pushl $10 + jmp ASM_PFX(CommonInterruptEntry) +Exception11Handle: + pushl $11 + jmp ASM_PFX(CommonInterruptEntry) +Exception12Handle: + pushl $12 + jmp ASM_PFX(CommonInterruptEntry) +Exception13Handle: + pushl $13 + jmp ASM_PFX(CommonInterruptEntry) +Exception14Handle: + pushl $14 + jmp ASM_PFX(CommonInterruptEntry) +Exception15Handle: + pushl $15 + jmp ASM_PFX(CommonInterruptEntry) +Exception16Handle: + pushl $16 + jmp ASM_PFX(CommonInterruptEntry) +Exception17Handle: + pushl $17 + jmp ASM_PFX(CommonInterruptEntry) +Exception18Handle: + pushl $18 + jmp ASM_PFX(CommonInterruptEntry) +Exception19Handle: + pushl $19 + jmp ASM_PFX(CommonInterruptEntry) +Exception20Handle: + pushl $20 + jmp ASM_PFX(CommonInterruptEntry) +Exception21Handle: + pushl $21 + jmp ASM_PFX(CommonInterruptEntry) +Exception22Handle: + pushl $22 + jmp ASM_PFX(CommonInterruptEntry) +Exception23Handle: + pushl $23 + jmp ASM_PFX(CommonInterruptEntry) +Exception24Handle: + pushl $24 + jmp ASM_PFX(CommonInterruptEntry) +Exception25Handle: + pushl $25 + jmp ASM_PFX(CommonInterruptEntry) +Exception26Handle: + pushl $26 + jmp ASM_PFX(CommonInterruptEntry) +Exception27Handle: + pushl $27 + jmp ASM_PFX(CommonInterruptEntry) +Exception28Handle: + pushl $28 + jmp ASM_PFX(CommonInterruptEntry) +Exception29Handle: + pushl $29 + jmp ASM_PFX(CommonInterruptEntry) +Exception30Handle: + pushl $30 + jmp ASM_PFX(CommonInterruptEntry) +Exception31Handle: + pushl $31 + jmp ASM_PFX(CommonInterruptEntry) + +#---------------------------------------; +# 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 + # + # Get the return address of call, actually, it is the + # address of vector number. + # + xchgl (%esp), %ecx + andl $0x0FFFF, %ecx + 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 + + # + # Fall through to join main routine code + # at ErrorCodeAndVectorOnStack + # +CommonInterruptEntry_al_0000: + jmp CommonInterruptEntry_al_0000 + +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 + +#; 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; + movl %cr4, %eax + orl $0x208, %eax + movl %eax, %cr4 + pushl %eax + 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 + .byte 0x0f, 0x0ae, 0x07 #fxsave [edi] + +#; 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 + .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi] + 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 + + movl %ebp, %esp + popl %ebp + addl $8, %esp + iretl + + +#---------------------------------------; +# _GetTemplateAddressMap ; +#----------------------------------------------------------------------------; +# +# Protocol prototype +# GetTemplateAddressMap ( +# 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(GetTemplateAddressMap) +ASM_PFX(GetTemplateAddressMap): + + pushl %ebp + movl %esp,%ebp + pushal + + movl 0x8(%ebp), %ebx + movl $Exception0Handle, (%ebx) + movl $(Exception1Handle - Exception0Handle), 0x4(%ebx) + + popal + popl %ebp + ret + -- cgit v1.2.3