Add host based unit tests for the MtrrLib services. The BaseLib services AsmCpuid(), AsmReadMsr64(), and AsmWriteMsr64() are hooked and provide simple emulation of the CPUID leafs and MSRs required by the MtrrLib to run as a host based unit test. Test cases are developed for each of the API. For the most important APIs MtrrSetMemoryAttributesInMtrrSettings() and MtrrSetMemoryAttributeInMtrrSettings(), random inputs are generated and fed to the APIs to make sure the implementation is good. The test application accepts an optional parameter which specifies how many iterations of feeding random inputs to the two APIs. The overall number of test cases increases when the iteration increases. Default iteration is 10 when no parameter is specified. Signed-off-by: Ray Ni <ray.ni@intel.com> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Ming Shao <ming.shao@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ming Shao <ming.shao@intel.com> Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com>
1140 lines
40 KiB
C
1140 lines
40 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 (Result, &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 (Result, &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 (Result, &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 (Result, &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 (Result, &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;
|
|
|
|
DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
srand ((unsigned int) time (NULL));
|
|
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 Iteration;
|
|
|
|
//
|
|
// First parameter specifies the test iterations.
|
|
// Default is 10.
|
|
//
|
|
Iteration = 10;
|
|
if (Argc == 2) {
|
|
Iteration = atoi (Argv[1]);
|
|
}
|
|
return UnitTestingEntry (Iteration);
|
|
}
|