mirror of https://github.com/acidanthera/audk.git
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:
parent
3999f1feef
commit
c878cee473
|
@ -20,6 +20,14 @@
|
|||
#include <Library/BaseMemoryLib.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
|
||||
//
|
||||
|
@ -166,16 +174,19 @@ MtrrGetDefaultMemoryType (
|
|||
This function will do some preparation for programming MTRRs:
|
||||
disable cache, invalid cache and disable MTRR caching functionality
|
||||
|
||||
@return CR4 value before changing.
|
||||
@param[out] Pointer to context to save
|
||||
|
||||
**/
|
||||
UINTN
|
||||
VOID
|
||||
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)
|
||||
//
|
||||
|
@ -184,8 +195,8 @@ PreMtrrChange (
|
|||
//
|
||||
// Save original CR4 value and clear PGE flag (Bit 7)
|
||||
//
|
||||
Value = AsmReadCr4 ();
|
||||
AsmWriteCr4 (Value & (~BIT7));
|
||||
MtrrContext->Cr4 = AsmReadCr4 ();
|
||||
AsmWriteCr4 (MtrrContext->Cr4 & (~BIT7));
|
||||
|
||||
//
|
||||
// Flush all TLBs
|
||||
|
@ -196,11 +207,6 @@ PreMtrrChange (
|
|||
// Disable Mtrrs
|
||||
//
|
||||
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:
|
||||
Flush all TLBs, re-enable caching, restore CR4.
|
||||
|
||||
@param Cr4 CR4 value to restore
|
||||
@param[in] Pointer to context to restore
|
||||
|
||||
**/
|
||||
VOID
|
||||
PostMtrrChangeEnableCache (
|
||||
IN UINTN Cr4
|
||||
IN MTRR_CONTEXT *MtrrContext
|
||||
)
|
||||
{
|
||||
//
|
||||
|
@ -230,7 +236,12 @@ PostMtrrChangeEnableCache (
|
|||
//
|
||||
// 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:
|
||||
enable MTRR caching functionality, and enable cache
|
||||
|
||||
@param Cr4 CR4 value to restore
|
||||
@param[in] Pointer to context to restore
|
||||
|
||||
**/
|
||||
VOID
|
||||
PostMtrrChange (
|
||||
IN UINTN Cr4
|
||||
IN MTRR_CONTEXT *MtrrContext
|
||||
)
|
||||
{
|
||||
//
|
||||
|
@ -252,7 +263,7 @@ PostMtrrChange (
|
|||
//
|
||||
AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3);
|
||||
|
||||
PostMtrrChangeEnableCache (Cr4);
|
||||
PostMtrrChangeEnableCache (MtrrContext);
|
||||
}
|
||||
|
||||
|
||||
|
@ -704,11 +715,11 @@ InvalidateMtrr (
|
|||
IN VARIABLE_MTRR *VariableMtrr
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINTN Cr4;
|
||||
UINTN VariableMtrrCount;
|
||||
UINTN Index;
|
||||
UINTN VariableMtrrCount;
|
||||
MTRR_CONTEXT MtrrContext;
|
||||
|
||||
Cr4 = PreMtrrChange ();
|
||||
PreMtrrChange (&MtrrContext);
|
||||
Index = 0;
|
||||
VariableMtrrCount = GetVariableMtrrCount ();
|
||||
while (Index < VariableMtrrCount) {
|
||||
|
@ -719,7 +730,7 @@ InvalidateMtrr (
|
|||
}
|
||||
Index ++;
|
||||
}
|
||||
PostMtrrChange (Cr4);
|
||||
PostMtrrChange (&MtrrContext);
|
||||
}
|
||||
|
||||
|
||||
|
@ -744,10 +755,10 @@ ProgramVariableMtrr (
|
|||
IN UINT64 MtrrValidAddressMask
|
||||
)
|
||||
{
|
||||
UINT64 TempQword;
|
||||
UINTN Cr4;
|
||||
UINT64 TempQword;
|
||||
MTRR_CONTEXT MtrrContext;
|
||||
|
||||
Cr4 = PreMtrrChange ();
|
||||
PreMtrrChange (&MtrrContext);
|
||||
|
||||
//
|
||||
// MTRR Physical Base
|
||||
|
@ -764,7 +775,7 @@ ProgramVariableMtrr (
|
|||
(TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED
|
||||
);
|
||||
|
||||
PostMtrrChange (Cr4);
|
||||
PostMtrrChange (&MtrrContext);
|
||||
}
|
||||
|
||||
|
||||
|
@ -953,10 +964,10 @@ MtrrSetMemoryAttribute (
|
|||
UINT32 UsedMtrr;
|
||||
UINT64 MtrrValidBitsMask;
|
||||
UINT64 MtrrValidAddressMask;
|
||||
UINTN Cr4;
|
||||
BOOLEAN OverwriteExistingMtrr;
|
||||
UINT32 FirmwareVariableMtrrCount;
|
||||
UINT32 VariableMtrrEnd;
|
||||
MTRR_CONTEXT MtrrContext;
|
||||
|
||||
DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
|
||||
|
||||
|
@ -995,9 +1006,9 @@ MtrrSetMemoryAttribute (
|
|||
//
|
||||
Status = RETURN_SUCCESS;
|
||||
while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {
|
||||
Cr4 = PreMtrrChange ();
|
||||
PreMtrrChange (&MtrrContext);
|
||||
Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);
|
||||
PostMtrrChange (Cr4);
|
||||
PostMtrrChange (&MtrrContext);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
@ -1353,15 +1364,15 @@ MtrrSetVariableMtrr (
|
|||
IN MTRR_VARIABLE_SETTINGS *VariableSettings
|
||||
)
|
||||
{
|
||||
UINTN Cr4;
|
||||
MTRR_CONTEXT MtrrContext;
|
||||
|
||||
if (!IsMtrrSupported ()) {
|
||||
return VariableSettings;
|
||||
}
|
||||
|
||||
Cr4 = PreMtrrChange ();
|
||||
PreMtrrChange (&MtrrContext);
|
||||
MtrrSetVariableMtrrWorker (VariableSettings);
|
||||
PostMtrrChange (Cr4);
|
||||
PostMtrrChange (&MtrrContext);
|
||||
return VariableSettings;
|
||||
}
|
||||
|
||||
|
@ -1430,15 +1441,15 @@ MtrrSetFixedMtrr (
|
|||
IN MTRR_FIXED_SETTINGS *FixedSettings
|
||||
)
|
||||
{
|
||||
UINTN Cr4;
|
||||
MTRR_CONTEXT MtrrContext;
|
||||
|
||||
if (!IsMtrrSupported ()) {
|
||||
return FixedSettings;
|
||||
}
|
||||
|
||||
Cr4 = PreMtrrChange ();
|
||||
PreMtrrChange (&MtrrContext);
|
||||
MtrrSetFixedMtrrWorker (FixedSettings);
|
||||
PostMtrrChange (Cr4);
|
||||
PostMtrrChange (&MtrrContext);
|
||||
|
||||
return FixedSettings;
|
||||
}
|
||||
|
@ -1495,13 +1506,13 @@ MtrrSetAllMtrrs (
|
|||
IN MTRR_SETTINGS *MtrrSetting
|
||||
)
|
||||
{
|
||||
UINTN Cr4;
|
||||
MTRR_CONTEXT MtrrContext;
|
||||
|
||||
if (!IsMtrrSupported ()) {
|
||||
return MtrrSetting;
|
||||
}
|
||||
|
||||
Cr4 = PreMtrrChange ();
|
||||
PreMtrrChange (&MtrrContext);
|
||||
|
||||
//
|
||||
// Set fixed MTRRs
|
||||
|
@ -1518,7 +1529,7 @@ MtrrSetAllMtrrs (
|
|||
//
|
||||
AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType);
|
||||
|
||||
PostMtrrChangeEnableCache (Cr4);
|
||||
PostMtrrChangeEnableCache (&MtrrContext);
|
||||
|
||||
return MtrrSetting;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue