/** @file
  Random test case for Unit tests of the CpuPageTableLib instance of the CpuPageTableLib class

  Copyright (c) 2022 - 2023, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "CpuPageTableLibUnitTest.h"
#include "RandomTest.h"

UINTN                     RandomNumber = 0;
extern IA32_PAGING_ENTRY  mValidMaskNoLeaf[6];
extern IA32_PAGING_ENTRY  mValidMaskLeaf[6];
extern IA32_PAGING_ENTRY  mValidMaskLeafFlag[6];
UINTN                     mRandomOption;
IA32_MAP_ATTRIBUTE        mSupportedBit;
extern UINTN              mNumberCount;
extern UINT8              mNumbers[];
UINTN                     mNumberIndex;
UINT64                    AlignedTable[] = {
  ~((UINT64)SIZE_4KB - 1),
  ~((UINT64)SIZE_2MB - 1),
  ~((UINT64)SIZE_1GB - 1)
};

/**
  Generates a pseudorandom byte stream of the specified size.

  Return FALSE to indicate this interface is not supported.

  @param[out]  Output  Pointer to buffer to receive random value.
  @param[in]   Size    Size of random bytes to generate.

  @retval TRUE   Always return TRUE

**/
BOOLEAN
EFIAPI
RandomBytesUsingArray (
  OUT  UINT8  *Output,
  IN   UINTN  Size
  )
{
  UINTN  Index;

  for (Index = 0; Index < Size; Index++) {
    if (mNumberIndex >= mNumberCount) {
      mNumberIndex = 0;
    }

    Output[Index] = mNumbers[mNumberIndex];
    mNumberIndex++;
  }

  return TRUE;
}

/**
  Generates a pseudorandom byte stream of the specified size.

  Return FALSE to indicate this interface is not supported.

  @param[out]  Output  Pointer to buffer to receive random value.
  @param[in]   Size    Size of random bytes to generate.

  @retval TRUE   Pseudorandom byte stream generated successfully.
  @retval FALSE  Pseudorandom number generator fails
**/
BOOLEAN
EFIAPI
LocalRandomBytes (
  OUT  UINT8  *Output,
  IN   UINTN  Size
  )
{
  if (mRandomOption & USE_RANDOM_ARRAY) {
    return RandomBytesUsingArray (Output, Size);
  } else {
    return RandomBytes (Output, Size);
  }
}

/**
  Return a 32bit random number.

  @param Start  Start of the random number range.
  @param Limit  Limit of the random number range, and return value can be Limit.
  @return 32bit random number
**/
UINT32
Random32 (
  UINT32  Start,
  UINT32  Limit
  )
{
  UINT64  Value;

  LocalRandomBytes ((UINT8 *)&Value, sizeof (UINT64));
  return (UINT32)(Value % (Limit - Start + 1)) + Start;
}

/**
  Return a 64bit random number.

  @param Start  Start of the random number range.
  @param Limit  Limit of the random number range, and return value can be Limit.
  @return 64bit random number
**/
UINT64
Random64 (
  UINT64  Start,
  UINT64  Limit
  )
{
  UINT64  Value;

  LocalRandomBytes ((UINT8 *)&Value, sizeof (UINT64));
  if (Limit - Start  == MAX_UINT64) {
    return (UINT64)(Value);
  }

  return (UINT64)(Value % (Limit - Start  + 1)) + Start;
}

/**
  Returns true with the percentage of input Probability.

  @param[in]   Probability    The percentage to return true.

  @return boolean
**/
BOOLEAN
RandomBoolean (
  UINT8  Probability
  )
{
  return ((Probability > ((UINT8)Random64 (0, 100))) ? TRUE : FALSE);
}

/**
  Set 8K stack as random value.
**/
VOID
SetRandomStack (
  VOID
  )
{
  UINT64  Buffer[SIZE_1KB];
  UINTN   Index;

  for (Index = 0; Index < SIZE_1KB; Index++) {
    Buffer[Index] = Random64 (0, MAX_UINT64);
    Buffer[Index] = Buffer[Index];
  }
}

