]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuDxe/CpuDxe.c
UefiCpuPkg: Clean up source files
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / CpuDxe.c
index bd0aedc7fb457d27fba9bea44630aa97498ce7c3..cfd4c415aedcb867d7549664b928f969cce8d1c5 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   CPU DXE Module to produce CPU ARCH Protocol.\r
 \r
-  Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2018, 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
 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
+BOOLEAN                   mIsAllocatingPageTable = FALSE;\r
+UINT64                    mValidMtrrAddressMask;\r
+UINT64                    mValidMtrrBitsMask;\r
+UINT64                    mTimerPeriod = 0;\r
 \r
 FIXED_MTRR    mFixedMtrrTable[] = {\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX64K_00000,\r
+    MSR_IA32_MTRR_FIX64K_00000,\r
     0,\r
     0x10000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX16K_80000,\r
+    MSR_IA32_MTRR_FIX16K_80000,\r
     0x80000,\r
     0x4000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX16K_A0000,\r
+    MSR_IA32_MTRR_FIX16K_A0000,\r
     0xA0000,\r
     0x4000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX4K_C0000,\r
+    MSR_IA32_MTRR_FIX4K_C0000,\r
     0xC0000,\r
     0x1000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX4K_C8000,\r
+    MSR_IA32_MTRR_FIX4K_C8000,\r
     0xC8000,\r
     0x1000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX4K_D0000,\r
+    MSR_IA32_MTRR_FIX4K_D0000,\r
     0xD0000,\r
     0x1000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX4K_D8000,\r
+    MSR_IA32_MTRR_FIX4K_D8000,\r
     0xD8000,\r
     0x1000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX4K_E0000,\r
+    MSR_IA32_MTRR_FIX4K_E0000,\r
     0xE0000,\r
     0x1000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX4K_E8000,\r
+    MSR_IA32_MTRR_FIX4K_E8000,\r
     0xE8000,\r
     0x1000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX4K_F0000,\r
+    MSR_IA32_MTRR_FIX4K_F0000,\r
     0xF0000,\r
     0x1000\r
   },\r
   {\r
-    MTRR_LIB_IA32_MTRR_FIX4K_F8000,\r
+    MSR_IA32_MTRR_FIX4K_F8000,\r
     0xF8000,\r
     0x1000\r
   },\r
