/** @file
  MTRR setting library

  @par Note:
    Most of services in this library instance are suggested to be invoked by BSP only,
    except for MtrrSetAllMtrrs() which is used to sync BSP's MTRR setting to APs.

  Copyright (c) 2008 - 2023, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Uefi.h>
#include <Register/Intel/Cpuid.h>
#include <Register/Intel/Msr.h>

#include <Library/MtrrLib.h>
#include <Library/BaseLib.h>
#include <Library/CpuLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>

#define OR_SEED              0x0101010101010101ull
#define CLEAR_SEED           0xFFFFFFFFFFFFFFFFull
#define MAX_WEIGHT           MAX_UINT8
#define SCRATCH_BUFFER_SIZE  (4 * SIZE_4KB)
#define MTRR_LIB_ASSERT_ALIGNED(B, L)  ASSERT ((B & ~(L - 1)) == B);

#define M(x, y)  ((x) * VertexCount + (y))
#define O(x, y)  ((y) * VertexCount + (x))

//
// Context to save and restore when MTRRs are programmed
//
typedef struct {
  UINTN                              Cr4;
  BOOLEAN                            InterruptState;
  MSR_IA32_MTRR_DEF_TYPE_REGISTER    DefType;
} MTRR_CONTEXT;

typedef struct {
  UINT64                    Address;
  UINT64                    Alignment;
  UINT64                    Length;
  MTRR_MEMORY_CACHE_TYPE    Type    : 7;

  //
  // Temprary use for calculating the best MTRR settings.
  //
  BOOLEAN                   Visited : 1;
  UINT8                     Weight;
  UINT16                    Previous;
} MTRR_LIB_ADDRESS;

//
// This table defines the offset, base and length of the fixed MTRRs
//
CONST FIXED_MTRR  mMtrrLibFixedMtrrTable[] = {
  {
    MSR_IA32_MTRR_FIX64K_00000,
    0,
    SIZE_64KB
  },
  {
    MSR_IA32_MTRR_FIX16K_80000,
    0x80000,
    SIZE_16KB
  },
  {
    MSR_IA32_MTRR_FIX16K_A0000,
    0xA0000,
    SIZE_16KB
  },
  {
    MSR_IA32_MTRR_FIX4K_C0000,
    0xC0000,
    SIZE_4KB
  },
  {
    MSR_IA32_MTRR_FIX4K_C8000,
    0xC8000,
    SIZE_4KB
  },
  {
    MSR_IA32_MTRR_FIX4K_D0000,
    0xD0000,
    SIZE_4KB
  },
  {
    MSR_IA32_MTRR_FIX4K_D8000,
    0xD8000,
    SIZE_4KB
  },
  {
    MSR_IA32_MTRR_FIX4K_E0000,
    0xE0000,
    SIZE_4KB
  },
  {
    MSR_IA32_MTRR_FIX4K_E8000,
    0xE8000,
    SIZE_4KB
  },
  {
    MSR_IA32_MTRR_FIX4K_F0000,
    0xF0000,
    SIZE_4KB
  },
  {
    MSR_IA32_MTRR_FIX4K_F8000,
    0xF8000,
    SIZE_4KB
  }
};

//
// Lookup table used to print MTRRs
//
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8  *mMtrrMemoryCacheTypeShortName[] = {
  "UC",  // CacheUncacheable
  "WC",  // CacheWriteCombining
  "R*",  // Invalid
  "R*",  // Invalid
  "WT",  // CacheWriteThrough
  "WP",  // CacheWriteProtected
  "WB",  // CacheWriteBack
  "R*"   // Invalid
};

/**
  Worker function prints all MTRRs for debugging.

  If MtrrSetting is not NULL, print MTRR settings from input MTRR
  settings buffer.
  If MtrrSetting is NULL, print MTRR settings from MTRRs.

  @param  MtrrSetting    A buffer holding all MTRRs content.
**/
VOID
MtrrDebugPrintAllMtrrsWorker (
  IN MTRR_SETTINGS  *MtrrSetting
  );

/**
  Return whether MTRR is supported.

  @param[out]  FixedMtrrSupported   Return whether fixed MTRR is supported.
  @param[out]  VariableMtrrCount    Return the max number of variable MTRRs.

  @retval TRUE  MTRR is supported when either fixed MTRR is supported or max number
                of variable MTRRs is not 0.
  @retval FALSE MTRR is not supported when both fixed MTRR is not supported and max
                number of variable MTRRs is 0.
**/
BOOLEAN
MtrrLibIsMtrrSupported (
  OUT BOOLEAN  *FixedMtrrSupported  OPTIONAL,
  OUT UINT32   *VariableMtrrCount   OPTIONAL
  )
{
  CPUID_VERSION_INFO_EDX     Edx;
  MSR_IA32_MTRRCAP_REGISTER  MtrrCap;

  //
  // Check CPUID(1).EDX[12] for MTRR capability
  //
  AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32);
  if (Edx.Bits.MTRR == 0) {
    if (FixedMtrrSupported != NULL) {
      *FixedMtrrSupported = FALSE;
    }

    if (VariableMtrrCount != NULL) {
      *VariableMtrrCount = 0;
    }

    return FALSE;
  }

  //
  // Check the number of variable MTRRs and determine whether fixed MTRRs exist.
  // If the count of variable MTRRs is zero and there are no fixed MTRRs,
  // then return false
  //
  MtrrCap.Uint64 = AsmReadMsr64 (MSR_IA32_MTRRCAP);
  ASSERT (MtrrCap.Bits.VCNT <= ARRAY_SIZE (((MTRR_VARIABLE_SETTINGS *)0)->Mtrr));
  if (FixedMtrrSupported != NULL) {
    *FixedMtrrSupported = (BOOLEAN)(MtrrCap.Bits.FIX == 1);
  }

  if (VariableMtrrCount != NULL) {
    *VariableMtrrCount = MtrrCap.Bits.VCNT;
  }

  if ((MtrrCap.Bits.VCNT == 0) && (MtrrCap.Bits.FIX == 0)) {
    return FALSE;
  }

  return TRUE;
}

/**
  Worker function returns the variable MTRR count for the CPU.

  @return Variable MTRR count

**/
UINT32
GetVariableMtrrCountWorker (
  VOID
  )
{
  MSR_IA32_MTRRCAP_REGISTER  MtrrCap;

  MtrrCap.Uint64 = AsmReadMsr64 (MSR_IA32_MTRRCAP);
  ASSERT (MtrrCap.Bits.VCNT <= ARRAY_SIZE (((MTRR_VARIABLE_SETTINGS *)0)->Mtrr));
  return MtrrCap.Bits.VCNT;
}

/**
  Returns the variable MTRR count for the CPU.

  @return Variable MTRR count

**/
UINT32
EFIAPI
GetVariableMtrrCount (
  VOID
  )
{
  if (!IsMtrrSupported ()) {
    return 0;
  }

  return GetVariableMtrrCountWorker ();
}

/**
  Worker function returns the firmware usable variable MTRR count for the CPU.

  @return Firmware usable variable MTRR count

**/
UINT32
GetFirmwareVariableMtrrCountWorker (
  VOID
  )
{
  UINT32  VariableMtrrCount;
  UINT32  ReservedMtrrNumber;

  VariableMtrrCount  = GetVariableMtrrCountWorker ();
  ReservedMtrrNumber = PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs);
  if (VariableMtrrCount < ReservedMtrrNumber) {
    return 0;
  }

  return VariableMtrrCount - ReservedMtrrNumber;
}

/**
  Returns the firmware usable variable MTRR count for the CPU.

  @return Firmware usable variable MTRR count

**/
UINT32
EFIAPI
GetFirmwareVariableMtrrCount (
  VOID
  )
{
  if (!IsMtrrSupported ()) {
    return 0;
  }

  return GetFirmwareVariableMtrrCountWorker ();
}

/**
  Worker function returns the default MTRR cache type for the system.

  If MtrrSetting is not NULL, returns the default MTRR cache type from input
  MTRR settings buffer.
  If MtrrSetting is NULL, returns the default MTRR cache type from MSR.

  @param[in]  MtrrSetting    A buffer holding all MTRRs content.

  @return  The default MTRR cache type.

**/
MTRR_MEMORY_CACHE_TYPE
MtrrGetDefaultMemoryTypeWorker (
  IN CONST MTRR_SETTINGS  *MtrrSetting
  )
{
  MSR_IA32_MTRR_DEF_TYPE_REGISTER  DefType;

  if (MtrrSetting == NULL) {
    DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);
  } else {
    DefType.Uint64 = MtrrSetting->MtrrDefType;
  }

  return (MTRR_MEMORY_CACHE_TYPE)DefType.Bits.Type;
}

/**
  Returns the default MTRR cache type for the system.

  @return  The default MTRR cache type.

**/
MTRR_MEMORY_CACHE_TYPE
EFIAPI
MtrrGetDefaultMemoryType (
  VOID
  )
{
  if (!IsMtrrSupported ()) {
    return CacheUncacheable;
  }

  return MtrrGetDefaultMemoryTypeWorker (NULL);
}

/**
  Preparation before programming MTRR.

  This function will do some preparation for programming MTRRs:
  disable cache, invalid cache and disable MTRR caching functionality

  @param[out] MtrrContext  Pointer to context to save

**/
VOID
MtrrLibPreMtrrChange (
  OUT MTRR_CONTEXT  *MtrrContext
  )
{
  MSR_IA32_MTRR_DEF_TYPE_REGISTER  DefType;

  //
  // Disable interrupts and save current interrupt state
  //
  MtrrContext->InterruptState = SaveAndDisableInterrupts ();

  //
  // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)
  //
  AsmDisableCache ();

  //
  // Save original CR4 value and clear PGE flag (Bit 7)
  //
  MtrrContext->Cr4 = AsmReadCr4 ();
  AsmWriteCr4 (MtrrContext->Cr4 & (~BIT7));

  //
  // Flush all TLBs
  //
  CpuFlushTlb ();

  //
  // Save current MTRR default type and disable MTRRs
  //
  MtrrContext->DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);
  DefType.Uint64              = MtrrContext->DefType.Uint64;
  DefType.Bits.E              = 0;
  AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, DefType.Uint64);
}

/**
  Cleaning up after programming MTRRs.

  This function will do some clean up after programming MTRRs:
  Flush all TLBs,  re-enable caching, restore CR4.

  @param[in] MtrrContext  Pointer to context to restore

**/
VOID
MtrrLibPostMtrrChangeEnableCache (
  IN MTRR_CONTEXT  *MtrrContext
  )
{
  //
  // Flush all TLBs
  //
  CpuFlushTlb ();

  //
  // Enable Normal Mode caching CD=NW=0, CD(Bit30), NW(Bit29)
  //
  AsmEnableCache ();

  //
  // Restore original CR4 value
  //
  AsmWriteCr4 (MtrrContext->Cr4);

  //
  // Restore original interrupt state
  //
  SetInterruptState (MtrrContext->InterruptState);
}

/**
  Cleaning up after programming MTRRs.

  This function will do some clean up after programming MTRRs:
  enable MTRR caching functionality, and enable cache

  @param[in] MtrrContext  Pointer to context to restore

**/
VOID
MtrrLibPostMtrrChange (
  IN MTRR_CONTEXT  *MtrrContext
  )
{
  //
  // Enable Cache MTRR
  // Note: It's possible that MTRR was not enabled earlier.
  //       But it will be enabled here unconditionally.
  //
  MtrrContext->DefType.Bits.E = 1;
  AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, MtrrContext->DefType.Uint64);

  MtrrLibPostMtrrChangeEnableCache (MtrrContext);
}

/**
  Worker function gets the content in fixed MTRRs

  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.

  @retval The pointer of FixedSettings

**/
MTRR_FIXED_SETTINGS *
MtrrGetFixedMtrrWorker (
  OUT MTRR_FIXED_SETTINGS  *FixedSettings
  )
{
  UINT32  Index;

  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
    FixedSettings->Mtrr[Index] =
      AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
  }

  return FixedSettings;
}

/**
  This function gets the content in fixed MTRRs

  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.

  @retval The pointer of FixedSettings

**/
MTRR_FIXED_SETTINGS *
EFIAPI
MtrrGetFixedMtrr (
  OUT MTRR_FIXED_SETTINGS  *FixedSettings
  )
{
  BOOLEAN  FixedMtrrSupported;

  MtrrLibIsMtrrSupported (&FixedMtrrSupported, NULL);

  if (!FixedMtrrSupported) {
    return FixedSettings;
  }

  return MtrrGetFixedMtrrWorker (FixedSettings);
}