/**
  Check if the Page table entry is valid

  @param[in]   PagingEntry    The entry in page table to verify
  @param[in]   Level          the level of PagingEntry.
  @param[in]   MaxLeafLevel   Max leaf entry level.
  @param[in]   LinearAddress  The linear address verified.

  @retval  Leaf entry.
**/
UNIT_TEST_STATUS
ValidateAndRandomeModifyPageTablePageTableEntry (
  IN IA32_PAGING_ENTRY  *PagingEntry,
  IN UINTN              Level,
  IN UINTN              MaxLeafLevel,
  IN UINT64             Address
  )
{
  UINT64             Index;
  UINT32             PageTableBaseAddressLow;
  UINT32             PageTableBaseAddressHigh;
  IA32_PAGING_ENTRY  *ChildPageEntry;
  UNIT_TEST_STATUS   Status;

  if (PagingEntry->Pce.Present == 0) {
    return UNIT_TEST_PASSED;
  }

  if ((PagingEntry->Uint64 & mValidMaskLeafFlag[Level].Uint64) == mValidMaskLeafFlag[Level].Uint64) {
    //
    // It is a Leaf
    //
    if (Level > MaxLeafLevel) {
      UT_ASSERT_TRUE (Level <= MaxLeafLevel);
    }

    if ((PagingEntry->Uint64 & mValidMaskLeaf[Level].Uint64) != PagingEntry->Uint64) {
      UT_ASSERT_EQUAL ((PagingEntry->Uint64 & mValidMaskLeaf[Level].Uint64), PagingEntry->Uint64);
    }

    if ((RandomNumber < 100) && RandomBoolean (50)) {
      RandomNumber++;
      if (Level == 1) {
        PageTableBaseAddressLow  = PagingEntry->Pte4K.Bits.PageTableBaseAddressLow;
        PageTableBaseAddressHigh = PagingEntry->Pte4K.Bits.PageTableBaseAddressHigh;
      } else {
        PageTableBaseAddressLow  = PagingEntry->PleB.Bits.PageTableBaseAddressLow;
        PageTableBaseAddressHigh = PagingEntry->PleB.Bits.PageTableBaseAddressHigh;
      }

      PagingEntry->Uint64             = (Random64 (0, MAX_UINT64) & mValidMaskLeaf[Level].Uint64) | mValidMaskLeafFlag[Level].Uint64;
      PagingEntry->Pte4K.Bits.Present = 1;
      if (Level == 1) {
        PagingEntry->Pte4K.Bits.PageTableBaseAddressLow  = PageTableBaseAddressLow;
        PagingEntry->Pte4K.Bits.PageTableBaseAddressHigh = PageTableBaseAddressHigh;
      } else {
        PagingEntry->PleB.Bits.PageTableBaseAddressLow  = PageTableBaseAddressLow;
        PagingEntry->PleB.Bits.PageTableBaseAddressHigh = PageTableBaseAddressHigh;
      }

      if ((PagingEntry->Uint64 & mValidMaskLeaf[Level].Uint64) != PagingEntry->Uint64) {
        UT_ASSERT_EQUAL ((PagingEntry->Uint64 & mValidMaskLeaf[Level].Uint64), PagingEntry->Uint64);
      }
    }

    return UNIT_TEST_PASSED;
  }

  //
  // Not a leaf
  //
  UT_ASSERT_NOT_EQUAL (Level, 1);
  if ((PagingEntry->Uint64 & mValidMaskNoLeaf[Level].Uint64) != PagingEntry->Uint64) {
    DEBUG ((DEBUG_ERROR, "ERROR: Level %d no Leaf entry is 0x%lx, which reserved bit is set \n", Level, PagingEntry->Uint64));
    UT_ASSERT_EQUAL ((PagingEntry->Uint64 & mValidMaskNoLeaf[Level].Uint64), PagingEntry->Uint64);
  }

  if ((RandomNumber < 100) && RandomBoolean (50)) {
    RandomNumber++;
    PageTableBaseAddressLow  = PagingEntry->PleB.Bits.PageTableBaseAddressLow;
    PageTableBaseAddressHigh = PagingEntry->PleB.Bits.PageTableBaseAddressHigh;

    PagingEntry->Uint64                             = Random64 (0, MAX_UINT64) & mValidMaskNoLeaf[Level].Uint64;
    PagingEntry->Pnle.Bits.Present                  = 1;
    PagingEntry->PleB.Bits.PageTableBaseAddressLow  = PageTableBaseAddressLow;
    PagingEntry->PleB.Bits.PageTableBaseAddressHigh = PageTableBaseAddressHigh;
    ASSERT ((PagingEntry->Uint64 & mValidMaskLeafFlag[Level].Uint64) != mValidMaskLeafFlag[Level].Uint64);
  }

  ChildPageEntry = (IA32_PAGING_ENTRY  *)(UINTN)(IA32_PNLE_PAGE_TABLE_BASE_ADDRESS (&PagingEntry->Pnle));
  for (Index = 0; Index < 512; Index++) {
    Status = ValidateAndRandomeModifyPageTablePageTableEntry (&ChildPageEntry[Index], Level-1, MaxLeafLevel, Address + (Index<<(9*(Level-1) + 3)));
    if (Status != UNIT_TEST_PASSED) {
      return Status;
    }
  }

  return UNIT_TEST_PASSED;
}

/**
  Check if the Page table is valid

  @param[in]   PageTable      The pointer to the page table.
  @param[in]   PagingMode     The paging mode.

  @retval  UNIT_TEST_PASSED   It is a valid Page Table
**/
UNIT_TEST_STATUS
ValidateAndRandomeModifyPageTable (
  IN     UINTN        PageTable,
  IN     PAGING_MODE  PagingMode
  )
{
  UINTN              MaxLevel;
  UINTN              MaxLeafLevel;
  UINT64             Index;
  UNIT_TEST_STATUS   Status;
  IA32_PAGING_ENTRY  *PagingEntry;

  if ((PagingMode == Paging32bit) || (PagingMode >= PagingModeMax)) {
    //
    // 32bit paging is never supported.
    //
    return UNIT_TEST_ERROR_TEST_FAILED;
  }

  MaxLeafLevel = (UINT8)PagingMode;
  MaxLevel     = (UINT8)(PagingMode >> 8);

  PagingEntry = (IA32_PAGING_ENTRY *)(UINTN)PageTable;
  for (Index = 0; Index < 512; Index++) {
    Status = ValidateAndRandomeModifyPageTablePageTableEntry (&PagingEntry[Index], MaxLevel, MaxLeafLevel, Index << (9 * MaxLevel + 3));
    if (Status != UNIT_TEST_PASSED) {
      return Status;
    }
  }

  return Status;
}

/**
  Remove the last MAP_ENTRY in MapEntrys.

  @param MapEntrys   Pointer to MapEntrys buffer
**/
VOID
RemoveLastMapEntry (
  IN OUT MAP_ENTRYS  *MapEntrys
  )
{
  UINTN  MapsIndex;

  if (MapEntrys->Count == 0) {
    return;
  }

  MapsIndex = MapEntrys->Count - 1;
  ZeroMem (&(MapEntrys->Maps[MapsIndex]), sizeof (MAP_ENTRY));
  MapEntrys->Count = MapsIndex;
}

