]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuDxe/CpuDxe.c
Fix a bug about the iSCSI DHCP dependency issue.
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / CpuDxe.c
index 04d76a5cebe886b361b3499604b626abc7c24c97..2dfde0677d88b54d5988bf974bbfa5f853dbacdc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   CPU DXE Module.\r
 \r
-  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 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
 //\r
 // Global Variables\r
 //\r
-IA32_IDT_GATE_DESCRIPTOR  gIdtTable[INTERRUPT_VECTOR_NUMBER] = { 0 };\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
+IA32_IDT_GATE_DESCRIPTOR  *mOrigIdtEntry        = NULL;\r
+UINT16                    mOrigIdtEntryCount    = 0;\r
 \r
 FIXED_MTRR    mFixedMtrrTable[] = {\r
   {\r
@@ -521,7 +522,15 @@ CpuRegisterInterruptHandler (
     return EFI_ALREADY_STARTED;\r
   }\r
 \r
-  SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL);\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
 }\r
@@ -628,9 +637,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
@@ -887,6 +896,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 +905,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 +931,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 +964,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 +983,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
@@ -1063,6 +1091,25 @@ SetInterruptDescriptorTableHandlerAddress (
 #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
@@ -1093,6 +1140,12 @@ InitInterruptDescriptorTable (
   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
@@ -1108,10 +1161,10 @@ InitInterruptDescriptorTable (
     // preserve it.\r
     //\r
     if (Index < OldIdtSize) {\r
-      IntHandler = \r
+      IntHandler =\r
         (VOID*) (\r
           OldIdt[Index].Bits.OffsetLow +\r
-          (OldIdt[Index].Bits.OffsetHigh << 16)\r
+          (((UINTN) OldIdt[Index].Bits.OffsetHigh) << 16)\r
 #if defined (MDE_CPU_X64)\r
             + (((UINTN) OldIdt[Index].Bits.OffsetUpper) << 32)\r
 #endif\r
@@ -1154,6 +1207,25 @@ InitInterruptDescriptorTable (
 }\r
 \r
 \r
+/**\r
+  Callback function for idle events.\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
+\r
+**/\r
+VOID\r
+EFIAPI\r
+IdleLoopEventCallback (\r
+  IN EFI_EVENT                Event,\r
+  IN VOID                     *Context\r
+  )\r
+{\r
+  CpuSleep ();\r
+}\r
+\r
+\r
 /**\r
   Initialize the state information for the CPU Architectural Protocol.\r
 \r
@@ -1173,6 +1245,9 @@ InitializeCpu (
   )\r
 {\r
   EFI_STATUS  Status;\r
+  EFI_EVENT   IdleLoopEvent;\r
+\r
+  InitializeFloatingPointUnits ();\r
 \r
   //\r
   // Make sure interrupts are disabled\r
@@ -1189,6 +1264,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
@@ -1204,6 +1284,19 @@ InitializeCpu (
   //\r
   RefreshGcdMemoryAttributes ();\r
 \r
+  //\r
+  // Setup a callback for idle events\r
+  //\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  IdleLoopEventCallback,\r
+                  NULL,\r
+                  &gIdleLoopEventGuid,\r
+                  &IdleLoopEvent\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   return Status;\r
 }\r
 \r