/* Return the number of memory types in range [BaseAddress, BaseAddress + Length). */
UINT8 MtrrLibGetNumberOfTypes(IN CONST MTRR_MEMORY_RANGE *Ranges, IN UINTN RangeCount, IN UINT64 BaseAddress, IN UINT64 Length, IN OUT UINT8 *Types OPTIONAL)
/* Return the number of memory types in range [BaseAddress, BaseAddress + Length). */
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;
}