/**
  Generate single random map entry.
  The map entry can be the input of function PageTableMap
  the LinearAddress and length is aligned to aligned table.

  @param MaxAddress  Max Address.
  @param MapEntrys   Output MapEntrys contains all parameter as input of function PageTableMap
**/
VOID
GenerateSingleRandomMapEntry (
  IN     UINT64      MaxAddress,
  IN OUT MAP_ENTRYS  *MapEntrys
  )
{
  UINTN   MapsIndex;
  UINT64  FormerLinearAddress;
  UINT64  FormerLinearAddressBottom;
  UINT64  FormerLinearAddressTop;

  MapsIndex = MapEntrys->Count;

  ASSERT (MapsIndex < MapEntrys->MaxCount);
  //
  // use AlignedTable to avoid that a random number can be very hard to be 1G or 2M aligned
  //
  if ((MapsIndex != 0) &&  (RandomBoolean (50))) {
    FormerLinearAddress = MapEntrys->Maps[Random32 (0, (UINT32)MapsIndex-1)].LinearAddress;
    if (FormerLinearAddress < 2 * (UINT64)SIZE_1GB) {
      FormerLinearAddressBottom = 0;
    } else {
      FormerLinearAddressBottom = FormerLinearAddress - 2 * (UINT64)SIZE_1GB;
    }

    if (FormerLinearAddress + 2 * (UINT64)SIZE_1GB > MaxAddress) {
      FormerLinearAddressTop = MaxAddress;
    } else {
      FormerLinearAddressTop = FormerLinearAddress + 2 * (UINT64)SIZE_1GB;
    }

    MapEntrys->Maps[MapsIndex].LinearAddress = Random64 (FormerLinearAddressBottom, FormerLinearAddressTop) & AlignedTable[Random32 (0, ARRAY_SIZE (AlignedTable) -1)];
  } else {
    MapEntrys->Maps[MapsIndex].LinearAddress = Random64 (0, MaxAddress) & AlignedTable[Random32 (0, ARRAY_SIZE (AlignedTable) -1)];
  }

  //
  // To have better performance, limit the size less than 10G
  //
  MapEntrys->Maps[MapsIndex].Length = Random64 (0, MIN (MaxAddress - MapEntrys->Maps[MapsIndex].LinearAddress, 10 * (UINT64)SIZE_1GB)) & AlignedTable[Random32 (0, ARRAY_SIZE (AlignedTable) -1)];

  if ((MapsIndex != 0)  && (RandomBoolean (50))) {
    MapEntrys->Maps[MapsIndex].Attribute.Uint64 = MapEntrys->Maps[Random32 (0, (UINT32)MapsIndex-1)].Attribute.Uint64;
    MapEntrys->Maps[MapsIndex].Mask.Uint64      = MapEntrys->Maps[Random32 (0, (UINT32)MapsIndex-1)].Mask.Uint64;
  } else {
    MapEntrys->Maps[MapsIndex].Attribute.Uint64 = Random64 (0, MAX_UINT64) & mSupportedBit.Uint64;
    if (RandomBoolean (5)) {
      //
      // The probability to get random Mask should be small since all bits of a random number
      // have a high probability of containing 0, which may be a invalid input.
      //
      MapEntrys->Maps[MapsIndex].Mask.Uint64 = Random64 (0, MAX_UINT64) & mSupportedBit.Uint64;
    } else {
      MapEntrys->Maps[MapsIndex].Mask.Uint64 = MAX_UINT64;
    }

    if (MapEntrys->Maps[MapsIndex].Mask.Bits.ProtectionKey != 0) {
      MapEntrys->Maps[MapsIndex].Mask.Bits.ProtectionKey = 0xF;
    }
  }

  if (mRandomOption & ONLY_ONE_ONE_MAPPING) {
    MapEntrys->Maps[MapsIndex].Attribute.Uint64 &= (~IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK);
    MapEntrys->Maps[MapsIndex].Attribute.Uint64 |= MapEntrys->Maps[MapsIndex].LinearAddress;
    MapEntrys->Maps[MapsIndex].Mask.Uint64      |= IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK;
  } else {
    MapEntrys->Maps[MapsIndex].Attribute.Uint64 &= (~IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK);
    MapEntrys->Maps[MapsIndex].Attribute.Uint64 |= (Random64 (0, (((UINT64)1)<<52) - 1) & AlignedTable[Random32 (0, ARRAY_SIZE (AlignedTable) -1)]);
  }

  MapEntrys->Count += 1;
}

