From: vanjeff Date: Thu, 11 Dec 2008 05:28:12 +0000 (+0000) Subject: 1. Merger generic functions into one file. X-Git-Tag: edk2-stable201903~19260 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=6e8a984eca4c9763038e887b8d813b2110bbaed6 1. Merger generic functions into one file. 2. Use the basic definitions in BaseLib.h, instead of local definitions git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6986 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf index c36ee518b0..d303847c75 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf +++ b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf @@ -32,14 +32,18 @@ DebugSupport.c [Sources.Ia32] + Ia32/DebugSupport.h Ia32/PlDebugSupport.c Ia32/PlDebugSupport.h + Ia32/PlDebugSupportIa32.c Ia32/AsmFuncs.S Ia32/AsmFuncs.asm [Sources.X64] - X64/PlDebugSupport.c + Ia32/DebugSupport.h + Ia32/PlDebugSupport.c X64/PlDebugSupport.h + X64/PlDebugSupportX64.c X64/AsmFuncs.S X64/AsmFuncs.asm diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm index 315120ef94..cc776c867e 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm @@ -132,21 +132,6 @@ FxStorSupport PROC C PUBLIC FxStorSupport ENDP -;------------------------------------------------------------------------------ -; DESCRIPTOR * -; GetIdtr ( -; void -; ) -; -; Abstract: Returns physical address of IDTR -; -GetIdtr PROC C PUBLIC - LOCAL IdtrBuf:FWORD - - sidt IdtrBuf - mov eax, DWORD PTR IdtrBuf + 2 - ret -GetIdtr ENDP ;------------------------------------------------------------------------------ diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h new file mode 100644 index 0000000000..72765507d5 --- /dev/null +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h @@ -0,0 +1,308 @@ +/** @file + Generic debug support macros, typedefs and prototypes for IA32/x64. + +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 _DEBUG_SUPPORT_H_ +#define _DEBUG_SUPPORT_H_ + + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define NUM_IDT_ENTRIES 0x78 +#define SYSTEM_TIMER_VECTOR 0x68 +#define VECTOR_ENTRY_PAGES 1 + +#define FF_FXSR (1 << 24) + +typedef +VOID +(*DEBUG_PROC) ( + VOID + ); + +typedef struct { + IA32_IDT_GATE_DESCRIPTOR OrigDesc; + DEBUG_PROC OrigVector; + IA32_IDT_GATE_DESCRIPTOR NewDesc; + DEBUG_PROC StubEntry; + VOID (*RegisteredCallback) (); +} IDT_ENTRY; + +extern EFI_SYSTEM_CONTEXT SystemContext; +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) + ); + +/** + Programs interrupt flag to the requested state and returns previous + state. + + @param NewState New interrupt status. + + @retval TRUE Old interrupt status is TRUE. + @retval FALSE Old interrupt status is FALSE + +**/ +BOOLEAN +WriteInterruptFlag ( + BOOLEAN NewState + ); + +/** + Initializes driver's handler registration databas. + + 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 + ); + +/** + This is a DebugSupport protocol member function, hard + coded to support only 1 processor for now. + + @param This The DebugSupport instance + @param MaxProcessorIndex The maximuim supported processor index + + @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0. + +**/ +EFI_STATUS +EFIAPI +GetMaximumProcessorIndex ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + OUT UINTN *MaxProcessorIndex + ); + +/** + DebugSupport protocol member function. + + @param This The DebugSupport instance + @param ProcessorIndex Which processor the callback applies to. + @param PeriodicCallback Callback function + + @retval EFI_SUCCESS Indicates the callback was registered. + @retval others Callback was not registered. + +**/ +EFI_STATUS +EFIAPI +RegisterPeriodicCallback ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_PERIODIC_CALLBACK PeriodicCallback + ); + +/** + DebugSupport protocol member function. + + This code executes in boot services context. + + @param This The DebugSupport instance + @param ProcessorIndex Which processor the callback applies to. + @param NewCallback Callback function + @param ExceptionType Which exception to hook + + @retval EFI_SUCCESS Indicates the callback was registered. + @retval others Callback was not registered. + +**/ +EFI_STATUS +EFIAPI +RegisterExceptionCallback ( + IN EFI_DEBUG_SUPPORT_PROTOCOL *This, + IN UINTN ProcessorIndex, + IN EFI_EXCEPTION_CALLBACK NewCallback, + IN EFI_EXCEPTION_TYPE ExceptionType + ); + +/** + DebugSupport protocol member function. Calls assembly routine to flush cache. + + @param This The DebugSupport instance + @param ProcessorIndex Which processor the callback applies to. + @param Start Physical base of the memory range to be invalidated + @param Length mininum number of bytes in 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. + + @retval EFI_SUCCESS Always. + +**/ +EFI_STATUS +CreateEntryStub ( + IN EFI_EXCEPTION_TYPE ExceptionType, + OUT VOID **Stub + ); + +/** + Get Procedure Entry Point from IDT Gate Descriptor. + + @param IdtGateDecriptor IDT Gate Descriptor. + + @return Procedure Entry Point located in IDT Gate Descriptor. + +**/ +UINTN GetProcedureEntryPoint ( + 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 ( + VOID (*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. + + @retval EFI_SUCCESS Always. + +**/ +EFI_STATUS +HookEntry ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN VOID (*NewCallback) () + ); + +/** + Undoes HookEntry. This code executes in boot services context. + + @param ExceptionType Specifies which entry to unhook + + @retval EFI_SUCCESS Always. + +**/ +EFI_STATUS +UnhookEntry ( + IN EFI_EXCEPTION_TYPE ExceptionType + ); + +#endif diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c index c650e6391f..932e923eaa 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c @@ -15,63 +15,56 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // // private header files // -#include "PlDebugSupport.h" +#include "DebugSupport.h" // // This the global main table to keep track of the interrupts // IDT_ENTRY *IdtEntryTable = NULL; -DESCRIPTOR NullDesc = 0; +IA32_IDT_GATE_DESCRIPTOR NullDesc = {0}; /** - Allocate pool for a new IDT entry stub. + Read IDT Gate Descriptor from IDT Table. - 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. - - @retval EFI_SUCCESS Always. + @param Vector Specifies vector number. + @param IdtGateDecriptor Pointer to IDT Gate Descriptor read from IDT Table. **/ -EFI_STATUS -CreateEntryStub ( - IN EFI_EXCEPTION_TYPE ExceptionType, - OUT VOID **Stub +VOID ReadIdtGateDecriptor ( + IN EFI_EXCEPTION_TYPE Vector, + OUT IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor ) { - UINT8 *StubCopy; + IA32_DESCRIPTOR IdtrValue; + IA32_IDT_GATE_DESCRIPTOR *IdtTable; - StubCopy = *Stub; + AsmReadIdtr (&IdtrValue); + IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtrValue.Base; - // - // Fixup the stub code for this vector - // + CopyMem ((VOID *) IdtGateDecriptor, (VOID *) &(IdtTable)[Vector], sizeof (IA32_IDT_GATE_DESCRIPTOR)); +} +/** + Write IDT Gate Descriptor into IDT Table. - // 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 - // + @param Vector Specifies vector number. + @param IdtGateDecriptor Pointer to IDT Gate Descriptor written into IDT Table. - // - // poke in the exception type so the second push pushes the exception type - // - StubCopy[0x0c] = (UINT8) ExceptionType; +**/ +VOID WriteIdtGateDecriptor ( + EFI_EXCEPTION_TYPE Vector, + IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor + ) +{ + IA32_DESCRIPTOR IdtrValue; + IA32_IDT_GATE_DESCRIPTOR *IdtTable; - // - // fixup the jump target to point to the common entry - // - *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize]; + AsmReadIdtr (&IdtrValue); + IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtrValue.Base; - return EFI_SUCCESS; + CopyMem ((VOID *) &(IdtTable)[Vector], (VOID *) IdtGateDecriptor, 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 @@ -98,14 +91,13 @@ HookEntry ( Status = CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry); if (Status == EFI_SUCCESS) { OldIntFlagState = WriteInterruptFlag (0); - READ_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); + ReadIdtGateDecriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); - ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[0] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[0]; - ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[1] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[3]; + IdtEntryTable[ExceptionType].OrigVector = (DEBUG_PROC) GetProcedureEntryPoint (&(IdtEntryTable[ExceptionType].OrigDesc)); Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry); IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback; - WRITE_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc)); + WriteIdtGateDecriptor (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc)); WriteInterruptFlag (OldIntFlagState); } @@ -128,71 +120,12 @@ UnhookEntry ( BOOLEAN OldIntFlagState; OldIntFlagState = WriteInterruptFlag (0); - WRITE_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); + WriteIdtGateDecriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); WriteInterruptFlag (OldIntFlagState); return EFI_SUCCESS; } -/** - 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 ( - VOID (*NewCallback)(), - EFI_EXCEPTION_TYPE ExceptionType - ) -{ - EFI_STATUS Status; - - Status = EFI_SUCCESS; - - if (!FeaturePcdGet (PcdNtEmulatorEnable)) { - if (COMPARE_DESCRIPTOR (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc)) { - // - // we've already installed to this vector - // - if (NewCallback != NULL) { - // - // if the input handler is non-null, error - // - Status = EFI_ALREADY_STARTED; - } else { - Status = 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 { - Status = HookEntry (ExceptionType, NewCallback); - } - } - } - - return Status; -} - /** This is a DebugSupport protocol member function, hard coded to support only 1 processor for now. diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h index 1566f3e8b7..525ae8b3d7 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h @@ -15,221 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef _PLDEBUG_SUPPORT_H_ #define _PLDEBUG_SUPPORT_H_ +#include "Ia32/DebugSupport.h" -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define NUM_IDT_ENTRIES 0x78 -#define SYSTEM_TIMER_VECTOR 0x68 -#define VECTOR_ENTRY_PAGES 1 -#define COPY_DESCRIPTOR(Dest, Src) CopyMem ((Dest), (Src), sizeof (DESCRIPTOR)) -#define READ_IDT(Vector, Dest) COPY_DESCRIPTOR ((Dest), &((GetIdtr ())[(Vector)])) -#define WRITE_IDT(Vector, Src) COPY_DESCRIPTOR (&((GetIdtr ())[(Vector)]), (Src)) -#define COMPARE_DESCRIPTOR(Desc1, Desc2) CompareMem ((Desc1), (Desc2), sizeof (DESCRIPTOR)) #define EFI_ISA IsaIa32 -#define FF_FXSR (1 << 24) - -typedef UINT64 DESCRIPTOR; - -typedef -VOID -(*DEBUG_PROC) ( - VOID - ); - -typedef struct { - DESCRIPTOR OrigDesc; - DEBUG_PROC OrigVector; - DESCRIPTOR NewDesc; - DEBUG_PROC StubEntry; - VOID (*RegisteredCallback) (); -} IDT_ENTRY; - -extern EFI_SYSTEM_CONTEXT SystemContext; -extern UINT8 InterruptEntryStub[]; -extern UINT32 StubSize; -extern VOID (*OrigVector) (VOID); - -/** - 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 - ); - -/** - Return the physical address of IDTR. - - @return The physical address of IDTR. - -**/ -DESCRIPTOR * -GetIdtr ( - VOID - ); - -/** - Encodes an IDT descriptor with the given physical address. - - @param DestDesc The IDT descriptor address. - @param Vecotr The interrupt vector entry. - -**/ -VOID -Vect2Desc ( - DESCRIPTOR * DestDesc, - VOID (*Vector) (VOID) - ); - -/** - Programs interrupt flag to the requested state and returns previous - state. - - @param NewState New interrupt status. - - @retval TRUE Old interrupt status is TRUE. - @retval FALSE Old interrupt status is FALSE - -**/ -BOOLEAN -WriteInterruptFlag ( - BOOLEAN NewState - ); - -/** - Initializes driver's handler registration databas. - - 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 - ); - -/** - This is a DebugSupport protocol member function, hard - coded to support only 1 processor for now. - - @param This The DebugSupport instance - @param MaxProcessorIndex The maximuim supported processor index - - @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0. - -**/ -EFI_STATUS -EFIAPI -GetMaximumProcessorIndex ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - OUT UINTN *MaxProcessorIndex - ); - -/** - DebugSupport protocol member function. - - @param This The DebugSupport instance - @param ProcessorIndex Which processor the callback applies to. - @param PeriodicCallback Callback function - - @retval EFI_SUCCESS Indicates the callback was registered. - @retval others Callback was not registered. - -**/ -EFI_STATUS -EFIAPI -RegisterPeriodicCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_PERIODIC_CALLBACK PeriodicCallback - ); - -/** - DebugSupport protocol member function. - - This code executes in boot services context. - - @param This The DebugSupport instance - @param ProcessorIndex Which processor the callback applies to. - @param NewCallback Callback function - @param ExceptionType Which exception to hook - - @retval EFI_SUCCESS Indicates the callback was registered. - @retval others Callback was not registered. - -**/ -EFI_STATUS -EFIAPI -RegisterExceptionCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_EXCEPTION_CALLBACK NewCallback, - IN EFI_EXCEPTION_TYPE ExceptionType - ); - -/** - DebugSupport protocol member function. Calls assembly routine to flush cache. - - @param This The DebugSupport instance - @param ProcessorIndex Which processor the callback applies to. - @param Start Physical base of the memory range to be invalidated - @param Length mininum number of bytes in 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 - ); #endif diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c new file mode 100644 index 0000000000..47e4e0e350 --- /dev/null +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c @@ -0,0 +1,143 @@ +/** @file + IA32 specific debug support functions + +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 "DebugSupport.h" + +/** + Get Procedure Entry Point from IDT Gate Descriptor. + + @param IdtGateDecriptor IDT Gate Descriptor. + + @return Procedure Entry Point located in IDT Gate Descriptor. + +**/ +UINTN GetProcedureEntryPoint ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor + ) +{ + UINTN ProcedureEntryPoint; + + ((UINT16 *) &ProcedureEntryPoint)[0] = (UINT16) IdtGateDecriptor->Bits.OffsetLow; + ((UINT16 *) &ProcedureEntryPoint)[1] = (UINT16) IdtGateDecriptor->Bits.OffsetHigh; + + return ProcedureEntryPoint; +} + +/** + 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. + + @retval EFI_SUCCESS Always. + +**/ +EFI_STATUS +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 EFI_SUCCESS; +} + +/** + 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 ( + VOID (*NewCallback)(), + EFI_EXCEPTION_TYPE ExceptionType + ) +{ + EFI_STATUS Status; + + Status = EFI_SUCCESS; + + if (!FeaturePcdGet (PcdNtEmulatorEnable)) { + 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 { + Status = 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 { + Status = HookEntry (ExceptionType, NewCallback); + } + } + } + + return Status; +} diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h index cd5bb8e038..f8f5532de7 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h @@ -26,8 +26,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include -#include -#include #define DISABLE_INTERRUPTS 0UL diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm index 5cc3e52bfe..f486bd32b5 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm +++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm @@ -108,19 +108,6 @@ text SEGMENT externdef InterruptDistrubutionHub:near -;------------------------------------------------------------------------------ -; VOID -; EfiWbinvd ( -; VOID -; ) -; -; Abstract: Writeback and invalidate cache -; -EfiWbinvd PROC PUBLIC - wbinvd - ret -EfiWbinvd ENDP - ;------------------------------------------------------------------------------ ; BOOLEAN ; FxStorSupport ( @@ -145,25 +132,6 @@ FxStorSupport PROC PUBLIC FxStorSupport ENDP -;------------------------------------------------------------------------------ -; DESCRIPTOR * -; GetIdtr ( -; void -; ) -; -; Abstract: Returns physical address of IDTR -; -GetIdtr PROC PUBLIC - push rbp - mov rbp, rsp - - sidt QWORD PTR [rbp - 0ah] - mov rax, QWORD PTR [rbp - 8h] - - mov rsp, rbp - pop rbp - ret -GetIdtr ENDP ;------------------------------------------------------------------------------ @@ -196,7 +164,7 @@ WriteInterruptFlag ENDP ;------------------------------------------------------------------------------ ; void ; Vect2Desc ( -; DESCRIPTOR * DestDesc, // rcx +; IA32_IDT_GATE_DESCRIPTOR * DestDesc, // rcx ; void (*Vector) (void) // rdx ; ) ; diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.c deleted file mode 100644 index 24e5acc74a..0000000000 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.c +++ /dev/null @@ -1,385 +0,0 @@ -/** @file - X64 specific debug support functions - -Copyright (c) 2006 - 2007, 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. - -**/ - -// -// private header files -// -#include "PlDebugSupport.h" - -// -// This the global main table to keep track of the interrupts -// -IDT_ENTRY *IdtEntryTable = NULL; -DESCRIPTOR NullDesc = {0, 0}; - -/** - 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. - - @retval EFI_SUCCESS Always. - -**/ -EFI_STATUS -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 EFI_SUCCESS; -} - -/** - 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. - - @retval EFI_SUCCESS Always. - -**/ -EFI_STATUS -HookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN VOID (*NewCallback) () - ) -{ - BOOLEAN OldIntFlagState; - EFI_STATUS Status; - - Status = CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry); - if (Status == EFI_SUCCESS) { - OldIntFlagState = WriteInterruptFlag (0); - READ_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); - - ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[0] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc.Low)[0]; - ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[1] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc.Low)[3]; - ((UINT32 *) &IdtEntryTable[ExceptionType].OrigVector)[1] = ((UINT32 *) &IdtEntryTable[ExceptionType].OrigDesc.High)[0]; - - Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry); - IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback; - WRITE_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc)); - WriteInterruptFlag (OldIntFlagState); - } - - return Status; -} - -/** - Undoes HookEntry. This code executes in boot services context. - - @param ExceptionType Specifies which entry to unhook - - @retval EFI_SUCCESS Always. - -**/ -EFI_STATUS -UnhookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType - ) -{ - BOOLEAN OldIntFlagState; - - OldIntFlagState = WriteInterruptFlag (0); - WRITE_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); - WriteInterruptFlag (OldIntFlagState); - - return EFI_SUCCESS; -} - -/** - 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 ( - VOID (*NewCallback)(), - EFI_EXCEPTION_TYPE ExceptionType - ) -{ - EFI_STATUS Status; - - Status = EFI_SUCCESS; - - if (COMPARE_DESCRIPTOR (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc)) { - // - // we've already installed to this vector - // - if (NewCallback != NULL) { - // - // if the input handler is non-null, error - // - Status = EFI_ALREADY_STARTED; - } else { - Status = 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 { - Status = HookEntry (ExceptionType, NewCallback); - } - } - - return Status; -} - -/** - This is a DebugSupport protocol member function, hard - coded to support only 1 processor for now. - - @param This The DebugSupport instance - @param MaxProcessorIndex The maximuim supported processor index - - @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); -} - -/** - DebugSupport protocol member function. - - @param This The DebugSupport instance - @param ProcessorIndex Which processor the callback applies to. - @param PeriodicCallback Callback function - - @retval EFI_SUCCESS Indicates the callback was registered. - @retval others Callback was not registered. - -**/ -EFI_STATUS -EFIAPI -RegisterPeriodicCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_PERIODIC_CALLBACK PeriodicCallback - ) -{ - return ManageIdtEntryTable (PeriodicCallback, SYSTEM_TIMER_VECTOR); -} - -/** - DebugSupport protocol member function. - - This code executes in boot services context. - - @param This The DebugSupport instance - @param ProcessorIndex Which processor the callback applies to. - @param NewCallback Callback function - @param ExceptionType Which exception to hook - - @retval EFI_SUCCESS Indicates the callback was registered. - @retval others Callback was not registered. - -**/ -EFI_STATUS -EFIAPI -RegisterExceptionCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_EXCEPTION_CALLBACK NewCallback, - IN EFI_EXCEPTION_TYPE ExceptionType - ) -{ - return ManageIdtEntryTable (NewCallback, ExceptionType); -} - -/** - DebugSupport protocol member function. Calls assembly routine to flush cache. - - @param This The DebugSupport instance - @param ProcessorIndex Which processor the callback applies to. - @param Start Physical base of the memory range to be invalidated - @param Length mininum number of bytes in 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; -} - -/** - Initializes driver's handler registration databas. - - This code executes in boot services context - Must be public because it's referenced from DebugSupport.c - - @retval EFI_UNSUPPORTED If x64 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 - ) -{ - EFI_EXCEPTION_TYPE ExceptionType; - - 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; - } - - 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; -} - -/** - 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 - ) -{ - EFI_EXCEPTION_TYPE ExceptionType; - - for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) { - ManageIdtEntryTable (NULL, ExceptionType); - } - - FreePool (IdtEntryTable); - return EFI_SUCCESS; -} - -/** - Common piece of code that invokes the registered handlers. - - This code executes in exception context so no efi calls are allowed. - - @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); - } - } -} diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h index eb04f1a88c..3a9b9030c2 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h +++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h @@ -1,5 +1,5 @@ /** @file - X64 specific debug support macros, typedefs and prototypes. + X64 specific debug support macros. Copyright (c) 2006 - 2008, Intel Corporation All rights reserved. This program and the accompanying materials @@ -15,224 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef _PLDEBUG_SUPPORT_H_ #define _PLDEBUG_SUPPORT_H_ +#include "Ia32/DebugSupport.h" -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#define NUM_IDT_ENTRIES 0x78 -#define SYSTEM_TIMER_VECTOR 0x68 -#define VECTOR_ENTRY_PAGES 1 -#define COPY_DESCRIPTOR(Dest, Src) CopyMem ((Dest), (Src), sizeof (DESCRIPTOR)) -#define READ_IDT(Vector, Dest) COPY_DESCRIPTOR ((Dest), &((GetIdtr ())[(Vector)])) -#define WRITE_IDT(Vector, Src) COPY_DESCRIPTOR (&((GetIdtr ())[(Vector)]), (Src)) -#define COMPARE_DESCRIPTOR(Desc1, Desc2) CompareMem ((Desc1), (Desc2), sizeof (DESCRIPTOR)) #define EFI_ISA IsaX64 -#define FF_FXSR (1 << 24) - -typedef struct { - UINT64 Low; - UINT64 High; -} DESCRIPTOR; - -typedef -VOID -(*DEBUG_PROC) ( - VOID - ); - -typedef struct { - DESCRIPTOR OrigDesc; - DEBUG_PROC OrigVector; - DESCRIPTOR NewDesc; - DEBUG_PROC StubEntry; - VOID (*RegisteredCallback) (); -} IDT_ENTRY; - -extern EFI_SYSTEM_CONTEXT SystemContext; -extern UINT8 InterruptEntryStub[]; -extern UINT32 StubSize; -extern VOID (*OrigVector) (VOID); - -/** - 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 - ); - -/** - Return the physical address of IDTR. - - @return The physical address of IDTR. - -**/ -DESCRIPTOR * -GetIdtr ( - VOID - ); - -/** - Encodes an IDT descriptor with the given physical address. - - @param DestDesc The IDT descriptor address. - @param Vecotr The interrupt vector entry. - -**/ -VOID -Vect2Desc ( - DESCRIPTOR * DestDesc, - VOID (*Vector) (VOID) - ); - -/** - Programs interrupt flag to the requested state and returns previous - state. - - @param NewState New interrupt status. - - @retval TRUE Old interrupt status is TRUE. - @retval FALSE Old interrupt status is FALSE - -**/ -BOOLEAN -WriteInterruptFlag ( - BOOLEAN NewState - ); - -/** - Initializes driver's handler registration databas. - - This code executes in boot services context - Must be public because it's referenced from DebugSupport.c - - @retval EFI_UNSUPPORTED If x64 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 - ); - -/** - This is a DebugSupport protocol member function, hard - coded to support only 1 processor for now. - - @param This The DebugSupport instance - @param MaxProcessorIndex The maximuim supported processor index - - @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0. - -**/ -EFI_STATUS -EFIAPI -GetMaximumProcessorIndex ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - OUT UINTN *MaxProcessorIndex - ); - -/** - DebugSupport protocol member function. - - @param This The DebugSupport instance - @param ProcessorIndex Which processor the callback applies to. - @param PeriodicCallback Callback function - - @retval EFI_SUCCESS Indicates the callback was registered. - @retval others Callback was not registered. - -**/ -EFI_STATUS -EFIAPI -RegisterPeriodicCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_PERIODIC_CALLBACK PeriodicCallback - ); - -/** - DebugSupport protocol member function. - - This code executes in boot services context. - - @param This The DebugSupport instance - @param ProcessorIndex Which processor the callback applies to. - @param NewCallback Callback function - @param ExceptionType Which exception to hook - - @retval EFI_SUCCESS Indicates the callback was registered. - @retval others Callback was not registered. - -**/ -EFI_STATUS -EFIAPI -RegisterExceptionCallback ( - IN EFI_DEBUG_SUPPORT_PROTOCOL *This, - IN UINTN ProcessorIndex, - IN EFI_EXCEPTION_CALLBACK NewCallback, - IN EFI_EXCEPTION_TYPE ExceptionType - ); - -/** - DebugSupport protocol member function. Calls assembly routine to flush cache. - - @param This The DebugSupport instance - @param ProcessorIndex Which processor the callback applies to. - @param Start Physical base of the memory range to be invalidated - @param Length mininum number of bytes in 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 - ); #endif diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c new file mode 100644 index 0000000000..943d2c6911 --- /dev/null +++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c @@ -0,0 +1,143 @@ +/** @file + X64 specific debug support functions + +Copyright (c) 2006 - 2007, 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. + +**/ + +// +// private header files +// +#include "DebugSupport.h" + +/** + Get Procedure Entry Point from IDT Gate Descriptor. + + @param IdtGateDecriptor IDT Gate Descriptor. + + @return Procedure Entry Point located in IDT Gate Descriptor. + +**/ +UINTN GetProcedureEntryPoint ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor + ) +{ + UINTN ProcedureEntryPoint; + + ((UINT16 *) &ProcedureEntryPoint)[0] = (UINT16) IdtGateDecriptor->Bits.OffsetLow; + ((UINT16 *) &ProcedureEntryPoint)[1] = (UINT16) IdtGateDecriptor->Bits.OffsetHigh; + ((UINT32 *) &ProcedureEntryPoint)[1] = (UINT32) IdtGateDecriptor->Bits.OffsetUpper; + + return ProcedureEntryPoint; +} + +/** + 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. + + @retval EFI_SUCCESS Always. + +**/ +EFI_STATUS +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 EFI_SUCCESS; +} + +/** + 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 ( + VOID (*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 { + Status = 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 { + Status = HookEntry (ExceptionType, NewCallback); + } + } + + return Status; +}