summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2011-11-16 02:31:31 +0000
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2011-11-16 02:31:31 +0000
commitde4b64f714332d80e9f1e0ada42c1998b5fbb81c (patch)
treef16115160c1bbefe0d300cae71236db182e26b7d
parent9463796b8829a65242d2b202d7f777643d4ba4c4 (diff)
downloadedk2-platforms-de4b64f714332d80e9f1e0ada42c1998b5fbb81c.tar.xz
Restore original IDT entry if RegisterInterruptHandler() was used to unregister user defined interrupt handler.
Signed-off-by: vanjeff Reviewed-by: rsun3 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12719 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--UefiCpuPkg/CpuDxe/CpuDxe.c37
-rw-r--r--UefiCpuPkg/CpuDxe/CpuDxe.h10
2 files changed, 46 insertions, 1 deletions
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c
index fab4ad23cb..89dd2df5be 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.c
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.c
@@ -25,6 +25,8 @@ EFI_HANDLE mCpuHandle = NULL;
BOOLEAN mIsFlushingGCD;
UINT64 mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;
UINT64 mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK;
+IA32_IDT_GATE_DESCRIPTOR *mOrigIdtEntry = NULL;
+UINT16 mOrigIdtEntryCount = 0;
FIXED_MTRR mFixedMtrrTable[] = {
{
@@ -520,7 +522,15 @@ CpuRegisterInterruptHandler (
return EFI_ALREADY_STARTED;
}
- SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL);
+ if (InterruptHandler != NULL) {
+ SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL);
+ } else {
+ //
+ // Restore the original IDT handler address if InterruptHandler is NULL.
+ //
+ RestoreInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType);
+ }
+
ExternalVectorTable[InterruptType] = InterruptHandler;
return EFI_SUCCESS;
}
@@ -1081,6 +1091,25 @@ SetInterruptDescriptorTableHandlerAddress (
#endif
}
+/**
+ Restore original Interrupt Descriptor Table Handler Address.
+
+ @param Index The Index of the interrupt descriptor table handle.
+
+**/
+VOID
+RestoreInterruptDescriptorTableHandlerAddress (
+ IN UINTN Index
+ )
+{
+ if (Index < mOrigIdtEntryCount) {
+ gIdtTable[Index].Bits.OffsetLow = mOrigIdtEntry[Index].Bits.OffsetLow;
+ gIdtTable[Index].Bits.OffsetHigh = mOrigIdtEntry[Index].Bits.OffsetHigh;
+#if defined (MDE_CPU_X64)
+ gIdtTable[Index].Bits.OffsetUpper = mOrigIdtEntry[Index].Bits.OffsetUpper;
+#endif
+ }
+}
/**
Initialize Interrupt Descriptor Table for interrupt handling.
@@ -1111,6 +1140,12 @@ InitInterruptDescriptorTable (
if ((OldIdtPtr.Base != 0) && ((OldIdtPtr.Limit & 7) == 7)) {
OldIdt = (IA32_IDT_GATE_DESCRIPTOR*) OldIdtPtr.Base;
OldIdtSize = (OldIdtPtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
+ //
+ // Save original IDT entry and IDT entry count.
+ //
+ mOrigIdtEntry = AllocateCopyPool (OldIdtPtr.Limit + 1, (VOID *) OldIdtPtr.Base);
+ ASSERT (mOrigIdtEntry != NULL);
+ mOrigIdtEntryCount = (UINT16) OldIdtSize;
} else {
OldIdt = NULL;
OldIdtSize = 0;
diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.h b/UefiCpuPkg/CpuDxe/CpuDxe.h
index e36cf1c82c..6d0d83ba08 100644
--- a/UefiCpuPkg/CpuDxe/CpuDxe.h
+++ b/UefiCpuPkg/CpuDxe/CpuDxe.h
@@ -275,6 +275,16 @@ SetDataSelectors (
UINT16 Selector
);
+/**
+ Restore original Interrupt Descriptor Table Handler Address.
+
+ @param Index The Index of the interrupt descriptor table handle.
+
+**/
+VOID
+RestoreInterruptDescriptorTableHandlerAddress (
+ IN UINTN Index
+ );
#endif