From 7779b1a0424aa96877b600f227c55039b2a4e10d Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 18 May 2026 23:23:07 +0000 Subject: DynamicTablesPkg: Add HMAT generator tests - Add unit tests for HMAT generator. Co-authored-by: Ryan Heise Signed-off-by: Oleksandr Tymoshenko --- .../GoogleTest/CedtGeneratorGoogleTest.cpp | 11 - .../GoogleTest/HmatGeneratorGoogleTest.cpp | 719 +++++++++++++++++++++ .../GoogleTest/HmatGeneratorGoogleTest.inf | 35 + DynamicTablesPkg/Test/DynamicTablesPkgHostTest.dsc | 11 + .../Protocol/MockConfigurationManagerProtocol.h | 11 + 5 files changed, 776 insertions(+), 11 deletions(-) create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/GoogleTest/HmatGeneratorGoogleTest.cpp create mode 100644 DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/GoogleTest/HmatGeneratorGoogleTest.inf diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiCedtLib/GoogleTest/CedtGeneratorGoogleTest.cpp b/DynamicTablesPkg/Library/Acpi/Common/AcpiCedtLib/GoogleTest/CedtGeneratorGoogleTest.cpp index 2754722d56..e4c54b8ba2 100644 --- a/DynamicTablesPkg/Library/Acpi/Common/AcpiCedtLib/GoogleTest/CedtGeneratorGoogleTest.cpp +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiCedtLib/GoogleTest/CedtGeneratorGoogleTest.cpp @@ -78,17 +78,6 @@ using ::testing::DoAll; using ::testing::SetArgPointee; using ::testing::AtLeast; -#define WRAP_ACCESSOR(accessor) \ - [this] \ - (IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *This, \ - IN CONST CM_OBJECT_ID CmObjectId, \ - IN CONST CM_OBJECT_TOKEN Token, \ - IN OUT CM_OBJ_DESCRIPTOR *CmObject \ - ) \ - { \ - return this->accessor(This, CmObjectId, Token, CmObject); \ - } - class CedtGeneratorTest : public ::testing::Test { protected: MockConfigurationManagerProtocol MockConfigMgrProtocol; diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/GoogleTest/HmatGeneratorGoogleTest.cpp b/DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/GoogleTest/HmatGeneratorGoogleTest.cpp new file mode 100644 index 0000000000..126820c4a4 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/GoogleTest/HmatGeneratorGoogleTest.cpp @@ -0,0 +1,719 @@ +/** @file + Unit tests for HMAT Generator + + Copyright (c) 2026, Google LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "Base.h" +#include +#include +#include + +extern "C" { + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include "GoogleTest/Protocol/MockConfigurationManagerProtocol.h" + #include "Library/Common/MetadataHandlerLib/MetadataHandler.h" + + EFI_STATUS + EFIAPI + AcpiHmatLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + + EFI_STATUS + EFIAPI + AcpiHmatLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + + // Global generator instance + static ACPI_TABLE_GENERATOR *gHmatGenerator = NULL; + + static METADATA_ROOT_HANDLE mMetadataRoot; + + // C++ wrapper functions for C linkage functions + EFI_STATUS + RegisterAcpiTableGenerator ( + IN CONST ACPI_TABLE_GENERATOR *CONST TableGenerator + ) + { + if (TableGenerator == NULL) { + return EFI_INVALID_PARAMETER; + } + + gHmatGenerator = const_cast(TableGenerator); + return EFI_SUCCESS; + } + + EFI_STATUS + DeregisterAcpiTableGenerator ( + IN CONST ACPI_TABLE_GENERATOR *CONST TableGenerator + ) + { + if (TableGenerator == NULL) { + return EFI_INVALID_PARAMETER; + } + + // Clear the stored generator + gHmatGenerator = NULL; + return EFI_SUCCESS; + } + + METADATA_ROOT_HANDLE + EFIAPI + GetMetadataRoot ( + VOID + ) + { + return mMetadataRoot; + } +} + +using namespace testing; +using ::testing::_; +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::DoAll; +using ::testing::SetArgPointee; +using ::testing::AtLeast; + +class HmatGeneratorTest : public ::testing::Test { +protected: + MockConfigurationManagerProtocol MockConfigMgrProtocol; + CM_STD_OBJ_CONFIGURATION_MANAGER_INFO CfgMgrInfo = { 0 }; + + void + ValidateMemProximityDomainAttrInfo ( + const EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES *Expected, + const EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES *Actual + ) + { + EXPECT_EQ (Actual->Type, Expected->Type); + EXPECT_EQ (Actual->Length, sizeof (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES)); + EXPECT_EQ (Actual->Flags.InitiatorProximityDomainValid, Expected->Flags.InitiatorProximityDomainValid); + EXPECT_EQ (Actual->InitiatorProximityDomain, Expected->InitiatorProximityDomain); + EXPECT_EQ (Actual->MemoryProximityDomain, Expected->MemoryProximityDomain); + } + + void + ValidateSSLBI ( + const EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO *ExpectedBase, + const UINT32 *ExpectedInitiatorDomains, + const UINT32 *ExpectedTargetDomains, + const UINT16 *ExpectedLatencyMatrix, + const EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO *Actual + ) + { + EXPECT_EQ (Actual->Type, ExpectedBase->Type); + EXPECT_EQ (Actual->Length, ExpectedBase->Length); + EXPECT_EQ (Actual->Flags.AccessAttributes, ExpectedBase->Flags.AccessAttributes); + EXPECT_EQ (Actual->Flags.MemoryHierarchy, ExpectedBase->Flags.MemoryHierarchy); + EXPECT_EQ (Actual->DataType, ExpectedBase->DataType); + EXPECT_EQ (Actual->NumberOfInitiatorProximityDomains, ExpectedBase->NumberOfInitiatorProximityDomains); + EXPECT_EQ (Actual->NumberOfTargetProximityDomains, ExpectedBase->NumberOfTargetProximityDomains); + EXPECT_EQ (Actual->EntryBaseUnit, ExpectedBase->EntryBaseUnit); + + UINT8 *Ptr = (UINT8 *)Actual; + UINT32 *ActualInitiatorDomains = (UINT32 *)(Ptr + sizeof (EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO)); + + for (UINT32 i = 0; i < ExpectedBase->NumberOfInitiatorProximityDomains; i++) { + EXPECT_EQ (ActualInitiatorDomains[i], ExpectedInitiatorDomains[i]); + } + + UINT32 *ActualTargetDomains = (UINT32 *)(ActualInitiatorDomains + ExpectedBase->NumberOfInitiatorProximityDomains); + + for (UINT32 i = 0; i < ExpectedBase->NumberOfTargetProximityDomains; i++) { + EXPECT_EQ (ActualTargetDomains[i], ExpectedTargetDomains[i]); + } + + UINT16 *ActualLatencyMatrix = (UINT16 *)(ActualTargetDomains + ExpectedBase->NumberOfTargetProximityDomains); + + for (UINT32 i = 0; i < ExpectedBase->NumberOfInitiatorProximityDomains * ExpectedBase->NumberOfTargetProximityDomains; i++) { + EXPECT_EQ (ActualLatencyMatrix[i], ExpectedLatencyMatrix[i]); + } + } + + void + SetUp ( + ) override + { + // Set up default behavior for GetObject + ON_CALL (MockConfigMgrProtocol, GetObject (_, _, _, _)) + .WillByDefault (Return (EFI_NOT_FOUND)); + + // Set up configuration manager info + CfgMgrInfo.Revision = CREATE_REVISION (1, 0); + CfgMgrInfo.OemId[0] = 'T'; + CfgMgrInfo.OemId[1] = 'E'; + CfgMgrInfo.OemId[2] = 'S'; + CfgMgrInfo.OemId[3] = 'T'; + CfgMgrInfo.OemId[4] = 'M'; + CfgMgrInfo.OemId[5] = 'E'; + + EXPECT_CALL (MockConfigMgrProtocol, GetObject (_, CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo), CM_NULL_TOKEN, _)) + .WillRepeatedly ( + DoAll ( + SetArgPointee<3>( + CM_OBJ_DESCRIPTOR { + CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo), + sizeof (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO), + &CfgMgrInfo, + 1 + } + ), + Return (EFI_SUCCESS) + ) + ); + + EXPECT_CALL ( + MockConfigMgrProtocol, + GetObject ( + _, + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjProximityDomainInfo), + _, + _ + ) + ) + .WillRepeatedly ( + Invoke (WRAP_ACCESSOR (GetProximityDomainInfo)) + ); + + EXPECT_CALL ( + MockConfigMgrProtocol, + GetObject ( + _, + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjMemoryProximityDomainAttrInfo), + CM_NULL_TOKEN, + _ + ) + ) + .WillRepeatedly ( + Invoke (WRAP_ACCESSOR (GetMemProximityDomainAttrInfo)) + ); + + EXPECT_CALL ( + MockConfigMgrProtocol, + GetObject ( + _, + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjMemoryLatBwInfo), + CM_NULL_TOKEN, + _ + ) + ) + .WillRepeatedly ( + Invoke (WRAP_ACCESSOR (GetMemLatBwInfo)) + ); + + EXPECT_CALL ( + MockConfigMgrProtocol, + GetObject ( + _, + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjProximityDomainRelationInfo), + _, + _ + ) + ) + .WillRepeatedly ( + Invoke (WRAP_ACCESSOR (GetProximityDomainRelationInfo)) + ); + + // Initialize the HMAT library with our mock protocol + EXPECT_EQ (AcpiHmatLibConstructor (NULL, NULL), EFI_SUCCESS); + + // Setup common test data with proper initialization + mAcpiTableInfo.TableGeneratorId = CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdHmat); + mAcpiTableInfo.AcpiTableSignature = EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE; + mAcpiTableInfo.AcpiTableRevision = EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_REVISION; + + MetadataInitializeHandle (&mMetadataRoot); + } + + void + TearDown ( + ) override + { + if (mTableUnderTest != nullptr) { + gHmatGenerator->FreeTableResources ( + gHmatGenerator, + &mAcpiTableInfo, + gConfigurationManagerProtocol, + &mTableUnderTest + ); + } + + // Clean up the HMAT library + AcpiHmatLibDestructor (NULL, NULL); + MetadataFreeHandle (mMetadataRoot); + } + + void + SetupProximityDomainInfo ( + UINT64 ProximityDomainInfoCount + ) + { + mProximityDomainInfo.resize (ProximityDomainInfoCount); + for (UINT64 i = 0; i < ProximityDomainInfoCount; i++) { + mProximityDomainInfo[i].GenerateDomainId = FALSE; + mProximityDomainInfo[i].DomainId = 100 + (UINT32)i; + } + } + + void + SetupMemProximityDomainAttrInfo ( + CM_ARCH_COMMON_MEMORY_PROXIMITY_DOMAIN_ATTR_INFO *MemProximityDomainAttrInfo, + UINT64 MemProximityDomainAttrInfoCount + ) + { + mMemProximityDomainAttrInfo.resize (MemProximityDomainAttrInfoCount); + for (UINT64 i = 0; i < MemProximityDomainAttrInfoCount; i++) { + mMemProximityDomainAttrInfo[i] = MemProximityDomainAttrInfo[i]; + } + } + + void + SetupMemLatBwInfo ( + CM_ARCH_COMMON_MEMORY_LAT_BW_INFO *MemLatBwInfo, + UINT64 MemLatBwInfoCount + ) + { + mMemLatBwInfo.resize (MemLatBwInfoCount); + for (UINT64 i = 0; i < MemLatBwInfoCount; i++) { + mMemLatBwInfo[i] = MemLatBwInfo[i]; + } + } + + void + SetupProximityDomainRelationInfo ( + CM_OBJECT_TOKEN Token, + CM_ARCH_COMMON_PROXIMITY_DOMAIN_RELATION_INFO *Matrix, + UINT64 MatrixCount + ) + { + mProximityDomainRelationInfo[Token].resize (MatrixCount); + for (UINT64 i = 0; i < MatrixCount; i++) { + mProximityDomainRelationInfo[Token][i] = Matrix[i]; + } + } + + EFI_STATUS + GetProximityDomainInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *This, + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token, + IN OUT CM_OBJ_DESCRIPTOR *CmObject + ) + { + UINT32 Index; + + if (CmObject == nullptr) { + return EFI_INVALID_PARAMETER; + } + + if (Token == CM_NULL_TOKEN) { + *CmObject = CM_OBJ_DESCRIPTOR { + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjProximityDomainInfo), + static_cast(sizeof (CM_ARCH_COMMON_PROXIMITY_DOMAIN_INFO) * mProximityDomainInfo.size ()), + mProximityDomainInfo.data (), + static_cast(mProximityDomainInfo.size ()) + }; + + return EFI_SUCCESS; + } + + Index = (UINT32)Token - 1; + if (Index >= mProximityDomainInfo.size ()) { + return EFI_NOT_FOUND; + } + + *CmObject = CM_OBJ_DESCRIPTOR { + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjProximityDomainInfo), + static_cast(sizeof (CM_ARCH_COMMON_PROXIMITY_DOMAIN_INFO)), + &mProximityDomainInfo[Index], + 1 + }; + + return EFI_SUCCESS; + } + + EFI_STATUS + GetMemProximityDomainAttrInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *This, + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token, + IN OUT CM_OBJ_DESCRIPTOR *CmObject + ) + { + if (CmObject == nullptr) { + return EFI_INVALID_PARAMETER; + } + + *CmObject = CM_OBJ_DESCRIPTOR { + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjMemoryProximityDomainAttrInfo), + static_cast(sizeof (CM_ARCH_COMMON_MEMORY_PROXIMITY_DOMAIN_ATTR_INFO) * mMemProximityDomainAttrInfo.size ()), + mMemProximityDomainAttrInfo.data (), + static_cast(mMemProximityDomainAttrInfo.size ()) + }; + + return EFI_SUCCESS; + } + + EFI_STATUS + GetMemLatBwInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *This, + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token, + IN OUT CM_OBJ_DESCRIPTOR *CmObject + ) + { + if (CmObject == nullptr) { + return EFI_INVALID_PARAMETER; + } + + *CmObject = CM_OBJ_DESCRIPTOR { + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjMemoryLatBwInfo), + static_cast(sizeof (CM_ARCH_COMMON_MEMORY_LAT_BW_INFO) * mMemLatBwInfo.size ()), + mMemLatBwInfo.data (), + static_cast(mMemLatBwInfo.size ()) + }; + + return EFI_SUCCESS; + } + + EFI_STATUS + GetProximityDomainRelationInfo ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *This, + IN CONST CM_OBJECT_ID CmObjectId, + IN CONST CM_OBJECT_TOKEN Token, + IN OUT CM_OBJ_DESCRIPTOR *CmObject + ) + { + if (CmObject == nullptr) { + return EFI_INVALID_PARAMETER; + } + + auto it = mProximityDomainRelationInfo.find (Token); + + if (it == mProximityDomainRelationInfo.end ()) { + return EFI_NOT_FOUND; + } + + *CmObject = CM_OBJ_DESCRIPTOR { + CREATE_CM_ARCH_COMMON_OBJECT_ID (EArchCommonObjProximityDomainRelationInfo), + static_cast(sizeof (CM_ARCH_COMMON_PROXIMITY_DOMAIN_RELATION_INFO) * it->second.size ()), + it->second.data (), + static_cast(it->second.size ()) + }; + + return EFI_SUCCESS; + } + + CM_STD_OBJ_ACPI_TABLE_INFO mAcpiTableInfo; + std::vector mProximityDomainInfo; + std::vector mMemProximityDomainAttrInfo; + std::vector mMemLatBwInfo; + std::map > mProximityDomainRelationInfo; + EFI_ACPI_DESCRIPTION_HEADER *mTableUnderTest = nullptr; + + CM_ARCH_COMMON_PROXIMITY_DOMAIN_INFO mDefaultProximityDomains[10]; + + CM_ARCH_COMMON_MEMORY_PROXIMITY_DOMAIN_ATTR_INFO mDefaultMemProximity[2] = { + { + .Flags = 0, + .InitiatorProximityDomain = 1, + .MemoryProximityDomain = 2 + }, + { + .Flags = 1, + .InitiatorProximityDomain = 3, + .MemoryProximityDomain = 4 + } + }; + + CM_ARCH_COMMON_MEMORY_LAT_BW_INFO mDefaultMemLatBw[2] = { + { + .Flags = 1, + .DataType = 3, + .MinTransferSize = 24, + .EntryBaseUnit = 2, + .RelativeDistanceArray = 1 + }, + { + .Flags = 1, + .DataType = 3, + .MinTransferSize = 24, + .EntryBaseUnit = 2, + .RelativeDistanceArray = 2 + } + }; + + CM_ARCH_COMMON_PROXIMITY_DOMAIN_RELATION_INFO mDefaultMatrix1[4] = { + { .FirstDomainToken = 1, .SecondDomainToken = 2, .Relation = 100 }, + { .FirstDomainToken = 1, .SecondDomainToken = 4, .Relation = 200 }, + { .FirstDomainToken = 3, .SecondDomainToken = 2, .Relation = 300 }, + { .FirstDomainToken = 3, .SecondDomainToken = 4, .Relation = 400 } + }; + + CM_ARCH_COMMON_PROXIMITY_DOMAIN_RELATION_INFO mDefaultMatrix2[2] = { + { .FirstDomainToken = 1, .SecondDomainToken = 5, .Relation = 1000 }, + { .FirstDomainToken = 1, .SecondDomainToken = 6, .Relation = 2000 }, + }; + + // Invalid relation value, should be in UINT16 range + CM_ARCH_COMMON_PROXIMITY_DOMAIN_RELATION_INFO mInvalidRelMatrix[2] = { + { .FirstDomainToken = 1, .SecondDomainToken = 2, .Relation = 301000 }, + { .FirstDomainToken = 1, .SecondDomainToken = 2, .Relation = 302000 }, + }; +}; + +STATIC +constexpr UINT32 +GetSLLBISize ( + UINT32 InitiatorCount, + UINT32 TargetCount + ) +{ + return sizeof (EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO) + + InitiatorCount * sizeof (UINT32) + + TargetCount * sizeof (UINT32) + + InitiatorCount * TargetCount * sizeof (UINT16); +} + +constexpr EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES kExpectedMpda[2] = { + { + .Type = 0, + .Length = 40, + .Flags = { + .InitiatorProximityDomainValid = 0 + }, + .InitiatorProximityDomain = 100, + .MemoryProximityDomain = 101, + }, + { + .Type = 0, + .Length = 40, + .Flags = { + .InitiatorProximityDomainValid = 1 + }, + .InitiatorProximityDomain = 102, + .MemoryProximityDomain = 103 + } +}; + +constexpr EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO kExpectedSllbiBase[2] = { + { + .Type = 1, + .Length = GetSLLBISize (2, 2), + .Flags = { + .MemoryHierarchy = 1 + }, + .DataType = 3, + .MinTransferSize = 24, + .NumberOfInitiatorProximityDomains = 2, + .NumberOfTargetProximityDomains = 2, + .EntryBaseUnit = 2 + }, + { + .Type = 1, + .Length = GetSLLBISize (1, 2), + .Flags = { + .MemoryHierarchy = 1 + }, + .DataType = 3, + .MinTransferSize = 24, + .NumberOfInitiatorProximityDomains = 1, + .NumberOfTargetProximityDomains = 2, + .EntryBaseUnit = 2 + } +}; + +constexpr UINT32 kExpectedSllbiInitiators0[2] = { + 100, 102 +}; + +constexpr UINT32 kExpectedSllbiInitiators1[1] = { + 100 +}; + +constexpr UINT32 kExpectedSllbiTargets0[2] = { + 101, 103 +}; + +constexpr UINT32 kExpectedSllbiTargets1[2] = { + 104, 105 +}; + +constexpr UINT16 kExpectedSllbiMatrix0[4] = { 100, 200, 300, 400 +}; + +constexpr UINT16 kExpectedSllbiMatrix1[2] = { 1000, 2000 +}; + +TEST_F (HmatGeneratorTest, NoProximityDomainsTest) { + SetupProximityDomainInfo (4); + SetupMemLatBwInfo (mDefaultMemLatBw, 1); + SetupProximityDomainRelationInfo ((CM_OBJECT_TOKEN)1, mDefaultMatrix1, 4); + EXPECT_EQ ( + gHmatGenerator->BuildAcpiTable ( + gHmatGenerator, + &mAcpiTableInfo, + gConfigurationManagerProtocol, + &mTableUnderTest + ), + EFI_SUCCESS + ); + UINT32 expectedSize = sizeof (EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER) + + GetSLLBISize (2, 2); + + EXPECT_EQ (mTableUnderTest->Length, expectedSize); + + UINT8 *mTableUnderTestPtr = (UINT8 *)mTableUnderTest; + + ValidateSSLBI ( + &kExpectedSllbiBase[0], + kExpectedSllbiInitiators0, + kExpectedSllbiTargets0, + kExpectedSllbiMatrix0, + (EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO *)&mTableUnderTestPtr[40] + ); +} + +TEST_F (HmatGeneratorTest, NoLatencyInfoTest) { + SetupProximityDomainInfo (4); + SetupMemProximityDomainAttrInfo (mDefaultMemProximity, 2); + EXPECT_EQ ( + gHmatGenerator->BuildAcpiTable ( + gHmatGenerator, + &mAcpiTableInfo, + gConfigurationManagerProtocol, + &mTableUnderTest + ), + EFI_SUCCESS + ); + UINT32 expectedSize = sizeof (EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER) + + 2 * sizeof (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES); + + EXPECT_EQ (mTableUnderTest->Length, expectedSize); + UINT8 *tableUnderTestPtr = (UINT8 *)mTableUnderTest; + + UINT32 Idx = sizeof (EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER); + + ValidateMemProximityDomainAttrInfo (&kExpectedMpda[0], (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES *)&tableUnderTestPtr[Idx]); + + Idx = sizeof (EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER) + + sizeof (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES); + ValidateMemProximityDomainAttrInfo (&kExpectedMpda[1], (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES *)&tableUnderTestPtr[Idx]); +} + +TEST_F (HmatGeneratorTest, MismatchedMatrixSizeTest) { + SetupProximityDomainInfo (4); + SetupMemProximityDomainAttrInfo (mDefaultMemProximity, 2); + SetupMemLatBwInfo (mDefaultMemLatBw, 1); + SetupProximityDomainRelationInfo ((CM_OBJECT_TOKEN)1, &mDefaultMatrix1[0], 3); // Should be 4 + EXPECT_EQ ( + gHmatGenerator->BuildAcpiTable ( + gHmatGenerator, + &mAcpiTableInfo, + gConfigurationManagerProtocol, + &mTableUnderTest + ), + EFI_INVALID_PARAMETER + ); +} + +TEST_F (HmatGeneratorTest, InvalidRelationValueTest) { + SetupProximityDomainInfo (4); + SetupMemProximityDomainAttrInfo (mDefaultMemProximity, 2); + SetupMemLatBwInfo (mDefaultMemLatBw, 1); + SetupProximityDomainRelationInfo ((CM_OBJECT_TOKEN)1, &mInvalidRelMatrix[0], 2); + EXPECT_EQ ( + gHmatGenerator->BuildAcpiTable ( + gHmatGenerator, + &mAcpiTableInfo, + gConfigurationManagerProtocol, + &mTableUnderTest + ), + EFI_INVALID_PARAMETER + ); +} + +TEST_F (HmatGeneratorTest, ValidTableTest) { + SetupProximityDomainInfo (7); + SetupMemProximityDomainAttrInfo (mDefaultMemProximity, 2); + SetupMemLatBwInfo (mDefaultMemLatBw, 2); + SetupProximityDomainRelationInfo ((CM_OBJECT_TOKEN)1, mDefaultMatrix1, 4); + SetupProximityDomainRelationInfo ((CM_OBJECT_TOKEN)2, mDefaultMatrix2, 2); + + EXPECT_EQ ( + gHmatGenerator->BuildAcpiTable ( + gHmatGenerator, + &mAcpiTableInfo, + gConfigurationManagerProtocol, + &mTableUnderTest + ), + EFI_SUCCESS + ); + + EXPECT_NE (mTableUnderTest, nullptr); + UINT32 expectedSize = sizeof (EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER) + + 2 * sizeof (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES) + + GetSLLBISize (2, 2) + + GetSLLBISize (2, 1); + + EXPECT_EQ (mTableUnderTest->Length, expectedSize); + UINT8 *tableUnderTestPtr = (UINT8 *)mTableUnderTest; + + UINT32 Idx = sizeof (EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER); + + ValidateMemProximityDomainAttrInfo (&kExpectedMpda[0], (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES *)&tableUnderTestPtr[Idx]); + + Idx = sizeof (EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER) + + sizeof (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES); + ValidateMemProximityDomainAttrInfo (&kExpectedMpda[1], (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES *)&tableUnderTestPtr[Idx]); + + Idx = sizeof (EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER) + + 2 * sizeof (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES); + ValidateSSLBI ( + &kExpectedSllbiBase[0], + kExpectedSllbiInitiators0, + kExpectedSllbiTargets0, + kExpectedSllbiMatrix0, + (EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO *)&tableUnderTestPtr[Idx] + ); + + Idx = sizeof (EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_HEADER) + + 2 * sizeof (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES) + + GetSLLBISize (2, 2); + ValidateSSLBI ( + &kExpectedSllbiBase[1], + kExpectedSllbiInitiators1, + kExpectedSllbiTargets1, + kExpectedSllbiMatrix1, + (EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO *)&tableUnderTestPtr[Idx] + ); +} + +int +main ( + int argc, + char *argv[] + ) +{ + testing::InitGoogleTest (&argc, argv); + return RUN_ALL_TESTS (); +} diff --git a/DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/GoogleTest/HmatGeneratorGoogleTest.inf b/DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/GoogleTest/HmatGeneratorGoogleTest.inf new file mode 100644 index 0000000000..9d117d370c --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/GoogleTest/HmatGeneratorGoogleTest.inf @@ -0,0 +1,35 @@ +## @file +# Google Test application for HMAT Generator. +# +# Copyright (c) 2026, Google LLC. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = HmatGeneratorGoogleTest + FILE_GUID = c78fdb8e-9d00-48fd-b06b-daafc7e947cf + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + +[Sources] + HmatGeneratorGoogleTest.cpp + ../../../../../Test/Mock/Library/GoogleTest/Protocol/MockConfigurationManagerProtocol.cpp + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + GoogleTestLib + TableHelperLib + CmObjHelperLib + +[Protocols] + gEdkiiConfigurationManagerProtocolGuid ## CONSUMES + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /EHsc diff --git a/DynamicTablesPkg/Test/DynamicTablesPkgHostTest.dsc b/DynamicTablesPkg/Test/DynamicTablesPkgHostTest.dsc index 33adde938b..c27cca1ec9 100644 --- a/DynamicTablesPkg/Test/DynamicTablesPkgHostTest.dsc +++ b/DynamicTablesPkg/Test/DynamicTablesPkgHostTest.dsc @@ -25,10 +25,17 @@ AcpiHelperLib|DynamicTablesPkg/Library/Common/AcpiHelperLib/AcpiHelperLib.inf AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf AmlLib|DynamicTablesPkg/Library/Common/AmlLib/AmlLib.inf + CmObjHelperLib|DynamicTablesPkg/Library/Common/CmObjHelperLib/CmObjHelperLib.inf + MetadataHandlerLib|DynamicTablesPkg/Library/Common/MetadataHandlerLib/MetadataHandlerLib.inf + MetadataObjLib|DynamicTablesPkg/Library/Common/MetadataObjLib/MetadataObjLib.inf SsdtSerialPortFixupLib|DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf [Components] + DynamicTablesPkg/Library/Common/CmObjHelperLib/CmObjHelperLib.inf + DynamicTablesPkg/Library/Common/MetadataHandlerLib/MetadataHandlerLib.inf + DynamicTablesPkg/Library/Common/MetadataObjLib/MetadataObjLib.inf + DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/GoogleTest/Dbg2GeneratorGoogleTest.inf { NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiDbg2Lib/AcpiDbg2Lib.inf @@ -37,3 +44,7 @@ NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiCedtLib/AcpiCedtLib.inf } + DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/GoogleTest/HmatGeneratorGoogleTest.inf { + + NULL|DynamicTablesPkg/Library/Acpi/Common/AcpiHmatLib/AcpiHmatLib.inf + } diff --git a/DynamicTablesPkg/Test/Mock/Include/GoogleTest/Protocol/MockConfigurationManagerProtocol.h b/DynamicTablesPkg/Test/Mock/Include/GoogleTest/Protocol/MockConfigurationManagerProtocol.h index 15db832b7c..5c5e07e99c 100644 --- a/DynamicTablesPkg/Test/Mock/Include/GoogleTest/Protocol/MockConfigurationManagerProtocol.h +++ b/DynamicTablesPkg/Test/Mock/Include/GoogleTest/Protocol/MockConfigurationManagerProtocol.h @@ -15,6 +15,17 @@ extern "C" { #include } +#define WRAP_ACCESSOR(accessor) \ + [this] \ + (IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *This, \ + IN CONST CM_OBJECT_ID CmObjectId, \ + IN CONST CM_OBJECT_TOKEN Token, \ + IN OUT CM_OBJ_DESCRIPTOR *CmObject \ + ) \ + { \ + return this->accessor(This, CmObjectId, Token, CmObject); \ + } + struct MockConfigurationManagerProtocol { MOCK_INTERFACE_DECLARATION (MockConfigurationManagerProtocol); -- cgit v1.2.3