UefiCpuPkg/ExceptionLib: Add CommonExceptionHandlerWorker()

Add internal worker function RegisterCpuInterruptHandlerWorker().

Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
This commit is contained in:
Jeff Fan 2016-05-24 21:31:11 +08:00
parent 670f13af60
commit 44ecbc28b6
4 changed files with 72 additions and 26 deletions

View File

@ -261,5 +261,19 @@ GetExceptionNameStr (
IN EFI_EXCEPTION_TYPE ExceptionType IN EFI_EXCEPTION_TYPE ExceptionType
); );
/**
Internal worker function for common exception handler.
@param ExceptionType Exception type.
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
@param ExceptionHandlerData Pointer to exception handler data.
**/
VOID
CommonExceptionHandlerWorker (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext,
IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
);
#endif #endif

View File

@ -19,12 +19,27 @@
CONST UINTN mDoFarReturnFlag = 0; CONST UINTN mDoFarReturnFlag = 0;
extern SPIN_LOCK mDisplayMessageSpinLock;
extern EFI_CPU_INTERRUPT_HANDLER *mExternalInterruptHandler; extern EFI_CPU_INTERRUPT_HANDLER *mExternalInterruptHandler;
extern RESERVED_VECTORS_DATA mReservedVectorsData[CPU_EXCEPTION_NUM]; extern RESERVED_VECTORS_DATA mReservedVectorsData[CPU_EXCEPTION_NUM];
extern EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM]; extern EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM];
EXCEPTION_HANDLER_DATA mExceptionHandlerData; EXCEPTION_HANDLER_DATA mExceptionHandlerData;
/**
Common exception handler.
@param ExceptionType Exception type.
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
**/
VOID
EFIAPI
CommonExceptionHandler (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
CommonExceptionHandlerWorker (ExceptionType, SystemContext, &mExceptionHandlerData);
}
/** /**
Initializes all CPU exceptions entries and provides the default exception handlers. Initializes all CPU exceptions entries and provides the default exception handlers.
@ -96,7 +111,7 @@ InitializeCpuInterruptHandlers (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
} }
InitializeSpinLock (&mDisplayMessageSpinLock);
ExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM); ExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM);
ASSERT (ExternalInterruptHandler != NULL); ASSERT (ExternalInterruptHandler != NULL);

View File

@ -15,10 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "CpuExceptionCommon.h" #include "CpuExceptionCommon.h"
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
//
// Spinlock for CPU information display
//
SPIN_LOCK mDisplayMessageSpinLock;
// //
// Image align size for DXE/SMM // Image align size for DXE/SMM
@ -31,49 +27,54 @@ EFI_CPU_INTERRUPT_HANDLER *mExternalInterruptHandler = NULL;
UINTN mEnabledInterruptNum = 0; UINTN mEnabledInterruptNum = 0;
/** /**
Common exception handler. Internal worker function for common exception handler.
@param ExceptionType Exception type. @param ExceptionType Exception type.
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT. @param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
@param ExceptionHandlerData Pointer to exception handler data.
**/ **/
VOID VOID
EFIAPI CommonExceptionHandlerWorker (
CommonExceptionHandler (
IN EFI_EXCEPTION_TYPE ExceptionType, IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext IN EFI_SYSTEM_CONTEXT SystemContext,
IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
) )
{ {
EXCEPTION_HANDLER_CONTEXT *ExceptionHandlerContext; EXCEPTION_HANDLER_CONTEXT *ExceptionHandlerContext;
RESERVED_VECTORS_DATA *ReservedVectors;
EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler;
ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32); ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32);
ReservedVectors = ExceptionHandlerData->ReservedVectors;
ExternalInterruptHandler = ExceptionHandlerData->ExternalInterruptHandler;
switch (mReservedVectors[ExceptionType].Attribute) { switch (ReservedVectors[ExceptionType].Attribute) {
case EFI_VECTOR_HANDOFF_HOOK_BEFORE: case EFI_VECTOR_HANDOFF_HOOK_BEFORE:
// //
// Need to jmp to old IDT handler after this exception handler // Need to jmp to old IDT handler after this exception handler
// //
ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE; ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;
ExceptionHandlerContext->OldIdtHandler = mReservedVectors[ExceptionType].ExceptonHandler; ExceptionHandlerContext->OldIdtHandler = ReservedVectors[ExceptionType].ExceptonHandler;
break; break;
case EFI_VECTOR_HANDOFF_HOOK_AFTER: case EFI_VECTOR_HANDOFF_HOOK_AFTER:
while (TRUE) { while (TRUE) {
// //
// If if anyone has gotten SPIN_LOCK for owner running hook after // If if anyone has gotten SPIN_LOCK for owner running hook after
// //
if (AcquireSpinLockOrFail (&mReservedVectors[ExceptionType].SpinLock)) { if (AcquireSpinLockOrFail (&ReservedVectors[ExceptionType].SpinLock)) {
// //
// Need to execute old IDT handler before running this exception handler // Need to execute old IDT handler before running this exception handler
// //
mReservedVectors[ExceptionType].ApicId = GetApicId (); ReservedVectors[ExceptionType].ApicId = GetApicId ();
ArchSaveExceptionContext (ExceptionType, SystemContext); ArchSaveExceptionContext (ExceptionType, SystemContext);
ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE; ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;
ExceptionHandlerContext->OldIdtHandler = mReservedVectors[ExceptionType].ExceptonHandler; ExceptionHandlerContext->OldIdtHandler = ReservedVectors[ExceptionType].ExceptonHandler;
return; return;
} }
// //
// If failed to acquire SPIN_LOCK, check if it was locked by processor itself // If failed to acquire SPIN_LOCK, check if it was locked by processor itself
// //
if (mReservedVectors[ExceptionType].ApicId == GetApicId ()) { if (ReservedVectors[ExceptionType].ApicId == GetApicId ()) {
// //
// Old IDT handler has been executed, then retore CPU exception content to // Old IDT handler has been executed, then retore CPU exception content to
// run new exception handler. // run new exception handler.
@ -82,7 +83,7 @@ CommonExceptionHandler (
// //
// Rlease spin lock for ApicId // Rlease spin lock for ApicId
// //
ReleaseSpinLock (&mReservedVectors[ExceptionType].SpinLock); ReleaseSpinLock (&ReservedVectors[ExceptionType].SpinLock);
break; break;
} }
CpuPause (); CpuPause ();
@ -98,13 +99,14 @@ CommonExceptionHandler (
break; break;
} }
if (mExternalInterruptHandler[ExceptionType] != NULL) { if (ExternalInterruptHandler != NULL &&
(mExternalInterruptHandler[ExceptionType]) (ExceptionType, SystemContext); ExternalInterruptHandler[ExceptionType] != NULL) {
(ExternalInterruptHandler[ExceptionType]) (ExceptionType, SystemContext);
} else if (ExceptionType < CPU_EXCEPTION_NUM) { } else if (ExceptionType < CPU_EXCEPTION_NUM) {
// //
// Get Spinlock to display CPU information // Get Spinlock to display CPU information
// //
while (!AcquireSpinLockOrFail (&mDisplayMessageSpinLock)) { while (!AcquireSpinLockOrFail (&ExceptionHandlerData->DisplayMessageSpinLock)) {
CpuPause (); CpuPause ();
} }
// //
@ -114,11 +116,11 @@ CommonExceptionHandler (
// //
// Release Spinlock of output message // Release Spinlock of output message
// //
ReleaseSpinLock (&mDisplayMessageSpinLock); ReleaseSpinLock (&ExceptionHandlerData->DisplayMessageSpinLock);
// //
// Enter a dead loop if needn't to execute old IDT handler further // Enter a dead loop if needn't to execute old IDT handler further
// //
if (mReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) { if (ReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) {
CpuDeadLoop (); CpuDeadLoop ();
} }
} }
@ -234,7 +236,6 @@ InitializeCpuExceptionHandlersWorker (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
} }
InitializeSpinLock (&mDisplayMessageSpinLock);
mExternalInterruptHandler = mExternalInterruptHandlerTable; mExternalInterruptHandler = mExternalInterruptHandlerTable;
// //

View File

@ -20,6 +20,22 @@ CONST UINTN mDoFarReturnFlag = 1;
extern RESERVED_VECTORS_DATA mReservedVectorsData[CPU_EXCEPTION_NUM]; extern RESERVED_VECTORS_DATA mReservedVectorsData[CPU_EXCEPTION_NUM];
extern EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM]; extern EFI_CPU_INTERRUPT_HANDLER mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM];
EXCEPTION_HANDLER_DATA mExceptionHandlerData; EXCEPTION_HANDLER_DATA mExceptionHandlerData;
/**
Common exception handler.
@param ExceptionType Exception type.
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
**/
VOID
EFIAPI
CommonExceptionHandler (
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
CommonExceptionHandlerWorker (ExceptionType, SystemContext, &mExceptionHandlerData);
}
/** /**
Initializes all CPU exceptions entries and provides the default exception handlers. Initializes all CPU exceptions entries and provides the default exception handlers.