/**
  Worker function will get the raw value in variable MTRRs

  If MtrrSetting is not NULL, gets the variable MTRRs raw value from input
  MTRR settings buffer.
  If MtrrSetting is NULL, gets the variable MTRRs raw value from MTRRs.

  @param[in]  MtrrSetting        A buffer holding all MTRRs content.
  @param[in]  VariableMtrrCount  Number of variable MTRRs.
  @param[out] VariableSettings   A buffer to hold variable MTRRs content.

  @return The VariableSettings input pointer

**/
MTRR_VARIABLE_SETTINGS *
MtrrGetVariableMtrrWorker (
  IN  MTRR_SETTINGS           *MtrrSetting,
  IN  UINT32                  VariableMtrrCount,
  OUT MTRR_VARIABLE_SETTINGS  *VariableSettings
  )
{
  UINT32  Index;

  ASSERT (VariableMtrrCount <= ARRAY_SIZE (VariableSettings->Mtrr));

  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));
    } else {
      VariableSettings->Mtrr[Index].Base = MtrrSetting->Variables.Mtrr[Index].Base;
      VariableSettings->Mtrr[Index].Mask = MtrrSetting->Variables.Mtrr[Index].Mask;
    }
  }

  return VariableSettings;
}

/**
  Programs fixed MTRRs registers.

  @param[in]      Type             The memory type to set.
  @param[in, out] Base             The base address of memory range.
  @param[in, out] Length           The length of memory range.
  @param[in, out] LastMsrIndex     On input, the last index of the fixed MTRR MSR to program.
                                   On return, the current index of the fixed MTRR MSR to program.
  @param[out]     ClearMask        The bits to clear in the fixed MTRR MSR.
  @param[out]     OrMask           The bits to set in the fixed MTRR MSR.

  @retval RETURN_SUCCESS      The cache type was updated successfully
  @retval RETURN_UNSUPPORTED  The requested range or cache type was invalid
                              for the fixed MTRRs.

**/
RETURN_STATUS
MtrrLibProgramFixedMtrr (
  IN     MTRR_MEMORY_CACHE_TYPE  Type,
  IN OUT UINT64                  *Base,
  IN OUT UINT64                  *Length,
  IN OUT UINT32                  *LastMsrIndex,
  OUT    UINT64                  *ClearMask,
  OUT    UINT64                  *OrMask
  )
{
  UINT32  MsrIndex;
  UINT32  LeftByteShift;
  UINT32  RightByteShift;
  UINT64  SubLength;

  //
  // Find the fixed MTRR index to be programmed
  //
  for (MsrIndex = *LastMsrIndex + 1; MsrIndex < ARRAY_SIZE (mMtrrLibFixedMtrrTable); MsrIndex++) {
    if ((*Base >= mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress) &&
        (*Base <
         (
          mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress +
          (8 * mMtrrLibFixedMtrrTable[MsrIndex].Length)
         )
        )
        )
    {
      break;
    }
  }

  ASSERT (MsrIndex != ARRAY_SIZE (mMtrrLibFixedMtrrTable));

  //
  // Find the begin offset in fixed MTRR and calculate byte offset of left shift
  //
  if ((((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress) % mMtrrLibFixedMtrrTable[MsrIndex].Length) != 0) {
    //
    // Base address should be aligned to the begin of a certain Fixed MTRR range.
    //
    return RETURN_UNSUPPORTED;
  }

  LeftByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress) / mMtrrLibFixedMtrrTable[MsrIndex].Length;
  ASSERT (LeftByteShift < 8);

  //
  // Find the end offset in fixed MTRR and calculate byte offset of right shift
  //
  SubLength = mMtrrLibFixedMtrrTable[MsrIndex].Length * (8 - LeftByteShift);
  if (*Length >= SubLength) {
    RightByteShift = 0;
  } else {
    if (((UINT32)(*Length) % mMtrrLibFixedMtrrTable[MsrIndex].Length) != 0) {
      //
      // Length should be aligned to the end of a certain Fixed MTRR range.
      //
      return RETURN_UNSUPPORTED;
    }

    RightByteShift = 8 - LeftByteShift - (UINT32)(*Length) / mMtrrLibFixedMtrrTable[MsrIndex].Length;
    //
    // Update SubLength by actual length
    //
    SubLength = *Length;
  }

  *ClearMask = CLEAR_SEED;
  *OrMask    = MultU64x32 (OR_SEED, (UINT32)Type);

  if (LeftByteShift != 0) {
    //
    // Clear the low bits by LeftByteShift
    //
    *ClearMask &= LShiftU64 (*ClearMask, LeftByteShift * 8);
    *OrMask    &= LShiftU64 (*OrMask, LeftByteShift * 8);
  }

  if (RightByteShift != 0) {
    //
    // Clear the high bits by RightByteShift
    //
    *ClearMask &= RShiftU64 (*ClearMask, RightByteShift * 8);
    *OrMask    &= RShiftU64 (*OrMask, RightByteShift * 8);
  }

  *Length -= SubLength;
  *Base   += SubLength;

  *LastMsrIndex = MsrIndex;

  return RETURN_SUCCESS;
}

/**
  Worker function gets the attribute of variable MTRRs.

  This function shadows the content of variable MTRRs into an
  internal array: VariableMtrr.

  @param[in]   VariableSettings      The variable MTRR values to shadow
  @param[in]   VariableMtrrCount     The number of variable MTRRs
  @param[in]   MtrrValidBitsMask     The mask for the valid bit of the MTRR
  @param[in]   MtrrValidAddressMask  The valid address mask for MTRR
  @param[out]  VariableMtrr          The array to shadow variable MTRRs content

  @return      Number of MTRRs which has been used.

**/
UINT32
MtrrGetMemoryAttributeInVariableMtrrWorker (
  IN  MTRR_VARIABLE_SETTINGS  *VariableSettings,
  IN  UINTN                   VariableMtrrCount,
  IN  UINT64                  MtrrValidBitsMask,
  IN  UINT64                  MtrrValidAddressMask,
  OUT VARIABLE_MTRR           *VariableMtrr
  )
{
  UINTN   Index;
  UINT32  UsedMtrr;

  ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * ARRAY_SIZE (VariableSettings->Mtrr));
  for (Index = 0, UsedMtrr = 0; Index < VariableMtrrCount; Index++) {
    if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *)&VariableSettings->Mtrr[Index].Mask)->Bits.V != 0) {
      VariableMtrr[Index].Msr         = (UINT32)Index;
      VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask);
      VariableMtrr[Index].Length      =
        ((~(VariableSettings->Mtrr[Index].Mask & MtrrValidAddressMask)) & MtrrValidBitsMask) + 1;
      VariableMtrr[Index].Type  = (VariableSettings->Mtrr[Index].Base & 0x0ff);
      VariableMtrr[Index].Valid = TRUE;
      VariableMtrr[Index].Used  = TRUE;
      UsedMtrr++;
    }
  }

  return UsedMtrr;
}

/**
  Convert variable MTRRs to a RAW MTRR_MEMORY_RANGE array.
  One MTRR_MEMORY_RANGE element is created for each MTRR setting.
  The routine doesn't remove the overlap or combine the near-by region.

  @param[in]   VariableSettings      The variable MTRR values to shadow
  @param[in]   VariableMtrrCount     The number of variable MTRRs
  @param[in]   MtrrValidBitsMask     The mask for the valid bit of the MTRR
  @param[in]   MtrrValidAddressMask  The valid address mask for MTRR
  @param[out]  VariableMtrr          The array to shadow variable MTRRs content

  @return      Number of MTRRs which has been used.

**/
UINT32
MtrrLibGetRawVariableRanges (
  IN  CONST MTRR_VARIABLE_SETTINGS  *VariableSettings,
  IN  UINTN                         VariableMtrrCount,
  IN  UINT64                        MtrrValidBitsMask,
  IN  UINT64                        MtrrValidAddressMask,
  OUT MTRR_MEMORY_RANGE             *VariableMtrr
  )
{
  UINTN   Index;
  UINT32  UsedMtrr;

  ZeroMem (VariableMtrr, sizeof (MTRR_MEMORY_RANGE) * ARRAY_SIZE (VariableSettings->Mtrr));
  for (Index = 0, UsedMtrr = 0; Index < VariableMtrrCount; Index++) {
    if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *)&VariableSettings->Mtrr[Index].Mask)->Bits.V != 0) {
      VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask);
      VariableMtrr[Index].Length      =
        ((~(VariableSettings->Mtrr[Index].Mask & MtrrValidAddressMask)) & MtrrValidBitsMask) + 1;
      VariableMtrr[Index].Type = (MTRR_MEMORY_CACHE_TYPE)(VariableSettings->Mtrr[Index].Base & 0x0ff);
      UsedMtrr++;
    }
  }

  return UsedMtrr;
}

/**
  Gets the attribute of variable MTRRs.

  This function shadows the content of variable MTRRs into an
  internal array: VariableMtrr.

  @param[in]   MtrrValidBitsMask     The mask for the valid bit of the MTRR
  @param[in]   MtrrValidAddressMask  The valid address mask for MTRR
  @param[out]  VariableMtrr          The array to shadow variable MTRRs content

  @return                       The return value of this parameter indicates the
                                number of MTRRs which has been used.

**/
UINT32
EFIAPI
MtrrGetMemoryAttributeInVariableMtrr (
  IN  UINT64         MtrrValidBitsMask,
  IN  UINT64         MtrrValidAddressMask,
  OUT VARIABLE_MTRR  *VariableMtrr
  )
{
  MTRR_VARIABLE_SETTINGS  VariableSettings;

  if (!IsMtrrSupported ()) {
    return 0;
  }

  MtrrGetVariableMtrrWorker (
    NULL,
    GetVariableMtrrCountWorker (),
    &VariableSettings
    );

  return MtrrGetMemoryAttributeInVariableMtrrWorker (
           &VariableSettings,
           GetFirmwareVariableMtrrCountWorker (),
           MtrrValidBitsMask,
           MtrrValidAddressMask,
           VariableMtrr
           );
}

/**
  Return the biggest alignment (lowest set bit) of address.
  The function is equivalent to: 1 << LowBitSet64 (Address).

  @param Address    The address to return the alignment.
  @param Alignment0 The alignment to return when Address is 0.

  @return The least alignment of the Address.
**/
UINT64
MtrrLibBiggestAlignment (
  UINT64  Address,
  UINT64  Alignment0
  )
{
  if (Address == 0) {
    return Alignment0;
  }

  return Address & ((~Address) + 1);
}

/**
  Return whether the left MTRR type precedes the right MTRR type.

  The MTRR type precedence rules are:
    1. UC precedes any other type
    2. WT precedes WB
  For further details, please refer the IA32 Software Developer's Manual,
  Volume 3, Section "MTRR Precedences".

  @param Left  The left MTRR type.
  @param Right The right MTRR type.

  @retval TRUE  Left precedes Right.
  @retval FALSE Left doesn't precede Right.
**/
BOOLEAN
MtrrLibTypeLeftPrecedeRight (
  IN MTRR_MEMORY_CACHE_TYPE  Left,
  IN MTRR_MEMORY_CACHE_TYPE  Right
  )
{
  return (BOOLEAN)(Left == CacheUncacheable || (Left == CacheWriteThrough && Right == CacheWriteBack));
}

/**
  Initializes the valid bits mask and valid address mask for MTRRs.

  This function initializes the valid bits mask and valid address mask for MTRRs.

  @param[out]  MtrrValidBitsMask     The mask for the valid bit of the MTRR
  @param[out]  MtrrValidAddressMask  The valid address mask for the MTRR

**/
VOID
MtrrLibInitializeMtrrMask (
  OUT UINT64  *MtrrValidBitsMask,
  OUT UINT64  *MtrrValidAddressMask
  )
{
  UINT32                                       MaxExtendedFunction;
  CPUID_VIR_PHY_ADDRESS_SIZE_EAX               VirPhyAddressSize;
  UINT32                                       MaxFunction;
  CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX  ExtendedFeatureFlagsEcx;
  MSR_IA32_TME_ACTIVATE_REGISTER               TmeActivate;

  AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunction, NULL, NULL, NULL);

  if (MaxExtendedFunction >= CPUID_VIR_PHY_ADDRESS_SIZE) {
    AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &VirPhyAddressSize.Uint32, NULL, NULL, NULL);
  } else {
    VirPhyAddressSize.Bits.PhysicalAddressBits = 36;
  }

  //
  // CPUID enumeration of MAX_PA is unaffected by TME-MK activation and will continue
  // to report the maximum physical address bits available for software to use,
  // irrespective of the number of KeyID bits.
  // So, we need to check if TME is enabled and adjust the PA size accordingly.
  //
  AsmCpuid (CPUID_SIGNATURE, &MaxFunction, NULL, NULL, NULL);
  if (MaxFunction >= CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) {
    AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, NULL, NULL, &ExtendedFeatureFlagsEcx.Uint32, NULL);
    if (ExtendedFeatureFlagsEcx.Bits.TME_EN == 1) {
      TmeActivate.Uint64 = AsmReadMsr64 (MSR_IA32_TME_ACTIVATE);
      if (TmeActivate.Bits.TmeEnable == 1) {
        VirPhyAddressSize.Bits.PhysicalAddressBits -= TmeActivate.Bits.MkTmeKeyidBits;
      }
    }
  }

  *MtrrValidBitsMask    = LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits) - 1;
  *MtrrValidAddressMask = *MtrrValidBitsMask & 0xfffffffffffff000ULL;
}