/**
  Compare the attribute for one point.
  MapEntrys records every memory ranges that is used as input
  Map and MapCount are gotten from Page table
  Compare if this point have same attribute.

  @param[in] Address      Address of one Point.
  @param[in] MapEntrys    Record every memory ranges that is used as input
  @param[in] Map          Pointer to an array that describes multiple linear address ranges.
  @param[in] MapCount     Pointer to a UINTN that hold the number of entries in the Map.
  @param[in] InitMap      Pointer to an array that describes init map entries.
  @param[in] InitMapCount Pointer to a UINTN that hold the number of init map entries.

  @retval TRUE          At least one byte of data is available to be read
  @retval FALSE         No data is available to be read
**/
BOOLEAN
CompareEntrysforOnePoint (
  IN  UINT64          Address,
  IN  MAP_ENTRYS      *MapEntrys,
  IN  IA32_MAP_ENTRY  *Map,
  IN  UINTN           MapCount,
  IN  IA32_MAP_ENTRY  *InitMap,
  IN  UINTN           InitMapCount
  )
{
  UINTN               Index;
  IA32_MAP_ATTRIBUTE  AttributeInInitMap;
  IA32_MAP_ATTRIBUTE  AttributeInMap;
  IA32_MAP_ATTRIBUTE  AttributeInMapEntrys;
  IA32_MAP_ATTRIBUTE  MaskInMapEntrys;

  AttributeInMap.Uint64       = 0;
  AttributeInMapEntrys.Uint64 = 0;
  AttributeInInitMap.Uint64   = 0;
  MaskInMapEntrys.Uint64      = 0;
  //
  // Assume every entry in maps does not overlap with each other
  //
  for (Index = 0; Index < MapCount; Index++) {
    if ((Address >= Map[Index].LinearAddress) && (Address < (Map[Index].LinearAddress + Map[Index].Length))) {
      AttributeInMap.Uint64  = (Map[Index].Attribute.Uint64 & mSupportedBit.Uint64);
      AttributeInMap.Uint64 &= (~IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK);
      AttributeInMap.Uint64 |= (Address - Map[Index].LinearAddress + IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&Map[Index].Attribute)) & IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK;
      break;
    }
  }

  //
  // Assume every entry in maps does not overlap with each other
  //
  for (Index = 0; Index < InitMapCount; Index++) {
    if ((Address >= InitMap[Index].LinearAddress) && (Address < (InitMap[Index].LinearAddress + InitMap[Index].Length))) {
      AttributeInInitMap.Uint64  = (InitMap[Index].Attribute.Uint64 & mSupportedBit.Uint64);
      AttributeInInitMap.Uint64 &= (~IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK);
      AttributeInInitMap.Uint64 |= (Address - InitMap[Index].LinearAddress + IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&InitMap[Index].Attribute)) & IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK;

      break;
    }
  }

  AttributeInMapEntrys.Uint64 = AttributeInInitMap.Uint64;

  for (Index = MapEntrys->InitCount; Index < MapEntrys->Count; Index++) {
    if ((Address >= MapEntrys->Maps[Index].LinearAddress) && (Address < (MapEntrys->Maps[Index].LinearAddress + MapEntrys->Maps[Index].Length))) {
      if (AttributeInMapEntrys.Bits.Present == 0) {
        AttributeInMapEntrys.Uint64 = 0;
        MaskInMapEntrys.Uint64      = 0;
      }

      MaskInMapEntrys.Uint64      |= MapEntrys->Maps[Index].Mask.Uint64;
      AttributeInMapEntrys.Uint64 &= (~MapEntrys->Maps[Index].Mask.Uint64);
      AttributeInMapEntrys.Uint64 |=  (MapEntrys->Maps[Index].Attribute.Uint64 & MapEntrys->Maps[Index].Mask.Uint64);
      if (IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&MapEntrys->Maps[Index].Mask) != 0) {
        AttributeInMapEntrys.Uint64 &= (~IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK);
        AttributeInMapEntrys.Uint64 |= (Address - MapEntrys->Maps[Index].LinearAddress + IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&MapEntrys->Maps[Index].Attribute)) & IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS_MASK;
      }
    }
  }

  if (AttributeInMap.Bits.Present == 0) {
    if (AttributeInMapEntrys.Bits.Present == 0) {
      return TRUE;
    }
  }

  if ((AttributeInMap.Uint64 & MaskInMapEntrys.Uint64) != (AttributeInMapEntrys.Uint64 & MaskInMapEntrys.Uint64)) {
    DEBUG ((DEBUG_INFO, "======detailed information begin=====\n"));
    DEBUG ((DEBUG_INFO, "\nError: Detect different attribute on a point with linear address: 0x%lx\n", Address));
    DEBUG ((DEBUG_INFO, "By parsing page table, the point has Attribute 0x%lx, and map to physical address 0x%lx\n", IA32_MAP_ATTRIBUTE_ATTRIBUTES (&AttributeInMap) & MaskInMapEntrys.Uint64, IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&AttributeInMap)));
    DEBUG ((DEBUG_INFO, "While according to inputs, the point should Attribute 0x%lx, and should map to physical address 0x%lx\n", IA32_MAP_ATTRIBUTE_ATTRIBUTES (&AttributeInMapEntrys) & MaskInMapEntrys.Uint64, IA32_MAP_ATTRIBUTE_PAGE_TABLE_BASE_ADDRESS (&AttributeInMapEntrys)));
    DEBUG ((DEBUG_INFO, "The total Mask is 0x%lx\n", MaskInMapEntrys.Uint64));

    if (MapEntrys->InitCount != 0) {
      DEBUG ((DEBUG_INFO, "Below is the initialization status:\n"));
      for (Index = 0; Index < InitMapCount; Index++) {
        if ((Address >= InitMap[Index].LinearAddress) && (Address < (InitMap[Index].LinearAddress + InitMap[Index].Length))) {
          DEBUG ((DEBUG_INFO, " *"));
        } else {
          DEBUG ((DEBUG_INFO, "  "));
        }

        DEBUG ((DEBUG_INFO, "  %02d: {0x%lx, 0x%lx, 0x%lx}\n", Index, InitMap[Index].LinearAddress, InitMap[Index].LinearAddress + InitMap[Index].Length, InitMap[Index].Attribute.Uint64));
      }
    }

    DEBUG ((DEBUG_INFO, "Below is the inputs:\n"));
    DEBUG ((DEBUG_INFO, "  Index: {LinearAddress, LinearLimit, Mask, Attribute}\n"));
    for (Index = MapEntrys->InitCount; Index < MapEntrys->Count; Index++) {
      if ((Address >= MapEntrys->Maps[Index].LinearAddress) && (Address < (MapEntrys->Maps[Index].LinearAddress + MapEntrys->Maps[Index].Length))) {
        DEBUG ((DEBUG_INFO, " *"));
      } else {
        DEBUG ((DEBUG_INFO, "  "));
      }

      DEBUG ((
        DEBUG_INFO,
        "  %02d: {0x%lx, 0x%lx, 0x%lx,0x%lx}\n",
        Index,
        MapEntrys->Maps[Index].LinearAddress,
        MapEntrys->Maps[Index].LinearAddress + MapEntrys->Maps[Index].Length,
        MapEntrys->Maps[Index].Mask.Uint64,
        MapEntrys->Maps[Index].Attribute.Uint64
        ));
    }

    DEBUG ((DEBUG_INFO, "Below is the dumped from pagetable:\n"));
    for (Index = 0; Index < MapCount; Index++) {
      if ((Address >= Map[Index].LinearAddress) && (Address < (Map[Index].LinearAddress + Map[Index].Length))) {
        DEBUG ((DEBUG_INFO, " *"));
      } else {
        DEBUG ((DEBUG_INFO, "  "));
      }

      DEBUG ((DEBUG_INFO, "%02d: {0x%lx, 0x%lx, 0x%lx}\n", Index, Map[Index].LinearAddress, Map[Index].LinearAddress + Map[Index].Length, Map[Index].Attribute.Uint64));
    }

    DEBUG ((DEBUG_INFO, "======detailed information done=====\n"));
    return FALSE;
  }

  return TRUE;
}

