]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuDxe/CpuDxe.c
OptionRomPkg/AtapiPassThruDxe: rebase to ARRAY_SIZE()
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / CpuDxe.c
index ad4599dab93c8674ecaa9303c54846fcd8cd0ee0..f6d0a67dba137ced0b21cc68e2c66c596edecf27 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
-  CPU DXE Module.\r
+  CPU DXE Module to produce CPU ARCH Protocol.\r
 \r
-  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2016, 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
 #include "CpuDxe.h"\r
+#include "CpuMp.h"\r
 \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
-UINT8                     mDefaultMemoryType    = MTRR_CACHE_WRITE_BACK;\r
 UINT64                    mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;\r
 UINT64                    mValidMtrrBitsMask    = MTRR_LIB_MSR_VALID_MASK;\r
 \r
@@ -99,259 +96,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
@@ -509,21 +257,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
-  SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL);\r
-  ExternalVectorTable[InterruptType] = InterruptHandler;\r
-  return EFI_SUCCESS;\r
+  return RegisterCpuInterruptHandler (InterruptType, InterruptHandler);\r
 }\r
 \r
 \r
@@ -579,6 +313,21 @@ CpuGetTimerValue (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  A minimal wrapper function that allows MtrrSetAllMtrrs() to be passed to\r
+  EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() as Procedure.\r
+\r
+  @param[in] Buffer  Pointer to an MTRR_SETTINGS object, to be passed to\r
+                     MtrrSetAllMtrrs().\r
+**/\r
+VOID\r
+EFIAPI\r
+SetMtrrsFromBuffer (\r
+  IN VOID *Buffer\r
+  )\r
+{\r
+  MtrrSetAllMtrrs (Buffer);\r
+}\r
 \r
 /**\r
   Implementation of SetMemoryAttributes() service of CPU Architecture Protocol.\r
@@ -616,6 +365,9 @@ CpuSetMemoryAttributes (
 {\r
   RETURN_STATUS             Status;\r
   MTRR_MEMORY_CACHE_TYPE    CacheType;\r
+  EFI_STATUS                MpStatus;\r
+  EFI_MP_SERVICES_PROTOCOL  *MpService;\r
+  MTRR_SETTINGS             MtrrSettings;\r
 \r
   if (!IsMtrrSupported ()) {\r
     return EFI_UNSUPPORTED;\r
@@ -628,9 +380,9 @@ CpuSetMemoryAttributes (
   // to avoid unnecessary computing.\r
   //\r
   if (mIsFlushingGCD) {\r
-    DEBUG((EFI_D_ERROR, "  Flushing GCD\n"));\r
-      return EFI_SUCCESS;\r
-    }\r
+    DEBUG((EFI_D_INFO, "  Flushing GCD\n"));\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
   switch (Attributes) {\r
   case EFI_MEMORY_UC:\r
@@ -671,6 +423,29 @@ CpuSetMemoryAttributes (
              CacheType\r
              );\r
 \r
+  if (!RETURN_ERROR (Status)) {\r
+    MpStatus = gBS->LocateProtocol (\r
+                      &gEfiMpServiceProtocolGuid,\r
+                      NULL,\r
+                      (VOID **)&MpService\r
+                      );\r
+    //\r
+    // Synchronize the update with all APs\r
+    //\r
+    if (!EFI_ERROR (MpStatus)) {\r
+      MtrrGetAllMtrrs (&MtrrSettings);\r
+      MpStatus = MpService->StartupAllAPs (\r
+                              MpService,          // This\r
+                              SetMtrrsFromBuffer, // Procedure\r
+                              FALSE,              // SingleThread\r
+                              NULL,               // WaitEvent\r
+                              0,                  // TimeoutInMicrosecsond\r
+                              &MtrrSettings,      // ProcedureArgument\r
+                              NULL                // FailedCpuList\r
+                              );\r
+      ASSERT (MpStatus == EFI_SUCCESS || MpStatus == EFI_NOT_STARTED);\r
+    }\r
+  }\r
   return (EFI_STATUS) Status;\r
 }\r
 \r
@@ -887,6 +662,7 @@ RefreshGcdMemoryAttributes (
   VARIABLE_MTRR                       VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
   MTRR_FIXED_SETTINGS                 MtrrFixedSettings;\r
   UINT32                              FirmwareVariableMtrrCount;\r
+  UINT8                               DefaultMemoryType;\r
 \r
   if (!IsMtrrSupported ()) {\r
     return;\r
@@ -895,8 +671,7 @@ RefreshGcdMemoryAttributes (
   FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
   ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
 \r
-//  mIsFlushingGCD = TRUE;\r
-  mIsFlushingGCD = FALSE;\r
+  mIsFlushingGCD = TRUE;\r
   MemorySpaceMap = NULL;\r
 \r
   //\r
@@ -922,7 +697,8 @@ RefreshGcdMemoryAttributes (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  DefaultAttributes = GetMemorySpaceAttributeFromMtrrType (mDefaultMemoryType);\r
+  DefaultMemoryType = (UINT8) MtrrGetDefaultMemoryType ();\r
+  DefaultAttributes = GetMemorySpaceAttributeFromMtrrType (DefaultMemoryType);\r
 \r
   //\r
   // Set default attributes to all spaces.\r
@@ -954,12 +730,14 @@ RefreshGcdMemoryAttributes (
         );\r
     }\r
   }\r
+\r
   //\r
-  // Go for variable MTRRs with Non-WB attribute\r
+  // Go for variable MTRRs with the attribute except for WB and UC attributes\r
   //\r
   for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
     if (VariableMtrr[Index].Valid &&\r
-        VariableMtrr[Index].Type != MTRR_CACHE_WRITE_BACK) {\r
+        VariableMtrr[Index].Type != MTRR_CACHE_WRITE_BACK &&\r
+        VariableMtrr[Index].Type != MTRR_CACHE_UNCACHEABLE) {\r
       Attributes = GetMemorySpaceAttributeFromMtrrType ((UINT8) VariableMtrr[Index].Type);\r
       SetGcdMemorySpaceAttributes (\r
         MemorySpaceMap,\r
@@ -971,6 +749,22 @@ RefreshGcdMemoryAttributes (
     }\r
   }\r
 \r
+  //\r
+  // Go for variable MTRRs with UC attribute\r
+  //\r
+  for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
+    if (VariableMtrr[Index].Valid &&\r
+        VariableMtrr[Index].Type == MTRR_CACHE_UNCACHEABLE) {\r
+      SetGcdMemorySpaceAttributes (\r
+        MemorySpaceMap,\r
+        NumberOfDescriptors,\r
+        VariableMtrr[Index].BaseAddress,\r
+        VariableMtrr[Index].Length,\r
+        EFI_MEMORY_UC\r
+        );\r
+    }\r
+  }\r
+\r
   //\r
   // Go for fixed MTRRs\r
   //\r
@@ -1032,38 +826,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
 /**\r
   Initialize Interrupt Descriptor Table for interrupt handling.\r
 \r
@@ -1073,90 +835,23 @@ 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
-  } 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
-          (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
 /**\r
   Callback function for idle events.\r
\r
+\r
   @param  Event                 Event whose notification function is being invoked.\r
   @param  Context               The pointer to the notification function's context,\r
                                 which is implementation-dependent.\r
@@ -1194,6 +889,8 @@ InitializeCpu (
   EFI_STATUS  Status;\r
   EFI_EVENT   IdleLoopEvent;\r
 \r
+  InitializeFloatingPointUnits ();\r
+\r
   //\r
   // Make sure interrupts are disabled\r
   //\r
@@ -1209,6 +906,11 @@ InitializeCpu (
   //\r
   InitInterruptDescriptorTable ();\r
 \r
+  //\r
+  // Enable the local APIC for Virtual Wire Mode.\r
+  //\r
+  ProgramVirtualWireMode ();\r
+\r
   //\r
   // Install CPU Architectural Protocol\r
   //\r
@@ -1237,6 +939,8 @@ InitializeCpu (
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  InitializeMpSupport ();\r
+\r
   return Status;\r
 }\r
 \r