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