/**
  Append key point of a given address to Buffer
  if buffer is NULL, only count needed count

  @param[in, out] Buffer  Buffer to contains all key point.
  @param[in, out] Count   Count of the key point.
  @param[in]      Address given address
**/
VOID
AppendKeyPointToBuffer (
  IN OUT UINT64  *Buffer,
  IN OUT UINTN   *Count,
  IN     UINT64  Address
  )
{
  if ( Buffer != NULL) {
    Buffer[*Count] = Address;
    (*Count)++;
    Buffer[*Count] = Address+1;
    (*Count)++;
    Buffer[*Count] = Address-1;
    (*Count)++;
  } else {
    (*Count) = (*Count) +3;
  }
}

/**
  Get all key points from a buffer
  if buffer is NULL, only count needed count

  @param[in] MapEntrys    Record every memory ranges that is used as input
  @param[in] Map          Pointer to an array that describes multiple linear address ranges.
  @param[in] MapCount     Pointer to a UINTN that hold the actual number of entries in the Map.
  @param[in, out] Buffer  Buffer to contains all key point.
  @param[in, out] Count   Count of the key point.
**/
VOID
GetKeyPointList (
  IN     MAP_ENTRYS      *MapEntrys,
  IN     IA32_MAP_ENTRY  *Map,
  IN     UINTN           MapCount,
  IN OUT UINT64          *Buffer,
  IN OUT UINTN           *Count
  )
{
  UINTN  TemCount;
  UINTN  Index1;
  UINTN  Index2;

  TemCount = 0;

  for (Index1 = 0; Index1 < MapEntrys->Count; Index1++) {
    AppendKeyPointToBuffer (Buffer, &TemCount, MapEntrys->Maps[Index1].LinearAddress);
    AppendKeyPointToBuffer (Buffer, &TemCount, MapEntrys->Maps[Index1].LinearAddress + MapEntrys->Maps[Index1].Length);
  }

  for (Index2 = 0; Index2 < MapCount; Index2++) {
    if (Buffer != NULL) {
      for (Index1 = 0; Index1 < TemCount; Index1++) {
        if (Buffer[Index1] == Map[Index2].LinearAddress) {
          break;
        }
      }

      if (Index1 < TemCount) {
        continue;
      }
    }

    AppendKeyPointToBuffer (Buffer, &TemCount, Map[Index2].LinearAddress);
  }

  for (Index2 = 0; Index2 < MapCount; Index2++) {
    if (Buffer != NULL) {
      for (Index1 = 0; Index1 < TemCount; Index1++) {
        if (Buffer[Index1] == (Map[Index2].LinearAddress + Map[Index2].Length)) {
          break;
        }
      }

      if (Index1 < TemCount) {
        continue;
      }
    }

    AppendKeyPointToBuffer (Buffer, &TemCount, Map[Index2].LinearAddress + Map[Index2].Length);
  }

  *Count = TemCount;
}

