From c84507ab5229c462806187b090ba6249540c9070 Mon Sep 17 00:00:00 2001 From: vanjeff Date: Thu, 11 Dec 2008 08:38:20 +0000 Subject: [PATCH] code scrub for DebugSpport Module. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6997 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/DebugSupportDxe/DebugSupport.c | 29 +- .../DebugSupportDxe/DebugSupportDxe.inf | 2 +- .../Universal/DebugSupportDxe/Ia32/AsmFuncs.S | 27 -- .../DebugSupportDxe/Ia32/AsmFuncs.asm | 28 -- .../DebugSupportDxe/Ia32/DebugSupport.h | 128 ++++---- .../DebugSupportDxe/Ia32/PlDebugSupport.c | 291 ++++++++++-------- .../DebugSupportDxe/Ia32/PlDebugSupportIa32.c | 34 +- .../DebugSupportDxe/Ipf/PlDebugSupport.c | 87 ------ .../DebugSupportDxe/Ipf/PlDebugSupport.h | 91 +++++- .../Universal/DebugSupportDxe/X64/AsmFuncs.S | 8 - .../DebugSupportDxe/X64/AsmFuncs.asm | 30 -- .../DebugSupportDxe/X64/PlDebugSupportX64.c | 30 +- 12 files changed, 349 insertions(+), 436 deletions(-) diff --git a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupport.c index ed4d86038a..4ef12cac19 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupport.c +++ b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupport.c @@ -12,15 +12,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ -// -// private header files -// #include "PlDebugSupport.h" -// -// This is a global that is the actual interface -// -EFI_DEBUG_SUPPORT_PROTOCOL gDebugSupportProtocolInterface = { +EFI_DEBUG_SUPPORT_PROTOCOL mDebugSupportProtocolInterface = { EFI_ISA, GetMaximumProcessorIndex, RegisterPeriodicCallback, @@ -30,16 +24,16 @@ EFI_DEBUG_SUPPORT_PROTOCOL gDebugSupportProtocolInterface = { /** - Debug Port Driver entry point. + Debug Support Driver entry point. - Checks to see there's not already a DebugSupport protocol installed for - the selected processor before installing protocol. + 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 DebugSupport protocol is installed already. + @retval EFI_ALREADY_STARTED DebugS upport protocol is installed already. @retval other Some error occurs when executing this entry point. **/ @@ -56,8 +50,6 @@ InitializeDebugSupportDriver ( UINTN NumHandles; EFI_DEBUG_SUPPORT_PROTOCOL *DebugSupportProtocolPtr; - // - // Install Protocol Interface... // // First check to see that the debug support protocol for this processor // type is not already installed @@ -81,7 +73,10 @@ InitializeDebugSupportDriver ( NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); - if (Status == EFI_SUCCESS && DebugSupportProtocolPtr->Isa == EFI_ISA) { + 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; @@ -109,7 +104,7 @@ InitializeDebugSupportDriver ( LoadedImageProtocolPtr->Unload = PlUnloadDebugSupportDriver; // - // Call hook for platform specific initialization + // Call hook for processor specific initialization // Status = PlInitializeDebugSupportDriver (); ASSERT (!EFI_ERROR (Status)); @@ -118,14 +113,14 @@ InitializeDebugSupportDriver ( } // - // Install DebugSupport protocol to new handle + // Install Debug Support protocol to new handle // Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gEfiDebugSupportProtocolGuid, EFI_NATIVE_INTERFACE, - &gDebugSupportProtocolInterface + &mDebugSupportProtocolInterface ); ASSERT (!EFI_ERROR (Status)); if (Status != EFI_SUCCESS) { diff --git a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf index d303847c75..41ed14d453 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf +++ b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf @@ -77,7 +77,7 @@ [Protocols] gEfiLoadedImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED - gEfiDebugSupportProtocolGuid # PROTOCOL SOMETIMES_PRODUCED + gEfiDebugSupportProtocolGuid # PROTOCOL ALWAYS_PRODUCED [FeaturePcd.IA32] diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.S b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.S index 965828cf56..b6f326d805 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.S +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.S @@ -37,33 +37,6 @@ ASM_PFX(FxStorSupport): pop %ebx ret -.globl ASM_PFX(GetIdtr) -ASM_PFX(GetIdtr): - push %ebp - mov %esp,%ebp - add $0xfffffff8,%esp - sidtl 0xfffffffa(%ebp) - mov 0xfffffffc(%ebp),%eax - leave - ret - -.globl ASM_PFX(WriteInterruptFlag) -ASM_PFX(WriteInterruptFlag): - push %ebp - mov %esp,%ebp - pushf - pop %eax - and $0x200,%eax - shr $0x9,%eax - mov 0x8(%ebp),%ecx - or %cl,%cl - jne ASM_PFX(WriteInterruptFlag+0x17) - cli - jmp ASM_PFX(WriteInterruptFlag+0x18) - sti - leave - ret - .globl ASM_PFX(Vect2Desc) ASM_PFX(Vect2Desc): push %ebp diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm index cc776c867e..3cf75025ad 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm @@ -133,34 +133,6 @@ FxStorSupport ENDP - -;------------------------------------------------------------------------------ -; BOOLEAN -; WriteInterruptFlag ( -; BOOLEAN NewState -; ) -; -; Abstract: Programs interrupt flag to the requested state and returns previous -; state. -; -WriteInterruptFlag PROC C PUBLIC State:DWORD - - pushfd - pop eax - and eax, 200h - shr eax, 9 - mov ecx, State - .IF cl == 0 - cli - .ELSE - sti - .ENDIF - ret - -WriteInterruptFlag ENDP - - - ;------------------------------------------------------------------------------ ; void ; Vect2Desc ( diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h index 72765507d5..d1a126c1c2 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h @@ -15,7 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef _DEBUG_SUPPORT_H_ #define _DEBUG_SUPPORT_H_ - #include #include @@ -31,9 +30,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define NUM_IDT_ENTRIES 0x78 #define SYSTEM_TIMER_VECTOR 0x68 -#define VECTOR_ENTRY_PAGES 1 - -#define FF_FXSR (1 << 24) typedef VOID @@ -49,11 +45,10 @@ typedef struct { VOID (*RegisteredCallback) (); } IDT_ENTRY; -extern EFI_SYSTEM_CONTEXT SystemContext; -extern UINT8 InterruptEntryStub[]; -extern UINT32 StubSize; -extern VOID (*OrigVector) (VOID); -extern IDT_ENTRY *IdtEntryTable; +extern UINT8 InterruptEntryStub[]; +extern UINT32 StubSize; +extern VOID (*OrigVector) (VOID); +extern IDT_ENTRY *IdtEntryTable; extern IA32_IDT_GATE_DESCRIPTOR NullDesc; /** @@ -90,21 +85,6 @@ Vect2Desc ( 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. @@ -139,13 +119,16 @@ PlUnloadDebugSupportDriver ( ); /** - 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 + 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. - @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0. + @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 @@ -156,15 +139,18 @@ GetMaximumProcessorIndex ( ); /** - 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. - + 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 @@ -175,37 +161,42 @@ RegisterPeriodicCallback ( ); /** - DebugSupport protocol member function. + Registers a function to be called when a given processor exception occurs. 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. - + + @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 NewCallback, + IN EFI_EXCEPTION_CALLBACK ExceptionCallback, 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. + 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 @@ -227,24 +218,23 @@ InvalidateInstructionCache ( for. @param Stub On successful exit, *Stub contains the newly allocated entry stub. - @retval EFI_SUCCESS Always. - **/ -EFI_STATUS +VOID CreateEntryStub ( IN EFI_EXCEPTION_TYPE ExceptionType, OUT VOID **Stub ); /** - Get Procedure Entry Point from IDT Gate Descriptor. + Get Interrupt Handle from IDT Gate Descriptor. @param IdtGateDecriptor IDT Gate Descriptor. - @return Procedure Entry Point located in IDT Gate Descriptor. + @return Interrupt Handle stored in IDT Gate Descriptor. **/ -UINTN GetProcedureEntryPoint ( +UINTN +GetInterruptHandleFromIdt ( IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor ); @@ -268,7 +258,7 @@ UINTN GetProcedureEntryPoint ( **/ EFI_STATUS ManageIdtEntryTable ( - VOID (*NewCallback)(), + VOID (*NewCallback)(), EFI_EXCEPTION_TYPE ExceptionType ); @@ -283,10 +273,8 @@ ManageIdtEntryTable ( @param ExceptionType Specifies which vector to hook. @param NewCallback A pointer to the new function to be registered. - @retval EFI_SUCCESS Always. - **/ -EFI_STATUS +VOID HookEntry ( IN EFI_EXCEPTION_TYPE ExceptionType, IN VOID (*NewCallback) () @@ -297,10 +285,8 @@ HookEntry ( @param ExceptionType Specifies which entry to unhook - @retval EFI_SUCCESS Always. - **/ -EFI_STATUS +VOID UnhookEntry ( IN EFI_EXCEPTION_TYPE ExceptionType ); diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c index 932e923eaa..24e2cd0700 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c @@ -1,5 +1,5 @@ /** @file - IA32 specific debug support functions + Generic debug support functions for IA32/x64. Copyright (c) 2006 - 2008, Intel Corporation All rights reserved. This program and the accompanying materials @@ -12,27 +12,25 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ -// -// private header files -// #include "DebugSupport.h" // // This the global main table to keep track of the interrupts // -IDT_ENTRY *IdtEntryTable = NULL; +IDT_ENTRY *IdtEntryTable = NULL; IA32_IDT_GATE_DESCRIPTOR NullDesc = {0}; /** Read IDT Gate Descriptor from IDT Table. @param Vector Specifies vector number. - @param IdtGateDecriptor Pointer to IDT Gate Descriptor read from IDT Table. + @param IdtGateDescriptor Pointer to IDT Gate Descriptor read from IDT Table. **/ -VOID ReadIdtGateDecriptor ( +VOID +ReadIdtGateDescriptor ( IN EFI_EXCEPTION_TYPE Vector, - OUT IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor + OUT IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor ) { IA32_DESCRIPTOR IdtrValue; @@ -41,18 +39,20 @@ VOID ReadIdtGateDecriptor ( AsmReadIdtr (&IdtrValue); IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtrValue.Base; - CopyMem ((VOID *) IdtGateDecriptor, (VOID *) &(IdtTable)[Vector], sizeof (IA32_IDT_GATE_DESCRIPTOR)); + CopyMem ((VOID *) IdtGateDescriptor, (VOID *) &(IdtTable)[Vector], sizeof (IA32_IDT_GATE_DESCRIPTOR)); } + /** Write IDT Gate Descriptor into IDT Table. @param Vector Specifies vector number. - @param IdtGateDecriptor Pointer to IDT Gate Descriptor written into IDT Table. + @param IdtGateDescriptor Pointer to IDT Gate Descriptor written into IDT Table. **/ -VOID WriteIdtGateDecriptor ( +VOID +WriteIdtGateDescriptor ( EFI_EXCEPTION_TYPE Vector, - IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor + IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor ) { IA32_DESCRIPTOR IdtrValue; @@ -61,10 +61,9 @@ VOID WriteIdtGateDecriptor ( AsmReadIdtr (&IdtrValue); IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtrValue.Base; - CopyMem ((VOID *) &(IdtTable)[Vector], (VOID *) IdtGateDecriptor, sizeof (IA32_IDT_GATE_DESCRIPTOR)); + 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 @@ -76,32 +75,35 @@ VOID WriteIdtGateDecriptor ( @param ExceptionType Specifies which vector to hook. @param NewCallback A pointer to the new function to be registered. - @retval EFI_SUCCESS Always. - **/ -EFI_STATUS +VOID 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); - ReadIdtGateDecriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); + CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry); + + // + // Disables CPU interrupts and returns the previous interrupt state + // + OldIntFlagState = SaveAndDisableInterrupts (); - IdtEntryTable[ExceptionType].OrigVector = (DEBUG_PROC) GetProcedureEntryPoint (&(IdtEntryTable[ExceptionType].OrigDesc)); + ReadIdtGateDescriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); + IdtEntryTable[ExceptionType].OrigVector = (DEBUG_PROC) GetInterruptHandleFromIdt (&(IdtEntryTable[ExceptionType].OrigDesc)); - Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry); - IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback; - WriteIdtGateDecriptor (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc)); - WriteInterruptFlag (OldIntFlagState); - } + Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry); + IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback; + WriteIdtGateDescriptor (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc)); + + // + // restore interrupt state + // + SetInterruptState (OldIntFlagState); - return Status; + return ; } /** @@ -109,31 +111,43 @@ HookEntry ( @param ExceptionType Specifies which entry to unhook - @retval EFI_SUCCESS Always. - **/ -EFI_STATUS +VOID UnhookEntry ( IN EFI_EXCEPTION_TYPE ExceptionType ) { BOOLEAN OldIntFlagState; - OldIntFlagState = WriteInterruptFlag (0); - WriteIdtGateDecriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); - WriteInterruptFlag (OldIntFlagState); + // + // Disables CPU interrupts and returns the previous interrupt state + // + OldIntFlagState = SaveAndDisableInterrupts (); - return EFI_SUCCESS; + // + // restore the default IDT Date Descriptor + // + WriteIdtGateDescriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc)); + + // + // restore interrupt state + // + SetInterruptState (OldIntFlagState); + + return ; } /** - This is a DebugSupport protocol member function, hard - coded to support only 1 processor for now. + 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 The DebugSupport instance - @param MaxProcessorIndex The maximuim supported processor index - - @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0. + @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 @@ -144,19 +158,22 @@ GetMaximumProcessorIndex ( ) { *MaxProcessorIndex = 0; - return (EFI_SUCCESS); + 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. - + 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 @@ -170,40 +187,45 @@ RegisterPeriodicCallback ( } /** - DebugSupport protocol member function. + Registers a function to be called when a given processor exception occurs. 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. - + + @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 NewCallback, + IN EFI_EXCEPTION_CALLBACK ExceptionCallback, IN EFI_EXCEPTION_TYPE ExceptionType ) { - return ManageIdtEntryTable (NewCallback, ExceptionType); + return ManageIdtEntryTable (ExceptionCallback, 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. + 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 @@ -220,57 +242,32 @@ InvalidateInstructionCache ( } /** - Initializes driver's handler registration databas. - - This code executes in boot services context - Must be public because it's referenced from DebugSupport.c + Common piece of code that invokes the registered handlers. - @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. + This code executes in exception context so no efi calls are allowed. + + @param ExceptionType Exception type + @param ContextRecord System context **/ -EFI_STATUS -PlInitializeDebugSupportDriver ( - VOID +VOID +InterruptDistrubutionHub ( + EFI_EXCEPTION_TYPE ExceptionType, + EFI_SYSTEM_CONTEXT_IA32 *ContextRecord ) { - 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); + if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) { + if (ExceptionType != SYSTEM_TIMER_VECTOR) { + IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord); + } else { + OrigVector = IdtEntryTable[ExceptionType].OrigVector; + IdtEntryTable[ExceptionType].RegisteredCallback (ContextRecord); } } - FreePool (IdtEntryTable); - - return EFI_OUT_OF_RESOURCES; } /** - This is the callback that is written to the LoadedImage protocol instance + 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. @@ -289,33 +286,71 @@ PlUnloadDebugSupportDriver ( 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; } /** - Common piece of code that invokes the registered handlers. - - This code executes in exception context so no efi calls are allowed. + Initializes driver's handler registration database. + + This code executes in boot services context. + Must be public because it's referenced from DebugSupport.c - @param ExceptionType Exception type - @param ContextRecord System context + @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. **/ -VOID -InterruptDistrubutionHub ( - EFI_EXCEPTION_TYPE ExceptionType, - EFI_SYSTEM_CONTEXT_IA32 *ContextRecord +EFI_STATUS +PlInitializeDebugSupportDriver ( + VOID ) { - if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) { - if (ExceptionType != SYSTEM_TIMER_VECTOR) { - IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord); - } else { - OrigVector = IdtEntryTable[ExceptionType].OrigVector; - IdtEntryTable[ExceptionType].RegisteredCallback (ContextRecord); + 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/PlDebugSupportIa32.c b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c index 47e4e0e350..ff21ed7f2a 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c @@ -15,23 +15,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "DebugSupport.h" /** - Get Procedure Entry Point from IDT Gate Descriptor. + Get Interrupt Handle from IDT Gate Descriptor. - @param IdtGateDecriptor IDT Gate Descriptor. + @param IdtGateDescriptor IDT Gate Descriptor. - @return Procedure Entry Point located in IDT Gate Descriptor. + @return Interrupt Handle stored in IDT Gate Descriptor. **/ -UINTN GetProcedureEntryPoint ( - IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor +UINTN +GetInterruptHandleFromIdt ( + IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDescriptor ) { - UINTN ProcedureEntryPoint; + UINTN InterruptHandle; - ((UINT16 *) &ProcedureEntryPoint)[0] = (UINT16) IdtGateDecriptor->Bits.OffsetLow; - ((UINT16 *) &ProcedureEntryPoint)[1] = (UINT16) IdtGateDecriptor->Bits.OffsetHigh; + ((UINT16 *) &InterruptHandle)[0] = (UINT16) IdtGateDescriptor->Bits.OffsetLow; + ((UINT16 *) &InterruptHandle)[1] = (UINT16) IdtGateDescriptor->Bits.OffsetHigh; - return ProcedureEntryPoint; + return InterruptHandle; } /** @@ -44,10 +45,8 @@ UINTN GetProcedureEntryPoint ( for. @param Stub On successful exit, *Stub contains the newly allocated entry stub. - @retval EFI_SUCCESS Always. - **/ -EFI_STATUS +VOID CreateEntryStub ( IN EFI_EXCEPTION_TYPE ExceptionType, OUT VOID **Stub @@ -80,7 +79,7 @@ CreateEntryStub ( // *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize]; - return EFI_SUCCESS; + return ; } /** @@ -94,16 +93,15 @@ CreateEntryStub ( be uninstalled. @param ExceptionType Indicates which entry to manage. - @retval EFI_SUCCESS Process is ok. + @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. - @retval others Possible return values are passed through from UnHookEntry and HookEntry. **/ EFI_STATUS ManageIdtEntryTable ( - VOID (*NewCallback)(), + VOID (*NewCallback)(), EFI_EXCEPTION_TYPE ExceptionType ) { @@ -122,7 +120,7 @@ ManageIdtEntryTable ( // Status = EFI_ALREADY_STARTED; } else { - Status = UnhookEntry (ExceptionType); + UnhookEntry (ExceptionType); } } else { // @@ -134,7 +132,7 @@ ManageIdtEntryTable ( // Status = EFI_INVALID_PARAMETER; } else { - Status = HookEntry (ExceptionType, NewCallback); + HookEntry (ExceptionType, NewCallback); } } } diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.c index 7b91ae4b63..d358b425de 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.c +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.c @@ -19,11 +19,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. BOOLEAN mInHandler = FALSE; -typedef struct { - UINT64 low; - UINT64 high; -} BUNDLE; - // // number of bundles to swap in ivt // @@ -50,88 +45,6 @@ UINT8 IpfContextBuf[sizeof (EFI_SYSTEM_CONTEXT_IPF) + 512]; UINT8 PatchSaveBuffer[0x400]; UINTN ExternalInterruptCount; -/** - This is the worker function that uninstalls and removes all handlers. - - @param ExceptionType Exception Type - @param NewBundles New Boundles - @param NewCallback New Callback - - @retval EFI_ALEADY_STARTED Ivt already hooked. - @retval others Indicates the request was not satisfied. - @retval EFI_SUCCESS Successfully uninstalled. - -**/ -EFI_STATUS -ManageIvtEntryTable ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN BUNDLE NewBundles[4], - IN VOID (*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 Exception Type - @param NewBundles New Boundles - @param NewCallback New Callback - -**/ -VOID -HookEntry ( - IN EFI_EXCEPTION_TYPE ExceptionType, - IN BUNDLE NewBundles[4], - IN VOID (*NewCallback) () - ); - -/** - Restores original IVT contents when unregistering a callback function. - - @param ExceptionType Exception Type - -**/ -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 New Callback. - -**/ -VOID -ChainExternalInterrupt ( - IN VOID (*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 - ); - /** IPF specific DebugSupport driver initialization. diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h index f8f5532de7..e1e34a449c 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h +++ b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h @@ -15,7 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #ifndef _PLDEBUG_SUPPORT_H_ #define _PLDEBUG_SUPPORT_H_ - #include #include @@ -29,11 +28,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define DISABLE_INTERRUPTS 0UL -// -// The remaining definitions comprise the protocol members. -// #define EFI_ISA IsaIpf +typedef struct { + UINT64 low; + UINT64 high; +} BUNDLE; + /** IPF specific DebugSupport driver initialization. @@ -217,4 +218,86 @@ CommonHandler ( IN EFI_SYSTEM_CONTEXT Context ); +/** + This is the worker function that uninstalls and removes all handlers. + + @param ExceptionType Exception Type + @param NewBundles New Boundles + @param NewCallback New Callback + + @retval EFI_ALEADY_STARTED Ivt already hooked. + @retval others Indicates the request was not satisfied. + @retval EFI_SUCCESS Successfully uninstalled. + +**/ +EFI_STATUS +ManageIvtEntryTable ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN BUNDLE NewBundles[4], + IN VOID (*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 Exception Type + @param NewBundles New Boundles + @param NewCallback New Callback + +**/ +VOID +HookEntry ( + IN EFI_EXCEPTION_TYPE ExceptionType, + IN BUNDLE NewBundles[4], + IN VOID (*NewCallback) () + ); + +/** + Restores original IVT contents when unregistering a callback function. + + @param ExceptionType Exception Type + +**/ +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 New Callback. + +**/ +VOID +ChainExternalInterrupt ( + IN VOID (*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 index 087e5490bb..693d26e6e4 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S +++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S @@ -30,14 +30,6 @@ _StubSize: .long _InterruptEntryStubEnd - _InterruptEntryStub _FxStorSupport: ret -.globl _GetIdtr -_GetIdtr: - ret - -.globl _WriteInterruptFlag -_WriteInterruptFlag: - ret - .globl _Vect2Desc _Vect2Desc: ret diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm index f486bd32b5..d9ba0be191 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm +++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm @@ -131,36 +131,6 @@ FxStorSupport PROC PUBLIC ret FxStorSupport ENDP - - - -;------------------------------------------------------------------------------ -; BOOLEAN -; WriteInterruptFlag ( -; BOOLEAN NewState // rcx -; ) -; -; Abstract: Programs interrupt flag to the requested state and returns previous -; state. -; -WriteInterruptFlag PROC PUBLIC - - pushfq - pop rax - and rax, 200h - shr rax, 9 - cmp rcx, 0 - jnz EnableIF - cli - ret -EnableIF: - sti - ret - -WriteInterruptFlag ENDP - - - ;------------------------------------------------------------------------------ ; void ; Vect2Desc ( diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c index 943d2c6911..e898d82271 100644 --- a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c +++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c @@ -12,30 +12,28 @@ 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. + Get Interrupt Handle from IDT Gate Descriptor. @param IdtGateDecriptor IDT Gate Descriptor. - @return Procedure Entry Point located in IDT Gate Descriptor. + @return Interrupt Handle stored in IDT Gate Descriptor. **/ -UINTN GetProcedureEntryPoint ( +UINTN +GetInterruptHandleFromIdt ( IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor ) { - UINTN ProcedureEntryPoint; + UINTN InterruptHandle; - ((UINT16 *) &ProcedureEntryPoint)[0] = (UINT16) IdtGateDecriptor->Bits.OffsetLow; - ((UINT16 *) &ProcedureEntryPoint)[1] = (UINT16) IdtGateDecriptor->Bits.OffsetHigh; - ((UINT32 *) &ProcedureEntryPoint)[1] = (UINT32) IdtGateDecriptor->Bits.OffsetUpper; + ((UINT16 *) &InterruptHandle)[0] = (UINT16) IdtGateDecriptor->Bits.OffsetLow; + ((UINT16 *) &InterruptHandle)[1] = (UINT16) IdtGateDecriptor->Bits.OffsetHigh; + ((UINT32 *) &InterruptHandle)[1] = (UINT32) IdtGateDecriptor->Bits.OffsetUpper; - return ProcedureEntryPoint; + return InterruptHandle; } /** @@ -48,10 +46,8 @@ UINTN GetProcedureEntryPoint ( for. @param Stub On successful exit, *Stub contains the newly allocated entry stub. - @retval EFI_SUCCESS Always. - **/ -EFI_STATUS +VOID CreateEntryStub ( IN EFI_EXCEPTION_TYPE ExceptionType, OUT VOID **Stub @@ -82,7 +78,7 @@ CreateEntryStub ( // *(UINT32 *) &StubCopy[0x3] = (UINT32)((UINTN) CommonIdtEntry - (UINTN) &StubCopy[StubSize]); - return EFI_SUCCESS; + return; } /** @@ -123,7 +119,7 @@ ManageIdtEntryTable ( // Status = EFI_ALREADY_STARTED; } else { - Status = UnhookEntry (ExceptionType); + UnhookEntry (ExceptionType); } } else { // @@ -135,7 +131,7 @@ ManageIdtEntryTable ( // Status = EFI_INVALID_PARAMETER; } else { - Status = HookEntry (ExceptionType, NewCallback); + HookEntry (ExceptionType, NewCallback); } } -- 2.39.2