Save and disable CPU interrupt before programming MTRR settings, and restore the CPU interrupt after programming MTRR setting.

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
This commit is contained in:
vanjeff 2012-09-27 03:04:31 +00:00
parent 3999f1feef
commit c878cee473

View File

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