/**
  Generate random one range with randome attribute, and add it into pagetable
  Compare the key point has same attribute

  @param[in, out] PageTable     The pointer to the page table to update, or pointer to NULL if a new page table is to be created.
  @param[in]      PagingMode    The paging mode.
  @param[in]      MaxAddress    Max Address.
  @param[in]      MapEntrys     Record every memory ranges that is used as input
  @param[in]      PagesRecord   Used to record memory usage for page table.
  @param[in]      InitMap      Pointer to an array that describes init map entries.
  @param[in]      InitMapCount Pointer to a UINTN that hold the number of init map entries.

  @retval  UNIT_TEST_PASSED        The test is successful.
**/
UNIT_TEST_STATUS
SingleMapEntryTest (
  IN OUT UINTN                  *PageTable,
  IN     PAGING_MODE            PagingMode,
  IN     UINT64                 MaxAddress,
  IN     MAP_ENTRYS             *MapEntrys,
  IN     ALLOCATE_PAGE_RECORDS  *PagesRecord,
  IN     IA32_MAP_ENTRY         *InitMap,
  IN     UINTN                  InitMapCount
  )
{
  UINTN               MapsIndex;
  RETURN_STATUS       Status;
  UINTN               PageTableBufferSize;
  VOID                *Buffer;
  IA32_MAP_ENTRY      *Map;
  UINTN               MapCount;
  IA32_MAP_ENTRY      *Map2;
  UINTN               MapCount2;
  UINTN               Index;
  UINTN               KeyPointCount;
  UINTN               NewKeyPointCount;
  UINT64              *KeyPointBuffer;
  UINTN               Level;
  UINT64              Value;
  UNIT_TEST_STATUS    TestStatus;
  MAP_ENTRY           *LastMapEntry;
  IA32_MAP_ATTRIBUTE  *Mask;
  IA32_MAP_ATTRIBUTE  *Attribute;
  UINT64              LastNotPresentRegionStart;
  BOOLEAN             IsNotPresent;
  BOOLEAN             IsModified;

  MapsIndex                 = MapEntrys->Count;
  MapCount                  = 0;
  LastNotPresentRegionStart = 0;
  IsNotPresent              = FALSE;
  IsModified                = FALSE;

  SetRandomStack ();
  GenerateSingleRandomMapEntry (MaxAddress, MapEntrys);
  LastMapEntry = &MapEntrys->Maps[MapsIndex];
  Status       = PageTableParse (*PageTable, PagingMode, NULL, &MapCount);

  if (MapCount != 0) {
    UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);
    Map = AllocatePages (EFI_SIZE_TO_PAGES (MapCount * sizeof (IA32_MAP_ENTRY)));
    ASSERT (Map != NULL);
    Status = PageTableParse (*PageTable, PagingMode, Map, &MapCount);
  }

  //
  // Check if the generated MapEntrys->Maps[MapsIndex] contains not-present range.
  //
  if (LastMapEntry->Length > 0) {
    for (Index = 0; Index < MapCount; Index++) {
      if ((LastNotPresentRegionStart < Map[Index].LinearAddress) &&
          (LastMapEntry->LinearAddress < Map[Index].LinearAddress) && (LastMapEntry->LinearAddress + LastMapEntry->Length > LastNotPresentRegionStart))
      {
        //
        // MapEntrys->Maps[MapsIndex] contains not-present range in exsiting page table.
        //
        break;
      }

      LastNotPresentRegionStart = Map[Index].LinearAddress + Map[Index].Length;
    }

    //
    // Either LastMapEntry overlaps with the not-present region in the very end
    // Or it overlaps with one in the middle
    if (LastNotPresentRegionStart < LastMapEntry->LinearAddress + LastMapEntry->Length) {
      IsNotPresent = TRUE;
    }
  }

  PageTableBufferSize = 0;
  Status              = PageTableMap (
                          PageTable,
                          PagingMode,
                          NULL,
                          &PageTableBufferSize,
                          LastMapEntry->LinearAddress,
                          LastMapEntry->Length,
                          &LastMapEntry->Attribute,
                          &LastMapEntry->Mask,
                          &IsModified
                          );

  Attribute = &LastMapEntry->Attribute;
  Mask      = &LastMapEntry->Mask;
  //
  // If set [LinearAddress, LinearAddress+Attribute] to not preset, all
  // other attributes should not be provided.
  //
  if ((LastMapEntry->Length > 0) && (Attribute->Bits.Present == 0) && (Mask->Bits.Present == 1) && (Mask->Uint64 > 1)) {
    RemoveLastMapEntry (MapEntrys);
    UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
    return UNIT_TEST_PASSED;
  }

  //
  // Return Status for non-present range also should be InvalidParameter when:
  // 1. Some of attributes are not provided when mapping non-present range to present.
  // 2. Set any other attribute without setting the non-present range to Present.
  //
  if (IsNotPresent) {
    if ((Mask->Bits.Present == 1) && (Attribute->Bits.Present == 1)) {
      //
      // Creating new page table or remapping non-present range to present.
      //
      if ((Mask->Bits.ReadWrite == 0) || (Mask->Bits.UserSupervisor == 0) || (Mask->Bits.WriteThrough == 0) || (Mask->Bits.CacheDisabled == 0) ||
          (Mask->Bits.Accessed == 0) || (Mask->Bits.Dirty == 0) || (Mask->Bits.Pat == 0) || (Mask->Bits.Global == 0) ||
          ((Mask->Bits.PageTableBaseAddressLow == 0) && (Mask->Bits.PageTableBaseAddressHigh == 0)) || (Mask->Bits.ProtectionKey == 0) || (Mask->Bits.Nx == 0))
      {
        RemoveLastMapEntry (MapEntrys);
        UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
        return UNIT_TEST_PASSED;
      }
    } else if ((Mask->Bits.Present == 0) && (Mask->Uint64 > 1)) {
      //
      // Only change other attributes for non-present range is not permitted.
      //
      RemoveLastMapEntry (MapEntrys);
      UT_ASSERT_EQUAL (Status, RETURN_INVALID_PARAMETER);
      return UNIT_TEST_PASSED;
    }
  }

  if (PageTableBufferSize != 0) {
    UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);

    //
    // Allocate memory for Page table
    // Note the memory is used in one complete Random test.
    //
    Buffer = PagesRecord->AllocatePagesForPageTable (PagesRecord, EFI_SIZE_TO_PAGES (PageTableBufferSize));
    UT_ASSERT_NOT_NULL (Buffer);
    Status = PageTableMap (
               PageTable,
               PagingMode,
               Buffer,
               &PageTableBufferSize,
               LastMapEntry->LinearAddress,
               LastMapEntry->Length,
               &LastMapEntry->Attribute,
               &LastMapEntry->Mask,
               &IsModified
               );
  }

  if (Status != RETURN_SUCCESS ) {
    UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
  }

  UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
  TestStatus = IsPageTableValid (*PageTable, PagingMode);
  if (TestStatus != UNIT_TEST_PASSED) {
    return TestStatus;
  }

  MapCount2 = 0;
  Status    = PageTableParse (*PageTable, PagingMode, NULL, &MapCount2);
  if (MapCount2 != 0) {
    UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);

    //
    // Allocate memory for Map2
    // Note the memory is only used in this one Single MapEntry Test
    //
    Map2 = AllocatePages (EFI_SIZE_TO_PAGES (MapCount2 * sizeof (IA32_MAP_ENTRY)));
    ASSERT (Map2 != NULL);
    Status = PageTableParse (*PageTable, PagingMode, Map2, &MapCount2);
  }

  //
  // Check if PageTable has been modified.
  //
  if (MapCount2 != MapCount) {
    UT_ASSERT_EQUAL (IsModified, TRUE);
  } else {
    if (CompareMem (Map, Map2, MapCount2 * sizeof (IA32_MAP_ENTRY)) != 0) {
      UT_ASSERT_EQUAL (IsModified, TRUE);
    } else {
      UT_ASSERT_EQUAL (IsModified, FALSE);
    }
  }

  UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);

  //
  // Allocate memory to record all key point
  // Note the memory is only used in this one Single MapEntry Test
  //
  KeyPointCount = 0;
  GetKeyPointList (MapEntrys, Map2, MapCount2, NULL, &KeyPointCount);
  KeyPointBuffer = AllocatePages (EFI_SIZE_TO_PAGES (KeyPointCount * sizeof (UINT64)));
  ASSERT (KeyPointBuffer != NULL);
  NewKeyPointCount = 0;
  GetKeyPointList (MapEntrys, Map2, MapCount2, KeyPointBuffer, &NewKeyPointCount);

  //
  // Compare all key point's attribute
  //
  for (Index = 0; Index < NewKeyPointCount; Index++) {
    if (!CompareEntrysforOnePoint (KeyPointBuffer[Index], MapEntrys, Map2, MapCount2, InitMap, InitMapCount)) {
      DEBUG ((DEBUG_INFO, "Error happens at below key point\n"));
      DEBUG ((DEBUG_INFO, "Index = %d KeyPointBuffer[Index] = 0x%lx\n", Index, KeyPointBuffer[Index]));
      Value = GetEntryFromPageTable (*PageTable, PagingMode, KeyPointBuffer[Index], &Level);
      DEBUG ((DEBUG_INFO, "From Page table, this key point is in level %d entry, with entry value is 0x%lx\n", Level, Value));
      UT_ASSERT_TRUE (FALSE);
    }
  }

  FreePages (KeyPointBuffer, EFI_SIZE_TO_PAGES (KeyPointCount * sizeof (UINT64)));
  if (MapCount != 0) {
    FreePages (Map, EFI_SIZE_TO_PAGES (MapCount * sizeof (IA32_MAP_ENTRY)));
  }

  if (MapCount2 != 0) {
    FreePages (Map2, EFI_SIZE_TO_PAGES (MapCount2 * sizeof (IA32_MAP_ENTRY)));
  }

  return UNIT_TEST_PASSED;
}

