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:
parent
670f13af60
commit
44ecbc28b6
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
//
|
//
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue