mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-25 06:34:30 +02:00
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/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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user