/**
  Allocate page and record the information in PagesRecord

  @param[in]  PagesRecord   Point to a struct to record memory usage
  @param[in]  Pages         Page count needed to allocate

  @return A pointer to the allocated buffer or NULL if allocation fails.
**/
VOID *
EFIAPI
RecordAllocatePages (
  IN ALLOCATE_PAGE_RECORDS  *PagesRecord,
  IN UINTN                  Pages
  )
{
  VOID  *Buffer;

  Buffer = NULL;
  if (PagesRecord->Count < PagesRecord->MaxCount) {
    Buffer                                          = AllocatePages (Pages);
    PagesRecord->Records[PagesRecord->Count].Buffer = Buffer;
    PagesRecord->Records[PagesRecord->Count].Pages  = Pages;
    PagesRecord->Count++;
  }

  ASSERT (Buffer != NULL);

  return Buffer;
}

/**
  The function is a whole Random test, it will call SingleMapEntryTest for ExpctedEntryNumber times

  @param[in]  ExpctedEntryNumber   The count of random entry
  @param[in]  PagingMode           The paging mode.

  @retval  UNIT_TEST_PASSED        The test is successful.
**/
UNIT_TEST_STATUS
MultipleMapEntryTest (
  IN UINTN        ExpctedEntryNumber,
  IN PAGING_MODE  PagingMode
  )
{
  UINTN                  PageTable;
  UINT64                 MaxAddress;
  MAP_ENTRYS             *MapEntrys;
  ALLOCATE_PAGE_RECORDS  *PagesRecord;
  UINTN                  Index;
  UNIT_TEST_STATUS       TestStatus;
  RETURN_STATUS          Status;
  IA32_MAP_ENTRY         *InitMap;
  UINTN                  InitMapCount;

  MaxAddress = GetMaxAddress (PagingMode);
  PageTable  = 0;
  MapEntrys  = AllocatePages (EFI_SIZE_TO_PAGES (1000*sizeof (MAP_ENTRY) + sizeof (MAP_ENTRYS)));
  ASSERT (MapEntrys != NULL);
  MapEntrys->Count     = 0;
  MapEntrys->InitCount = 0;
  MapEntrys->MaxCount  = 1000;
  PagesRecord          = AllocatePages (EFI_SIZE_TO_PAGES (1000*sizeof (ALLOCATE_PAGE_RECORD) + sizeof (ALLOCATE_PAGE_RECORDS)));
  ASSERT (PagesRecord != NULL);
  PagesRecord->Count                     = 0;
  PagesRecord->MaxCount                  = 1000;
  PagesRecord->AllocatePagesForPageTable = RecordAllocatePages;

  if (mRandomOption & MANUAL_CHANGE_PAGE_TABLE) {
    ExpctedEntryNumber = ExpctedEntryNumber/2;
  }

  for (Index = 0; Index < ExpctedEntryNumber; Index++) {
    TestStatus = SingleMapEntryTest (
                   &PageTable,
                   PagingMode,
                   MaxAddress,
                   MapEntrys,
                   PagesRecord,
                   NULL,
                   0
                   );
    if (TestStatus != UNIT_TEST_PASSED) {
      return TestStatus;
    }
  }

  if ((mRandomOption & MANUAL_CHANGE_PAGE_TABLE) != 0) {
    MapEntrys->InitCount = ExpctedEntryNumber;
    TestStatus           = ValidateAndRandomeModifyPageTable (PageTable, PagingMode);
    RandomNumber         = 0;
    if (TestStatus != UNIT_TEST_PASSED) {
      return TestStatus;
    }

    InitMapCount = 0;
    Status       = PageTableParse (PageTable, PagingMode, NULL, &InitMapCount);
    if (InitMapCount != 0) {
      UT_ASSERT_EQUAL (Status, RETURN_BUFFER_TOO_SMALL);

      //
      // Allocate memory for Maps
      // Note the memory is only used in this one Single MapEntry Test
      //
      InitMap = AllocatePages (EFI_SIZE_TO_PAGES (InitMapCount * sizeof (IA32_MAP_ENTRY)));
      ASSERT (InitMap != NULL);
      Status = PageTableParse (PageTable, PagingMode, InitMap, &InitMapCount);
    }

    UT_ASSERT_EQUAL (Status, RETURN_SUCCESS);
    for (Index = 0; Index < ExpctedEntryNumber; Index++) {
      TestStatus = SingleMapEntryTest (
                     &PageTable,
                     PagingMode,
                     MaxAddress,
                     MapEntrys,
                     PagesRecord,
                     InitMap,
                     InitMapCount
                     );
      if (TestStatus != UNIT_TEST_PASSED) {
        return TestStatus;
      }
    }

    if (InitMapCount != 0) {
      FreePages (InitMap, EFI_SIZE_TO_PAGES (InitMapCount*sizeof (IA32_MAP_ENTRY)));
    }
  }

  FreePages (
    MapEntrys,
    EFI_SIZE_TO_PAGES (1000*sizeof (MAP_ENTRY) + sizeof (MAP_ENTRYS))
    );

  for (Index = 0; Index < PagesRecord->Count; Index++) {
    FreePages (PagesRecord->Records[Index].Buffer, PagesRecord->Records[Index].Pages);
  }

  FreePages (PagesRecord, EFI_SIZE_TO_PAGES (1000*sizeof (ALLOCATE_PAGE_RECORD) + sizeof (ALLOCATE_PAGE_RECORDS)));

  return UNIT_TEST_PASSED;
}

