From c23f114d3cfbb29b8734b87213d1ec0de404197b Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 27 Apr 2017 11:05:07 +0800 Subject: MdeModulePkg: Move to new location Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../Universal/DebugSupportDxe/DebugSupport.c | 133 -- .../Universal/DebugSupportDxe/DebugSupportDxe.inf | 89 -- .../Universal/DebugSupportDxe/DebugSupportDxe.uni | 24 - .../DebugSupportDxe/DebugSupportDxeExtra.uni | 19 - .../Universal/DebugSupportDxe/Ia32/AsmFuncs.S | 407 ------ .../Universal/DebugSupportDxe/Ia32/AsmFuncs.asm | 509 ------- .../Universal/DebugSupportDxe/Ia32/AsmFuncs.nasm | 499 ------- .../Universal/DebugSupportDxe/Ia32/DebugSupport.h | 298 ----- .../DebugSupportDxe/Ia32/PlDebugSupport.c | 373 ------ .../DebugSupportDxe/Ia32/PlDebugSupport.h | 22 - .../DebugSupportDxe/Ia32/PlDebugSupportIa32.c | 145 -- .../Universal/DebugSupportDxe/Ipf/AsmFuncs.s | 1382 -------------------- .../Universal/DebugSupportDxe/Ipf/Common.i | 29 - .../Universal/DebugSupportDxe/Ipf/Ds64Macros.i | 78 -- .../Universal/DebugSupportDxe/Ipf/PlDebugSupport.c | 467 ------- .../Universal/DebugSupportDxe/Ipf/PlDebugSupport.h | 324 ----- .../Universal/DebugSupportDxe/X64/AsmFuncs.S | 551 -------- .../Universal/DebugSupportDxe/X64/AsmFuncs.asm | 596 --------- .../Universal/DebugSupportDxe/X64/AsmFuncs.nasm | 587 --------- .../Universal/DebugSupportDxe/X64/PlDebugSupport.h | 22 - .../DebugSupportDxe/X64/PlDebugSupportX64.c | 146 --- 21 files changed, 6700 deletions(-) delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/DebugSupport.c delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.uni delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxeExtra.uni delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.S delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.nasm delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ipf/AsmFuncs.s delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ipf/Common.i delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ipf/Ds64Macros.i delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.c delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.nasm delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h delete mode 100644 MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c (limited to 'MdeModulePkg/Universal/DebugSupportDxe') diff --git a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupport.c deleted file mode 100644 index 9a8f86de10..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupport.c +++ /dev/null @@ -1,133 +0,0 @@ -/** @file - Top level C file for debug support driver. Contains initialization function. - -Copyright (c) 2006 - 2009, 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. - -**/ - -#include "PlDebugSupport.h" - -EFI_DEBUG_SUPPORT_PROTOCOL mDebugSupportProtocolInterface = { - EFI_ISA, - GetMaximumProcessorIndex, - RegisterPeriodicCallback, - RegisterExceptionCallback, - InvalidateInstructionCache -}; - - -/** - Debug Support Driver entry point. - - Checks to see if there's not already a Debug Support protocol installed for - the selected processor before installing it. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval EFI_ALREADY_STARTED Debug Support protocol is installed already. - @retval other Some error occurs when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -InitializeDebugSupportDriver ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocolPtr; - EFI_STATUS Status; - EFI_HANDLE Handle; - EFI_HANDLE *HandlePtr; - UINTN NumHandles; - EFI_DEBUG_SUPPORT_PROTOCOL *DebugSupportProtocolPtr; - - // - // First check to see that the debug support protocol for this processor - // type is not already installed - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiDebugSupportProtocolGuid, - NULL, - &NumHandles, - &HandlePtr - ); - - if (Status != EFI_NOT_FOUND) { - do { - NumHandles--; - Status = gBS->OpenProtocol ( - HandlePtr[NumHandles], - &gEfiDebugSupportProtocolGuid, - (VOID **) &DebugSupportProtocolPtr, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if ((Status == EFI_SUCCESS) && (DebugSupportProtocolPtr->Isa == EFI_ISA)) { - // - // a Debug Support protocol has been installed for this processor - // - FreePool (HandlePtr); - Status = EFI_ALREADY_STARTED; - goto ErrExit; - } - } while (NumHandles > 0); - FreePool (HandlePtr); - } - - // - // Get our image information and install platform specific unload handler - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID **) &LoadedImageProtocolPtr, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT (!EFI_ERROR (Status)); - if (Status != EFI_SUCCESS) { - goto ErrExit; - } - - LoadedImageProtocolPtr->Unload = PlUnloadDebugSupportDriver; - - // - // Call hook for processor specific initialization - // - Status = PlInitializeDebugSupportDriver (); - ASSERT (!EFI_ERROR (Status)); - if (Status != EFI_SUCCESS) { - goto ErrExit; - } - - // - // Install Debug Support protocol to new handle - // - Handle = NULL; - Status = gBS->InstallProtocolInterface ( - &Handle, - &gEfiDebugSupportProtocolGuid, - EFI_NATIVE_INTERFACE, - &mDebugSupportProtocolInterface - ); - ASSERT (!EFI_ERROR (Status)); - if (Status != EFI_SUCCESS) { - goto ErrExit; - } - -ErrExit: - return Status; -} diff --git a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf deleted file mode 100644 index 72a5dadb29..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf +++ /dev/null @@ -1,89 +0,0 @@ -## @file -# This driver installs Debug Support protocol for the selected processor. -# -# This driver provides the capabilities for debug-agent to gain control of the machine -# when certain types of events occur, i.e. breakpoint, processor execptions, etc. It also -# provides debug-agent to periodically gain control during operation of the machine to -# check for asynchronous commands form the host. -# -# Copyright (c) 2006 - 2016, 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. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = DebugSupportDxe - MODULE_UNI_FILE = DebugSupportDxe.uni - FILE_GUID = 911D584C-35F7-4955-BEF9-B452769DDC3A - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = InitializeDebugSupportDriver - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF -# - -[Sources] - DebugSupport.c - -[Sources.Ia32] - Ia32/DebugSupport.h - Ia32/PlDebugSupport.c - Ia32/PlDebugSupport.h - Ia32/PlDebugSupportIa32.c - Ia32/AsmFuncs.nasm - Ia32/AsmFuncs.S - Ia32/AsmFuncs.asm - -[Sources.X64] - Ia32/DebugSupport.h - Ia32/PlDebugSupport.c - X64/PlDebugSupport.h - X64/PlDebugSupportX64.c - X64/AsmFuncs.nasm - X64/AsmFuncs.S - X64/AsmFuncs.asm - -[Sources.IPF] - Ipf/PlDebugSupport.h - Ipf/PlDebugSupport.c - Ipf/Ds64Macros.i - Ipf/Common.i - Ipf/AsmFuncs.s - - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - - -[LibraryClasses] - UefiBootServicesTableLib - MemoryAllocationLib - BaseMemoryLib - UefiDriverEntryPoint - DebugLib - -[LibraryClasses.IA32, LibraryClasses.X64] - BaseLib - -[Protocols] - gEfiLoadedImageProtocolGuid ## CONSUMES - gEfiDebugSupportProtocolGuid ## PRODUCES - - -[Depex] - TRUE - -[UserExtensions.TianoCore."ExtraFiles"] - DebugSupportDxeExtra.uni diff --git a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.uni b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.uni deleted file mode 100644 index e6bbf1e565..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.uni +++ /dev/null @@ -1,24 +0,0 @@ -// /** @file -// This driver installs Debug Support protocol for the selected processor. -// -// This driver provides the capabilities for debug-agent to gain control of the machine -// when certain types of events occur, i.e. breakpoint, processor execptions, etc. It also -// provides debug-agent to periodically gain control during operation of the machine to -// check for asynchronous commands form the host. -// -// Copyright (c) 2006 - 2014, 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. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Installs Debug Support protocol for the selected processor" - -#string STR_MODULE_DESCRIPTION #language en-US "This driver provides the capabilities for debug-agent to gain control of the machine when certain types of events occur, i.e. breakpoint, processor exceptions, etc. It also provides debug-agent to periodically gain control during operation of the machine to check for asynchronous commands from the host." - diff --git a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxeExtra.uni b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxeExtra.uni deleted file mode 100644 index 9e92374696..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxeExtra.uni +++ /dev/null @@ -1,19 +0,0 @@ -// /** @file -// DebugSupportDxe Localized Strings and Content -// -// Copyright (c) 2013 - 2014, 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. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Debug Support DXE Driver" - - diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.S b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.S deleted file mode 100644 index fd1a96b76f..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.S +++ /dev/null @@ -1,407 +0,0 @@ -#/**@file -# Low leve IA32 specific debug support functions. -# -# Copyright (c) 2006 - 2011, 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. -# -#**/ - -ASM_GLOBAL ASM_PFX(OrigVector) -ASM_GLOBAL ASM_PFX(InterruptEntryStub) -ASM_GLOBAL ASM_PFX(StubSize) -ASM_GLOBAL ASM_PFX(CommonIdtEntry) -ASM_GLOBAL ASM_PFX(FxStorSupport) - -ASM_PFX(StubSize): .long ASM_PFX(InterruptEntryStubEnd) - ASM_PFX(InterruptEntryStub) -ASM_PFX(AppEsp): .long 0x11111111 # ? -ASM_PFX(DebugEsp): .long 0x22222222 # ? -ASM_PFX(ExtraPush): .long 0x33333333 # ? -ASM_PFX(ExceptData): .long 0x44444444 # ? -ASM_PFX(Eflags): .long 0x55555555 # ? -ASM_PFX(OrigVector): .long 0x66666666 # ? - -#------------------------------------------------------------------------------ -# BOOLEAN -# FxStorSupport ( -# void -# ) -# -# Abstract: Returns TRUE if FxStor instructions are supported -# -ASM_GLOBAL ASM_PFX(FxStorSupport) -ASM_PFX(FxStorSupport): -# -# cpuid corrupts ebx which must be preserved per the C calling convention -# - push %ebx - mov $0x1,%eax - cpuid - mov %edx,%eax - and $0x1000000,%eax - shr $0x18,%eax - pop %ebx - ret -#------------------------------------------------------------------------------ -# void -# Vect2Desc ( -# DESCRIPTOR * DestDesc, -# void (*Vector) (void) -# ) -# -# Abstract: Encodes an IDT descriptor with the given physical address -# - -ASM_GLOBAL ASM_PFX(Vect2Desc) -ASM_PFX(Vect2Desc): - push %ebp - mov %esp,%ebp - mov 0xc(%ebp),%eax - mov 0x8(%ebp),%ecx - mov %ax,(%ecx) - movw $0x20,0x2(%ecx) - movw $0x8e00,0x4(%ecx) - shr $0x10,%eax - mov %ax,0x6(%ecx) - leave - ret - -ASM_GLOBAL ASM_PFX(InterruptEntryStub) -ASM_PFX(InterruptEntryStub): - mov %esp,0x0 # save stack top - mov $0x0,%esp # switch to debugger stack - push $0x0 # push vector number - will be modified before installed - jmp ASM_PFX(CommonIdtEntry) # jump CommonIdtEntry -ASM_GLOBAL ASM_PFX(InterruptEntryStubEnd) -ASM_PFX(InterruptEntryStubEnd): - -#------------------------------------------------------------------------------ -# CommonIdtEntry -# -# Abstract: This code is not a function, but is the common part for all IDT -# vectors. -# -ASM_GLOBAL ASM_PFX(CommonIdtEntry) -ASM_PFX(CommonIdtEntry): -## -## At this point, the stub has saved the current application stack esp into AppEsp -## and switched stacks to the debug stack, where it pushed the vector number -## -## The application stack looks like this: -## -## ... -## (last application stack entry) -## eflags from interrupted task -## CS from interrupted task -## EIP from interrupted task -## Error code <-------------------- Only present for some exeption types -## -## - - -## The stub switched us to the debug stack and pushed the interrupt number. -## -## Next, construct the context record. It will be build on the debug stack by -## pushing the registers in the correct order so as to create the context structure -## on the debug stack. The context record must be built from the end back to the -## beginning because the stack grows down... -# -## For reference, the context record looks like this: -## -## typedef -## struct { -## UINT32 ExceptionData; -## FX_SAVE_STATE_IA32 FxSaveState; -## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -## UINT32 Cr0, Cr2, Cr3, Cr4; -## UINT32 EFlags; -## UINT32 Ldtr, Tr; -## UINT32 Gdtr[2], Idtr[2]; -## UINT32 Eip; -## UINT32 Gs, Fs, Es, Ds, Cs, Ss; -## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; -## } SYSTEM_CONTEXT_IA32; // 32 bit system context record - -## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - pusha -## Save interrupt state eflags register... - pushf - pop %eax -## We need to determine if any extra data was pushed by the exception, and if so, save it -## To do this, we check the exception number pushed by the stub, and cache the -## result in a variable since we'll need this again. - mov %eax,0x0 - cmpl $0x8,0x0 - jne ASM_PFX(CommonIdtEntry+0x20) - movl $0x1,0x0 - jmp ASM_PFX(CommonIdtEntry+0xa8) - cmpl $0xa,0x0 - jne ASM_PFX(CommonIdtEntry+0x35) - movl $0x1,0x0 - jmp ASM_PFX(CommonIdtEntry+0xa8) - cmpl $0xb,0x0 - jne ASM_PFX(CommonIdtEntry+0x4a) - movl $0x1,0x0 - jmp ASM_PFX(CommonIdtEntry+0xa8) - cmpl $0xc,0x0 - jne ASM_PFX(CommonIdtEntry+0x5f) - movl $0x1,0x0 - jmp ASM_PFX(CommonIdtEntry+0xa8) - cmpl $0xd,0x0 - jne ASM_PFX(CommonIdtEntry+0x74) - movl $0x1,0x0 - jmp ASM_PFX(CommonIdtEntry+0xa8) - cmpl $0xe,0x0 - jne ASM_PFX(CommonIdtEntry+0x89) - movl $0x1,0x0 - jmp ASM_PFX(CommonIdtEntry+0xa8) - cmpl $0x11,0x0 - jne ASM_PFX(CommonIdtEntry+0x9e) - movl $0x1,0x0 - jmp ASM_PFX(CommonIdtEntry+0xa8) - movl $0x0,0x0 -## If there's some extra data, save it also, and modify the saved AppEsp to effectively -## pop this value off the application's stack. - - cmpl $0x1,0x0 - jne ASM_PFX(CommonIdtEntry+0xc8) - mov 0x0,%eax - mov (%eax),%ebx - mov %ebx,0x0 - add $0x4,%eax - mov %eax,0x0 - jmp ASM_PFX(CommonIdtEntry+0xd2) - movl $0x0,0x0 -## The "pushad" above pushed the debug stack esp. Since what we're actually doing -## is building the context record on the debug stack, we need to save the pushed -## debug ESP, and replace it with the application's last stack entry... - mov 0xc(%esp),%eax - mov %eax,0x0 - mov 0x0,%eax - add $0xc,%eax - # application stack has eflags, cs, & eip, so - # last actual application stack entry is - # 12 bytes into the application stack. - mov %eax,0xc(%esp) -## continue building context record -## UINT32 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - mov %ss,%eax - push %eax - - # CS from application is one entry back in application stack - mov 0x0,%eax - movzwl 0x4(%eax),%eax - push %eax - mov %ds,%eax - push %eax - mov %es,%eax - push %eax - mov %fs,%eax - push %eax - mov %gs,%eax - push %eax - -## UINT32 Eip; - # Eip from application is on top of application stack - mov 0x0,%eax - pushl (%eax) - -## UINT32 Gdtr[2], Idtr[2]; - push $0x0 - push $0x0 - sidtl (%esp) - push $0x0 - push $0x0 - sgdtl (%esp) - -## UINT32 Ldtr, Tr; - xor %eax,%eax - str %eax - push %eax - sldt %eax - push %eax - -## UINT32 EFlags; -## Eflags from application is two entries back in application stack - mov 0x0,%eax - pushl 0x8(%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 %cr4,%eax - or $0x208,%eax - mov %eax,%cr4 - push %eax - mov %cr3,%eax - push %eax - mov %cr2,%eax - push %eax - push $0x0 - mov %cr0,%eax - push %eax - -## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - mov %db7,%eax - push %eax - -## clear Dr7 while executing debugger itself - xor %eax,%eax - mov %eax,%db7 - mov %db6,%eax - push %eax - -## insure all status bits in dr6 are clear... - xor %eax,%eax - mov %eax,%db6 - mov %db3,%eax - push %eax - mov %db2,%eax - push %eax - mov %db1,%eax - push %eax - mov %db0,%eax - push %eax - -## FX_SAVE_STATE_IA32 FxSaveState; - sub $0x200,%esp - mov %esp,%edi - # IMPORTANT!! The debug stack has been carefully constructed to - # insure that esp and edi are 16 byte aligned when we get here. - # They MUST be. If they are not, a GP fault will occur. - fxsave (%edi) - -## UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear - cld - -## UINT32 ExceptionData; - mov 0x0,%eax - push %eax - -# call to C code which will in turn call registered handler -# pass in the vector number - mov %esp,%eax - push %eax - mov 0x0,%eax - push %eax - call ASM_PFX(CommonIdtEntry+0x184) - add $0x8,%esp - -# restore context... -## UINT32 ExceptionData; - add $0x4,%esp - -## FX_SAVE_STATE_IA32 FxSaveState; - mov %esp,%esi - fxrstor (%esi) - add $0x200,%esp - -## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - pop %eax - mov %eax,%db0 - pop %eax - mov %eax,%db1 - pop %eax - mov %eax,%db2 - pop %eax - mov %eax,%db3 - -## skip restore of dr6. We cleared dr6 during the context save. - add $0x4,%esp - pop %eax - mov %eax,%db7 - -## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - pop %eax - mov %eax,%cr0 - add $0x4,%esp - pop %eax - mov %eax,%cr2 - pop %eax - mov %eax,%cr3 - pop %eax - mov %eax,%cr4 - -## UINT32 EFlags; - mov 0x0,%eax - popl 0x8(%eax) - -## UINT32 Ldtr, Tr; -## UINT32 Gdtr[2], Idtr[2]; -## Best not let anyone mess with these particular registers... - add $0x18,%esp - -## UINT32 Eip; - popl (%eax) - -## UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs; -## NOTE - modified segment registers could hang the debugger... We -## could attempt to insulate ourselves against this possibility, -## but that poses risks as well. -## - - pop %gs - pop %fs - pop %es - pop %ds - popl 0x4(%eax) - pop %ss - mov 0xc(%esp),%ebx - -## The next stuff to restore is the general purpose registers that were pushed -## using the "pushad" instruction. -## -## The value of ESP as stored in the context record is the application ESP -## including the 3 entries on the application stack caused by the exception -## itself. It may have been modified by the debug agent, so we need to -## determine if we need to relocate the application stack. - - mov 0x0,%eax # move the potentially modified AppEsp into ebx - add $0xc,%eax - cmp %eax,%ebx - je ASM_PFX(CommonIdtEntry+0x202) - mov 0x0,%eax - mov (%eax),%ecx # EIP - mov %ecx,(%ebx) - mov 0x4(%eax),%ecx # CS - mov %ecx,0x4(%ebx) - mov 0x8(%eax),%ecx # EFLAGS - mov %ecx,0x8(%ebx) - - mov %ebx,%eax # modify the saved AppEsp to the new AppEsp - mov %eax,0x0 - mov 0x0,%eax # restore the DebugEsp on the debug stack - # so our "popad" will not cause a stack switch - mov %eax,0xc(%esp) - cmpl $0x68,0x0 - jne PhonyIretd+0xd -## Restore eflags so when we chain, the flags will be exactly as if we were never here. -## We gin up the stack to do an iretd so we can get ALL the flags. - mov 0x0,%eax - mov 0x8(%eax),%ebx - and $0xfffffcff,%ebx # special handling for IF and TF - push %ebx - push %cs - push $0x0 - iret - -PhonyIretd: -## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popa - -## Switch back to application stack - mov 0x0,%esp - jmp *0x0 -## Jump to original handler -## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popa -## Switch back to application stack - mov 0x0,%esp - -## We're outa here... - iret diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm deleted file mode 100644 index 32cbc31654..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm +++ /dev/null @@ -1,509 +0,0 @@ -;/** @file -; Low leve IA32 specific debug support functions. -; -; Copyright (c) 2006 - 2011, 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. -; -;**/ - -.586p -.MODEL FLAT, C - -EXCPT32_DIVIDE_ERROR EQU 0 -EXCPT32_DEBUG EQU 1 -EXCPT32_NMI EQU 2 -EXCPT32_BREAKPOINT EQU 3 -EXCPT32_OVERFLOW EQU 4 -EXCPT32_BOUND EQU 5 -EXCPT32_INVALID_OPCODE EQU 6 -EXCPT32_DOUBLE_FAULT EQU 8 -EXCPT32_INVALID_TSS EQU 10 -EXCPT32_SEG_NOT_PRESENT EQU 11 -EXCPT32_STACK_FAULT EQU 12 -EXCPT32_GP_FAULT EQU 13 -EXCPT32_PAGE_FAULT EQU 14 -EXCPT32_FP_ERROR EQU 16 -EXCPT32_ALIGNMENT_CHECK EQU 17 -EXCPT32_MACHINE_CHECK EQU 18 -EXCPT32_SIMD EQU 19 - -FXSTOR_FLAG EQU 01000000h ; bit cpuid 24 of feature flags - -;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87, -;; MMX, SSE, SSE2, etc registers. The initialization of the debugsupport driver -;; MUST check the CPUID feature flags to see that these instructions are available -;; and fail to init if they are not. - -;; fxstor [edi] -FXSTOR_EDI MACRO - db 0fh, 0aeh, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [edi] -ENDM - -;; fxrstor [esi] -FXRSTOR_ESI MACRO - db 0fh, 0aeh, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [esi] -ENDM -.DATA - -public OrigVector, InterruptEntryStub, StubSize, CommonIdtEntry, FxStorSupport - -StubSize dd InterruptEntryStubEnd - InterruptEntryStub -AppEsp dd 11111111h ; ? -DebugEsp dd 22222222h ; ? -ExtraPush dd 33333333h ; ? -ExceptData dd 44444444h ; ? -Eflags dd 55555555h ; ? -OrigVector dd 66666666h ; ? - -;; The declarations below define the memory region that will be used for the debug stack. -;; The context record will be built by pushing register values onto this stack. -;; It is imparitive that alignment be carefully managed, since the FXSTOR and -;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned. -;; -;; The stub will switch stacks from the application stack to the debuger stack -;; and pushes the exception number. -;; -;; Then we building the context record on the stack. Since the stack grows down, -;; we push the fields of the context record from the back to the front. There -;; are 132 bytes of stack used prior allocating the 512 bytes of stack to be -;; used as the memory buffer for the fxstor instruction. Therefore address of -;; the buffer used for the FXSTOR instruction is &Eax - 132 - 512, which -;; must be 16 byte aligned. -;; -;; We carefully locate the stack to make this happen. -;; -;; For reference, the context structure looks like this: -;; struct { -;; UINT32 ExceptionData; -;; FX_SAVE_STATE_IA32 FxSaveState; // 512 bytes, must be 16 byte aligned -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; -;; UINT32 EFlags; -;; UINT32 Ldtr, Tr; -;; UINT32 Gdtr[2], Idtr[2]; -;; UINT32 Eip; -;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; -;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record - - -align 16 -DebugStackEnd db "DbgStkEnd >>>>>>" ;; 16 byte long string - must be 16 bytes to preserve alignment - dd 1ffdh dup (000000000h) ;; 32K should be enough stack - ;; This allocation is coocked to insure - ;; that the the buffer for the FXSTORE instruction - ;; will be 16 byte aligned also. - ;; -ExceptionNumber dd ? ;; first entry will be the vector number pushed by the stub - -DebugStackBegin db "<<<< DbgStkBegin" ;; initial debug ESP == DebugStackBegin, set in stub - -.CODE - -externdef InterruptDistrubutionHub:near - -;------------------------------------------------------------------------------ -; BOOLEAN -; FxStorSupport ( -; void -; ) -; -; Abstract: Returns TRUE if FxStor instructions are supported -; -FxStorSupport PROC C PUBLIC - -; -; cpuid corrupts ebx which must be preserved per the C calling convention -; - push ebx - mov eax, 1 - cpuid - mov eax, edx - and eax, FXSTOR_FLAG - shr eax, 24 - pop ebx - ret -FxStorSupport ENDP - - - -;------------------------------------------------------------------------------ -; void -; Vect2Desc ( -; DESCRIPTOR * DestDesc, -; void (*Vector) (void) -; ) -; -; Abstract: Encodes an IDT descriptor with the given physical address -; -Vect2Desc PROC C PUBLIC DestPtr:DWORD, Vector:DWORD - - mov eax, Vector - mov ecx, DestPtr - mov word ptr [ecx], ax ; write bits 15..0 of offset - mov dx, cs - mov word ptr [ecx+2], dx ; SYS_CODE_SEL from GDT - mov word ptr [ecx+4], 0e00h OR 8000h ; type = 386 interrupt gate, present - shr eax, 16 - mov word ptr [ecx+6], ax ; write bits 31..16 of offset - - ret - -Vect2Desc ENDP - - - -;------------------------------------------------------------------------------ -; InterruptEntryStub -; -; Abstract: This code is not a function, but is a small piece of code that is -; copied and fixed up once for each IDT entry that is hooked. -; -InterruptEntryStub:: - mov AppEsp, esp ; save stack top - mov esp, offset DebugStackBegin ; switch to debugger stack - push 0 ; push vector number - will be modified before installed - db 0e9h ; jump rel32 - dd 0 ; fixed up to relative address of CommonIdtEntry -InterruptEntryStubEnd: - - - -;------------------------------------------------------------------------------ -; CommonIdtEntry -; -; Abstract: This code is not a function, but is the common part for all IDT -; vectors. -; -CommonIdtEntry:: -;; -;; At this point, the stub has saved the current application stack esp into AppEsp -;; and switched stacks to the debug stack, where it pushed the vector number -;; -;; The application stack looks like this: -;; -;; ... -;; (last application stack entry) -;; eflags from interrupted task -;; CS from interrupted task -;; EIP from interrupted task -;; Error code <-------------------- Only present for some exeption types -;; -;; - - -;; The stub switched us to the debug stack and pushed the interrupt number. -;; -;; Next, construct the context record. It will be build on the debug stack by -;; pushing the registers in the correct order so as to create the context structure -;; on the debug stack. The context record must be built from the end back to the -;; beginning because the stack grows down... -; -;; For reference, the context record looks like this: -;; -;; typedef -;; struct { -;; UINT32 ExceptionData; -;; FX_SAVE_STATE_IA32 FxSaveState; -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT32 Cr0, Cr2, Cr3, Cr4; -;; UINT32 EFlags; -;; UINT32 Ldtr, Tr; -;; UINT32 Gdtr[2], Idtr[2]; -;; UINT32 Eip; -;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; -;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record - -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - pushad - -;; Save interrupt state eflags register... - pushfd - pop eax - mov dword ptr Eflags, eax - -;; We need to determine if any extra data was pushed by the exception, and if so, save it -;; To do this, we check the exception number pushed by the stub, and cache the -;; result in a variable since we'll need this again. - .IF ExceptionNumber == EXCPT32_DOUBLE_FAULT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_INVALID_TSS - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_SEG_NOT_PRESENT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_STACK_FAULT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_GP_FAULT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_PAGE_FAULT - mov ExtraPush, 1 - .ELSEIF ExceptionNumber == EXCPT32_ALIGNMENT_CHECK - mov ExtraPush, 1 - .ELSE - mov ExtraPush, 0 - .ENDIF - -;; If there's some extra data, save it also, and modify the saved AppEsp to effectively -;; pop this value off the application's stack. - .IF ExtraPush == 1 - mov eax, AppEsp - mov ebx, [eax] - mov ExceptData, ebx - add eax, 4 - mov AppEsp, eax - .ELSE - mov ExceptData, 0 - .ENDIF - -;; The "pushad" above pushed the debug stack esp. Since what we're actually doing -;; is building the context record on the debug stack, we need to save the pushed -;; debug ESP, and replace it with the application's last stack entry... - mov eax, [esp + 12] - mov DebugEsp, eax - mov eax, AppEsp - add eax, 12 - ; application stack has eflags, cs, & eip, so - ; last actual application stack entry is - ; 12 bytes into the application stack. - mov [esp + 12], eax - -;; continue building context record -;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - mov eax, ss - push eax - - ; CS from application is one entry back in application stack - mov eax, AppEsp - movzx eax, word ptr [eax + 4] - push eax - - mov eax, ds - push eax - mov eax, es - push eax - mov eax, fs - push eax - mov eax, gs - push eax - -;; UINT32 Eip; - ; Eip from application is on top of application stack - mov eax, AppEsp - push dword ptr [eax] - -;; UINT32 Gdtr[2], Idtr[2]; - push 0 - push 0 - sidt fword ptr [esp] - push 0 - push 0 - sgdt fword ptr [esp] - -;; UINT32 Ldtr, Tr; - xor eax, eax - str ax - push eax - sldt ax - push eax - -;; UINT32 EFlags; -;; Eflags from application is two entries back in application stack - mov eax, AppEsp - push dword ptr [eax + 8] - -;; 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 eax, cr4 - or eax, 208h - mov cr4, eax - push eax - mov eax, cr3 - push eax - mov eax, cr2 - push eax - push 0 - mov eax, cr0 - push eax - -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - mov eax, dr7 - push eax -;; clear Dr7 while executing debugger itself - xor eax, eax - mov dr7, eax - - mov eax, dr6 - push eax -;; insure all status bits in dr6 are clear... - xor eax, eax - mov dr6, eax - - mov eax, dr3 - push eax - mov eax, dr2 - push eax - mov eax, dr1 - push eax - mov eax, dr0 - push eax - -;; FX_SAVE_STATE_IA32 FxSaveState; - sub esp, 512 - mov edi, esp - ; IMPORTANT!! The debug stack has been carefully constructed to - ; insure that esp and edi are 16 byte aligned when we get here. - ; They MUST be. If they are not, a GP fault will occur. - FXSTOR_EDI - -;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear - cld - -;; UINT32 ExceptionData; - mov eax, ExceptData - push eax - -; call to C code which will in turn call registered handler -; pass in the vector number - mov eax, esp - push eax - mov eax, ExceptionNumber - push eax - call InterruptDistrubutionHub - add esp, 8 - -; restore context... -;; UINT32 ExceptionData; - add esp, 4 - -;; FX_SAVE_STATE_IA32 FxSaveState; - mov esi, esp - FXRSTOR_ESI - add esp, 512 - -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - pop eax - mov dr0, eax - pop eax - mov dr1, eax - pop eax - mov dr2, eax - pop eax - mov dr3, eax -;; skip restore of dr6. We cleared dr6 during the context save. - add esp, 4 - pop eax - mov dr7, eax - -;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - pop eax - mov cr0, eax - add esp, 4 - pop eax - mov cr2, eax - pop eax - mov cr3, eax - pop eax - mov cr4, eax - -;; UINT32 EFlags; - mov eax, AppEsp - pop dword ptr [eax + 8] - -;; UINT32 Ldtr, Tr; -;; UINT32 Gdtr[2], Idtr[2]; -;; Best not let anyone mess with these particular registers... - add esp, 24 - -;; UINT32 Eip; - pop dword ptr [eax] - -;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs; -;; NOTE - modified segment registers could hang the debugger... We -;; could attempt to insulate ourselves against this possibility, -;; but that poses risks as well. -;; - - pop gs - pop fs - pop es - pop ds - pop [eax + 4] - pop ss - -;; The next stuff to restore is the general purpose registers that were pushed -;; using the "pushad" instruction. -;; -;; The value of ESP as stored in the context record is the application ESP -;; including the 3 entries on the application stack caused by the exception -;; itself. It may have been modified by the debug agent, so we need to -;; determine if we need to relocate the application stack. - - mov ebx, [esp + 12] ; move the potentially modified AppEsp into ebx - mov eax, AppEsp - add eax, 12 - cmp ebx, eax - je NoAppStackMove - - mov eax, AppEsp - mov ecx, [eax] ; EIP - mov [ebx], ecx - - mov ecx, [eax + 4] ; CS - mov [ebx + 4], ecx - - mov ecx, [eax + 8] ; EFLAGS - mov [ebx + 8], ecx - - mov eax, ebx ; modify the saved AppEsp to the new AppEsp - mov AppEsp, eax -NoAppStackMove: - mov eax, DebugEsp ; restore the DebugEsp on the debug stack - ; so our "popad" will not cause a stack switch - mov [esp + 12], eax - - cmp ExceptionNumber, 068h - jne NoChain - -Chain: - -;; Restore eflags so when we chain, the flags will be exactly as if we were never here. -;; We gin up the stack to do an iretd so we can get ALL the flags. - mov eax, AppEsp - mov ebx, [eax + 8] - and ebx, NOT 300h ; special handling for IF and TF - push ebx - push cs - push PhonyIretd - iretd -PhonyIretd: - -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popad - -;; Switch back to application stack - mov esp, AppEsp - -;; Jump to original handler - jmp OrigVector - -NoChain: -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popad - -;; Switch back to application stack - mov esp, AppEsp - -;; We're outa here... - iretd -END - - - diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.nasm b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.nasm deleted file mode 100644 index fc151c272b..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.nasm +++ /dev/null @@ -1,499 +0,0 @@ -;/** @file -; Low leve IA32 specific debug support functions. -; -; Copyright (c) 2006 - 2011, 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. -; -;**/ - -%define EXCPT32_DIVIDE_ERROR 0 -%define EXCPT32_DEBUG 1 -%define EXCPT32_NMI 2 -%define EXCPT32_BREAKPOINT 3 -%define EXCPT32_OVERFLOW 4 -%define EXCPT32_BOUND 5 -%define EXCPT32_INVALID_OPCODE 6 -%define EXCPT32_DOUBLE_FAULT 8 -%define EXCPT32_INVALID_TSS 10 -%define EXCPT32_SEG_NOT_PRESENT 11 -%define EXCPT32_STACK_FAULT 12 -%define EXCPT32_GP_FAULT 13 -%define EXCPT32_PAGE_FAULT 14 -%define EXCPT32_FP_ERROR 16 -%define EXCPT32_ALIGNMENT_CHECK 17 -%define EXCPT32_MACHINE_CHECK 18 -%define EXCPT32_SIMD 19 - -%define FXSTOR_FLAG 0x1000000 ; bit cpuid 24 of feature flags - -;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87, -;; MMX, SSE, SSE2, etc registers. The initialization of the debugsupport driver -;; MUST check the CPUID feature flags to see that these instructions are available -;; and fail to init if they are not. - -;; fxstor [edi] -%macro FXSTOR_EDI 0 - db 0xf, 0xae, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [edi] -%endmacro - -;; fxrstor [esi] -%macro FXRSTOR_ESI 0 - db 0xf, 0xae, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [esi] -%endmacro -SECTION .data - -global ASM_PFX(OrigVector) -global ASM_PFX(InterruptEntryStub) -global ASM_PFX(StubSize) -global ASM_PFX(CommonIdtEntry) -global ASM_PFX(FxStorSupport) -extern ASM_PFX(InterruptDistrubutionHub) - -ASM_PFX(StubSize): dd InterruptEntryStubEnd - ASM_PFX(InterruptEntryStub) -AppEsp: dd 0x11111111 ; ? -DebugEsp: dd 0x22222222 ; ? -ExtraPush: dd 0x33333333 ; ? -ExceptData: dd 0x44444444 ; ? -Eflags: dd 0x55555555 ; ? -ASM_PFX(OrigVector): dd 0x66666666 ; ? - -;; The declarations below define the memory region that will be used for the debug stack. -;; The context record will be built by pushing register values onto this stack. -;; It is imparitive that alignment be carefully managed, since the FXSTOR and -;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned. -;; -;; The stub will switch stacks from the application stack to the debuger stack -;; and pushes the exception number. -;; -;; Then we building the context record on the stack. Since the stack grows down, -;; we push the fields of the context record from the back to the front. There -;; are 132 bytes of stack used prior allocating the 512 bytes of stack to be -;; used as the memory buffer for the fxstor instruction. Therefore address of -;; the buffer used for the FXSTOR instruction is &Eax - 132 - 512, which -;; must be 16 byte aligned. -;; -;; We carefully locate the stack to make this happen. -;; -;; For reference, the context structure looks like this: -;; struct { -;; UINT32 ExceptionData; -;; FX_SAVE_STATE_IA32 FxSaveState; // 512 bytes, must be 16 byte aligned -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; -;; UINT32 EFlags; -;; UINT32 Ldtr, Tr; -;; UINT32 Gdtr[2], Idtr[2]; -;; UINT32 Eip; -;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; -;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record - -align 16 -DebugStackEnd: db "DbgStkEnd >>>>>>" ;; 16 byte long string - must be 16 bytes to preserve alignment - times 0x1ffc dd 0x0 ;; 32K should be enough stack - ;; This allocation is coocked to insure - ;; that the the buffer for the FXSTORE instruction - ;; will be 16 byte aligned also. - ;; -ExceptionNumber: dd 0 ;; first entry will be the vector number pushed by the stub - -DebugStackBegin: db "<<<< DbgStkBegin" ;; initial debug ESP == DebugStackBegin, set in stub - -SECTION .text - -;------------------------------------------------------------------------------ -; BOOLEAN -; FxStorSupport ( -; void -; ) -; -; Abstract: Returns TRUE if FxStor instructions are supported -; -global ASM_PFX(FxStorSupport) -ASM_PFX(FxStorSupport): - -; -; cpuid corrupts ebx which must be preserved per the C calling convention -; - push ebx - mov eax, 1 - cpuid - mov eax, edx - and eax, FXSTOR_FLAG - shr eax, 24 - pop ebx - ret - -;------------------------------------------------------------------------------ -; void -; Vect2Desc ( -; DESCRIPTOR * DestDesc, -; void (*Vector) (void) -; ) -; -; Abstract: Encodes an IDT descriptor with the given physical address -; -global ASM_PFX(Vect2Desc) -ASM_PFX(Vect2Desc): - push ebp - mov ebp, esp - mov eax, [ebp + 0xC] - mov ecx, [ebp + 0x8] - mov word [ecx], ax ; write bits 15..0 of offset - mov dx, cs - mov word [ecx+2], dx ; SYS_CODE_SEL from GDT - mov word [ecx+4], 0xe00 | 0x8000 ; type = 386 interrupt gate, present - shr eax, 16 - mov word [ecx+6], ax ; write bits 31..16 of offset - leave - ret - -;------------------------------------------------------------------------------ -; InterruptEntryStub -; -; Abstract: This code is not a function, but is a small piece of code that is -; copied and fixed up once for each IDT entry that is hooked. -; -ASM_PFX(InterruptEntryStub): - mov [AppEsp], esp ; save stack top - mov esp, DebugStackBegin ; switch to debugger stack - push 0 ; push vector number - will be modified before installed - db 0xe9 ; jump rel32 - dd 0 ; fixed up to relative address of CommonIdtEntry -InterruptEntryStubEnd: - -;------------------------------------------------------------------------------ -; CommonIdtEntry -; -; Abstract: This code is not a function, but is the common part for all IDT -; vectors. -; -ASM_PFX(CommonIdtEntry): -;; -;; At this point, the stub has saved the current application stack esp into AppEsp -;; and switched stacks to the debug stack, where it pushed the vector number -;; -;; The application stack looks like this: -;; -;; ... -;; (last application stack entry) -;; eflags from interrupted task -;; CS from interrupted task -;; EIP from interrupted task -;; Error code <-------------------- Only present for some exeption types -;; -;; - -;; The stub switched us to the debug stack and pushed the interrupt number. -;; -;; Next, construct the context record. It will be build on the debug stack by -;; pushing the registers in the correct order so as to create the context structure -;; on the debug stack. The context record must be built from the end back to the -;; beginning because the stack grows down... -; -;; For reference, the context record looks like this: -;; -;; typedef -;; struct { -;; UINT32 ExceptionData; -;; FX_SAVE_STATE_IA32 FxSaveState; -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT32 Cr0, Cr2, Cr3, Cr4; -;; UINT32 EFlags; -;; UINT32 Ldtr, Tr; -;; UINT32 Gdtr[2], Idtr[2]; -;; UINT32 Eip; -;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; -;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record - -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - pushad - -;; Save interrupt state eflags register... - pushfd - pop eax - mov [Eflags], eax - -;; We need to determine if any extra data was pushed by the exception, and if so, save it -;; To do this, we check the exception number pushed by the stub, and cache the -;; result in a variable since we'll need this again. - cmp dword [ExceptionNumber], EXCPT32_DOUBLE_FAULT - jz ExtraPushOne - cmp dword [ExceptionNumber], EXCPT32_INVALID_TSS - jz ExtraPushOne - cmp dword [ExceptionNumber], EXCPT32_SEG_NOT_PRESENT - jz ExtraPushOne - cmp dword [ExceptionNumber], EXCPT32_STACK_FAULT - jz ExtraPushOne - cmp dword [ExceptionNumber], EXCPT32_GP_FAULT - jz ExtraPushOne - cmp dword [ExceptionNumber], EXCPT32_PAGE_FAULT - jz ExtraPushOne - cmp dword [ExceptionNumber], EXCPT32_ALIGNMENT_CHECK - jz ExtraPushOne - mov dword [ExtraPush], 0 - mov dword [ExceptData], 0 - jmp ExtraPushDone - -ExtraPushOne: - mov dword [ExtraPush], 1 - -;; If there's some extra data, save it also, and modify the saved AppEsp to effectively -;; pop this value off the application's stack. - mov eax, [AppEsp] - mov ebx, [eax] - mov [ExceptData], ebx - add eax, 4 - mov [AppEsp], eax - -ExtraPushDone: - -;; The "pushad" above pushed the debug stack esp. Since what we're actually doing -;; is building the context record on the debug stack, we need to save the pushed -;; debug ESP, and replace it with the application's last stack entry... - mov eax, [esp + 12] - mov [DebugEsp], eax - mov eax, [AppEsp] - add eax, 12 - ; application stack has eflags, cs, & eip, so - ; last actual application stack entry is - ; 12 bytes into the application stack. - mov [esp + 12], eax - -;; continue building context record -;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - mov eax, ss - push eax - - ; CS from application is one entry back in application stack - mov eax, [AppEsp] - movzx eax, word [eax + 4] - push eax - - mov eax, ds - push eax - mov eax, es - push eax - mov eax, fs - push eax - mov eax, gs - push eax - -;; UINT32 Eip; - ; Eip from application is on top of application stack - mov eax, [AppEsp] - push dword [eax] - -;; UINT32 Gdtr[2], Idtr[2]; - push 0 - push 0 - sidt [esp] - push 0 - push 0 - sgdt [esp] - -;; UINT32 Ldtr, Tr; - xor eax, eax - str ax - push eax - sldt ax - push eax - -;; UINT32 EFlags; -;; Eflags from application is two entries back in application stack - mov eax, [AppEsp] - push dword [eax + 8] - -;; 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 eax, cr4 - or eax, 0x208 - mov cr4, eax - push eax - mov eax, cr3 - push eax - mov eax, cr2 - push eax - push 0 - mov eax, cr0 - push eax - -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - mov eax, dr7 - push eax -;; clear Dr7 while executing debugger itself - xor eax, eax - mov dr7, eax - - mov eax, dr6 - push eax -;; insure all status bits in dr6 are clear... - xor eax, eax - mov dr6, eax - - mov eax, dr3 - push eax - mov eax, dr2 - push eax - mov eax, dr1 - push eax - mov eax, dr0 - push eax - -;; FX_SAVE_STATE_IA32 FxSaveState; - sub esp, 512 - mov edi, esp - ; IMPORTANT!! The debug stack has been carefully constructed to - ; insure that esp and edi are 16 byte aligned when we get here. - ; They MUST be. If they are not, a GP fault will occur. - FXSTOR_EDI - -;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear - cld - -;; UINT32 ExceptionData; - mov eax, [ExceptData] - push eax - -; call to C code which will in turn call registered handler -; pass in the vector number - mov eax, esp - push eax - mov eax, [ExceptionNumber] - push eax - call ASM_PFX(InterruptDistrubutionHub) - add esp, 8 - -; restore context... -;; UINT32 ExceptionData; - add esp, 4 - -;; FX_SAVE_STATE_IA32 FxSaveState; - mov esi, esp - FXRSTOR_ESI - add esp, 512 - -;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - pop eax - mov dr0, eax - pop eax - mov dr1, eax - pop eax - mov dr2, eax - pop eax - mov dr3, eax -;; skip restore of dr6. We cleared dr6 during the context save. - add esp, 4 - pop eax - mov dr7, eax - -;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4; - pop eax - mov cr0, eax - add esp, 4 - pop eax - mov cr2, eax - pop eax - mov cr3, eax - pop eax - mov cr4, eax - -;; UINT32 EFlags; - mov eax, [AppEsp] - pop dword [eax + 8] - -;; UINT32 Ldtr, Tr; -;; UINT32 Gdtr[2], Idtr[2]; -;; Best not let anyone mess with these particular registers... - add esp, 24 - -;; UINT32 Eip; - pop dword [eax] - -;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs; -;; NOTE - modified segment registers could hang the debugger... We -;; could attempt to insulate ourselves against this possibility, -;; but that poses risks as well. -;; - - pop gs - pop fs - pop es - pop ds - pop dword [eax + 4] - pop ss - -;; The next stuff to restore is the general purpose registers that were pushed -;; using the "pushad" instruction. -;; -;; The value of ESP as stored in the context record is the application ESP -;; including the 3 entries on the application stack caused by the exception -;; itself. It may have been modified by the debug agent, so we need to -;; determine if we need to relocate the application stack. - - mov ebx, [esp + 12] ; move the potentially modified AppEsp into ebx - mov eax, [AppEsp] - add eax, 12 - cmp ebx, eax - je NoAppStackMove - - mov eax, [AppEsp] - mov ecx, [eax] ; EIP - mov [ebx], ecx - - mov ecx, [eax + 4] ; CS - mov [ebx + 4], ecx - - mov ecx, [eax + 8] ; EFLAGS - mov [ebx + 8], ecx - - mov eax, ebx ; modify the saved AppEsp to the new AppEsp - mov [AppEsp], eax -NoAppStackMove: - mov eax, [DebugEsp] ; restore the DebugEsp on the debug stack - ; so our "popad" will not cause a stack switch - mov [esp + 12], eax - - cmp dword [ExceptionNumber], 0x68 - jne NoChain - -Chain: - -;; Restore eflags so when we chain, the flags will be exactly as if we were never here. -;; We gin up the stack to do an iretd so we can get ALL the flags. - mov eax, [AppEsp] - mov ebx, [eax + 8] - and ebx, ~ 0x300 ; special handling for IF and TF - push ebx - push cs - push PhonyIretd - iretd -PhonyIretd: - -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popad - -;; Switch back to application stack - mov esp, [AppEsp] - -;; Jump to original handler - jmp [ASM_PFX(OrigVector)] - -NoChain: -;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax; - popad - -;; Switch back to application stack - mov esp, [AppEsp] - -;; We're outa here... - iretd - diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h deleted file mode 100644 index 7f7d8e5ba6..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h +++ /dev/null @@ -1,298 +0,0 @@ -/** @file - Generic debug support macros, typedefs and prototypes for IA32/x64. - -Copyright (c) 2006 - 2010, 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. - -**/ - -#ifndef _DEBUG_SUPPORT_H_ -#define _DEBUG_SUPPORT_H_ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#define NUM_IDT_ENTRIES 0x78 -#define SYSTEM_TIMER_VECTOR 0x68 - -typedef -VOID -(*DEBUG_PROC) ( - VOID - ); - -typedef -VOID -(EFIAPI *CALLBACK_FUNC) ( - ); - -typedef struct { - IA32_IDT_GATE_DESCRIPTOR OrigDesc; - DEBUG_PROC OrigVector; - IA32_IDT_GATE_DESCRIPTOR NewDesc; - DEBUG_PROC StubEntry; - CALLBACK_FUNC RegisteredCallback; -} IDT_ENTRY; - -extern UINT8 InterruptEntryStub[]; -extern UINT32 StubSize; -extern VOID (*OrigVector) (VOID); -extern IDT_ENTRY *IdtEntryTable; -extern IA32_IDT_GATE_DESCRIPTOR NullDesc; - -/** - Generic IDT entry. - -**/ -VOID -CommonIdtEntry ( - VOID - ); - -/** - Check whether FXSTOR is supported - - @retval TRUE FXSTOR is supported. - @retval FALSE FXSTOR is not supported. - -**/ -BOOLEAN -FxStorSupport ( - VOID - ); - -/** - Encodes an IDT descriptor with the given physical address. - - @param DestDesc The IDT descriptor address. - @param Vecotr The interrupt vector entry. - -**/ -VOID -Vect2Desc ( - IA32_IDT_GATE_DESCRIPTOR * DestDesc, - VOID (*Vector) (VOID) - ); - -/** - Initializes driver's handler registration database. - - This code executes in boot services context - Must be public because it's referenced from DebugSupport.c - - @retval EFI_UNSUPPORTED If IA32 processor does not support FXSTOR/FXRSTOR instructions, - the context save will fail, so these processor's are not supported. - @retval EFI_OUT_OF_RESOURCES Fails to allocate memory. - @retval EFI_SUCCESS Initializes successfully. - -**/ -EFI_STATUS -PlInitializeDebugSupportDriver ( - VOID - ); - -/** - This is the callback that is written to the LoadedImage protocol instance - on the image handle. It uninstalls all registered handlers and frees all entry - stub memory. - - @param ImageHandle The firmware allocated handle for the EFI image. - - @retval EFI_SUCCESS Always. - -**/ -EFI_STATUS -EFIAPI -PlUnloadDebugSupportDriver ( - IN EFI_HANDLE ImageHandle - ); - -/** - Returns the maximum value that may be used for the ProcessorIndex parameter in - RegisterPeriodicCallback() and RegisterExceptionCallback(). - - Hard coded to support only 1 processor for now. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param MaxProcessorIndex Pointer to a caller-allocated UINTN in which the maximum supported - processor index is returned. Always 0 returned. - - @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0. - -**/ -EFI_STATUS -EFIAPI -GetMaximumProcessorIndex ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - OUT UINTN *MaxProcessorIndex - ); - -/** - Registers a function to be called back periodically in interrupt context. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor the callback function applies to. - @param PeriodicCallback A pointer to a function of type PERIODIC_CALLBACK that is the main - periodic entry point of the debug agent. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback - function was previously registered. - @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback - function. -**/ -EFI_STATUS -EFIAPI -RegisterPeriodicCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_PERIODIC_CALLBACK PeriodicCallback - ); - -/** - Registers a function to be called when a given processor exception occurs. - - This code executes in boot services context. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor the callback function applies to. - @param ExceptionCallback A pointer to a function of type EXCEPTION_CALLBACK that is called - when the processor exception specified by ExceptionType occurs. - @param ExceptionType Specifies which processor exception to hook. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback - function was previously registered. - @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback - function. -**/ -EFI_STATUS -EFIAPI -RegisterExceptionCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_EXCEPTION_CALLBACK ExceptionCallback, - IN EFI_EXCEPTION_TYPE ExceptionType - ); - -/** - Invalidates processor instruction cache for a memory range. Subsequent execution in this range - causes a fresh memory fetch to retrieve code to be executed. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor's instruction cache is to be invalidated. - @param Start Specifies the physical base of the memory range to be invalidated. - @param Length Specifies the minimum number of bytes in the processor's instruction - cache to invalidate. - - @retval EFI_SUCCESS Always returned. - -**/ -EFI_STATUS -EFIAPI -InvalidateInstructionCache ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN VOID *Start, - IN UINT64 Length - ); - -/** - Allocate pool for a new IDT entry stub. - - Copy the generic stub into the new buffer and fixup the vector number - and jump target address. - - @param ExceptionType This is the exception type that the new stub will be created - for. - @param Stub On successful exit, *Stub contains the newly allocated entry stub. - -**/ -VOID -CreateEntryStub ( - IN EFI_EXCEPTION_TYPE ExceptionType, - OUT VOID **Stub - ); - -/** - Get Interrupt Handle from IDT Gate Descriptor. - - @param IdtGateDecriptor IDT Gate Descriptor. - - @return Interrupt Handle stored in IDT Gate Descriptor. - -**/ -UINTN -GetInterruptHandleFromIdt ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor - ); - -/** - This is the main worker function that manages the state of the interrupt - handlers. It both installs and uninstalls interrupt handlers based on the - value of NewCallback. If NewCallback is NULL, then uninstall is indicated. - If NewCallback is non-NULL, then install is indicated. - - @param NewCallback If non-NULL, NewCallback specifies the new handler to register. - If NULL, specifies that the previously registered handler should - be uninstalled. - @param ExceptionType Indicates which entry to manage. - - @retval EFI_SUCCESS Process is ok. - @retval EFI_INVALID_PARAMETER Requested uninstalling a handler from a vector that has - no handler registered for it - @retval EFI_ALREADY_STARTED Requested install to a vector that already has a handler registered. - @retval others Possible return values are passed through from UnHookEntry and HookEntry. - -**/ -EFI_STATUS -ManageIdtEntryTable ( - CALLBACK_FUNC NewCallback, - EFI_EXCEPTION_TYPE ExceptionType - ); - -/** - Creates a nes entry stub. Then saves the current IDT entry and replaces it - with an interrupt gate for the new entry point. The IdtEntryTable is updated - with the new registered function. - - This code executes in boot services context. The stub entry executes in interrupt - context. - - @param ExceptionType Specifies which vector to hook. - @param NewCallback A pointer to the new function to be registered. - -**/ -VOID -HookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN CALLBACK_FUNC NewCallback - ); - -/** - Undoes HookEntry. This code executes in boot services context. - - @param ExceptionType Specifies which entry to unhook - -**/ -VOID -UnhookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType - ); - -#endif diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c deleted file mode 100644 index f0c529a41b..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c +++ /dev/null @@ -1,373 +0,0 @@ -/** @file - IA32/x64 generic functions to support Debug Support protocol. - -Copyright (c) 2006 - 2010, 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. - -**/ - -#include "DebugSupport.h" - -// -// This the global main table to keep track of the interrupts -// -IDT_ENTRY *IdtEntryTable = NULL; - -/** - Read IDT Gate Descriptor from IDT Table. - - @param Vector Specifies vector number. - @param IdtGateDescriptor Pointer to IDT Gate Descriptor read from IDT Table. - -**/ -VOID -ReadIdtGateDescriptor ( - IN EFI_EXCEPTION_TYPE Vector, - OUT IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor - ) -{ - IA32_DESCRIPTOR IdtrValue; - IA32_IDT_GATE_DESCRIPTOR *IdtTable; - - AsmReadIdtr (&IdtrValue); - IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtrValue.Base; - - CopyMem ((VOID *) IdtGateDescriptor, (VOID *) &(IdtTable)[Vector], sizeof (IA32_IDT_GATE_DESCRIPTOR)); -} - -/** - Write IDT Gate Descriptor into IDT Table. - - @param Vector Specifies vector number. - @param IdtGateDescriptor Pointer to IDT Gate Descriptor written into IDT Table. - -**/ -VOID -WriteIdtGateDescriptor ( - EFI_EXCEPTION_TYPE Vector, - IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor - ) -{ - IA32_DESCRIPTOR IdtrValue; - IA32_IDT_GATE_DESCRIPTOR *IdtTable; - - AsmReadIdtr (&IdtrValue); - IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtrValue.Base; - - CopyMem ((VOID *) &(IdtTable)[Vector], (VOID *) IdtGateDescriptor, sizeof (IA32_IDT_GATE_DESCRIPTOR)); -} - -/** - Creates a nes entry stub. Then saves the current IDT entry and replaces it - with an interrupt gate for the new entry point. The IdtEntryTable is updated - with the new registered function. - - This code executes in boot services context. The stub entry executes in interrupt - context. - - @param ExceptionType Specifies which vector to hook. - @param NewCallback A pointer to the new function to be registered. - -**/ -VOID -HookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN CALLBACK_FUNC NewCallback - ) -{ - BOOLEAN OldIntFlagState; - - CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry); - - // - // Disables CPU interrupts and returns the previous interrupt state - // - OldIntFlagState = SaveAndDisableInterrupts (); - - // - // gets IDT Gate descriptor by index - // - ReadIdtGateDescriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); - // - // stores orignal interrupt handle - // - IdtEntryTable[ExceptionType].OrigVector = (DEBUG_PROC) GetInterruptHandleFromIdt (&(IdtEntryTable[ExceptionType].OrigDesc)); - - // - // encodes new IDT Gate descriptor by stub entry - // - Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry); - // - // stores NewCallback - // - IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback; - - // - // writes back new IDT Gate descriptor - // - WriteIdtGateDescriptor (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc)); - - // - // restore interrupt state - // - SetInterruptState (OldIntFlagState); - - return ; -} - -/** - Undoes HookEntry. This code executes in boot services context. - - @param ExceptionType Specifies which entry to unhook - -**/ -VOID -UnhookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType - ) -{ - BOOLEAN OldIntFlagState; - - // - // Disables CPU interrupts and returns the previous interrupt state - // - OldIntFlagState = SaveAndDisableInterrupts (); - - // - // restore the default IDT Date Descriptor - // - WriteIdtGateDescriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); - - // - // restore interrupt state - // - SetInterruptState (OldIntFlagState); - - return ; -} - -/** - Returns the maximum value that may be used for the ProcessorIndex parameter in - RegisterPeriodicCallback() and RegisterExceptionCallback(). - - Hard coded to support only 1 processor for now. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param MaxProcessorIndex Pointer to a caller-allocated UINTN in which the maximum supported - processor index is returned. Always 0 returned. - - @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0. - -**/ -EFI_STATUS -EFIAPI -GetMaximumProcessorIndex ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - OUT UINTN *MaxProcessorIndex - ) -{ - *MaxProcessorIndex = 0; - return EFI_SUCCESS; -} - -/** - Registers a function to be called back periodically in interrupt context. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor the callback function applies to. - @param PeriodicCallback A pointer to a function of type PERIODIC_CALLBACK that is the main - periodic entry point of the debug agent. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback - function was previously registered. - @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback - function. -**/ -EFI_STATUS -EFIAPI -RegisterPeriodicCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_PERIODIC_CALLBACK PeriodicCallback - ) -{ - return ManageIdtEntryTable (PeriodicCallback, SYSTEM_TIMER_VECTOR); -} - -/** - Registers a function to be called when a given processor exception occurs. - - This code executes in boot services context. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor the callback function applies to. - @param ExceptionCallback A pointer to a function of type EXCEPTION_CALLBACK that is called - when the processor exception specified by ExceptionType occurs. - @param ExceptionType Specifies which processor exception to hook. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback - function was previously registered. - @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback - function. -**/ -EFI_STATUS -EFIAPI -RegisterExceptionCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_EXCEPTION_CALLBACK ExceptionCallback, - IN EFI_EXCEPTION_TYPE ExceptionType - ) -{ - return ManageIdtEntryTable (ExceptionCallback, ExceptionType); -} - - -/** - Invalidates processor instruction cache for a memory range. Subsequent execution in this range - causes a fresh memory fetch to retrieve code to be executed. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor's instruction cache is to be invalidated. - @param Start Specifies the physical base of the memory range to be invalidated. - @param Length Specifies the minimum number of bytes in the processor's instruction - cache to invalidate. - - @retval EFI_SUCCESS Always returned. - -**/ -EFI_STATUS -EFIAPI -InvalidateInstructionCache ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN VOID *Start, - IN UINT64 Length - ) -{ - AsmWbinvd (); - return EFI_SUCCESS; -} - -/** - Common piece of code that invokes the registered handlers. - - This code executes in exception context so no efi calls are allowed. - This code is called from assembly file. - - @param ExceptionType Exception type - @param ContextRecord System context - -**/ -VOID -InterruptDistrubutionHub ( - EFI_EXCEPTION_TYPE ExceptionType, - EFI_SYSTEM_CONTEXT_IA32 *ContextRecord - ) -{ - if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) { - if (ExceptionType != SYSTEM_TIMER_VECTOR) { - IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord); - } else { - OrigVector = IdtEntryTable[ExceptionType].OrigVector; - IdtEntryTable[ExceptionType].RegisteredCallback (ContextRecord); - } - } -} - -/** - This is the callback that is written to the Loaded Image protocol instance - on the image handle. It uninstalls all registered handlers and frees all entry - stub memory. - - @param ImageHandle The firmware allocated handle for the EFI image. - - @retval EFI_SUCCESS Always. - -**/ -EFI_STATUS -EFIAPI -PlUnloadDebugSupportDriver ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_EXCEPTION_TYPE ExceptionType; - - for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) { - ManageIdtEntryTable (NULL, ExceptionType); - // - // Free space for each Interrupt Stub precedure. - // - if (IdtEntryTable[ExceptionType].StubEntry != NULL) { - FreePool ((VOID *)(UINTN)IdtEntryTable[ExceptionType].StubEntry); - } - } - - FreePool (IdtEntryTable); - - return EFI_SUCCESS; -} - -/** - Initializes driver's handler registration database. - - This code executes in boot services context. - Must be public because it's referenced from DebugSupport.c - - @retval EFI_UNSUPPORTED If IA32/x64 processor does not support FXSTOR/FXRSTOR instructions, - the context save will fail, so these processors are not supported. - @retval EFI_OUT_OF_RESOURCES Fails to allocate memory. - @retval EFI_SUCCESS Initializes successfully. - -**/ -EFI_STATUS -PlInitializeDebugSupportDriver ( - VOID - ) -{ - EFI_EXCEPTION_TYPE ExceptionType; - - // - // Check whether FxStor instructions are supported. - // - if (!FxStorSupport ()) { - return EFI_UNSUPPORTED; - } - - IdtEntryTable = AllocateZeroPool (sizeof (IDT_ENTRY) * NUM_IDT_ENTRIES); - if (IdtEntryTable == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType ++) { - IdtEntryTable[ExceptionType].StubEntry = (DEBUG_PROC) (UINTN) AllocatePool (StubSize); - if (IdtEntryTable[ExceptionType].StubEntry == NULL) { - goto ErrorCleanup; - } - - // - // Copy Interrupt stub code. - // - CopyMem ((VOID *)(UINTN)IdtEntryTable[ExceptionType].StubEntry, InterruptEntryStub, StubSize); - } - return EFI_SUCCESS; - -ErrorCleanup: - - for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) { - if (IdtEntryTable[ExceptionType].StubEntry != NULL) { - FreePool ((VOID *)(UINTN)IdtEntryTable[ExceptionType].StubEntry); - } - } - FreePool (IdtEntryTable); - - return EFI_OUT_OF_RESOURCES; -} diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h deleted file mode 100644 index 0a1577fab3..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h +++ /dev/null @@ -1,22 +0,0 @@ -/** @file - IA32 specific debug support macros, typedefs and prototypes. - -Copyright (c) 2006 - 2008, 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. - -**/ - -#ifndef _PLDEBUG_SUPPORT_H_ -#define _PLDEBUG_SUPPORT_H_ - -#include "Ia32/DebugSupport.h" - -#define EFI_ISA IsaIa32 - -#endif diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c deleted file mode 100644 index 23222737f8..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c +++ /dev/null @@ -1,145 +0,0 @@ -/** @file - IA32 specific functions to support Debug Support protocol. - -Copyright (c) 2008 - 2010, 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. - -**/ - -#include "PlDebugSupport.h" - -IA32_IDT_GATE_DESCRIPTOR NullDesc = {{0}}; - -/** - Get Interrupt Handle from IDT Gate Descriptor. - - @param IdtGateDescriptor IDT Gate Descriptor. - - @return Interrupt Handle stored in IDT Gate Descriptor. - -**/ -UINTN -GetInterruptHandleFromIdt ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor - ) -{ - UINTN InterruptHandle; - - // - // InterruptHandle 0-15 : OffsetLow - // InterruptHandle 16-31 : OffsetHigh - // - ((UINT16 *) &InterruptHandle)[0] = (UINT16) IdtGateDescriptor->Bits.OffsetLow; - ((UINT16 *) &InterruptHandle)[1] = (UINT16) IdtGateDescriptor->Bits.OffsetHigh; - - return InterruptHandle; -} - -/** - Allocate pool for a new IDT entry stub. - - Copy the generic stub into the new buffer and fixup the vector number - and jump target address. - - @param ExceptionType This is the exception type that the new stub will be created - for. - @param Stub On successful exit, *Stub contains the newly allocated entry stub. - -**/ -VOID -CreateEntryStub ( - IN EFI_EXCEPTION_TYPE ExceptionType, - OUT VOID **Stub - ) -{ - UINT8 *StubCopy; - - StubCopy = *Stub; - - // - // Fixup the stub code for this vector - // - - // The stub code looks like this: - // - // 00000000 89 25 00000004 R mov AppEsp, esp ; save stack top - // 00000006 BC 00008014 R mov esp, offset DbgStkBot ; switch to debugger stack - // 0000000B 6A 00 push 0 ; push vector number - will be modified before installed - // 0000000D E9 db 0e9h ; jump rel32 - // 0000000E 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry - // - - // - // poke in the exception type so the second push pushes the exception type - // - StubCopy[0x0c] = (UINT8) ExceptionType; - - // - // fixup the jump target to point to the common entry - // - *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize]; - - return ; -} - -/** - This is the main worker function that manages the state of the interrupt - handlers. It both installs and uninstalls interrupt handlers based on the - value of NewCallback. If NewCallback is NULL, then uninstall is indicated. - If NewCallback is non-NULL, then install is indicated. - - @param NewCallback If non-NULL, NewCallback specifies the new handler to register. - If NULL, specifies that the previously registered handler should - be uninstalled. - @param ExceptionType Indicates which entry to manage. - - @retval EFI_SUCCESS Installing or Uninstalling operation is ok. - @retval EFI_INVALID_PARAMETER Requested uninstalling a handler from a vector that has - no handler registered for it - @retval EFI_ALREADY_STARTED Requested install to a vector that already has a handler registered. - -**/ -EFI_STATUS -ManageIdtEntryTable ( - CALLBACK_FUNC NewCallback, - EFI_EXCEPTION_TYPE ExceptionType - ) -{ - EFI_STATUS Status; - - Status = EFI_SUCCESS; - - if (CompareMem (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc, sizeof (IA32_IDT_GATE_DESCRIPTOR)) != 0) { - // - // we've already installed to this vector - // - if (NewCallback != NULL) { - // - // if the input handler is non-null, error - // - Status = EFI_ALREADY_STARTED; - } else { - UnhookEntry (ExceptionType); - } - } else { - // - // no user handler installed on this vector - // - if (NewCallback == NULL) { - // - // if the input handler is null, error - // - Status = EFI_INVALID_PARAMETER; - } else { - HookEntry (ExceptionType, NewCallback); - } - } - - return Status; -} diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/AsmFuncs.s b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/AsmFuncs.s deleted file mode 100644 index db75fc088e..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/AsmFuncs.s +++ /dev/null @@ -1,1382 +0,0 @@ -/// @file -/// Low level IPF routines used by the debug support driver -/// -/// Copyright (c) 2006 - 2008, 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. -/// -/// - - -#include "Common.i" -#include "Ds64Macros.i" - -ASM_GLOBAL PatchSaveBuffer -ASM_GLOBAL IpfContextBuf -ASM_GLOBAL CommonHandler -ASM_GLOBAL ExternalInterruptCount - - -///////////////////////////////////////////// -// -// Name: -// InstructionCacheFlush -// -// Description: -// Flushes instruction cache for specified number of bytes -// - ASM_GLOBAL InstructionCacheFlush - .proc InstructionCacheFlush - .align 32 -InstructionCacheFlush:: - { .mii - alloc r3=2, 0, 0, 0 - cmp4.leu p0,p6=32, r33;; - (p6) mov r33=32;; - } - { .mii - nop.m 0 - zxt4 r29=r33;; - dep.z r30=r29, 0, 5;; - } - { .mii - cmp4.eq p0,p7=r0, r30 - shr.u r28=r29, 5;; - (p7) adds r28=1, r28;; - } - { .mii - nop.m 0 - shl r27=r28, 5;; - zxt4 r26=r27;; - } - { .mfb - add r31=r26, r32 - nop.f 0 - nop.b 0 - } -LoopBack: // $L143: - { .mii - fc r32 - adds r32=32, r32;; - cmp.ltu p14,p15=r32, r31 - } - { .mfb - nop.m 0 - nop.f 0 - //(p14) br.cond.dptk.few $L143#;; - (p14) br.cond.dptk.few LoopBack;; - } - { .mmi - sync.i;; - srlz.i - nop.i 0;; - } - { .mfb - nop.m 0 - nop.f 0 - br.ret.sptk.few b0;; - } - .endp InstructionCacheFlush - - -///////////////////////////////////////////// -// -// Name: -// ChainHandler -// -// Description: -// Chains an interrupt handler -// -// The purpose of this function is to enable chaining of the external interrupt. -// Since there's no clean SAL abstraction for doing this, we must do it -// surreptitiously. -// -// The reserved IVT entry at offset 0x3400 is coopted for use by this handler. -// According to Itanium architecture, it is reserved. Strictly speaking, this is -// not safe, as we're cheating and violating the Itanium architecture. However, -// as long as we're the only ones cheating, we should be OK. Without hooks in -// the SAL to enable IVT management, there aren't many good options. -// -// The strategy is to replace the first bundle of the external interrupt handler -// with our own that will branch into a piece of code we've supplied and located -// in the reserved IVT entry. Only the first bundle of the external interrupt -// IVT entry is modified. -// -// The original bundle is moved and relocated to space -// allocated within the reserved IVT entry. The next bundle following is -// is generated to go a hard coded branch back to the second bundle of the -// external interrupt IVT entry just in case the first bundle had no branch. -// -// Our new code will execute our handler, and then fall through to the -// original bundle after restoring all context appropriately. -// -// The following is a representation of what the IVT memory map looks like with -// our chained handler installed: -// -// -// -// -// -// This IVT entry is Failsafe bundle -// reserved by the -// Itanium architecture Original bundle 0 -// and is used for -// for locating our -// handler and the -// original bundle Patch code... -// zero of the ext -// interrupt handler -// -// RSVD (3400) Unused -// -// -// -// -// -// -// -// -// -// -// -// -// EXT_INT (3000) Bundle 0 Bundle zero - This one is -// modified, all other bundles -// in the EXT_INT entry are -// untouched. -// -// -// Arguments: -// -// Returns: -// -// Notes: -// -// - ASM_GLOBAL ChainHandler - .proc ChainHandler -ChainHandler: - - NESTED_SETUP( 0,2+3,3,0 ) - - mov r8=1 // r8 = success - mov r2=cr.iva;; -// -// NOTE: There's a potential hazard here in that we're simply stealing a bunch of -// bundles (memory) from the IVT and assuming there's no catastrophic side effect. -// -// First, save IVT area we're taking over with the patch so we can restore it later -// - addl out0=PATCH_ENTRY_OFFSET, r2 // out0 = source buffer - movl out1=PatchSaveBuffer // out1 = destination buffer - mov out2=0x40;; // out2 = number of bundles to copy... save entire IDT entry - br.call.sptk.few b0 = CopyBundles - -// Next, copy the patch code into the IVT - movl out0=PatchCode // out0 = source buffer of patch code - addl out1=PATCH_OFFSET, r2 // out1 = destination buffer - in IVT - mov out2=PATCH_CODE_SIZE;; - shr out2=out2, 4;; // out2 = number of bundles to copy - br.call.sptk.few b0 = CopyBundles - - -// copy original bundle 0 from the external interrupt handler to the -// appropriate place in the reserved IVT interrupt slot - addl out0=EXT_INT_ENTRY_OFFSET, r2 // out0 = source buffer - addl out1=RELOCATED_EXT_INT, r2 // out1 = destination buffer - in reserved IVT - mov out2=1;; // out2 = copy 1 bundle - br.call.sptk.few b0 = CopyBundles - -// Now relocate it there because it very likely had a branch instruction that -// that must now be fixed up. - addl out0=RELOCATED_EXT_INT, r2 // out0 = new runtime address of bundle - in reserved IVT - addl out1=EXT_INT_ENTRY_OFFSET, r2;;// out1 = IP address of previous location - mov out2=out0;; // out2 = IP address of new location - br.call.sptk.few b0 = RelocateBundle - -// Now copy into the failsafe branch into the next bundle just in case -// the original ext int bundle 0 bundle did not contain a branch instruction - movl out0=FailsafeBranch // out0 = source buffer - addl out1=FAILSAFE_BRANCH_OFFSET, r2 // out1 = destination buffer - in reserved IVT - mov out2=1;; // out2 = copy 1 bundle - br.call.sptk.few b0 = CopyBundles - -// Last, copy in our replacement for the external interrupt IVT entry bundle 0 - movl out0=PatchCodeNewBun0 // out0 = source buffer - our replacement bundle 0 - addl out1=EXT_INT_ENTRY_OFFSET, r2 // out1 = destination buffer - bundle 0 of External interrupt entry - mov out2=1;; // out2 = copy 1 bundle - br.call.sptk.few b0 = CopyBundles - -ChainHandlerDone: - NESTED_RETURN - - .endp ChainHandler - - -///////////////////////////////////////////// -// -// Name: -// UnchainHandler -// -// Description: -// Unchains an interrupt handler -// -// Arguments: -// -// Returns: -// -// Notes: -// -// - ASM_GLOBAL UnchainHandler - .proc UnchainHandler - -UnchainHandler: - - NESTED_SETUP( 0,2+3,3,0 ) - - mov r8=1 // r8 = success - mov r2=cr.iva;; // r2 = interrupt vector address - -// First copy original Ext Int bundle 0 back to it's proper home... - addl out0=RELOCATED_EXT_INT, r2 // out0 = source - in reserved IVT - addl out1=EXT_INT_ENTRY_OFFSET, r2 // out1 = destination buffer - first bundle of Ext Int entry - mov out2=1;; // out2 = copy 1 bundle - br.call.sptk.few b0 = CopyBundles - -// Now, relocate it again... - addl out0=EXT_INT_ENTRY_OFFSET, r2 // out1 = New runtime address - addl out1=RELOCATED_EXT_INT, r2;; // out0 = IP address of previous location - mov out2=out0;; // out2 = IP address of new location - br.call.sptk.few b0 = RelocateBundle - -// Last, restore the patch area - movl out0=PatchSaveBuffer // out0 = source buffer - addl out1=PATCH_ENTRY_OFFSET, r2 // out1 = destination buffer - mov out2=0x40;; // out2 = number of bundles to copy... save entire IDT entry - br.call.sptk.few b0 = CopyBundles - -UnchainHandlerDone: - NESTED_RETURN - - .endp UnchainHandler - - -///////////////////////////////////////////// -// -// Name: -// CopyBundles -// -// Description: -// Copies instruction bundles - flushes icache as necessary -// -// Arguments: -// in0 - Bundle source -// in1 - Bundle destination -// in2 - Bundle count -// -// Returns: -// -// Notes: -// This procedure is a leaf routine -// - .proc CopyBundles - -CopyBundles: - - NESTED_SETUP(3,2+1,0,0) - - shl in2=in2, 1;; // in2 = count of 8 byte blocks to copy - -CopyBundlesLoop: - - cmp.eq p14, p15 = 0, in2;; // Check if done -(p14) br.sptk.few CopyBundlesDone;; - - ld8 loc2=[in0], 0x8;; // loc2 = source bytes - st8 [in1]=loc2;; // [in1] = destination bytes - fc in1;; // Flush instruction cache - sync.i;; // Ensure local and remote data/inst caches in sync - srlz.i;; // Ensure sync has been observed - add in1=0x8, in1;; // in1 = next destination - add in2=-1, in2;; // in2 = decrement 8 bytes blocks to copy - br.sptk.few CopyBundlesLoop;; - -CopyBundlesDone: - NESTED_RETURN - - .endp CopyBundles - - -///////////////////////////////////////////// -// -// Name: -// RelocateBundle -// -// Description: -// Relocates an instruction bundle by updating any ip-relative branch instructions. -// -// Arguments: -// in0 - Runtime address of bundle -// in1 - IP address of previous location of bundle -// in2 - IP address of new location of bundle -// -// Returns: -// in0 - 1 if successful or 0 if unsuccessful -// -// Notes: -// This routine examines all slots in the given bundle that are destined for the -// branch execution unit. If any of these slots contain an IP-relative branch -// namely instructions B1, B2, B3, or B6, the slot is fixed-up with a new relative -// address. Errors can occur if a branch cannot be reached. -// - .proc RelocateBundle - -RelocateBundle: - - NESTED_SETUP(3,2+4,3,0) - - mov loc2=SLOT0 // loc2 = slot index - mov loc5=in0;; // loc5 = runtime address of bundle - mov in0=1;; // in0 = success - -RelocateBundleNextSlot: - - cmp.ge p14, p15 = SLOT2, loc2;; // Check if maximum slot -(p15) br.sptk.few RelocateBundleDone - - mov out0=loc5;; // out0 = runtime address of bundle - br.call.sptk.few b0 = GetTemplate - mov loc3=out0;; // loc3 = instruction template - mov out0=loc5 // out0 = runtime address of bundle - mov out1=loc2;; // out1 = instruction slot number - br.call.sptk.few b0 = GetSlot - mov loc4=out0;; // loc4 = instruction encoding - mov out0=loc4 // out0 = instuction encoding - mov out1=loc2 // out1 = instruction slot number - mov out2=loc3;; // out2 = instruction template - br.call.sptk.few b0 = IsSlotBranch - cmp.eq p14, p15 = 1, out0;; // Check if branch slot -(p15) add loc2=1,loc2 // Increment slot -(p15) br.sptk.few RelocateBundleNextSlot - mov out0=loc4 // out0 = instuction encoding - mov out1=in1 // out1 = IP address of previous location - mov out2=in2;; // out2 = IP address of new location - br.call.sptk.few b0 = RelocateSlot - cmp.eq p14, p15 = 1, out1;; // Check if relocated slot -(p15) mov in0=0 // in0 = failure -(p15) br.sptk.few RelocateBundleDone - mov out2=out0;; // out2 = instruction encoding - mov out0=loc5 // out0 = runtime address of bundle - mov out1=loc2;; // out1 = instruction slot number - br.call.sptk.few b0 = SetSlot - add loc2=1,loc2;; // Increment slot - br.sptk.few RelocateBundleNextSlot - -RelocateBundleDone: - NESTED_RETURN - - .endp RelocateBundle - - -///////////////////////////////////////////// -// -// Name: -// RelocateSlot -// -// Description: -// Relocates an instruction bundle by updating any ip-relative branch instructions. -// -// Arguments: -// in0 - Instruction encoding (41-bits, right justified) -// in1 - IP address of previous location of bundle -// in2 - IP address of new location of bundle -// -// Returns: -// in0 - Instruction encoding (41-bits, right justified) -// in1 - 1 if successful otherwise 0 -// -// Notes: -// This procedure is a leaf routine -// - .proc RelocateSlot - -RelocateSlot: - NESTED_SETUP(3,2+5,0,0) - extr.u loc2=in0, 37, 4;; // loc2 = instruction opcode - cmp.eq p14, p15 = 4, loc2;; // IP-relative branch (B1) or - // IP-relative counted branch (B2) -(p15) cmp.eq p14, p15 = 5, loc2;; // IP-relative call (B3) -(p15) cmp.eq p14, p15 = 7, loc2;; // IP-relative predict (B6) -(p15) mov in1=1 // Instruction did not need to be reencoded -(p15) br.sptk.few RelocateSlotDone - tbit.nz p14, p15 = in0, 36;; // put relative offset sign bit in p14 - extr.u loc2=in0, 13, 20;; // loc2 = relative offset in instruction -(p14) movl loc3=0xfffffffffff00000;; // extend sign -(p14) or loc2=loc2, loc3;; - shl loc2=loc2,4;; // convert to byte offset instead of bundle offset - add loc3=loc2, in1;; // loc3 = physical address of branch target -(p14) sub loc2=r0,loc2;; // flip sign in loc2 if offset is negative - sub loc4=loc3,in2;; // loc4 = relative offset from new ip to branch target - cmp.lt p15, p14 = 0, loc4;; // get new sign bit -(p14) sub loc5=r0,loc4 // get absolute value of offset -(p15) mov loc5=loc4;; - movl loc6=0x0FFFFFF;; // maximum offset in bytes for ip-rel branch - cmp.gt p14, p15 = loc5, loc6;; // check to see we're not out of range for an ip-relative branch -(p14) br.sptk.few RelocateSlotError - cmp.lt p15, p14 = 0, loc4;; // store sign in p14 again -(p14) dep in0=-1,in0,36,1 // store sign bit in instruction -(p15) dep in0=0,in0,36,1 - shr loc4=loc4, 4;; // convert back to bundle offset - dep in0=loc4,in0,13,16;; // put first 16 bits of new offset into instruction - shr loc4=loc4,16;; - dep in0=loc4,in0,13+16,4 // put last 4 bits of new offset into instruction - mov in1=1;; // in1 = success - br.sptk.few RelocateSlotDone;; - -RelocateSlotError: - mov in1=0;; // in1 = failure - -RelocateSlotDone: - NESTED_RETURN - - .endp RelocateSlot - - -///////////////////////////////////////////// -// -// Name: -// IsSlotBranch -// -// Description: -// Determines if the given instruction is a branch instruction. -// -// Arguments: -// in0 - Instruction encoding (41-bits, right justified) -// in1 - Instruction slot number -// in2 - Bundle template -// -// Returns: -// in0 - 1 if branch or 0 if not branch -// -// Notes: -// This procedure is a leaf routine -// -// IsSlotBranch recognizes all branch instructions by looking at the provided template. -// The instruction encoding is only passed to this routine for future expansion. -// - .proc IsSlotBranch - -IsSlotBranch: - - NESTED_SETUP (3,2+0,0,0) - - mov in0=1;; // in0 = 1 which destroys the instruction - andcm in2=in2,in0;; // in2 = even template to reduce compares - mov in0=0;; // in0 = not a branch - cmp.eq p14, p15 = 0x16, in2;; // Template 0x16 is BBB -(p14) br.sptk.few IsSlotBranchTrue - cmp.eq p14, p15 = SLOT0, in1;; // Slot 0 has no other possiblities -(p14) br.sptk.few IsSlotBranchDone - cmp.eq p14, p15 = 0x12, in2;; // Template 0x12 is MBB -(p14) br.sptk.few IsSlotBranchTrue - cmp.eq p14, p15 = SLOT1, in1;; // Slot 1 has no other possiblities -(p14) br.sptk.few IsSlotBranchDone - cmp.eq p14, p15 = 0x10, in2;; // Template 0x10 is MIB -(p14) br.sptk.few IsSlotBranchTrue - cmp.eq p14, p15 = 0x18, in2;; // Template 0x18 is MMB -(p14) br.sptk.few IsSlotBranchTrue - cmp.eq p14, p15 = 0x1C, in2;; // Template 0x1C is MFB -(p14) br.sptk.few IsSlotBranchTrue - br.sptk.few IsSlotBranchDone - -IsSlotBranchTrue: - mov in0=1;; // in0 = branch - -IsSlotBranchDone: - NESTED_RETURN - - .endp IsSlotBranch - - -///////////////////////////////////////////// -// -// Name: -// GetTemplate -// -// Description: -// Retrieves the instruction template for an instruction bundle -// -// Arguments: -// in0 - Runtime address of bundle -// -// Returns: -// in0 - Instruction template (5-bits, right-justified) -// -// Notes: -// This procedure is a leaf routine -// - .proc GetTemplate - -GetTemplate: - - NESTED_SETUP (1,2+2,0,0) - - ld8 loc2=[in0], 0x8 // loc2 = first 8 bytes of branch bundle - movl loc3=MASK_0_4;; // loc3 = template mask - and loc2=loc2,loc3;; // loc2 = template, right justified - mov in0=loc2;; // in0 = template, right justified - - NESTED_RETURN - - .endp GetTemplate - - -///////////////////////////////////////////// -// -// Name: -// GetSlot -// -// Description: -// Gets the instruction encoding for an instruction slot and bundle -// -// Arguments: -// in0 - Runtime address of bundle -// in1 - Instruction slot (either 0, 1, or 2) -// -// Returns: -// in0 - Instruction encoding (41-bits, right justified) -// -// Notes: -// This procedure is a leaf routine -// -// Slot0 - [in0 + 0x8] Bits 45-5 -// Slot1 - [in0 + 0x8] Bits 63-46 and [in0] Bits 22-0 -// Slot2 - [in0] Bits 63-23 -// - .proc GetSlot - -GetSlot: - NESTED_SETUP (2,2+3,0,0) - - ld8 loc2=[in0], 0x8;; // loc2 = first 8 bytes of branch bundle - ld8 loc3=[in0];; // loc3 = second 8 bytes of branch bundle - cmp.eq p14, p15 = 2, in1;; // check if slot 2 specified - (p14) br.cond.sptk.few GetSlot2;; // get slot 2 - cmp.eq p14, p15 = 1, in1;; // check if slot 1 specified - (p14) br.cond.sptk.few GetSlot1;; // get slot 1 - -GetSlot0: - extr.u in0=loc2, 5, 45 // in0 = extracted slot 0 - br.sptk.few GetSlotDone;; - -GetSlot1: - extr.u in0=loc2, 46, 18 // in0 = bits 63-46 of loc2 right-justified - extr.u loc4=loc3, 0, 23;; // loc4 = bits 22-0 of loc3 right-justified - dep in0=loc4, in0, 18, 15;; - shr.u loc4=loc4,15;; - dep in0=loc4, in0, 33, 8;; // in0 = extracted slot 1 - br.sptk.few GetSlotDone;; - -GetSlot2: - extr.u in0=loc3, 23, 41;; // in0 = extracted slot 2 - -GetSlotDone: - NESTED_RETURN - - .endp GetSlot - - -///////////////////////////////////////////// -// -// Name: -// SetSlot -// -// Description: -// Sets the instruction encoding for an instruction slot and bundle -// -// Arguments: -// in0 - Runtime address of bundle -// in1 - Instruction slot (either 0, 1, or 2) -// in2 - Instruction encoding (41-bits, right justified) -// -// Returns: -// -// Notes: -// This procedure is a leaf routine -// - .proc SetSlot - -SetSlot: - NESTED_SETUP (3,2+3,0,0) - - ld8 loc2=[in0], 0x8;; // loc2 = first 8 bytes of bundle - ld8 loc3=[in0];; // loc3 = second 8 bytes of bundle - cmp.eq p14, p15 = 2, in1;; // check if slot 2 specified - (p14) br.cond.sptk.few SetSlot2;; // set slot 2 - cmp.eq p14, p15 = 1, in1;; // check if slot 1 specified - (p14) br.cond.sptk.few SetSlot1;; // set slot 1 - -SetSlot0: - dep loc2=0, loc2, 5, 41;; // remove old instruction from slot 0 - shl loc4=in2, 5;; // loc4 = new instruction ready to be inserted - or loc2=loc2, loc4;; // loc2 = updated first 8 bytes of bundle - add loc4=0x8,in0;; // loc4 = address to store first 8 bytes of bundle - st8 [loc4]=loc2 // [loc4] = updated bundle - br.sptk.few SetSlotDone;; - ;; - -SetSlot1: - dep loc2=0, loc2, 46, 18 // remove old instruction from slot 1 - dep loc3=0, loc3, 0, 23;; - shl loc4=in2, 46;; // loc4 = partial instruction ready to be inserted - or loc2=loc2, loc4;; // loc2 = updated first 8 bytes of bundle - add loc4=0x8,in0;; // loc4 = address to store first 8 bytes of bundle - st8 [loc4]=loc2;; // [loc4] = updated bundle - shr.u loc4=in2, 18;; // loc4 = partial instruction ready to be inserted - or loc3=loc3, loc4;; // loc3 = updated second 8 bytes of bundle - st8 [in0]=loc3;; // [in0] = updated bundle - br.sptk.few SetSlotDone;; - -SetSlot2: - dep loc3=0, loc3, 23, 41;; // remove old instruction from slot 2 - shl loc4=in2, 23;; // loc4 = instruction ready to be inserted - or loc3=loc3, loc4;; // loc3 = updated second 8 bytes of bundle - st8 [in0]=loc3;; // [in0] = updated bundle - -SetSlotDone: - - NESTED_RETURN - .endp SetSlot - - -///////////////////////////////////////////// -// -// Name: -// GetIva -// -// Description: -// C callable function to obtain the current value of IVA -// -// Returns: -// Current value if IVA - - ASM_GLOBAL GetIva - .proc GetIva -GetIva: - mov r8=cr2;; - br.ret.sptk.many b0 - - .endp GetIva - - -///////////////////////////////////////////// -// -// Name: -// ProgramInterruptFlags -// -// Description: -// C callable function to enable/disable interrupts -// -// Returns: -// Previous state of psr.ic -// - ASM_GLOBAL ProgramInterruptFlags - .proc ProgramInterruptFlags -ProgramInterruptFlags: - alloc loc0=1,2,0,0;; - mov loc0=psr - mov loc1=0x6000;; - and r8=loc0, loc1 // obtain current psr.ic and psr.i state - and in0=in0, loc1 // insure no extra bits set in input - andcm loc0=loc0,loc1;; // clear original psr.i and psr.ic - or loc0=loc0,in0;; // OR in new psr.ic value - mov psr.l=loc0;; // write new psr - srlz.d - br.ret.sptk.many b0 // return - - .endp ProgramInterruptFlags - - -///////////////////////////////////////////// -// -// Name: -// SpillContext -// -// Description: -// Saves system context to context record. -// -// Arguments: -// in0 = 512 byte aligned context record address -// in1 = original B0 -// in2 = original ar.bsp -// in3 = original ar.bspstore -// in4 = original ar.rnat -// in5 = original ar.pfs -// -// Notes: -// loc0 - scratch -// loc1 - scratch -// loc2 - temporary application unat storage -// loc3 - temporary exception handler unat storage - - .proc SpillContext - -SpillContext: - alloc loc0=6,4,0,0;; // alloc 6 input, 4 locals, 0 outs - mov loc2=ar.unat;; // save application context unat (spilled later) - mov ar.unat=r0;; // set UNAT=0 - st8.spill [in0]=r0,8;; - st8.spill [in0]=r1,8;; // save R1 - R31 - st8.spill [in0]=r2,8;; - st8.spill [in0]=r3,8;; - st8.spill [in0]=r4,8;; - st8.spill [in0]=r5,8;; - st8.spill [in0]=r6,8;; - st8.spill [in0]=r7,8;; - st8.spill [in0]=r8,8;; - st8.spill [in0]=r9,8;; - st8.spill [in0]=r10,8;; - st8.spill [in0]=r11,8;; - st8.spill [in0]=r12,8;; - st8.spill [in0]=r13,8;; - st8.spill [in0]=r14,8;; - st8.spill [in0]=r15,8;; - st8.spill [in0]=r16,8;; - st8.spill [in0]=r17,8;; - st8.spill [in0]=r18,8;; - st8.spill [in0]=r19,8;; - st8.spill [in0]=r20,8;; - st8.spill [in0]=r21,8;; - st8.spill [in0]=r22,8;; - st8.spill [in0]=r23,8;; - st8.spill [in0]=r24,8;; - st8.spill [in0]=r25,8;; - st8.spill [in0]=r26,8;; - st8.spill [in0]=r27,8;; - st8.spill [in0]=r28,8;; - st8.spill [in0]=r29,8;; - st8.spill [in0]=r30,8;; - st8.spill [in0]=r31,8;; - mov loc3=ar.unat;; // save debugger context unat (spilled later) - stf.spill [in0]=f2,16;; // save f2 - f31 - stf.spill [in0]=f3,16;; - stf.spill [in0]=f4,16;; - stf.spill [in0]=f5,16;; - stf.spill [in0]=f6,16;; - stf.spill [in0]=f7,16;; - stf.spill [in0]=f8,16;; - stf.spill [in0]=f9,16;; - stf.spill [in0]=f10,16;; - stf.spill [in0]=f11,16;; - stf.spill [in0]=f12,16;; - stf.spill [in0]=f13,16;; - stf.spill [in0]=f14,16;; - stf.spill [in0]=f15,16;; - stf.spill [in0]=f16,16;; - stf.spill [in0]=f17,16;; - stf.spill [in0]=f18,16;; - stf.spill [in0]=f19,16;; - stf.spill [in0]=f20,16;; - stf.spill [in0]=f21,16;; - stf.spill [in0]=f22,16;; - stf.spill [in0]=f23,16;; - stf.spill [in0]=f24,16;; - stf.spill [in0]=f25,16;; - stf.spill [in0]=f26,16;; - stf.spill [in0]=f27,16;; - stf.spill [in0]=f28,16;; - stf.spill [in0]=f29,16;; - stf.spill [in0]=f30,16;; - stf.spill [in0]=f31,16;; - mov loc0=pr;; // save predicates - st8.spill [in0]=loc0,8;; - st8.spill [in0]=in1,8;; // save b0 - b7... in1 already equals saved b0 - mov loc0=b1;; - st8.spill [in0]=loc0,8;; - mov loc0=b2;; - st8.spill [in0]=loc0,8;; - mov loc0=b3;; - st8.spill [in0]=loc0,8;; - mov loc0=b4;; - st8.spill [in0]=loc0,8;; - mov loc0=b5;; - st8.spill [in0]=loc0,8;; - mov loc0=b6;; - st8.spill [in0]=loc0,8;; - mov loc0=b7;; - st8.spill [in0]=loc0,8;; - mov loc0=ar.rsc;; // save ar.rsc - st8.spill [in0]=loc0,8;; - st8.spill [in0]=in2,8;; // save ar.bsp (in2) - st8.spill [in0]=in3,8;; // save ar.bspstore (in3) - st8.spill [in0]=in4,8;; // save ar.rnat (in4) - mov loc0=ar.fcr;; // save ar.fcr (ar21 - IA32 floating-point control register) - st8.spill [in0]=loc0,8;; - mov loc0=ar.eflag;; // save ar.eflag (ar24) - st8.spill [in0]=loc0,8;; - mov loc0=ar.csd;; // save ar.csd (ar25 - ia32 CS descriptor) - st8.spill [in0]=loc0,8;; - mov loc0=ar.ssd;; // save ar.ssd (ar26 - ia32 ss descriptor) - st8.spill [in0]=loc0,8;; - mov loc0=ar.cflg;; // save ar.cflg (ar27 - ia32 cr0 and cr4) - st8.spill [in0]=loc0,8;; - mov loc0=ar.fsr;; // save ar.fsr (ar28 - ia32 floating-point status register) - st8.spill [in0]=loc0,8;; - mov loc0=ar.fir;; // save ar.fir (ar29 - ia32 floating-point instruction register) - st8.spill [in0]=loc0,8;; - mov loc0=ar.fdr;; // save ar.fdr (ar30 - ia32 floating-point data register) - st8.spill [in0]=loc0,8;; - mov loc0=ar.ccv;; // save ar.ccv - st8.spill [in0]=loc0,8;; - st8.spill [in0]=loc2,8;; // save ar.unat (saved to loc2 earlier) - mov loc0=ar.fpsr;; // save floating point status register - st8.spill [in0]=loc0,8;; - st8.spill [in0]=in5,8;; // save ar.pfs - mov loc0=ar.lc;; // save ar.lc - st8.spill [in0]=loc0,8;; - mov loc0=ar.ec;; // save ar.ec - st8.spill [in0]=loc0,8;; - - // save control registers - mov loc0=cr.dcr;; // save dcr - st8.spill [in0]=loc0,8;; - mov loc0=cr.itm;; // save itm - st8.spill [in0]=loc0,8;; - mov loc0=cr.iva;; // save iva - st8.spill [in0]=loc0,8;; - mov loc0=cr.pta;; // save pta - st8.spill [in0]=loc0,8;; - mov loc0=cr.ipsr;; // save ipsr - st8.spill [in0]=loc0,8;; - mov loc0=cr.isr;; // save isr - st8.spill [in0]=loc0,8;; - mov loc0=cr.iip;; // save iip - st8.spill [in0]=loc0,8;; - mov loc0=cr.ifa;; // save ifa - st8.spill [in0]=loc0,8;; - mov loc0=cr.itir;; // save itir - st8.spill [in0]=loc0,8;; - mov loc0=cr.iipa;; // save iipa - st8.spill [in0]=loc0,8;; - mov loc0=cr.ifs;; // save ifs - st8.spill [in0]=loc0,8;; - mov loc0=cr.iim;; // save iim - st8.spill [in0]=loc0,8;; - mov loc0=cr.iha;; // save iha - st8.spill [in0]=loc0,8;; - - // save debug registers - mov loc0=dbr[r0];; // save dbr0 - dbr7 - st8.spill [in0]=loc0,8;; - movl loc1=1;; - mov loc0=dbr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=2;; - mov loc0=dbr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=3;; - mov loc0=dbr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=4;; - mov loc0=dbr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=5;; - mov loc0=dbr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=6;; - mov loc0=dbr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=7;; - mov loc0=dbr[loc1];; - st8.spill [in0]=loc0,8;; - mov loc0=ibr[r0];; // save ibr0 - ibr7 - st8.spill [in0]=loc0,8;; - movl loc1=1;; - mov loc0=ibr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=2;; - mov loc0=ibr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=3;; - mov loc0=ibr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=4;; - mov loc0=ibr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=5;; - mov loc0=ibr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=6;; - mov loc0=ibr[loc1];; - st8.spill [in0]=loc0,8;; - movl loc1=7;; - mov loc0=ibr[loc1];; - st8.spill [in0]=loc0,8;; - st8.spill [in0]=loc3;; - - br.ret.sptk.few b0 - - .endp SpillContext - - -///////////////////////////////////////////// -// -// Name: -// FillContext -// -// Description: -// Restores register context from context record. -// -// Arguments: -// in0 = address of last element 512 byte aligned context record address -// in1 = modified B0 -// in2 = modified ar.bsp -// in3 = modified ar.bspstore -// in4 = modified ar.rnat -// in5 = modified ar.pfs -// -// Notes: -// loc0 - scratch -// loc1 - scratch -// loc2 - temporary application unat storage -// loc3 - temporary exception handler unat storage - - .proc FillContext -FillContext: - alloc loc0=6,4,0,0;; // alloc 6 inputs, 4 locals, 0 outs - ld8.fill loc3=[in0],-8;; // int_nat (nat bits for R1-31) - movl loc1=7;; // ibr7 - ld8.fill loc0=[in0],-8;; - mov ibr[loc1]=loc0;; - movl loc1=6;; // ibr6 - ld8.fill loc0=[in0],-8;; - mov ibr[loc1]=loc0;; - movl loc1=5;; // ibr5 - ld8.fill loc0=[in0],-8;; - mov ibr[loc1]=loc0;; - movl loc1=4;; // ibr4 - ld8.fill loc0=[in0],-8;; - mov ibr[loc1]=loc0;; - movl loc1=3;; // ibr3 - ld8.fill loc0=[in0],-8;; - mov ibr[loc1]=loc0;; - movl loc1=2;; // ibr2 - ld8.fill loc0=[in0],-8;; - mov ibr[loc1]=loc0;; - movl loc1=1;; // ibr1 - ld8.fill loc0=[in0],-8;; - mov ibr[loc1]=loc0;; - ld8.fill loc0=[in0],-8;; // ibr0 - mov ibr[r0]=loc0;; - movl loc1=7;; // dbr7 - ld8.fill loc0=[in0],-8;; - mov dbr[loc1]=loc0;; - movl loc1=6;; // dbr6 - ld8.fill loc0=[in0],-8;; - mov dbr[loc1]=loc0;; - movl loc1=5;; // dbr5 - ld8.fill loc0=[in0],-8;; - mov dbr[loc1]=loc0;; - movl loc1=4;; // dbr4 - ld8.fill loc0=[in0],-8;; - mov dbr[loc1]=loc0;; - movl loc1=3;; // dbr3 - ld8.fill loc0=[in0],-8;; - mov dbr[loc1]=loc0;; - movl loc1=2;; // dbr2 - ld8.fill loc0=[in0],-8;; - mov dbr[loc1]=loc0;; - movl loc1=1;; // dbr1 - ld8.fill loc0=[in0],-8;; - mov dbr[loc1]=loc0;; - ld8.fill loc0=[in0],-8;; // dbr0 - mov dbr[r0]=loc0;; - ld8.fill loc0=[in0],-8;; // iha - mov cr.iha=loc0;; - ld8.fill loc0=[in0],-8;; // iim - mov cr.iim=loc0;; - ld8.fill loc0=[in0],-8;; // ifs - mov cr.ifs=loc0;; - ld8.fill loc0=[in0],-8;; // iipa - mov cr.iipa=loc0;; - ld8.fill loc0=[in0],-8;; // itir - mov cr.itir=loc0;; - ld8.fill loc0=[in0],-8;; // ifa - mov cr.ifa=loc0;; - ld8.fill loc0=[in0],-8;; // iip - mov cr.iip=loc0;; - ld8.fill loc0=[in0],-8;; // isr - mov cr.isr=loc0;; - ld8.fill loc0=[in0],-8;; // ipsr - mov cr.ipsr=loc0;; - ld8.fill loc0=[in0],-8;; // pta - mov cr.pta=loc0;; - ld8.fill loc0=[in0],-8;; // iva - mov cr.iva=loc0;; - ld8.fill loc0=[in0],-8;; // itm - mov cr.itm=loc0;; - ld8.fill loc0=[in0],-8;; // dcr - mov cr.dcr=loc0;; - ld8.fill loc0=[in0],-8;; // ec - mov ar.ec=loc0;; - ld8.fill loc0=[in0],-8;; // lc - mov ar.lc=loc0;; - ld8.fill in5=[in0],-8;; // ar.pfs - ld8.fill loc0=[in0],-8;; // ar.fpsr - mov ar.fpsr=loc0;; - ld8.fill loc2=[in0],-8;; // ar.unat - restored later... - ld8.fill loc0=[in0],-8;; // ar.ccv - mov ar.ccv=loc0;; - ld8.fill loc0=[in0],-8;; // ar.fdr - mov ar.fdr=loc0;; - ld8.fill loc0=[in0],-8;; // ar.fir - mov ar.fir=loc0;; - ld8.fill loc0=[in0],-8;; // ar.fsr - mov ar.fsr=loc0;; - ld8.fill loc0=[in0],-8;; // ar.cflg - mov ar.cflg=loc0;; - ld8.fill loc0=[in0],-8;; // ar.ssd - mov ar.ssd=loc0;; - ld8.fill loc0=[in0],-8;; // ar.csd - mov ar.csd=loc0;; - ld8.fill loc0=[in0],-8;; // ar.eflag - mov ar.eflag=loc0;; - ld8.fill loc0=[in0],-8;; // ar.fcr - mov ar.fcr=loc0;; - ld8.fill in4=[in0],-8;; // ar.rnat - ld8.fill in3=[in0],-8;; // bspstore - ld8.fill in2=[in0],-8;; // bsp - ld8.fill loc0=[in0],-8;; // ar.rsc - mov ar.rsc=loc0;; - ld8.fill loc0=[in0],-8;; // B7 - B0 - mov b7=loc0;; - ld8.fill loc0=[in0],-8;; - mov b6=loc0;; - ld8.fill loc0=[in0],-8;; - mov b5=loc0;; - ld8.fill loc0=[in0],-8;; - mov b4=loc0;; - ld8.fill loc0=[in0],-8;; - mov b3=loc0;; - ld8.fill loc0=[in0],-8;; - mov b2=loc0;; - ld8.fill loc0=[in0],-8;; - mov b1=loc0;; - ld8.fill in1=[in0],-8;; // b0 is temporarily stored in in1 - ld8.fill loc0=[in0],-16;; // predicates - mov pr=loc0;; - ldf.fill f31=[in0],-16;; - ldf.fill f30=[in0],-16;; - ldf.fill f29=[in0],-16;; - ldf.fill f28=[in0],-16;; - ldf.fill f27=[in0],-16;; - ldf.fill f26=[in0],-16;; - ldf.fill f25=[in0],-16;; - ldf.fill f24=[in0],-16;; - ldf.fill f23=[in0],-16;; - ldf.fill f22=[in0],-16;; - ldf.fill f21=[in0],-16;; - ldf.fill f20=[in0],-16;; - ldf.fill f19=[in0],-16;; - ldf.fill f18=[in0],-16;; - ldf.fill f17=[in0],-16;; - ldf.fill f16=[in0],-16;; - ldf.fill f15=[in0],-16;; - ldf.fill f14=[in0],-16;; - ldf.fill f13=[in0],-16;; - ldf.fill f12=[in0],-16;; - ldf.fill f11=[in0],-16;; - ldf.fill f10=[in0],-16;; - ldf.fill f9=[in0],-16;; - ldf.fill f8=[in0],-16;; - ldf.fill f7=[in0],-16;; - ldf.fill f6=[in0],-16;; - ldf.fill f5=[in0],-16;; - ldf.fill f4=[in0],-16;; - ldf.fill f3=[in0],-16;; - ldf.fill f2=[in0],-8;; - mov ar.unat=loc3;; // restore unat (int_nat) before fill of general registers - ld8.fill r31=[in0],-8;; - ld8.fill r30=[in0],-8;; - ld8.fill r29=[in0],-8;; - ld8.fill r28=[in0],-8;; - ld8.fill r27=[in0],-8;; - ld8.fill r26=[in0],-8;; - ld8.fill r25=[in0],-8;; - ld8.fill r24=[in0],-8;; - ld8.fill r23=[in0],-8;; - ld8.fill r22=[in0],-8;; - ld8.fill r21=[in0],-8;; - ld8.fill r20=[in0],-8;; - ld8.fill r19=[in0],-8;; - ld8.fill r18=[in0],-8;; - ld8.fill r17=[in0],-8;; - ld8.fill r16=[in0],-8;; - ld8.fill r15=[in0],-8;; - ld8.fill r14=[in0],-8;; - ld8.fill r13=[in0],-8;; - ld8.fill r12=[in0],-8;; - ld8.fill r11=[in0],-8;; - ld8.fill r10=[in0],-8;; - ld8.fill r9=[in0],-8;; - ld8.fill r8=[in0],-8;; - ld8.fill r7=[in0],-8;; - ld8.fill r6=[in0],-8;; - ld8.fill r5=[in0],-8;; - ld8.fill r4=[in0],-8;; - ld8.fill r3=[in0],-8;; - ld8.fill r2=[in0],-8;; - ld8.fill r1=[in0],-8;; - mov ar.unat=loc2;; // restore application context unat - - br.ret.sptk.many b0 - - .endp FillContext - - -///////////////////////////////////////////// -// -// Name: -// HookHandler -// -// Description: -// Common branch target from hooked IVT entries. Runs in interrupt context. -// Responsible for saving and restoring context and calling common C -// handler. Banked registers running on bank 0 at entry. -// -// Arguments: -// All arguments are passed in banked registers: -// B0_REG = Original B0 -// SCRATCH_REG1 = IVT entry index -// -// Returns: -// Returns via rfi -// -// Notes: -// loc0 - scratch -// loc1 - scratch -// loc2 - vector number / mask -// loc3 - 16 byte aligned context record address -// loc4 - temporary storage of last address in context record - -HookHandler: - flushrs;; // Synch RSE with backing store - mov SCRATCH_REG2=ar.bsp // save interrupted context bsp - mov SCRATCH_REG3=ar.bspstore // save interrupted context bspstore - mov SCRATCH_REG4=ar.rnat // save interrupted context rnat - mov SCRATCH_REG6=cr.ifs;; // save IFS in case we need to chain... - cover;; // creates new frame, moves old - // CFM to IFS. - alloc SCRATCH_REG5=0,5,6,0 // alloc 5 locals, 6 outs - ;; - // save banked registers to locals - mov out1=B0_REG // out1 = Original B0 - mov out2=SCRATCH_REG2 // out2 = original ar.bsp - mov out3=SCRATCH_REG3 // out3 = original ar.bspstore - mov out4=SCRATCH_REG4 // out4 = original ar.rnat - mov out5=SCRATCH_REG5 // out5 = original ar.pfs - mov loc2=SCRATCH_REG1;; // loc2 = vector number + chain flag - bsw.1;; // switch banked registers to bank 1 - srlz.d // explicit serialize required - // now fill in context record structure - movl loc3=IpfContextBuf // Insure context record is aligned - add loc0=-0x200,r0;; // mask the lower 9 bits (align on 512 byte boundary) - and loc3=loc3,loc0;; - add loc3=0x200,loc3;; // move to next 512 byte boundary - // loc3 now contains the 512 byte aligned context record - // spill register context into context record - mov out0=loc3;; // Context record base in out0 - // original B0 in out1 already - // original ar.bsp in out2 already - // original ar.bspstore in out3 already - br.call.sptk.few b0=SpillContext;; // spill context - mov loc4=out0 // save modified address - - // At this point, the context has been saved to the context record and we're - // ready to call the C part of the handler... - - movl loc0=CommonHandler;; // obtain address of plabel - ld8 loc1=[loc0];; // get entry point of CommonHandler - mov b6=loc1;; // put it in a branch register - adds loc1= 8, loc0;; // index to GP in plabel - ld8 r1=[loc1];; // set up gp for C call - mov loc1=0xfffff;; // mask off so only vector bits are present - and out0=loc2,loc1;; // pass vector number (exception type) - mov out1=loc3;; // pass context record address - br.call.sptk.few b0=b6;; // call C handler - - // We've returned from the C call, so restore the context and either rfi - // back to interrupted thread, or chain into the SAL if this was an external interrupt - mov out0=loc4;; // pass address of last element in context record - br.call.sptk.few b0=FillContext;; // Fill context - mov b0=out1 // fill in b0 - mov ar.rnat=out4 - mov ar.pfs=out5 - - // Loadrs is necessary because the debugger may have changed some values in - // the backing store. The processor, however may not be aware that the - // stacked registers need to be reloaded from the backing store. Therefore, - // we explicitly cause the RSE to refresh the stacked register's contents - // from the backing store. - mov loc0=ar.rsc // get RSC value - mov loc1=ar.rsc // save it so we can restore it - movl loc3=0xffffffffc000ffff;; // create mask for clearing RSC.loadrs - and loc0=loc0,loc3;; // create value for RSC with RSC.loadrs==0 - mov ar.rsc=loc0;; // modify RSC - loadrs;; // invalidate register stack - mov ar.rsc=loc1;; // restore original RSC - - bsw.0;; // switch banked registers back to bank 0 - srlz.d;; // explicit serialize required - mov PR_REG=pr // save predicates - to be restored after chaining decision - mov B0_REG=b0 // save b0 - required by chain code - mov loc2=EXCPT_EXTERNAL_INTERRUPT;; - cmp.eq p7,p0=SCRATCH_REG1,loc2;; // check to see if this is the timer tick - (p7) br.cond.dpnt.few DO_CHAIN;; - -NO_CHAIN: - mov pr=PR_REG;; - rfi;; // we're outa here. - -DO_CHAIN: - mov pr=PR_REG - mov SCRATCH_REG1=cr.iva - mov SCRATCH_REG2=PATCH_RETURN_OFFSET;; - add SCRATCH_REG1=SCRATCH_REG1, SCRATCH_REG2;; - mov b0=SCRATCH_REG1;; - br.cond.sptk.few b0;; - -EndHookHandler: - - -///////////////////////////////////////////// -// -// Name: -// HookStub -// -// Description: -// HookStub will be copied from it's loaded location into the IVT when -// an IVT entry is hooked. The IVT entry does an indirect jump via B0 to -// HookHandler, which in turn calls into the default C handler, which calls -// the user-installed C handler. The calls return and HookHandler executes -// an rfi. -// -// Notes: -// Saves B0 to B0_REG -// Saves IVT index to SCRATCH_REG1 (immediate value is fixed up when code is copied -// to the IVT entry. - - ASM_GLOBAL HookStub - .proc HookStub -HookStub: - - mov B0_REG=b0 - movl SCRATCH_REG1=HookHandler;; - mov b0=SCRATCH_REG1;; - mov SCRATCH_REG1=0;;// immediate value is fixed up during install of handler to be the vector number - br.cond.sptk.few b0 - - .endp HookStub - - -///////////////////////////////////////////// -// The following code is moved into IVT entry 14 (offset 3400) which is reserved -// in the Itanium architecture. The patch code is located at the end of the -// IVT entry. - -PatchCode: - mov SCRATCH_REG0=psr - mov SCRATCH_REG6=cr.ipsr - mov PR_REG=pr - mov B0_REG=b0;; - - // turn off any virtual translations - movl SCRATCH_REG1 = ~( MASK(PSR_DT,1) | MASK(PSR_RT,1));; - and SCRATCH_REG1 = SCRATCH_REG0, SCRATCH_REG1;; - mov psr.l = SCRATCH_REG1;; - srlz.d - tbit.z p14, p15 = SCRATCH_REG6, PSR_IS;; // Check to see if we were - // interrupted from IA32 - // context. If so, bail out - // and chain to SAL immediately - (p15) br.cond.sptk.few Stub_IVT_Passthru;; - // we only want to take 1 out of 32 external interrupts to minimize the - // impact to system performance. Check our interrupt count and bail - // out if we're not up to 32 - movl SCRATCH_REG1=ExternalInterruptCount;; - ld8 SCRATCH_REG2=[SCRATCH_REG1];; // ExternalInterruptCount - tbit.z p14, p15 = SCRATCH_REG2, 5;; // bit 5 set? - (p14) add SCRATCH_REG2=1, SCRATCH_REG2;; // No? Then increment - // ExternalInterruptCount - // and Chain to SAL - // immediately - (p14) st8 [SCRATCH_REG1]=SCRATCH_REG2;; - (p14) br.cond.sptk.few Stub_IVT_Passthru;; - (p15) mov SCRATCH_REG2=0;; // Yes? Then reset - // ExternalInterruptCount - // and branch to - // HookHandler - (p15) st8 [SCRATCH_REG1]=SCRATCH_REG2;; - mov pr=PR_REG - movl SCRATCH_REG1=HookHandler;; // SCRATCH_REG1 = entrypoint of HookHandler - mov b0=SCRATCH_REG1;; // b0 = entrypoint of HookHandler - mov SCRATCH_REG1=EXCPT_EXTERNAL_INTERRUPT;; - br.sptk.few b0;; // branch to HookHandler - -PatchCodeRet: - // fake-up an rfi to get RSE back to being coherent and insure psr has - // original contents when interrupt occured, then exit to SAL - // at this point: - // cr.ifs has been modified by previous "cover" - // SCRATCH_REG6 has original cr.ifs - - mov SCRATCH_REG5=cr.ipsr - mov SCRATCH_REG4=cr.iip;; - mov cr.ipsr=SCRATCH_REG0 - mov SCRATCH_REG1=ip;; - add SCRATCH_REG1=0x30, SCRATCH_REG1;; - mov cr.iip=SCRATCH_REG1;; - rfi;; // rfi to next instruction - -Stub_RfiTarget: - mov cr.ifs=SCRATCH_REG6 - mov cr.ipsr=SCRATCH_REG5 - mov cr.iip=SCRATCH_REG4;; - -Stub_IVT_Passthru: - mov pr=PR_REG // pr = saved predicate registers - mov b0=B0_REG;; // b0 = saved b0 -EndPatchCode: - - -///////////////////////////////////////////// -// The following bundle is moved into IVT entry 14 (offset 0x3400) which is reserved -// in the Itanium architecture. This bundle will be the last bundle and will -// be located at offset 0x37F0 in the IVT. - -FailsafeBranch: -{ - .mib - nop.m 0 - nop.i 0 - br.sptk.few -(FAILSAFE_BRANCH_OFFSET - EXT_INT_ENTRY_OFFSET - 0x10) -} - - -///////////////////////////////////////////// -// The following bundle is moved into IVT entry 13 (offset 0x3000) which is the -// external interrupt. It branches to the patch code. - -PatchCodeNewBun0: -{ - .mib - nop.m 0 - nop.i 0 - br.cond.sptk.few PATCH_BRANCH -} diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/Common.i b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/Common.i deleted file mode 100644 index a11f780125..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/Common.i +++ /dev/null @@ -1,29 +0,0 @@ -/// @file -/// This is set of useful macros. -/// -/// Copyright (c) 2006, 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. -/// -/// Module Name: Common.i -/// -/// - - -#define NESTED_SETUP(i,l,o,r) \ - alloc loc1=ar##.##pfs,i,l,o,r ; \ - mov loc0=b0 ;; - - -#define NESTED_RETURN \ - mov b0=loc0 ; \ - mov ar##.##pfs=loc1 ;; \ - br##.##ret##.##dpnt b0 ;; - -#define MASK(bp,value) (value << bp) - diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/Ds64Macros.i b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/Ds64Macros.i deleted file mode 100644 index 8ce97f32c2..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/Ds64Macros.i +++ /dev/null @@ -1,78 +0,0 @@ -/// @file -/// This is set of macros used in calculating offsets in the IVT. -/// -/// Copyright (c) 2006 - 2008, 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. -/// -/// - - -#define EXCPT_EXTERNAL_INTERRUPT 12 -#define MASK_0_4 0x000000000000001F // mask bits 0 through 4 -#define SLOT0 0 -#define SLOT1 1 -#define SLOT2 2 - -#define PSR_DT 17 -#define PSR_TB 26 -#define PSR_RT 27 -#define PSR_IS 34 -#define PSR_IT 36 -#define PSR_IC 13 -#define PSR_I 14 -#define PSR_SS 40 -#define PSR_BN 44 -#define PSR_RI_MASK 0x60000000000 - -#define EXCPT_EXTERNAL_INTERRUPT 12 - -#define SCRATCH_REG0 r23 -#define SCRATCH_REG1 r24 -#define SCRATCH_REG2 r25 -#define SCRATCH_REG3 r26 -#define SCRATCH_REG4 r27 -#define SCRATCH_REG5 r28 -#define SCRATCH_REG6 r29 -#define PR_REG r30 -#define B0_REG r31 - - -// EXT_INT_OFFSET is the offset of the external interrupt entry in the IVT -#define EXT_INT_ENTRY_OFFSET 0x03000 - -// PATCH_ENTRY_OFFSET is the offset into the IVT of the entry that is coopted (stolen) -// for use by the handler. The entire entry is restored when the handler is -// unloaded. -#define PATCH_ENTRY_OFFSET 0x03400 - -// PATCH_CODE_SIZE is the size of patch code -#define PATCH_CODE_SIZE (EndPatchCode - PatchCode) - -// A hard coded branch back into the external interrupt IVT entry's second bundle -// is put here, just in case the original bundle zero did not have a branch -// This is the last bundle in the reserved IVT entry -#define FAILSAFE_BRANCH_OFFSET (PATCH_ENTRY_OFFSET + 0x400 - 0x10) - -// the original external interrupt IVT entry bundle zero is copied and relocated -// here... also in the reserved IVT entry -// This is the second-to-last bundle in the reserved IVT entry -#define RELOCATED_EXT_INT (PATCH_ENTRY_OFFSET + 0x400 - 0x20) - -// The patch is actually stored at the end of IVT:PATCH_ENTRY. The PATCH_OFFSET -// is the offset into IVT where the patch is actually stored. It is carefully -// located so that when we run out of patch code, the next bundle is the -// relocated bundle 0 from the original external interrupt handler -#define PATCH_OFFSET (PATCH_ENTRY_OFFSET + 0x400 - ( EndPatchCode - PatchCode ) - 0x20) - -#define PATCH_RETURN_OFFSET (PATCH_ENTRY_OFFSET + 0x400 - ( EndPatchCode - PatchCodeRet ) - 0x20) - -// PATCH_BRANCH is used only in the new bundle that is placed at the beginning -// of the external interrupt IVT entry. -#define PATCH_BRANCH (PATCH_OFFSET - EXT_INT_ENTRY_OFFSET) - diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.c deleted file mode 100644 index 44f59e8ec8..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.c +++ /dev/null @@ -1,467 +0,0 @@ -/** @file - IPF specific functions to support Debug Support protocol. - -Copyright (c) 2006 - 2010, 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. - -**/ - -#include "PlDebugSupport.h" - -BOOLEAN mInHandler = FALSE; - -// -// number of bundles to swap in ivt -// -#define NUM_BUNDLES_IN_STUB 5 -#define NUM_IVT_ENTRIES 64 - -typedef struct { - BUNDLE OrigBundles[NUM_BUNDLES_IN_STUB]; - CALLBACK_FUNC RegisteredCallback; -} IVT_ENTRY; - -IVT_ENTRY IvtEntryTable[NUM_IVT_ENTRIES]; - -// -// IPF context record is overallocated by 512 bytes to guarantee a 512 byte alignment exists -// within the buffer and still have a large enough buffer to hold a whole IPF context record. -// -UINT8 IpfContextBuf[sizeof (EFI_SYSTEM_CONTEXT_IPF) + 512]; - -// -// The PatchSaveBuffer is used to store the original bundles from the IVT where it is patched -// with the common handler. -// -UINT8 PatchSaveBuffer[0x400]; -UINTN ExternalInterruptCount; - - -/** - IPF specific DebugSupport driver initialization. - - Must be public because it's referenced from DebugSupport.c - - @retval EFI_SUCCESS Always. - -**/ -EFI_STATUS -PlInitializeDebugSupportDriver ( - VOID - ) -{ - ZeroMem (IvtEntryTable, sizeof (IvtEntryTable)); - ExternalInterruptCount = 0; - return EFI_SUCCESS; -} - -/** - Unload handler that is called during UnloadImage() - deallocates pool memory - used by the driver. - - Must be public because it's referenced from DebugSuport.c - - @param ImageHandle The firmware allocated handle for the EFI image. - - @retval EFI_SUCCESS Always. - -**/ -EFI_STATUS -EFIAPI -PlUnloadDebugSupportDriver ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_EXCEPTION_TYPE ExceptionType; - - for (ExceptionType = 0; ExceptionType < NUM_IVT_ENTRIES; ExceptionType++) { - ManageIvtEntryTable (ExceptionType, NULL, NULL); - } - - return EFI_SUCCESS; -} - -/** - C routine that is called for all registered exceptions. This is the main - exception dispatcher. - - Must be public because it's referenced from AsmFuncs.s. - - @param ExceptionType Specifies which processor exception. - @param Context System Context. -**/ -VOID -CommonHandler ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN EFI_SYSTEM_CONTEXT Context - ) -{ - DEBUG_CODE_BEGIN (); - if (mInHandler) { - DEBUG ((EFI_D_INFO, "ERROR: Re-entered debugger!\n" - " ExceptionType == %X\n" - " Context == %X\n" - " Context.SystemContextIpf->CrIip == %LX\n" - " Context.SystemContextIpf->CrIpsr == %LX\n" - " mInHandler == %X\n", - (INT32)ExceptionType, - Context, - Context.SystemContextIpf->CrIip, - Context.SystemContextIpf->CrIpsr, - mInHandler)); - } - DEBUG_CODE_END (); - - ASSERT (!mInHandler); - mInHandler = TRUE; - if (IvtEntryTable[ExceptionType].RegisteredCallback != NULL) { - if (ExceptionType != EXCEPT_IPF_EXTERNAL_INTERRUPT) { - IvtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, Context.SystemContextIpf); - } else { - IvtEntryTable[ExceptionType].RegisteredCallback (Context.SystemContextIpf); - } - } else { - ASSERT (0); - } - - mInHandler = FALSE; -} - -/** - Given an integer number, return the physical address of the entry point in the IFT. - - @param HandlerIndex Index of the Handler - @param EntryPoint IFT Entrypoint - -**/ -VOID -GetHandlerEntryPoint ( - UINTN HandlerIndex, - VOID **EntryPoint - ) -{ - UINT8 *TempPtr; - - // - // get base address of IVT - // - TempPtr = GetIva (); - - if (HandlerIndex < 20) { - // - // first 20 provide 64 bundles per vector - // - TempPtr += 0x400 * HandlerIndex; - } else { - // - // the rest provide 16 bundles per vector - // - TempPtr += 0x5000 + 0x100 * (HandlerIndex - 20); - } - - *EntryPoint = (VOID *) TempPtr; -} - -/** - This is the worker function that uninstalls and removes all handlers. - - @param ExceptionType Specifies which processor exception. - @param NewBundles New Boundles. - @param NewCallback A pointer to the new function to be registered. - - @retval EFI_ALEADY_STARTED Ivt already hooked. - @retval EFI_SUCCESS Successfully uninstalled. - -**/ -EFI_STATUS -ManageIvtEntryTable ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN BUNDLE NewBundles[NUM_BUNDLES_IN_STUB], - IN CALLBACK_FUNC NewCallback - ) -{ - BUNDLE *B0Ptr; - UINT64 InterruptFlags; - EFI_TPL OldTpl; - - // - // Get address of bundle 0 - // - GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr); - - if (IvtEntryTable[ExceptionType].RegisteredCallback != NULL) { - // - // we've already installed to this vector - // - if (NewCallback != NULL) { - // - // if the input handler is non-null, error - // - return EFI_ALREADY_STARTED; - } else { - // - // else remove the previously installed handler - // - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - InterruptFlags = ProgramInterruptFlags (DISABLE_INTERRUPTS); - if (ExceptionType == EXCEPT_IPF_EXTERNAL_INTERRUPT) { - UnchainExternalInterrupt (); - } else { - UnhookEntry (ExceptionType); - } - - ProgramInterruptFlags (InterruptFlags); - gBS->RestoreTPL (OldTpl); - // - // re-init IvtEntryTable - // - ZeroMem (&IvtEntryTable[ExceptionType], sizeof (IVT_ENTRY)); - } - } else { - // - // no user handler installed on this vector - // - if (NewCallback != NULL) { - OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); - InterruptFlags = ProgramInterruptFlags (DISABLE_INTERRUPTS); - if (ExceptionType == EXCEPT_IPF_EXTERNAL_INTERRUPT) { - ChainExternalInterrupt (NewCallback); - } else { - HookEntry (ExceptionType, NewBundles, NewCallback); - } - - ProgramInterruptFlags (InterruptFlags); - gBS->RestoreTPL (OldTpl); - } - } - - return EFI_SUCCESS; -} - -/** - Saves original IVT contents and inserts a few new bundles which are fixed up - to store the ExceptionType and then call the common handler. - - @param ExceptionType Specifies which processor exception. - @param NewBundles New Boundles. - @param NewCallback A pointer to the new function to be hooked. - -**/ -VOID -HookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN BUNDLE NewBundles[4], - IN CALLBACK_FUNC NewCallback - ) -{ - BUNDLE *FixupBundle; - BUNDLE *B0Ptr; - - // - // Get address of bundle 0 - // - GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr); - - // - // copy original bundles from IVT to IvtEntryTable so we can restore them later - // - CopyMem ( - IvtEntryTable[ExceptionType].OrigBundles, - B0Ptr, - sizeof (BUNDLE) * NUM_BUNDLES_IN_STUB - ); - // - // insert new B0 - // - CopyMem (B0Ptr, NewBundles, sizeof (BUNDLE) * NUM_BUNDLES_IN_STUB); - - // - // fixup IVT entry so it stores its index and whether or not to chain... - // - FixupBundle = B0Ptr + 2; - FixupBundle->High |= ExceptionType << 36; - - InstructionCacheFlush (B0Ptr, 5); - IvtEntryTable[ExceptionType].RegisteredCallback = NewCallback; -} - -/** - Restores original IVT contents when unregistering a callback function. - - @param ExceptionType Specifies which processor exception. - -**/ -VOID -UnhookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType - ) -{ - BUNDLE *B0Ptr; - - // - // Get address of bundle 0 - // - GetHandlerEntryPoint (ExceptionType, (VOID **) &B0Ptr); - // - // restore original bundles in IVT - // - CopyMem ( - B0Ptr, - IvtEntryTable[ExceptionType].OrigBundles, - sizeof (BUNDLE) * NUM_BUNDLES_IN_STUB - ); - InstructionCacheFlush (B0Ptr, 5); -} - -/** - Sets up cache flush and calls assembly function to chain external interrupt. - - Records new callback in IvtEntryTable. - - @param NewCallback A pointer to the interrupt handle. - -**/ -VOID -ChainExternalInterrupt ( - IN CALLBACK_FUNC NewCallback - ) -{ - VOID *Start; - - Start = (VOID *) ((UINT8 *) GetIva () + 0x400 * EXCEPT_IPF_EXTERNAL_INTERRUPT + 0x400); - IvtEntryTable[EXCEPT_IPF_EXTERNAL_INTERRUPT].RegisteredCallback = NewCallback; - ChainHandler (); - InstructionCacheFlush (Start, 0x400); -} - -/** - Sets up cache flush and calls assembly function to restore external interrupt. - Removes registered callback from IvtEntryTable. - -**/ -VOID -UnchainExternalInterrupt ( - VOID - ) -{ - VOID *Start; - - Start = (VOID *) ((UINT8 *) GetIva () + 0x400 * EXCEPT_IPF_EXTERNAL_INTERRUPT + 0x400); - UnchainHandler (); - InstructionCacheFlush (Start, 0x400); - IvtEntryTable[EXCEPT_IPF_EXTERNAL_INTERRUPT].RegisteredCallback = NULL; -} - -/** - Returns the maximum value that may be used for the ProcessorIndex parameter in - RegisterPeriodicCallback() and RegisterExceptionCallback(). - - Hard coded to support only 1 processor for now. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param MaxProcessorIndex Pointer to a caller-allocated UINTN in which the maximum supported - processor index is returned. Always 0 returned. - - @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0. - -**/ -EFI_STATUS -EFIAPI -GetMaximumProcessorIndex ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - OUT UINTN *MaxProcessorIndex - ) -{ - *MaxProcessorIndex = 0; - return (EFI_SUCCESS); -} - -/** - Registers a function to be called back periodically in interrupt context. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor the callback function applies to. - @param PeriodicCallback A pointer to a function of type PERIODIC_CALLBACK that is the main - periodic entry point of the debug agent. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback - function was previously registered. - @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback - function. -**/ -EFI_STATUS -EFIAPI -RegisterPeriodicCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_PERIODIC_CALLBACK PeriodicCallback - ) -{ - return ManageIvtEntryTable (EXCEPT_IPF_EXTERNAL_INTERRUPT, NULL, PeriodicCallback); -} - -/** - Registers a function to be called when a given processor exception occurs. - - This code executes in boot services context. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor the callback function applies to. - @param ExceptionCallback A pointer to a function of type EXCEPTION_CALLBACK that is called - when the processor exception specified by ExceptionType occurs. - @param ExceptionType Specifies which processor exception to hook. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback - function was previously registered. - @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback - function. -**/ -EFI_STATUS -EFIAPI -RegisterExceptionCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_EXCEPTION_CALLBACK ExceptionCallback, - IN EFI_EXCEPTION_TYPE ExceptionType - ) -{ - return ManageIvtEntryTable ( - ExceptionType, - (BUNDLE *) ((EFI_PLABEL *) HookStub)->EntryPoint, - ExceptionCallback - ); -} - -/** - Invalidates processor instruction cache for a memory range. Subsequent execution in this range - causes a fresh memory fetch to retrieve code to be executed. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor's instruction cache is to be invalidated. - @param Start Specifies the physical base of the memory range to be invalidated. - @param Length Specifies the minimum number of bytes in the processor's instruction - cache to invalidate. - - @retval EFI_SUCCESS Always returned. - -**/ -EFI_STATUS -EFIAPI -InvalidateInstructionCache ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN VOID *Start, - IN UINTN Length - ) -{ - InstructionCacheFlush (Start, Length); - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h deleted file mode 100644 index 0cf29cadfb..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h +++ /dev/null @@ -1,324 +0,0 @@ -/** @file - IPF specific types, macros, and definitions for Debug Support Driver. - -Copyright (c) 2004 - 2010, 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. - -**/ - -#ifndef _PLDEBUG_SUPPORT_H_ -#define _PLDEBUG_SUPPORT_H_ - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#define DISABLE_INTERRUPTS 0UL - -#define EFI_ISA IsaIpf - -typedef struct { - UINT64 Low; - UINT64 High; -} BUNDLE; - -typedef -VOID -(*CALLBACK_FUNC) ( - ); - -/** - IPF specific DebugSupport driver initialization. - - Must be public because it's referenced from DebugSupport.c - - @retval EFI_SUCCESS Always. - -**/ -EFI_STATUS -PlInitializeDebugSupportDriver ( - VOID - ); - -/** - Unload handler that is called during UnloadImage() - deallocates pool memory - used by the driver. - - Must be public because it's referenced from DebugSuport.c - - @param ImageHandle The firmware allocated handle for the EFI image. - - @retval EFI_SUCCESS Always. - -**/ -EFI_STATUS -EFIAPI -PlUnloadDebugSupportDriver ( - IN EFI_HANDLE ImageHandle - ); - -/** - C callable function to obtain the current value of IVA. - - @return Current value of IVA. - -**/ -VOID * -GetIva ( - VOID - ); - -/** - C callable function that HookStub will be copied from it's loaded location into the IVT when - an IVT entry is hooked. - -**/ -VOID -HookStub ( - VOID - ); - -/** - C callable function to chain an interrupt handler. - -**/ -VOID -ChainHandler ( - VOID - ); - -/** - C callable function to unchain an interrupt handler. - -**/ -VOID -UnchainHandler ( - VOID - ); - -/** - C callable function to enable/disable interrupts. - - @param NewInterruptState New Interrupt State. - - @return Previous state of psr.ic. - -**/ -UINT64 -ProgramInterruptFlags ( - IN UINT64 NewInterruptState - ); - -/** - Flushes instruction cache for specified number of bytes. - - @param StartAddress Cache Start Address. - @param SizeInBytes Cache Size. - -**/ -VOID -InstructionCacheFlush ( - IN VOID *StartAddress, - IN UINTN SizeInBytes - ); - -/** - Returns the maximum value that may be used for the ProcessorIndex parameter in - RegisterPeriodicCallback() and RegisterExceptionCallback(). - - Hard coded to support only 1 processor for now. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param MaxProcessorIndex Pointer to a caller-allocated UINTN in which the maximum supported - processor index is returned. Always 0 returned. - - @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0. - -**/ -EFI_STATUS -EFIAPI -GetMaximumProcessorIndex ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - OUT UINTN *MaxProcessorIndex - ); - -/** - Registers a function to be called back periodically in interrupt context. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor the callback function applies to. - @param PeriodicCallback A pointer to a function of type PERIODIC_CALLBACK that is the main - periodic entry point of the debug agent. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback - function was previously registered. - @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback - function. -**/ -EFI_STATUS -EFIAPI -RegisterPeriodicCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_PERIODIC_CALLBACK PeriodicCallback - ); - -/** - Registers a function to be called when a given processor exception occurs. - - This code executes in boot services context. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor the callback function applies to. - @param ExceptionCallback A pointer to a function of type EXCEPTION_CALLBACK that is called - when the processor exception specified by ExceptionType occurs. - @param ExceptionType Specifies which processor exception to hook. - - @retval EFI_SUCCESS The function completed successfully. - @retval EFI_ALREADY_STARTED Non-NULL PeriodicCallback parameter when a callback - function was previously registered. - @retval EFI_OUT_OF_RESOURCES System has insufficient memory resources to register new callback - function. -**/ -EFI_STATUS -EFIAPI -RegisterExceptionCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_EXCEPTION_CALLBACK ExceptionCallback, - IN EFI_EXCEPTION_TYPE ExceptionType - ); - -/** - Invalidates processor instruction cache for a memory range. Subsequent execution in this range - causes a fresh memory fetch to retrieve code to be executed. - - @param This A pointer to the EFI_DEBUG_SUPPORT_PROTOCOL instance. - @param ProcessorIndex Specifies which processor's instruction cache is to be invalidated. - @param Start Specifies the physical base of the memory range to be invalidated. - @param Length Specifies the minimum number of bytes in the processor's instruction - cache to invalidate. - - @retval EFI_SUCCESS Always returned. - -**/ -EFI_STATUS -EFIAPI -InvalidateInstructionCache ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN VOID *Start, - IN UINTN Length - ); - -/** - C routine that is called for all registered exceptions. This is the main - exception dispatcher. - - Must be public because it's referenced from AsmFuncs.s. - - @param ExceptionType Specifies which processor exception. - @param Context System Context. -**/ -VOID -CommonHandler ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN EFI_SYSTEM_CONTEXT Context - ); - -/** - This is the worker function that uninstalls and removes all handlers. - - @param ExceptionType Specifies which processor exception. - @param NewBundles New Boundles. - @param NewCallback A pointer to the new function to be registered. - - @retval EFI_ALEADY_STARTED Ivt already hooked. - @retval EFI_SUCCESS Successfully uninstalled. - -**/ -EFI_STATUS -ManageIvtEntryTable ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN BUNDLE NewBundles[4], - IN CALLBACK_FUNC NewCallback - ); - -/** - Saves original IVT contents and inserts a few new bundles which are fixed up - to store the ExceptionType and then call the common handler. - - @param ExceptionType Specifies which processor exception. - @param NewBundles New Boundles. - @param NewCallback A pointer to the new function to be hooked. - -**/ -VOID -HookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN BUNDLE NewBundles[4], - IN CALLBACK_FUNC NewCallback - ); - -/** - Restores original IVT contents when unregistering a callback function. - - @param ExceptionType Specifies which processor exception. - -**/ -VOID -UnhookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType - ); - -/** - Sets up cache flush and calls assembly function to chain external interrupt. - - Records new callback in IvtEntryTable. - - @param NewCallback A pointer to the interrupt handle. - -**/ -VOID -ChainExternalInterrupt ( - IN CALLBACK_FUNC NewCallback - ); - -/** - Sets up cache flush and calls assembly function to restore external interrupt. - Removes registered callback from IvtEntryTable. - -**/ -VOID -UnchainExternalInterrupt ( - VOID - ); - -/** - Given an integer number, return the physical address of the entry point in the IFT. - - @param HandlerIndex Index of the Handler - @param EntryPoint IFT Entrypoint - -**/ -VOID -GetHandlerEntryPoint ( - UINTN HandlerIndex, - VOID **EntryPoint - ); - -#endif diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S deleted file mode 100644 index 7f0919ee1b..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S +++ /dev/null @@ -1,551 +0,0 @@ -///**@file -// Low leve x64 specific debug support functions. -// -// Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
-// Portions copyright (c) 2008 - 2009, Apple Inc. 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. -// -//**/ - -ASM_GLOBAL ASM_PFX(OrigVector) -ASM_GLOBAL ASM_PFX(InterruptEntryStub) -ASM_GLOBAL ASM_PFX(StubSize) -ASM_GLOBAL ASM_PFX(CommonIdtEntry) -ASM_GLOBAL ASM_PFX(FxStorSupport) - -.data - -ASM_PFX(StubSize): .long ASM_PFX(InterruptEntryStubEnd) - ASM_PFX(InterruptEntryStub) -ASM_PFX(AppRsp): .long 0x11111111 # ? - .long 0x11111111 # ? -ASM_PFX(DebugRsp): .long 0x22222222 # ? - .long 0x22222222 # ? -ASM_PFX(ExtraPush): .long 0x33333333 # ? - .long 0x33333333 # ? -ASM_PFX(ExceptData): .long 0x44444444 # ? - .long 0x44444444 # ? -ASM_PFX(Rflags): .long 0x55555555 # ? - .long 0x55555555 # ? -ASM_PFX(OrigVector): .long 0x66666666 # ? - .long 0x66666666 # ? - -// The declarations below define the memory region that will be used for the debug stack. -// The context record will be built by pushing register values onto this stack. -// It is imparitive that alignment be carefully managed, since the FXSTOR and -// FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned. -// -// The stub will switch stacks from the application stack to the debuger stack -// and pushes the exception number. -// -// Then we building the context record on the stack. Since the stack grows down, -// we push the fields of the context record from the back to the front. There -// are 336 bytes of stack used prior allocating the 512 bytes of stack to be -// used as the memory buffer for the fxstor instruction. Therefore address of -// the buffer used for the FXSTOR instruction is &Eax - 336 - 512, which -// must be 16 byte aligned. -// -// We carefully locate the stack to make this happen. -// -// For reference, the context structure looks like this: -// struct { -// UINT64 ExceptionData; -// FX_SAVE_STATE_X64 FxSaveState; // 512 bytes, must be 16 byte aligned -// UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -// UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; -// UINT64 RFlags; -// UINT64 Ldtr, Tr; -// UINT64 Gdtr[2], Idtr[2]; -// UINT64 Rip; -// UINT64 Gs, Fs, Es, Ds, Cs, Ss; -// UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -// UINT64 R8, R9, R10, R11, R12, R13, R14, R15; -// } SYSTEM_CONTEXT_X64; // 64 bit system context record - -.p2align 4 -DebugStackEnd : .ascii "DbgStkEnd >>>>>>" # 16 byte long string - must be 16 bytes to preserve alignment - .fill 0x1ffc, 4, 0x00000000 - # 32K should be enough stack - # This allocation is coocked to insure - # that the the buffer for the FXSTORE instruction - # will be 16 byte aligned also. - # -ASM_PFX(ExceptionNumber): .long 0x77777777 # first entry will be the vector number pushed by the stub - .long 0x77777777 # ? - -DebugStackBegin : .ascii "<<<< DbgStkBegin" # initial debug ESP == DebugStackBegin, set in stub - - -.text - -//------------------------------------------------------------------------------ -// BOOLEAN -// FxStorSupport ( -// void -// ) -// -// Abstract: Returns TRUE if FxStor instructions are supported -// -ASM_GLOBAL ASM_PFX(FxStorSupport) -ASM_PFX(FxStorSupport): -// -// cpuid corrupts rbx which must be preserved per the C calling convention -// - pushq %rbx - movq $1, %rax - cpuid - movl %edx, %eax - andq $0x01000000, %rax - shrq $24, %rax - popq %rbx - ret -//------------------------------------------------------------------------------ -// void -// Vect2Desc ( -// IA32_IDT_GATE_DESCRIPTOR * DestDesc, // rcx -// void (*Vector) (void) // rdx -// ) -// -// Abstract: Encodes an IDT descriptor with the given physical address -// -ASM_GLOBAL ASM_PFX(Vect2Desc) -ASM_PFX(Vect2Desc): - movq %rdx, %rax - movw %ax, (%rcx) # write bits 15..0 of offset - movw %cs, %dx - movw %dx, 2(%rcx) # SYS_CODE_SEL from GDT - movw $(0x0e00 | 0x8000), 4(%rcx) # type = 386 interrupt gate, present - shrq $16, %rax - movw %ax, 6(%rcx) # write bits 31..16 of offset - shrq $16, %rax - movl %eax, 8(%rcx) # write bits 63..32 of offset - - ret - -//------------------------------------------------------------------------------ -// InterruptEntryStub -// -// Abstract: This code is not a function, but is a small piece of code that is -// copied and fixed up once for each IDT entry that is hooked. -// -ASM_GLOBAL ASM_PFX(InterruptEntryStub) -ASM_PFX(InterruptEntryStub): - - pushq $0 # push vector number - will be modified before installed - jmp ASM_PFX(CommonIdtEntry) - -ASM_GLOBAL ASM_PFX(InterruptEntryStubEnd) -ASM_PFX(InterruptEntryStubEnd): - -//------------------------------------------------------------------------------ -// CommonIdtEntry -// -// Abstract: This code is not a function, but is the common part for all IDT -// vectors. -// -ASM_GLOBAL ASM_PFX(CommonIdtEntry) -// -// At this point, the stub has saved the current application stack esp into AppRsp -// and switched stacks to the debug stack, where it pushed the vector number -// -// The application stack looks like this: -// -// ... -// (last application stack entry) -// [16 bytes alignment, do not care it] -// SS from interrupted task -// RSP from interrupted task -// rflags from interrupted task -// CS from interrupted task -// RIP from interrupted task -// Error code <-------------------- Only present for some exeption types -// -// Vector Number <----------------- pushed in our IDT Entry -// - - -// The stub switched us to the debug stack and pushed the interrupt number. -// -// Next, construct the context record. It will be build on the debug stack by -// pushing the registers in the correct order so as to create the context structure -// on the debug stack. The context record must be built from the end back to the -// beginning because the stack grows down... -// -// For reference, the context record looks like this: -// -// typedef -// struct { -// UINT64 ExceptionData; -// FX_SAVE_STATE_X64 FxSaveState; -// UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -// UINT64 Cr0, Cr2, Cr3, Cr4, Cr8; -// UINT64 RFlags; -// UINT64 Ldtr, Tr; -// UINT64 Gdtr[2], Idtr[2]; -// UINT64 Rip; -// UINT64 Gs, Fs, Es, Ds, Cs, Ss; -// UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -// UINT64 R8, R9, R10, R11, R12, R13, R14, R15; -// } SYSTEM_CONTEXT_X64; // 64 -ASM_PFX(CommonIdtEntry): -// NOTE: we save rsp here to prevent compiler put rip reference cause error AppRsp - pushq %rax - movq (8)(%rsp), %rax # save vector number - movq %rax, ASM_PFX(ExceptionNumber)(%rip) # save vector number - popq %rax - addq $8, %rsp # pop vector number - movq %rsp, ASM_PFX(AppRsp)(%rip) # save stack top - movq DebugStackBegin(%rip), %rsp # switch to debugger stack - subq $8, %rsp # leave space for vector number -// 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 %rcx - pushq %rdx - pushq %rbx - pushq %rsp - pushq %rbp - pushq %rsi - pushq %rdi -// Save interrupt state rflags register... - pushfq - popq %rax - movq %rax, ASM_PFX(Rflags)(%rip) -// We need to determine if any extra data was pushed by the exception, and if so, save it -// To do this, we check the exception number pushed by the stub, and cache the -// result in a variable since we'll need this again. - cmpl $0, ASM_PFX(ExceptionNumber)(%rip) - jz ExtraPushOne - cmpl $10, ASM_PFX(ExceptionNumber)(%rip) - jz ExtraPushOne - cmpl $11, ASM_PFX(ExceptionNumber)(%rip) - jz ExtraPushOne - cmpl $12, ASM_PFX(ExceptionNumber)(%rip) - jz ExtraPushOne - cmpl $13, ASM_PFX(ExceptionNumber)(%rip) - jz ExtraPushOne - cmpl $14, ASM_PFX(ExceptionNumber)(%rip) - jz ExtraPushOne - cmpl $17, ASM_PFX(ExceptionNumber)(%rip) - jz ExtraPushOne - movl $0, ASM_PFX(ExtraPush)(%rip) - movl $0, ASM_PFX(ExceptData)(%rip) - jmp ExtraPushDone -ExtraPushOne: - movl $1, ASM_PFX(ExtraPush)(%rip) - -// If there's some extra data, save it also, and modify the saved AppRsp to effectively -// pop this value off the application's stack. - movq ASM_PFX(AppRsp)(%rip), %rax - movq (%rax), %rbx - movq %rbx, ASM_PFX(ExceptData)(%rip) - addq $8, %rax - movq %rax, ASM_PFX(AppRsp)(%rip) - -ExtraPushDone: - -// The "push" above pushed the debug stack rsp. Since what we're actually doing -// is building the context record on the debug stack, we need to save the pushed -// debug RSP, and replace it with the application's last stack entry... - movq 24(%rsp), %rax - movq %rax, ASM_PFX(DebugRsp)(%rip) - movq ASM_PFX(AppRsp)(%rip), %rax - movq 24(%rax), %rax - # application stack has ss, rsp, rflags, cs, & rip, so - # last actual application stack entry is saved at offset - # 24 bytes from stack top. - movq %rax, 24(%rsp) - -// continue building context record -// UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - mov %ss, %rax - pushq %rax - # CS from application is one entry back in application stack - movq ASM_PFX(AppRsp)(%rip), %rax - movzxw 8(%rax), %rax - pushq %rax - - mov %ds, %rax - pushq %rax - mov %es, %rax - pushq %rax - mov %fs, %rax - pushq %rax - mov %gs, %rax - pushq %rax -// UINT64 Rip; - # Rip from application is on top of application stack - movq ASM_PFX(AppRsp)(%rip), %rax - pushq (%rax) -// UINT64 Gdtr[2], Idtr[2]; - push $0 - push $0 - sidtq (%rsp) - push $0 - push $0 - sgdtq (%rsp) - -// UINT64 Ldtr, Tr; - xorq %rax, %rax - str %ax - pushq %rax - sldt %ax - pushq %rax - -// UINT64 RFlags; -// Rflags from application is two entries back in application stack - movq ASM_PFX(AppRsp)(%rip), %rax - pushq 16(%rax) -// UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; -// insure FXSAVE/FXRSTOR is enabled in CR4... -// ... while we're at it, make sure DE is also enabled... - movq %cr8, %rax - pushq %rax - movq %cr4, %rax - orq $0x208, %rax - movq %rax, %cr4 - pushq %rax - movq %cr3, %rax - pushq %rax - movq %cr2, %rax - pushq %rax - push $0 - movq %cr0, %rax - pushq %rax -// UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - movq %dr7, %rax - pushq %rax -// clear Dr7 while executing debugger itself - xorq %rax, %rax - movq %rax, %dr7 - - movq %dr6, %rax - pushq %rax -// insure all status bits in dr6 are clear... - xorq %rax, %rax - movq %rax, %dr6 - - 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 - # IMPORTANT!! The debug stack has been carefully constructed to - # insure that rsp and rdi are 16 byte aligned when we get here. - # They MUST be. If they are not, a GP fault will occur. - - # FXSTOR_RDI - fxsave (%rdi) - -// UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear - cld - -// UINT64 ExceptionData; - movq ASM_PFX(ExceptData)(%rip), %rax - pushq %rax - -// call to C code which will in turn call registered handler -// pass in the vector number - movq %rsp, %rdx - movq ASM_PFX(ExceptionNumber)(%rip), %rcx - subq $40, %rsp - call ASM_PFX(InterruptDistrubutionHub) - addq $40, %rsp -// restore context... -// UINT64 ExceptionData; - addq $8, %rsp - -// FX_SAVE_STATE_X64 FxSaveState; - movq %rsp, %rsi - - # FXRSTOR_RSI - fxrstor (%rsi) - - addq $512, %rsp - -// UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - popq %rax - movq %rax, %dr0 - popq %rax - movq %rax, %dr1 - popq %rax - movq %rax, %dr2 - popq %rax - movq %rax, %dr3 - -// skip restore of dr6. We cleared dr6 during the context save. - addq $8, %rsp - popq %rax - movq %rax, %dr7 - -// UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - popq %rax - movq %rax, %cr0 - addq $8, %rsp - popq %rax - movq %rax, %cr2 - popq %rax - movq %rax, %cr3 - popq %rax - movq %rax, %cr4 - popq %rax - movq %rax, %cr8 -// UINT64 RFlags; - movq ASM_PFX(AppRsp)(%rip), %rax - popq 16(%rax) -// UINT64 Ldtr, Tr; -// UINT64 Gdtr[2], Idtr[2]; -// Best not let anyone mess with these particular registers... - addq $48, %rsp -// UINT64 Rip; - popq (%rax) - -// UINT64 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. -// - - popq %rax - # mov %rax, %gs - popq %rax - # mov %rax, %fs - popq %rax - mov %rax, %es - popq %rax - mov %rax, %ds - movq ASM_PFX(AppRsp)(%rip), %rax - popq 8(%rax) - popq %rax - mov %rax, %ss -## The next stuff to restore is the general purpose registers that were pushed -## using the "push" instruction. -## -## The value of RSP as stored in the context record is the application RSP -## including the 5 entries on the application stack caused by the exception -## itself. It may have been modified by the debug agent, so we need to -## determine if we need to relocate the application stack. - - movq 24(%rsp), %rbx # move the potentially modified AppRsp into rbx - movq ASM_PFX(AppRsp)(%rip), %rax - movq 24(%rax), %rax - cmpq %rax, %rbx - je NoAppStackMove - - movq ASM_PFX(AppRsp)(%rip), %rax - movq (%rax), %rcx # RIP - movq %rcx, (%rbx) - - movq 8(%rax), %rcx # CS - movq %rcx, 8(%rbx) - - movq 16(%rax), %rcx # RFLAGS - movq %rcx, 16(%rbx) - - movq 24(%rax), %rcx # RSP - movq %rcx, 24(%rbx) - - movq 32(%rax), %rcx # SS - movq %rcx, 32(%rbx) - - movq %rbx, %rax # modify the saved AppRsp to the new AppRsp - movq %rax, ASM_PFX(AppRsp)(%rip) -NoAppStackMove: - movq ASM_PFX(DebugRsp)(%rip), %rax # restore the DebugRsp on the debug stack - # so our "pop" will not cause a stack switch - movq %rax, 24(%rsp) - - cmpl $0x068, ASM_PFX(ExceptionNumber)(%rip) - jne NoChain - -Chain: - -// Restore rflags so when we chain, the flags will be exactly as if we were never here. -// We gin up the stack to do an iretq so we can get ALL the flags. - movq ASM_PFX(AppRsp)(%rip), %rax - movq 40(%rax), %rbx - pushq %rbx - mov %ss, %rax - pushq %rax - movq %rsp, %rax - addq $16, %rax - pushq %rax - movq ASM_PFX(AppRsp)(%rip), %rax - movq 16(%rax), %rbx - andq $0xfffffffffffffcff, %rbx # special handling for IF and TF - pushq %rbx - mov %cs, %rax - pushq %rax - movq PhonyIretq(%rip), %rax - pushq %rax - iretq -PhonyIretq: - -// UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -// UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - popq %rdi - popq %rsi - popq %rbp - popq %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 - -// Switch back to application stack - movq ASM_PFX(AppRsp)(%rip), %rsp -// Jump to original handler - jmp ASM_PFX(OrigVector) -NoChain: -// UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -// UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - popq %rdi - popq %rsi - popq %rbp - popq %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 - -// Switch back to application stack - movq ASM_PFX(AppRsp)(%rip), %rsp - -// We're outa here... - iret diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm deleted file mode 100644 index bce49ef762..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm +++ /dev/null @@ -1,596 +0,0 @@ -;/** @file -; Low level x64 routines used by the debug support driver. -; -; Copyright (c) 2007 - 2011, 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. -; -;**/ - -EXCPT64_DIVIDE_ERROR EQU 0 -EXCPT64_DEBUG EQU 1 -EXCPT64_NMI EQU 2 -EXCPT64_BREAKPOINT EQU 3 -EXCPT64_OVERFLOW EQU 4 -EXCPT64_BOUND EQU 5 -EXCPT64_INVALID_OPCODE EQU 6 -EXCPT64_DOUBLE_FAULT EQU 8 -EXCPT64_INVALID_TSS EQU 10 -EXCPT64_SEG_NOT_PRESENT EQU 11 -EXCPT64_STACK_FAULT EQU 12 -EXCPT64_GP_FAULT EQU 13 -EXCPT64_PAGE_FAULT EQU 14 -EXCPT64_FP_ERROR EQU 16 -EXCPT64_ALIGNMENT_CHECK EQU 17 -EXCPT64_MACHINE_CHECK EQU 18 -EXCPT64_SIMD EQU 19 - -FXSTOR_FLAG EQU 01000000h ; bit cpuid 24 of feature flags - -;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87, -;; MMX, SSE, SSE2, etc registers. The initialization of the debugsupport driver -;; MUST check the CPUID feature flags to see that these instructions are available -;; and fail to init if they are not. - -;; fxstor [rdi] -FXSTOR_RDI MACRO - db 0fh, 0aeh, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [rdi] -ENDM - -;; fxrstor [rsi] -FXRSTOR_RSI MACRO - db 0fh, 0aeh, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [rsi] -ENDM - -data SEGMENT - -public OrigVector, InterruptEntryStub, StubSize, CommonIdtEntry, FxStorSupport - -StubSize dd InterruptEntryStubEnd - InterruptEntryStub -AppRsp dq 1111111111111111h ; ? -DebugRsp dq 2222222222222222h ; ? -ExtraPush dq 3333333333333333h ; ? -ExceptData dq 4444444444444444h ; ? -Rflags dq 5555555555555555h ; ? -OrigVector dq 6666666666666666h ; ? - -;; The declarations below define the memory region that will be used for the debug stack. -;; The context record will be built by pushing register values onto this stack. -;; It is imparitive that alignment be carefully managed, since the FXSTOR and -;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned. -;; -;; The stub will switch stacks from the application stack to the debuger stack -;; and pushes the exception number. -;; -;; Then we building the context record on the stack. Since the stack grows down, -;; we push the fields of the context record from the back to the front. There -;; are 336 bytes of stack used prior allocating the 512 bytes of stack to be -;; used as the memory buffer for the fxstor instruction. Therefore address of -;; the buffer used for the FXSTOR instruction is &Eax - 336 - 512, which -;; must be 16 byte aligned. -;; -;; We carefully locate the stack to make this happen. -;; -;; For reference, the context structure looks like this: -;; struct { -;; UINT64 ExceptionData; -;; FX_SAVE_STATE_X64 FxSaveState; // 512 bytes, must be 16 byte aligned -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; -;; UINT64 RFlags; -;; UINT64 Ldtr, Tr; -;; UINT64 Gdtr[2], Idtr[2]; -;; UINT64 Rip; -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; -;; } SYSTEM_CONTEXT_X64; // 64 bit system context record - -align 16 -DebugStackEnd db "DbgStkEnd >>>>>>" ;; 16 byte long string - must be 16 bytes to preserve alignment - dd 1ffch dup (000000000h) ;; 32K should be enough stack - ;; This allocation is coocked to insure - ;; that the the buffer for the FXSTORE instruction - ;; will be 16 byte aligned also. - ;; -ExceptionNumber dq ? ;; first entry will be the vector number pushed by the stub - -DebugStackBegin db "<<<< DbgStkBegin" ;; initial debug ESP == DebugStackBegin, set in stub - -data ENDS - -text SEGMENT - -externdef InterruptDistrubutionHub:near - -;------------------------------------------------------------------------------ -; BOOLEAN -; FxStorSupport ( -; void -; ) -; -; Abstract: Returns TRUE if FxStor instructions are supported -; -FxStorSupport PROC PUBLIC - -; -; cpuid corrupts rbx which must be preserved per the C calling convention -; - push rbx - mov rax, 1 - cpuid - mov eax, edx - and rax, FXSTOR_FLAG - shr rax, 24 - pop rbx - ret -FxStorSupport ENDP - -;------------------------------------------------------------------------------ -; void -; Vect2Desc ( -; IA32_IDT_GATE_DESCRIPTOR * DestDesc, // rcx -; void (*Vector) (void) // rdx -; ) -; -; Abstract: Encodes an IDT descriptor with the given physical address -; -Vect2Desc PROC PUBLIC - - mov rax, rdx - mov word ptr [rcx], ax ; write bits 15..0 of offset - mov dx, cs - mov word ptr [rcx+2], dx ; SYS_CODE_SEL from GDT - mov word ptr [rcx+4], 0e00h OR 8000h ; type = 386 interrupt gate, present - shr rax, 16 - mov word ptr [rcx+6], ax ; write bits 31..16 of offset - shr rax, 16 - mov dword ptr [rcx+8], eax ; write bits 63..32 of offset - - ret - -Vect2Desc ENDP - - - -;------------------------------------------------------------------------------ -; InterruptEntryStub -; -; Abstract: This code is not a function, but is a small piece of code that is -; copied and fixed up once for each IDT entry that is hooked. -; -InterruptEntryStub:: - push 0 ; push vector number - will be modified before installed - db 0e9h ; jump rel32 - dd 0 ; fixed up to relative address of CommonIdtEntry -InterruptEntryStubEnd: - - - -;------------------------------------------------------------------------------ -; CommonIdtEntry -; -; Abstract: This code is not a function, but is the common part for all IDT -; vectors. -; -CommonIdtEntry:: -;; -;; At this point, the stub has saved the current application stack esp into AppRsp -;; and switched stacks to the debug stack, where it pushed the vector number -;; -;; The application stack looks like this: -;; -;; ... -;; (last application stack entry) -;; [16 bytes alignment, do not care it] -;; SS from interrupted task -;; RSP from interrupted task -;; rflags from interrupted task -;; CS from interrupted task -;; RIP from interrupted task -;; Error code <-------------------- Only present for some exeption types -;; -;; Vector Number <----------------- pushed in our IDT Entry -;; - - -;; The stub switched us to the debug stack and pushed the interrupt number. -;; -;; Next, construct the context record. It will be build on the debug stack by -;; pushing the registers in the correct order so as to create the context structure -;; on the debug stack. The context record must be built from the end back to the -;; beginning because the stack grows down... -; -;; For reference, the context record looks like this: -;; -;; typedef -;; struct { -;; UINT64 ExceptionData; -;; FX_SAVE_STATE_X64 FxSaveState; -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT64 Cr0, Cr2, Cr3, Cr4, Cr8; -;; UINT64 RFlags; -;; UINT64 Ldtr, Tr; -;; UINT64 Gdtr[2], Idtr[2]; -;; UINT64 Rip; -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; -;; } SYSTEM_CONTEXT_X64; // 64 bit system context record - -;; NOTE: we save rsp here to prevent compiler put rip reference cause error AppRsp - push rax - mov rax, qword ptr [rsp][8] ; save vector number - mov ExceptionNumber, rax ; save vector number - pop rax - add rsp, 8 ; pop vector number - mov AppRsp, rsp ; save stack top - mov rsp, offset DebugStackBegin ; switch to debugger stack - sub rsp, 8 ; leave space for vector number - -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - push r15 - push r14 - push r13 - push r12 - push r11 - push r10 - push r9 - push r8 - push rax - push rcx - push rdx - push rbx - push rsp - push rbp - push rsi - push rdi - -;; Save interrupt state rflags register... - pushfq - pop rax - mov qword ptr Rflags, rax - -;; We need to determine if any extra data was pushed by the exception, and if so, save it -;; To do this, we check the exception number pushed by the stub, and cache the -;; result in a variable since we'll need this again. - cmp ExceptionNumber, EXCPT64_DOUBLE_FAULT - jz ExtraPushOne - cmp ExceptionNumber, EXCPT64_INVALID_TSS - jz ExtraPushOne - cmp ExceptionNumber, EXCPT64_SEG_NOT_PRESENT - jz ExtraPushOne - cmp ExceptionNumber, EXCPT64_STACK_FAULT - jz ExtraPushOne - cmp ExceptionNumber, EXCPT64_GP_FAULT - jz ExtraPushOne - cmp ExceptionNumber, EXCPT64_PAGE_FAULT - jz ExtraPushOne - cmp ExceptionNumber, EXCPT64_ALIGNMENT_CHECK - jz ExtraPushOne - mov ExtraPush, 0 - mov ExceptData, 0 - jmp ExtraPushDone -ExtraPushOne: - mov ExtraPush, 1 - -;; If there's some extra data, save it also, and modify the saved AppRsp to effectively -;; pop this value off the application's stack. - mov rax, AppRsp - mov rbx, [rax] - mov ExceptData, rbx - add rax, 8 - mov AppRsp, rax - -ExtraPushDone: - -;; The "push" above pushed the debug stack rsp. Since what we're actually doing -;; is building the context record on the debug stack, we need to save the pushed -;; debug RSP, and replace it with the application's last stack entry... - mov rax, [rsp + 24] - mov DebugRsp, rax - mov rax, AppRsp - mov rax, QWORD PTR [rax + 24] - ; application stack has ss, rsp, rflags, cs, & rip, so - ; last actual application stack entry is saved at offset - ; 24 bytes from stack top. - mov [rsp + 24], rax - -;; continue building context record -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - mov rax, ss - push rax - - ; CS from application is one entry back in application stack - mov rax, AppRsp - movzx rax, word ptr [rax + 8] - push rax - - mov rax, ds - push rax - mov rax, es - push rax - mov rax, fs - push rax - mov rax, gs - push rax - -;; UINT64 Rip; - ; Rip from application is on top of application stack - mov rax, AppRsp - push qword ptr [rax] - -;; UINT64 Gdtr[2], Idtr[2]; - push 0 - push 0 - sidt fword ptr [rsp] - push 0 - push 0 - sgdt fword ptr [rsp] - -;; UINT64 Ldtr, Tr; - xor rax, rax - str ax - push rax - sldt ax - push rax - -;; UINT64 RFlags; -;; Rflags from application is two entries back in application stack - mov rax, AppRsp - push qword ptr [rax + 16] - -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; -;; insure FXSAVE/FXRSTOR is enabled in CR4... -;; ... while we're at it, make sure DE is also enabled... - mov rax, cr8 - push rax - mov rax, cr4 - or rax, 208h - mov cr4, rax - push rax - mov rax, cr3 - push rax - mov rax, cr2 - push rax - push 0 - mov rax, cr0 - push rax - -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - mov rax, dr7 - push rax -;; clear Dr7 while executing debugger itself - xor rax, rax - mov dr7, rax - - mov rax, dr6 - push rax -;; insure all status bits in dr6 are clear... - xor rax, rax - mov dr6, rax - - mov rax, dr3 - push rax - mov rax, dr2 - push rax - mov rax, dr1 - push rax - mov rax, dr0 - push rax - -;; FX_SAVE_STATE_X64 FxSaveState; - sub rsp, 512 - mov rdi, rsp - ; IMPORTANT!! The debug stack has been carefully constructed to - ; insure that rsp and rdi are 16 byte aligned when we get here. - ; They MUST be. If they are not, a GP fault will occur. - FXSTOR_RDI - -;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear - cld - -;; UINT64 ExceptionData; - mov rax, ExceptData - push rax - -; call to C code which will in turn call registered handler -; pass in the vector number - mov rdx, rsp - mov rcx, ExceptionNumber - sub rsp, 40 - call InterruptDistrubutionHub - add rsp, 40 - -; restore context... -;; UINT64 ExceptionData; - add rsp, 8 - -;; FX_SAVE_STATE_X64 FxSaveState; - mov rsi, rsp - FXRSTOR_RSI - add rsp, 512 - -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - pop rax - mov dr0, rax - pop rax - mov dr1, rax - pop rax - mov dr2, rax - pop rax - mov dr3, rax -;; skip restore of dr6. We cleared dr6 during the context save. - add rsp, 8 - pop rax - mov dr7, rax - -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - pop rax - mov cr0, rax - add rsp, 8 - pop rax - mov cr2, rax - pop rax - mov cr3, rax - pop rax - mov cr4, rax - pop rax - mov cr8, rax - -;; UINT64 RFlags; - mov rax, AppRsp - pop qword ptr [rax + 16] - -;; UINT64 Ldtr, Tr; -;; UINT64 Gdtr[2], Idtr[2]; -;; Best not let anyone mess with these particular registers... - add rsp, 48 - -;; UINT64 Rip; - pop qword ptr [rax] - -;; UINT64 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. -;; - - pop rax - ; mov gs, rax - pop rax - ; mov fs, rax - pop rax - mov es, rax - pop rax - mov ds, rax - mov rax, AppRsp - pop qword ptr [rax + 8] - pop rax - mov ss, rax - -;; The next stuff to restore is the general purpose registers that were pushed -;; using the "push" instruction. -;; -;; The value of RSP as stored in the context record is the application RSP -;; including the 5 entries on the application stack caused by the exception -;; itself. It may have been modified by the debug agent, so we need to -;; determine if we need to relocate the application stack. - - mov rbx, [rsp + 24] ; move the potentially modified AppRsp into rbx - mov rax, AppRsp - mov rax, QWORD PTR [rax + 24] - cmp rbx, rax - je NoAppStackMove - - mov rax, AppRsp - mov rcx, [rax] ; RIP - mov [rbx], rcx - - mov rcx, [rax + 8] ; CS - mov [rbx + 8], rcx - - mov rcx, [rax + 16] ; RFLAGS - mov [rbx + 16], rcx - - mov rcx, [rax + 24] ; RSP - mov [rbx + 24], rcx - - mov rcx, [rax + 32] ; SS - mov [rbx + 32], rcx - - mov rax, rbx ; modify the saved AppRsp to the new AppRsp - mov AppRsp, rax -NoAppStackMove: - mov rax, DebugRsp ; restore the DebugRsp on the debug stack - ; so our "pop" will not cause a stack switch - mov [rsp + 24], rax - - cmp ExceptionNumber, 068h - jne NoChain - -Chain: - -;; Restore rflags so when we chain, the flags will be exactly as if we were never here. -;; We gin up the stack to do an iretq so we can get ALL the flags. - mov rax, AppRsp - mov rbx, [rax + 40] - push rbx - mov rax, ss - push rax - mov rax, rsp - add rax, 16 - push rax - mov rax, AppRsp - mov rbx, [rax + 16] - and rbx, NOT 300h ; special handling for IF and TF - push rbx - mov rax, cs - push rax - mov rax, offset PhonyIretq - push rax - iretq -PhonyIretq: - -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - pop rdi - pop rsi - pop rbp - pop rsp - pop rbx - pop rdx - pop rcx - pop rax - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 - -;; Switch back to application stack - mov rsp, AppRsp - -;; Jump to original handler - jmp OrigVector - -NoChain: -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - pop rdi - pop rsi - pop rbp - pop rsp - pop rbx - pop rdx - pop rcx - pop rax - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 - -;; Switch back to application stack - mov rsp, AppRsp - -;; We're outa here... - iretq -text ENDS - -END - - - diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.nasm b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.nasm deleted file mode 100644 index 134842a68a..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.nasm +++ /dev/null @@ -1,587 +0,0 @@ -;/** @file -; Low level x64 routines used by the debug support driver. -; -; Copyright (c) 2007 - 2016, 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. -; -;**/ - -%define EXCPT64_DIVIDE_ERROR 0 -%define EXCPT64_DEBUG 1 -%define EXCPT64_NMI 2 -%define EXCPT64_BREAKPOINT 3 -%define EXCPT64_OVERFLOW 4 -%define EXCPT64_BOUND 5 -%define EXCPT64_INVALID_OPCODE 6 -%define EXCPT64_DOUBLE_FAULT 8 -%define EXCPT64_INVALID_TSS 10 -%define EXCPT64_SEG_NOT_PRESENT 11 -%define EXCPT64_STACK_FAULT 12 -%define EXCPT64_GP_FAULT 13 -%define EXCPT64_PAGE_FAULT 14 -%define EXCPT64_FP_ERROR 16 -%define EXCPT64_ALIGNMENT_CHECK 17 -%define EXCPT64_MACHINE_CHECK 18 -%define EXCPT64_SIMD 19 - -%define FXSTOR_FLAG 0x1000000 ; bit cpuid 24 of feature flags - -;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87, -;; MMX, SSE, SSE2, etc registers. The initialization of the debugsupport driver -;; MUST check the CPUID feature flags to see that these instructions are available -;; and fail to init if they are not. - -;; fxstor [rdi] -%macro FXSTOR_RDI 0 - db 0xf, 0xae, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [rdi] -%endmacro - -;; fxrstor [rsi] -%macro FXRSTOR_RSI 0 - db 0xf, 0xae, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [rsi] -%endmacro - -SECTION .data - -global ASM_PFX(OrigVector) -global ASM_PFX(InterruptEntryStub) -global ASM_PFX(StubSize) -global ASM_PFX(CommonIdtEntry) -global ASM_PFX(FxStorSupport) -extern ASM_PFX(InterruptDistrubutionHub) - -ASM_PFX(StubSize): dd InterruptEntryStubEnd - ASM_PFX(InterruptEntryStub) -AppRsp: dq 0x1111111111111111 ; ? -DebugRsp: dq 0x2222222222222222 ; ? -ExtraPush: dq 0x3333333333333333 ; ? -ExceptData: dq 0x4444444444444444 ; ? -Rflags: dq 0x5555555555555555 ; ? -ASM_PFX(OrigVector): dq 0x6666666666666666 ; ? - -;; The declarations below define the memory region that will be used for the debug stack. -;; The context record will be built by pushing register values onto this stack. -;; It is imparitive that alignment be carefully managed, since the FXSTOR and -;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned. -;; -;; The stub will switch stacks from the application stack to the debuger stack -;; and pushes the exception number. -;; -;; Then we building the context record on the stack. Since the stack grows down, -;; we push the fields of the context record from the back to the front. There -;; are 336 bytes of stack used prior allocating the 512 bytes of stack to be -;; used as the memory buffer for the fxstor instruction. Therefore address of -;; the buffer used for the FXSTOR instruction is &Eax - 336 - 512, which -;; must be 16 byte aligned. -;; -;; We carefully locate the stack to make this happen. -;; -;; For reference, the context structure looks like this: -;; struct { -;; UINT64 ExceptionData; -;; FX_SAVE_STATE_X64 FxSaveState; // 512 bytes, must be 16 byte aligned -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; -;; UINT64 RFlags; -;; UINT64 Ldtr, Tr; -;; UINT64 Gdtr[2], Idtr[2]; -;; UINT64 Rip; -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; -;; } SYSTEM_CONTEXT_X64; // 64 bit system context record - -align 16 -DebugStackEnd: db "DbgStkEnd >>>>>>" ;; 16 byte long string - must be 16 bytes to preserve alignment - times 0x1ffc dd 0x0 ;; 32K should be enough stack - ;; This allocation is coocked to insure - ;; that the the buffer for the FXSTORE instruction - ;; will be 16 byte aligned also. - ;; -ExceptionNumber: dq 0 ;; first entry will be the vector number pushed by the stub - -DebugStackBegin: db "<<<< DbgStkBegin" ;; initial debug ESP == DebugStackBegin, set in stub - -DEFAULT REL -SECTION .text - -;------------------------------------------------------------------------------ -; BOOLEAN -; FxStorSupport ( -; void -; ) -; -; Abstract: Returns TRUE if FxStor instructions are supported -; -global ASM_PFX(FxStorSupport) -ASM_PFX(FxStorSupport): - -; -; cpuid corrupts rbx which must be preserved per the C calling convention -; - push rbx - mov rax, dword 1 - cpuid - mov eax, edx - and rax, FXSTOR_FLAG - shr rax, 24 - pop rbx - ret - -;------------------------------------------------------------------------------ -; void -; Vect2Desc ( -; IA32_IDT_GATE_DESCRIPTOR * DestDesc, // rcx -; void (*Vector) (void) // rdx -; ) -; -; Abstract: Encodes an IDT descriptor with the given physical address -; -global ASM_PFX(Vect2Desc) -ASM_PFX(Vect2Desc): - - mov rax, rdx - mov word [rcx], ax ; write bits 15..0 of offset - mov dx, cs - mov word [rcx+2], dx ; SYS_CODE_SEL from GDT - mov word [rcx+4], 0xe00 | 0x8000 ; type = 386 interrupt gate, present - shr rax, 16 - mov word [rcx+6], ax ; write bits 31..16 of offset - shr rax, 16 - mov dword [rcx+8], eax ; write bits 63..32 of offset - - ret - -;------------------------------------------------------------------------------ -; InterruptEntryStub -; -; Abstract: This code is not a function, but is a small piece of code that is -; copied and fixed up once for each IDT entry that is hooked. -; -ASM_PFX(InterruptEntryStub): - push 0 ; push vector number - will be modified before installed - db 0xe9 ; jump rel32 - dd 0 ; fixed up to relative address of CommonIdtEntry -InterruptEntryStubEnd: - -;------------------------------------------------------------------------------ -; CommonIdtEntry -; -; Abstract: This code is not a function, but is the common part for all IDT -; vectors. -; -ASM_PFX(CommonIdtEntry): -;; -;; At this point, the stub has saved the current application stack esp into AppRsp -;; and switched stacks to the debug stack, where it pushed the vector number -;; -;; The application stack looks like this: -;; -;; ... -;; (last application stack entry) -;; [16 bytes alignment, do not care it] -;; SS from interrupted task -;; RSP from interrupted task -;; rflags from interrupted task -;; CS from interrupted task -;; RIP from interrupted task -;; Error code <-------------------- Only present for some exeption types -;; -;; Vector Number <----------------- pushed in our IDT Entry -;; - -;; The stub switched us to the debug stack and pushed the interrupt number. -;; -;; Next, construct the context record. It will be build on the debug stack by -;; pushing the registers in the correct order so as to create the context structure -;; on the debug stack. The context record must be built from the end back to the -;; beginning because the stack grows down... -; -;; For reference, the context record looks like this: -;; -;; typedef -;; struct { -;; UINT64 ExceptionData; -;; FX_SAVE_STATE_X64 FxSaveState; -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; -;; UINT64 Cr0, Cr2, Cr3, Cr4, Cr8; -;; UINT64 RFlags; -;; UINT64 Ldtr, Tr; -;; UINT64 Gdtr[2], Idtr[2]; -;; UINT64 Rip; -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; -;; } SYSTEM_CONTEXT_X64; // 64 bit system context record - -;; NOTE: we save rsp here to prevent compiler put rip reference cause error AppRsp - push rax - mov rax, qword [rsp+8] ; save vector number - mov [ExceptionNumber], rax ; save vector number - pop rax - add rsp, 8 ; pop vector number - mov [AppRsp], rsp ; save stack top - mov rsp, DebugStackBegin ; switch to debugger stack - sub rsp, 8 ; leave space for vector number - -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - push r15 - push r14 - push r13 - push r12 - push r11 - push r10 - push r9 - push r8 - push rax - push rcx - push rdx - push rbx - push rsp - push rbp - push rsi - push rdi - -;; Save interrupt state rflags register... - pushfq - pop rax - mov [Rflags], rax - -;; We need to determine if any extra data was pushed by the exception, and if so, save it -;; To do this, we check the exception number pushed by the stub, and cache the -;; result in a variable since we'll need this again. - cmp qword [ExceptionNumber], EXCPT64_DOUBLE_FAULT - jz ExtraPushOne - cmp qword [ExceptionNumber], EXCPT64_INVALID_TSS - jz ExtraPushOne - cmp qword [ExceptionNumber], EXCPT64_SEG_NOT_PRESENT - jz ExtraPushOne - cmp qword [ExceptionNumber], EXCPT64_STACK_FAULT - jz ExtraPushOne - cmp qword [ExceptionNumber], EXCPT64_GP_FAULT - jz ExtraPushOne - cmp qword [ExceptionNumber], EXCPT64_PAGE_FAULT - jz ExtraPushOne - cmp qword [ExceptionNumber], EXCPT64_ALIGNMENT_CHECK - jz ExtraPushOne - mov qword [ExtraPush], 0 - mov qword [ExceptData], 0 - jmp ExtraPushDone -ExtraPushOne: - mov qword [ExtraPush], 1 - -;; If there's some extra data, save it also, and modify the saved AppRsp to effectively -;; pop this value off the application's stack. - mov rax, [AppRsp] - mov rbx, [rax] - mov qword [ExceptData], rbx - add rax, 8 - mov [AppRsp], rax - -ExtraPushDone: - -;; The "push" above pushed the debug stack rsp. Since what we're actually doing -;; is building the context record on the debug stack, we need to save the pushed -;; debug RSP, and replace it with the application's last stack entry... - mov rax, [rsp + 24] - mov [DebugRsp], rax - mov rax, [AppRsp] - mov rax, QWORD [rax + 24] - ; application stack has ss, rsp, rflags, cs, & rip, so - ; last actual application stack entry is saved at offset - ; 24 bytes from stack top. - mov [rsp + 24], rax - -;; continue building context record -;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero - mov rax, ss - push rax - - ; CS from application is one entry back in application stack - mov rax, [AppRsp] - movzx rax, word [rax + 8] - push rax - - mov rax, ds - push rax - mov rax, es - push rax - mov rax, fs - push rax - mov rax, gs - push rax - -;; UINT64 Rip; - ; Rip from application is on top of application stack - mov rax, [AppRsp] - push qword [rax] - -;; UINT64 Gdtr[2], Idtr[2]; - push 0 - push 0 - sidt [rsp] - push 0 - push 0 - sgdt [rsp] - -;; UINT64 Ldtr, Tr; - xor rax, rax - str ax - push rax - sldt ax - push rax - -;; UINT64 RFlags; -;; Rflags from application is two entries back in application stack - mov rax, [AppRsp] - push qword [rax + 16] - -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; -;; insure FXSAVE/FXRSTOR is enabled in CR4... -;; ... while we're at it, make sure DE is also enabled... - mov rax, cr8 - push rax - mov rax, cr4 - or rax, 0x208 - mov cr4, rax - push rax - mov rax, cr3 - push rax - mov rax, cr2 - push rax - push 0 - mov rax, cr0 - push rax - -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - mov rax, dr7 - push rax -;; clear Dr7 while executing debugger itself - xor rax, rax - mov dr7, rax - - mov rax, dr6 - push rax -;; insure all status bits in dr6 are clear... - xor rax, rax - mov dr6, rax - - mov rax, dr3 - push rax - mov rax, dr2 - push rax - mov rax, dr1 - push rax - mov rax, dr0 - push rax - -;; FX_SAVE_STATE_X64 FxSaveState; - sub rsp, 512 - mov rdi, rsp - ; IMPORTANT!! The debug stack has been carefully constructed to - ; insure that rsp and rdi are 16 byte aligned when we get here. - ; They MUST be. If they are not, a GP fault will occur. - FXSTOR_RDI - -;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear - cld - -;; UINT64 ExceptionData; - mov rax, [ExceptData] - push rax - -; call to C code which will in turn call registered handler -; pass in the vector number - mov rdx, rsp - mov rcx, [ExceptionNumber] - sub rsp, 40 - call ASM_PFX(InterruptDistrubutionHub) - add rsp, 40 - -; restore context... -;; UINT64 ExceptionData; - add rsp, 8 - -;; FX_SAVE_STATE_X64 FxSaveState; - mov rsi, rsp - FXRSTOR_RSI - add rsp, 512 - -;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7; - pop rax - mov dr0, rax - pop rax - mov dr1, rax - pop rax - mov dr2, rax - pop rax - mov dr3, rax -;; skip restore of dr6. We cleared dr6 during the context save. - add rsp, 8 - pop rax - mov dr7, rax - -;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8; - pop rax - mov cr0, rax - add rsp, 8 - pop rax - mov cr2, rax - pop rax - mov cr3, rax - pop rax - mov cr4, rax - pop rax - mov cr8, rax - -;; UINT64 RFlags; - mov rax, [AppRsp] - pop qword [rax + 16] - -;; UINT64 Ldtr, Tr; -;; UINT64 Gdtr[2], Idtr[2]; -;; Best not let anyone mess with these particular registers... - add rsp, 48 - -;; UINT64 Rip; - pop qword [rax] - -;; UINT64 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. -;; - - pop rax - ; mov gs, rax - pop rax - ; mov fs, rax - pop rax - mov es, rax - pop rax - mov ds, rax - mov rax, [AppRsp] - pop qword [rax + 8] - pop rax - mov ss, rax - -;; The next stuff to restore is the general purpose registers that were pushed -;; using the "push" instruction. -;; -;; The value of RSP as stored in the context record is the application RSP -;; including the 5 entries on the application stack caused by the exception -;; itself. It may have been modified by the debug agent, so we need to -;; determine if we need to relocate the application stack. - - mov rbx, [rsp + 24] ; move the potentially modified AppRsp into rbx - mov rax, [AppRsp] - mov rax, QWORD [rax + 24] - cmp rbx, rax - je NoAppStackMove - - mov rax, [AppRsp] - mov rcx, [rax] ; RIP - mov [rbx], rcx - - mov rcx, [rax + 8] ; CS - mov [rbx + 8], rcx - - mov rcx, [rax + 16] ; RFLAGS - mov [rbx + 16], rcx - - mov rcx, [rax + 24] ; RSP - mov [rbx + 24], rcx - - mov rcx, [rax + 32] ; SS - mov [rbx + 32], rcx - - mov rax, rbx ; modify the saved AppRsp to the new AppRsp - mov [AppRsp], rax -NoAppStackMove: - mov rax, [DebugRsp] ; restore the DebugRsp on the debug stack - ; so our "pop" will not cause a stack switch - mov [rsp + 24], rax - - cmp qword [ExceptionNumber], 0x68 - jne NoChain - -Chain: - -;; Restore rflags so when we chain, the flags will be exactly as if we were never here. -;; We gin up the stack to do an iretq so we can get ALL the flags. - mov rax, [AppRsp] - mov rbx, [rax + 40] - push rbx - mov rax, ss - push rax - mov rax, rsp - add rax, 16 - push rax - mov rax, [AppRsp] - mov rbx, [rax + 16] - and rbx, ~ 0x300 ; special handling for IF and TF - push rbx - mov rax, cs - push rax - mov rax, PhonyIretq - push rax - iretq -PhonyIretq: - -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - pop rdi - pop rsi - pop rbp - pop rsp - pop rbx - pop rdx - pop rcx - pop rax - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 - -;; Switch back to application stack - mov rsp, [AppRsp] - -;; Jump to original handler - jmp [ASM_PFX(OrigVector)] - -NoChain: -;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax; -;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15; - pop rdi - pop rsi - pop rbp - pop rsp - pop rbx - pop rdx - pop rcx - pop rax - pop r8 - pop r9 - pop r10 - pop r11 - pop r12 - pop r13 - pop r14 - pop r15 - -;; Switch back to application stack - mov rsp, [AppRsp] - -;; We're outa here... - iretq - diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h deleted file mode 100644 index 044e5d9d07..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h +++ /dev/null @@ -1,22 +0,0 @@ -/** @file - X64 specific debug support macros. - -Copyright (c) 2006 - 2008, 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. - -**/ - -#ifndef _PLDEBUG_SUPPORT_H_ -#define _PLDEBUG_SUPPORT_H_ - -#include "Ia32/DebugSupport.h" - -#define EFI_ISA IsaX64 - -#endif diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c deleted file mode 100644 index fa8869d287..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c +++ /dev/null @@ -1,146 +0,0 @@ -/** @file - X64 specific functions to support Debug Support protocol. - -Copyright (c) 2008 - 2010, 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. - -**/ - -#include "PlDebugSupport.h" - -IA32_IDT_GATE_DESCRIPTOR NullDesc = {{0,0}}; - -/** - Get Interrupt Handle from IDT Gate Descriptor. - - @param IdtGateDecriptor IDT Gate Descriptor. - - @return Interrupt Handle stored in IDT Gate Descriptor. - -**/ -UINTN -GetInterruptHandleFromIdt ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor - ) -{ - UINTN InterruptHandle; - - // - // InterruptHandle 0-15 : OffsetLow - // InterruptHandle 16-31 : OffsetHigh - // InterruptHandle 32-63 : OffsetUpper - // - InterruptHandle = ((UINTN) IdtGateDecriptor->Bits.OffsetLow) | - (((UINTN) IdtGateDecriptor->Bits.OffsetHigh) << 16) | - (((UINTN) IdtGateDecriptor->Bits.OffsetUpper) << 32) ; - - return InterruptHandle; -} - -/** - Allocate pool for a new IDT entry stub. - - Copy the generic stub into the new buffer and fixup the vector number - and jump target address. - - @param ExceptionType This is the exception type that the new stub will be created - for. - @param Stub On successful exit, *Stub contains the newly allocated entry stub. - -**/ -VOID -CreateEntryStub ( - IN EFI_EXCEPTION_TYPE ExceptionType, - OUT VOID **Stub - ) -{ - UINT8 *StubCopy; - - StubCopy = *Stub; - - // - // Fixup the stub code for this vector - // - - // The stub code looks like this: - // - // 00000000 6A 00 push 0 ; push vector number - will be modified before installed - // 00000002 E9 db 0e9h ; jump rel32 - // 00000003 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry - // - - // - // poke in the exception type so the second push pushes the exception type - // - StubCopy[0x1] = (UINT8) ExceptionType; - - // - // fixup the jump target to point to the common entry - // - *(UINT32 *) &StubCopy[0x3] = (UINT32)((UINTN) CommonIdtEntry - (UINTN) &StubCopy[StubSize]); - - return; -} - -/** - This is the main worker function that manages the state of the interrupt - handlers. It both installs and uninstalls interrupt handlers based on the - value of NewCallback. If NewCallback is NULL, then uninstall is indicated. - If NewCallback is non-NULL, then install is indicated. - - @param NewCallback If non-NULL, NewCallback specifies the new handler to register. - If NULL, specifies that the previously registered handler should - be uninstalled. - @param ExceptionType Indicates which entry to manage. - - @retval EFI_SUCCESS Process is ok. - @retval EFI_INVALID_PARAMETER Requested uninstalling a handler from a vector that has - no handler registered for it - @retval EFI_ALREADY_STARTED Requested install to a vector that already has a handler registered. - @retval others Possible return values are passed through from UnHookEntry and HookEntry. - -**/ -EFI_STATUS -ManageIdtEntryTable ( - CALLBACK_FUNC NewCallback, - EFI_EXCEPTION_TYPE ExceptionType - ) -{ - EFI_STATUS Status; - - Status = EFI_SUCCESS; - - if (CompareMem (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc, sizeof (IA32_IDT_GATE_DESCRIPTOR)) != 0) { - // - // we've already installed to this vector - // - if (NewCallback != NULL) { - // - // if the input handler is non-null, error - // - Status = EFI_ALREADY_STARTED; - } else { - UnhookEntry (ExceptionType); - } - } else { - // - // no user handler installed on this vector - // - if (NewCallback == NULL) { - // - // if the input handler is null, error - // - Status = EFI_INVALID_PARAMETER; - } else { - HookEntry (ExceptionType, NewCallback); - } - } - - return Status; -} -- cgit v1.2.3