@@ -297,6 +299,9 @@ CpuGetTimerValue (
   OUT UINT64                    *TimerPeriod OPTIONAL\r
   )\r
 {\r
+  UINT64          BeginValue;\r
+  UINT64          EndValue;\r
+\r
   if (TimerValue == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -308,10 +313,26 @@ CpuGetTimerValue (
   *TimerValue = AsmReadTsc ();\r
 \r
   if (TimerPeriod != NULL) {\r
+    if (mTimerPeriod == 0) {\r
+      //\r
+      // Read time stamp counter before and after delay of 100 microseconds\r
       //\r
-      // BugBug: Hard coded. Don't know how to do this generically\r
+      BeginValue = AsmReadTsc ();\r
+      MicroSecondDelay (100);\r
+      EndValue   = AsmReadTsc ();\r
       //\r
-      *TimerPeriod = 1000000000;\r
+      // Calculate the actual frequency\r
+      //\r
+      mTimerPeriod = DivU64x64Remainder (\r
+                       MultU64x32 (\r
+                         1000 * 1000 * 1000,\r
+                         100\r
+                         ),\r
+                       EndValue - BeginValue,\r
+                       NULL\r
+                       );\r
+    }\r
+    *TimerPeriod = mTimerPeriod;\r
   }\r
 \r
   return EFI_SUCCESS;\r
@@ -383,10 +404,24 @@ CpuSetMemoryAttributes (
   // to avoid unnecessary computing.\r
   //\r
   if (mIsFlushingGCD) {\r
-    DEBUG((EFI_D_INFO, "  Flushing GCD\n"));\r
+    DEBUG((DEBUG_INFO, "  Flushing GCD\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
+  //\r
+  // During memory attributes updating, new pages may be allocated to setup\r
+  // smaller granularity of page table. Page allocation action might then cause\r
+  // another calling of CpuSetMemoryAttributes() recursively, due to memory\r
+  // protection policy configured (such as PcdDxeNxMemoryProtectionPolicy).\r
+  // Since this driver will always protect memory used as page table by itself,\r
+  // there's no need to apply protection policy requested from memory service.\r
+  // So it's safe to just return EFI_SUCCESS if this time of calling is caused\r
+  // by page table memory allocation.\r
+  //\r
+  if (mIsAllocatingPageTable) {\r
+    DEBUG((DEBUG_VERBOSE, "  Allocating page table memory\n"));\r
+    return EFI_SUCCESS;\r
+  }\r
 \r
   CacheAttributes = Attributes & CACHE_ATTRIBUTE_MASK;\r
   MemoryAttributes = Attributes & MEMORY_ATTRIBUTE_MASK;\r
@@ -467,7 +502,7 @@ CpuSetMemoryAttributes (
   //\r
   // Set memory attribute by page table\r
   //\r
-  return AssignMemoryPageAttributes (NULL, BaseAddress, Length, MemoryAttributes, AllocatePages);\r
+  return AssignMemoryPageAttributes (NULL, BaseAddress, Length, MemoryAttributes, NULL);\r
 }\r
 \r
 /**\r
@@ -490,13 +525,12 @@ InitializeMtrrMask (
     AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
 \r
     PhysicalAddressBits = (UINT8) RegEax;\r
-\r
-    mValidMtrrBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;\r
-    mValidMtrrAddressMask = mValidMtrrBitsMask & 0xfffffffffffff000ULL;\r
   } else {\r
-    mValidMtrrBitsMask    = MTRR_LIB_MSR_VALID_MASK;\r
-    mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;\r
+    PhysicalAddressBits = 36;\r
   }\r
+\r
+  mValidMtrrBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;\r
+  mValidMtrrAddressMask = mValidMtrrBitsMask & 0xfffffffffffff000ULL;\r
 }\r
 \r
 /**\r
@@ -664,7 +698,7 @@ SetGcdMemorySpaceAttributes (
 \r
 **/\r
 VOID\r
-RefreshGcdMemoryAttributes (\r
+RefreshMemoryAttributesFromMtrr (\r
   VOID\r
   )\r
 {\r
@@ -685,14 +719,9 @@ RefreshGcdMemoryAttributes (
   UINT32                              FirmwareVariableMtrrCount;\r
   UINT8                               DefaultMemoryType;\r
 \r
-  if (!IsMtrrSupported ()) {\r
-    return;\r
-  }\r
-\r
   FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
   ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
 \r
-  mIsFlushingGCD = TRUE;\r
   MemorySpaceMap = NULL;\r
 \r
   //\r
@@ -843,6 +872,46 @@ RefreshGcdMemoryAttributes (
   if (MemorySpaceMap != NULL) {\r
     FreePool (MemorySpaceMap);\r
   }\r
+}\r
+\r
+/**\r
+ Check if paging is enabled or not.\r
+**/\r
+BOOLEAN\r
+IsPagingAndPageAddressExtensionsEnabled (\r
+  VOID\r
+  )\r
+{\r
+  IA32_CR0  Cr0;\r
+  IA32_CR4  Cr4;\r
+\r
+  Cr0.UintN = AsmReadCr0 ();\r
+  Cr4.UintN = AsmReadCr4 ();\r
+\r
+  return ((Cr0.Bits.PG != 0) && (Cr4.Bits.PAE != 0));\r
+}\r
+\r
+/**\r
+  Refreshes the GCD Memory Space attributes according to MTRRs and Paging.\r
+\r
+  This function refreshes the GCD Memory Space attributes according to MTRRs\r
+  and page tables.\r
+\r
+**/\r
+VOID\r
+RefreshGcdMemoryAttributes (\r
+  VOID\r
+  )\r
+{\r
+  mIsFlushingGCD = TRUE;\r
+\r
+  if (IsMtrrSupported ()) {\r
+    RefreshMemoryAttributesFromMtrr ();\r
+  }\r
+\r
+  if (IsPagingAndPageAddressExtensionsEnabled ()) {\r
+    RefreshGcdMemoryAttributesFromPaging ();\r
+  }\r
 \r
   mIsFlushingGCD = FALSE;\r
 }\r
@@ -959,13 +1028,13 @@ IntersectMemoryDescriptor (
                     IntersectionBase, IntersectionEnd - IntersectionBase,\r
                     Capabilities);\r
 \r
-    DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE,\r
+    DEBUG ((EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,\r
       "%a: %a: add [%Lx, %Lx): %r\n", gEfiCallerBaseName, __FUNCTION__,\r
       IntersectionBase, IntersectionEnd, Status));\r
     return Status;\r
   }\r
 \r
-  DEBUG ((EFI_D_ERROR, "%a: %a: desc [%Lx, %Lx) type %u cap %Lx conflicts "\r
+  DEBUG ((DEBUG_ERROR, "%a: %a: desc [%Lx, %Lx) type %u cap %Lx conflicts "\r
     "with aperture [%Lx, %Lx) cap %Lx\n", gEfiCallerBaseName, __FUNCTION__,\r
     Descriptor->BaseAddress, Descriptor->BaseAddress + Descriptor->Length,\r
     (UINT32)Descriptor->GcdMemoryType, Descriptor->Capabilities,\r
@@ -998,7 +1067,7 @@ AddMemoryMappedIoSpace (
 \r
   Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);\r
   if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "%a: %a: GetMemorySpaceMap(): %r\n",\r
+    DEBUG ((DEBUG_ERROR, "%a: %a: GetMemorySpaceMap(): %r\n",\r
       gEfiCallerBaseName, __FUNCTION__, Status));\r
     return Status;\r
   }\r
@@ -1037,6 +1106,44 @@ FreeMemorySpaceMap:
   return Status;\r
 }\r
 \r
+/**\r
+  Add and allocate CPU local APIC memory mapped space.\r
+\r
+  @param[in]ImageHandle     Image handle this driver.\r
+\r
+**/\r
+VOID\r
+AddLocalApicMemorySpace (\r
+  IN EFI_HANDLE               ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_PHYSICAL_ADDRESS    BaseAddress;\r
+\r
+  BaseAddress = (EFI_PHYSICAL_ADDRESS) GetLocalApicBaseAddress();\r
+  Status = AddMemoryMappedIoSpace (BaseAddress, SIZE_4KB, EFI_MEMORY_UC);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Try to allocate APIC memory mapped space, does not check return\r
+  // status because it may be allocated by other driver, or DXE Core if\r
+  // this range is built into Memory Allocation HOB.\r
+  //\r
+  Status = gDS->AllocateMemorySpace (\r
+                  EfiGcdAllocateAddress,\r
+                  EfiGcdMemoryTypeMemoryMappedIo,\r
+                  0,\r
+                  SIZE_4KB,\r
+                  &BaseAddress,\r
+                  ImageHandle,\r
+                  NULL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_INFO, "%a: %a: AllocateMemorySpace() Status - %r\n",\r
+                         gEfiCallerBaseName, __FUNCTION__, Status));\r
+  }\r
+}\r
+\r
 /**\r
   Initialize the state information for the CPU Architectural Protocol.\r
 \r
@@ -1057,7 +1164,7 @@ InitializeCpu (
 {\r
   EFI_STATUS  Status;\r
   EFI_EVENT   IdleLoopEvent;\r
-  \r
+\r
   InitializePageTableLib();\r
 \r
   InitializeFloatingPointUnits ();\r
@@ -1077,11 +1184,6 @@ 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
@@ -1097,6 +1199,11 @@ InitializeCpu (
   //\r
   RefreshGcdMemoryAttributes ();\r
 \r
+  //\r
+  // Add and allocate local APIC memory mapped space\r
+  //\r
+  AddLocalApicMemorySpace (ImageHandle);\r
+\r
   //\r
   // Setup a callback for idle events\r
   //\r