/**
  Determines the real attribute of a memory range.

  This function is to arbitrate the real attribute of the memory when
  there are 2 MTRRs covers the same memory range. For further details,
  please refer the IA32 Software Developer's Manual, Volume 3,
  Section "MTRR Precedences".

  @param[in]  MtrrType1    The first kind of Memory type
  @param[in]  MtrrType2    The second kind of memory type

**/
MTRR_MEMORY_CACHE_TYPE
MtrrLibPrecedence (
  IN MTRR_MEMORY_CACHE_TYPE  MtrrType1,
  IN MTRR_MEMORY_CACHE_TYPE  MtrrType2
  )
{
  if (MtrrType1 == MtrrType2) {
    return MtrrType1;
  }

  ASSERT (
    MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2) ||
    MtrrLibTypeLeftPrecedeRight (MtrrType2, MtrrType1)
    );

  if (MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2)) {
    return MtrrType1;
  } else {
    return MtrrType2;
  }
}

/**
  Worker function will get the memory cache type of the specific address.

  If MtrrSetting is not NULL, gets the memory cache type from input
  MTRR settings buffer.
  If MtrrSetting is NULL, gets the memory cache type from MTRRs.

  @param[in]  MtrrSetting        A buffer holding all MTRRs content.
  @param[in]  Address            The specific address

  @return Memory cache type of the specific address

**/
MTRR_MEMORY_CACHE_TYPE
MtrrGetMemoryAttributeByAddressWorker (
  IN MTRR_SETTINGS     *MtrrSetting,
  IN PHYSICAL_ADDRESS  Address
  )
{
  MSR_IA32_MTRR_DEF_TYPE_REGISTER  DefType;
  UINT64                           FixedMtrr;
  UINTN                            Index;
  UINTN                            SubIndex;
  MTRR_MEMORY_CACHE_TYPE           MtrrType;
  MTRR_MEMORY_RANGE                VariableMtrr[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)];
  UINT64                           MtrrValidBitsMask;
  UINT64                           MtrrValidAddressMask;
  UINT32                           VariableMtrrCount;
  MTRR_VARIABLE_SETTINGS           VariableSettings;

  //
  // Check if MTRR is enabled, if not, return UC as attribute
  //
  if (MtrrSetting == NULL) {
    DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);
  } else {
    DefType.Uint64 = MtrrSetting->MtrrDefType;
  }

  if (DefType.Bits.E == 0) {
    return CacheUncacheable;
  }

  //
  // If address is less than 1M, then try to go through the fixed MTRR
  //
  if (Address < BASE_1MB) {
    if (DefType.Bits.FE != 0) {
      //
      // Go through the fixed MTRR
      //
      for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
        if ((Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress) &&
            (Address < mMtrrLibFixedMtrrTable[Index].BaseAddress +
             (mMtrrLibFixedMtrrTable[Index].Length * 8)))
        {
          SubIndex =
            ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /
            mMtrrLibFixedMtrrTable[Index].Length;
          if (MtrrSetting == NULL) {
            FixedMtrr = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
          } else {
            FixedMtrr = MtrrSetting->Fixed.Mtrr[Index];
          }

          return (MTRR_MEMORY_CACHE_TYPE)(RShiftU64 (FixedMtrr, SubIndex * 8) & 0xFF);
        }
      }
    }
  }

  VariableMtrrCount = GetVariableMtrrCountWorker ();
  ASSERT (VariableMtrrCount <= ARRAY_SIZE (MtrrSetting->Variables.Mtrr));
  MtrrGetVariableMtrrWorker (MtrrSetting, VariableMtrrCount, &VariableSettings);

  MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
  MtrrLibGetRawVariableRanges (
    &VariableSettings,
    VariableMtrrCount,
    MtrrValidBitsMask,
    MtrrValidAddressMask,
    VariableMtrr
    );

  //
  // Go through the variable MTRR
  //
  MtrrType = CacheInvalid;
  for (Index = 0; Index < VariableMtrrCount; Index++) {
    if (VariableMtrr[Index].Length != 0) {
      if ((Address >= VariableMtrr[Index].BaseAddress) &&
          (Address < VariableMtrr[Index].BaseAddress + VariableMtrr[Index].Length))
      {
        if (MtrrType == CacheInvalid) {
          MtrrType = (MTRR_MEMORY_CACHE_TYPE)VariableMtrr[Index].Type;
        } else {
          MtrrType = MtrrLibPrecedence (MtrrType, (MTRR_MEMORY_CACHE_TYPE)VariableMtrr[Index].Type);
        }
      }
    }
  }

  //
  // If there is no MTRR which covers the Address, use the default MTRR type.
  //
  if (MtrrType == CacheInvalid) {
    MtrrType = (MTRR_MEMORY_CACHE_TYPE)DefType.Bits.Type;
  }

  return MtrrType;
}

/**
  This function will get the memory cache type of the specific address.

  This function is mainly for debug purpose.

  @param[in]  Address   The specific address

  @return Memory cache type of the specific address

**/
MTRR_MEMORY_CACHE_TYPE
EFIAPI
MtrrGetMemoryAttribute (
  IN PHYSICAL_ADDRESS  Address
  )
{
  if (!IsMtrrSupported ()) {
    return CacheUncacheable;
  }

  return MtrrGetMemoryAttributeByAddressWorker (NULL, Address);
}

/**
  Update the Ranges array to change the specified range identified by
  BaseAddress and Length to Type.

  @param Ranges      Array holding memory type settings for all memory regions.
  @param Capacity    The maximum count of memory ranges the array can hold.
  @param Count       Return the new memory range count in the array.
  @param BaseAddress The base address of the memory range to change type.
  @param Length      The length of the memory range to change type.
  @param Type        The new type of the specified memory range.

  @retval RETURN_SUCCESS          The type of the specified memory range is
                                  changed successfully.
  @retval RETURN_ALREADY_STARTED  The type of the specified memory range equals
                                  to the desired type.
  @retval RETURN_OUT_OF_RESOURCES The new type set causes the count of memory
                                  range exceeds capacity.
**/
RETURN_STATUS
MtrrLibSetMemoryType (
  IN MTRR_MEMORY_RANGE       *Ranges,
  IN UINTN                   Capacity,
  IN OUT UINTN               *Count,
  IN UINT64                  BaseAddress,
  IN UINT64                  Length,
  IN MTRR_MEMORY_CACHE_TYPE  Type
  )
{
  UINTN   Index;
  UINT64  Limit;
  UINT64  LengthLeft;
  UINT64  LengthRight;
  UINTN   StartIndex;
  UINTN   EndIndex;
  UINTN   DeltaCount;

  ASSERT (Length != 0);

  LengthRight = 0;
  LengthLeft  = 0;
  Limit       = BaseAddress + Length;
  StartIndex  = *Count;
  EndIndex    = *Count;
  for (Index = 0; Index < *Count; Index++) {
    if ((StartIndex == *Count) &&
        (Ranges[Index].BaseAddress <= BaseAddress) &&
        (BaseAddress < Ranges[Index].BaseAddress + Ranges[Index].Length))
    {
      StartIndex = Index;
      LengthLeft = BaseAddress - Ranges[Index].BaseAddress;
    }

    if ((EndIndex == *Count) &&
        (Ranges[Index].BaseAddress < Limit) &&
        (Limit <= Ranges[Index].BaseAddress + Ranges[Index].Length))
    {
      EndIndex    = Index;
      LengthRight = Ranges[Index].BaseAddress + Ranges[Index].Length - Limit;
      break;
    }
  }

  ASSERT (StartIndex != *Count && EndIndex != *Count);
  if ((StartIndex == EndIndex) && (Ranges[StartIndex].Type == Type)) {
    return RETURN_ALREADY_STARTED;
  }

  //
  // The type change may cause merging with previous range or next range.
  // Update the StartIndex, EndIndex, BaseAddress, Length so that following
  // logic doesn't need to consider merging.
  //
  if (StartIndex != 0) {
    if ((LengthLeft == 0) && (Ranges[StartIndex - 1].Type == Type)) {
      StartIndex--;
      Length      += Ranges[StartIndex].Length;
      BaseAddress -= Ranges[StartIndex].Length;
    }
  }

  if (EndIndex != (*Count) - 1) {
    if ((LengthRight == 0) && (Ranges[EndIndex + 1].Type == Type)) {
      EndIndex++;
      Length += Ranges[EndIndex].Length;
    }
  }

  //
  // |- 0 -|- 1 -|- 2 -|- 3 -| StartIndex EndIndex DeltaCount  Count (Count = 4)
  //   |++++++++++++++++++|    0          3         1=3-0-2    3
  //   |+++++++|               0          1        -1=1-0-2    5
  //   |+|                     0          0        -2=0-0-2    6
  // |+++|                     0          0        -1=0-0-2+1  5
  //
  //
  DeltaCount = EndIndex - StartIndex - 2;
  if (LengthLeft == 0) {
    DeltaCount++;
  }

  if (LengthRight == 0) {
    DeltaCount++;
  }

  if (*Count - DeltaCount > Capacity) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Reserve (-DeltaCount) space
  //
  CopyMem (&Ranges[EndIndex + 1 - DeltaCount], &Ranges[EndIndex + 1], (*Count - EndIndex - 1) * sizeof (Ranges[0]));
  *Count -= DeltaCount;

  if (LengthLeft != 0) {
    Ranges[StartIndex].Length = LengthLeft;
    StartIndex++;
  }

  if (LengthRight != 0) {
    Ranges[EndIndex - DeltaCount].BaseAddress = BaseAddress + Length;
    Ranges[EndIndex - DeltaCount].Length      = LengthRight;
    Ranges[EndIndex - DeltaCount].Type        = Ranges[EndIndex].Type;
  }

  Ranges[StartIndex].BaseAddress = BaseAddress;
  Ranges[StartIndex].Length      = Length;
  Ranges[StartIndex].Type        = Type;
  return RETURN_SUCCESS;
}

/**
  Return the number of memory types in range [BaseAddress, BaseAddress + Length).

  @param Ranges      Array holding memory type settings for all memory regions.
  @param RangeCount  The count of memory ranges the array holds.
  @param BaseAddress Base address.
  @param Length      Length.
  @param Types       Return bit mask to indicate all memory types in the specified range.

  @retval  Number of memory types.
**/
UINT8
MtrrLibGetNumberOfTypes (
  IN CONST MTRR_MEMORY_RANGE  *Ranges,
  IN UINTN                    RangeCount,
  IN UINT64                   BaseAddress,
  IN UINT64                   Length,
  IN OUT UINT8                *Types  OPTIONAL
  )
{
  UINTN  Index;
  UINT8  TypeCount;
  UINT8  LocalTypes;

  TypeCount  = 0;
  LocalTypes = 0;
  for (Index = 0; Index < RangeCount; Index++) {
    if ((Ranges[Index].BaseAddress <= BaseAddress) &&
        (BaseAddress < Ranges[Index].BaseAddress + Ranges[Index].Length)
        )
    {
      if ((LocalTypes & (1 << Ranges[Index].Type)) == 0) {
        LocalTypes |= (UINT8)(1 << Ranges[Index].Type);
        TypeCount++;
      }

      if (BaseAddress + Length > Ranges[Index].BaseAddress + Ranges[Index].Length) {
        Length     -= Ranges[Index].BaseAddress + Ranges[Index].Length - BaseAddress;
        BaseAddress = Ranges[Index].BaseAddress + Ranges[Index].Length;
      } else {
        break;
      }
    }
  }

  if (Types != NULL) {
    *Types = LocalTypes;
  }

  return TypeCount;
}

/**
  Calculate the least MTRR number from vertex Start to Stop and update
  the Previous of all vertices from Start to Stop is updated to reflect
  how the memory range is covered by MTRR.

  @param VertexCount     The count of vertices in the graph.
  @param Vertices        Array holding all vertices.
  @param Weight          2-dimention array holding weights between vertices.
  @param Start           Start vertex.
  @param Stop            Stop vertex.
  @param IncludeOptional TRUE to count the optional weight.
**/
VOID
MtrrLibCalculateLeastMtrrs (
  IN UINT16            VertexCount,
  IN MTRR_LIB_ADDRESS  *Vertices,
  IN OUT CONST UINT8   *Weight,
  IN UINT16            Start,
  IN UINT16            Stop,
  IN BOOLEAN           IncludeOptional
  )
{
  UINT16  Index;
  UINT8   MinWeight;
  UINT16  MinI;
  UINT8   Mandatory;
  UINT8   Optional;

  for (Index = Start; Index <= Stop; Index++) {
    Vertices[Index].Visited = FALSE;
    Mandatory               = Weight[M (Start, Index)];
    Vertices[Index].Weight  = Mandatory;
    if (Mandatory != MAX_WEIGHT) {
      Optional                = IncludeOptional ? Weight[O (Start, Index)] : 0;
      Vertices[Index].Weight += Optional;
      ASSERT (Vertices[Index].Weight >= Optional);
    }
  }

  MinI      = Start;
  MinWeight = 0;
  while (!Vertices[Stop].Visited) {
    //
    // Update the weight from the shortest vertex to other unvisited vertices
    //
    for (Index = Start + 1; Index <= Stop; Index++) {
      if (!Vertices[Index].Visited) {
        Mandatory = Weight[M (MinI, Index)];
        if (Mandatory != MAX_WEIGHT) {
          Optional = IncludeOptional ? Weight[O (MinI, Index)] : 0;
          if (MinWeight + Mandatory + Optional <= Vertices[Index].Weight) {
            Vertices[Index].Weight   = MinWeight + Mandatory + Optional;
            Vertices[Index].Previous = MinI; // Previous is Start based.
          }
        }
      }
    }

    //
    // Find the shortest vertex from Start
    //
    MinI      = VertexCount;
    MinWeight = MAX_WEIGHT;
    for (Index = Start + 1; Index <= Stop; Index++) {
      if (!Vertices[Index].Visited && (MinWeight > Vertices[Index].Weight)) {
        MinI      = Index;
        MinWeight = Vertices[Index].Weight;
      }
    }

    //
    // Mark the shortest vertex from Start as visited
    //
    Vertices[MinI].Visited = TRUE;
  }
}

