/* Programming MTRR according to Memory address, length, and type. */
VOID EfiProgramMtrr(IN UINT32 MtrrNumber, IN EFI_PHYSICAL_ADDRESS MemoryAddress, IN UINT64 MemoryLength, IN EFI_MEMORY_CACHE_TYPE MemoryCacheType, IN UINT64 ValidMtrrAddressMask)
/* Programming MTRR according to Memory address, length, and type. */
VOID EfiProgramMtrr(IN UINT32 MtrrNumber, IN EFI_PHYSICAL_ADDRESS MemoryAddress, IN UINT64 MemoryLength, IN EFI_MEMORY_CACHE_TYPE MemoryCacheType, IN UINT64 ValidMtrrAddressMask)
{
  UINT64  TempQword;
  UINT64  OldMtrr;
  if (MemoryLength == 0) {
    return;
  }
  EfiDisableCacheMtrr (&OldMtrr);
  TempQword = (MemoryAddress & ValidMtrrAddressMask) | MemoryCacheType;
  AsmWriteMsr64 (MtrrNumber, TempQword);
  TempQword = ~(MemoryLength - 1);
  AsmWriteMsr64 (MtrrNumber + 1, (TempQword & ValidMtrrAddressMask) | B_EFI_MSR_CACHE_MTRR_VALID);
  EfiRecoverCacheMtrr (TRUE, OldMtrr);
}