]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Save and disable CPU interrupt before programming MTRR settings, and restore the...
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 27 Sep 2012 03:04:31 +0000 (03:04 +0000)
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 27 Sep 2012 03:04:31 +0000 (03:04 +0000)
signed-off-by: Kinney, Michael D <michael.d.kinney@intel.com>
reviewed-by: Bjorge, Erik C <erik.c.bjorge@intel.com>
reviewed-by: Jeff Fan <jeff.fan@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13749 6f19259b-4bc3-4df7-8a09-765794883524

UefiCpuPkg/Library/MtrrLib/MtrrLib.c

index b598d51b4b86c4c62724c50027ab1dc24fa9af02..dea474dd9451f38b1075a080cf3b9a1b218e5f82 100644 (file)
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 \r
+//\r
+// Context to save and restore when MTRRs are programmed\r
+//\r
+typedef struct {\r
+  UINTN    Cr4;\r
+  BOOLEAN  InterruptState;\r
+} MTRR_CONTEXT;\r
+\r
 //\r
 // This table defines the offset, base and length of the fixed MTRRs\r
 //\r
@@ -166,16 +174,19 @@ MtrrGetDefaultMemoryType (
   This function will do some preparation for programming MTRRs:\r
   disable cache, invalid cache and disable MTRR caching functionality\r
 \r
-  @return  CR4 value before changing.\r
+  @param[out]  Pointer to context to save\r
 \r
 **/\r
-UINTN\r
+VOID\r
 PreMtrrChange (\r
-  VOID\r
+  OUT MTRR_CONTEXT  *MtrrContext\r
   )\r
 {\r
-  UINTN  Value;\r
-\r
+  //\r
+  // Disable interrupts and save current interrupt state\r
+  //\r
+  MtrrContext->InterruptState = SaveAndDisableInterrupts();\r
+  \r
   //\r
   // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)\r
   //\r
@@ -184,8 +195,8 @@ PreMtrrChange (
   //\r
   // Save original CR4 value and clear PGE flag (Bit 7)\r
   //\r
-  Value = AsmReadCr4 ();\r
-  AsmWriteCr4 (Value & (~BIT7));\r
+  MtrrContext->Cr4 = AsmReadCr4 ();\r
+  AsmWriteCr4 (MtrrContext->Cr4 & (~BIT7));\r
 \r
   //\r
   // Flush all TLBs\r
@@ -196,11 +207,6 @@ PreMtrrChange (
   // 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
 /**\r
@@ -209,12 +215,12 @@ PreMtrrChange (
   This function will do some clean up after programming MTRRs:\r
   Flush all TLBs,  re-enable caching, restore CR4.\r
 \r
-  @param  Cr4  CR4 value to restore\r
+  @param[in]  Pointer to context to restore\r
 \r
 **/\r
 VOID\r
 PostMtrrChangeEnableCache (\r
-  IN UINTN  Cr4\r
+  IN MTRR_CONTEXT  *MtrrContext\r
   )\r
 {\r
   //\r
@@ -230,7 +236,12 @@ PostMtrrChangeEnableCache (
   //\r
   // Restore original CR4 value\r
   //\r
-  AsmWriteCr4 (Cr4);\r
+  AsmWriteCr4 (MtrrContext->Cr4);\r
+  \r
+  //\r
+  // Restore original interrupt state\r
+  //\r
+  SetInterruptState (MtrrContext->InterruptState);\r
 }\r
 \r
 /**\r
@@ -239,12 +250,12 @@ PostMtrrChangeEnableCache (
   This function will do some clean up after programming MTRRs:\r
   enable MTRR caching functionality, and enable cache\r
 \r
-  @param  Cr4  CR4 value to restore\r
+  @param[in]  Pointer to context to restore\r
 \r
 **/\r
 VOID\r
 PostMtrrChange (\r
-  IN UINTN  Cr4\r
+  IN MTRR_CONTEXT  *MtrrContext\r
   )\r
 {\r
   //\r
@@ -252,7 +263,7 @@ PostMtrrChange (
   //\r
   AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3);\r
 \r
-  PostMtrrChangeEnableCache (Cr4);\r
+  PostMtrrChangeEnableCache (MtrrContext);\r
 }\r
 \r
 \r
@@ -704,11 +715,11 @@ InvalidateMtrr (
    IN     VARIABLE_MTRR      *VariableMtrr\r
    )\r
 {\r
-  UINTN Index;\r
-  UINTN Cr4;\r
-  UINTN VariableMtrrCount;\r
+  UINTN         Index;\r
+  UINTN         VariableMtrrCount;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
   Index = 0;\r
   VariableMtrrCount = GetVariableMtrrCount ();\r
   while (Index < VariableMtrrCount) {\r
@@ -719,7 +730,7 @@ InvalidateMtrr (
     }\r
     Index ++;\r
   }\r
-  PostMtrrChange (Cr4);\r
+  PostMtrrChange (&MtrrContext);\r
 }\r
 \r
 \r
@@ -744,10 +755,10 @@ ProgramVariableMtrr (
   IN UINT64                   MtrrValidAddressMask\r
   )\r
 {\r
-  UINT64  TempQword;\r
-  UINTN   Cr4;\r
+  UINT64        TempQword;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
 \r
   //\r
   // MTRR Physical Base\r
@@ -764,7 +775,7 @@ ProgramVariableMtrr (
     (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED\r
     );\r
 \r
-  PostMtrrChange (Cr4);\r
+  PostMtrrChange (&MtrrContext);\r
 }\r
 \r
 \r
@@ -953,10 +964,10 @@ MtrrSetMemoryAttribute (
   UINT32                    UsedMtrr;\r
   UINT64                    MtrrValidBitsMask;\r
   UINT64                    MtrrValidAddressMask;\r
-  UINTN                     Cr4;\r
   BOOLEAN                   OverwriteExistingMtrr;\r
   UINT32                    FirmwareVariableMtrrCount;\r
   UINT32                    VariableMtrrEnd;\r
+  MTRR_CONTEXT              MtrrContext;\r
 \r
   DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
 \r
@@ -995,9 +1006,9 @@ MtrrSetMemoryAttribute (
   //\r
   Status = RETURN_SUCCESS;\r
   while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {\r
-    Cr4 = PreMtrrChange ();\r
+    PreMtrrChange (&MtrrContext);\r
     Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);\r
-    PostMtrrChange (Cr4);\r
+    PostMtrrChange (&MtrrContext);\r
     if (RETURN_ERROR (Status)) {\r
       goto Done;\r
     }\r
@@ -1353,15 +1364,15 @@ MtrrSetVariableMtrr (
   IN MTRR_VARIABLE_SETTINGS         *VariableSettings\r
   )\r
 {\r
-  UINTN  Cr4;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
   if (!IsMtrrSupported ()) {\r
     return VariableSettings;\r
   }\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
   MtrrSetVariableMtrrWorker (VariableSettings);\r
-  PostMtrrChange (Cr4);\r
+  PostMtrrChange (&MtrrContext);\r
   return  VariableSettings;\r
 }\r
 \r
@@ -1430,15 +1441,15 @@ MtrrSetFixedMtrr (
   IN MTRR_FIXED_SETTINGS          *FixedSettings\r
   )\r
 {\r
-  UINTN  Cr4;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
   if (!IsMtrrSupported ()) {\r
     return FixedSettings;\r
   }\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
   MtrrSetFixedMtrrWorker (FixedSettings);\r
-  PostMtrrChange (Cr4);\r
+  PostMtrrChange (&MtrrContext);\r
 \r
   return FixedSettings;\r
 }\r
@@ -1495,13 +1506,13 @@ MtrrSetAllMtrrs (
   IN MTRR_SETTINGS                *MtrrSetting\r
   )\r
 {\r
-  UINTN  Cr4;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
   if (!IsMtrrSupported ()) {\r
     return MtrrSetting;\r
   }\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
 \r
   //\r
   // Set fixed MTRRs\r
@@ -1518,7 +1529,7 @@ MtrrSetAllMtrrs (
   //\r
   AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType);\r
 \r
-  PostMtrrChangeEnableCache (Cr4);\r
+  PostMtrrChangeEnableCache (&MtrrContext);\r
 \r
   return MtrrSetting;\r
 }\r