/**
  Append the MTRR setting to MTRR setting array.

  @param Mtrrs        Array holding all MTRR settings.
  @param MtrrCapacity Capacity of the MTRR array.
  @param MtrrCount    The count of MTRR settings in array.
  @param BaseAddress  Base address.
  @param Length       Length.
  @param Type         Memory type.

  @retval RETURN_SUCCESS          MTRR setting is appended to array.
  @retval RETURN_OUT_OF_RESOURCES Array is full.
**/
RETURN_STATUS
MtrrLibAppendVariableMtrr (
  IN OUT MTRR_MEMORY_RANGE       *Mtrrs,
  IN     UINT32                  MtrrCapacity,
  IN OUT UINT32                  *MtrrCount,
  IN     UINT64                  BaseAddress,
  IN     UINT64                  Length,
  IN     MTRR_MEMORY_CACHE_TYPE  Type
  )
{
  if (*MtrrCount == MtrrCapacity) {
    return RETURN_OUT_OF_RESOURCES;
  }

  Mtrrs[*MtrrCount].BaseAddress = BaseAddress;
  Mtrrs[*MtrrCount].Length      = Length;
  Mtrrs[*MtrrCount].Type        = Type;
  (*MtrrCount)++;
  return RETURN_SUCCESS;
}

/**
  Return the memory type that has the least precedence.

  @param TypeBits  Bit mask of memory type.

  @retval  Memory type that has the least precedence.
**/
MTRR_MEMORY_CACHE_TYPE
MtrrLibLowestType (
  IN      UINT8  TypeBits
  )
{
  INT8  Type;

  ASSERT (TypeBits != 0);
  for (Type = 7; (INT8)TypeBits > 0; Type--, TypeBits <<= 1) {
  }

  return (MTRR_MEMORY_CACHE_TYPE)Type;
}

/**
  Calculate the subtractive path from vertex Start to Stop.

  @param DefaultType  Default memory type.
  @param A0           Alignment to use when base address is 0.
  @param Ranges       Array holding memory type settings for all memory regions.
  @param RangeCount   The count of memory ranges the array holds.
  @param VertexCount  The count of vertices in the graph.
  @param Vertices     Array holding all vertices.
  @param Weight       2-dimention array holding weights between vertices.
  @param Start        Start vertex.
  @param Stop         Stop vertex.
  @param Types        Type bit mask of memory range from Start to Stop.
  @param TypeCount    Number of different memory types from Start to Stop.
  @param Mtrrs        Array holding all MTRR settings.
  @param MtrrCapacity Capacity of the MTRR array.
  @param MtrrCount    The count of MTRR settings in array.

  @retval RETURN_SUCCESS          The subtractive path is calculated successfully.
  @retval RETURN_OUT_OF_RESOURCES The MTRR setting array is full.

**/
RETURN_STATUS
MtrrLibCalculateSubtractivePath (
  IN MTRR_MEMORY_CACHE_TYPE   DefaultType,
  IN UINT64                   A0,
  IN CONST MTRR_MEMORY_RANGE  *Ranges,
  IN UINTN                    RangeCount,
  IN UINT16                   VertexCount,
  IN MTRR_LIB_ADDRESS         *Vertices,
  IN OUT UINT8                *Weight,
  IN UINT16                   Start,
  IN UINT16                   Stop,
  IN UINT8                    Types,
  IN UINT8                    TypeCount,
  IN OUT MTRR_MEMORY_RANGE    *Mtrrs        OPTIONAL,
  IN UINT32                   MtrrCapacity  OPTIONAL,
  IN OUT UINT32               *MtrrCount    OPTIONAL
  )
{
  RETURN_STATUS           Status;
  UINT64                  Base;
  UINT64                  Length;
  UINT8                   PrecedentTypes;
  UINTN                   Index;
  UINT64                  HBase;
  UINT64                  HLength;
  UINT64                  SubLength;
  UINT16                  SubStart;
  UINT16                  SubStop;
  UINT16                  Cur;
  UINT16                  Pre;
  MTRR_MEMORY_CACHE_TYPE  LowestType;
  MTRR_MEMORY_CACHE_TYPE  LowestPrecedentType;

  Base   = Vertices[Start].Address;
  Length = Vertices[Stop].Address - Base;

  LowestType = MtrrLibLowestType (Types);

  //
  // Clear the lowest type (highest bit) to get the precedent types
  //
  PrecedentTypes      = ~(1 << LowestType) & Types;
  LowestPrecedentType = MtrrLibLowestType (PrecedentTypes);

  if (Mtrrs == NULL) {
    Weight[M (Start, Stop)] = ((LowestType == DefaultType) ? 0 : 1);
    Weight[O (Start, Stop)] = ((LowestType == DefaultType) ? 1 : 0);
  }

  // Add all high level ranges
  HBase   = MAX_UINT64;
  HLength = 0;
  for (Index = 0; Index < RangeCount; Index++) {
    if (Length == 0) {
      break;
    }

    if ((Base < Ranges[Index].BaseAddress) || (Ranges[Index].BaseAddress + Ranges[Index].Length <= Base)) {
      continue;
    }

    //
    // Base is in the Range[Index]
    //
    if (Base + Length > Ranges[Index].BaseAddress + Ranges[Index].Length) {
      SubLength = Ranges[Index].BaseAddress + Ranges[Index].Length - Base;
    } else {
      SubLength = Length;
    }

    if (((1 << Ranges[Index].Type) & PrecedentTypes) != 0) {
      //
      // Meet a range whose types take precedence.
      // Update the [HBase, HBase + HLength) to include the range,
      // [HBase, HBase + HLength) may contain sub ranges with 2 different types, and both take precedence.
      //
      if (HBase == MAX_UINT64) {
        HBase = Base;
      }

      HLength += SubLength;
    }

    Base   += SubLength;
    Length -= SubLength;

    if (HLength == 0) {
      continue;
    }

    if ((Ranges[Index].Type == LowestType) || (Length == 0)) {
      // meet low type or end

      //
      // Add the MTRRs for each high priority type range
      // the range[HBase, HBase + HLength) contains only two types.
      // We might use positive or subtractive, depending on which way uses less MTRR
      //
      for (SubStart = Start; SubStart <= Stop; SubStart++) {
        if (Vertices[SubStart].Address == HBase) {
          break;
        }
      }

      for (SubStop = SubStart; SubStop <= Stop; SubStop++) {
        if (Vertices[SubStop].Address == HBase + HLength) {
          break;
        }
      }

      ASSERT (Vertices[SubStart].Address == HBase);
      ASSERT (Vertices[SubStop].Address == HBase + HLength);

      if ((TypeCount == 2) || (SubStart == SubStop - 1)) {
        //
        // add subtractive MTRRs for [HBase, HBase + HLength)
        // [HBase, HBase + HLength) contains only one type.
        // while - loop is to split the range to MTRR - compliant aligned range.
        //
        if (Mtrrs == NULL) {
          Weight[M (Start, Stop)] += (UINT8)(SubStop - SubStart);
        } else {
          while (SubStart != SubStop) {
            Status = MtrrLibAppendVariableMtrr (
                       Mtrrs,
                       MtrrCapacity,
                       MtrrCount,
                       Vertices[SubStart].Address,
                       Vertices[SubStart].Length,
                       Vertices[SubStart].Type
                       );
            if (RETURN_ERROR (Status)) {
              return Status;
            }

            SubStart++;
          }
        }
      } else {
        ASSERT (TypeCount == 3);
        MtrrLibCalculateLeastMtrrs (VertexCount, Vertices, Weight, SubStart, SubStop, TRUE);

        if (Mtrrs == NULL) {
          Weight[M (Start, Stop)] += Vertices[SubStop].Weight;
        } else {
          // When we need to collect the optimal path from SubStart to SubStop
          while (SubStop != SubStart) {
            Cur     = SubStop;
            Pre     = Vertices[Cur].Previous;
            SubStop = Pre;

            if (Weight[M (Pre, Cur)] + Weight[O (Pre, Cur)] != 0) {
              Status = MtrrLibAppendVariableMtrr (
                         Mtrrs,
                         MtrrCapacity,
                         MtrrCount,
                         Vertices[Pre].Address,
                         Vertices[Cur].Address - Vertices[Pre].Address,
                         (Pre != Cur - 1) ? LowestPrecedentType : Vertices[Pre].Type
                         );
              if (RETURN_ERROR (Status)) {
                return Status;
              }
            }

            if (Pre != Cur - 1) {
              Status = MtrrLibCalculateSubtractivePath (
                         DefaultType,
                         A0,
                         Ranges,
                         RangeCount,
                         VertexCount,
                         Vertices,
                         Weight,
                         Pre,
                         Cur,
                         PrecedentTypes,
                         2,
                         Mtrrs,
                         MtrrCapacity,
                         MtrrCount
                         );
              if (RETURN_ERROR (Status)) {
                return Status;
              }
            }
          }
        }
      }

      //
      // Reset HBase, HLength
      //
      HBase   = MAX_UINT64;
      HLength = 0;
    }
  }

  return RETURN_SUCCESS;
}