/**
  Random Test

  @param[in]  Context    [Optional] An optional parameter that enables:
                         1) test-case reuse with varied parameters and
                         2) test-case re-entry for Target tests that need a
                         reboot.  This parameter is a VOID* and it is the
                         responsibility of the test author to ensure that the
                         contents are well understood by all test cases that may
                         consume it.

  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test
                                        case was successful.
  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.
**/
UNIT_TEST_STATUS
EFIAPI
TestCaseforRandomTest (
  IN UNIT_TEST_CONTEXT  Context
  )
{
  UNIT_TEST_STATUS  Status;
  UINTN             Index;

  UT_ASSERT_EQUAL (RandomSeed (NULL, 0), TRUE);
  UT_ASSERT_EQUAL (Random32 (100, 100), 100);
  UT_ASSERT_EQUAL (Random64 (100, 100), 100);
  UT_ASSERT_TRUE ((Random32 (9, 10) >= 9) & (Random32 (9, 10) <= 10));
  UT_ASSERT_TRUE ((Random64 (9, 10) >= 9) & (Random64 (9, 10) <= 10));
  mSupportedBit.Uint64              = 0;
  mSupportedBit.Bits.Present        = 1;
  mSupportedBit.Bits.ReadWrite      = 1;
  mSupportedBit.Bits.UserSupervisor = 1;
  mSupportedBit.Bits.WriteThrough   = 1;
  mSupportedBit.Bits.CacheDisabled  = 1;
  mSupportedBit.Bits.Accessed       = 1;
  mSupportedBit.Bits.Dirty          = 1;
  mSupportedBit.Bits.Pat            = 1;
  mSupportedBit.Bits.Global         = 1;
  mSupportedBit.Bits.ProtectionKey  = 0xF;
  if (((CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT *)Context)->PagingMode == PagingPae) {
    mSupportedBit.Bits.ProtectionKey = 0;
  }

  mSupportedBit.Bits.Nx = 1;

  mRandomOption = ((CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT *)Context)->RandomOption;
  mNumberIndex  = 0;

  for (Index = 0; Index < ((CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT *)Context)->TestCount; Index++) {
    Status = MultipleMapEntryTest (
               ((CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT *)Context)->TestRangeCount,
               ((CPU_PAGE_TABLE_LIB_RANDOM_TEST_CONTEXT *)Context)->PagingMode
               );
    if (Status != UNIT_TEST_PASSED) {
      return Status;
    }

    DEBUG ((DEBUG_INFO, "."));
  }

  DEBUG ((DEBUG_INFO, "\n"));

  return UNIT_TEST_PASSED;
}
