]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/MtrrLib.c
Update the copyright notice format
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / MtrrLib.c
index 1a8ffc2cdc234d4dd54f10d3f5d6897945da279c..2bf0ce74bb5e5f17ae9b1df516b7b9db9effc5b7 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   MTRR setting library\r
 \r
-  Copyright (c) 2008 - 2010, Intel Corporation\r
-  All rights reserved. This program and the accompanying materials\r
+  Copyright (c) 2008 - 2010, 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
@@ -89,10 +89,15 @@ FIXED_MTRR    MtrrLibFixedMtrrTable[] = {
 \r
 **/\r
 UINT32\r
+EFIAPI\r
 GetVariableMtrrCount (\r
   VOID\r
   )\r
 {\r
+  if (!IsMtrrSupported ()) {\r
+    return 0;\r
+  }\r
+\r
   return (UINT32)(AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP) & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK);\r
 }\r
 \r
@@ -103,11 +108,19 @@ GetVariableMtrrCount (
 \r
 **/\r
 UINT32\r
+EFIAPI\r
 GetFirmwareVariableMtrrCount (\r
   VOID\r
   )\r
 {\r
-  return GetVariableMtrrCount () - RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER;\r
+  UINT32  VariableMtrrCount;\r
+\r
+  VariableMtrrCount = GetVariableMtrrCount ();\r
+  if (VariableMtrrCount < RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER) {\r
+    return 0;\r
+  }\r
+\r
+  return VariableMtrrCount - RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER;\r
 }\r
 \r
 /**\r
@@ -144,28 +157,27 @@ PreMtrrChange (
   //\r
   // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)\r
   //\r
-  Value = AsmReadCr0 ();\r
-  Value = (UINTN) BitFieldWrite64 (Value, 30, 30, 1);\r
-  Value = (UINTN) BitFieldWrite64 (Value, 29, 29, 0);\r
-  AsmWriteCr0 (Value);\r
-  //\r
-  // Flush cache\r
-  //\r
-  AsmWbinvd ();\r
+  AsmDisableCache ();\r
+\r
   //\r
-  // Clear PGE flag Bit 7\r
+  // Save original CR4 value and clear PGE flag (Bit 7)\r
   //\r
   Value = AsmReadCr4 ();\r
-  AsmWriteCr4 ((UINTN) BitFieldWrite64 (Value, 7, 7, 0));\r
+  AsmWriteCr4 (Value & (~BIT7));\r
+\r
   //\r
   // Flush all TLBs\r
   //\r
   CpuFlushTlb ();\r
+\r
   //\r
   // Disable Mtrrs\r
   //\r
   AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 0);\r
 \r
+  //\r
+  // Return original CR4 value\r
+  //\r
   return Value;\r
 }\r
 \r
@@ -184,30 +196,25 @@ PostMtrrChange (
   UINTN Cr4\r
   )\r
 {\r
-  UINTN  Value;\r
-\r
   //\r
   // Enable Cache MTRR\r
   //\r
   AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3);\r
 \r
   //\r
-  // Flush all TLBs and cache the second time\r
+  // Flush all TLBs \r
   //\r
-  AsmWbinvd ();\r
   CpuFlushTlb ();\r
 \r
   //\r
   // Enable Normal Mode caching CD=NW=0, CD(Bit30), NW(Bit29)\r
   //\r
-  Value = AsmReadCr0 ();\r
-  Value = (UINTN) BitFieldWrite64 (Value, 30, 30, 0);\r
-  Value = (UINTN) BitFieldWrite64 (Value, 29, 29, 0);\r
-  AsmWriteCr0 (Value);\r
+  AsmEnableCache ();\r
 \r
+  //\r
+  // Restore original CR4 value\r
+  //\r
   AsmWriteCr4 (Cr4);\r
-\r
-  return ;\r
 }\r
 \r
 \r
@@ -325,6 +332,10 @@ MtrrGetMemoryAttributeInVariableMtrr (
   UINT32  FirmwareVariableMtrrCount;\r
   UINT32  VariableMtrrEnd;\r
 \r
+  if (!IsMtrrSupported ()) {\r
+    return 0;\r
+  }\r
+\r
   FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
   VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;\r
 \r
@@ -876,6 +887,10 @@ MtrrSetMemoryAttribute (
   UINT32                    FirmwareVariableMtrrCount;\r
   UINT32                    VariableMtrrEnd;\r
 \r
+  if (!IsMtrrSupported ()) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
   FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
   VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;\r
 \r
@@ -1116,6 +1131,10 @@ MtrrGetMemoryAttribute (
   UINT64                  MtrrValidAddressMask;\r
   UINTN                   VariableMtrrCount;\r
 \r
+  if (!IsMtrrSupported ()) {\r
+    return CacheUncacheable;\r
+  }\r
+\r
   //\r
   // Check if MTRR is enabled, if not, return UC as attribute\r
   //\r
@@ -1162,6 +1181,8 @@ MtrrGetMemoryAttribute (
   // Go through the variable MTRR\r
   //\r
   VariableMtrrCount = GetVariableMtrrCount ();\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+\r
   for (Index = 0; Index < VariableMtrrCount; Index++) {\r
     if (VariableMtrr[Index].Valid) {\r
       if (Address >= VariableMtrr[Index].BaseAddress &&\r
@@ -1194,7 +1215,13 @@ MtrrGetVariableMtrr (
   UINT32  Index;\r
   UINT32  VariableMtrrCount;\r
 \r
+  if (!IsMtrrSupported ()) {\r
+    return VariableSettings;\r
+  }\r
+\r
   VariableMtrrCount = GetVariableMtrrCount ();\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+\r
   for (Index = 0; Index < VariableMtrrCount; Index++) {\r
     VariableSettings->Mtrr[Index].Base =\r
       AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1));\r
@@ -1221,6 +1248,8 @@ MtrrSetVariableMtrrWorker (
   UINT32  VariableMtrrCount;\r
 \r
   VariableMtrrCount = GetVariableMtrrCount ();\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+\r
   for (Index = 0; Index < VariableMtrrCount; Index++) {\r
     AsmWriteMsr64 (\r
       MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1),\r
@@ -1250,6 +1279,10 @@ MtrrSetVariableMtrr (
 {\r
   UINTN  Cr4;\r
 \r
+  if (!IsMtrrSupported ()) {\r
+    return VariableSettings;\r
+  }\r
+\r
   Cr4 = PreMtrrChange ();\r
   MtrrSetVariableMtrrWorker (VariableSettings);\r
   PostMtrrChange (Cr4);\r
@@ -1273,6 +1306,10 @@ MtrrGetFixedMtrr (
 {\r
   UINT32  Index;\r
 \r
+  if (!IsMtrrSupported ()) {\r
+    return FixedSettings;\r
+  }\r
+\r
   for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
       FixedSettings->Mtrr[Index] =\r
         AsmReadMsr64 (MtrrLibFixedMtrrTable[Index].Msr);\r
@@ -1319,6 +1356,10 @@ MtrrSetFixedMtrr (
 {\r
   UINTN  Cr4;\r
 \r
+  if (!IsMtrrSupported ()) {\r
+    return FixedSettings;\r
+  }\r
+\r
   Cr4 = PreMtrrChange ();\r
   MtrrSetFixedMtrrWorker (FixedSettings);\r
   PostMtrrChange (Cr4);\r
@@ -1341,6 +1382,10 @@ MtrrGetAllMtrrs (
   OUT MTRR_SETTINGS                *MtrrSetting\r
   )\r
 {\r
+  if (!IsMtrrSupported ()) {\r
+    return MtrrSetting;\r
+  }\r
+\r
   //\r
   // Get fixed MTRRs\r
   //\r
@@ -1376,6 +1421,10 @@ MtrrSetAllMtrrs (
 {\r
   UINTN  Cr4;\r
 \r
+  if (!IsMtrrSupported ()) {\r
+    return MtrrSetting;\r
+  }\r
+\r
   Cr4 = PreMtrrChange ();\r
 \r
   //\r
@@ -1412,6 +1461,10 @@ MtrrDebugPrintAllMtrrs (
       UINTN          Index;\r
       UINTN          VariableMtrrCount;\r
 \r
+      if (!IsMtrrSupported ()) {\r
+        return;\r
+      }\r
+\r
       MtrrGetAllMtrrs (&MtrrSettings);\r
       DEBUG((EFI_D_ERROR, "DefaultType = %016lx\n", MtrrSettings.MtrrDefType));\r
       for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
@@ -1435,3 +1488,39 @@ MtrrDebugPrintAllMtrrs (
   );\r
 }\r
 \r
+/**\r
+  Checks if MTRR is supported.\r
+\r
+  @retval TRUE  MTRR is supported.\r
+  @retval FALSE MTRR is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+IsMtrrSupported (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  RegEdx;\r
+  UINT64  MtrrCap;\r
+\r
+  //\r
+  // Check CPUID(1).EDX[12] for MTRR capability\r
+  //\r
+  AsmCpuid (1, NULL, NULL, NULL, &RegEdx);\r
+  if (BitFieldRead32 (RegEdx, 12, 12) == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Check IA32_MTRRCAP.[0..7] for number of variable MTRRs and IA32_MTRRCAP[8] for\r
+  // fixed MTRRs existence. If number of variable MTRRs is zero, or fixed MTRRs do not\r
+  // exist, return false.\r
+  //\r
+  MtrrCap = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP);\r
+  if  ((BitFieldRead64 (MtrrCap, 0, 7) == 0) || (BitFieldRead64 (MtrrCap, 8, 8) == 0)) {\r
+    return FALSE;\r
+  }\r
+\r
+  return TRUE;\r
+}\r