/**
  Calculate MTRR settings to cover the specified memory ranges.

  @param DefaultType  Default memory type.
  @param A0           Alignment to use when base address is 0.
  @param Ranges       Memory range array holding the memory type
                      settings for all memory address.
  @param RangeCount   Count of memory ranges.
  @param Scratch      A temporary scratch buffer that is used to perform the calculation.
                      This is an optional parameter that may be NULL.
  @param ScratchSize  Pointer to the size in bytes of the scratch buffer.
                      It may be updated to the actual required size when the calculation
                      needs more scratch buffer.
  @param Mtrrs        Array holding all MTRR settings.
  @param MtrrCapacity Capacity of the MTRR array.
  @param MtrrCount    The count of MTRR settings in array.

  @retval RETURN_SUCCESS          Variable MTRRs are allocated successfully.
  @retval RETURN_OUT_OF_RESOURCES Count of variable MTRRs exceeds capacity.
  @retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation.
**/
RETURN_STATUS
MtrrLibCalculateMtrrs (
  IN MTRR_MEMORY_CACHE_TYPE   DefaultType,
  IN UINT64                   A0,
  IN CONST MTRR_MEMORY_RANGE  *Ranges,
  IN UINTN                    RangeCount,
  IN VOID                     *Scratch,
  IN OUT UINTN                *ScratchSize,
  IN OUT MTRR_MEMORY_RANGE    *Mtrrs,
  IN UINT32                   MtrrCapacity,
  IN OUT UINT32               *MtrrCount
  )
{
  UINT64            Base0;
  UINT64            Base1;
  UINTN             Index;
  UINT64            Base;
  UINT64            Length;
  UINT64            Alignment;
  UINT64            SubLength;
  MTRR_LIB_ADDRESS  *Vertices;
  UINT8             *Weight;
  UINT32            VertexIndex;
  UINT32            VertexCount;
  UINTN             RequiredScratchSize;
  UINT8             TypeCount;
  UINT16            Start;
  UINT16            Stop;
  UINT8             Type;
  RETURN_STATUS     Status;

  Base0 = Ranges[0].BaseAddress;
  Base1 = Ranges[RangeCount - 1].BaseAddress + Ranges[RangeCount - 1].Length;
  MTRR_LIB_ASSERT_ALIGNED (Base0, Base1 - Base0);

  //
  // Count the number of vertices.
  //
  Vertices = (MTRR_LIB_ADDRESS *)Scratch;
  for (VertexIndex = 0, Index = 0; Index < RangeCount; Index++) {
    Base   = Ranges[Index].BaseAddress;
    Length = Ranges[Index].Length;
    while (Length != 0) {
      Alignment = MtrrLibBiggestAlignment (Base, A0);
      SubLength = Alignment;
      if (SubLength > Length) {
        SubLength = GetPowerOfTwo64 (Length);
      }

      if (VertexIndex < *ScratchSize / sizeof (*Vertices)) {
        Vertices[VertexIndex].Address   = Base;
        Vertices[VertexIndex].Alignment = Alignment;
        Vertices[VertexIndex].Type      = Ranges[Index].Type;
        Vertices[VertexIndex].Length    = SubLength;
      }

      Base   += SubLength;
      Length -= SubLength;
      VertexIndex++;
    }
  }

  //
  // Vertices[VertexIndex] = Base1, so whole vertex count is (VertexIndex + 1).
  //
  VertexCount = VertexIndex + 1;
  DEBUG ((
    DEBUG_CACHE,
    "  Count of vertices (%016llx - %016llx) = %d\n",
    Ranges[0].BaseAddress,
    Ranges[RangeCount - 1].BaseAddress + Ranges[RangeCount - 1].Length,
    VertexCount
    ));
  ASSERT (VertexCount < MAX_UINT16);

  RequiredScratchSize = VertexCount * sizeof (*Vertices) + VertexCount * VertexCount * sizeof (*Weight);
  if (*ScratchSize < RequiredScratchSize) {
    *ScratchSize = RequiredScratchSize;
    return RETURN_BUFFER_TOO_SMALL;
  }

  Vertices[VertexCount - 1].Address = Base1;

  Weight = (UINT8 *)&Vertices[VertexCount];
  for (VertexIndex = 0; VertexIndex < VertexCount; VertexIndex++) {
    //
    // Set optional weight between vertices and self->self to 0
    //
    SetMem (&Weight[M (VertexIndex, 0)], VertexIndex + 1, 0);
    //
    // Set mandatory weight between vertices to MAX_WEIGHT
    //
    SetMem (&Weight[M (VertexIndex, VertexIndex + 1)], VertexCount - VertexIndex - 1, MAX_WEIGHT);

    // Final result looks like:
    //   00 FF FF FF
    //   00 00 FF FF
    //   00 00 00 FF
    //   00 00 00 00
  }

  //
  // Set mandatory weight and optional weight for adjacent vertices
  //
  for (VertexIndex = 0; VertexIndex < VertexCount - 1; VertexIndex++) {
    if (Vertices[VertexIndex].Type != DefaultType) {
      Weight[M (VertexIndex, VertexIndex + 1)] = 1;
      Weight[O (VertexIndex, VertexIndex + 1)] = 0;
    } else {
      Weight[M (VertexIndex, VertexIndex + 1)] = 0;
      Weight[O (VertexIndex, VertexIndex + 1)] = 1;
    }
  }

  for (TypeCount = 2; TypeCount <= 3; TypeCount++) {
    for (Start = 0; Start < VertexCount; Start++) {
      for (Stop = Start + 2; Stop < VertexCount; Stop++) {
        ASSERT (Vertices[Stop].Address > Vertices[Start].Address);
        Length = Vertices[Stop].Address - Vertices[Start].Address;
        if (Length > Vertices[Start].Alignment) {
          //
          // Pickup a new Start when [Start, Stop) cannot be described by one MTRR.
          //
          break;
        }

        if ((Weight[M (Start, Stop)] == MAX_WEIGHT) && IS_POW2 (Length)) {
          if (MtrrLibGetNumberOfTypes (
                Ranges,
                RangeCount,
                Vertices[Start].Address,
                Vertices[Stop].Address - Vertices[Start].Address,
                &Type
                ) == TypeCount)
          {
            //
            // Update the Weight[Start, Stop] using subtractive path.
            //
            MtrrLibCalculateSubtractivePath (
              DefaultType,
              A0,
              Ranges,
              RangeCount,
              (UINT16)VertexCount,
              Vertices,
              Weight,
              Start,
              Stop,
              Type,
              TypeCount,
              NULL,
              0,
              NULL
              );
          } else if (TypeCount == 2) {
            //
            // Pick up a new Start when we expect 2-type range, but 3-type range is met.
            // Because no matter how Stop is increased, we always meet 3-type range.
            //
            break;
          }
        }
      }
    }
  }

  Status = RETURN_SUCCESS;
  MtrrLibCalculateLeastMtrrs ((UINT16)VertexCount, Vertices, Weight, 0, (UINT16)VertexCount - 1, FALSE);
  Stop = (UINT16)VertexCount - 1;
  while (Stop != 0) {
    Start     = Vertices[Stop].Previous;
    TypeCount = MAX_UINT8;
    Type      = 0;
    if (Weight[M (Start, Stop)] != 0) {
      TypeCount = MtrrLibGetNumberOfTypes (Ranges, RangeCount, Vertices[Start].Address, Vertices[Stop].Address - Vertices[Start].Address, &Type);
      Status    = MtrrLibAppendVariableMtrr (
                    Mtrrs,
                    MtrrCapacity,
                    MtrrCount,
                    Vertices[Start].Address,
                    Vertices[Stop].Address - Vertices[Start].Address,
                    MtrrLibLowestType (Type)
                    );
      if (RETURN_ERROR (Status)) {
        break;
      }
    }

    if (Start != Stop - 1) {
      //
      // substractive path
      //
      if (TypeCount == MAX_UINT8) {
        TypeCount = MtrrLibGetNumberOfTypes (
                      Ranges,
                      RangeCount,
                      Vertices[Start].Address,
                      Vertices[Stop].Address - Vertices[Start].Address,
                      &Type
                      );
      }

      Status = MtrrLibCalculateSubtractivePath (
                 DefaultType,
                 A0,
                 Ranges,
                 RangeCount,
                 (UINT16)VertexCount,
                 Vertices,
                 Weight,
                 Start,
                 Stop,
                 Type,
                 TypeCount,
                 Mtrrs,
                 MtrrCapacity,
                 MtrrCount
                 );
      if (RETURN_ERROR (Status)) {
        break;
      }
    }

    Stop = Start;
  }

  return Status;
}

/**
  Apply the fixed MTRR settings to memory range array.

  @param Fixed             The fixed MTRR settings.
  @param Ranges            Return the memory range array holding memory type
                           settings for all memory address.
  @param RangeCapacity     The capacity of memory range array.
  @param RangeCount        Return the count of memory range.

  @retval RETURN_SUCCESS          The memory range array is returned successfully.
  @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds capacity.
**/
RETURN_STATUS
MtrrLibApplyFixedMtrrs (
  IN     CONST MTRR_FIXED_SETTINGS  *Fixed,
  IN OUT MTRR_MEMORY_RANGE          *Ranges,
  IN     UINTN                      RangeCapacity,
  IN OUT UINTN                      *RangeCount
  )
{
  RETURN_STATUS           Status;
  UINTN                   MsrIndex;
  UINTN                   Index;
  MTRR_MEMORY_CACHE_TYPE  MemoryType;
  UINT64                  Base;

  Base = 0;
  for (MsrIndex = 0; MsrIndex < ARRAY_SIZE (mMtrrLibFixedMtrrTable); MsrIndex++) {
    ASSERT (Base == mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress);
    for (Index = 0; Index < sizeof (UINT64); Index++) {
      MemoryType = (MTRR_MEMORY_CACHE_TYPE)((UINT8 *)(&Fixed->Mtrr[MsrIndex]))[Index];
      Status     = MtrrLibSetMemoryType (
                     Ranges,
                     RangeCapacity,
                     RangeCount,
                     Base,
                     mMtrrLibFixedMtrrTable[MsrIndex].Length,
                     MemoryType
                     );
      if (Status == RETURN_OUT_OF_RESOURCES) {
        return Status;
      }

      Base += mMtrrLibFixedMtrrTable[MsrIndex].Length;
    }
  }

  ASSERT (Base == BASE_1MB);
  return RETURN_SUCCESS;
}

/**
  Apply the variable MTRR settings to memory range array.

  @param VariableMtrr      The variable MTRR array.
  @param VariableMtrrCount The count of variable MTRRs.
  @param Ranges            Return the memory range array with new MTRR settings applied.
  @param RangeCapacity     The capacity of memory range array.
  @param RangeCount        Return the count of memory range.

  @retval RETURN_SUCCESS          The memory range array is returned successfully.
  @retval RETURN_OUT_OF_RESOURCES The count of memory ranges exceeds capacity.
**/
RETURN_STATUS
MtrrLibApplyVariableMtrrs (
  IN     CONST MTRR_MEMORY_RANGE  *VariableMtrr,
  IN     UINT32                   VariableMtrrCount,
  IN OUT MTRR_MEMORY_RANGE        *Ranges,
  IN     UINTN                    RangeCapacity,
  IN OUT UINTN                    *RangeCount
  )
{
  RETURN_STATUS  Status;
  UINTN          Index;

  //
  // WT > WB
  // UC > *
  // UC > * (except WB, UC) > WB
  //

  //
  // 1. Set WB
  //
  for (Index = 0; Index < VariableMtrrCount; Index++) {
    if ((VariableMtrr[Index].Length != 0) && (VariableMtrr[Index].Type == CacheWriteBack)) {
      Status = MtrrLibSetMemoryType (
                 Ranges,
                 RangeCapacity,
                 RangeCount,
                 VariableMtrr[Index].BaseAddress,
                 VariableMtrr[Index].Length,
                 VariableMtrr[Index].Type
                 );
      if (Status == RETURN_OUT_OF_RESOURCES) {
        return Status;
      }
    }
  }

  //
  // 2. Set other types than WB or UC
  //
  for (Index = 0; Index < VariableMtrrCount; Index++) {
    if ((VariableMtrr[Index].Length != 0) &&
        (VariableMtrr[Index].Type != CacheWriteBack) && (VariableMtrr[Index].Type != CacheUncacheable))
    {
      Status = MtrrLibSetMemoryType (
                 Ranges,
                 RangeCapacity,
                 RangeCount,
                 VariableMtrr[Index].BaseAddress,
                 VariableMtrr[Index].Length,
                 VariableMtrr[Index].Type
                 );
      if (Status == RETURN_OUT_OF_RESOURCES) {
        return Status;
      }
    }
  }

  //
  // 3. Set UC
  //
  for (Index = 0; Index < VariableMtrrCount; Index++) {
    if ((VariableMtrr[Index].Length != 0) && (VariableMtrr[Index].Type == CacheUncacheable)) {
      Status = MtrrLibSetMemoryType (
                 Ranges,
                 RangeCapacity,
                 RangeCount,
                 VariableMtrr[Index].BaseAddress,
                 VariableMtrr[Index].Length,
                 VariableMtrr[Index].Type
                 );
      if (Status == RETURN_OUT_OF_RESOURCES) {
        return Status;
      }
    }
  }

  return RETURN_SUCCESS;
}

/**
  Return the memory type bit mask that's compatible to first type in the Ranges.

  @param Ranges     Memory range array holding the memory type
                    settings for all memory address.
  @param RangeCount Count of memory ranges.

  @return Compatible memory type bit mask.
**/
UINT8
MtrrLibGetCompatibleTypes (
  IN CONST MTRR_MEMORY_RANGE  *Ranges,
  IN UINTN                    RangeCount
  )
{
  ASSERT (RangeCount != 0);

  switch (Ranges[0].Type) {
    case CacheWriteBack:
    case CacheWriteThrough:
      return (1 << CacheWriteBack) | (1 << CacheWriteThrough) | (1 << CacheUncacheable);
      break;

    case CacheWriteCombining:
    case CacheWriteProtected:
      return (1 << Ranges[0].Type) | (1 << CacheUncacheable);
      break;

    case CacheUncacheable:
      if (RangeCount == 1) {
        return (1 << CacheUncacheable);
      }

      return MtrrLibGetCompatibleTypes (&Ranges[1], RangeCount - 1);
      break;

    case CacheInvalid:
    default:
      ASSERT (FALSE);
      break;
  }

  return 0;
}

/**
  Overwrite the destination MTRR settings with the source MTRR settings.
  This routine is to make sure the modification to destination MTRR settings
  is as small as possible.

  @param DstMtrrs     Destination MTRR settings.
  @param DstMtrrCount Count of destination MTRR settings.
  @param SrcMtrrs     Source MTRR settings.
  @param SrcMtrrCount Count of source MTRR settings.
  @param Modified     Flag array to indicate which destination MTRR setting is modified.
**/
VOID
MtrrLibMergeVariableMtrr (
  MTRR_MEMORY_RANGE  *DstMtrrs,
  UINT32             DstMtrrCount,
  MTRR_MEMORY_RANGE  *SrcMtrrs,
  UINT32             SrcMtrrCount,
  BOOLEAN            *Modified
  )
{
  UINT32  DstIndex;
  UINT32  SrcIndex;

  ASSERT (SrcMtrrCount <= DstMtrrCount);

  for (DstIndex = 0; DstIndex < DstMtrrCount; DstIndex++) {
    Modified[DstIndex] = FALSE;

    if (DstMtrrs[DstIndex].Length == 0) {
      continue;
    }

    for (SrcIndex = 0; SrcIndex < SrcMtrrCount; SrcIndex++) {
      if ((DstMtrrs[DstIndex].BaseAddress == SrcMtrrs[SrcIndex].BaseAddress) &&
          (DstMtrrs[DstIndex].Length == SrcMtrrs[SrcIndex].Length) &&
          (DstMtrrs[DstIndex].Type == SrcMtrrs[SrcIndex].Type))
      {
        break;
      }
    }

    if (SrcIndex == SrcMtrrCount) {
      //
      // Remove the one from DstMtrrs which is not in SrcMtrrs
      //
      DstMtrrs[DstIndex].Length = 0;
      Modified[DstIndex]        = TRUE;
    } else {
      //
      // Remove the one from SrcMtrrs which is also in DstMtrrs
      //
      SrcMtrrs[SrcIndex].Length = 0;
    }
  }

  //
  // Now valid MTRR only exists in either DstMtrrs or SrcMtrrs.
  // Merge MTRRs from SrcMtrrs to DstMtrrs
  //
  DstIndex = 0;
  for (SrcIndex = 0; SrcIndex < SrcMtrrCount; SrcIndex++) {
    if (SrcMtrrs[SrcIndex].Length != 0) {
      //
      // Find the empty slot in DstMtrrs
      //
      while (DstIndex < DstMtrrCount) {
        if (DstMtrrs[DstIndex].Length == 0) {
          break;
        }

        DstIndex++;
      }

      ASSERT (DstIndex < DstMtrrCount);
      CopyMem (&DstMtrrs[DstIndex], &SrcMtrrs[SrcIndex], sizeof (SrcMtrrs[0]));
      Modified[DstIndex] = TRUE;
    }
  }
}

