]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/UnitTest/MtrrLibUnitTest.c
UefiCpuPkg/MtrrLib/UnitTest: Add host based unit test
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / UnitTest / MtrrLibUnitTest.c
diff --git a/UefiCpuPkg/Library/MtrrLib/UnitTest/MtrrLibUnitTest.c b/UefiCpuPkg/Library/MtrrLib/UnitTest/MtrrLibUnitTest.c
new file mode 100644 (file)
index 0000000..123e1c7
--- /dev/null
@@ -0,0 +1,1139 @@
+/** @file\r
+  Unit tests of the MtrrLib instance of the MtrrLib class\r
+\r
+  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "MtrrLibUnitTest.h"\r
+\r
+STATIC CONST MTRR_LIB_SYSTEM_PARAMETER mDefaultSystemParameter = {\r
+  42, TRUE, TRUE, CacheUncacheable, 12\r
+};\r
+\r
+STATIC MTRR_LIB_SYSTEM_PARAMETER mSystemParameters[] = {\r
+  { 38, TRUE, TRUE, CacheUncacheable,    12 },\r
+  { 38, TRUE, TRUE, CacheWriteBack,      12 },\r
+  { 38, TRUE, TRUE, CacheWriteThrough,   12 },\r
+  { 38, TRUE, TRUE, CacheWriteProtected, 12 },\r
+  { 38, TRUE, TRUE, CacheWriteCombining, 12 },\r
+\r
+  { 42, TRUE, TRUE, CacheUncacheable,    12 },\r
+  { 42, TRUE, TRUE, CacheWriteBack,      12 },\r
+  { 42, TRUE, TRUE, CacheWriteThrough,   12 },\r
+  { 42, TRUE, TRUE, CacheWriteProtected, 12 },\r
+  { 42, TRUE, TRUE, CacheWriteCombining, 12 },\r
+\r
+  { 48, TRUE, TRUE, CacheUncacheable,    12 },\r
+  { 48, TRUE, TRUE, CacheWriteBack,      12 },\r
+  { 48, TRUE, TRUE, CacheWriteThrough,   12 },\r
+  { 48, TRUE, TRUE, CacheWriteProtected, 12 },\r
+  { 48, TRUE, TRUE, CacheWriteCombining, 12 },\r
+};\r
+\r
+UINT32                    mFixedMtrrsIndex[] = {\r
+  MSR_IA32_MTRR_FIX64K_00000,\r
+  MSR_IA32_MTRR_FIX16K_80000,\r
+  MSR_IA32_MTRR_FIX16K_A0000,\r
+  MSR_IA32_MTRR_FIX4K_C0000,\r
+  MSR_IA32_MTRR_FIX4K_C8000,\r
+  MSR_IA32_MTRR_FIX4K_D0000,\r
+  MSR_IA32_MTRR_FIX4K_D8000,\r
+  MSR_IA32_MTRR_FIX4K_E0000,\r
+  MSR_IA32_MTRR_FIX4K_E8000,\r
+  MSR_IA32_MTRR_FIX4K_F0000,\r
+  MSR_IA32_MTRR_FIX4K_F8000\r
+};\r
+STATIC_ASSERT (\r
+  (ARRAY_SIZE (mFixedMtrrsIndex) == MTRR_NUMBER_OF_FIXED_MTRR),\r
+  "gFixedMtrrIndex does NOT contain all the fixed MTRRs!"\r
+  );\r
+\r
+//\r
+// Context structure to be used for most of the test cases.\r
+//\r
+typedef struct {\r
+  CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;\r
+} MTRR_LIB_TEST_CONTEXT;\r
+\r
+//\r
+// Context structure to be used for GetFirmwareVariableMtrrCount() test.\r
+//\r
+typedef struct {\r
+  UINT32                          NumberOfReservedVariableMtrrs;\r
+  CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;\r
+} MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT;\r
+\r
+STATIC CHAR8 *mCacheDescription[] = { "UC", "WC", "N/A", "N/A", "WT", "WP", "WB" };\r
+\r
+/**\r
+  Compare the actual memory ranges against expected memory ranges and return PASS when they match.\r
+\r
+  @param ExpectedMemoryRanges     Expected memory ranges.\r
+  @param ExpectedMemoryRangeCount Count of expected memory ranges.\r
+  @param ActualRanges             Actual memory ranges.\r
+  @param ActualRangeCount         Count of actual memory ranges.\r
+\r
+  @retval UNIT_TEST_PASSED  Test passed.\r
+  @retval others            Test failed.\r
+**/\r
+UNIT_TEST_STATUS\r
+VerifyMemoryRanges (\r
+  IN MTRR_MEMORY_RANGE  *ExpectedMemoryRanges,\r
+  IN UINTN              ExpectedMemoryRangeCount,\r
+  IN MTRR_MEMORY_RANGE  *ActualRanges,\r
+  IN UINTN              ActualRangeCount\r
+  )\r
+{\r
+  UINTN  Index;\r
+  UT_ASSERT_EQUAL (ExpectedMemoryRangeCount, ActualRangeCount);\r
+  for (Index = 0; Index < ExpectedMemoryRangeCount; Index++) {\r
+    UT_ASSERT_EQUAL (ExpectedMemoryRanges[Index].BaseAddress, ActualRanges[Index].BaseAddress);\r
+    UT_ASSERT_EQUAL (ExpectedMemoryRanges[Index].Length, ActualRanges[Index].Length);\r
+    UT_ASSERT_EQUAL (ExpectedMemoryRanges[Index].Type, ActualRanges[Index].Type);\r
+  }\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Dump the memory ranges.\r
+\r
+  @param Ranges       Memory ranges to dump.\r
+  @param RangeCount   Count of memory ranges.\r
+**/\r
+VOID\r
+DumpMemoryRanges (\r
+  MTRR_MEMORY_RANGE    *Ranges,\r
+  UINTN                RangeCount\r
+  )\r
+{\r
+  UINTN     Index;\r
+  for (Index = 0; Index < RangeCount; Index++) {\r
+    UT_LOG_INFO ("\t{ 0x%016llx, 0x%016llx, %a },\n", Ranges[Index].BaseAddress, Ranges[Index].Length, mCacheDescription[Ranges[Index].Type]);\r
+  }\r
+}\r
+\r
+/**\r
+**/\r
+\r
+/**\r
+  Generate random count of MTRRs for each cache type.\r
+\r
+  @param TotalCount Total MTRR count.\r
+  @param UcCount    Return count of Uncacheable type.\r
+  @param WtCount    Return count of Write Through type.\r
+  @param WbCount    Return count of Write Back type.\r
+  @param WpCount    Return count of Write Protected type.\r
+  @param WcCount    Return count of Write Combining type.\r
+**/\r
+VOID\r
+GenerateRandomMemoryTypeCombination (\r
+  IN  UINT32 TotalCount,\r
+  OUT UINT32 *UcCount,\r
+  OUT UINT32 *WtCount,\r
+  OUT UINT32 *WbCount,\r
+  OUT UINT32 *WpCount,\r
+  OUT UINT32 *WcCount\r
+  )\r
+{\r
+  UINTN  Index;\r
+  UINT32 TotalMtrrCount;\r
+  UINT32 *CountPerType[5];\r
+\r
+  CountPerType[0] = UcCount;\r
+  CountPerType[1] = WtCount;\r
+  CountPerType[2] = WbCount;\r
+  CountPerType[3] = WpCount;\r
+  CountPerType[4] = WcCount;\r
+\r
+  //\r
+  // Initialize the count of each cache type to 0.\r
+  //\r
+  for (Index = 0; Index < ARRAY_SIZE (CountPerType); Index++) {\r
+    *(CountPerType[Index]) = 0;\r
+  }\r
+\r
+  //\r
+  // Pick a random count of MTRRs\r
+  //\r
+  TotalMtrrCount = Random32 (1, TotalCount);\r
+  for (Index = 0; Index < TotalMtrrCount; Index++) {\r
+    //\r
+    // For each of them, pick a random cache type.\r
+    //\r
+    (*(CountPerType[Random32 (0, ARRAY_SIZE (CountPerType) - 1)]))++;\r
+  }\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service MtrrSetMemoryAttribute()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestMtrrSetMemoryAttributesInMtrrSettings (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;\r
+  RETURN_STATUS                   Status;\r
+  UINT32                          UcCount;\r
+  UINT32                          WtCount;\r
+  UINT32                          WbCount;\r
+  UINT32                          WpCount;\r
+  UINT32                          WcCount;\r
+\r
+  UINT32                          MtrrIndex;\r
+  UINT8                           *Scratch;\r
+  UINTN                           ScratchSize;\r
+  MTRR_SETTINGS                   LocalMtrrs;\r
+\r
+  MTRR_MEMORY_RANGE               RawMtrrRange[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  MTRR_MEMORY_RANGE               ExpectedMemoryRanges[MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];\r
+  UINT32                          ExpectedVariableMtrrUsage;\r
+  UINTN                           ExpectedMemoryRangesCount;\r
+\r
+  MTRR_MEMORY_RANGE               ActualMemoryRanges[MTRR_NUMBER_OF_FIXED_MTRR   * sizeof (UINT64) + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];\r
+  UINT32                          ActualVariableMtrrUsage;\r
+  UINTN                           ActualMemoryRangesCount;\r
+\r
+  MTRR_SETTINGS             *Mtrrs[2];\r
+\r
+  SystemParameter = (MTRR_LIB_SYSTEM_PARAMETER *) Context;\r
+  GenerateRandomMemoryTypeCombination (\r
+    SystemParameter->VariableMtrrCount - PatchPcdGet32 (PcdCpuNumberOfReservedVariableMtrrs),\r
+    &UcCount, &WtCount, &WbCount, &WpCount, &WcCount\r
+    );\r
+  GenerateValidAndConfigurableMtrrPairs (\r
+    SystemParameter->PhysicalAddressBits, RawMtrrRange,\r
+    UcCount, WtCount, WbCount, WpCount, WcCount\r
+    );\r
+\r
+  ExpectedVariableMtrrUsage = UcCount + WtCount + WbCount + WpCount + WcCount;\r
+  ExpectedMemoryRangesCount = ARRAY_SIZE (ExpectedMemoryRanges);\r
+  GetEffectiveMemoryRanges (\r
+    SystemParameter->DefaultCacheType,\r
+    SystemParameter->PhysicalAddressBits,\r
+    RawMtrrRange, ExpectedVariableMtrrUsage,\r
+    ExpectedMemoryRanges, &ExpectedMemoryRangesCount\r
+    );\r
+\r
+  UT_LOG_INFO (\r
+    "Total MTRR [%d]: UC=%d, WT=%d, WB=%d, WP=%d, WC=%d\n",\r
+    ExpectedVariableMtrrUsage, UcCount, WtCount, WbCount, WpCount, WcCount\r
+    );\r
+  UT_LOG_INFO ("--- Expected Memory Ranges [%d] ---\n", ExpectedMemoryRangesCount);\r
+  DumpMemoryRanges (ExpectedMemoryRanges, ExpectedMemoryRangesCount);\r
+\r
+  //\r
+  // Default cache type is always an INPUT\r
+  //\r
+  ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));\r
+  LocalMtrrs.MtrrDefType = MtrrGetDefaultMemoryType ();\r
+  ScratchSize            = SCRATCH_BUFFER_SIZE;\r
+  Mtrrs[0]               = &LocalMtrrs;\r
+  Mtrrs[1]               = NULL;\r
+\r
+  for (MtrrIndex = 0; MtrrIndex < ARRAY_SIZE (Mtrrs); MtrrIndex++) {\r
+    Scratch = calloc (ScratchSize, sizeof (UINT8));\r
+    Status = MtrrSetMemoryAttributesInMtrrSettings (Mtrrs[MtrrIndex], Scratch, &ScratchSize, ExpectedMemoryRanges, ExpectedMemoryRangesCount);\r
+    if (Status == RETURN_BUFFER_TOO_SMALL) {\r
+      Scratch = realloc (Scratch, ScratchSize);\r
+      Status = MtrrSetMemoryAttributesInMtrrSettings (Mtrrs[MtrrIndex], Scratch, &ScratchSize, ExpectedMemoryRanges, ExpectedMemoryRangesCount);\r
+    }\r
+    UT_ASSERT_STATUS_EQUAL (Status, RETURN_SUCCESS);\r
+\r
+    if (Mtrrs[MtrrIndex] == NULL) {\r
+      ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));\r
+      MtrrGetAllMtrrs (&LocalMtrrs);\r
+    }\r
+    ActualMemoryRangesCount = ARRAY_SIZE (ActualMemoryRanges);\r
+    CollectTestResult (\r
+      SystemParameter->DefaultCacheType, SystemParameter->PhysicalAddressBits, SystemParameter->VariableMtrrCount,\r
+      &LocalMtrrs, ActualMemoryRanges, &ActualMemoryRangesCount, &ActualVariableMtrrUsage\r
+      );\r
+\r
+    UT_LOG_INFO ("--- Actual Memory Ranges [%d] ---\n", ActualMemoryRangesCount);\r
+    DumpMemoryRanges (ActualMemoryRanges, ActualMemoryRangesCount);\r
+    VerifyMemoryRanges (ExpectedMemoryRanges, ExpectedMemoryRangesCount, ActualMemoryRanges, ActualMemoryRangesCount);\r
+    UT_ASSERT_TRUE (ExpectedVariableMtrrUsage >= ActualVariableMtrrUsage);\r
+\r
+    ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));\r
+  }\r
+\r
+  free (Scratch);\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Test routine to check whether invalid base/size can be rejected.\r
+\r
+  @param Context   Pointer to MTRR_LIB_SYSTEM_PARAMETER.\r
+\r
+  @return Test status.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestInvalidMemoryLayouts (\r
+  IN UNIT_TEST_CONTEXT          Context\r
+  )\r
+{\r
+  CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;\r
+  MTRR_MEMORY_RANGE               Ranges[MTRR_NUMBER_OF_VARIABLE_MTRR * 2 + 1];\r
+  UINTN                           RangeCount;\r
+  UINT64                          MaxAddress;\r
+  UINT32                          Index;\r
+  UINT64                          BaseAddress;\r
+  UINT64                          Length;\r
+  RETURN_STATUS                   Status;\r
+  UINTN                           ScratchSize;\r
+\r
+  SystemParameter = (MTRR_LIB_SYSTEM_PARAMETER *) Context;\r
+\r
+  RangeCount = Random32 (1, ARRAY_SIZE (Ranges));\r
+  MaxAddress = 1ull << SystemParameter->PhysicalAddressBits;\r
+\r
+  for (Index = 0; Index < RangeCount; Index++) {\r
+    do {\r
+      BaseAddress = Random64 (0, MaxAddress);\r
+      Length      = Random64 (1, MaxAddress - BaseAddress);\r
+    } while (((BaseAddress & 0xFFF) == 0) || ((Length & 0xFFF) == 0));\r
+\r
+    Ranges[Index].BaseAddress = BaseAddress;\r
+    Ranges[Index].Length      = Length;\r
+    Ranges[Index].Type        = GenerateRandomCacheType ();\r
+\r
+    Status = MtrrSetMemoryAttribute (\r
+      Ranges[Index].BaseAddress, Ranges[Index].Length, Ranges[Index].Type\r
+      );\r
+    UT_ASSERT_TRUE (RETURN_ERROR (Status));\r
+  }\r
+\r
+  ScratchSize = 0;\r
+  Status = MtrrSetMemoryAttributesInMtrrSettings (NULL, NULL, &ScratchSize, Ranges, RangeCount);\r
+  UT_ASSERT_TRUE (RETURN_ERROR (Status));\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service IsMtrrSupported()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestIsMtrrSupported (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  MTRR_LIB_SYSTEM_PARAMETER  SystemParameter;\r
+  MTRR_LIB_TEST_CONTEXT      *LocalContext;\r
+\r
+  LocalContext = (MTRR_LIB_TEST_CONTEXT *) Context;\r
+\r
+  CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));\r
+  //\r
+  // MTRR capability off in CPUID leaf.\r
+  //\r
+  SystemParameter.MtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_ASSERT_FALSE (IsMtrrSupported ());\r
+\r
+  //\r
+  // MTRR capability on in CPUID leaf, but no variable or fixed MTRRs.\r
+  //\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.VariableMtrrCount = 0;\r
+  SystemParameter.FixedMtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_ASSERT_FALSE (IsMtrrSupported ());\r
+\r
+  //\r
+  // MTRR capability on in CPUID leaf, but no variable MTRRs.\r
+  //\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.VariableMtrrCount = 0;\r
+  SystemParameter.FixedMtrrSupported = TRUE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_ASSERT_FALSE (IsMtrrSupported ());\r
+\r
+  //\r
+  // MTRR capability on in CPUID leaf, but no fixed MTRRs.\r
+  //\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.VariableMtrrCount = 7;\r
+  SystemParameter.FixedMtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_ASSERT_FALSE (IsMtrrSupported ());\r
+\r
+  //\r
+  // MTRR capability on in CPUID leaf with both variable and fixed MTRRs.\r
+  //\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.VariableMtrrCount = 7;\r
+  SystemParameter.FixedMtrrSupported = TRUE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_ASSERT_TRUE (IsMtrrSupported ());\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service GetVariableMtrrCount()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestGetVariableMtrrCount (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  UINT32                    Result;\r
+  MTRR_LIB_SYSTEM_PARAMETER SystemParameter;\r
+  MTRR_LIB_TEST_CONTEXT     *LocalContext;\r
+\r
+  LocalContext = (MTRR_LIB_TEST_CONTEXT *) Context;\r
+\r
+  CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));\r
+  //\r
+  // If MTRR capability off in CPUID leaf, then the count is always 0.\r
+  //\r
+  SystemParameter.MtrrSupported = FALSE;\r
+  for (SystemParameter.VariableMtrrCount = 1; SystemParameter.VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR; SystemParameter.VariableMtrrCount++) {\r
+    InitializeMtrrRegs (&SystemParameter);\r
+    Result = GetVariableMtrrCount ();\r
+    UT_ASSERT_EQUAL (Result, 0);\r
+  }\r
+\r
+  //\r
+  // Try all supported variable MTRR counts.\r
+  // If variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR, then an ASSERT()\r
+  // is generated.\r
+  //\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  for (SystemParameter.VariableMtrrCount = 1; SystemParameter.VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR; SystemParameter.VariableMtrrCount++) {\r
+    InitializeMtrrRegs (&SystemParameter);\r
+    Result = GetVariableMtrrCount ();\r
+    UT_ASSERT_EQUAL (Result, SystemParameter.VariableMtrrCount);\r
+  }\r
+\r
+  //\r
+  // Expect ASSERT() if variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR\r
+  //\r
+  SystemParameter.VariableMtrrCount = MTRR_NUMBER_OF_VARIABLE_MTRR + 1;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_EXPECT_ASSERT_FAILURE (GetVariableMtrrCount (), NULL);\r
+\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.VariableMtrrCount = MAX_UINT8;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_EXPECT_ASSERT_FAILURE (GetVariableMtrrCount (), NULL);\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service GetFirmwareVariableMtrrCount()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestGetFirmwareVariableMtrrCount (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  UINT32                                            Result;\r
+  UINT32                                            ReservedMtrrs;\r
+  MTRR_LIB_SYSTEM_PARAMETER                         SystemParameter;\r
+  MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *LocalContext;\r
+\r
+  LocalContext = (MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *) Context;\r
+\r
+  CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));\r
+\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  //\r
+  // Positive test cases for VCNT = 10 and Reserved PCD in range 0..10\r
+  //\r
+  for (ReservedMtrrs = 0; ReservedMtrrs <= SystemParameter.VariableMtrrCount; ReservedMtrrs++) {\r
+    PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, ReservedMtrrs);\r
+    Result = GetFirmwareVariableMtrrCount ();\r
+    UT_ASSERT_EQUAL (Result, SystemParameter.VariableMtrrCount - ReservedMtrrs);\r
+  }\r
+\r
+  //\r
+  // Negative test cases when Reserved PCD is larger than VCNT\r
+  //\r
+  for (ReservedMtrrs = SystemParameter.VariableMtrrCount + 1; ReservedMtrrs <= 255; ReservedMtrrs++) {\r
+    PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, ReservedMtrrs);\r
+    Result = GetFirmwareVariableMtrrCount ();\r
+    UT_ASSERT_EQUAL (Result, 0);\r
+  }\r
+\r
+  //\r
+  // Negative test cases when Reserved PCD is larger than VCNT\r
+  //\r
+  PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, MAX_UINT32);\r
+  Result = GetFirmwareVariableMtrrCount ();\r
+  UT_ASSERT_EQUAL (Result, 0);\r
+\r
+  //\r
+  // Negative test case when MTRRs are not supported\r
+  //\r
+  SystemParameter.MtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, 2);\r
+  Result = GetFirmwareVariableMtrrCount ();\r
+  UT_ASSERT_EQUAL (Result, 0);\r
+\r
+  //\r
+  // Negative test case when Fixed MTRRs are not supported\r
+  //\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.FixedMtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, 2);\r
+  Result = GetFirmwareVariableMtrrCount ();\r
+  UT_ASSERT_EQUAL (Result, 0);\r
+\r
+  //\r
+  // Expect ASSERT() if variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR\r
+  //\r
+  SystemParameter.FixedMtrrSupported = TRUE;\r
+  SystemParameter.VariableMtrrCount = MTRR_NUMBER_OF_VARIABLE_MTRR + 1;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_EXPECT_ASSERT_FAILURE (GetFirmwareVariableMtrrCount (), NULL);\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service MtrrGetMemoryAttribute()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestMtrrGetMemoryAttribute (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service MtrrGetFixedMtrr()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestMtrrGetFixedMtrr (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  MTRR_FIXED_SETTINGS       *Result;\r
+  MTRR_FIXED_SETTINGS       ExpectedFixedSettings;\r
+  MTRR_FIXED_SETTINGS       FixedSettings;\r
+  UINTN                     Index;\r
+  UINTN                     MsrIndex;\r
+  UINTN                     ByteIndex;\r
+  UINT64                    MsrValue;\r
+  MTRR_LIB_SYSTEM_PARAMETER SystemParameter;\r
+  MTRR_LIB_TEST_CONTEXT     *LocalContext;\r
+\r
+  LocalContext = (MTRR_LIB_TEST_CONTEXT *) Context;\r
+\r
+  CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  //\r
+  // Set random cache type to different ranges under 1MB and make sure\r
+  // the fixed MTRR settings are expected.\r
+  // Try 100 times.\r
+  //\r
+  for (Index = 0; Index < 100; Index++) {\r
+    for (MsrIndex = 0; MsrIndex < ARRAY_SIZE (mFixedMtrrsIndex); MsrIndex++) {\r
+      MsrValue = 0;\r
+      for (ByteIndex = 0; ByteIndex < sizeof (UINT64); ByteIndex++) {\r
+        MsrValue = MsrValue | LShiftU64 (GenerateRandomCacheType (), ByteIndex * 8);\r
+      }\r
+      ExpectedFixedSettings.Mtrr[MsrIndex] = MsrValue;\r
+      AsmWriteMsr64 (mFixedMtrrsIndex[MsrIndex], MsrValue);\r
+    }\r
+\r
+    Result = MtrrGetFixedMtrr (&FixedSettings);\r
+    UT_ASSERT_EQUAL (Result, &FixedSettings);\r
+    UT_ASSERT_MEM_EQUAL (&FixedSettings, &ExpectedFixedSettings, sizeof (FixedSettings));\r
+  }\r
+\r
+  //\r
+  // Negative test case when MTRRs are not supported\r
+  //\r
+  SystemParameter.MtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+\r
+  ZeroMem (&FixedSettings, sizeof (FixedSettings));\r
+  ZeroMem (&ExpectedFixedSettings, sizeof (ExpectedFixedSettings));\r
+  Result = MtrrGetFixedMtrr (&FixedSettings);\r
+  UT_ASSERT_EQUAL (Result, &FixedSettings);\r
+  UT_ASSERT_MEM_EQUAL (&ExpectedFixedSettings, &FixedSettings, sizeof (ExpectedFixedSettings));\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service MtrrGetAllMtrrs()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestMtrrGetAllMtrrs (\r
+  IN UNIT_TEST_CONTEXT      Context\r
+  )\r
+{\r
+  MTRR_SETTINGS             *Result;\r
+  MTRR_SETTINGS             Mtrrs;\r
+  MTRR_SETTINGS             ExpectedMtrrs;\r
+  MTRR_VARIABLE_SETTING     VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  UINT32                    Index;\r
+  MTRR_LIB_SYSTEM_PARAMETER SystemParameter;\r
+  MTRR_LIB_TEST_CONTEXT     *LocalContext;\r
+\r
+  LocalContext = (MTRR_LIB_TEST_CONTEXT *) Context;\r
+\r
+  CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));\r
+  InitializeMtrrRegs (&SystemParameter);\r
+\r
+  for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {\r
+    GenerateRandomMtrrPair (SystemParameter.PhysicalAddressBits, GenerateRandomCacheType (), &VariableMtrr[Index], NULL);\r
+    AsmWriteMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), VariableMtrr[Index].Base);\r
+    AsmWriteMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), VariableMtrr[Index].Mask);\r
+  }\r
+  Result = MtrrGetAllMtrrs (&Mtrrs);\r
+  UT_ASSERT_EQUAL (Result, &Mtrrs);\r
+  UT_ASSERT_MEM_EQUAL (Mtrrs.Variables.Mtrr, VariableMtrr, sizeof (MTRR_VARIABLE_SETTING) * SystemParameter.VariableMtrrCount);\r
+\r
+  //\r
+  // Negative test case when MTRRs are not supported\r
+  //\r
+  ZeroMem (&ExpectedMtrrs, sizeof (ExpectedMtrrs));\r
+  ZeroMem (&Mtrrs, sizeof (Mtrrs));\r
+\r
+  SystemParameter.MtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  Result = MtrrGetAllMtrrs (&Mtrrs);\r
+  UT_ASSERT_EQUAL (Result, &Mtrrs);\r
+  UT_ASSERT_MEM_EQUAL (&ExpectedMtrrs, &Mtrrs, sizeof (ExpectedMtrrs));\r
+\r
+  //\r
+  // Expect ASSERT() if variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR\r
+  //\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.VariableMtrrCount = MTRR_NUMBER_OF_VARIABLE_MTRR + 1;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_EXPECT_ASSERT_FAILURE (MtrrGetAllMtrrs (&Mtrrs), NULL);\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service MtrrSetAllMtrrs()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestMtrrSetAllMtrrs (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  MTRR_SETTINGS                   *Result;\r
+  MTRR_SETTINGS                   Mtrrs;\r
+  UINT32                          Index;\r
+  MSR_IA32_MTRR_DEF_TYPE_REGISTER Default;\r
+  MTRR_LIB_SYSTEM_PARAMETER       SystemParameter;\r
+  MTRR_LIB_TEST_CONTEXT           *LocalContext;\r
+\r
+  LocalContext = (MTRR_LIB_TEST_CONTEXT *) Context;\r
+\r
+  CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));\r
+  InitializeMtrrRegs (&SystemParameter);\r
+\r
+  Default.Uint64 = 0;\r
+  Default.Bits.E = 1;\r
+  Default.Bits.FE = 1;\r
+  Default.Bits.Type = GenerateRandomCacheType ();\r
+\r
+  ZeroMem (&Mtrrs, sizeof (Mtrrs));\r
+  Mtrrs.MtrrDefType = Default.Uint64;\r
+  for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {\r
+    GenerateRandomMtrrPair (SystemParameter.PhysicalAddressBits, GenerateRandomCacheType (), &Mtrrs.Variables.Mtrr[Index], NULL);\r
+  }\r
+  Result = MtrrSetAllMtrrs (&Mtrrs);\r
+  UT_ASSERT_EQUAL (Result, &Mtrrs);\r
+\r
+  UT_ASSERT_EQUAL (AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE), Mtrrs.MtrrDefType);\r
+  for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {\r
+    UT_ASSERT_EQUAL (AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1)), Mtrrs.Variables.Mtrr[Index].Base);\r
+    UT_ASSERT_EQUAL (AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1)), Mtrrs.Variables.Mtrr[Index].Mask);\r
+  }\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service MtrrGetMemoryAttributeInVariableMtrr()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestMtrrGetMemoryAttributeInVariableMtrr (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  MTRR_LIB_TEST_CONTEXT           *LocalContext;\r
+  MTRR_LIB_SYSTEM_PARAMETER       SystemParameter;\r
+  UINT32                          Result;\r
+  MTRR_VARIABLE_SETTING           VariableSetting[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  VARIABLE_MTRR                   VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  UINT64                          ValidMtrrBitsMask;\r
+  UINT64                          ValidMtrrAddressMask;\r
+  UINT32                          Index;\r
+  MSR_IA32_MTRR_PHYSBASE_REGISTER Base;\r
+  MSR_IA32_MTRR_PHYSMASK_REGISTER Mask;\r
+\r
+  LocalContext = (MTRR_LIB_TEST_CONTEXT *) Context;\r
+\r
+  CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));\r
+\r
+  InitializeMtrrRegs (&SystemParameter);\r
+\r
+  ValidMtrrBitsMask    = (1ull << SystemParameter.PhysicalAddressBits) - 1;\r
+  ValidMtrrAddressMask = ValidMtrrBitsMask & 0xfffffffffffff000ULL;\r
+\r
+  for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {\r
+    GenerateRandomMtrrPair (SystemParameter.PhysicalAddressBits, GenerateRandomCacheType (), &VariableSetting[Index], NULL);\r
+    AsmWriteMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), VariableSetting[Index].Base);\r
+    AsmWriteMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), VariableSetting[Index].Mask);\r
+  }\r
+  Result = MtrrGetMemoryAttributeInVariableMtrr (ValidMtrrBitsMask, ValidMtrrAddressMask, VariableMtrr);\r
+  UT_ASSERT_EQUAL (Result, SystemParameter.VariableMtrrCount);\r
+\r
+  for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {\r
+    Base.Uint64    = VariableMtrr[Index].BaseAddress;\r
+    Base.Bits.Type = (UINT32) VariableMtrr[Index].Type;\r
+    UT_ASSERT_EQUAL (Base.Uint64, VariableSetting[Index].Base);\r
+\r
+    Mask.Uint64    = ~(VariableMtrr[Index].Length - 1) & ValidMtrrBitsMask;\r
+    Mask.Bits.V    = 1;\r
+    UT_ASSERT_EQUAL (Mask.Uint64, VariableSetting[Index].Mask);\r
+  }\r
+\r
+  //\r
+  // Negative test case when MTRRs are not supported\r
+  //\r
+  SystemParameter.MtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  Result = MtrrGetMemoryAttributeInVariableMtrr (ValidMtrrBitsMask, ValidMtrrAddressMask, VariableMtrr);\r
+  UT_ASSERT_EQUAL (Result, 0);\r
+\r
+  //\r
+  // Expect ASSERT() if variable MTRR count is > MTRR_NUMBER_OF_VARIABLE_MTRR\r
+  //\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.VariableMtrrCount = MTRR_NUMBER_OF_VARIABLE_MTRR + 1;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  UT_EXPECT_ASSERT_FAILURE (MtrrGetMemoryAttributeInVariableMtrr (ValidMtrrBitsMask, ValidMtrrAddressMask, VariableMtrr), NULL);\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service MtrrDebugPrintAllMtrrs()\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestMtrrDebugPrintAllMtrrs (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service MtrrGetDefaultMemoryType().\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestMtrrGetDefaultMemoryType (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  MTRR_LIB_TEST_CONTEXT     *LocalContext;\r
+  UINTN                     Index;\r
+  MTRR_MEMORY_CACHE_TYPE    Result;\r
+  MTRR_LIB_SYSTEM_PARAMETER SystemParameter;\r
+  MTRR_MEMORY_CACHE_TYPE    CacheType[5];\r
+\r
+  CacheType[0] = CacheUncacheable;\r
+  CacheType[1] = CacheWriteCombining;\r
+  CacheType[2] = CacheWriteThrough;\r
+  CacheType[3] = CacheWriteProtected;\r
+  CacheType[4] = CacheWriteBack;\r
+\r
+  LocalContext = (MTRR_LIB_TEST_CONTEXT *) Context;\r
+\r
+  CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));\r
+  //\r
+  // If MTRRs are supported, then always return the cache type in the MSR\r
+  // MSR_IA32_MTRR_DEF_TYPE\r
+  //\r
+  for (Index = 0; Index < ARRAY_SIZE (CacheType); Index++) {\r
+    SystemParameter.DefaultCacheType = CacheType[Index];\r
+    InitializeMtrrRegs (&SystemParameter);\r
+    Result = MtrrGetDefaultMemoryType ();\r
+    UT_ASSERT_EQUAL (Result, SystemParameter.DefaultCacheType);\r
+  }\r
+\r
+  //\r
+  // If MTRRs are not supported, then always return CacheUncacheable\r
+  //\r
+  SystemParameter.MtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  Result = MtrrGetDefaultMemoryType ();\r
+  UT_ASSERT_EQUAL (Result, CacheUncacheable);\r
+\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.FixedMtrrSupported = FALSE;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  Result = MtrrGetDefaultMemoryType ();\r
+  UT_ASSERT_EQUAL (Result, CacheUncacheable);\r
+\r
+  SystemParameter.MtrrSupported = TRUE;\r
+  SystemParameter.FixedMtrrSupported = TRUE;\r
+  SystemParameter.VariableMtrrCount = 0;\r
+  InitializeMtrrRegs (&SystemParameter);\r
+  Result = MtrrGetDefaultMemoryType ();\r
+  UT_ASSERT_EQUAL (Result, CacheUncacheable);\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Unit test of MtrrLib service MtrrSetMemoryAttributeInMtrrSettings().\r
+\r
+  @param[in]  Context    Ignored\r
+\r
+  @retval  UNIT_TEST_PASSED             The Unit test has completed and the test\r
+                                        case was successful.\r
+  @retval  UNIT_TEST_ERROR_TEST_FAILED  A test case assertion has failed.\r
+\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+UnitTestMtrrSetMemoryAttributeInMtrrSettings (\r
+  IN UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  CONST MTRR_LIB_SYSTEM_PARAMETER *SystemParameter;\r
+  RETURN_STATUS                   Status;\r
+  UINT32                          UcCount;\r
+  UINT32                          WtCount;\r
+  UINT32                          WbCount;\r
+  UINT32                          WpCount;\r
+  UINT32                          WcCount;\r
+\r
+  UINTN                           MtrrIndex;\r
+  UINTN                           Index;\r
+  MTRR_SETTINGS                   LocalMtrrs;\r
+\r
+  MTRR_MEMORY_RANGE               RawMtrrRange[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  MTRR_MEMORY_RANGE               ExpectedMemoryRanges[MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];\r
+  UINT32                          ExpectedVariableMtrrUsage;\r
+  UINTN                           ExpectedMemoryRangesCount;\r
+\r
+  MTRR_MEMORY_RANGE               ActualMemoryRanges[MTRR_NUMBER_OF_FIXED_MTRR * sizeof (UINT64) + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];\r
+  UINT32                          ActualVariableMtrrUsage;\r
+  UINTN                           ActualMemoryRangesCount;\r
+\r
+  MTRR_SETTINGS                   *Mtrrs[2];\r
+\r
+  SystemParameter = (MTRR_LIB_SYSTEM_PARAMETER *) Context;\r
+  GenerateRandomMemoryTypeCombination (\r
+    SystemParameter->VariableMtrrCount - PatchPcdGet32 (PcdCpuNumberOfReservedVariableMtrrs),\r
+    &UcCount, &WtCount, &WbCount, &WpCount, &WcCount\r
+    );\r
+  GenerateValidAndConfigurableMtrrPairs (\r
+    SystemParameter->PhysicalAddressBits, RawMtrrRange,\r
+    UcCount, WtCount, WbCount, WpCount, WcCount\r
+    );\r
+\r
+  ExpectedVariableMtrrUsage = UcCount + WtCount + WbCount + WpCount + WcCount;\r
+  ExpectedMemoryRangesCount = ARRAY_SIZE (ExpectedMemoryRanges);\r
+  GetEffectiveMemoryRanges (\r
+    SystemParameter->DefaultCacheType,\r
+    SystemParameter->PhysicalAddressBits,\r
+    RawMtrrRange, ExpectedVariableMtrrUsage,\r
+    ExpectedMemoryRanges, &ExpectedMemoryRangesCount\r
+    );\r
+\r
+  UT_LOG_INFO ("--- Expected Memory Ranges [%d] ---\n", ExpectedMemoryRangesCount);\r
+  DumpMemoryRanges (ExpectedMemoryRanges, ExpectedMemoryRangesCount);\r
+  //\r
+  // Default cache type is always an INPUT\r
+  //\r
+  ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));\r
+  LocalMtrrs.MtrrDefType = MtrrGetDefaultMemoryType ();\r
+  Mtrrs[0]               = &LocalMtrrs;\r
+  Mtrrs[1]               = NULL;\r
+\r
+  for (MtrrIndex = 0; MtrrIndex < ARRAY_SIZE (Mtrrs); MtrrIndex++) {\r
+    for (Index = 0; Index < ExpectedMemoryRangesCount; Index++) {\r
+      Status = MtrrSetMemoryAttributeInMtrrSettings (\r
+                 Mtrrs[MtrrIndex],\r
+                 ExpectedMemoryRanges[Index].BaseAddress,\r
+                 ExpectedMemoryRanges[Index].Length,\r
+                 ExpectedMemoryRanges[Index].Type\r
+                 );\r
+      UT_ASSERT_TRUE (Status == RETURN_SUCCESS || Status == RETURN_OUT_OF_RESOURCES || Status == RETURN_BUFFER_TOO_SMALL);\r
+      if (Status == RETURN_OUT_OF_RESOURCES || Status == RETURN_BUFFER_TOO_SMALL) {\r
+        return UNIT_TEST_SKIPPED;\r
+      }\r
+    }\r
+\r
+    if (Mtrrs[MtrrIndex] == NULL) {\r
+      ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));\r
+      MtrrGetAllMtrrs (&LocalMtrrs);\r
+    }\r
+    ActualMemoryRangesCount = ARRAY_SIZE (ActualMemoryRanges);\r
+    CollectTestResult (\r
+      SystemParameter->DefaultCacheType, SystemParameter->PhysicalAddressBits, SystemParameter->VariableMtrrCount,\r
+      &LocalMtrrs, ActualMemoryRanges, &ActualMemoryRangesCount, &ActualVariableMtrrUsage\r
+      );\r
+    UT_LOG_INFO ("--- Actual Memory Ranges [%d] ---\n", ActualMemoryRangesCount);\r
+    DumpMemoryRanges (ActualMemoryRanges, ActualMemoryRangesCount);\r
+    VerifyMemoryRanges (ExpectedMemoryRanges, ExpectedMemoryRangesCount, ActualMemoryRanges, ActualMemoryRangesCount);\r
+    UT_ASSERT_TRUE (ExpectedVariableMtrrUsage >= ActualVariableMtrrUsage);\r
+\r
+    ZeroMem (&LocalMtrrs, sizeof (LocalMtrrs));\r
+  }\r
+\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+\r
+/**\r
+  Prep routine for UnitTestGetFirmwareVariableMtrrCount().\r
+\r
+  @param Context  Point to a UINT32 data to save the PcdCpuNumberOfReservedVariableMtrrs.\r
+**/\r
+UNIT_TEST_STATUS\r
+EFIAPI\r
+SavePcdValue (\r
+  UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT  *LocalContext;\r
+\r
+  LocalContext = (MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *) Context;\r
+  LocalContext->NumberOfReservedVariableMtrrs = PatchPcdGet32 (PcdCpuNumberOfReservedVariableMtrrs);\r
+  return UNIT_TEST_PASSED;\r
+}\r
+\r
+/**\r
+  Clean up routine for UnitTestGetFirmwareVariableMtrrCount().\r
+\r
+  @param Context  Point to a UINT32 data to save the PcdCpuNumberOfReservedVariableMtrrs.\r
+**/\r
+VOID\r
+EFIAPI\r
+RestorePcdValue (\r
+  UNIT_TEST_CONTEXT  Context\r
+  )\r
+{\r
+  MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT  *LocalContext;\r
+\r
+  LocalContext = (MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT *) Context;\r
+  PatchPcdSet32 (PcdCpuNumberOfReservedVariableMtrrs, LocalContext->NumberOfReservedVariableMtrrs);\r
+}\r
+\r
+/**\r
+  Initialize the unit test framework, suite, and unit tests for the\r
+  ResetSystemLib and run the ResetSystemLib unit test.\r
+\r
+  @param Iteration               Iteration of testing MtrrSetMemoryAttributeInMtrrSettings\r
+                                 and MtrrSetMemoryAttributesInMtrrSettings using random inputs.\r
+\r
+  @retval  EFI_SUCCESS           All test cases were dispatched.\r
+  @retval  EFI_OUT_OF_RESOURCES  There are not enough resources available to\r
+                                 initialize the unit tests.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+UnitTestingEntry (\r
+  UINTN                       Iteration\r
+  )\r
+{\r
+  EFI_STATUS                                        Status;\r
+  UNIT_TEST_FRAMEWORK_HANDLE                        Framework;\r
+  UNIT_TEST_SUITE_HANDLE                            MtrrApiTests;\r
+  UINTN                                             Index;\r
+  UINTN                                             SystemIndex;\r
+  MTRR_LIB_TEST_CONTEXT                             Context;\r
+  MTRR_LIB_GET_FIRMWARE_VARIABLE_MTRR_COUNT_CONTEXT GetFirmwareVariableMtrrCountContext;\r
+\r
+  Context.SystemParameter                             = &mDefaultSystemParameter;\r
+  GetFirmwareVariableMtrrCountContext.SystemParameter = &mDefaultSystemParameter;\r
+  Framework = NULL;\r
+\r
+  DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));\r
+\r
+  //\r
+  // Setup the test framework for running the tests.\r
+  //\r
+  Status = InitUnitTestFramework (&Framework, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));\r
+    goto EXIT;\r
+  }\r
+\r
+  //\r
+  // --------------Suite-----------Description--------------Name----------Function--------Pre---Post-------------------Context-----------\r
+  //\r
+\r
+  //\r
+  // Populate the MtrrLib API Unit Test Suite.\r
+  //\r
+  Status = CreateUnitTestSuite (&MtrrApiTests, Framework, "MtrrLib API Tests", "MtrrLib.MtrrLib", NULL, NULL);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MtrrLib API Tests\n"));\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto EXIT;\r
+  }\r
+  AddTestCase (MtrrApiTests, "Test IsMtrrSupported",                      "MtrrSupported",                        UnitTestIsMtrrSupported,                      NULL, NULL, &Context);\r
+  AddTestCase (MtrrApiTests, "Test GetVariableMtrrCount",                 "GetVariableMtrrCount",                 UnitTestGetVariableMtrrCount,                 NULL, NULL, &Context);\r
+  AddTestCase (MtrrApiTests, "Test GetFirmwareVariableMtrrCount",         "GetFirmwareVariableMtrrCount",         UnitTestGetFirmwareVariableMtrrCount,         SavePcdValue, RestorePcdValue, &GetFirmwareVariableMtrrCountContext);\r
+  AddTestCase (MtrrApiTests, "Test MtrrGetMemoryAttribute",               "MtrrGetMemoryAttribute",               UnitTestMtrrGetMemoryAttribute,               NULL, NULL, &Context);\r
+  AddTestCase (MtrrApiTests, "Test MtrrGetFixedMtrr",                     "MtrrGetFixedMtrr",                     UnitTestMtrrGetFixedMtrr,                     NULL, NULL, &Context);\r
+  AddTestCase (MtrrApiTests, "Test MtrrGetAllMtrrs",                      "MtrrGetAllMtrrs",                      UnitTestMtrrGetAllMtrrs,                      NULL, NULL, &Context);\r
+  AddTestCase (MtrrApiTests, "Test MtrrSetAllMtrrs",                      "MtrrSetAllMtrrs",                      UnitTestMtrrSetAllMtrrs,                      NULL, NULL, &Context);\r
+  AddTestCase (MtrrApiTests, "Test MtrrGetMemoryAttributeInVariableMtrr", "MtrrGetMemoryAttributeInVariableMtrr", UnitTestMtrrGetMemoryAttributeInVariableMtrr, NULL, NULL, &Context);\r
+  AddTestCase (MtrrApiTests, "Test MtrrDebugPrintAllMtrrs",               "MtrrDebugPrintAllMtrrs",               UnitTestMtrrDebugPrintAllMtrrs,               NULL, NULL, &Context);\r
+  AddTestCase (MtrrApiTests, "Test MtrrGetDefaultMemoryType",             "MtrrGetDefaultMemoryType",             UnitTestMtrrGetDefaultMemoryType,             NULL, NULL, &Context);\r
+\r
+  for (SystemIndex = 0; SystemIndex < ARRAY_SIZE (mSystemParameters); SystemIndex++) {\r
+    for (Index = 0; Index < Iteration; Index++) {\r
+      AddTestCase (MtrrApiTests, "Test InvalidMemoryLayouts",                  "InvalidMemoryLayouts",                  UnitTestInvalidMemoryLayouts,                  InitializeSystem, NULL, &mSystemParameters[SystemIndex]);\r
+      AddTestCase (MtrrApiTests, "Test MtrrSetMemoryAttributeInMtrrSettings",  "MtrrSetMemoryAttributeInMtrrSettings",  UnitTestMtrrSetMemoryAttributeInMtrrSettings,  InitializeSystem, NULL, &mSystemParameters[SystemIndex]);\r
+      AddTestCase (MtrrApiTests, "Test MtrrSetMemoryAttributesInMtrrSettings", "MtrrSetMemoryAttributesInMtrrSettings", UnitTestMtrrSetMemoryAttributesInMtrrSettings, InitializeSystem, NULL, &mSystemParameters[SystemIndex]);\r
+    }\r
+  }\r
+  //\r
+  // Execute the tests.\r
+  //\r
+  srand ((unsigned int) time (NULL));\r
+  Status = RunAllTestSuites (Framework);\r
+\r
+EXIT:\r
+  if (Framework != NULL) {\r
+    FreeUnitTestFramework (Framework);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Standard POSIX C entry point for host based unit test execution.\r
+\r
+  @param Argc  Number of arguments.\r
+  @param Argv  Array of arguments.\r
+\r
+  @return Test application exit code.\r
+**/\r
+INT32\r
+main (\r
+  INT32 Argc,\r
+  CHAR8 *Argv[]\r
+  )\r
+{\r
+  UINTN    Iteration;\r
+\r
+  //\r
+  // First parameter specifies the test iterations.\r
+  // Default is 10.\r
+  //\r
+  Iteration = 10;\r
+  if (Argc == 2) {\r
+    Iteration = atoi (Argv[1]);\r
+  }\r
+  return UnitTestingEntry (Iteration);\r
+}\r