UefiCpuPkg/ExceptionLib: Update UpdateIdtTable()

Add parameter CpuExceptionData for UpdateIdtTable().

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:09:22 +08:00
parent ab95e54dc4
commit 9db15f8148
3 changed files with 37 additions and 24 deletions

View File

@ -174,16 +174,17 @@ RegisterCpuInterruptHandlerWorker (
/** /**
Internal worker function to update IDT entries accordling to vector attributes. Internal worker function to update IDT entries accordling to vector attributes.
@param[in] IdtTable Pointer to IDT table. @param[in] IdtTable Pointer to IDT table.
@param[in] TemplateMap Pointer to a buffer where the address map is returned. @param[in] TemplateMap Pointer to a buffer where the address map is
@param[in] IdtEntryCount IDT entries number to be updated. returned.
@param[in] ExceptionHandlerData Pointer to exception handler data.
**/ **/
VOID VOID
UpdateIdtTable ( UpdateIdtTable (
IN IA32_IDT_GATE_DESCRIPTOR *IdtTable, IN IA32_IDT_GATE_DESCRIPTOR *IdtTable,
IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap, IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap,
IN UINTN IdtEntryCount IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
); );
/** /**

View File

@ -83,20 +83,22 @@ InitializeCpuInterruptHandlers (
UINTN Index; UINTN Index;
UINTN InterruptEntry; UINTN InterruptEntry;
UINT8 *InterruptEntryCode; UINT8 *InterruptEntryCode;
RESERVED_VECTORS_DATA *ReservedVectors;
EFI_CPU_INTERRUPT_HANDLER *ExternalInterruptHandler;
mReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM); ReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM);
ASSERT (mReservedVectors != NULL); ASSERT (ReservedVectors != NULL);
SetMem ((VOID *) mReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM, 0xff); SetMem ((VOID *) ReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM, 0xff);
if (VectorInfo != NULL) { if (VectorInfo != NULL) {
Status = ReadAndVerifyVectorInfo (VectorInfo, mReservedVectors, CPU_INTERRUPT_NUM); Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectors, CPU_INTERRUPT_NUM);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
FreePool (mReservedVectors); FreePool (ReservedVectors);
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
} }
InitializeSpinLock (&mDisplayMessageSpinLock); InitializeSpinLock (&mDisplayMessageSpinLock);
mExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM); ExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM);
ASSERT (mExternalInterruptHandler != NULL); ASSERT (ExternalInterruptHandler != NULL);
// //
// Read IDT descriptor and calculate IDT size // Read IDT descriptor and calculate IDT size
@ -130,7 +132,12 @@ InitializeCpuInterruptHandlers (
} }
TemplateMap.ExceptionStart = (UINTN) InterruptEntryCode; TemplateMap.ExceptionStart = (UINTN) InterruptEntryCode;
UpdateIdtTable (IdtTable, &TemplateMap, CPU_INTERRUPT_NUM); mExceptionHandlerData.IdtEntryCount = CPU_INTERRUPT_NUM;
mExceptionHandlerData.ReservedVectors = ReservedVectors;
mExceptionHandlerData.ExternalInterruptHandler = ExternalInterruptHandler;
InitializeSpinLock (&mExceptionHandlerData.DisplayMessageSpinLock);
UpdateIdtTable (IdtTable, &TemplateMap, &mExceptionHandlerData);
// //
// Load Interrupt Descriptor Table // Load Interrupt Descriptor Table

View File

@ -127,47 +127,50 @@ CommonExceptionHandler (
/** /**
Internal worker function to update IDT entries accordling to vector attributes. Internal worker function to update IDT entries accordling to vector attributes.
@param[in] IdtTable Pointer to IDT table. @param[in] IdtTable Pointer to IDT table.
@param[in] TemplateMap Pointer to a buffer where the address map is returned. @param[in] TemplateMap Pointer to a buffer where the address map is
@param[in] IdtEntryCount IDT entries number to be updated. returned.
@param[in] ExceptionHandlerData Pointer to exception handler data.
**/ **/
VOID VOID
UpdateIdtTable ( UpdateIdtTable (
IN IA32_IDT_GATE_DESCRIPTOR *IdtTable, IN IA32_IDT_GATE_DESCRIPTOR *IdtTable,
IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap, IN EXCEPTION_HANDLER_TEMPLATE_MAP *TemplateMap,
IN UINTN IdtEntryCount IN EXCEPTION_HANDLER_DATA *ExceptionHandlerData
) )
{ {
UINT16 CodeSegment; UINT16 CodeSegment;
UINTN Index; UINTN Index;
UINTN InterruptHandler; UINTN InterruptHandler;
RESERVED_VECTORS_DATA *ReservedVectors;
ReservedVectors = ExceptionHandlerData->ReservedVectors;
// //
// Use current CS as the segment selector of interrupt gate in IDT // Use current CS as the segment selector of interrupt gate in IDT
// //
CodeSegment = AsmReadCs (); CodeSegment = AsmReadCs ();
for (Index = 0; Index < IdtEntryCount; Index ++) { for (Index = 0; Index < ExceptionHandlerData->IdtEntryCount; Index ++) {
IdtTable[Index].Bits.Selector = CodeSegment; IdtTable[Index].Bits.Selector = CodeSegment;
// //
// Check reserved vectors attributes // Check reserved vectors attributes
// //
switch (mReservedVectors[Index].Attribute) { switch (ReservedVectors[Index].Attribute) {
case EFI_VECTOR_HANDOFF_DO_NOT_HOOK: case EFI_VECTOR_HANDOFF_DO_NOT_HOOK:
// //
// Keep original IDT entry // Keep original IDT entry
// //
continue; continue;
case EFI_VECTOR_HANDOFF_HOOK_AFTER: case EFI_VECTOR_HANDOFF_HOOK_AFTER:
InitializeSpinLock (&mReservedVectors[Index].SpinLock); InitializeSpinLock (&ReservedVectors[Index].SpinLock);
CopyMem ( CopyMem (
(VOID *) mReservedVectors[Index].HookAfterStubHeaderCode, (VOID *) ReservedVectors[Index].HookAfterStubHeaderCode,
(VOID *) TemplateMap->HookAfterStubHeaderStart, (VOID *) TemplateMap->HookAfterStubHeaderStart,
TemplateMap->ExceptionStubHeaderSize TemplateMap->ExceptionStubHeaderSize
); );
AsmVectorNumFixup ( AsmVectorNumFixup (
(VOID *) mReservedVectors[Index].HookAfterStubHeaderCode, (VOID *) ReservedVectors[Index].HookAfterStubHeaderCode,
(UINT8) Index, (UINT8) Index,
(VOID *) TemplateMap->HookAfterStubHeaderStart (VOID *) TemplateMap->HookAfterStubHeaderStart
); );
@ -178,7 +181,7 @@ UpdateIdtTable (
// //
// Save original IDT handler address // Save original IDT handler address
// //
mReservedVectors[Index].ExceptonHandler = ArchGetIdtHandler (&IdtTable[Index]); ReservedVectors[Index].ExceptonHandler = ArchGetIdtHandler (&IdtTable[Index]);
// //
// Go on the following code // Go on the following code
// //
@ -195,7 +198,7 @@ UpdateIdtTable (
// //
// Save Interrupt number to global variable used for RegisterCpuInterruptHandler () // Save Interrupt number to global variable used for RegisterCpuInterruptHandler ()
// //
mEnabledInterruptNum = IdtEntryCount; mEnabledInterruptNum = ExceptionHandlerData->IdtEntryCount;
} }
/** /**
@ -249,7 +252,9 @@ InitializeCpuExceptionHandlersWorker (
IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
AsmGetTemplateAddressMap (&TemplateMap); AsmGetTemplateAddressMap (&TemplateMap);
ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE); ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE);
UpdateIdtTable (IdtTable, &TemplateMap, IdtEntryCount);
ExceptionHandlerData->IdtEntryCount = IdtEntryCount;
UpdateIdtTable (IdtTable, &TemplateMap, ExceptionHandlerData);
mEnabledInterruptNum = IdtEntryCount; mEnabledInterruptNum = IdtEntryCount;
return EFI_SUCCESS; return EFI_SUCCESS;
} }