/**
  Calculate the variable MTRR settings for all memory ranges.

  @param DefaultType          Default memory type.
  @param A0                   Alignment to use when base address is 0.
  @param Ranges               Memory range array holding the memory type
                              settings for all memory address.
  @param RangeCount           Count of memory ranges.
  @param Scratch              Scratch buffer to be used in MTRR calculation.
  @param ScratchSize          Pointer to the size of scratch buffer.
  @param VariableMtrr         Array holding all MTRR settings.
  @param VariableMtrrCapacity Capacity of the MTRR array.
  @param VariableMtrrCount    The count of MTRR settings in array.

  @retval RETURN_SUCCESS          Variable MTRRs are allocated successfully.
  @retval RETURN_OUT_OF_RESOURCES Count of variable MTRRs exceeds capacity.
  @retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation.
                                  The required scratch buffer size is returned through ScratchSize.
**/
RETURN_STATUS
MtrrLibSetMemoryRanges (
  IN MTRR_MEMORY_CACHE_TYPE  DefaultType,
  IN UINT64                  A0,
  IN MTRR_MEMORY_RANGE       *Ranges,
  IN UINTN                   RangeCount,
  IN VOID                    *Scratch,
  IN OUT UINTN               *ScratchSize,
  OUT MTRR_MEMORY_RANGE      *VariableMtrr,
  IN UINT32                  VariableMtrrCapacity,
  OUT UINT32                 *VariableMtrrCount
  )
{
  RETURN_STATUS  Status;
  UINT32         Index;
  UINT64         Base0;
  UINT64         Base1;
  UINT64         Alignment;
  UINT8          CompatibleTypes;
  UINT64         Length;
  UINT32         End;
  UINTN          ActualScratchSize;
  UINTN          BiggestScratchSize;

  *VariableMtrrCount = 0;

  //
  // Since the whole ranges need multiple calls of MtrrLibCalculateMtrrs().
  // Each call needs different scratch buffer size.
  // When the provided scratch buffer size is not sufficient in any call,
  // set the GetActualScratchSize to TRUE, and following calls will only
  // calculate the actual scratch size for the caller.
  //
  BiggestScratchSize = 0;

  for (Index = 0; Index < RangeCount;) {
    Base0 = Ranges[Index].BaseAddress;

    //
    // Full step is optimal
    //
    while (Index < RangeCount) {
      ASSERT (Ranges[Index].BaseAddress == Base0);
      Alignment = MtrrLibBiggestAlignment (Base0, A0);
      while (Base0 + Alignment <= Ranges[Index].BaseAddress + Ranges[Index].Length) {
        if ((BiggestScratchSize <= *ScratchSize) && (Ranges[Index].Type != DefaultType)) {
          Status = MtrrLibAppendVariableMtrr (
                     VariableMtrr,
                     VariableMtrrCapacity,
                     VariableMtrrCount,
                     Base0,
                     Alignment,
                     Ranges[Index].Type
                     );
          if (RETURN_ERROR (Status)) {
            return Status;
          }
        }

        Base0    += Alignment;
        Alignment = MtrrLibBiggestAlignment (Base0, A0);
      }

      //
      // Remove the above range from Ranges[Index]
      //
      Ranges[Index].Length     -= Base0 - Ranges[Index].BaseAddress;
      Ranges[Index].BaseAddress = Base0;
      if (Ranges[Index].Length != 0) {
        break;
      } else {
        Index++;
      }
    }

    if (Index == RangeCount) {
      break;
    }

    //
    // Find continous ranges [Base0, Base1) which could be combined by MTRR.
    // Per SDM, the compatible types between[B0, B1) are:
    //   UC, *
    //   WB, WT
    //   UC, WB, WT
    //
    CompatibleTypes = MtrrLibGetCompatibleTypes (&Ranges[Index], RangeCount - Index);

    End = Index; // End points to last one that matches the CompatibleTypes.
    while (End + 1 < RangeCount) {
      if (((1 << Ranges[End + 1].Type) & CompatibleTypes) == 0) {
        break;
      }

      End++;
    }

    Alignment = MtrrLibBiggestAlignment (Base0, A0);
    Length    = GetPowerOfTwo64 (Ranges[End].BaseAddress + Ranges[End].Length - Base0);
    Base1     = Base0 + MIN (Alignment, Length);

    //
    // Base1 may not in Ranges[End]. Update End to the range Base1 belongs to.
    //
    End = Index;
    while (End + 1 < RangeCount) {
      if (Base1 <= Ranges[End + 1].BaseAddress) {
        break;
      }

      End++;
    }

    Length             = Ranges[End].Length;
    Ranges[End].Length = Base1 - Ranges[End].BaseAddress;
    ActualScratchSize  = *ScratchSize;
    Status             = MtrrLibCalculateMtrrs (
                           DefaultType,
                           A0,
                           &Ranges[Index],
                           End + 1 - Index,
                           Scratch,
                           &ActualScratchSize,
                           VariableMtrr,
                           VariableMtrrCapacity,
                           VariableMtrrCount
                           );
    if (Status == RETURN_BUFFER_TOO_SMALL) {
      BiggestScratchSize = MAX (BiggestScratchSize, ActualScratchSize);
      //
      // Ignore this error, because we need to calculate the biggest
      // scratch buffer size.
      //
      Status = RETURN_SUCCESS;
    }

    if (RETURN_ERROR (Status)) {
      return Status;
    }

    if (Length != Ranges[End].Length) {
      Ranges[End].BaseAddress = Base1;
      Ranges[End].Length      = Length - Ranges[End].Length;
      Index                   = End;
    } else {
      Index = End + 1;
    }
  }

  if (*ScratchSize < BiggestScratchSize) {
    *ScratchSize = BiggestScratchSize;
    return RETURN_BUFFER_TOO_SMALL;
  }

  return RETURN_SUCCESS;
}

/**
  Set the below-1MB memory attribute to fixed MTRR buffer.
  Modified flag array indicates which fixed MTRR is modified.

  @param [in, out] ClearMasks    The bits (when set) to clear in the fixed MTRR MSR.
  @param [in, out] OrMasks       The bits to set in the fixed MTRR MSR.
  @param [in]      BaseAddress   Base address.
  @param [in]      Length        Length.
  @param [in]      Type          Memory type.

  @retval RETURN_SUCCESS      The memory attribute is set successfully.
  @retval RETURN_UNSUPPORTED  The requested range or cache type was invalid
                              for the fixed MTRRs.
**/
RETURN_STATUS
MtrrLibSetBelow1MBMemoryAttribute (
  IN OUT UINT64              *ClearMasks,
  IN OUT UINT64              *OrMasks,
  IN PHYSICAL_ADDRESS        BaseAddress,
  IN UINT64                  Length,
  IN MTRR_MEMORY_CACHE_TYPE  Type
  )
{
  RETURN_STATUS  Status;
  UINT32         MsrIndex;
  UINT64         ClearMask;
  UINT64         OrMask;

  ASSERT (BaseAddress < BASE_1MB);

  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] = ClearMasks[MsrIndex] | ClearMask;
    OrMasks[MsrIndex]    = (OrMasks[MsrIndex] & ~ClearMask) | OrMask;
  }

  return RETURN_SUCCESS;
}

