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
#include <Library/BaseMemoryLib.h>\r
#include <Library/DebugLib.h>\r
\r
#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
//\r
// This table defines the offset, base and length of the fixed MTRRs\r
//\r
This function will do some preparation for programming MTRRs:\r
disable cache, invalid cache and disable MTRR caching functionality\r
\r
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
+ OUT MTRR_CONTEXT *MtrrContext\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
//\r
// Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)\r
//\r
//\r
// Save original CR4 value and clear PGE flag (Bit 7)\r
//\r
//\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
\r
//\r
// Flush all TLBs\r
// Disable Mtrrs\r
//\r
AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 0);\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
This function will do some clean up after programming MTRRs:\r
Flush all TLBs, re-enable caching, restore CR4.\r
\r
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
\r
**/\r
VOID\r
PostMtrrChangeEnableCache (\r
+ IN MTRR_CONTEXT *MtrrContext\r
//\r
// Restore original CR4 value\r
//\r
//\r
// Restore original CR4 value\r
//\r
+ AsmWriteCr4 (MtrrContext->Cr4);\r
+ \r
+ //\r
+ // Restore original interrupt state\r
+ //\r
+ SetInterruptState (MtrrContext->InterruptState);\r
This function will do some clean up after programming MTRRs:\r
enable MTRR caching functionality, and enable cache\r
\r
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
\r
**/\r
VOID\r
PostMtrrChange (\r
+ IN MTRR_CONTEXT *MtrrContext\r
//\r
AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3);\r
\r
//\r
AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3);\r
\r
- PostMtrrChangeEnableCache (Cr4);\r
+ PostMtrrChangeEnableCache (MtrrContext);\r
IN VARIABLE_MTRR *VariableMtrr\r
)\r
{\r
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
- Cr4 = PreMtrrChange ();\r
+ PreMtrrChange (&MtrrContext);\r
Index = 0;\r
VariableMtrrCount = GetVariableMtrrCount ();\r
while (Index < VariableMtrrCount) {\r
Index = 0;\r
VariableMtrrCount = GetVariableMtrrCount ();\r
while (Index < VariableMtrrCount) {\r
- PostMtrrChange (Cr4);\r
+ PostMtrrChange (&MtrrContext);\r
IN UINT64 MtrrValidAddressMask\r
)\r
{\r
IN UINT64 MtrrValidAddressMask\r
)\r
{\r
- UINT64 TempQword;\r
- UINTN Cr4;\r
+ UINT64 TempQword;\r
+ MTRR_CONTEXT MtrrContext;\r
- Cr4 = PreMtrrChange ();\r
+ PreMtrrChange (&MtrrContext);\r
\r
//\r
// MTRR Physical Base\r
\r
//\r
// MTRR Physical Base\r
(TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED\r
);\r
\r
(TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED\r
);\r
\r
- PostMtrrChange (Cr4);\r
+ PostMtrrChange (&MtrrContext);\r
UINT32 UsedMtrr;\r
UINT64 MtrrValidBitsMask;\r
UINT64 MtrrValidAddressMask;\r
UINT32 UsedMtrr;\r
UINT64 MtrrValidBitsMask;\r
UINT64 MtrrValidAddressMask;\r
BOOLEAN OverwriteExistingMtrr;\r
UINT32 FirmwareVariableMtrrCount;\r
UINT32 VariableMtrrEnd;\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
\r
DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
\r
//\r
Status = RETURN_SUCCESS;\r
while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {\r
//\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
Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);\r
- PostMtrrChange (Cr4);\r
+ PostMtrrChange (&MtrrContext);\r
if (RETURN_ERROR (Status)) {\r
goto Done;\r
}\r
if (RETURN_ERROR (Status)) {\r
goto Done;\r
}\r
IN MTRR_VARIABLE_SETTINGS *VariableSettings\r
)\r
{\r
IN MTRR_VARIABLE_SETTINGS *VariableSettings\r
)\r
{\r
+ MTRR_CONTEXT MtrrContext;\r
\r
if (!IsMtrrSupported ()) {\r
return VariableSettings;\r
}\r
\r
\r
if (!IsMtrrSupported ()) {\r
return VariableSettings;\r
}\r
\r
- Cr4 = PreMtrrChange ();\r
+ PreMtrrChange (&MtrrContext);\r
MtrrSetVariableMtrrWorker (VariableSettings);\r
MtrrSetVariableMtrrWorker (VariableSettings);\r
- PostMtrrChange (Cr4);\r
+ PostMtrrChange (&MtrrContext);\r
return VariableSettings;\r
}\r
\r
return VariableSettings;\r
}\r
\r
IN MTRR_FIXED_SETTINGS *FixedSettings\r
)\r
{\r
IN MTRR_FIXED_SETTINGS *FixedSettings\r
)\r
{\r
+ MTRR_CONTEXT MtrrContext;\r
\r
if (!IsMtrrSupported ()) {\r
return FixedSettings;\r
}\r
\r
\r
if (!IsMtrrSupported ()) {\r
return FixedSettings;\r
}\r
\r
- Cr4 = PreMtrrChange ();\r
+ PreMtrrChange (&MtrrContext);\r
MtrrSetFixedMtrrWorker (FixedSettings);\r
MtrrSetFixedMtrrWorker (FixedSettings);\r
- PostMtrrChange (Cr4);\r
+ PostMtrrChange (&MtrrContext);\r
\r
return FixedSettings;\r
}\r
\r
return FixedSettings;\r
}\r
IN MTRR_SETTINGS *MtrrSetting\r
)\r
{\r
IN MTRR_SETTINGS *MtrrSetting\r
)\r
{\r
+ MTRR_CONTEXT MtrrContext;\r
\r
if (!IsMtrrSupported ()) {\r
return MtrrSetting;\r
}\r
\r
\r
if (!IsMtrrSupported ()) {\r
return MtrrSetting;\r
}\r
\r
- Cr4 = PreMtrrChange ();\r
+ PreMtrrChange (&MtrrContext);\r
\r
//\r
// Set fixed MTRRs\r
\r
//\r
// Set fixed MTRRs\r
//\r
AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType);\r
\r
//\r
AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType);\r
\r
- PostMtrrChangeEnableCache (Cr4);\r
+ PostMtrrChangeEnableCache (&MtrrContext);\r
\r
return MtrrSetting;\r
}\r
\r
return MtrrSetting;\r
}\r