]> git.proxmox.com Git - mirror_edk2.git/commitdiff
1. Separated DxeSmmCpuExceptionHandlerLib.inf into 2 instance DxeCpuExceptionHandlerL...
authorJeff Fan <jeff.fan@intel.com>
Fri, 22 Nov 2013 06:24:41 +0000 (06:24 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 22 Nov 2013 06:24:41 +0000 (06:24 +0000)
2. Updated CPU Exception Handler Library instance according to the new CPU Exception Handler Library class definitions.
3. Updated CPU Exception Handler Library instance to handle the vector attributes defined in PI 1.2.1.

Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Hot Tian <hot.tian@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14885 6f19259b-4bc3-4df7-8a09-765794883524

28 files changed:
UefiCpuPkg/CpuDxe/CpuDxe.c
UefiCpuPkg/CpuDxe/CpuDxe.h
UefiCpuPkg/CpuDxe/CpuDxe.inf
UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S [deleted file]
UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm [deleted file]
UefiCpuPkg/CpuDxe/X64/CpuAsm.S
UefiCpuPkg/CpuDxe/X64/CpuAsm.asm
UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.c
UefiCpuPkg/Library/CpuExceptionHandlerLib/CpuExceptionCommon.h
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuException.c
UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf [deleted file]
UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchExceptionHandler.c
UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.S
UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuException.c
UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchExceptionHandler.c
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h [new file with mode: 0644]
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.S
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.asm
UefiCpuPkg/UefiCpuPkg.dsc

index 2dfde0677d88b54d5988bf974bbfa5f853dbacdc..f165e17c5934942bec6b14884efc6268cdf69a1a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   CPU DXE Module.\r
 \r
-  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 //\r
 // Global Variables\r
 //\r
-IA32_IDT_GATE_DESCRIPTOR  gIdtTable[INTERRUPT_VECTOR_NUMBER] = { { { 0 } } };\r
-\r
-EFI_CPU_INTERRUPT_HANDLER ExternalVectorTable[0x100];\r
 BOOLEAN                   InterruptState = FALSE;\r
 EFI_HANDLE                mCpuHandle = NULL;\r
 BOOLEAN                   mIsFlushingGCD;\r
 UINT64                    mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;\r
 UINT64                    mValidMtrrBitsMask    = MTRR_LIB_MSR_VALID_MASK;\r
-IA32_IDT_GATE_DESCRIPTOR  *mOrigIdtEntry        = NULL;\r
-UINT16                    mOrigIdtEntryCount    = 0;\r
 \r
 FIXED_MTRR    mFixedMtrrTable[] = {\r
   {\r
@@ -100,259 +95,10 @@ EFI_CPU_ARCH_PROTOCOL  gCpu = {
   4                           // DmaBufferAlignment\r
 };\r
 \r
-//\r
-// Error code flag indicating whether or not an error code will be\r
-// pushed on the stack if an exception occurs.\r
-//\r
-// 1 means an error code will be pushed, otherwise 0\r
-//\r
-// bit 0 - exception 0\r
-// bit 1 - exception 1\r
-// etc.\r
-//\r
-UINT32 mErrorCodeFlag = 0x00027d00;\r
-\r
-//\r
-// Local function prototypes\r
-//\r
-\r
-/**\r
-  Set Interrupt Descriptor Table Handler Address.\r
-\r
-  @param Index        The Index of the interrupt descriptor table handle.\r
-  @param Handler      Handler address.\r
-\r
-**/\r
-VOID\r
-SetInterruptDescriptorTableHandlerAddress (\r
-  IN UINTN Index,\r
-  IN VOID  *Handler  OPTIONAL\r
-  );\r
-\r
 //\r
 // CPU Arch Protocol Functions\r
 //\r
 \r
-\r
-/**\r
-  Common exception handler.\r
-\r
-  @param  InterruptType  Exception type\r
-  @param  SystemContext  EFI_SYSTEM_CONTEXT\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-CommonExceptionHandler (\r
-  IN EFI_EXCEPTION_TYPE   InterruptType,\r
-  IN EFI_SYSTEM_CONTEXT   SystemContext\r
-  )\r
-{\r
-#if defined (MDE_CPU_IA32)\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "!!!! IA32 Exception Type - %08x !!!!\n",\r
-    InterruptType\r
-    ));\r
-  if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {\r
-    DEBUG ((\r
-      EFI_D_ERROR,\r
-      "ExceptionData - %08x\n",\r
-      SystemContext.SystemContextIa32->ExceptionData\r
-      ));\r
-  }\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "CS  - %04x,     EIP - %08x, EFL - %08x, SS  - %04x\n",\r
-    SystemContext.SystemContextIa32->Cs,\r
-    SystemContext.SystemContextIa32->Eip,\r
-    SystemContext.SystemContextIa32->Eflags,\r
-    SystemContext.SystemContextIa32->Ss\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "DS  - %04x,     ES  - %04x,     FS  - %04x,     GS  - %04x\n",\r
-    SystemContext.SystemContextIa32->Ds,\r
-    SystemContext.SystemContextIa32->Es,\r
-    SystemContext.SystemContextIa32->Fs,\r
-    SystemContext.SystemContextIa32->Gs\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "EAX - %08x, EBX - %08x, ECX - %08x, EDX - %08x\n",\r
-    SystemContext.SystemContextIa32->Eax,\r
-    SystemContext.SystemContextIa32->Ebx,\r
-    SystemContext.SystemContextIa32->Ecx,\r
-    SystemContext.SystemContextIa32->Edx\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",\r
-    SystemContext.SystemContextIa32->Esp,\r
-    SystemContext.SystemContextIa32->Ebp,\r
-    SystemContext.SystemContextIa32->Esi,\r
-    SystemContext.SystemContextIa32->Edi\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "GDT - %08x  LIM - %04x,     IDT - %08x  LIM - %04x\n",\r
-    SystemContext.SystemContextIa32->Gdtr[0],\r
-    SystemContext.SystemContextIa32->Gdtr[1],\r
-    SystemContext.SystemContextIa32->Idtr[0],\r
-    SystemContext.SystemContextIa32->Idtr[1]\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "LDT - %08x, TR  - %08x\n",\r
-    SystemContext.SystemContextIa32->Ldtr,\r
-    SystemContext.SystemContextIa32->Tr\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",\r
-    SystemContext.SystemContextIa32->Cr0,\r
-    SystemContext.SystemContextIa32->Cr2,\r
-    SystemContext.SystemContextIa32->Cr3,\r
-    SystemContext.SystemContextIa32->Cr4\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",\r
-    SystemContext.SystemContextIa32->Dr0,\r
-    SystemContext.SystemContextIa32->Dr1,\r
-    SystemContext.SystemContextIa32->Dr2,\r
-    SystemContext.SystemContextIa32->Dr3\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "DR6 - %08x, DR7 - %08x\n",\r
-    SystemContext.SystemContextIa32->Dr6,\r
-    SystemContext.SystemContextIa32->Dr7\r
-    ));\r
-#elif defined (MDE_CPU_X64)\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "!!!! X64 Exception Type - %016lx !!!!\n",\r
-    (UINT64)InterruptType\r
-    ));\r
-  if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {\r
-    DEBUG ((\r
-      EFI_D_ERROR,\r
-      "ExceptionData - %016lx\n",\r
-      SystemContext.SystemContextX64->ExceptionData\r
-      ));\r
-  }\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "RIP - %016lx, RFL - %016lx\n",\r
-    SystemContext.SystemContextX64->Rip,\r
-    SystemContext.SystemContextX64->Rflags\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "RAX - %016lx, RCX - %016lx, RDX - %016lx\n",\r
-    SystemContext.SystemContextX64->Rax,\r
-    SystemContext.SystemContextX64->Rcx,\r
-    SystemContext.SystemContextX64->Rdx\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "RBX - %016lx, RSP - %016lx, RBP - %016lx\n",\r
-    SystemContext.SystemContextX64->Rbx,\r
-    SystemContext.SystemContextX64->Rsp,\r
-    SystemContext.SystemContextX64->Rbp\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "RSI - %016lx, RDI - %016lx\n",\r
-    SystemContext.SystemContextX64->Rsi,\r
-    SystemContext.SystemContextX64->Rdi\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "R8  - %016lx, R9  - %016lx, R10 - %016lx\n",\r
-    SystemContext.SystemContextX64->R8,\r
-    SystemContext.SystemContextX64->R9,\r
-    SystemContext.SystemContextX64->R10\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "R11 - %016lx, R12 - %016lx, R13 - %016lx\n",\r
-    SystemContext.SystemContextX64->R11,\r
-    SystemContext.SystemContextX64->R12,\r
-    SystemContext.SystemContextX64->R13\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "R14 - %016lx, R15 - %016lx\n",\r
-    SystemContext.SystemContextX64->R14,\r
-    SystemContext.SystemContextX64->R15\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "CS  - %04lx, DS  - %04lx, ES  - %04lx, FS  - %04lx, GS  - %04lx, SS  - %04lx\n",\r
-    SystemContext.SystemContextX64->Cs,\r
-    SystemContext.SystemContextX64->Ds,\r
-    SystemContext.SystemContextX64->Es,\r
-    SystemContext.SystemContextX64->Fs,\r
-    SystemContext.SystemContextX64->Gs,\r
-    SystemContext.SystemContextX64->Ss\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "GDT - %016lx; %04lx,                   IDT - %016lx; %04lx\n",\r
-    SystemContext.SystemContextX64->Gdtr[0],\r
-    SystemContext.SystemContextX64->Gdtr[1],\r
-    SystemContext.SystemContextX64->Idtr[0],\r
-    SystemContext.SystemContextX64->Idtr[1]\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "LDT - %016lx, TR  - %016lx\n",\r
-    SystemContext.SystemContextX64->Ldtr,\r
-    SystemContext.SystemContextX64->Tr\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",\r
-    SystemContext.SystemContextX64->Cr0,\r
-    SystemContext.SystemContextX64->Cr2,\r
-    SystemContext.SystemContextX64->Cr3\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "CR4 - %016lx, CR8 - %016lx\n",\r
-    SystemContext.SystemContextX64->Cr4,\r
-    SystemContext.SystemContextX64->Cr8\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",\r
-    SystemContext.SystemContextX64->Dr0,\r
-    SystemContext.SystemContextX64->Dr1,\r
-    SystemContext.SystemContextX64->Dr2\r
-    ));\r
-  DEBUG ((\r
-    EFI_D_ERROR,\r
-    "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",\r
-    SystemContext.SystemContextX64->Dr3,\r
-    SystemContext.SystemContextX64->Dr6,\r
-    SystemContext.SystemContextX64->Dr7\r
-    ));\r
-#else\r
-#error CPU type not supported for exception information dump!\r
-#endif\r
-\r
-  //\r
-  // Hang the system with CpuSleep so the processor will enter a lower power\r
-  // state.\r
-  //\r
-  while (TRUE) {\r
-    CpuSleep ();\r
-  };\r
-}\r
-\r
-\r
 /**\r
   Flush CPU data cache. If the instruction cache is fully coherent\r
   with all DMA operations then function can just return EFI_SUCCESS.\r
@@ -510,29 +256,7 @@ CpuRegisterInterruptHandler (
   IN EFI_CPU_INTERRUPT_HANDLER     InterruptHandler\r
   )\r
 {\r
-  if (InterruptType < 0 || InterruptType > 0xff) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  if (InterruptHandler == NULL && ExternalVectorTable[InterruptType] == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (InterruptHandler != NULL && ExternalVectorTable[InterruptType] != NULL) {\r
-    return EFI_ALREADY_STARTED;\r
-  }\r
-\r
-  if (InterruptHandler != NULL) {\r
-    SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL);\r
-  } else {\r
-    //\r
-    // Restore the original IDT handler address if InterruptHandler is NULL.\r
-    //\r
-    RestoreInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType);\r
-  }\r
-\r
-  ExternalVectorTable[InterruptType] = InterruptHandler;\r
-  return EFI_SUCCESS;\r
+  return RegisterCpuInterruptHandler (InterruptType, InterruptHandler);\r
 }\r
 \r
 \r
@@ -1060,57 +784,6 @@ RefreshGcdMemoryAttributes (
   mIsFlushingGCD = FALSE;\r
 }\r
 \r
-/**\r
-  Set Interrupt Descriptor Table Handler Address.\r
-\r
-  @param Index        The Index of the interrupt descriptor table handle.\r
-  @param Handler      Handler address.\r
-\r
-**/\r
-VOID\r
-SetInterruptDescriptorTableHandlerAddress (\r
-  IN UINTN Index,\r
-  IN VOID  *Handler  OPTIONAL\r
-  )\r
-{\r
-  UINTN                     UintnHandler;\r
-\r
-  if (Handler != NULL) {\r
-    UintnHandler = (UINTN) Handler;\r
-  } else {\r
-    UintnHandler = ((UINTN) AsmIdtVector00) + (8 * Index);\r
-  }\r
-\r
-  gIdtTable[Index].Bits.OffsetLow   = (UINT16)UintnHandler;\r
-  gIdtTable[Index].Bits.Reserved_0  = 0;\r
-  gIdtTable[Index].Bits.GateType    = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
-  gIdtTable[Index].Bits.OffsetHigh  = (UINT16)(UintnHandler >> 16);\r
-#if defined (MDE_CPU_X64)\r
-  gIdtTable[Index].Bits.OffsetUpper = (UINT32)(UintnHandler >> 32);\r
-  gIdtTable[Index].Bits.Reserved_1  = 0;\r
-#endif\r
-}\r
-\r
-/**\r
-  Restore original Interrupt Descriptor Table Handler Address.\r
-\r
-  @param Index        The Index of the interrupt descriptor table handle.\r
-\r
-**/\r
-VOID\r
-RestoreInterruptDescriptorTableHandlerAddress (\r
-  IN UINTN       Index\r
-  )\r
-{\r
-  if (Index < mOrigIdtEntryCount) {\r
-    gIdtTable[Index].Bits.OffsetLow   = mOrigIdtEntry[Index].Bits.OffsetLow;\r
-    gIdtTable[Index].Bits.OffsetHigh  = mOrigIdtEntry[Index].Bits.OffsetHigh;\r
-#if defined (MDE_CPU_X64)\r
-    gIdtTable[Index].Bits.OffsetUpper = mOrigIdtEntry[Index].Bits.OffsetUpper;\r
-#endif\r
-  }\r
-}\r
-\r
 /**\r
   Initialize Interrupt Descriptor Table for interrupt handling.\r
 \r
@@ -1120,90 +793,17 @@ InitInterruptDescriptorTable (
   VOID\r
   )\r
 {\r
-  EFI_STATUS                Status;\r
-  IA32_DESCRIPTOR           OldIdtPtr;\r
-  IA32_IDT_GATE_DESCRIPTOR  *OldIdt;\r
-  UINTN                     OldIdtSize;\r
-  VOID                      *IdtPtrAlignmentBuffer;\r
-  IA32_DESCRIPTOR           *IdtPtr;\r
-  UINTN                     Index;\r
-  UINT16                    CurrentCs;\r
-  VOID                      *IntHandler;\r
-\r
-  SetMem (ExternalVectorTable, sizeof(ExternalVectorTable), 0);\r
-\r
-  //\r
-  // Get original IDT address and size.\r
-  //\r
-  AsmReadIdtr ((IA32_DESCRIPTOR *) &OldIdtPtr);\r
-\r
-  if ((OldIdtPtr.Base != 0) && ((OldIdtPtr.Limit & 7) == 7)) {\r
-    OldIdt = (IA32_IDT_GATE_DESCRIPTOR*) OldIdtPtr.Base;\r
-    OldIdtSize = (OldIdtPtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);\r
-    //\r
-    // Save original IDT entry and IDT entry count.\r
-    //\r
-    mOrigIdtEntry = AllocateCopyPool (OldIdtPtr.Limit + 1, (VOID *) OldIdtPtr.Base);\r
-    ASSERT (mOrigIdtEntry != NULL);\r
-    mOrigIdtEntryCount = (UINT16) OldIdtSize;\r
-  } else {\r
-    OldIdt = NULL;\r
-    OldIdtSize = 0;\r
-  }\r
-\r
-  //\r
-  // Intialize IDT\r
-  //\r
-  CurrentCs = AsmReadCs();\r
-  for (Index = 0; Index < INTERRUPT_VECTOR_NUMBER; Index ++) {\r
-    //\r
-    // If the old IDT had a handler for this interrupt, then\r
-    // preserve it.\r
-    //\r
-    if (Index < OldIdtSize) {\r
-      IntHandler =\r
-        (VOID*) (\r
-          OldIdt[Index].Bits.OffsetLow +\r
-          (((UINTN) OldIdt[Index].Bits.OffsetHigh) << 16)\r
-#if defined (MDE_CPU_X64)\r
-            + (((UINTN) OldIdt[Index].Bits.OffsetUpper) << 32)\r
-#endif\r
-          );\r
-    } else {\r
-      IntHandler = NULL;\r
-    }\r
-\r
-    gIdtTable[Index].Bits.Selector    = CurrentCs;\r
-    gIdtTable[Index].Bits.Reserved_0  = 0;\r
-    gIdtTable[Index].Bits.GateType    = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
-    SetInterruptDescriptorTableHandlerAddress (Index, IntHandler);\r
-  }\r
-\r
-  //\r
-  // Load IDT Pointer\r
-  //\r
-  IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16);\r
-  IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16);\r
-  IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1));\r
-  IdtPtr->Limit = (UINT16) (sizeof (gIdtTable) - 1);\r
-\r
-  AsmWriteIdtr (IdtPtr);\r
-\r
-  FreePool (IdtPtrAlignmentBuffer);\r
-\r
-  //\r
-  // Initialize Exception Handlers\r
-  //\r
-  for (Index = OldIdtSize; Index < 32; Index++) {\r
-    Status = CpuRegisterInterruptHandler (&gCpu, Index, CommonExceptionHandler);\r
-    ASSERT_EFI_ERROR (Status);\r
+  EFI_STATUS                     Status;\r
+  EFI_VECTOR_HANDOFF_INFO        *VectorInfoList;\r
+  EFI_VECTOR_HANDOFF_INFO        *VectorInfo;\r
+\r
+  VectorInfo = NULL;\r
+  Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorInfoList);\r
+  if (Status == EFI_SUCCESS && VectorInfoList != NULL) {\r
+    VectorInfo = VectorInfoList;\r
   }\r
-\r
-  //\r
-  // Set the pointer to the array of C based exception handling routines.\r
-  //\r
-  InitializeExternalVectorTablePtr (ExternalVectorTable);\r
-\r
+  Status = InitializeCpuInterruptHandlers (VectorInfo);\r
+  ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
 \r
index a75ec0593f64a4ede0793d87fb6374d6927fb5bd..2001cfc605606621005e8e5b577184435f22c9e2 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   CPU DXE Module.\r
 \r
-  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #include <Library/MtrrLib.h>\r
 #include <Library/LocalApicLib.h>\r
 #include <Library/UefiCpuLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/CpuExceptionHandlerLib.h>\r
 #include <Guid/IdleLoopEvent.h>\r
-\r
-//\r
-//\r
-//\r
-#define INTERRUPT_VECTOR_NUMBER   256\r
+#include <Guid/VectorHandoffTable.h>\r
 \r
 #define EFI_MEMORY_CACHETYPE_MASK     (EFI_MEMORY_UC  | \\r
                                        EFI_MEMORY_WC  | \\r
@@ -220,30 +218,6 @@ CpuSetMemoryAttributes (
   IN UINT64                     Attributes\r
   );\r
 \r
-/**\r
-  Label of base address of IDT vector 0.\r
-\r
-  This is just a label of base address of IDT vector 0.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-AsmIdtVector00 (\r
-  VOID\r
-  );\r
-\r
-/**\r
-  Initializes the pointer to the external interrupt vector table.\r
-\r
-  @param  VectorTable  Address of the external interrupt vector table.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-InitializeExternalVectorTablePtr (\r
-  EFI_CPU_INTERRUPT_HANDLER  *VectorTable\r
-  );\r
-\r
 /**\r
   Initialize Global Descriptor Table.\r
 \r
@@ -277,16 +251,5 @@ SetDataSelectors (
   UINT16 Selector\r
   );\r
 \r
-/**\r
-  Restore original Interrupt Descriptor Table Handler Address.\r
-\r
-  @param Index        The Index of the interrupt descriptor table handle.\r
-\r
-**/\r
-VOID\r
-RestoreInterruptDescriptorTableHandlerAddress (\r
-  IN UINTN       Index\r
-  );\r
-\r
 #endif\r
 \r
index b43506ef58667b7c969a1d84c49e4ec245d7d7c4..a8dfed163b472add784bbcd97b80f161c7b4c9c7 100644 (file)
@@ -2,7 +2,7 @@
 #\r
 #    Component description file for simple CPU driver\r
 #\r
-#  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
 #  which accompanies this distribution.  The full text of the license may be found at\r
   UefiDriverEntryPoint\r
   LocalApicLib\r
   UefiCpuLib\r
+  UefiLib\r
+  CpuExceptionHandlerLib\r
 \r
 [Sources]\r
   CpuDxe.c\r
   CpuDxe.h\r
   CpuGdt.c\r
 \r
-  Ia32/IvtAsm.asm | MSFT\r
-  Ia32/IvtAsm.asm | INTEL\r
-  Ia32/IvtAsm.S   | GCC\r
-\r
 [Sources.IA32]\r
   Ia32/CpuAsm.asm | MSFT\r
   Ia32/CpuAsm.asm | INTEL\r
@@ -64,6 +62,7 @@
 \r
 [Guids]\r
   gIdleLoopEventGuid                            ## CONSUMES ## GUID\r
+  gEfiVectorHandoffTableGuid                    ## CONSUMES ## Configuration Table\r
 \r
 [Depex]\r
   TRUE\r
index 3b43b6fd8b1df64e97921fa6bf2e13002260d3f1..e034bc2e2ed3b625233dcfb085a887002cb9ed66 100644 (file)
@@ -1,6 +1,6 @@
 #------------------------------------------------------------------------------\r
 #*\r
-#*   Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+#*   Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
 #*   This program and the accompanying materials\r
 #*   are licensed and made available under the terms and conditions of the BSD License\r
 #*   which accompanies this distribution.  The full text of the license may be found at\r
 #.MMX\r
 #.XMM\r
 \r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
-\r
-\r
-#\r
-# point to the external interrupt vector table\r
-#\r
-ExternalVectorTablePtr:\r
-    .byte      0, 0, 0, 0\r
-\r
-ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)\r
-ASM_PFX(InitializeExternalVectorTablePtr):\r
-    movl    4(%esp), %eax\r
-    movl    %eax, ExternalVectorTablePtr\r
-    ret\r
-\r
 #------------------------------------------------------------------------------\r
 # VOID\r
 # SetCodeSelector (\r
@@ -68,298 +53,5 @@ ASM_PFX(SetDataSelectors):
     movw    %cx, %gs\r
     ret\r
 \r
-#---------------------------------------;\r
-# CommonInterruptEntry                  ;\r
-#---------------------------------------;\r
-# The follow algorithm is used for the common interrupt routine.\r
-\r
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
-ASM_PFX(CommonInterruptEntry):\r
-    cli\r
-    #\r
-    # All interrupt handlers are invoked through interrupt gates, so\r
-    # IF flag automatically cleared at the entry point\r
-    #\r
-\r
-    #\r
-    # Calculate vector number\r
-    #\r
-    # Get the return address of call, actually, it is the\r
-    # address of vector number.\r
-    #\r
-    xchgl   (%esp), %ecx\r
-    movw    (%ecx), %cx\r
-    andl    $0x0FFFF, %ecx\r
-    cmpl    $32, %ecx         # Intel reserved vector for exceptions?\r
-    jae     NoErrorCode\r
-    bt      %ecx, ASM_PFX(mErrorCodeFlag)\r
-    jc      HasErrorCode\r
-\r
-NoErrorCode:\r
-\r
-    #\r
-    # Stack:\r
-    # +---------------------+\r
-    # +    EFlags           +\r
-    # +---------------------+\r
-    # +    CS               +\r
-    # +---------------------+\r
-    # +    EIP              +\r
-    # +---------------------+\r
-    # +    ECX              +\r
-    # +---------------------+ <-- ESP\r
-    #\r
-    # Registers:\r
-    #   ECX - Vector Number\r
-    #\r
-\r
-    #\r
-    # Put Vector Number on stack\r
-    #\r
-    pushl   %ecx\r
-\r
-    #\r
-    # Put 0 (dummy) error code on stack, and restore ECX\r
-    #\r
-    xorl    %ecx, %ecx  # ECX = 0\r
-    xchgl   4(%esp), %ecx\r
-\r
-    jmp     ErrorCodeAndVectorOnStack\r
-\r
-HasErrorCode:\r
-\r
-    #\r
-    # Stack:\r
-    # +---------------------+\r
-    # +    EFlags           +\r
-    # +---------------------+\r
-    # +    CS               +\r
-    # +---------------------+\r
-    # +    EIP              +\r
-    # +---------------------+\r
-    # +    Error Code       +\r
-    # +---------------------+\r
-    # +    ECX              +\r
-    # +---------------------+ <-- ESP\r
-    #\r
-    # Registers:\r
-    #   ECX - Vector Number\r
-    #\r
-\r
-    #\r
-    # Put Vector Number on stack and restore ECX\r
-    #\r
-    xchgl   (%esp), %ecx \r
-\r
-ErrorCodeAndVectorOnStack:\r
-    pushl   %ebp\r
-    movl    %esp, %ebp\r
-\r
-    #\r
-    # Stack:\r
-    # +---------------------+\r
-    # +    EFlags           +\r
-    # +---------------------+\r
-    # +    CS               +\r
-    # +---------------------+\r
-    # +    EIP              +\r
-    # +---------------------+\r
-    # +    Error Code       +\r
-    # +---------------------+\r
-    # +    Vector Number    +\r
-    # +---------------------+\r
-    # +    EBP              +\r
-    # +---------------------+ <-- EBP\r
-    #\r
-\r
-    #\r
-    # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
-    # is 16-byte aligned\r
-    #\r
-    andl    $0x0fffffff0, %esp \r
-    subl    $12, %esp\r
-\r
-#; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
-    pushl   %eax\r
-    pushl   %ecx\r
-    pushl   %edx\r
-    pushl   %ebx\r
-    leal    24(%ebp), %ecx\r
-    pushl   %ecx                          # ESP\r
-    pushl   (%ebp)              # EBP\r
-    pushl   %esi\r
-    pushl   %edi\r
-\r
-#; UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
-    movl    %ss, %eax\r
-    pushl   %eax\r
-    movzwl  16(%ebp), %eax \r
-    pushl   %eax\r
-    movl    %ds, %eax\r
-    pushl   %eax\r
-    movl    %es, %eax\r
-    pushl   %eax\r
-    movl    %fs, %eax\r
-    pushl   %eax\r
-    movl    %gs, %eax\r
-    pushl   %eax\r
-\r
-#; UINT32  Eip;\r
-    movl    12(%ebp), %eax\r
-    pushl   %eax\r
-\r
-#; UINT32  Gdtr[2], Idtr[2];\r
-    subl    $8, %esp\r
-    sidt    (%esp)\r
-    movl    2(%esp), %eax\r
-    xchgl   (%esp), %eax\r
-    andl    $0x0FFFF, %eax \r
-    movl    %eax, 4(%esp)\r
-\r
-    subl    $8, %esp\r
-    sgdt    (%esp)\r
-    movl    2(%esp), %eax\r
-    xchgl   (%esp), %eax\r
-    andl    $0x0FFFF, %eax \r
-    movl    %eax, 4(%esp)\r
-\r
-#; UINT32  Ldtr, Tr;\r
-    xorl    %eax, %eax\r
-    str     %ax\r
-    pushl   %eax\r
-    sldt    %ax\r
-    pushl   %eax\r
-\r
-#; UINT32  EFlags;\r
-    movl    20(%ebp), %eax\r
-    pushl   %eax\r
-\r
-#; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
-    movl    %cr4, %eax\r
-    orl     $0x208, %eax\r
-    movl    %eax, %cr4\r
-    pushl   %eax\r
-    movl    %cr3, %eax\r
-    pushl   %eax\r
-    movl    %cr2, %eax\r
-    pushl   %eax\r
-    xorl    %eax, %eax\r
-    pushl   %eax\r
-    movl    %cr0, %eax\r
-    pushl   %eax\r
-\r
-#; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-    movl    %dr7, %eax\r
-    pushl   %eax\r
-    movl    %dr6, %eax\r
-    pushl   %eax\r
-    movl    %dr3, %eax\r
-    pushl   %eax\r
-    movl    %dr2, %eax\r
-    pushl   %eax\r
-    movl    %dr1, %eax\r
-    pushl   %eax\r
-    movl    %dr0, %eax\r
-    pushl   %eax\r
-\r
-#; FX_SAVE_STATE_IA32 FxSaveState;\r
-    subl    $512, %esp\r
-    movl    %esp, %edi\r
-    .byte      0x0f, 0x0ae, 0x07 #fxsave [edi]\r
-\r
-#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
-    cld\r
-\r
-#; UINT32  ExceptionData;\r
-    pushl   8(%ebp)\r
-\r
-#; call into exception handler\r
-    movl    ExternalVectorTablePtr, %eax  # get the interrupt vectors base\r
-    orl     %eax, %eax                        # NULL?\r
-    jz      nullExternalExceptionHandler\r
-\r
-    mov     4(%ebp), %ecx\r
-    movl    (%eax,%ecx,4), %eax\r
-    orl     %eax, %eax                        # NULL?\r
-    jz      nullExternalExceptionHandler\r
-\r
-#; Prepare parameter and call\r
-    movl    %esp, %edx\r
-    pushl   %edx\r
-    movl    4(%ebp), %edx\r
-    pushl   %edx\r
-\r
-    #\r
-    # Call External Exception Handler\r
-    #\r
-    call    *%eax\r
-    addl    $8, %esp\r
-\r
-nullExternalExceptionHandler:\r
-\r
-    cli\r
-#; UINT32  ExceptionData;\r
-    addl    $4, %esp\r
-\r
-#; FX_SAVE_STATE_IA32 FxSaveState;\r
-    movl    %esp, %esi\r
-    .byte      0x0f, 0x0ae, 0x0e # fxrstor [esi]\r
-    addl    $512, %esp\r
-\r
-#; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-#; Skip restoration of DRx registers to support in-circuit emualators\r
-#; or debuggers set breakpoint in interrupt/exception context\r
-    addl    $24, %esp\r
-\r
-#; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
-    popl    %eax\r
-    movl    %eax, %cr0\r
-    addl    $4, %esp    # not for Cr1\r
-    popl    %eax\r
-    movl    %eax, %cr2\r
-    popl    %eax\r
-    movl    %eax, %cr3\r
-    popl    %eax\r
-    movl    %eax, %cr4\r
-\r
-#; UINT32  EFlags;\r
-    popl    20(%ebp)\r
-\r
-#; UINT32  Ldtr, Tr;\r
-#; UINT32  Gdtr[2], Idtr[2];\r
-#; Best not let anyone mess with these particular registers...\r
-    addl    $24, %esp\r
-\r
-#; UINT32  Eip;\r
-    popl    12(%ebp)\r
-\r
-#; UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
-#; NOTE - modified segment registers could hang the debugger...  We\r
-#;        could attempt to insulate ourselves against this possibility,\r
-#;        but that poses risks as well.\r
-#;\r
-    popl    %gs\r
-    popl    %fs\r
-    popl    %es\r
-    popl    %ds\r
-    popl    16(%ebp)\r
-    popl    %ss\r
-\r
-#; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
-    popl    %edi\r
-    popl    %esi\r
-    addl    $4, %esp   # not for ebp\r
-    addl    $4, %esp   # not for esp\r
-    popl    %ebx\r
-    popl    %edx\r
-    popl    %ecx\r
-    popl    %eax\r
-\r
-    movl    %ebp, %esp\r
-    popl    %ebp\r
-    addl    $8, %esp\r
-    iretl\r
-\r
-\r
 #END\r
 \r
index 0924dc5bb383985d246b78544a9b497aecec0533..7f8f0d6f3ad848841389240a7aeb0eb60337a433 100644 (file)
@@ -1,7 +1,7 @@
       TITLE   CpuAsm.asm:\r
 ;------------------------------------------------------------------------------\r
 ;*\r
-;*   Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+;*   Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
 ;*   This program and the accompanying materials\r
 ;*   are licensed and made available under the terms and conditions of the BSD License\r
 ;*   which accompanies this distribution.  The full text of the license may be found at\r
     .model  flat,C\r
     .code\r
 \r
-EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
-\r
-;\r
-; point to the external interrupt vector table\r
-;\r
-ExternalVectorTablePtr DWORD 0\r
-\r
-InitializeExternalVectorTablePtr PROC PUBLIC\r
-    mov     eax, [esp+4]\r
-    mov     ExternalVectorTablePtr, eax\r
-    ret\r
-InitializeExternalVectorTablePtr ENDP\r
-\r
 ;------------------------------------------------------------------------------\r
 ; VOID\r
 ; SetCodeSelector (\r
@@ -67,297 +54,5 @@ SetDataSelectors PROC PUBLIC
     ret\r
 SetDataSelectors ENDP\r
 \r
-;---------------------------------------;\r
-; CommonInterruptEntry                  ;\r
-;---------------------------------------;\r
-; The follow algorithm is used for the common interrupt routine.\r
-\r
-CommonInterruptEntry PROC PUBLIC\r
-    cli\r
-    ;\r
-    ; All interrupt handlers are invoked through interrupt gates, so\r
-    ; IF flag automatically cleared at the entry point\r
-    ;\r
-\r
-    ;\r
-    ; Calculate vector number\r
-    ;\r
-    ; Get the return address of call, actually, it is the\r
-    ; address of vector number.\r
-    ;\r
-    xchg    ecx, [esp]\r
-    mov     cx, [ecx]\r
-    and     ecx, 0FFFFh\r
-    cmp     ecx, 32         ; Intel reserved vector for exceptions?\r
-    jae     NoErrorCode\r
-    bt      mErrorCodeFlag, ecx\r
-    jc      HasErrorCode\r
-\r
-NoErrorCode:\r
-\r
-    ;\r
-    ; Stack:\r
-    ; +---------------------+\r
-    ; +    EFlags           +\r
-    ; +---------------------+\r
-    ; +    CS               +\r
-    ; +---------------------+\r
-    ; +    EIP              +\r
-    ; +---------------------+\r
-    ; +    ECX              +\r
-    ; +---------------------+ <-- ESP\r
-    ;\r
-    ; Registers:\r
-    ;   ECX - Vector Number\r
-    ;\r
-\r
-    ;\r
-    ; Put Vector Number on stack\r
-    ;\r
-    push    ecx\r
-\r
-    ;\r
-    ; Put 0 (dummy) error code on stack, and restore ECX\r
-    ;\r
-    xor     ecx, ecx  ; ECX = 0\r
-    xchg    ecx, [esp+4]\r
-\r
-    jmp     ErrorCodeAndVectorOnStack\r
-\r
-HasErrorCode:\r
-\r
-    ;\r
-    ; Stack:\r
-    ; +---------------------+\r
-    ; +    EFlags           +\r
-    ; +---------------------+\r
-    ; +    CS               +\r
-    ; +---------------------+\r
-    ; +    EIP              +\r
-    ; +---------------------+\r
-    ; +    Error Code       +\r
-    ; +---------------------+\r
-    ; +    ECX              +\r
-    ; +---------------------+ <-- ESP\r
-    ;\r
-    ; Registers:\r
-    ;   ECX - Vector Number\r
-    ;\r
-\r
-    ;\r
-    ; Put Vector Number on stack and restore ECX\r
-    ;\r
-    xchg    ecx, [esp]\r
-\r
-ErrorCodeAndVectorOnStack:\r
-    push    ebp\r
-    mov     ebp, esp\r
-\r
-    ;\r
-    ; Stack:\r
-    ; +---------------------+\r
-    ; +    EFlags           +\r
-    ; +---------------------+\r
-    ; +    CS               +\r
-    ; +---------------------+\r
-    ; +    EIP              +\r
-    ; +---------------------+\r
-    ; +    Error Code       +\r
-    ; +---------------------+\r
-    ; +    Vector Number    +\r
-    ; +---------------------+\r
-    ; +    EBP              +\r
-    ; +---------------------+ <-- EBP\r
-    ;\r
-\r
-    ;\r
-    ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
-    ; is 16-byte aligned\r
-    ;\r
-    and     esp, 0fffffff0h\r
-    sub     esp, 12\r
-\r
-;; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
-    push    eax\r
-    push    ecx\r
-    push    edx\r
-    push    ebx\r
-    lea     ecx, [ebp + 6 * 4]\r
-    push    ecx                          ; ESP\r
-    push    dword ptr [ebp]              ; EBP\r
-    push    esi\r
-    push    edi\r
-\r
-;; UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
-    mov     eax, ss\r
-    push    eax\r
-    movzx   eax, word ptr [ebp + 4 * 4]\r
-    push    eax\r
-    mov     eax, ds\r
-    push    eax\r
-    mov     eax, es\r
-    push    eax\r
-    mov     eax, fs\r
-    push    eax\r
-    mov     eax, gs\r
-    push    eax\r
-\r
-;; UINT32  Eip;\r
-    mov     eax, [ebp + 3 * 4]\r
-    push    eax\r
-\r
-;; UINT32  Gdtr[2], Idtr[2];\r
-    sub     esp, 8\r
-    sidt    [esp]\r
-    mov     eax, [esp + 2]\r
-    xchg    eax, [esp]\r
-    and     eax, 0FFFFh\r
-    mov     [esp+4], eax\r
-\r
-    sub     esp, 8\r
-    sgdt    [esp]\r
-    mov     eax, [esp + 2]\r
-    xchg    eax, [esp]\r
-    and     eax, 0FFFFh\r
-    mov     [esp+4], eax\r
-\r
-;; UINT32  Ldtr, Tr;\r
-    xor     eax, eax\r
-    str     ax\r
-    push    eax\r
-    sldt    ax\r
-    push    eax\r
-\r
-;; UINT32  EFlags;\r
-    mov     eax, [ebp + 5 * 4]\r
-    push    eax\r
-\r
-;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
-    mov     eax, cr4\r
-    or      eax, 208h\r
-    mov     cr4, eax\r
-    push    eax\r
-    mov     eax, cr3\r
-    push    eax\r
-    mov     eax, cr2\r
-    push    eax\r
-    xor     eax, eax\r
-    push    eax\r
-    mov     eax, cr0\r
-    push    eax\r
-\r
-;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-    mov     eax, dr7\r
-    push    eax\r
-    mov     eax, dr6\r
-    push    eax\r
-    mov     eax, dr3\r
-    push    eax\r
-    mov     eax, dr2\r
-    push    eax\r
-    mov     eax, dr1\r
-    push    eax\r
-    mov     eax, dr0\r
-    push    eax\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
-    sub     esp, 512\r
-    mov     edi, esp\r
-    db      0fh, 0aeh, 07h ;fxsave [edi]\r
-\r
-;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
-    cld\r
-\r
-;; UINT32  ExceptionData;\r
-    push    dword ptr [ebp + 2 * 4]\r
-\r
-;; call into exception handler\r
-    mov     eax, ExternalVectorTablePtr  ; get the interrupt vectors base\r
-    or      eax, eax                        ; NULL?\r
-    jz      nullExternalExceptionHandler\r
-\r
-    mov     ecx, [ebp + 4]\r
-    mov     eax, [eax + ecx * 4]\r
-    or      eax, eax                        ; NULL?\r
-    jz      nullExternalExceptionHandler\r
-\r
-;; Prepare parameter and call\r
-    mov     edx, esp\r
-    push    edx\r
-    mov     edx, dword ptr [ebp + 1 * 4]\r
-    push    edx\r
-\r
-    ;\r
-    ; Call External Exception Handler\r
-    ;\r
-    call    eax\r
-    add     esp, 8\r
-\r
-nullExternalExceptionHandler:\r
-\r
-    cli\r
-;; UINT32  ExceptionData;\r
-    add     esp, 4\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
-    mov     esi, esp\r
-    db      0fh, 0aeh, 0eh ; fxrstor [esi]\r
-    add     esp, 512\r
-\r
-;; UINT32  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; Skip restoration of DRx registers to support in-circuit emualators\r
-;; or debuggers set breakpoint in interrupt/exception context\r
-    add     esp, 4 * 6\r
-\r
-;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;\r
-    pop     eax\r
-    mov     cr0, eax\r
-    add     esp, 4    ; not for Cr1\r
-    pop     eax\r
-    mov     cr2, eax\r
-    pop     eax\r
-    mov     cr3, eax\r
-    pop     eax\r
-    mov     cr4, eax\r
-\r
-;; UINT32  EFlags;\r
-    pop     dword ptr [ebp + 5 * 4]\r
-\r
-;; UINT32  Ldtr, Tr;\r
-;; UINT32  Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
-    add     esp, 24\r
-\r
-;; UINT32  Eip;\r
-    pop     dword ptr [ebp + 3 * 4]\r
-\r
-;; UINT32  Gs, Fs, Es, Ds, Cs, Ss;\r
-;; NOTE - modified segment registers could hang the debugger...  We\r
-;;        could attempt to insulate ourselves against this possibility,\r
-;;        but that poses risks as well.\r
-;;\r
-    pop     gs\r
-    pop     fs\r
-    pop     es\r
-    pop     ds\r
-    pop     dword ptr [ebp + 4 * 4]\r
-    pop     ss\r
-\r
-;; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
-    pop     edi\r
-    pop     esi\r
-    add     esp, 4   ; not for ebp\r
-    add     esp, 4   ; not for esp\r
-    pop     ebx\r
-    pop     edx\r
-    pop     ecx\r
-    pop     eax\r
-\r
-    mov     esp, ebp\r
-    pop     ebp\r
-    add     esp, 8\r
-    iretd\r
-\r
-CommonInterruptEntry ENDP\r
 \r
 END\r
diff --git a/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S b/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S
deleted file mode 100644 (file)
index c38461d..0000000
+++ /dev/null
@@ -1,818 +0,0 @@
-#------------------------------------------------------------------------------\r
-#\r
-# Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
-# This program and the accompanying materials\r
-# are licensed and made available under the terms and conditions of the BSD License\r
-# which accompanies this distribution.  The full text of the license may be found at\r
-# http://opensource.org/licenses/bsd-license.php\r
-#\r
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#\r
-# Module Name:\r
-#\r
-#   IvtAsm.S\r
-#\r
-# Abstract:\r
-#\r
-#   Interrupt Vector Table\r
-#\r
-#------------------------------------------------------------------------------\r
-\r
-#\r
-# Interrupt Vector Table\r
-#\r
-\r
-\r
-ASM_GLOBAL ASM_PFX(AsmIdtVector00)\r
-.p2align 3\r
-ASM_PFX(AsmIdtVector00):\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x00\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x01\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x02\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x03\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x04\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x05\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x06\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x07\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x08\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x09\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x0a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x0b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x0c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x0d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x0e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x0f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x10\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x11\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x12\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x13\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x14\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x15\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x16\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x17\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x18\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x19\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x1a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x1b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x1c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x1d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x1e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x1f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x00\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x21\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x22\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x23\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x24\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x25\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x26\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x27\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x28\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x29\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x2a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x2b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x2c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x2d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x2e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x2f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x30\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x31\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x32\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x33\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x34\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x35\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x36\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x37\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x38\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x39\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x3a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x3b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x3c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x3d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x3e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x3f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x40\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x41\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x42\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x43\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x44\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x45\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x46\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x47\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x48\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x49\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x4a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x4b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x4c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x4d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x4e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x4f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x50\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x51\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x52\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x53\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x54\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x55\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x56\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x57\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x58\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x59\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x5a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x5b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x5c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x5d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x5e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x5f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x60\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x61\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x62\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x63\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x64\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x65\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x66\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x67\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x68\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x69\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x6a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x6b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x6c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x6d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x6e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x6f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x70\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x71\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x72\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x73\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x74\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x75\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x76\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x77\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x78\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x79\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x7a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x7b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x7c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x7d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x7e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x7f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x80\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x81\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x82\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x83\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x84\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x85\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x86\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x87\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x88\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x89\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x8a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x8b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x8c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x8d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x8e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x8f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x90\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x91\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x92\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x93\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x94\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x95\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x96\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x97\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x98\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x99\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x9a\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x9b\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x9c\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x9d\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x9e\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0x9f\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa0\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa1\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa2\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa3\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa4\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa5\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa6\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa7\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa8\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xa9\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xaa\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xab\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xac\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xad\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xae\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xaf\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb0\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb1\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb2\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb3\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb4\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb5\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb6\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb7\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb8\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xb9\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xba\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xbb\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xbc\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xbd\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xbe\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xbf\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc0\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc1\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc2\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc3\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc4\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc5\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc6\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc7\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc8\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xc9\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xca\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xcb\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xcc\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xcd\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xce\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xcf\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd0\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd1\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd2\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd3\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd4\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd5\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd6\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd7\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd8\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xd9\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xda\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xdb\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xdc\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xdd\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xde\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xdf\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe0\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe1\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe2\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe3\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe4\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe5\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe6\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe7\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe8\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xe9\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xea\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xeb\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xec\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xed\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xee\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xef\r
-    nop\r
-    \r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf0\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf1\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf2\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf3\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf4\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf5\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf6\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf7\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf8\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xf9\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xfa\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xfb\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xfc\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xfd\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xfe\r
-    nop\r
-    call    ASM_PFX(CommonInterruptEntry)\r
-    .short  0xff\r
-    nop\r
-    \r
-ASM_GLOBAL ASM_PFX(AsmCommonIdtEnd)\r
-ASM_PFX(AsmCommonIdtEnd):\r
-    .byte 0\r
-\r
-    \r
diff --git a/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm b/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm
deleted file mode 100644 (file)
index 02003c9..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-      TITLE   IvtAsm.asm:\r
-;------------------------------------------------------------------------------\r
-;*\r
-;*   Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>\r
-;*   This program and the accompanying materials\r
-;*   are licensed and made available under the terms and conditions of the BSD License\r
-;*   which accompanies this distribution.  The full text of the license may be found at\r
-;*   http://opensource.org/licenses/bsd-license.php\r
-;*\r
-;*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-;*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-;*\r
-;*    IvtAsm.asm\r
-;*\r
-;*   Abstract:\r
-;*\r
-;------------------------------------------------------------------------------\r
-\r
-#include <Base.h>\r
-\r
-#ifdef MDE_CPU_IA32\r
-    .686\r
-    .model  flat,C\r
-#endif\r
-    .code\r
-\r
-;------------------------------------------------------------------------------\r
-;  Generic IDT Vector Handlers for the Host. They are all the same so they\r
-;  will compress really well.\r
-;\r
-;  By knowing the return address for Vector 00 you can can calculate the\r
-;  vector number by looking at the call CommonInterruptEntry return address.\r
-;  (return address - (AsmIdtVector00 + 5))/8 == IDT index\r
-;\r
-;------------------------------------------------------------------------------\r
-\r
-EXTRN CommonInterruptEntry:PROC\r
-\r
-ALIGN   8\r
-\r
-PUBLIC AsmIdtVector00\r
-\r
-AsmIdtVector00 LABEL BYTE\r
-REPEAT  256\r
-    call    CommonInterruptEntry\r
-    dw      ($ - AsmIdtVector00 - 5) / 8 ; vector number\r
-    nop\r
-ENDM\r
-\r
-END\r
-\r
index e038f2e341726bf59ebbc97fadb61c16725209ba..e82cadf36918d9c9ef74d06a78b4158a7ad4ef49 100644 (file)
@@ -2,7 +2,7 @@
 \r
 #------------------------------------------------------------------------------\r
 #*\r
-#*   Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+#*   Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>\r
 #*   This program and the accompanying materials\r
 #*   are licensed and made available under the terms and conditions of the BSD License\r
 #*   which accompanies this distribution.  The full text of the license may be found at\r
 #text  SEGMENT\r
 \r
 \r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
-\r
-\r
-#\r
-# point to the external interrupt vector table\r
-#\r
-ExternalVectorTablePtr:\r
-    .byte      0, 0, 0, 0, 0, 0, 0, 0\r
-\r
-ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)\r
-ASM_PFX(InitializeExternalVectorTablePtr):\r
-    lea     ExternalVectorTablePtr(%rip), %rax # save vector number\r
-    mov     %rcx, (%rax) \r
-    ret\r
-\r
-\r
 #------------------------------------------------------------------------------\r
 # VOID\r
 # SetCodeSelector (\r
@@ -69,275 +53,6 @@ ASM_PFX(SetDataSelectors):
     movw    %cx, %gs\r
     ret\r
 \r
-#---------------------------------------;\r
-# CommonInterruptEntry                  ;\r
-#---------------------------------------;\r
-# The follow algorithm is used for the common interrupt routine.\r
-\r
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
-ASM_PFX(CommonInterruptEntry):\r
-    cli\r
-    #\r
-    # All interrupt handlers are invoked through interrupt gates, so\r
-    # IF flag automatically cleared at the entry point\r
-    #\r
-    #\r
-    # Calculate vector number\r
-    #\r
-    xchgq   (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.\r
-    movzwl  (%rcx), %ecx \r
-    cmp     $32, %ecx          # Intel reserved vector for exceptions?\r
-    jae     NoErrorCode\r
-    pushq   %rax\r
-    leaq    ASM_PFX(mErrorCodeFlag)(%rip), %rax\r
-    bt      %ecx, (%rax) \r
-    popq    %rax\r
-    jc      CommonInterruptEntry_al_0000\r
-\r
-NoErrorCode:\r
-\r
-    #\r
-    # Push a dummy error code on the stack\r
-    # to maintain coherent stack map\r
-    #\r
-    pushq   (%rsp)\r
-    movq    $0, 8(%rsp)\r
-CommonInterruptEntry_al_0000:\r
-    pushq   %rbp\r
-    movq    %rsp, %rbp\r
-\r
-    #\r
-    # Stack:\r
-    # +---------------------+ <-- 16-byte aligned ensured by processor\r
-    # +    Old SS           +\r
-    # +---------------------+\r
-    # +    Old RSP          +\r
-    # +---------------------+\r
-    # +    RFlags           +\r
-    # +---------------------+\r
-    # +    CS               +\r
-    # +---------------------+\r
-    # +    RIP              +\r
-    # +---------------------+\r
-    # +    Error Code       +\r
-    # +---------------------+\r
-    # + RCX / Vector Number +\r
-    # +---------------------+\r
-    # +    RBP              +\r
-    # +---------------------+ <-- RBP, 16-byte aligned\r
-    #\r
-\r
-\r
-    #\r
-    # Since here the stack pointer is 16-byte aligned, so\r
-    # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
-    # is 16-byte aligned\r
-    #\r
-\r
-#; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-#; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
-    pushq    %r15\r
-    pushq    %r14\r
-    pushq    %r13\r
-    pushq    %r12\r
-    pushq    %r11\r
-    pushq    %r10\r
-    pushq    %r9\r
-    pushq    %r8\r
-    pushq    %rax\r
-    pushq    8(%rbp)   # RCX\r
-    pushq    %rdx\r
-    pushq    %rbx\r
-    pushq    48(%rbp)  # RSP\r
-    pushq    (%rbp)    # RBP\r
-    pushq    %rsi\r
-    pushq    %rdi\r
-\r
-#; UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero\r
-    movzwq  56(%rbp), %rax\r
-    pushq   %rax                      # for ss\r
-    movzwq  32(%rbp), %rax\r
-    pushq   %rax                      # for cs\r
-    movl    %ds, %eax\r
-    pushq   %rax\r
-    movl    %es, %eax\r
-    pushq   %rax\r
-    movl    %fs, %eax\r
-    pushq   %rax\r
-    movl    %gs, %eax\r
-    pushq   %rax\r
-\r
-    movq    %rcx, 8(%rbp)                # save vector number\r
-\r
-#; UINT64  Rip;\r
-    pushq   24(%rbp)\r
-\r
-#; UINT64  Gdtr[2], Idtr[2];\r
-    xorq    %rax, %rax\r
-    pushq   %rax\r
-    pushq   %rax\r
-    sidt    (%rsp)\r
-    xchgq   2(%rsp), %rax\r
-    xchgq   (%rsp), %rax\r
-    xchgq   8(%rsp), %rax\r
-\r
-    xorq    %rax, %rax\r
-    pushq   %rax\r
-    pushq   %rax\r
-    sgdt    (%rsp)\r
-    xchgq   2(%rsp), %rax\r
-    xchgq   (%rsp), %rax\r
-    xchgq   8(%rsp), %rax\r
-\r
-#; UINT64  Ldtr, Tr;\r
-    xorq    %rax, %rax\r
-    str     %ax\r
-    pushq   %rax\r
-    sldt    %ax\r
-    pushq   %rax\r
-\r
-#; UINT64  RFlags;\r
-    pushq   40(%rbp)\r
-\r
-#; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
-    movq    %cr8, %rax\r
-    pushq   %rax\r
-    movq    %cr4, %rax\r
-    orq     $0x208, %rax \r
-    movq    %rax, %cr4 \r
-    pushq   %rax\r
-    mov     %cr3, %rax \r
-    pushq   %rax\r
-    mov     %cr2, %rax \r
-    pushq   %rax\r
-    xorq    %rax, %rax\r
-    pushq   %rax\r
-    mov     %cr0, %rax \r
-    pushq   %rax\r
-\r
-#; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-    movq    %dr7, %rax\r
-    pushq   %rax\r
-    movq    %dr6, %rax\r
-    pushq   %rax\r
-    movq    %dr3, %rax\r
-    pushq   %rax\r
-    movq    %dr2, %rax\r
-    pushq   %rax\r
-    movq    %dr1, %rax\r
-    pushq   %rax\r
-    movq    %dr0, %rax\r
-    pushq   %rax\r
-\r
-#; FX_SAVE_STATE_X64 FxSaveState;\r
-    subq    $512, %rsp\r
-    movq    %rsp, %rdi\r
-    .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]\r
-\r
-#; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
-    cld\r
-\r
-#; UINT32  ExceptionData;\r
-    pushq   16(%rbp)\r
-\r
-#; call into exception handler\r
-    movq    8(%rbp), %rcx\r
-    leaq    ExternalVectorTablePtr(%rip), %rax\r
-    movl    (%eax), %eax\r
-    movq    (%rax,%rcx,8), %rax\r
-    orq     %rax, %rax                        # NULL?\r
-\r
-    je    nonNullValue#\r
-\r
-#; Prepare parameter and call\r
-#  mov     rcx, [rbp + 8]\r
-    mov     %rsp, %rdx\r
-    #\r
-    # Per X64 calling convention, allocate maximum parameter stack space\r
-    # and make sure RSP is 16-byte aligned\r
-    #\r
-    subq    $40, %rsp \r
-    call    *%rax\r
-    addq    $40, %rsp\r
-\r
-nonNullValue:\r
-    cli\r
-#; UINT64  ExceptionData;\r
-    addq    $8, %rsp\r
-\r
-#; FX_SAVE_STATE_X64 FxSaveState;\r
-\r
-    movq    %rsp, %rsi\r
-    .byte   0x0f, 0x0ae, 0x0E # fxrstor [rsi]\r
-    addq    $512, %rsp\r
-\r
-#; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-#; Skip restoration of DRx registers to support in-circuit emualators\r
-#; or debuggers set breakpoint in interrupt/exception context\r
-    addq    $48, %rsp\r
-\r
-#; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
-    popq    %rax\r
-    movq    %rax, %cr0\r
-    addq    $8, %rsp   # not for Cr1\r
-    popq    %rax\r
-    movq    %rax, %cr2\r
-    popq    %rax\r
-    movq    %rax, %cr3\r
-    popq    %rax\r
-    movq    %rax, %cr4\r
-    popq    %rax\r
-    movq    %rax, %cr8\r
-\r
-#; UINT64  RFlags;\r
-    popq    40(%rbp)\r
-\r
-#; UINT64  Ldtr, Tr;\r
-#; UINT64  Gdtr[2], Idtr[2];\r
-#; Best not let anyone mess with these particular registers...\r
-    addq    $48, %rsp\r
-\r
-#; UINT64  Rip;\r
-    popq    24(%rbp)\r
-\r
-#; UINT64  Gs, Fs, Es, Ds, Cs, Ss;\r
-    popq    %rax\r
-    # mov   %rax, %gs ; not for gs\r
-    popq    %rax\r
-    # mov   %rax, %fs ; not for fs\r
-    # (X64 will not use fs and gs, so we do not restore it)\r
-    popq    %rax\r
-    movl    %eax, %es\r
-    popq    %rax\r
-    movl    %eax, %ds\r
-    popq    32(%rbp)  # for cs\r
-    popq    56(%rbp)  # for ss\r
-\r
-#; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-#; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
-    popq    %rdi\r
-    popq    %rsi\r
-    addq    $8, %rsp              # not for rbp\r
-    popq    48(%rbp)              # for rsp\r
-    popq    %rbx\r
-    popq    %rdx\r
-    popq    %rcx\r
-    popq    %rax\r
-    popq    %r8\r
-    popq    %r9\r
-    popq    %r10\r
-    popq    %r11\r
-    popq    %r12\r
-    popq    %r13\r
-    popq    %r14\r
-    popq    %r15\r
-\r
-    movq    %rbp, %rsp\r
-    popq    %rbp\r
-    addq    $16, %rsp\r
-    iretq\r
-\r
-\r
 #text  ENDS\r
 \r
 #END\r
index 68fcd3f404657451a50caf5e0d5c99963a3e2867..c71b06a81e898be6c19f2bd23465418e01d7c724 100644 (file)
@@ -1,7 +1,7 @@
       TITLE   CpuAsm.asm: \r
 ;------------------------------------------------------------------------------\r
 ;*\r
-;*   Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+;*   Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>\r
 ;*   This program and the accompanying materials                          \r
 ;*   are licensed and made available under the terms and conditions of the BSD License         \r
 ;*   which accompanies this distribution.  The full text of the license may be found at        \r
 \r
     .code\r
 \r
-EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
-\r
-;\r
-; point to the external interrupt vector table\r
-;\r
-ExternalVectorTablePtr QWORD 0\r
-\r
-InitializeExternalVectorTablePtr PROC PUBLIC\r
-    mov  ExternalVectorTablePtr, rcx\r
-    ret\r
-InitializeExternalVectorTablePtr ENDP\r
-\r
 ;------------------------------------------------------------------------------\r
 ; VOID\r
 ; SetCodeSelector (\r
@@ -62,270 +50,5 @@ SetDataSelectors PROC PUBLIC
     ret\r
 SetDataSelectors ENDP\r
 \r
-;---------------------------------------;\r
-; CommonInterruptEntry                  ;\r
-;---------------------------------------;\r
-; The follow algorithm is used for the common interrupt routine.\r
-\r
-CommonInterruptEntry PROC PUBLIC  \r
-    cli\r
-    ;\r
-    ; All interrupt handlers are invoked through interrupt gates, so\r
-    ; IF flag automatically cleared at the entry point\r
-    ;\r
-    ;\r
-    ; Calculate vector number\r
-    ;\r
-    xchg    rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.\r
-    movzx   ecx, word ptr [rcx]\r
-    cmp     ecx, 32         ; Intel reserved vector for exceptions?\r
-    jae     NoErrorCode\r
-    bt      mErrorCodeFlag, ecx\r
-    jc      @F\r
-\r
-NoErrorCode:\r
-\r
-    ;\r
-    ; Push a dummy error code on the stack\r
-    ; to maintain coherent stack map\r
-    ;\r
-    push    [rsp]\r
-    mov     qword ptr [rsp + 8], 0\r
-@@:       \r
-    push    rbp\r
-    mov     rbp, rsp\r
-\r
-    ;\r
-    ; Stack:\r
-    ; +---------------------+ <-- 16-byte aligned ensured by processor\r
-    ; +    Old SS           +\r
-    ; +---------------------+\r
-    ; +    Old RSP          +\r
-    ; +---------------------+\r
-    ; +    RFlags           +\r
-    ; +---------------------+\r
-    ; +    CS               +\r
-    ; +---------------------+\r
-    ; +    RIP              +\r
-    ; +---------------------+\r
-    ; +    Error Code       +\r
-    ; +---------------------+\r
-    ; + RCX / Vector Number +\r
-    ; +---------------------+\r
-    ; +    RBP              +\r
-    ; +---------------------+ <-- RBP, 16-byte aligned\r
-    ;\r
-\r
-\r
-    ;\r
-    ; Since here the stack pointer is 16-byte aligned, so\r
-    ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
-    ; is 16-byte aligned\r
-    ;\r
-\r
-;; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
-    push r15\r
-    push r14\r
-    push r13\r
-    push r12\r
-    push r11\r
-    push r10\r
-    push r9\r
-    push r8\r
-    push rax\r
-    push qword ptr [rbp + 8]   ; RCX\r
-    push rdx\r
-    push rbx\r
-    push qword ptr [rbp + 48]  ; RSP\r
-    push qword ptr [rbp]       ; RBP\r
-    push rsi\r
-    push rdi\r
-\r
-;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero\r
-    movzx   rax, word ptr [rbp + 56]\r
-    push    rax                      ; for ss\r
-    movzx   rax, word ptr [rbp + 32]\r
-    push    rax                      ; for cs\r
-    mov     rax, ds\r
-    push    rax\r
-    mov     rax, es\r
-    push    rax\r
-    mov     rax, fs\r
-    push    rax\r
-    mov     rax, gs\r
-    push    rax\r
-\r
-    mov     [rbp + 8], rcx               ; save vector number\r
-\r
-;; UINT64  Rip;\r
-    push    qword ptr [rbp + 24]\r
-\r
-;; UINT64  Gdtr[2], Idtr[2];\r
-    xor     rax, rax\r
-    push    rax\r
-    push    rax\r
-    sidt    [rsp]\r
-    xchg    rax, [rsp + 2]\r
-    xchg    rax, [rsp]\r
-    xchg    rax, [rsp + 8]\r
-\r
-    xor     rax, rax\r
-    push    rax\r
-    push    rax\r
-    sgdt    [rsp]\r
-    xchg    rax, [rsp + 2]\r
-    xchg    rax, [rsp]\r
-    xchg    rax, [rsp + 8]\r
-\r
-;; UINT64  Ldtr, Tr;\r
-    xor     rax, rax\r
-    str     ax\r
-    push    rax\r
-    sldt    ax\r
-    push    rax\r
-\r
-;; UINT64  RFlags;\r
-    push    qword ptr [rbp + 40]\r
-\r
-;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
-    mov     rax, cr8\r
-    push    rax\r
-    mov     rax, cr4\r
-    or      rax, 208h\r
-    mov     cr4, rax\r
-    push    rax\r
-    mov     rax, cr3\r
-    push    rax\r
-    mov     rax, cr2\r
-    push    rax\r
-    xor     rax, rax\r
-    push    rax\r
-    mov     rax, cr0\r
-    push    rax\r
-\r
-;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-    mov     rax, dr7\r
-    push    rax\r
-    mov     rax, dr6\r
-    push    rax\r
-    mov     rax, dr3\r
-    push    rax\r
-    mov     rax, dr2\r
-    push    rax\r
-    mov     rax, dr1\r
-    push    rax\r
-    mov     rax, dr0\r
-    push    rax\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
-    sub rsp, 512\r
-    mov rdi, rsp\r
-    db 0fh, 0aeh, 07h ;fxsave [rdi]\r
-\r
-;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
-    cld\r
-\r
-;; UINT32  ExceptionData;\r
-    push    qword ptr [rbp + 16]\r
-\r
-;; call into exception handler\r
-    mov     rcx, [rbp + 8]\r
-    mov     rax, ExternalVectorTablePtr  ; get the interrupt vectors base\r
-    mov     rax, [rax + rcx * 8]       \r
-    or      rax, rax                        ; NULL?\r
-\r
-    je    nonNullValue;\r
-\r
-;; Prepare parameter and call\r
-;  mov     rcx, [rbp + 8]\r
-    mov     rdx, rsp\r
-    ;\r
-    ; Per X64 calling convention, allocate maximum parameter stack space\r
-    ; and make sure RSP is 16-byte aligned\r
-    ;\r
-    sub     rsp, 4 * 8 + 8\r
-    call    rax\r
-    add     rsp, 4 * 8 + 8\r
-\r
-nonNullValue:\r
-    cli\r
-;; UINT64  ExceptionData;\r
-    add     rsp, 8\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
-\r
-    mov rsi, rsp\r
-    db 0fh, 0aeh, 0Eh ; fxrstor [rsi]\r
-    add rsp, 512\r
-\r
-;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; Skip restoration of DRx registers to support in-circuit emualators\r
-;; or debuggers set breakpoint in interrupt/exception context\r
-    add     rsp, 8 * 6\r
-\r
-;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
-    pop     rax\r
-    mov     cr0, rax\r
-    add     rsp, 8   ; not for Cr1\r
-    pop     rax\r
-    mov     cr2, rax\r
-    pop     rax\r
-    mov     cr3, rax\r
-    pop     rax\r
-    mov     cr4, rax\r
-    pop     rax\r
-    mov     cr8, rax\r
-\r
-;; UINT64  RFlags;\r
-    pop     qword ptr [rbp + 40]\r
-\r
-;; UINT64  Ldtr, Tr;\r
-;; UINT64  Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
-    add     rsp, 48\r
-\r
-;; UINT64  Rip;\r
-    pop     qword ptr [rbp + 24]\r
-\r
-;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;\r
-    pop     rax\r
-    ; mov     gs, rax ; not for gs\r
-    pop     rax\r
-    ; mov     fs, rax ; not for fs\r
-    ; (X64 will not use fs and gs, so we do not restore it)\r
-    pop     rax\r
-    mov     es, rax\r
-    pop     rax\r
-    mov     ds, rax\r
-    pop     qword ptr [rbp + 32]  ; for cs\r
-    pop     qword ptr [rbp + 56]  ; for ss\r
-\r
-;; UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64  R8, R9, R10, R11, R12, R13, R14, R15;\r
-    pop     rdi\r
-    pop     rsi\r
-    add     rsp, 8               ; not for rbp\r
-    pop     qword ptr [rbp + 48] ; for rsp\r
-    pop     rbx\r
-    pop     rdx\r
-    pop     rcx\r
-    pop     rax\r
-    pop     r8\r
-    pop     r9\r
-    pop     r10\r
-    pop     r11\r
-    pop     r12\r
-    pop     r13\r
-    pop     r14\r
-    pop     r15\r
-\r
-    mov     rsp, rbp\r
-    pop     rbp\r
-    add     rsp, 16\r
-    iretq\r
-\r
-CommonInterruptEntry ENDP\r
-\r
 END\r
 \r
index b1c6923035a873e40e1f8235ff86b5bfd806358d..c075d5f168dde4b4e5f9a05de5f0804aedef44aa 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   CPU Exception Hanlder Library common functions.\r
 \r
-  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #include "CpuExceptionCommon.h"\r
 \r
 //\r
-// Error code flag indicating whether or not an error code will be \r
+// Error code flag indicating whether or not an error code will be\r
 // pushed on the stack if an exception occurs.\r
 //\r
 // 1 means an error code will be pushed, otherwise 0\r
 //\r
-UINT32 mErrorCodeFlag = 0x00027d00;\r
+CONST UINT32 mErrorCodeFlag             = 0x00027d00;\r
+RESERVED_VECTORS_DATA *mReservedVectors = NULL;\r
 \r
 //\r
 // Define the maximum message length \r
@@ -133,3 +134,35 @@ FindModuleImageBase (
   return Pe32Data;\r
 }\r
 \r
+/**\r
+  Read and save reserved vector information\r
+  \r
+  @param[in]  VectorInfo        Pointer to reserved vector list.\r
+  @param[out] ReservedVector    Pointer to reserved vector data buffer.\r
+  @param[in]  VectorCount       Vector number to be updated.\r
+  \r
+  @return EFI_SUCCESS           Read and save vector info successfully.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+ReadAndVerifyVectorInfo (\r
+  IN  EFI_VECTOR_HANDOFF_INFO       *VectorInfo,\r
+  OUT RESERVED_VECTORS_DATA         *ReservedVector,\r
+  IN  UINTN                         VectorCount\r
+  )\r
+{\r
+  while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) {\r
+    if (VectorInfo->Attribute > EFI_VECTOR_HANDOFF_HOOK_AFTER) {\r
+      //\r
+      // If vector attrubute is invalid\r
+      //\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    if (VectorInfo->VectorNumber < VectorCount) {\r
+      ReservedVector[VectorInfo->VectorNumber].Attribute = VectorInfo->Attribute;\r
+    }\r
+    VectorInfo ++;\r
+  }\r
+  return EFI_SUCCESS;\r
+}
\ No newline at end of file
index 66847eaae60239d84b5d5a4b0c459950f3c0b3f4..6b0ccfe73de28d69f22e4ff908a97c41b9c2d953 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Common header file for CPU Exception Handler Library.\r
 \r
-  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #ifndef _CPU_EXCEPTION_COMMON_H_\r
 #define _CPU_EXCEPTION_COMMON_H_\r
 \r
+#include <Ppi/VectorHandoffInfo.h>\r
+#include <Protocol/Cpu.h>\r
 #include <Library/BaseLib.h>\r
 #include <Library/SerialPortLib.h>\r
 #include <Library/PrintLib.h>\r
 #include <Library/LocalApicLib.h>\r
 #include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/ReportStatusCodeLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/SynchronizationLib.h>\r
+\r
+#define  CPU_EXCEPTION_NUM          32\r
+#define  CPU_INTERRUPT_NUM         256\r
+#define  HOOKAFTER_STUB_SIZE        16\r
+\r
+#include "ArchInterruptDefs.h"\r
 \r
-#define  CPU_EXCEPTION_NUM     32\r
 //\r
 // Record exception handler information\r
 //\r
 typedef struct {\r
   UINTN ExceptionStart;\r
   UINTN ExceptionStubHeaderSize;\r
+  UINTN HookAfterStubHeaderStart;\r
 } EXCEPTION_HANDLER_TEMPLATE_MAP;\r
 \r
-extern UINT32           mErrorCodeFlag;\r
-extern CONST UINTN      mImageAlignSize;\r
+extern CONST UINT32                mErrorCodeFlag;\r
+extern CONST UINTN                 mImageAlignSize;\r
+extern CONST UINTN                 mDoFarReturnFlag;\r
+extern RESERVED_VECTORS_DATA       *mReservedVectors;\r
 \r
 /**\r
   Return address map of exception handler template so that C code can generate\r
@@ -41,17 +54,33 @@ extern CONST UINTN      mImageAlignSize;
 **/\r
 VOID\r
 EFIAPI\r
-GetTemplateAddressMap (\r
+AsmGetTemplateAddressMap (\r
   OUT EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
   );\r
 \r
 /**\r
-  Internal function to setup CPU exception handlers.\r
+  Return address map of exception handler template so that C code can generate\r
+  exception tables.\r
+\r
+  @param IdtEntry          Pointer to IDT entry to be updated.\r
+  @param InterruptHandler  IDT handler value.\r
 \r
 **/\r
 VOID\r
-InternalSetupCpuExceptionHandlers (\r
-  VOID\r
+ArchUpdateIdtEntry (\r
+  IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry,\r
+  IN UINTN                           InterruptHandler\r
+  );\r
+\r
+/**\r
+  Read IDT handler value from IDT entry.\r
+\r
+  @param IdtEntry          Pointer to IDT entry to be read.\r
+\r
+**/\r
+UINTN\r
+ArchGetIdtHandler (\r
+  IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry\r
   );\r
 \r
 /**\r
@@ -92,8 +121,120 @@ FindModuleImageBase (
 **/\r
 VOID\r
 DumpCpuContent (\r
-  IN UINTN                InterruptType,\r
+  IN EFI_EXCEPTION_TYPE   ExceptionType,\r
   IN EFI_SYSTEM_CONTEXT   SystemContext\r
   );\r
 \r
+/**\r
+  Internal worker function to initialize exception handler.\r
+\r
+  @param[in]  VectorInfo    Pointer to reserved vector list.\r
+  \r
+  @retval EFI_SUCCESS           CPU Exception Entries have been successfully initialized \r
+                                with default exception handlers.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+  @retval EFI_UNSUPPORTED       This function is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeCpuExceptionHandlersWorker (\r
+  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
+  );\r
+\r
+/**\r
+  Registers a function to be called from the processor interrupt handler.\r
+\r
+  @param[in]  InterruptType     Defines which interrupt or exception to hook.\r
+  @param[in]  InterruptHandler  A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
+                                when a processor interrupt occurs. If this parameter is NULL, then the handler\r
+                                will be uninstalled.\r
+\r
+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.\r
+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was\r
+                                previously installed.\r
+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not\r
+                                previously installed.\r
+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported,\r
+                                or this function is not supported.\r
+*/\r
+EFI_STATUS\r
+RegisterCpuInterruptHandlerWorker (\r
+  IN EFI_EXCEPTION_TYPE            InterruptType,\r
+  IN EFI_CPU_INTERRUPT_HANDLER     InterruptHandler\r
+  );\r
+\r
+/**\r
+  Internal worker function to update IDT entries accordling to vector attributes.\r
+\r
+  @param[in] IdtTable       Pointer to IDT table.\r
+  @param[in] TemplateMap    Pointer to a buffer where the address map is returned.\r
+  @param[in] IdtEntryCount  IDT entries number to be updated.\r
+\r
+**/\r
+VOID\r
+UpdateIdtTable (\r
+  IN IA32_IDT_GATE_DESCRIPTOR        *IdtTable,\r
+  IN EXCEPTION_HANDLER_TEMPLATE_MAP  *TemplateMap,\r
+  IN UINTN                           IdtEntryCount\r
+  );\r
+\r
+/**\r
+  Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.\r
+\r
+  @param[in] ExceptionType  Exception type.\r
+  @param[in] SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+\r
+**/\r
+VOID\r
+ArchSaveExceptionContext (\r
+  IN UINTN                ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext \r
+  );\r
+\r
+/**\r
+  Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.\r
+\r
+  @param[in] ExceptionType  Exception type.\r
+  @param[in] SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+\r
+**/\r
+VOID\r
+ArchRestoreExceptionContext (\r
+  IN UINTN                ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext \r
+  );\r
+\r
+/**\r
+  Fix up the vector number in the vector code.\r
\r
+  @param[in] VectorBase   Base address of the vector handler.\r
+  @param[in] VectorNum    Index of vector.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmVectorNumFixup (\r
+  IN VOID    *VectorBase,\r
+  IN UINT8   VectorNum\r
+  );\r
+\r
+/**\r
+  Read and save reserved vector information\r
+  \r
+  @param[in]  VectorInfo        Pointer to reserved vector list.\r
+  @param[out] ReservedVector    Pointer to reserved vector data buffer.\r
+  @param[in]  VectorCount       Vector number to be updated.\r
+  \r
+  @return EFI_SUCCESS           Read and save vector info successfully.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+ReadAndVerifyVectorInfo (\r
+  IN  EFI_VECTOR_HANDOFF_INFO       *VectorInfo,\r
+  OUT RESERVED_VECTORS_DATA         *ReservedVector,\r
+  IN  UINTN                         VectorCount\r
+  );\r
+\r
 #endif\r
+\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
new file mode 100644 (file)
index 0000000..454307b
--- /dev/null
@@ -0,0 +1,66 @@
+## @file\r
+#  Component description file for DXE CPU Exception Handler Library instance.\r
+#\r
+#  This library instance supports DXE module only.\r
+#\r
+#  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  \r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = DxeCpuExceptionHandlerLib\r
+  FILE_GUID                      = B6E9835A-EDCF-4748-98A8-27D3C722E02D\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = CpuExceptionHandlerLib|DXE_CORE DXE_DRIVER UEFI_APPLICATION\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources.Ia32]\r
+  Ia32/ExceptionHandlerAsm.asm |MSFT\r
+  Ia32/ExceptionHandlerAsm.S   |GCC\r
+  Ia32/ArchExceptionHandler.c\r
+  Ia32/ArchInterruptDefs.h\r
+\r
+[Sources.X64]\r
+  X64/ExceptionHandlerAsm.asm   |MSFT\r
+  X64/ExceptionHandlerAsm.S     |GCC\r
+  X64/ArchExceptionHandler.c\r
+  X64/ArchInterruptDefs.h\r
+\r
+[Sources.common]\r
+  CpuExceptionCommon.h\r
+  CpuExceptionCommon.c\r
+  DxeSmmCpuException.c\r
+  DxeException.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  SerialPortLib\r
+  PrintLib\r
+  SynchronizationLib\r
+  LocalApicLib\r
+  PeCoffGetEntryPointLib \r
+  ReportStatusCodeLib\r
+  MemoryAllocationLib\r
+  DebugLib\r
+\r
+[Ppis]\r
+  gEfiVectorHandoffInfoPpiGuid\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeException.c
new file mode 100644 (file)
index 0000000..b4b844c
--- /dev/null
@@ -0,0 +1,170 @@
+/** @file\r
+  CPU exception handler library implemenation for DXE modules.\r
+\r
+  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+#include "CpuExceptionCommon.h"\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+CONST UINTN    mDoFarReturnFlag  = 0;\r
+\r
+extern SPIN_LOCK                   mDisplayMessageSpinLock;\r
+extern EFI_CPU_INTERRUPT_HANDLER   *mExternalInterruptHandler;\r
+\r
+/**\r
+  Initializes all CPU exceptions entries and provides the default exception handlers.\r
+  \r
+  Caller should try to get an array of interrupt and/or exception vectors that are in use and need to\r
+  persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.\r
+  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. \r
+  If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.\r
+\r
+  @param[in]  VectorInfo    Pointer to reserved vector list.\r
+  \r
+  @retval EFI_SUCCESS           CPU Exception Entries have been successfully initialized \r
+                                with default exception handlers.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+  @retval EFI_UNSUPPORTED       This function is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeCpuExceptionHandlers (\r
+  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
+  )\r
+{\r
+  return InitializeCpuExceptionHandlersWorker (VectorInfo);\r
+}\r
+\r
+/**\r
+  Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.\r
+  \r
+  Caller should try to get an array of interrupt and/or exception vectors that are in use and need to\r
+  persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.\r
+  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. \r
+  If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.\r
+\r
+  @param[in]  VectorInfo    Pointer to reserved vector list.\r
+  \r
+  @retval EFI_SUCCESS           All CPU interrupt/exception entries have been successfully initialized \r
+                                with default interrupt/exception handlers.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+  @retval EFI_UNSUPPORTED       This function is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeCpuInterruptHandlers (\r
+  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                         Status;\r
+  IA32_IDT_GATE_DESCRIPTOR           *IdtTable;\r
+  IA32_DESCRIPTOR                    IdtDescriptor;\r
+  UINTN                              IdtEntryCount;\r
+  EXCEPTION_HANDLER_TEMPLATE_MAP     TemplateMap;\r
+  UINTN                              Index;\r
+  UINTN                              InterruptEntry;\r
+  UINT8                              *InterruptEntryCode;\r
+\r
+  mReservedVectors = AllocatePool (sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM);\r
+  ASSERT (mReservedVectors != NULL);\r
+  SetMem ((VOID *) mReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_INTERRUPT_NUM, 0xff);\r
+  if (VectorInfo != NULL) {\r
+    Status = ReadAndVerifyVectorInfo (VectorInfo, mReservedVectors, CPU_INTERRUPT_NUM);\r
+    if (EFI_ERROR (Status)) {\r
+      FreePool (mReservedVectors);\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  InitializeSpinLock (&mDisplayMessageSpinLock);\r
+  mExternalInterruptHandler = AllocateZeroPool (sizeof (EFI_CPU_INTERRUPT_HANDLER) * CPU_INTERRUPT_NUM);\r
+  ASSERT (mExternalInterruptHandler != NULL);\r
+\r
+  //\r
+  // Read IDT descriptor and calculate IDT size\r
+  //\r
+  AsmReadIdtr (&IdtDescriptor);\r
+  IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);\r
+  if (IdtEntryCount > CPU_INTERRUPT_NUM) {\r
+    IdtEntryCount = CPU_INTERRUPT_NUM;\r
+  }\r
+  //\r
+  // Create Interrupt Descriptor Table and Copy the old IDT table in\r
+  //\r
+  IdtTable = AllocateZeroPool (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM);\r
+  ASSERT (IdtTable != NULL);\r
+  CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount);\r
+\r
+  AsmGetTemplateAddressMap (&TemplateMap);\r
+  ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE);\r
+  InterruptEntryCode = AllocatePool (TemplateMap.ExceptionStubHeaderSize * CPU_INTERRUPT_NUM);\r
+  ASSERT (InterruptEntryCode != NULL);\r
+  \r
+  InterruptEntry = (UINTN) InterruptEntryCode;\r
+  for (Index = 0; Index < CPU_INTERRUPT_NUM; Index ++) {\r
+    CopyMem (\r
+      (VOID *) InterruptEntry,\r
+      (VOID *) TemplateMap.ExceptionStart,\r
+      TemplateMap.ExceptionStubHeaderSize\r
+      );\r
+    AsmVectorNumFixup ((VOID *) InterruptEntry, (UINT8) Index);\r
+    InterruptEntry += TemplateMap.ExceptionStubHeaderSize;\r
+  }\r
+\r
+  TemplateMap.ExceptionStart = (UINTN) InterruptEntryCode;\r
+  UpdateIdtTable (IdtTable, &TemplateMap, CPU_INTERRUPT_NUM);\r
+\r
+  //\r
+  // Load Interrupt Descriptor Table\r
+  //\r
+  IdtDescriptor.Base  = (UINTN) IdtTable;\r
+  IdtDescriptor.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1);\r
+  AsmWriteIdtr ((IA32_DESCRIPTOR *) &IdtDescriptor);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Registers a function to be called from the processor interrupt handler.\r
+\r
+  This function registers and enables the handler specified by InterruptHandler for a processor \r
+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the \r
+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled. \r
+  The installed handler is called once for each processor interrupt or exception.\r
+  NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or\r
+  InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.\r
+\r
+  @param[in]  InterruptType     Defines which interrupt or exception to hook.\r
+  @param[in]  InterruptHandler  A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
+                                when a processor interrupt occurs. If this parameter is NULL, then the handler\r
+                                will be uninstalled.\r
+\r
+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.\r
+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was\r
+                                previously installed.\r
+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not\r
+                                previously installed.\r
+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported,\r
+                                or this function is not supported.\r
+*/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterCpuInterruptHandler (\r
+  IN EFI_EXCEPTION_TYPE            InterruptType,\r
+  IN EFI_CPU_INTERRUPT_HANDLER     InterruptHandler\r
+  )\r
+{\r
+  return RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler);\r
+}\r
index 682def43be172ce54db2ef6e9f1652da73d4f20b..aed5cf8128a949c5c3519783ff5777893b26ef45 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
-  CPU Exception Library provides DXE/SMM CPU exception handler.\r
+  CPU Exception Library provides DXE/SMM CPU common exception handler.\r
 \r
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed and made available under\r
 the terms and conditions of the BSD License that accompanies this distribution.\r
 The full text of the license may be found at\r
@@ -12,10 +12,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 **/\r
 \r
-#include <PiDxe.h>\r
-\r
 #include "CpuExceptionCommon.h"\r
-#include <Library/SynchronizationLib.h>\r
+#include <Library/DebugLib.h>\r
 \r
 //\r
 // Spinlock for CPU information display\r
@@ -27,6 +25,11 @@ SPIN_LOCK        mDisplayMessageSpinLock;
 //\r
 CONST UINTN      mImageAlignSize = SIZE_4KB;\r
 \r
+RESERVED_VECTORS_DATA       mReservedVectorsData[CPU_EXCEPTION_NUM];\r
+EFI_CPU_INTERRUPT_HANDLER   mExternalInterruptHandlerTable[CPU_EXCEPTION_NUM];\r
+EFI_CPU_INTERRUPT_HANDLER   *mExternalInterruptHandler = NULL;\r
+UINTN                       mEnabledInterruptNum = 0;\r
+\r
 /**\r
   Common exception handler.\r
 \r
@@ -36,49 +39,250 @@ CONST UINTN      mImageAlignSize = SIZE_4KB;
 VOID\r
 EFIAPI\r
 CommonExceptionHandler (\r
-  IN EFI_EXCEPTION_TYPE   ExceptionType, \r
-  IN EFI_SYSTEM_CONTEXT   SystemContext\r
+  IN EFI_EXCEPTION_TYPE          ExceptionType, \r
+  IN EFI_SYSTEM_CONTEXT          SystemContext\r
   )\r
 {\r
-  //\r
-  // Get Spinlock to display CPU information\r
-  //\r
-  while (!AcquireSpinLockOrFail (&mDisplayMessageSpinLock)) {\r
-    CpuPause ();\r
+  EXCEPTION_HANDLER_CONTEXT      *ExceptionHandlerContext;\r
+\r
+  ExceptionHandlerContext = (EXCEPTION_HANDLER_CONTEXT *) (UINTN) (SystemContext.SystemContextIa32);\r
+\r
+  switch (mReservedVectors[ExceptionType].Attribute) {\r
+  case EFI_VECTOR_HANDOFF_HOOK_BEFORE:\r
+    //\r
+    // Need to jmp to old IDT handler after this exception handler\r
+    //\r
+    ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;\r
+    ExceptionHandlerContext->OldIdtHandler     = mReservedVectors[ExceptionType].ExceptonHandler;\r
+    break;\r
+  case EFI_VECTOR_HANDOFF_HOOK_AFTER:\r
+    while (TRUE) {\r
+      //\r
+      // If if anyone has gotten SPIN_LOCK for owner running hook after\r
+      //\r
+      if (AcquireSpinLockOrFail (&mReservedVectors[ExceptionType].SpinLock)) {\r
+        //\r
+        // Need to execute old IDT handler before running this exception handler\r
+        //\r
+        mReservedVectors[ExceptionType].ApicId = GetApicId ();\r
+        ArchSaveExceptionContext (ExceptionType, SystemContext);\r
+        ExceptionHandlerContext->ExceptionDataFlag = (mErrorCodeFlag & (1 << ExceptionType)) ? TRUE : FALSE;\r
+        ExceptionHandlerContext->OldIdtHandler     = mReservedVectors[ExceptionType].ExceptonHandler;\r
+        return;\r
+      }\r
+      //\r
+      // If failed to acquire SPIN_LOCK, check if it was locked by processor itself\r
+      //\r
+      if (mReservedVectors[ExceptionType].ApicId == GetApicId ()) {\r
+        //\r
+        // Old IDT handler has been executed, then retore CPU exception content to\r
+        // run new exception handler.\r
+        //\r
+        ArchRestoreExceptionContext (ExceptionType, SystemContext);\r
+        //\r
+        // Rlease spin lock for ApicId\r
+        //\r
+        ReleaseSpinLock (&mReservedVectors[ExceptionType].SpinLock);\r
+        break;\r
+      }\r
+      CpuPause ();\r
+    }\r
+    break;\r
+  case 0xffffffff:\r
+    break;\r
+  default:\r
+    //\r
+    // It should never reach here\r
+    //\r
+    CpuDeadLoop ();\r
+    break;\r
   }\r
+  \r
+  if (mExternalInterruptHandler[ExceptionType] != NULL) {\r
+    (mExternalInterruptHandler[ExceptionType]) (ExceptionType, SystemContext);\r
+  } else {\r
+    //\r
+    // Get Spinlock to display CPU information\r
+    //\r
+    while (!AcquireSpinLockOrFail (&mDisplayMessageSpinLock)) {\r
+      CpuPause ();\r
+    }\r
+    //\r
+    // Display ExceptionType, CPU information and Image information\r
+    //  \r
+    DumpCpuContent (ExceptionType, SystemContext);\r
+    //\r
+    // Release Spinlock of output message\r
+    //\r
+    ReleaseSpinLock (&mDisplayMessageSpinLock);\r
+    //\r
+    // Enter a dead loop if needn't to execute old IDT handler further\r
+    //\r
+    if (mReservedVectors[ExceptionType].Attribute != EFI_VECTOR_HANDOFF_HOOK_BEFORE) {\r
+      CpuDeadLoop ();\r
+    }\r
+  }\r
+}\r
 \r
-  //\r
-  // Display ExceptionType, CPU information and Image information\r
-  //\r
-  DumpCpuContent (ExceptionType, SystemContext);\r
+/**\r
+  Internal worker function to update IDT entries accordling to vector attributes.\r
+\r
+  @param[in] IdtTable       Pointer to IDT table.\r
+  @param[in] TemplateMap    Pointer to a buffer where the address map is returned.\r
+  @param[in] IdtEntryCount  IDT entries number to be updated.\r
+\r
+**/\r
+VOID\r
+UpdateIdtTable (\r
+  IN IA32_IDT_GATE_DESCRIPTOR        *IdtTable,\r
+  IN EXCEPTION_HANDLER_TEMPLATE_MAP  *TemplateMap,\r
+  IN UINTN                           IdtEntryCount\r
+  )\r
+{\r
+  UINT16                             CodeSegment;\r
+  UINTN                              Index;\r
+  UINTN                              InterruptHandler;\r
 \r
   //\r
-  // Release Spinlock\r
+  // Use current CS as the segment selector of interrupt gate in IDT\r
   //\r
-  ReleaseSpinLock (&mDisplayMessageSpinLock);\r
+  CodeSegment = AsmReadCs ();\r
 \r
+  for (Index = 0; Index < IdtEntryCount; Index ++) {\r
+    IdtTable[Index].Bits.Selector = CodeSegment;\r
+    //\r
+    // Check reserved vectors attributes\r
+    //\r
+    switch (mReservedVectors[Index].Attribute) {\r
+    case EFI_VECTOR_HANDOFF_DO_NOT_HOOK:\r
+      //\r
+      // Keep original IDT entry\r
+      //\r
+      continue;\r
+    case EFI_VECTOR_HANDOFF_HOOK_AFTER:\r
+      InitializeSpinLock (&mReservedVectors[Index].SpinLock);\r
+      CopyMem (\r
+        (VOID *) mReservedVectors[Index].HookAfterStubHeaderCode,\r
+        (VOID *) TemplateMap->HookAfterStubHeaderStart,\r
+        TemplateMap->ExceptionStubHeaderSize\r
+        );\r
+      AsmVectorNumFixup ((VOID *) mReservedVectors[Index].HookAfterStubHeaderCode, (UINT8) Index);\r
+      //\r
+      // Go on the following code\r
+      //\r
+    case EFI_VECTOR_HANDOFF_HOOK_BEFORE:\r
+      //\r
+      // Save original IDT handler address\r
+      //\r
+      mReservedVectors[Index].ExceptonHandler = ArchGetIdtHandler (&IdtTable[Index]);\r
+      //\r
+      // Go on the following code\r
+      //\r
+    default:\r
+      //\r
+      // Update new IDT entry\r
+      //\r
+      InterruptHandler = TemplateMap->ExceptionStart + Index * TemplateMap->ExceptionStubHeaderSize;\r
+      ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler);\r
+      break;\r
+    }\r
+  }\r
\r
   //\r
-  // Enter a dead loop.\r
+  // Save Interrupt number to global variable used for RegisterCpuInterruptHandler ()\r
   //\r
-  CpuDeadLoop ();\r
+  mEnabledInterruptNum = IdtEntryCount;\r
 }\r
 \r
 /**\r
-  Setup CPU exception handlers.\r
+  Internal worker function to initialize exception handler.\r
 \r
-  This API will setups the CPU exception handler to display CPU contents and run into\r
-  CpuDeadLoop(). \r
-  Note: Before invoking this API, caller must allocate memory for IDT table and load \r
-        IDTR by AsmWriteIdtr().\r
+  @param[in]  VectorInfo    Pointer to reserved vector list.\r
   \r
+  @retval EFI_SUCCESS           CPU Exception Entries have been successfully initialized \r
+                                with default exception handlers.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+  @retval EFI_UNSUPPORTED       This function is not supported.\r
+\r
 **/\r
-VOID\r
-EFIAPI\r
-SetupCpuExceptionHandlers (\r
-  IN VOID\r
+EFI_STATUS\r
+InitializeCpuExceptionHandlersWorker (\r
+  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
   )\r
 {\r
+  EFI_STATUS                       Status;\r
+  IA32_DESCRIPTOR                  IdtDescriptor;\r
+  UINTN                            IdtEntryCount;\r
+  EXCEPTION_HANDLER_TEMPLATE_MAP   TemplateMap;\r
+  IA32_IDT_GATE_DESCRIPTOR         *IdtTable;\r
+\r
+  mReservedVectors = mReservedVectorsData;\r
+  SetMem ((VOID *) mReservedVectors, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);\r
+  if (VectorInfo != NULL) {\r
+    Status = ReadAndVerifyVectorInfo (VectorInfo, mReservedVectors, CPU_EXCEPTION_NUM);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
   InitializeSpinLock (&mDisplayMessageSpinLock);\r
-  InternalSetupCpuExceptionHandlers ();\r
+\r
+  mExternalInterruptHandler = mExternalInterruptHandlerTable;\r
+  //\r
+  // Read IDT descriptor and calculate IDT size\r
+  //\r
+  AsmReadIdtr (&IdtDescriptor);\r
+  IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);\r
+  if (IdtEntryCount > CPU_EXCEPTION_NUM) {\r
+    //\r
+    // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most\r
+    //\r
+    IdtEntryCount = CPU_EXCEPTION_NUM;\r
+  }\r
+\r
+  IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
+  AsmGetTemplateAddressMap (&TemplateMap);\r
+  ASSERT (TemplateMap.ExceptionStubHeaderSize <= HOOKAFTER_STUB_SIZE);\r
+  UpdateIdtTable (IdtTable, &TemplateMap, IdtEntryCount);\r
+  mEnabledInterruptNum = IdtEntryCount;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Registers a function to be called from the processor interrupt handler.\r
+\r
+  @param[in]  InterruptType     Defines which interrupt or exception to hook.\r
+  @param[in]  InterruptHandler  A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
+                                when a processor interrupt occurs. If this parameter is NULL, then the handler\r
+                                will be uninstalled.\r
+\r
+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.\r
+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was\r
+                                previously installed.\r
+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not\r
+                                previously installed.\r
+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported,\r
+                                or this function is not supported.\r
+*/\r
+EFI_STATUS\r
+RegisterCpuInterruptHandlerWorker (\r
+  IN EFI_EXCEPTION_TYPE            InterruptType,\r
+  IN EFI_CPU_INTERRUPT_HANDLER     InterruptHandler\r
+  )\r
+{\r
+  if (InterruptType < 0 || InterruptType > (EFI_EXCEPTION_TYPE)mEnabledInterruptNum ||\r
+      mReservedVectors[InterruptType].Attribute == EFI_VECTOR_HANDOFF_DO_NOT_HOOK) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  if (InterruptHandler == NULL && mExternalInterruptHandler[InterruptType] == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (InterruptHandler != NULL && mExternalInterruptHandler[InterruptType] != NULL) {\r
+    return EFI_ALREADY_STARTED;\r
+  }\r
+\r
+  mExternalInterruptHandler[InterruptType] = InterruptHandler;\r
+  return EFI_SUCCESS;\r
 }\r
 \r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf
deleted file mode 100644 (file)
index 9f0f2d9..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-## @file\r
-#  Component description file for DXE/SMM CPU Exception Handler Library instance.\r
-#\r
-#  This library instance supports DXE SMM module only.\r
-#\r
-#  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
-#  This program and the accompanying materials\r
-#  are licensed and made available under the terms and conditions of the BSD License\r
-#  which accompanies this distribution.  The full text of the license may be found at\r
-#  http://opensource.org/licenses/bsd-license.php\r
-#  \r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-#  \r
-##\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = DxeSmmCpuExceptionHandlerLib\r
-  FILE_GUID                      = EC629480-BD36-4e8e-8AB2-D28BF0D45864\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = CpuExceptionHandlerLib|DXE_CORE DXE_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64\r
-#\r
-\r
-[Sources.Ia32]\r
-  Ia32/ExceptionHandlerAsm.asm |MSFT\r
-  Ia32/ExceptionHandlerAsm.S   |GCC\r
-  Ia32/ArchExceptionHandler.c\r
-\r
-[Sources.X64]\r
-  X64/ExceptionHandlerAsm.asm   |MSFT\r
-  X64/ExceptionHandlerAsm.S     |GCC\r
-  X64/ArchExceptionHandler.c\r
-\r
-[Sources.common]\r
-  CpuExceptionCommon.h\r
-  CpuExceptionCommon.c\r
-  DxeSmmCpuException.c\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  MdeModulePkg/MdeModulePkg.dec\r
-  UefiCpuPkg/UefiCpuPkg.dec\r
-\r
-[LibraryClasses]\r
-  BaseLib\r
-  SerialPortLib\r
-  PrintLib\r
-  SynchronizationLib\r
-  LocalApicLib\r
-  PeCoffGetEntryPointLib \r
index a69f0d3d2bd0f70daba4442177dab7b49fb7fcd0..ba2cc6f227eb554fda36d6864204212070977aa3 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   IA32 CPU Exception Hanlder functons.\r
 \r
-  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #include "CpuExceptionCommon.h"\r
 \r
 /**\r
-  Internal function to setup CPU exception handlers.\r
+  Return address map of exception handler template so that C code can generate\r
+  exception tables.\r
+\r
+  @param IdtEntry          Pointer to IDT entry to be updated.\r
+  @param InterruptHandler  IDT handler value.\r
 \r
 **/\r
 VOID\r
-InternalSetupCpuExceptionHandlers (\r
-  VOID\r
+ArchUpdateIdtEntry (\r
+  IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry,\r
+  IN UINTN                           InterruptHandler\r
+  )\r
+{\r
+  IdtEntry->Bits.OffsetLow   = (UINT16)(UINTN)InterruptHandler;\r
+  IdtEntry->Bits.OffsetHigh  = (UINT16)((UINTN)InterruptHandler >> 16);\r
+  IdtEntry->Bits.GateType    = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
+}\r
+\r
+/**\r
+  Read IDT handler value from IDT entry.\r
+\r
+  @param IdtEntry          Pointer to IDT entry to be read.\r
+\r
+**/\r
+UINTN\r
+ArchGetIdtHandler (\r
+  IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry\r
   )\r
 {\r
-  IA32_DESCRIPTOR                     IdtDescriptor;\r
-  UINTN                               IdtSize;\r
-  EXCEPTION_HANDLER_TEMPLATE_MAP      TemplateMap;\r
-  UINT16                              CodeSegment;\r
-  IA32_IDT_GATE_DESCRIPTOR            *IdtEntry;\r
-  UINTN                               Index;\r
-  UINTN                               InterruptHandler;;\r
+  return (UINTN)IdtEntry->Bits.OffsetLow + (((UINTN)IdtEntry->Bits.OffsetHigh) << 16);\r
+}\r
+\r
+/**\r
+  Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.\r
 \r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+\r
+**/\r
+VOID\r
+ArchSaveExceptionContext (\r
+  IN UINTN                ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext \r
+  )\r
+{\r
+  IA32_EFLAGS32           Eflags;\r
   //\r
-  // Read IDT descriptor and calculate IDT size\r
+  // Save Exception context in global variable\r
   //\r
-  AsmReadIdtr (&IdtDescriptor);\r
-  IdtSize = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);\r
-  if (IdtSize > CPU_EXCEPTION_NUM) {\r
-    //\r
-    // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most\r
-    //\r
-    IdtSize = CPU_EXCEPTION_NUM;\r
-  }\r
-\r
+  mReservedVectors[ExceptionType].OldFlags      = SystemContext.SystemContextIa32->Eflags;\r
+  mReservedVectors[ExceptionType].OldCs         = SystemContext.SystemContextIa32->Cs;\r
+  mReservedVectors[ExceptionType].OldIp         = SystemContext.SystemContextIa32->Eip;\r
+  mReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextIa32->ExceptionData;\r
+  //\r
+  // Clear IF flag to avoid old IDT handler enable interrupt by IRET\r
   //\r
-  // Use current CS as the segment selector of interrupt gate in IDT\r
+  Eflags.UintN = SystemContext.SystemContextIa32->Eflags;\r
+  Eflags.Bits.IF = 0; \r
+  SystemContext.SystemContextIa32->Eflags = Eflags.UintN;\r
   //\r
-  CodeSegment = AsmReadCs ();\r
-  IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
+  // Modify the EIP in stack, then old IDT handler will return to the stub code\r
+  //\r
+  SystemContext.SystemContextIa32->Eip    = (UINTN) mReservedVectors[ExceptionType].HookAfterStubHeaderCode;\r
+}\r
 \r
-  GetTemplateAddressMap (&TemplateMap);\r
+/**\r
+  Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.\r
 \r
-  for (Index = 0; Index < IdtSize; Index ++) {\r
-    InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;\r
-    IdtEntry[Index].Bits.OffsetLow  = (UINT16)(UINTN)InterruptHandler;\r
-    IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);\r
-    IdtEntry[Index].Bits.Selector   = CodeSegment;\r
-    IdtEntry[Index].Bits.GateType   = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
-  }\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+ArchRestoreExceptionContext (\r
+  IN UINTN                ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext \r
+  )\r
+{\r
+  SystemContext.SystemContextIa32->Eflags        = mReservedVectors[ExceptionType].OldFlags;\r
+  SystemContext.SystemContextIa32->Cs            = mReservedVectors[ExceptionType].OldCs;\r
+  SystemContext.SystemContextIa32->Eip           = mReservedVectors[ExceptionType].OldIp;\r
+  SystemContext.SystemContextIa32->ExceptionData = mReservedVectors[ExceptionType].ExceptionData;\r
 }\r
 \r
 /**\r
@@ -68,7 +106,7 @@ InternalSetupCpuExceptionHandlers (
 **/\r
 VOID\r
 DumpCpuContent (\r
-  IN UINTN                ExceptionType,\r
+  IN EFI_EXCEPTION_TYPE   ExceptionType,\r
   IN EFI_SYSTEM_CONTEXT   SystemContext\r
   )\r
 {\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ArchInterruptDefs.h
new file mode 100644 (file)
index 0000000..a8d3556
--- /dev/null
@@ -0,0 +1,44 @@
+/** @file\r
+  Ia32 arch definition for CPU Exception Handler Library.\r
+\r
+  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _ARCH_CPU_INTERRUPT_DEFS_H_\r
+#define _ARCH_CPU_INTERRUPT_DEFS_H_\r
+\r
+typedef struct {\r
+  EFI_SYSTEM_CONTEXT_IA32 SystemContext;\r
+  BOOLEAN                 ExceptionDataFlag;\r
+  UINTN                   OldIdtHandler;\r
+} EXCEPTION_HANDLER_CONTEXT;\r
+\r
+//\r
+// Register Structure Definitions\r
+//\r
+typedef struct {\r
+  EFI_STATUS_CODE_DATA      Header;\r
+  EFI_SYSTEM_CONTEXT_IA32   SystemContext;\r
+} CPU_STATUS_CODE_TEMPLATE;\r
+\r
+typedef struct {\r
+  SPIN_LOCK   SpinLock;\r
+  UINT32      ApicId;\r
+  UINT32      Attribute;\r
+  UINTN       ExceptonHandler;\r
+  UINTN       OldFlags;\r
+  UINTN       OldCs;\r
+  UINTN       OldIp;\r
+  UINTN       ExceptionData;\r
+  UINT8       HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE];\r
+} RESERVED_VECTORS_DATA;\r
+\r
+#endif\r
index b9e881ac5e5d8fe8b28179287b23a1e9fbfdd462..92c8dcafd47dfaf178a3d4e96a916d81e653c5ec 100644 (file)
@@ -1,6 +1,6 @@
 #------------------------------------------------------------------------------\r
 #*\r
-#*   Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+#*   Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
 #*   This program and the accompanying materials\r
 #*   are licensed and made available under the terms and conditions of the BSD License\r
 #*   which accompanies this distribution.  The full text of the license may be found at\r
 #------------------------------------------------------------------------------\r
 \r
 \r
-\r
-\r
-\r
 #.MMX\r
 #.XMM\r
 \r
 ASM_GLOBAL ASM_PFX(CommonExceptionHandler)\r
 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+ASM_GLOBAL ASM_PFX(HookAfterStubEnd)\r
 \r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD           # Error code flags for exceptions\r
+#EXTRN ASM_PFX(mDoFarReturnFlag):DWORD         # Do far return flag\r
 \r
 .text\r
 \r
@@ -35,101 +34,250 @@ ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
 # exception handler stub table\r
 #\r
 Exception0Handle:\r
-    pushl   $0\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   0\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception1Handle:\r
-    pushl   $1\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   1\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception2Handle:\r
-    pushl   $2\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   2\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception3Handle:\r
-    pushl    $3\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   3\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception4Handle:\r
-    pushl    $4\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   4\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception5Handle:\r
-    pushl    $5\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   5\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception6Handle:\r
-    pushl    $6\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   6\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception7Handle:\r
-    pushl    $7\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   7\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception8Handle:\r
-    pushl    $8\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   8\r
+    pushl   %eax\r
+     .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception9Handle:\r
-    pushl    $9\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   9\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception10Handle:\r
-    pushl    $10\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   10\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception11Handle:\r
-    pushl    $11\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   11\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception12Handle:\r
-    pushl    $12\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   12\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception13Handle:\r
-    pushl    $13\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   13\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception14Handle:\r
-    pushl    $14\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   14\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception15Handle:\r
-    pushl    $15\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   15\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception16Handle:\r
-    pushl    $16\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   16\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception17Handle:\r
-    pushl    $17\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   17\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception18Handle:\r
-    pushl    $18\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   18\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception19Handle:\r
-    pushl    $19\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   19\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception20Handle:\r
-    pushl    $20\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   20\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception21Handle:\r
-    pushl    $21\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   21\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception22Handle:\r
-    pushl    $22\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   22\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception23Handle:\r
-    pushl    $23\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   23\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception24Handle:\r
-    pushl    $24\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   24\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception25Handle:\r
-    pushl    $25\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   25\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception26Handle:\r
-    pushl    $26\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   26\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception27Handle:\r
-    pushl    $27\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   27\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception28Handle:\r
-    pushl    $28\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   28\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception29Handle:\r
-    pushl    $29\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   29\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception30Handle:\r
-    pushl    $30\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   30\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
 Exception31Handle:\r
-    pushl    $31\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   31\r
+    pushl   %eax\r
+    .byte   0xB8\r
+    .long   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%eax\r
+\r
+HookAfterStubBegin:\r
+    .byte   0x6a       # push\r
+VectorNum:\r
+    .byte   0          # 0 will be fixed\r
+    pushl   %eax\r
+    .byte   0xB8       # movl    ASM_PFX(HookAfterStubHeaderEnd), %eax\r
+    .long   ASM_PFX(HookAfterStubHeaderEnd)\r
+    jmp     *%eax\r
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
+HookAfterStubHeaderEnd:\r
+    popl    %eax\r
+    subl    $8, %esp        # reserve room for filling exception data later\r
+    pushl   8(%esp)\r
+    xchgl   (%esp), %ecx    # get vector number\r
+    bt      %ecx, ASM_PFX(mErrorCodeFlag)\r
+    jnc     NoErrorData\r
+    pushl    (%esp)         # addition push if exception data needed\r
+NoErrorData:\r
+    xchg    (%esp), %ecx    # restore ecx\r
+    pushl   %eax\r
 \r
 #---------------------------------------;\r
 # CommonInterruptEntry                  ;\r
@@ -139,19 +287,17 @@ Exception31Handle:
 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
 ASM_PFX(CommonInterruptEntry):\r
     cli\r
+    popl    %eax\r
     #\r
     # All interrupt handlers are invoked through interrupt gates, so\r
     # IF flag automatically cleared at the entry point\r
     #\r
 \r
     #\r
-    # Calculate vector number\r
-    #\r
-    # Get the return address of call, actually, it is the\r
-    # address of vector number.\r
+    # Get vector number from top of stack\r
     #\r
     xchgl   (%esp), %ecx\r
-    andl    $0x0FFFF, %ecx\r
+    andl    $0x0FF, %ecx      # Vector number should be less than 256\r
     cmpl    $32, %ecx         # Intel reserved vector for exceptions?\r
     jae     NoErrorCode\r
     bt      %ecx, ASM_PFX(mErrorCodeFlag)\r
@@ -241,6 +387,10 @@ ErrorCodeAndVectorOnStack:
     andl    $0x0fffffff0, %esp \r
     subl    $12, %esp\r
 \r
+    subl    $8, %esp\r
+    pushl   $0         # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    pushl   $0         # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+       \r
 #; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
     pushl   %eax\r
     pushl   %ecx\r
@@ -405,18 +555,41 @@ ErrorCodeAndVectorOnStack:
     popl    %ecx\r
     popl    %eax\r
 \r
+    popl    -8(%ebp)\r
+    popl    -4(%ebp)\r
     movl    %ebp, %esp\r
     popl    %ebp\r
     addl    $8, %esp\r
+    cmpl    $0, -16(%esp)  # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    jz      DoReturn\r
+    cmpl    $1, -20(%esp)  # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+    jz      ErrorCode\r
+    jmp     *-16(%esp)\r
+ErrorCode:\r
+    subl    $4, %esp\r
+    jmp     *-12(%esp)\r
+\r
+DoReturn:\r
+    cmpl    $0, ASM_PFX(mDoFarReturnFlag)\r
+    jz      DoIret\r
+    pushl   8(%esp)       # save EFLAGS\r
+    addl    $16, %esp\r
+    pushl   -8(%esp)      # save CS in new location\r
+    pushl   -8(%esp)      # save EIP in new location\r
+    pushl   -8(%esp)      # save EFLAGS in new location\r
+    popfl                 # restore EFLAGS\r
+    retf                  # far return\r
+\r
+DoIret:\r
     iretl\r
 \r
 \r
 #---------------------------------------;\r
-# _GetTemplateAddressMap                  ;\r
-#----------------------------------------------------------------------------;\r
+# _AsmGetTemplateAddressMap             ;\r
+#---------------------------------------;\r
 # \r
 # Protocol prototype\r
-#   GetTemplateAddressMap (\r
+#   AsmGetTemplateAddressMap (\r
 #     EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
 #   );\r
 #           \r
@@ -443,8 +616,8 @@ ErrorCodeAndVectorOnStack:
 #-------------------------------------------------------------------------------------\r
 #  AsmGetAddressMap (&AddressMap);\r
 #-------------------------------------------------------------------------------------\r
-ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)\r
-ASM_PFX(GetTemplateAddressMap):\r
+ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)\r
+ASM_PFX(AsmGetTemplateAddressMap):\r
 \r
         pushl       %ebp\r
         movl        %esp,%ebp\r
@@ -453,8 +626,17 @@ ASM_PFX(GetTemplateAddressMap):
         movl        0x8(%ebp), %ebx\r
         movl        $Exception0Handle, (%ebx)\r
         movl        $(Exception1Handle - Exception0Handle), 0x4(%ebx)\r
+        movl        $(HookAfterStubBegin), 0x8(%ebx)\r
 \r
         popal\r
         popl        %ebp\r
         ret\r
-\r
+#-------------------------------------------------------------------------------------\r
+#  AsmVectorNumFixup (*VectorBase, VectorNum);\r
+#-------------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)\r
+ASM_PFX(AsmVectorNumFixup):\r
+        movl  8(%esp), %eax\r
+        movl  4(%esp), %ecx\r
+        movb  %al, (VectorNum - HookAfterStubBegin)(%ecx)\r
+        ret\r
index 869f18dfde054108b70b782cc88e7bb1731f7a92..74d4e89047108c654027e213138ab7fcbdddda02 100644 (file)
@@ -1,5 +1,5 @@
 ;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
 ; This program and the accompanying materials\r
 ; are licensed and made available under the terms and conditions of the BSD License\r
 ; which accompanies this distribution.  The full text of the license may be found at\r
@@ -30,133 +30,77 @@ CommonExceptionHandler             PROTO   C
 \r
 .data\r
 \r
-CommonEntryAddr           DD    CommonInterruptEntry\r
-\r
-EXTRN mErrorCodeFlag:DWORD             ; Error code flags for exceptions\r
+EXTRN mErrorCodeFlag:DWORD            ; Error code flags for exceptions\r
+EXTRN mDoFarReturnFlag:DWORD          ; Do far return flag\r
 \r
 .code\r
 \r
+ALIGN   8\r
+\r
 ;\r
 ; exception handler stub table\r
 ;\r
-Exception0Handle:\r
-    push    0\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception1Handle:\r
-    push    1\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception2Handle:\r
-    push    2\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception3Handle:\r
-    push    3\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception4Handle:\r
-    push    4\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception5Handle:\r
-    push    5\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception6Handle:\r
-    push    6\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception7Handle:\r
-    push    7\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception8Handle:\r
-    push    8\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception9Handle:\r
-    push    9\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception10Handle:\r
-    push    10\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception11Handle:\r
-    push    11\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception12Handle:\r
-    push    12\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception13Handle:\r
-    push    13\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception14Handle:\r
-    push    14\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception15Handle:\r
-    push    15\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception16Handle:\r
-    push    16\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception17Handle:\r
-    push    17\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception18Handle:\r
-    push    18\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception19Handle:\r
-    push    19\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception20Handle:\r
-    push    20\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception21Handle:\r
-    push    21\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception22Handle:\r
-    push    22\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception23Handle:\r
-    push    23\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception24Handle:\r
-    push    24\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception25Handle:\r
-    push    25\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception26Handle:\r
-    push    26\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception27Handle:\r
-    push    27\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception28Handle:\r
-    push    28\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception29Handle:\r
-    push    29\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception30Handle:\r
-    push    30\r
-    jmp     dword ptr [CommonEntryAddr]\r
-Exception31Handle:\r
-    push    31\r
-    jmp     dword ptr [CommonEntryAddr]\r
+AsmIdtVectorBegin:\r
+REPEAT  32\r
+    db      6ah        ; push  #VectorNum\r
+    db      ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum\r
+    push    eax\r
+    mov     eax, CommonInterruptEntry\r
+    jmp     eax\r
+ENDM\r
+AsmIdtVectorEnd:\r
+\r
+HookAfterStubBegin:\r
+    db      6ah        ; push\r
+VectorNum:\r
+    db      0          ; 0 will be fixed \r
+    push    eax\r
+    mov     eax, HookAfterStubHeaderEnd\r
+    jmp     eax\r
+HookAfterStubHeaderEnd:\r
+    pop     eax\r
+    sub     esp, 8     ; reserve room for filling exception data later\r
+    push    [esp + 8]\r
+    xchg    ecx, [esp] ; get vector number\r
+    bt      mErrorCodeFlag, ecx\r
+    jnc     @F\r
+    push    [esp]      ; addition push if exception data needed\r
+@@:\r
+    xchg    ecx, [esp] ; restore ecx\r
+    push    eax\r
 \r
 ;----------------------------------------------------------------------------;\r
 ; CommonInterruptEntry                                                               ;\r
 ;----------------------------------------------------------------------------;\r
 ; The follow algorithm is used for the common interrupt routine.\r
 ; Entry from each interrupt with a push eax and eax=interrupt number\r
-\r
+; Stack:\r
+; +---------------------+\r
+; +    EFlags           +\r
+; +---------------------+\r
+; +    CS               +\r
+; +---------------------+\r
+; +    EIP              +\r
+; +---------------------+\r
+; +    Error Code       +\r
+; +---------------------+\r
+; +    Vector Number    +\r
+; +---------------------+\r
+; +    EBP              +\r
+; +---------------------+ <-- EBP\r
 CommonInterruptEntry PROC PUBLIC\r
     cli\r
+    pop    eax\r
     ;\r
     ; All interrupt handlers are invoked through interrupt gates, so\r
     ; IF flag automatically cleared at the entry point\r
     ;\r
 \r
     ;\r
-    ; Calculate vector number\r
-    ;\r
-    ; Get the return address of call, actually, it is the\r
-    ; address of vector number.\r
+    ; Get vector number from top of stack\r
     ;\r
     xchg    ecx, [esp]\r
-    and     ecx, 0FFFFh\r
+    and     ecx, 0FFh       ; Vector number should be less than 256\r
     cmp     ecx, 32         ; Intel reserved vector for exceptions?\r
     jae     NoErrorCode\r
     bt      mErrorCodeFlag, ecx\r
@@ -246,6 +190,10 @@ ErrorCodeAndVectorOnStack:
     and     esp, 0fffffff0h\r
     sub     esp, 12\r
 \r
+    sub     esp, 8\r
+    push    0            ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    push    0            ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+       \r
 ;; UINT32  Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
     push    eax\r
     push    ecx\r
@@ -411,19 +359,42 @@ ErrorCodeAndVectorOnStack:
     pop     ecx\r
     pop     eax\r
 \r
+    pop     dword ptr [ebp - 8]\r
+    pop     dword ptr [ebp - 4]\r
     mov     esp, ebp\r
     pop     ebp\r
     add     esp, 8\r
+    cmp     dword ptr [esp - 16], 0   ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    jz      DoReturn\r
+    cmp     dword ptr [esp - 20], 1   ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+    jz      ErrorCode\r
+    jmp     dword ptr [esp - 16]\r
+ErrorCode:\r
+    sub     esp, 4\r
+    jmp     dword ptr [esp - 12]\r
+\r
+DoReturn:    \r
+    cmp     mDoFarReturnFlag, 0   ; Check if need to do far return instead of IRET\r
+    jz      DoIret\r
+    push    [esp + 8]    ; save EFLAGS\r
+    add     esp, 16\r
+    push    [esp - 8]    ; save CS in new location\r
+    push    [esp - 8]    ; save EIP in new location\r
+    push    [esp - 8]    ; save EFLAGS in new location\r
+    popfd                ; restore EFLAGS\r
+    retf                 ; far return\r
+\r
+DoIret:\r
     iretd\r
 \r
 CommonInterruptEntry ENDP\r
 \r
 ;---------------------------------------;\r
-; _GetTemplateAddressMap                  ;\r
+; _AsmGetTemplateAddressMap                  ;\r
 ;----------------------------------------------------------------------------;\r
 ; \r
 ; Protocol prototype\r
-;   GetTemplateAddressMap (\r
+;   AsmGetTemplateAddressMap (\r
 ;     EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
 ;   );\r
 ;           \r
@@ -447,18 +418,28 @@ CommonInterruptEntry ENDP
 ;           \r
 ; Destroys: Nothing\r
 ;-----------------------------------------------------------------------------;\r
-GetTemplateAddressMap  proc near public\r
+AsmGetTemplateAddressMap  proc near public\r
     push    ebp                 ; C prolog\r
     mov     ebp, esp\r
     pushad\r
 \r
-    mov ebx, dword ptr [ebp+08h]\r
-    mov dword ptr [ebx],    Exception0Handle\r
-    mov dword ptr [ebx+4h], Exception1Handle - Exception0Handle\r
+    mov ebx, dword ptr [ebp + 08h]\r
+    mov dword ptr [ebx],      AsmIdtVectorBegin\r
+    mov dword ptr [ebx + 4h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32\r
+    mov dword ptr [ebx + 8h], HookAfterStubBegin\r
   \r
     popad\r
     pop     ebp\r
     ret\r
-GetTemplateAddressMap  ENDP\r
-\r
+AsmGetTemplateAddressMap  ENDP\r
+\r
+;-------------------------------------------------------------------------------------\r
+;  AsmVectorNumFixup (*VectorBase, VectorNum);\r
+;-------------------------------------------------------------------------------------\r
+AsmVectorNumFixup   proc near public\r
+    mov     eax, dword ptr [esp + 8]\r
+    mov     ecx, [esp + 4]\r
+    mov     [ecx + (VectorNum - HookAfterStubBegin)], al\r
+    ret\r
+AsmVectorNumFixup   ENDP\r
 END\r
index ebd9fe32b7b7e139d985b3f5d1b9f567939d58a2..f2e7c81257dc0cfa1a7c95a2e5a35dd7d7f511de 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
-  CPU Exception Library provides SEC/PEIM CPU exception handler.\r
+  CPU exception handler library implemenation for SEC/PEIM modules.\r
 \r
-Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed and made available under\r
 the terms and conditions of the BSD License that accompanies this distribution.\r
 The full text of the license may be found at\r
@@ -18,7 +18,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 //\r
 // Image Aglinment size for SEC/PEI phase\r
 //\r
-CONST UINTN      mImageAlignSize = 4;\r
+CONST UINTN    mImageAlignSize   = 4;\r
+CONST UINTN    mDoFarReturnFlag  = 0;\r
 \r
 /**\r
   Common exception handler.\r
@@ -45,19 +46,138 @@ CommonExceptionHandler (
 }\r
 \r
 /**\r
-  Setup CPU exception handlers.\r
-\r
-  This API will setups the CPU exception handler to display CPU contents and run into\r
-  CpuDeadLoop(). \r
+  Initializes all CPU exceptions entries and provides the default exception handlers.\r
+  \r
+  Caller should try to get an array of interrupt and/or exception vectors that are in use and need to\r
+  persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.\r
+  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. \r
+  If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.\r
   Note: Before invoking this API, caller must allocate memory for IDT table and load \r
         IDTR by AsmWriteIdtr().\r
+\r
+  @param[in]  VectorInfo    Pointer to reserved vector list.\r
   \r
+  @retval EFI_SUCCESS           CPU Exception Entries have been successfully initialized \r
+                                with default exception handlers.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+  @retval EFI_UNSUPPORTED       This function is not supported.\r
+\r
 **/\r
-VOID\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeCpuExceptionHandlers (\r
+  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                       Status;  \r
+  RESERVED_VECTORS_DATA            ReservedVectorData[CPU_EXCEPTION_NUM];\r
+  IA32_DESCRIPTOR                  IdtDescriptor;\r
+  UINTN                            IdtEntryCount;\r
+  UINT16                           CodeSegment;\r
+  EXCEPTION_HANDLER_TEMPLATE_MAP   TemplateMap;\r
+  IA32_IDT_GATE_DESCRIPTOR         *IdtTable;\r
+  UINTN                            Index;\r
+  UINTN                            InterruptHandler;\r
+\r
+  if (VectorInfo != NULL) {\r
+    SetMem ((VOID *) ReservedVectorData, sizeof (RESERVED_VECTORS_DATA) * CPU_EXCEPTION_NUM, 0xff);\r
+    Status = ReadAndVerifyVectorInfo (VectorInfo, ReservedVectorData, CPU_EXCEPTION_NUM);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+  }\r
+  //\r
+  // Read IDT descriptor and calculate IDT size\r
+  //\r
+  AsmReadIdtr (&IdtDescriptor);\r
+  IdtEntryCount = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);\r
+  if (IdtEntryCount > CPU_EXCEPTION_NUM) {\r
+    //\r
+    // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most\r
+    //\r
+    IdtEntryCount = CPU_EXCEPTION_NUM;\r
+  }\r
+  //\r
+  // Use current CS as the segment selector of interrupt gate in IDT\r
+  //\r
+  CodeSegment = AsmReadCs ();\r
+\r
+  AsmGetTemplateAddressMap (&TemplateMap);\r
+  IdtTable = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor.Base;\r
+  for (Index = 0; Index < IdtEntryCount; Index ++) {\r
+    IdtTable[Index].Bits.Selector = CodeSegment;\r
+    //\r
+    // Check reserved vectors attributes if has, only EFI_VECTOR_HANDOFF_DO_NOT_HOOK\r
+    // supported in this instance\r
+    //\r
+    if (VectorInfo != NULL) {\r
+      if (ReservedVectorData[Index].Attribute == EFI_VECTOR_HANDOFF_DO_NOT_HOOK) {\r
+        continue;\r
+      }\r
+    }\r
+    //\r
+    // Update IDT entry\r
+    //\r
+    InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;\r
+    ArchUpdateIdtEntry (&IdtTable[Index], InterruptHandler);\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.\r
+  \r
+  Caller should try to get an array of interrupt and/or exception vectors that are in use and need to\r
+  persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.\r
+  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. \r
+  If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.\r
+\r
+  @param[in]  VectorInfo    Pointer to reserved vector list.\r
+  \r
+  @retval EFI_SUCCESS           All CPU interrupt/exception entries have been successfully initialized \r
+                                with default interrupt/exception handlers.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+  @retval EFI_UNSUPPORTED       This function is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
 EFIAPI\r
-SetupCpuExceptionHandlers (\r
-  IN VOID\r
+InitializeCpuInterruptHandlers (\r
+  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
   )\r
 {\r
-  InternalSetupCpuExceptionHandlers ();\r
+  return EFI_UNSUPPORTED;\r
 }\r
+\r
+/**\r
+  Registers a function to be called from the processor interrupt handler.\r
+\r
+  This function registers and enables the handler specified by InterruptHandler for a processor \r
+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the \r
+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled. \r
+  The installed handler is called once for each processor interrupt or exception.\r
+  NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or\r
+  InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.\r
+\r
+  @param[in]  InterruptType     Defines which interrupt or exception to hook.\r
+  @param[in]  InterruptHandler  A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
+                                when a processor interrupt occurs. If this parameter is NULL, then the handler\r
+                                will be uninstalled.\r
+\r
+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.\r
+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was\r
+                                previously installed.\r
+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not\r
+                                previously installed.\r
+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported,\r
+                                or this function is not supported.\r
+*/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterCpuInterruptHandler (\r
+  IN EFI_EXCEPTION_TYPE            InterruptType,\r
+  IN EFI_CPU_INTERRUPT_HANDLER     InterruptHandler\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}
\ No newline at end of file
index 96ddaafd43a21d44fa35f14d8e352521e7455941..c8553623d2c4203b44685058a96918641ab5382e 100644 (file)
@@ -3,7 +3,7 @@
 #\r
 #  This library instance supports SEC/PEI module only.\r
 #\r
-#  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
 #  which accompanies this distribution.  The full text of the license may be found at\r
   Ia32/ExceptionHandlerAsm.asm |MSFT\r
   Ia32/ExceptionHandlerAsm.S   |GCC\r
   Ia32/ArchExceptionHandler.c\r
+  Ia32/ArchInterruptDefs.h\r
 \r
 [Sources.X64]\r
   X64/ExceptionHandlerAsm.asm |MSFT\r
   X64/ExceptionHandlerAsm.S   |GCC\r
   X64/ArchExceptionHandler.c\r
+  X64/ArchInterruptDefs.h\r
 \r
 [Sources.common]\r
   CpuExceptionCommon.h\r
@@ -54,3 +56,7 @@
   PrintLib\r
   LocalApicLib\r
   PeCoffGetEntryPointLib\r
+  ReportStatusCodeLib\r
+\r
+[Ppis]\r
+  gEfiVectorHandoffInfoPpiGuid\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf
new file mode 100644 (file)
index 0000000..bee0c46
--- /dev/null
@@ -0,0 +1,65 @@
+## @file\r
+#  Component description file for SMM CPU Exception Handler Library instance.\r
+#\r
+#  This library instance supports SMM module only.\r
+#\r
+#  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#  \r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  \r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SmmCpuExceptionHandlerLib\r
+  FILE_GUID                      = 8D2C439B-3981-42ff-9CE5-1B50ECA502D6\r
+  MODULE_TYPE                    = DXE_SMM_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = CpuExceptionHandlerLib|DXE_SMM_DRIVER\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources.Ia32]\r
+  Ia32/ExceptionHandlerAsm.asm |MSFT\r
+  Ia32/ExceptionHandlerAsm.S   |GCC\r
+  Ia32/ArchExceptionHandler.c\r
+  Ia32/ArchInterruptDefs.h\r
+\r
+[Sources.X64]\r
+  X64/ExceptionHandlerAsm.asm   |MSFT\r
+  X64/ExceptionHandlerAsm.S     |GCC\r
+  X64/ArchExceptionHandler.c\r
+  X64/ArchInterruptDefs.h\r
+\r
+[Sources.common]\r
+  CpuExceptionCommon.h\r
+  CpuExceptionCommon.c\r
+  DxeSmmCpuException.c\r
+  SmmException.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  SerialPortLib\r
+  PrintLib\r
+  SynchronizationLib\r
+  LocalApicLib\r
+  PeCoffGetEntryPointLib\r
+  ReportStatusCodeLib\r
+  DebugLib\r
\r
+[Ppis]\r
+  gEfiVectorHandoffInfoPpiGuid\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c b/UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmException.c
new file mode 100644 (file)
index 0000000..c3f4425
--- /dev/null
@@ -0,0 +1,101 @@
+/** @file\r
+  CPU exception handler library implemenation for SMM modules.\r
+\r
+  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiSmm.h>\r
+#include "CpuExceptionCommon.h"\r
+\r
+CONST UINTN   mDoFarReturnFlag   = 1; \r
+\r
+/**\r
+  Initializes all CPU exceptions entries and provides the default exception handlers.\r
+  \r
+  Caller should try to get an array of interrupt and/or exception vectors that are in use and need to\r
+  persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.\r
+  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. \r
+  If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.\r
+\r
+  @param[in]  VectorInfo    Pointer to reserved vector list.\r
+  \r
+  @retval EFI_SUCCESS           CPU Exception Entries have been successfully initialized \r
+                                with default exception handlers.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+  @retval EFI_UNSUPPORTED       This function is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeCpuExceptionHandlers (\r
+  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
+  )\r
+{\r
+  return InitializeCpuExceptionHandlersWorker (VectorInfo);\r
+}\r
+\r
+/**\r
+  Initializes all CPU interrupt/exceptions entries and provides the default interrupt/exception handlers.\r
+  \r
+  Caller should try to get an array of interrupt and/or exception vectors that are in use and need to\r
+  persist by EFI_VECTOR_HANDOFF_INFO defined in PI 1.3 specification.\r
+  If caller cannot get reserved vector list or it does not exists, set VectorInfo to NULL. \r
+  If VectorInfo is not NULL, the exception vectors will be initialized per vector attribute accordingly.\r
+\r
+  @param[in]  VectorInfo    Pointer to reserved vector list.\r
+  \r
+  @retval EFI_SUCCESS           All CPU interrupt/exception entries have been successfully initialized \r
+                                with default interrupt/exception handlers.\r
+  @retval EFI_INVALID_PARAMETER VectorInfo includes the invalid content if VectorInfo is not NULL.\r
+  @retval EFI_UNSUPPORTED       This function is not supported.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeCpuInterruptHandlers (\r
+  IN EFI_VECTOR_HANDOFF_INFO       *VectorInfo OPTIONAL\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Registers a function to be called from the processor interrupt handler.\r
+\r
+  This function registers and enables the handler specified by InterruptHandler for a processor \r
+  interrupt or exception type specified by InterruptType. If InterruptHandler is NULL, then the \r
+  handler for the processor interrupt or exception type specified by InterruptType is uninstalled. \r
+  The installed handler is called once for each processor interrupt or exception.\r
+  NOTE: This function should be invoked after InitializeCpuExceptionHandlers() or\r
+  InitializeCpuInterruptHandlers() invoked, otherwise EFI_UNSUPPORTED returned.\r
+\r
+  @param[in]  InterruptType     Defines which interrupt or exception to hook.\r
+  @param[in]  InterruptHandler  A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER that is called\r
+                                when a processor interrupt occurs. If this parameter is NULL, then the handler\r
+                                will be uninstalled.\r
+\r
+  @retval EFI_SUCCESS           The handler for the processor interrupt was successfully installed or uninstalled.\r
+  @retval EFI_ALREADY_STARTED   InterruptHandler is not NULL, and a handler for InterruptType was\r
+                                previously installed.\r
+  @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not\r
+                                previously installed.\r
+  @retval EFI_UNSUPPORTED       The interrupt specified by InterruptType is not supported,\r
+                                or this function is not supported.\r
+*/\r
+EFI_STATUS\r
+EFIAPI\r
+RegisterCpuInterruptHandler (\r
+  IN EFI_EXCEPTION_TYPE            InterruptType,\r
+  IN EFI_CPU_INTERRUPT_HANDLER     InterruptHandler\r
+  )\r
+{\r
+  return RegisterCpuInterruptHandlerWorker (InterruptType, InterruptHandler);\r
+}
\ No newline at end of file
index 664472a6678ecf1fa76af84f8fffab3f2f59bf51..1af2999ac0b237533b24fbf372c956c5779a9021 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   x64 CPU Exception Hanlder.\r
 \r
-  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #include "CpuExceptionCommon.h"\r
 \r
 /**\r
-  Internal function to setup CPU exception handlers.\r
+  Return address map of exception handler template so that C code can generate\r
+  exception tables.\r
 \r
+  @param IdtEntry          Pointer to IDT entry to be updated.\r
+  @param InterruptHandler  IDT handler value.\r
 **/\r
 VOID\r
-InternalSetupCpuExceptionHandlers (\r
-  VOID\r
+ArchUpdateIdtEntry (\r
+  IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry,\r
+  IN UINTN                           InterruptHandler\r
   )\r
 {\r
-  IA32_DESCRIPTOR                     IdtDescriptor;\r
-  UINTN                               IdtSize;\r
-  EXCEPTION_HANDLER_TEMPLATE_MAP      TemplateMap;\r
-  UINT16                              CodeSegment;\r
-  IA32_IDT_GATE_DESCRIPTOR            *IdtEntry;\r
-  UINTN                               Index;\r
-  UINTN                               InterruptHandler;\r
+  IdtEntry->Bits.OffsetLow   = (UINT16)(UINTN)InterruptHandler;\r
+  IdtEntry->Bits.OffsetHigh  = (UINT16)((UINTN)InterruptHandler >> 16);\r
+  IdtEntry->Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);        \r
+  IdtEntry->Bits.GateType    = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
+}\r
+\r
+/**\r
+  Read IDT handler value from IDT entry.\r
+\r
+  @param IdtEntry          Pointer to IDT entry to be read.\r
+\r
+**/\r
+UINTN\r
+ArchGetIdtHandler (\r
+  IN IA32_IDT_GATE_DESCRIPTOR        *IdtEntry\r
+  )\r
+{\r
+  return IdtEntry->Bits.OffsetLow + (((UINTN) IdtEntry->Bits.OffsetHigh)  << 16) +\r
+                                    (((UINTN) IdtEntry->Bits.OffsetUpper) << 32);\r
+}\r
 \r
+/**\r
+  Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.\r
+\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+ArchSaveExceptionContext (\r
+  IN UINTN                ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext \r
+  )\r
+{\r
+  IA32_EFLAGS32           Eflags;\r
   //\r
-  // Read IDT descriptor and calculate IDT size\r
+  // Save Exception context in global variable\r
   //\r
-  AsmReadIdtr (&IdtDescriptor);\r
-  IdtSize = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);\r
-  if (IdtSize > CPU_EXCEPTION_NUM) {\r
-    //\r
-    // CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most\r
-    //\r
-    IdtSize = CPU_EXCEPTION_NUM;\r
-  }\r
-\r
+  mReservedVectors[ExceptionType].OldSs         = SystemContext.SystemContextX64->Ss;\r
+  mReservedVectors[ExceptionType].OldSp         = SystemContext.SystemContextX64->Rsp;\r
+  mReservedVectors[ExceptionType].OldFlags      = SystemContext.SystemContextX64->Rflags;\r
+  mReservedVectors[ExceptionType].OldCs         = SystemContext.SystemContextX64->Cs;\r
+  mReservedVectors[ExceptionType].OldIp         = SystemContext.SystemContextX64->Rip;\r
+  mReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextX64->ExceptionData;\r
   //\r
-  // Use current CS as the segment selector of interrupt gate in IDT\r
+  // Clear IF flag to avoid old IDT handler enable interrupt by IRET\r
   //\r
-  CodeSegment = AsmReadCs ();\r
-  IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;\r
-\r
-  GetTemplateAddressMap (&TemplateMap);\r
-\r
-  for (Index = 0; Index < IdtSize; Index ++) {\r
-    InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;\r
-    IdtEntry[Index].Bits.OffsetLow       = (UINT16)(UINTN)InterruptHandler;\r
-    IdtEntry[Index].Bits.OffsetHigh      = (UINT16)((UINTN)InterruptHandler >> 16);\r
-    IdtEntry[Index].Bits.OffsetUpper     = (UINT32)((UINTN)InterruptHandler >> 32);\r
-    IdtEntry[Index].Bits.Selector        = CodeSegment;\r
-    IdtEntry[Index].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;\r
-  }\r
+  Eflags.UintN = SystemContext.SystemContextX64->Rflags;\r
+  Eflags.Bits.IF = 0; \r
+  SystemContext.SystemContextX64->Rflags = Eflags.UintN;\r
+  //\r
+  // Modify the EIP in stack, then old IDT handler will return to the stub code\r
+  //\r
+  SystemContext.SystemContextX64->Rip = (UINTN) mReservedVectors[ExceptionType].HookAfterStubHeaderCode;\r
 }\r
 \r
 /**\r
-  Common exception handler.\r
+  Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.\r
 \r
   @param ExceptionType  Exception type.\r
   @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
 **/\r
 VOID\r
-DumpCpuContent (\r
+ArchRestoreExceptionContext (\r
   IN UINTN                ExceptionType,\r
+  IN EFI_SYSTEM_CONTEXT   SystemContext \r
+  )\r
+{\r
+  SystemContext.SystemContextX64->Ss            = mReservedVectors[ExceptionType].OldSs;\r
+  SystemContext.SystemContextX64->Rsp           = mReservedVectors[ExceptionType].OldSp;\r
+  SystemContext.SystemContextX64->Rflags        = mReservedVectors[ExceptionType].OldFlags;\r
+  SystemContext.SystemContextX64->Cs            = mReservedVectors[ExceptionType].OldCs;\r
+  SystemContext.SystemContextX64->Rip           = mReservedVectors[ExceptionType].OldIp;\r
+  SystemContext.SystemContextX64->ExceptionData = mReservedVectors[ExceptionType].ExceptionData;\r
+}\r
+\r
+/**\r
+  Dump CPU content information.\r
+\r
+  @param ExceptionType  Exception type.\r
+  @param SystemContext  Pointer to EFI_SYSTEM_CONTEXT.\r
+**/\r
+VOID\r
+DumpCpuContent (\r
+  IN EFI_EXCEPTION_TYPE   ExceptionType,\r
   IN EFI_SYSTEM_CONTEXT   SystemContext\r
   )\r
 {\r
diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ArchInterruptDefs.h
new file mode 100644 (file)
index 0000000..9064801
--- /dev/null
@@ -0,0 +1,46 @@
+/** @file\r
+  X64 arch definition for CPU Exception Handler Library.\r
+\r
+  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _ARCH_CPU_INTERRUPT_DEFS_H_\r
+#define _ARCH_CPU_INTERRUPT_DEFS_H_\r
+\r
+typedef struct {\r
+  EFI_SYSTEM_CONTEXT_X64  SystemContext;\r
+  BOOLEAN                 ExceptionDataFlag;\r
+  UINTN                   OldIdtHandler;\r
+} EXCEPTION_HANDLER_CONTEXT;\r
+\r
+//\r
+// Register Structure Definitions\r
+//\r
+typedef struct {\r
+  EFI_STATUS_CODE_DATA      Header;\r
+  EFI_SYSTEM_CONTEXT_X64    SystemContext;\r
+} CPU_STATUS_CODE_TEMPLATE;\r
+\r
+typedef struct {\r
+  SPIN_LOCK   SpinLock;\r
+  UINT32      ApicId;\r
+  UINT32      Attribute;\r
+  UINTN       ExceptonHandler;\r
+  UINTN       OldSs;\r
+  UINTN       OldSp;\r
+  UINTN       OldFlags;\r
+  UINTN       OldCs;\r
+  UINTN       OldIp;\r
+  UINTN       ExceptionData;\r
+  UINT8       HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE];\r
+} RESERVED_VECTORS_DATA;\r
+\r
+#endif\r
index cd101475a7c11adde5b1d9ffa25341eeb73709f8..7d5672f892b9d7886158d254e72fe4541617272d 100644 (file)
@@ -1,5 +1,5 @@
 #------------------------------------------------------------------------------ ;\r
-# Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
 #------------------------------------------------------------------------------\r
 \r
 \r
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
 \r
 ASM_GLOBAL ASM_PFX(CommonExceptionHandler)\r
 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
 \r
-\r
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
+#EXTRN ASM_PFX(mDoFarReturnFlag):QWORD  # Do far return flag\r
 .text\r
 \r
 #\r
-# point to the external interrupt vector table\r
+# exception handler stub table\r
 #\r
 Exception0Handle:\r
-    pushq   $0\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   0\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception1Handle:\r
-    pushq   $1\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   1\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception2Handle:\r
-    pushq   $2\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   2\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception3Handle:\r
-    pushq   $3\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   3\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception4Handle:\r
-    pushq   $4\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   4\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception5Handle:\r
-    pushq   $5\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   5\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception6Handle:\r
-    pushq   $6\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   6\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception7Handle:\r
-    pushq   $7\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   7\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception8Handle:\r
-    pushq   $8\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   8\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception9Handle:\r
-    pushq   $9\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   9\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception10Handle:\r
-    pushq   $10\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   10\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception11Handle:\r
-    pushq   $11\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   11\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception12Handle:\r
-    pushq   $12\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   12\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception13Handle:\r
-    pushq   $13\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   13\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception14Handle:\r
-    pushq   $14\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   14\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception15Handle:\r
-    pushq   $15\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   15\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception16Handle:\r
-    pushq   $16\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   16\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception17Handle:\r
-    pushq   $17\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   17\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception18Handle:\r
-    pushq   $18\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   18\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception19Handle:\r
-    pushq   $19\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   19\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception20Handle:\r
-    pushq   $20\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   20\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception21Handle:\r
-    pushq   $21\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   21\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception22Handle:\r
-    pushq   $22\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   22\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception23Handle:\r
-    pushq   $23\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   23\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception24Handle:\r
-    pushq   $24\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   24\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception25Handle:\r
-    pushq   $25\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   25\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception26Handle:\r
-    pushq   $26\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   26\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception27Handle:\r
-    pushq   $27\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   27\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception28Handle:\r
-    pushq   $28\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   28\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception29Handle:\r
-    pushq   $29\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   29\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception30Handle:\r
-    pushq   $30\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   30\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
 Exception31Handle:\r
-    pushq   $31\r
-    jmp     ASM_PFX(CommonInterruptEntry)\r
-\r
+    .byte   0x6a    #  push #VectorNum\r
+    .byte   31\r
+    pushq   %rax\r
+    .byte   0x48, 0xB8\r
+    .quad   ASM_PFX(CommonInterruptEntry)\r
+    jmp     *%rax\r
+    \r
+HookAfterStubHeaderBegin:\r
+    .byte   0x6a      # push\r
+VectorNum:\r
+    .byte   0         # 0 will be fixed \r
+    pushq   %rax\r
+    .byte   0x48, 0xB8      # movq    ASM_PFX(HookAfterStubHeaderEnd), %rax\r
+    .quad   ASM_PFX(HookAfterStubHeaderEnd)\r
+    jmp     *%rax\r
+ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)\r
+ASM_PFX(HookAfterStubHeaderEnd):\r
+    movq    %rsp, %rax\r
+    subq    $8, %rsp\r
+    andl    $0x0fffffff0, %esp\r
+    pushq   %rcx\r
+    movq    8(%rax), %rcx\r
+    bt      %ecx, ASM_PFX(mErrorCodeFlag)\r
+    jc      NoErrorData\r
+    pushq   (%rsp)            # push additional rcx to make stack alignment\r
+NoErrorData:\r
+    xchgq   (%rsp), %rcx      # restore rcx, save Exception Number in stack\r
+    pushq   (%rax)            # push rax into stack to keep code consistence\r
 \r
 #---------------------------------------;\r
 # CommonInterruptEntry                  ;\r
@@ -138,6 +288,7 @@ Exception31Handle:
 ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
 ASM_PFX(CommonInterruptEntry):\r
     cli\r
+    popq    %rax\r
     #\r
     # All interrupt handlers are invoked through interrupt gates, so\r
     # IF flag automatically cleared at the entry point\r
@@ -145,7 +296,8 @@ ASM_PFX(CommonInterruptEntry):
     #\r
     # Calculate vector number\r
     #\r
-    xchgq   (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.\r
+    xchgq   (%rsp), %rcx       # get the return address of call, actually, it is the address of vector number.\r
+    andq     $0x0FF, %rcx\r
     cmp     $32, %ecx          # Intel reserved vector for exceptions?\r
     jae     NoErrorCode\r
     pushq   %rax\r
@@ -165,6 +317,8 @@ NoErrorCode:
 CommonInterruptEntry_al_0000:\r
     pushq   %rbp\r
     movq    %rsp, %rbp\r
+    pushq   $0          # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    pushq   $0          # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
 \r
     #\r
     # Stack:\r
@@ -385,20 +539,53 @@ CommonInterruptEntry_al_0000:
     movq    %rbp, %rsp\r
     popq    %rbp\r
     addq    $16, %rsp\r
+    cmpq    $0, -32(%rsp)      # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    jz      DoReturn           # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+    cmpb    $1, -40(%rsp)\r
+    jz      ErrorCode\r
+    jmp     *-32(%rsp)\r
+ErrorCode:\r
+    subq    $8, %rsp\r
+    jmp     *-24(%rsp)\r
+\r
+DoReturn:\r
+    cmpq    $0, ASM_PFX(mDoFarReturnFlag)   # Check if need to do far return instead of IRET\r
+    jz      DoIret\r
+    pushq   %rax\r
+    movq    %rsp, %rax        # save old RSP to rax\r
+    movq    0x20(%rsp), %rsp\r
+    pushq   0x10(%rax)        # save CS in new location\r
+    pushq   0x8(%rax)         # save EIP in new location\r
+    pushq   0x18(%rax)        # save EFLAGS in new location\r
+    movq    (%rax), %rax      # restore rax\r
+    popfq                     # restore EFLAGS\r
+    .byte   0x48              # prefix to composite "retq" with next "retf"\r
+    retf                      # far return\r
+DoIret:\r
     iretq\r
 \r
 \r
 #-------------------------------------------------------------------------------------\r
-#  AsmGetAddressMap (&AddressMap);\r
+#  AsmGetTemplateAddressMap (&AddressMap);\r
 #-------------------------------------------------------------------------------------\r
 # comments here for definition of address map\r
-ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)\r
-ASM_PFX(GetTemplateAddressMap):\r
+ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)\r
+ASM_PFX(AsmGetTemplateAddressMap):\r
 \r
         movabsq      $Exception0Handle, %rax\r
         movq         %rax, (%rcx)\r
         movq         $(Exception1Handle - Exception0Handle), 0x08(%rcx)\r
+        movabsq      $HookAfterStubHeaderBegin, %rax\r
+        movq         %rax, 0x10(%rcx)\r
+        ret\r
 \r
+#-------------------------------------------------------------------------------------\r
+#  AsmVectorNumFixup (*VectorBase, VectorNum);\r
+#-------------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)\r
+ASM_PFX(AsmVectorNumFixup):\r
+        movq  %rdx, %rax\r
+        movb  %al, (VectorNum - HookAfterStubHeaderBegin)(%rcx)\r
         ret\r
 \r
 #END\r
index 2cc78db374882c91edf0c1a0a6502b4b71b7109b..f348efe4befeb3406db407dbb3a39dab5b252436 100644 (file)
 ;\r
 externdef CommonExceptionHandler:near\r
 \r
-EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
+EXTRN mErrorCodeFlag:DWORD    ; Error code flags for exceptions\r
+EXTRN mDoFarReturnFlag:QWORD  ; Do far return flag\r
 \r
 data SEGMENT\r
 \r
-CommonEntryAddr                dq      CommonInterruptEntry;\r
-\r
 .code\r
 \r
-Exception0Handle:\r
-    push    0\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception1Handle:\r
-    push    1\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception2Handle:\r
-    push    2\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception3Handle:\r
-    push    3\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception4Handle:\r
-    push    4\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception5Handle:\r
-    push    5\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception6Handle:\r
-    push    6\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception7Handle:\r
-    push    7\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception8Handle:\r
-    push    8\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception9Handle:\r
-    push    9\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception10Handle:\r
-    push    10\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception11Handle:\r
-    push    11\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception12Handle:\r
-    push    12\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception13Handle:\r
-    push    13\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception14Handle:\r
-    push    14\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception15Handle:\r
-    push    15\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception16Handle:\r
-    push    16\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception17Handle:\r
-    push    17\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception18Handle:\r
-    push    18\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception19Handle:\r
-    push    19\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception20Handle:\r
-    push    20\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception21Handle:\r
-    push    21\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception22Handle:\r
-    push    22\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception23Handle:\r
-    push    23\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception24Handle:\r
-    push    24\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception25Handle:\r
-    push    25\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception26Handle:\r
-    push    26\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception27Handle:\r
-    push    27\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception28Handle:\r
-    push    28\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception29Handle:\r
-    push    29\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception30Handle:\r
-    push    30\r
-    jmp     qword ptr [CommonEntryAddr]\r
-Exception31Handle:\r
-    push    31\r
-    jmp     qword ptr [CommonEntryAddr]\r
-\r
-;CommonInterruptEntrypoint:\r
-;---------------------------------------;\r
-; _CommonEntry                  ;\r
-;----------------------------------------------------------------------------;\r
-; The follow algorithm is used for the common interrupt routine.\r
-; Entry from each interrupt with a push eax and eax=interrupt number\r
+ALIGN   8\r
+\r
+AsmIdtVectorBegin:\r
+REPEAT  32\r
+    db      6ah        ; push  #VectorNum\r
+    db      ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum\r
+    push    rax\r
+    mov     rax, CommonInterruptEntry\r
+    jmp     rax\r
+ENDM\r
+AsmIdtVectorEnd:\r
+\r
+HookAfterStubHeaderBegin:\r
+    db      6ah        ; push\r
+@VectorNum:\r
+    db      0          ; 0 will be fixed \r
+    push    rax\r
+    mov     rax, HookAfterStubHeaderEnd\r
+    jmp     rax\r
+HookAfterStubHeaderEnd:\r
+    mov     rax, rsp\r
+    sub     rsp, 8h\r
+    and     sp, 0fff0h\r
+    push    rcx\r
+    mov     rcx, [rax + 8]\r
+    bt      mErrorCodeFlag, ecx\r
+    jc      @F\r
+    push    [rsp]             ; push additional rcx to make stack alignment\r
+@@:\r
+    xchg    rcx, [rsp]        ; restore rcx, save Exception Number in stack\r
+    push    [rax]             ; push rax into stack to keep code consistence\r
 \r
 ;---------------------------------------;\r
 ; CommonInterruptEntry                  ;\r
 ;---------------------------------------;\r
 ; The follow algorithm is used for the common interrupt routine.\r
-\r
+; Entry from each interrupt with a push eax and eax=interrupt number\r
+; Stack frame would be as follows as specified in IA32 manuals:\r
+;\r
+; +---------------------+ <-- 16-byte aligned ensured by processor\r
+; +    Old SS           +\r
+; +---------------------+\r
+; +    Old RSP          +\r
+; +---------------------+\r
+; +    RFlags           +\r
+; +---------------------+\r
+; +    CS               +\r
+; +---------------------+\r
+; +    RIP              +\r
+; +---------------------+\r
+; +    Error Code       +\r
+; +---------------------+\r
+; +   Vector Number     +\r
+; +---------------------+\r
+; +    RBP              +\r
+; +---------------------+ <-- RBP, 16-byte aligned\r
+; The follow algorithm is used for the common interrupt routine.\r
 CommonInterruptEntry PROC PUBLIC  \r
     cli\r
+    pop     rax\r
     ;\r
     ; All interrupt handlers are invoked through interrupt gates, so\r
     ; IF flag automatically cleared at the entry point\r
     ;\r
-    ;\r
-    ; Calculate vector number\r
-    ;\r
-    xchg    rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.\r
+    xchg    rcx, [rsp]      ; Save rcx into stack and save vector number into rcx\r
+    and     rcx, 0FFh\r
     cmp     ecx, 32         ; Intel reserved vector for exceptions?\r
     jae     NoErrorCode\r
     bt      mErrorCodeFlag, ecx\r
@@ -168,6 +114,8 @@ NoErrorCode:
 @@:       \r
     push    rbp\r
     mov     rbp, rsp\r
+    push    0             ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    push    0             ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
 \r
     ;\r
     ; Stack:\r
@@ -389,6 +337,29 @@ NoErrorCode:
     mov     rsp, rbp\r
     pop     rbp\r
     add     rsp, 16\r
+    cmp     qword ptr [rsp - 32], 0  ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    jz      DoReturn\r
+    cmp     qword ptr [rsp - 40], 1  ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+    jz      ErrorCode\r
+    jmp     qword ptr [rsp - 32]\r
+ErrorCode:\r
+    sub     rsp, 8\r
+    jmp     qword ptr [rsp - 24]\r
+\r
+DoReturn:\r
+    cmp     mDoFarReturnFlag, 0   ; Check if need to do far return instead of IRET\r
+    jz      DoIret\r
+    push    rax\r
+    mov     rax, rsp          ; save old RSP to rax\r
+    mov     rsp, [rsp + 20h]   \r
+    push    [rax + 10h]       ; save CS in new location\r
+    push    [rax + 8h]        ; save EIP in new location\r
+    push    [rax + 18h]       ; save EFLAGS in new location\r
+    mov     rax, [rax]        ; restore rax\r
+    popfq                     ; restore EFLAGS\r
+    DB      48h               ; prefix to composite "retq" with next "retf"\r
+    retf                      ; far return\r
+DoIret:\r
     iretq\r
 \r
 CommonInterruptEntry ENDP\r
@@ -397,11 +368,22 @@ CommonInterruptEntry ENDP
 ;  GetTemplateAddressMap (&AddressMap);\r
 ;-------------------------------------------------------------------------------------\r
 ; comments here for definition of address map\r
-GetTemplateAddressMap   PROC\r
-        mov         rax, offset Exception0Handle\r
-        mov         qword ptr [rcx], rax\r
-        mov         qword ptr [rcx+8h], Exception1Handle - Exception0Handle\r
-        ret\r
-GetTemplateAddressMap   ENDP\r
+AsmGetTemplateAddressMap   PROC\r
+    mov     rax, offset AsmIdtVectorBegin\r
+    mov     qword ptr [rcx], rax\r
+    mov     qword ptr [rcx + 8h],  (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32\r
+    mov     rax, offset HookAfterStubHeaderBegin\r
+    mov     qword ptr [rcx + 10h], rax\r
+    ret\r
+AsmGetTemplateAddressMap   ENDP\r
+\r
+;-------------------------------------------------------------------------------------\r
+;  AsmVectorNumFixup (*VectorBase, VectorNum);\r
+;-------------------------------------------------------------------------------------\r
+AsmVectorNumFixup   PROC\r
+    mov     rax, rdx\r
+    mov     [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al\r
+    ret\r
+AsmVectorNumFixup   ENDP\r
 \r
 END\r
index 505c69e4c83af221a7b1daf8b713ca52ba78724b..fa33c1342cd3a426ea542f45ae209d48cb826b3d 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 #  UefiCpuPkg Package\r
 #\r
-#  Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -50,7 +50,8 @@
   TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf\r
   DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf\r
   LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf\r
-  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf  \r
+  ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf\r
+  CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf  \r
 \r
 [LibraryClasses.common.PEIM]\r
   MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf\r
@@ -87,6 +88,7 @@
   UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf\r
   UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf\r
   UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf\r
-  UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeSmmCpuExceptionHandlerLib.inf\r
+  UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf\r
+  UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf  \r
   UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf\r
 \r