/**
  This function attempts to set the attributes into MTRR setting buffer for multiple memory ranges.

  @param[in, out]  MtrrSetting  MTRR setting buffer to be set.
  @param[in]       Scratch      A temporary scratch buffer that is used to perform the calculation.
  @param[in, out]  ScratchSize  Pointer to the size in bytes of the scratch buffer.
                                It may be updated to the actual required size when the calculation
                                needs more scratch buffer.
  @param[in]       Ranges       Pointer to an array of MTRR_MEMORY_RANGE.
                                When range overlap happens, the last one takes higher priority.
                                When the function returns, either all the attributes are set successfully,
                                or none of them is set.
  @param[in]       RangeCount   Count of MTRR_MEMORY_RANGE.

  @retval RETURN_SUCCESS            The attributes were set for all the memory ranges.
  @retval RETURN_INVALID_PARAMETER  Length in any range is zero.
  @retval RETURN_UNSUPPORTED        The processor does not support one or more bytes of the
                                    memory resource range specified by BaseAddress and Length in any range.
  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support for the memory resource
                                    range specified by BaseAddress and Length in any range.
  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to modify the attributes of
                                    the memory resource ranges.
  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource range specified by
                                    BaseAddress and Length cannot be modified.
  @retval RETURN_BUFFER_TOO_SMALL   The scratch buffer is too small for MTRR calculation.
**/
RETURN_STATUS
EFIAPI
MtrrSetMemoryAttributesInMtrrSettings (
  IN OUT MTRR_SETTINGS            *MtrrSetting,
  IN     VOID                     *Scratch,
  IN OUT UINTN                    *ScratchSize,
  IN     CONST MTRR_MEMORY_RANGE  *Ranges,
  IN     UINTN                    RangeCount
  )
{
  RETURN_STATUS  Status;
  UINT32         Index;
  UINT64         BaseAddress;
  UINT64         Length;
  BOOLEAN        VariableMtrrNeeded;

  UINT64                  MtrrValidBitsMask;
  UINT64                  MtrrValidAddressMask;
  MTRR_MEMORY_CACHE_TYPE  DefaultType;
  MTRR_VARIABLE_SETTINGS  VariableSettings;
  MTRR_MEMORY_RANGE       WorkingRanges[2 * ARRAY_SIZE (MtrrSetting->Variables.Mtrr) + 2];
  UINTN                   WorkingRangeCount;
  BOOLEAN                 Modified;
  MTRR_VARIABLE_SETTING   VariableSetting;
  UINT32                  OriginalVariableMtrrCount;
  UINT32                  FirmwareVariableMtrrCount;
  UINT32                  WorkingVariableMtrrCount;
  MTRR_MEMORY_RANGE       OriginalVariableMtrr[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)];
  MTRR_MEMORY_RANGE       WorkingVariableMtrr[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)];
  BOOLEAN                 VariableSettingModified[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)];

  UINT64   FixedMtrrMemoryLimit;
  BOOLEAN  FixedMtrrSupported;
  UINT64   ClearMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)];
  UINT64   OrMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)];

  MTRR_CONTEXT  MtrrContext;
  BOOLEAN       MtrrContextValid;

  Status = RETURN_SUCCESS;
  MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);

  //
  // TRUE indicating the accordingly Variable setting needs modificaiton in OriginalVariableMtrr.
  //
  SetMem (VariableSettingModified, ARRAY_SIZE (VariableSettingModified), FALSE);

  //
  // TRUE indicating the caller requests to set variable MTRRs.
  //
  VariableMtrrNeeded        = FALSE;
  OriginalVariableMtrrCount = 0;

  //
  // 0. Dump the requests.
  //
  DEBUG_CODE_BEGIN ();
  DEBUG ((
    DEBUG_CACHE,
    "Mtrr: Set Mem Attribute to %a, ScratchSize = %x%a",
    (MtrrSetting == NULL) ? "Hardware" : "Buffer",
    *ScratchSize,
    (RangeCount <= 1) ? "," : "\n"
    ));
  for (Index = 0; Index < RangeCount; Index++) {
    DEBUG ((
      DEBUG_CACHE,
      " %a: [%016lx, %016lx)\n",
      mMtrrMemoryCacheTypeShortName[MIN (Ranges[Index].Type, CacheInvalid)],
      Ranges[Index].BaseAddress,
      Ranges[Index].BaseAddress + Ranges[Index].Length
      ));
  }

  DEBUG_CODE_END ();

  //
  // 1. Validate the parameters.
  //
  if (!MtrrLibIsMtrrSupported (&FixedMtrrSupported, &OriginalVariableMtrrCount)) {
    Status = RETURN_UNSUPPORTED;
    goto Exit;
  }

  FixedMtrrMemoryLimit = FixedMtrrSupported ? BASE_1MB : 0;

  for (Index = 0; Index < RangeCount; Index++) {
    if (Ranges[Index].Length == 0) {
      Status = RETURN_INVALID_PARAMETER;
      goto Exit;
    }

    if (((Ranges[Index].BaseAddress & ~MtrrValidAddressMask) != 0) ||
        ((((Ranges[Index].BaseAddress + Ranges[Index].Length) & ~MtrrValidAddressMask) != 0) &&
         ((Ranges[Index].BaseAddress + Ranges[Index].Length) != MtrrValidBitsMask + 1))
        )
    {
      //
      // Either the BaseAddress or the Limit doesn't follow the alignment requirement.
      // Note: It's still valid if Limit doesn't follow the alignment requirement but equals to MAX Address.
      //
      Status = RETURN_UNSUPPORTED;
      goto Exit;
    }

    if ((Ranges[Index].Type != CacheUncacheable) &&
        (Ranges[Index].Type != CacheWriteCombining) &&
        (Ranges[Index].Type != CacheWriteThrough) &&
        (Ranges[Index].Type != CacheWriteProtected) &&
        (Ranges[Index].Type != CacheWriteBack))
    {
      Status = RETURN_INVALID_PARAMETER;
      goto Exit;
    }

    if (Ranges[Index].BaseAddress + Ranges[Index].Length > FixedMtrrMemoryLimit) {
      VariableMtrrNeeded = TRUE;
    }
  }

  //
  // 2. Apply the above-1MB memory attribute settings.
  //
  if (VariableMtrrNeeded) {
    //
    // 2.1. Read all variable MTRRs and convert to Ranges.
    //
    MtrrGetVariableMtrrWorker (MtrrSetting, OriginalVariableMtrrCount, &VariableSettings);
    MtrrLibGetRawVariableRanges (
      &VariableSettings,
      OriginalVariableMtrrCount,
      MtrrValidBitsMask,
      MtrrValidAddressMask,
      OriginalVariableMtrr
      );

    DefaultType                  = MtrrGetDefaultMemoryTypeWorker (MtrrSetting);
    WorkingRangeCount            = 1;
    WorkingRanges[0].BaseAddress = 0;
    WorkingRanges[0].Length      = MtrrValidBitsMask + 1;
    WorkingRanges[0].Type        = DefaultType;

    Status = MtrrLibApplyVariableMtrrs (
               OriginalVariableMtrr,
               OriginalVariableMtrrCount,
               WorkingRanges,
               ARRAY_SIZE (WorkingRanges),
               &WorkingRangeCount
               );
    ASSERT_RETURN_ERROR (Status);

    ASSERT (OriginalVariableMtrrCount >= PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs));
    FirmwareVariableMtrrCount = OriginalVariableMtrrCount - PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs);
    ASSERT (WorkingRangeCount <= 2 * FirmwareVariableMtrrCount + 1);

    //
    // 2.2. Force [0, 1M) to UC, so that it doesn't impact subtraction algorithm.
    //
    if (FixedMtrrMemoryLimit != 0) {
      Status = MtrrLibSetMemoryType (
                 WorkingRanges,
                 ARRAY_SIZE (WorkingRanges),
                 &WorkingRangeCount,
                 0,
                 FixedMtrrMemoryLimit,
                 CacheUncacheable
                 );
      ASSERT (Status != RETURN_OUT_OF_RESOURCES);
    }

    //
    // 2.3. Apply the new memory attribute settings to Ranges.
    //
    Modified = FALSE;
    for (Index = 0; Index < RangeCount; Index++) {
      BaseAddress = Ranges[Index].BaseAddress;
      Length      = Ranges[Index].Length;
      if (BaseAddress < FixedMtrrMemoryLimit) {
        if (Length <= FixedMtrrMemoryLimit - BaseAddress) {
          continue;
        }

        Length     -= FixedMtrrMemoryLimit - BaseAddress;
        BaseAddress = FixedMtrrMemoryLimit;
      }

      Status = MtrrLibSetMemoryType (
                 WorkingRanges,
                 ARRAY_SIZE (WorkingRanges),
                 &WorkingRangeCount,
                 BaseAddress,
                 Length,
                 Ranges[Index].Type
                 );
      if (Status == RETURN_ALREADY_STARTED) {
        Status = RETURN_SUCCESS;
      } else if (Status == RETURN_OUT_OF_RESOURCES) {
        goto Exit;
      } else {
        ASSERT_RETURN_ERROR (Status);
        Modified = TRUE;
      }
    }

    if (Modified) {
      //
      // 2.4. Calculate the Variable MTRR settings based on the Ranges.
      //      Buffer Too Small may be returned if the scratch buffer size is insufficient.
      //
      Status = MtrrLibSetMemoryRanges (
                 DefaultType,
                 LShiftU64 (1, (UINTN)HighBitSet64 (MtrrValidBitsMask)),
                 WorkingRanges,
                 WorkingRangeCount,
                 Scratch,
                 ScratchSize,
                 WorkingVariableMtrr,
                 FirmwareVariableMtrrCount + 1,
                 &WorkingVariableMtrrCount
                 );
      if (RETURN_ERROR (Status)) {
        goto Exit;
      }

      //
      // 2.5. Remove the [0, 1MB) MTRR if it still exists (not merged with other range)
      //
      for (Index = 0; Index < WorkingVariableMtrrCount; Index++) {
        if ((WorkingVariableMtrr[Index].BaseAddress == 0) && (WorkingVariableMtrr[Index].Length == FixedMtrrMemoryLimit)) {
          ASSERT (WorkingVariableMtrr[Index].Type == CacheUncacheable);
          WorkingVariableMtrrCount--;
          CopyMem (
            &WorkingVariableMtrr[Index],
            &WorkingVariableMtrr[Index + 1],
            (WorkingVariableMtrrCount - Index) * sizeof (WorkingVariableMtrr[0])
            );
          break;
        }
      }

      if (WorkingVariableMtrrCount > FirmwareVariableMtrrCount) {
        Status = RETURN_OUT_OF_RESOURCES;
        goto Exit;
      }

      //
      // 2.6. Merge the WorkingVariableMtrr to OriginalVariableMtrr
      //      Make sure least modification is made to OriginalVariableMtrr.
      //
      MtrrLibMergeVariableMtrr (
        OriginalVariableMtrr,
        OriginalVariableMtrrCount,
        WorkingVariableMtrr,
        WorkingVariableMtrrCount,
        VariableSettingModified
        );
    }
  }

  //
  // 3. Apply the below-1MB memory attribute settings.
  //
  // (Value & ~0 | 0) still equals to (Value)
  //
  ZeroMem (ClearMasks, sizeof (ClearMasks));
  ZeroMem (OrMasks, sizeof (OrMasks));
  for (Index = 0; Index < RangeCount; Index++) {
    if (Ranges[Index].BaseAddress >= FixedMtrrMemoryLimit) {
      continue;
    }

    Status = MtrrLibSetBelow1MBMemoryAttribute (
               ClearMasks,
               OrMasks,
               Ranges[Index].BaseAddress,
               Ranges[Index].Length,
               Ranges[Index].Type
               );
    if (RETURN_ERROR (Status)) {
      goto Exit;
    }
  }

  MtrrContextValid = FALSE;
  //
  // 4. Write fixed MTRRs that have been modified
  //
  for (Index = 0; Index < ARRAY_SIZE (ClearMasks); Index++) {
    if (ClearMasks[Index] != 0) {
      if (MtrrSetting != NULL) {
        //
        // Fixed MTRR is modified indicating fixed MTRR should be enabled in the end of MTRR programming.
        //
        ((MSR_IA32_MTRR_DEF_TYPE_REGISTER *)&MtrrSetting->MtrrDefType)->Bits.FE = 1;
        MtrrSetting->Fixed.Mtrr[Index]                                          = (MtrrSetting->Fixed.Mtrr[Index] & ~ClearMasks[Index]) | OrMasks[Index];
      } else {
        if (!MtrrContextValid) {
          MtrrLibPreMtrrChange (&MtrrContext);
          //
          // Fixed MTRR is modified indicating fixed MTRR should be enabled in the end of MTRR programming.
          //
          MtrrContext.DefType.Bits.FE = 1;
          MtrrContextValid            = TRUE;
        }

        AsmMsrAndThenOr64 (mMtrrLibFixedMtrrTable[Index].Msr, ~ClearMasks[Index], OrMasks[Index]);
      }
    }
  }

  //
  // 5. Write variable MTRRs that have been modified
  //
  for (Index = 0; Index < OriginalVariableMtrrCount; Index++) {
    if (VariableSettingModified[Index]) {
      if (OriginalVariableMtrr[Index].Length != 0) {
        VariableSetting.Base = (OriginalVariableMtrr[Index].BaseAddress & MtrrValidAddressMask)
                               | (UINT8)OriginalVariableMtrr[Index].Type;
        VariableSetting.Mask = ((~(OriginalVariableMtrr[Index].Length - 1)) & MtrrValidAddressMask) | BIT11;
      } else {
        VariableSetting.Base = 0;
        VariableSetting.Mask = 0;
      }

      if (MtrrSetting != NULL) {
        CopyMem (&MtrrSetting->Variables.Mtrr[Index], &VariableSetting, sizeof (VariableSetting));
      } else {
        if (!MtrrContextValid) {
          MtrrLibPreMtrrChange (&MtrrContext);
          MtrrContextValid = TRUE;
        }

        AsmWriteMsr64 (
          MSR_IA32_MTRR_PHYSBASE0 + (Index << 1),
          VariableSetting.Base
          );
        AsmWriteMsr64 (
          MSR_IA32_MTRR_PHYSMASK0 + (Index << 1),
          VariableSetting.Mask
          );
      }
    }
  }

  if (MtrrSetting != NULL) {
    //
    // Enable MTRR unconditionally
    //
    ((MSR_IA32_MTRR_DEF_TYPE_REGISTER *)&MtrrSetting->MtrrDefType)->Bits.E = 1;
  } else {
    if (MtrrContextValid) {
      MtrrLibPostMtrrChange (&MtrrContext);
    }
  }

Exit:
  DEBUG ((DEBUG_CACHE, "  Result = %r\n", Status));
  if (!RETURN_ERROR (Status)) {
    MtrrDebugPrintAllMtrrsWorker (MtrrSetting);
  }

  return Status;
}

/**
  This function attempts to set the attributes into MTRR setting buffer for a memory range.

  @param[in, out]  MtrrSetting  MTRR setting buffer to be set.
  @param[in]       BaseAddress  The physical address that is the start address
                                of a memory range.
  @param[in]       Length       The size in bytes of the memory range.
  @param[in]       Attribute    The bit mask of attributes to set for the
                                memory range.

  @retval RETURN_SUCCESS            The attributes were set for the memory range.
  @retval RETURN_INVALID_PARAMETER  Length is zero.
  @retval RETURN_UNSUPPORTED        The processor does not support one or more bytes of the
                                    memory resource range specified by BaseAddress and Length.
  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support for the memory resource
                                    range specified by BaseAddress and Length.
  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource range specified by
                                    BaseAddress and Length cannot be modified.
  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to modify the attributes of
                                    the memory resource range.
                                    Multiple memory range attributes setting by calling this API multiple
                                    times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean
                                    the number of CPU MTRRs are too small to set such memory attributes.
                                    Pass the multiple memory range attributes to one call of
                                    MtrrSetMemoryAttributesInMtrrSettings() may succeed.
  @retval RETURN_BUFFER_TOO_SMALL   The fixed internal scratch buffer is too small for MTRR calculation.
                                    Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify
                                    external scratch buffer.
**/
RETURN_STATUS
EFIAPI
MtrrSetMemoryAttributeInMtrrSettings (
  IN OUT MTRR_SETTINGS       *MtrrSetting,
  IN PHYSICAL_ADDRESS        BaseAddress,
  IN UINT64                  Length,
  IN MTRR_MEMORY_CACHE_TYPE  Attribute
  )
{
  UINT8              Scratch[SCRATCH_BUFFER_SIZE];
  UINTN              ScratchSize;
  MTRR_MEMORY_RANGE  Range;

  Range.BaseAddress = BaseAddress;
  Range.Length      = Length;
  Range.Type        = Attribute;
  ScratchSize       = sizeof (Scratch);
  return MtrrSetMemoryAttributesInMtrrSettings (MtrrSetting, Scratch, &ScratchSize, &Range, 1);
}

/**
  This function attempts to set the attributes for a memory range.

  @param[in]  BaseAddress        The physical address that is the start
                                 address of a memory range.
  @param[in]  Length             The size in bytes of the memory range.
  @param[in]  Attributes         The bit mask of attributes to set for the
                                 memory range.

  @retval RETURN_SUCCESS            The attributes were set for the memory
                                    range.
  @retval RETURN_INVALID_PARAMETER  Length is zero.
  @retval RETURN_UNSUPPORTED        The processor does not support one or
                                    more bytes of the memory resource range
                                    specified by BaseAddress and Length.
  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support
                                    for the memory resource range specified
                                    by BaseAddress and Length.
  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource
                                    range specified by BaseAddress and Length
                                    cannot be modified.
  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to
                                    modify the attributes of the memory
                                    resource range.
                                    Multiple memory range attributes setting by calling this API multiple
                                    times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean
                                    the number of CPU MTRRs are too small to set such memory attributes.
                                    Pass the multiple memory range attributes to one call of
                                    MtrrSetMemoryAttributesInMtrrSettings() may succeed.
  @retval RETURN_BUFFER_TOO_SMALL   The fixed internal scratch buffer is too small for MTRR calculation.
                                    Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify
                                    external scratch buffer.
**/
RETURN_STATUS
EFIAPI
MtrrSetMemoryAttribute (
  IN PHYSICAL_ADDRESS        BaseAddress,
  IN UINT64                  Length,
  IN MTRR_MEMORY_CACHE_TYPE  Attribute
  )
{
  return MtrrSetMemoryAttributeInMtrrSettings (NULL, BaseAddress, Length, Attribute);
}

