REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the UefiCpuPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			1213 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1213 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Unit tests of the MtrrLib instance of the MtrrLib class
 | |
| 
 | |
|   Copyright (c) 2020, 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 },
 | |
| };
 | |
| 
 | |
| 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 MtrrSetMemoryAttribute()
 | |
| 
 | |
|   @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
 | |
| UnitTestMtrrSetMemoryAttributesInMtrrSettings (
 | |
|   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_SETTINGS  *Mtrrs[2];
 | |
| 
 | |
|   SystemParameter = (MTRR_LIB_SYSTEM_PARAMETER *)Context;
 | |
|   GenerateRandomMemoryTypeCombination (
 | |
|     SystemParameter->VariableMtrrCount - PatchPcdGet32 (PcdCpuNumberOfReservedVariableMtrrs),
 | |
|     &UcCount,
 | |
|     &WtCount,
 | |
|     &WbCount,
 | |
|     &WpCount,
 | |
|     &WcCount
 | |
|     );
 | |
|   GenerateValidAndConfigurableMtrrPairs (
 | |
|     SystemParameter->PhysicalAddressBits,
 | |
|     RawMtrrRange,
 | |
|     UcCount,
 | |
|     WtCount,
 | |
|     WbCount,
 | |
|     WpCount,
 | |
|     WcCount
 | |
|     );
 | |
| 
 | |
|   ExpectedVariableMtrrUsage = UcCount + WtCount + WbCount + WpCount + WcCount;
 | |
|   ExpectedMemoryRangesCount = ARRAY_SIZE (ExpectedMemoryRanges);
 | |
|   GetEffectiveMemoryRanges (
 | |
|     SystemParameter->DefaultCacheType,
 | |
|     SystemParameter->PhysicalAddressBits,
 | |
|     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->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);
 | |
| 
 | |
|     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;
 | |
| 
 | |
|   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_FALSE (IsMtrrSupported ());
 | |
| 
 | |
|   //
 | |
|   // MTRR capability on in CPUID leaf, but no fixed MTRRs.
 | |
|   //
 | |
|   SystemParameter.MtrrSupported      = TRUE;
 | |
|   SystemParameter.VariableMtrrCount  = 7;
 | |
|   SystemParameter.FixedMtrrSupported = FALSE;
 | |
|   InitializeMtrrRegs (&SystemParameter);
 | |
|   UT_ASSERT_FALSE (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, 0);
 | |
| 
 | |
|   //
 | |
|   // 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));
 | |
| 
 | |
|   return UNIT_TEST_PASSED;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   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_VARIABLE_SETTING      VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
 | |
|   UINT32                     Index;
 | |
|   MTRR_LIB_SYSTEM_PARAMETER  SystemParameter;
 | |
|   MTRR_LIB_TEST_CONTEXT      *LocalContext;
 | |
| 
 | |
|   LocalContext = (MTRR_LIB_TEST_CONTEXT *)Context;
 | |
| 
 | |
|   CopyMem (&SystemParameter, LocalContext->SystemParameter, sizeof (SystemParameter));
 | |
|   InitializeMtrrRegs (&SystemParameter);
 | |
| 
 | |
|   for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {
 | |
|     GenerateRandomMtrrPair (SystemParameter.PhysicalAddressBits, GenerateRandomCacheType (), &VariableMtrr[Index], NULL);
 | |
|     AsmWriteMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), VariableMtrr[Index].Base);
 | |
|     AsmWriteMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), VariableMtrr[Index].Mask);
 | |
|   }
 | |
| 
 | |
|   Result = MtrrGetAllMtrrs (&Mtrrs);
 | |
|   UT_ASSERT_EQUAL ((UINTN)Result, (UINTN)&Mtrrs);
 | |
