X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FLibrary%2FMtrrLib%2FMtrrLib.c;h=200becdd4a2500eb3145788bc2f97a19a47c3aae;hp=a7adbafae397b215752f663ef90c9e6db3a7dd87;hb=86cabbcfa005ca9c9589402d4fb7c984e741cc19;hpb=2bbd7e2fbd4b382f0bb0b289d0c40ed80a7d85cc diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c index a7adbafae3..200becdd4a 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -449,10 +449,13 @@ MtrrGetVariableMtrrWorker ( for (Index = 0; Index < VariableMtrrCount; Index++) { if (MtrrSetting == NULL) { - VariableSettings->Mtrr[Index].Base = - AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1)); - VariableSettings->Mtrr[Index].Mask = - AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1)); + VariableSettings->Mtrr[Index].Mask = AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1)); + // + // Skip to read the Base MSR when the Mask.V is not set. + // + if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *)&VariableSettings->Mtrr[Index].Mask)->Bits.V != 0) { + VariableSettings->Mtrr[Index].Base = AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1)); + } } else { VariableSettings->Mtrr[Index].Base = MtrrSetting->Variables.Mtrr[Index].Base; VariableSettings->Mtrr[Index].Mask = MtrrSetting->Variables.Mtrr[Index].Mask; @@ -2111,22 +2114,32 @@ MtrrLibSetBelow1MBMemoryAttribute ( UINT64 OrMask; UINT64 ClearMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)]; UINT64 OrMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)]; + BOOLEAN LocalModified[ARRAY_SIZE (mMtrrLibFixedMtrrTable)]; ASSERT (BaseAddress < BASE_1MB); + SetMem (LocalModified, sizeof (LocalModified), FALSE); + + // + // (Value & ~0 | 0) still equals to (Value) + // + SetMem64 (ClearMasks, sizeof (ClearMasks), 0); + SetMem64 (OrMasks, sizeof (OrMasks), 0); + MsrIndex = (UINT32)-1; while ((BaseAddress < BASE_1MB) && (Length != 0)) { Status = MtrrLibProgramFixedMtrr (Type, &BaseAddress, &Length, &MsrIndex, &ClearMask, &OrMask); if (RETURN_ERROR (Status)) { return Status; } - ClearMasks[MsrIndex] = ClearMask; - OrMasks[MsrIndex] = OrMask; - Modified[MsrIndex] = TRUE; + ClearMasks[MsrIndex] = ClearMask; + OrMasks[MsrIndex] = OrMask; + Modified[MsrIndex] = TRUE; + LocalModified[MsrIndex] = TRUE; } for (MsrIndex = 0; MsrIndex < ARRAY_SIZE (mMtrrLibFixedMtrrTable); MsrIndex++) { - if (Modified[MsrIndex]) { + if (LocalModified[MsrIndex]) { FixedSettings->Mtrr[MsrIndex] = (FixedSettings->Mtrr[MsrIndex] & ~ClearMasks[MsrIndex]) | OrMasks[MsrIndex]; } } @@ -2351,6 +2364,7 @@ MtrrSetMemoryAttributesInMtrrSettings ( // // 3. Apply the below-1MB memory attribute settings. // + ZeroMem (WorkingFixedSettings.Mtrr, sizeof (WorkingFixedSettings.Mtrr)); for (Index = 0; Index < RangeCount; Index++) { if (Ranges[Index].BaseAddress >= BASE_1MB) { continue; @@ -2540,14 +2554,14 @@ MtrrSetVariableMtrrWorker ( ASSERT (VariableMtrrCount <= ARRAY_SIZE (VariableSettings->Mtrr)); for (Index = 0; Index < VariableMtrrCount; Index++) { - AsmWriteMsr64 ( - MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), - VariableSettings->Mtrr[Index].Base - ); - AsmWriteMsr64 ( - MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), - VariableSettings->Mtrr[Index].Mask - ); + // + // Mask MSR is always updated since caller might need to invalidate the MSR pair. + // Base MSR is skipped when Mask.V is not set. + // + AsmWriteMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), VariableSettings->Mtrr[Index].Mask); + if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *)&VariableSettings->Mtrr[Index].Mask)->Bits.V != 0) { + AsmWriteMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), VariableSettings->Mtrr[Index].Base); + } } } @@ -2773,6 +2787,7 @@ MtrrDebugPrintAllMtrrsWorker ( UINTN RangeCount; UINT64 MtrrValidBitsMask; UINT64 MtrrValidAddressMask; + UINT32 VariableMtrrCount; MTRR_MEMORY_RANGE Ranges[ ARRAY_SIZE (mMtrrLibFixedMtrrTable) * sizeof (UINT64) + 2 * ARRAY_SIZE (Mtrrs->Variables.Mtrr) + 1 ]; @@ -2782,6 +2797,8 @@ MtrrDebugPrintAllMtrrsWorker ( return; } + VariableMtrrCount = GetVariableMtrrCountWorker (); + if (MtrrSetting != NULL) { Mtrrs = MtrrSetting; } else { @@ -2799,8 +2816,8 @@ MtrrDebugPrintAllMtrrsWorker ( DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d] : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index])); } - for (Index = 0; Index < ARRAY_SIZE (Mtrrs->Variables.Mtrr); Index++) { - if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) { + for (Index = 0; Index < VariableMtrrCount; Index++) { + if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *)&Mtrrs->Variables.Mtrr[Index].Mask)->Bits.V == 0) { // // If mask is not valid, then do not display range // @@ -2826,11 +2843,11 @@ MtrrDebugPrintAllMtrrsWorker ( RangeCount = 1; MtrrLibGetRawVariableRanges ( - &Mtrrs->Variables, ARRAY_SIZE (Mtrrs->Variables.Mtrr), + &Mtrrs->Variables, VariableMtrrCount, MtrrValidBitsMask, MtrrValidAddressMask, RawVariableRanges ); MtrrLibApplyVariableMtrrs ( - RawVariableRanges, ARRAY_SIZE (RawVariableRanges), + RawVariableRanges, VariableMtrrCount, Ranges, ARRAY_SIZE (Ranges), &RangeCount );