/**
  Worker function setting variable MTRRs

  @param[in]  VariableSettings   A buffer to hold variable MTRRs content.

**/
VOID
MtrrSetVariableMtrrWorker (
  IN MTRR_VARIABLE_SETTINGS  *VariableSettings
  )
{
  UINT32  Index;
  UINT32  VariableMtrrCount;

  VariableMtrrCount = GetVariableMtrrCountWorker ();
  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
      );
  }
}

/**
  Worker function setting fixed MTRRs

  @param[in]  FixedSettings  A buffer to hold fixed MTRRs content.

**/
VOID
MtrrSetFixedMtrrWorker (
  IN MTRR_FIXED_SETTINGS  *FixedSettings
  )
{
  UINT32  Index;

  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
    AsmWriteMsr64 (
      mMtrrLibFixedMtrrTable[Index].Msr,
      FixedSettings->Mtrr[Index]
      );
  }
}

/**
  This function gets the content in all MTRRs (variable and fixed)

  @param[out]  MtrrSetting  A buffer to hold all MTRRs content.

  @retval the pointer of MtrrSetting

**/
MTRR_SETTINGS *
EFIAPI
MtrrGetAllMtrrs (
  OUT MTRR_SETTINGS  *MtrrSetting
  )
{
  BOOLEAN                          FixedMtrrSupported;
  UINT32                           VariableMtrrCount;
  MSR_IA32_MTRR_DEF_TYPE_REGISTER  *MtrrDefType;

  ZeroMem (MtrrSetting, sizeof (*MtrrSetting));

  MtrrDefType = (MSR_IA32_MTRR_DEF_TYPE_REGISTER *)&MtrrSetting->MtrrDefType;
  if (!MtrrLibIsMtrrSupported (&FixedMtrrSupported, &VariableMtrrCount)) {
    return MtrrSetting;
  }

  //
  // Get MTRR_DEF_TYPE value
  //
  MtrrDefType->Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);

  //
  // Enabling the Fixed MTRR bit when unsupported is not allowed.
  //
  ASSERT (FixedMtrrSupported || (MtrrDefType->Bits.FE == 0));

  //
  // Get fixed MTRRs
  //
  if (MtrrDefType->Bits.FE == 1) {
    MtrrGetFixedMtrrWorker (&MtrrSetting->Fixed);
  }

  //
  // Get variable MTRRs
  //
  MtrrGetVariableMtrrWorker (
    NULL,
    VariableMtrrCount,
    &MtrrSetting->Variables
    );

  return MtrrSetting;
}

/**
  This function sets all MTRRs includes Variable and Fixed.

  The behavior of this function is to program everything in MtrrSetting to hardware.
  MTRRs might not be enabled because the enable bit is clear in MtrrSetting->MtrrDefType.

  @param[in]  MtrrSetting  A buffer holding all MTRRs content.

  @retval The pointer of MtrrSetting

**/
MTRR_SETTINGS *
EFIAPI
MtrrSetAllMtrrs (
  IN MTRR_SETTINGS  *MtrrSetting
  )
{
  BOOLEAN                          FixedMtrrSupported;
  MSR_IA32_MTRR_DEF_TYPE_REGISTER  *MtrrDefType;
  MTRR_CONTEXT                     MtrrContext;

  MtrrDefType = (MSR_IA32_MTRR_DEF_TYPE_REGISTER *)&MtrrSetting->MtrrDefType;
  if (!MtrrLibIsMtrrSupported (&FixedMtrrSupported, NULL)) {
    return MtrrSetting;
  }

  MtrrLibPreMtrrChange (&MtrrContext);

  //
  // Enabling the Fixed MTRR bit when unsupported is not allowed.
  //
  ASSERT (FixedMtrrSupported || (MtrrDefType->Bits.FE == 0));

  //
  // If the hardware supports Fixed MTRR, it is sufficient
  // to set MTRRs regardless of whether Fixed MTRR bit is enabled.
  //
  if (FixedMtrrSupported) {
    MtrrSetFixedMtrrWorker (&MtrrSetting->Fixed);
  }

  //
  // Set Variable MTRRs
  //
  MtrrSetVariableMtrrWorker (&MtrrSetting->Variables);

  //
  // Set MTRR_DEF_TYPE value
  //
  AsmWriteMsr64 (MSR_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType);

  MtrrLibPostMtrrChangeEnableCache (&MtrrContext);

  return MtrrSetting;
}

/**
  Checks if MTRR is supported.

  @retval TRUE  MTRR is supported.
  @retval FALSE MTRR is not supported.

**/
BOOLEAN
EFIAPI
IsMtrrSupported (
  VOID
  )
{
  return MtrrLibIsMtrrSupported (NULL, NULL);
}

/**
  This function returns a Ranges array containing the memory cache types
  of all memory addresses.

  @param[in]      MtrrSetting  MTRR setting buffer to parse.
  @param[out]     Ranges       Pointer to an array of MTRR_MEMORY_RANGE.
  @param[in,out]  RangeCount   Count of MTRR_MEMORY_RANGE.
                               On input, the maximum entries the Ranges can hold.
                               On output, the actual entries that the function returns.

  @retval RETURN_INVALID_PARAMETER RangeCount is NULL.
  @retval RETURN_INVALID_PARAMETER *RangeCount is not 0 but Ranges is NULL.
  @retval RETURN_BUFFER_TOO_SMALL  *RangeCount is too small.
  @retval RETURN_SUCCESS           Ranges are successfully returned.
**/
RETURN_STATUS
EFIAPI
MtrrGetMemoryAttributesInMtrrSettings (
  IN CONST MTRR_SETTINGS      *MtrrSetting OPTIONAL,
  OUT      MTRR_MEMORY_RANGE  *Ranges,
  IN OUT   UINTN              *RangeCount
  )
{
  RETURN_STATUS                    Status;
  MTRR_SETTINGS                    LocalMtrrs;
  CONST MTRR_SETTINGS              *Mtrrs;
  MSR_IA32_MTRR_DEF_TYPE_REGISTER  *MtrrDefType;
  UINTN                            LocalRangeCount;
  UINT64                           MtrrValidBitsMask;
  UINT64                           MtrrValidAddressMask;
  UINT32                           VariableMtrrCount;
  MTRR_MEMORY_RANGE                RawVariableRanges[ARRAY_SIZE (Mtrrs->Variables.Mtrr)];
  MTRR_MEMORY_RANGE                LocalRanges[
                                               ARRAY_SIZE (mMtrrLibFixedMtrrTable) * sizeof (UINT64) + 2 * ARRAY_SIZE (Mtrrs->Variables.Mtrr) + 1
  ];

  if (RangeCount == NULL) {
    return RETURN_INVALID_PARAMETER;
  }

  if ((*RangeCount != 0) && (Ranges == NULL)) {
    return RETURN_INVALID_PARAMETER;
  }

  if (MtrrSetting != NULL) {
    Mtrrs = MtrrSetting;
  } else {
    MtrrGetAllMtrrs (&LocalMtrrs);
    Mtrrs = &LocalMtrrs;
  }

  MtrrDefType = (MSR_IA32_MTRR_DEF_TYPE_REGISTER *)&Mtrrs->MtrrDefType;

  LocalRangeCount = 1;
  MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
  LocalRanges[0].BaseAddress = 0;
  LocalRanges[0].Length      = MtrrValidBitsMask + 1;

  if (MtrrDefType->Bits.E == 0) {
    LocalRanges[0].Type = CacheUncacheable;
  } else {
    LocalRanges[0].Type = MtrrGetDefaultMemoryTypeWorker (Mtrrs);

    VariableMtrrCount = GetVariableMtrrCountWorker ();
    ASSERT (VariableMtrrCount <= ARRAY_SIZE (MtrrSetting->Variables.Mtrr));

    MtrrLibGetRawVariableRanges (
      &Mtrrs->Variables,
      VariableMtrrCount,
      MtrrValidBitsMask,
      MtrrValidAddressMask,
      RawVariableRanges
      );
    Status = MtrrLibApplyVariableMtrrs (
               RawVariableRanges,
               VariableMtrrCount,
               LocalRanges,
               ARRAY_SIZE (LocalRanges),
               &LocalRangeCount
               );
    ASSERT_RETURN_ERROR (Status);

    if (MtrrDefType->Bits.FE == 1) {
      MtrrLibApplyFixedMtrrs (&Mtrrs->Fixed, LocalRanges, ARRAY_SIZE (LocalRanges), &LocalRangeCount);
    }
  }

  if (*RangeCount < LocalRangeCount) {
    *RangeCount = LocalRangeCount;
    return RETURN_BUFFER_TOO_SMALL;
  }

  CopyMem (Ranges, LocalRanges, LocalRangeCount * sizeof (LocalRanges[0]));
  *RangeCount = LocalRangeCount;
  return RETURN_SUCCESS;
}

/**
  Worker function prints all MTRRs for debugging.

  If MtrrSetting is not NULL, print MTRR settings from input MTRR
  settings buffer.
  If MtrrSetting is NULL, print MTRR settings from MTRRs.

  @param  MtrrSetting    A buffer holding all MTRRs content.
**/
VOID
MtrrDebugPrintAllMtrrsWorker (
  IN MTRR_SETTINGS  *MtrrSetting
  )
{
  DEBUG_CODE_BEGIN ();
  UINT32             Index;
  MTRR_SETTINGS      LocalMtrrs;
  MTRR_SETTINGS      *Mtrrs;
  RETURN_STATUS      Status;
  UINTN              RangeCount;
  BOOLEAN            ContainVariableMtrr;
  MTRR_MEMORY_RANGE  Ranges[
                            ARRAY_SIZE (mMtrrLibFixedMtrrTable) * sizeof (UINT64) + 2 * ARRAY_SIZE (Mtrrs->Variables.Mtrr) + 1
  ];

  if (MtrrSetting != NULL) {
    Mtrrs = MtrrSetting;
  } else {
    MtrrGetAllMtrrs (&LocalMtrrs);
    Mtrrs = &LocalMtrrs;
  }

  RangeCount = ARRAY_SIZE (Ranges);
  Status     = MtrrGetMemoryAttributesInMtrrSettings (Mtrrs, Ranges, &RangeCount);
  if (RETURN_ERROR (Status)) {
    DEBUG ((DEBUG_CACHE, "MTRR is not enabled.\n"));
    return;
  }

  //
  // Dump RAW MTRR contents
  //
  DEBUG ((DEBUG_CACHE, "MTRR Settings:\n"));
  DEBUG ((DEBUG_CACHE, "=============\n"));
  DEBUG ((DEBUG_CACHE, "MTRR Default Type: %016lx\n", Mtrrs->MtrrDefType));
  for (Index = 0; Index < ARRAY_SIZE (mMtrrLibFixedMtrrTable); Index++) {
    DEBUG ((DEBUG_CACHE, "Fixed MTRR[%02d]   : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index]));
  }

  ContainVariableMtrr = FALSE;
  for (Index = 0; Index < ARRAY_SIZE (Mtrrs->Variables.Mtrr); Index++) {
    if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {
      //
      // If mask is not valid, then do not display range
      //
      continue;
    }

    ContainVariableMtrr = TRUE;
    DEBUG ((
      DEBUG_CACHE,
      "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
      Index,
      Mtrrs->Variables.Mtrr[Index].Base,
      Mtrrs->Variables.Mtrr[Index].Mask
      ));
  }

  if (!ContainVariableMtrr) {
    DEBUG ((DEBUG_CACHE, "Variable MTRR    : None.\n"));
  }

  DEBUG ((DEBUG_CACHE, "\n"));

  //
  // Dump MTRR setting in ranges
  //
  DEBUG ((DEBUG_CACHE, "Memory Ranges:\n"));
  DEBUG ((DEBUG_CACHE, "====================================\n"));
  for (Index = 0; Index < RangeCount; Index++) {
    DEBUG ((
      DEBUG_CACHE,
      "%a:%016lx-%016lx\n",
      mMtrrMemoryCacheTypeShortName[Ranges[Index].Type],
      Ranges[Index].BaseAddress,
      Ranges[Index].BaseAddress + Ranges[Index].Length - 1
      ));
  }

  DEBUG_CODE_END ();
}

/**
  This function prints all MTRRs for debugging.
**/
VOID
EFIAPI
MtrrDebugPrintAllMtrrs (
  VOID
  )
{
  MtrrDebugPrintAllMtrrsWorker (NULL);
}