|   UT_ASSERT_MEM_EQUAL (Mtrrs.Variables.Mtrr, VariableMtrr, 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                    Mtrrs;
 | |
|   UINT32                           Index;
 | |
|   MSR_IA32_MTRR_DEF_TYPE_REGISTER  Default;
 | |
|   MTRR_LIB_SYSTEM_PARAMETER        SystemParameter;
 | |
|   MTRR_LIB_TEST_CONTEXT            *LocalContext;
 | |
| 
 | |
|   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 (&Mtrrs, sizeof (Mtrrs));
 | |
|   Mtrrs.MtrrDefType = Default.Uint64;
 | |
|   for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {
 | |
|     GenerateRandomMtrrPair (SystemParameter.PhysicalAddressBits, GenerateRandomCacheType (), &Mtrrs.Variables.Mtrr[Index], NULL);
 | |
|   }
 | |
| 
 | |
|   Result = MtrrSetAllMtrrs (&Mtrrs);
 | |
|   UT_ASSERT_EQUAL ((UINTN)Result, (UINTN)&Mtrrs);
 | |
| 
 | |
|   UT_ASSERT_EQUAL (AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE), Mtrrs.MtrrDefType);
 | |
|   for (Index = 0; Index < SystemParameter.VariableMtrrCount; Index++) {
 | |
|     UT_ASSERT_EQUAL (AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1)), Mtrrs.Variables.Mtrr[Index].Base);
 | |
|     UT_ASSERT_EQUAL (AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1)), Mtrrs.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);
 | |
| 
 | |
|   SystemParameter.MtrrSupported      = TRUE;
 | |
|   SystemParameter.FixedMtrrSupported = FALSE;
 | |
|   InitializeMtrrRegs (&SystemParameter);
 | |
|   Result = MtrrGetDefaultMemoryType ();
 | |
|   UT_ASSERT_EQUAL (Result, CacheUncacheable);
 | |
| 
 | |
|   SystemParameter.MtrrSupported      = TRUE;
 | |
|   SystemParameter.FixedMtrrSupported = TRUE;
 | |
|   SystemParameter.VariableMtrrCount  = 0;
 | |
|   InitializeMtrrRegs (&SystemParameter);
 | |
|   Result = MtrrGetDefaultMemoryType ();
 | |
|   UT_ASSERT_EQUAL (Result, CacheUncacheable);
 | |
| 
 | |
|   return UNIT_TEST_PASSED;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Unit test of MtrrLib service MtrrSetMemoryAttributeInMtrrSettings().
 | |
| 
 | |
|   @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
 | |
| UnitTestMtrrSetMemoryAttributeInMtrrSettings (
 | |
|   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_SETTINGS  *Mtrrs[2];
 | |
| 
 | |
|   SystemParameter = (MTRR_LIB_SYSTEM_PARAMETER *)Context;
 | |
|   GenerateRandomMemoryTypeCombination (
 | |
|     SystemParameter->VariableMtrrCount - PatchPcdGet32 (PcdCpuNumberOfReservedVariableMtrrs),
 | |
|     &UcCount,
 | |
|     &WtCount,
 | |
|     &WbCount,
 | |
|     &WpCount,
 | |
|     &WcCount
 | |
|     );
 | |
|   GenerateValidAndConfigurableMtrrPairs (
 | |
|     SystemParameter->PhysicalAddressBits,
 | |
|     RawMtrrRange,
 | |
|     UcCount,
 | |
|     WtCount,
 | |
|     WbCount,
 | |
|     WpCount,
 | |
|     WcCount
 | |
|     );
 | |
| 
 | |
|   ExpectedVariableMtrrUsage = UcCount + WtCount + WbCount + WpCount + WcCount;
 | |
|   ExpectedMemoryRangesCount = ARRAY_SIZE (ExpectedMemoryRanges);
 | |
|   GetEffectiveMemoryRanges (
 | |
|     SystemParameter->DefaultCacheType,
 | |
|     SystemParameter->PhysicalAddressBits,
 | |
|     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->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);
 | |
| 
 | |
|     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", "MtrrSetMemoryAttributeInMtrrSettings", UnitTestMtrrSetMemoryAttributeInMtrrSettings, InitializeSystem, NULL, &mSystemParameters[SystemIndex]);
 | |
|       AddTestCase (MtrrApiTests, "Test MtrrSetMemoryAttributesInMtrrSettings", "MtrrSetMemoryAttributesInMtrrSettings", UnitTestMtrrSetMemoryAttributesInMtrrSettings, 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);
 | |
| }
 |