From 998950e8ff36bf3ac663b2137067fbc18962d35d Mon Sep 17 00:00:00 2001 From: Harshal Ratan Patil Date: Wed, 17 May 2023 17:24:31 +0000 Subject: [PATCH] DynamicTablesPkg: Smbios Type4 and Type7 population. Create a SmbiosType4Lib and SmbiosType7Lib in DynamicTablesPkg for Smbios Type4 and Type7 table generation. Signed-off-by: Harshal Ratan Patil Reviewed-by: Girish Mahadevan Reviewed-by: Jeff Brasen --- .../Include/SmbiosNameSpaceObjects.h | 154 +++++++ .../SmbiosType4Lib/SmbiosType4Generator.c | 402 ++++++++++++++++++ .../Smbios/SmbiosType4Lib/SmbiosType4Lib.inf | 37 ++ .../SmbiosType7Lib/SmbiosType7Generator.c | 313 ++++++++++++++ .../Smbios/SmbiosType7Lib/SmbiosType7Lib.inf | 37 ++ 5 files changed, 943 insertions(+) create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosType4Lib/SmbiosType4Generator.c create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosType4Lib/SmbiosType4Lib.inf create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosType7Lib/SmbiosType7Generator.c create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosType7Lib/SmbiosType7Lib.inf diff --git a/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h b/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h index f6fab75f8b..9b3863c47f 100644 --- a/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h @@ -36,6 +36,8 @@ typedef enum SmbiosObjectID { ESmbiosObjMemoryArrayMappedAddress, ESmbiosObjPowerSupplyInfo, ESmbiosObjFirmwareInventoryInfo, + ESmbiosObjProcessorInfo, + ESmbiosObjCacheInfo, ESmbiosObjMax } ESMBIOS_OBJECT_ID; @@ -607,6 +609,158 @@ typedef struct CmStdFirmwareInventoryInfo { SMBIOS_TABLE_GENERATOR_ID GeneratorId; } CM_SMBIOS_FIRMWARE_INVENTORY_INFO; +/** A structure that describes the Processor Information. + + The Processor Information on the system is described by this object. + + SMBIOS Specification v3.6.0 Type4 + + ID: EStdObjProcessorInfo +**/ +typedef struct CmSmbiosProcessorInfo { + /** Socket Designation string */ + CHAR8 *SocketDesignation; + + /** Processor Type */ + UINT8 ProcessorType; + + /** Processor Family */ + UINT8 ProcessorFamily; + + /** Processor Manufacturer string */ + CHAR8 *ProcessorManufacturer; + + /** Processor ID */ + PROCESSOR_ID_DATA ProcessorId; + + /** Processor Version string */ + CHAR8 *ProcessorVersion; + + /** Voltage */ + PROCESSOR_VOLTAGE Voltage; + + /** External Clock */ + UINT16 ExternalClock; + + /** Max Speed*/ + UINT16 MaxSpeed; + + /** Current Speed */ + UINT16 CurrentSpeed; + + /** Status */ + UINT8 Status; + + /** Processor Upgrade */ + UINT8 ProcessorUpgrade; + + /** L1 Cache Handle */ + UINT16 L1CacheHandle; + + /** L2 Cache Handle */ + UINT16 L2CacheHandle; + + /** L3 Cache Handle */ + UINT16 L3CacheHandle; + + /** Serial Number string */ + CHAR8 *SerialNumber; + + /** Asset Tag string */ + CHAR8 *AssetTag; + + /** Part Number string */ + CHAR8 *PartNumber; + + /** Core Count */ + UINT8 CoreCount; + + /** Enabled Core Count */ + UINT8 EnabledCoreCount; + + /** Thread Count */ + UINT8 ThreadCount; + + /** Processor Characteristics */ + UINT16 ProcessorCharacteristics; + + /** Processor Family 2 */ + UINT16 ProcessorFamily2; + + /** Core Count 2 */ + UINT16 CoreCount2; + + /** Enabled Core Count 2 */ + UINT16 EnabledCoreCount2; + + /** Thread Count 2 */ + UINT16 ThreadCount2; + + /** Thread Enabled */ + UINT16 ThreadEnabled; + + /** CM Object Token of Processor information */ + CM_OBJECT_TOKEN ProcessorInfoToken; + + /** CM Object Token of L1 Cache information */ + CM_OBJECT_TOKEN CacheInfoTokenL1; + + /** CM Object Token of L2 Cache information */ + CM_OBJECT_TOKEN CacheInfoTokenL2; + + /** CM Object Token of L3 Cache information */ + CM_OBJECT_TOKEN CacheInfoTokenL3; +} CM_SMBIOS_PROCESSOR_INFO; + +/** A structure that describes the Cache Information. + + The Cache Information on the system is described by this object. + + SMBIOS Specification v3.6.0 Type7 + + ID: EStdObjCacheInfo +**/ +typedef struct CmSmbiosCacheInfo { + /** Socket Designation string */ + CHAR8 *SocketDesignation; + + /** Cache Configuration */ + UINT16 CacheConfiguration; + + /** Maximum Cache Size */ + UINT16 MaximumCacheSize; + + /** Installed Size */ + UINT16 InstalledSize; + + /** Supported SRAM Type */ + CACHE_SRAM_TYPE_DATA SupportedSRAMType; + + /** Current SRAM Type */ + CACHE_SRAM_TYPE_DATA CurrentSRAMType; + + /** Cache Speed */ + UINT8 CacheSpeed; + + /** Error Correction Type */ + UINT8 ErrorCorrectionType; + + /** System Cache Type*/ + UINT8 SystemCacheType; + + /** Associativity */ + UINT8 Associativity; + + /** Maximum Cache Size 2*/ + UINT32 MaximumCacheSize2; + + /** Installed Size 2*/ + UINT32 InstalledSize2; + + /** CM Object Token of Cache information */ + CM_OBJECT_TOKEN CacheInfoToken; +} CM_SMBIOS_CACHE_INFO; + #pragma pack() #endif // SMBIOS_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosType4Lib/SmbiosType4Generator.c b/DynamicTablesPkg/Library/Smbios/SmbiosType4Lib/SmbiosType4Generator.c new file mode 100644 index 0000000000..bc79b94ad6 --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosType4Lib/SmbiosType4Generator.c @@ -0,0 +1,402 @@ +/** @file + SMBIOS Type4 Table Generator. + + Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include + +#define SMBIOS_TYPE4_MAX_STRINGS (6) + +/** This macro expands to a function that retrieves the Memory Device + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceSmbios, + ESmbiosObjProcessorInfo, + CM_SMBIOS_PROCESSOR_INFO + ) + +/** This function pointer describes the interface to used by the + Table Manager to give the generator an opportunity to free + any resources allocated for building the SMBIOS table. + + @param [in] Generator Pointer to the SMBIOS table generator. + @param [in] TableFactoryProtocol Pointer to the Table Factory protocol. + @param [in] SmbiosTableInfo Pointer to the SMBIOS table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [in] Table Pointer to the generated SMBIOS table. + @param [in] CmObjectToken Pointer to the CM ObjectToken Array. + @param [in] TableCount Number of SMBIOS tables. + + @return EFI_SUCCESS If freed successfully or other failure codes + as returned by the generator. +**/ +EFI_STATUS +FreeSmbiosType4TableEx ( + IN CONST SMBIOS_TABLE_GENERATOR *Generator, + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN SMBIOS_STRUCTURE ***CONST Table, + IN CM_OBJECT_TOKEN **CmObjectToken, + IN CONST UINTN TableCount + ) +{ + UINTN Index; + SMBIOS_STRUCTURE **TableList; + + TableList = *Table; + for (Index = 0; Index < TableCount; Index++) { + if (TableList[Index] != NULL) { + FreePool (TableList[Index]); + } + } + + if (*CmObjectToken != NULL) { + FreePool (*CmObjectToken); + } + + if (TableList != NULL) { + FreePool (TableList); + } + + return EFI_SUCCESS; +} + +STATIC +VOID +AddCacheInfoHandle ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CM_OBJECT_TOKEN CmObjToken1, + IN CM_OBJECT_TOKEN CmObjToken2, + IN CM_OBJECT_TOKEN CmObjToken3, + OUT SMBIOS_TABLE_TYPE4 *SmbiosRecord + ) +{ + EFI_SMBIOS_HANDLE CacheInfoHandle; + SMBIOS_HANDLE_MAP *HandleMap; + + HandleMap = TableFactoryProtocol->GetSmbiosHandle (CmObjToken1); + if (HandleMap == NULL) { + DEBUG ((DEBUG_ERROR, "%a:Failed to get SMBIOS Handle\n", __FUNCTION__)); + CacheInfoHandle = 0xFFFF; + } else { + CacheInfoHandle = HandleMap->SmbiosTblHandle; + } + + SmbiosRecord->L1CacheHandle = CacheInfoHandle; + + HandleMap = TableFactoryProtocol->GetSmbiosHandle (CmObjToken2); + if (HandleMap == NULL) { + DEBUG ((DEBUG_ERROR, "%a:Failed to get SMBIOS Handle\n", __FUNCTION__)); + CacheInfoHandle = 0xFFFF; + } else { + CacheInfoHandle = HandleMap->SmbiosTblHandle; + } + + SmbiosRecord->L2CacheHandle = CacheInfoHandle; + + HandleMap = TableFactoryProtocol->GetSmbiosHandle (CmObjToken3); + if (HandleMap == NULL) { + DEBUG ((DEBUG_ERROR, "%a:Failed to get SMBIOS Handle\n", __FUNCTION__)); + CacheInfoHandle = 0xFFFF; + } else { + CacheInfoHandle = HandleMap->SmbiosTblHandle; + } + + SmbiosRecord->L3CacheHandle = CacheInfoHandle; +} + +/** This function pointer describes the interface to SMBIOS table build + functions provided by the SMBIOS table generator and called by the + Table Manager to build an SMBIOS table. + + @param [in] Generator Pointer to the SMBIOS table generator. + @param [in] TableFactoryProtocol Pointer to the Table Factory protocol. + @param [in] SmbiosTableInfo Pointer to the SMBIOS table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [out] Table Pointer to the generated SMBIOS table. + @param [in] CmObjectToken Pointer to the CM object token. + + @return EFI_SUCCESS If the table is generated successfully or other + failure codes as returned by the generator. +**/ +EFI_STATUS +BuildSmbiosType4TableEx ( + IN CONST SMBIOS_TABLE_GENERATOR *Generator, + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT SMBIOS_STRUCTURE ***Table, + OUT CM_OBJECT_TOKEN **CmObjToken, + OUT UINTN *CONST TableCount + ) +{ + EFI_STATUS Status; + CM_SMBIOS_PROCESSOR_INFO *ProcessorInfo; + UINT8 SocketDesignationRef; + UINT8 ProcessorManufacturerRef; + UINT8 ProcessorVersionRef; + UINT8 SerialNumberRef; + UINT8 AssetTagRef; + UINT8 PartNumberRef; + CHAR8 *OptionalStrings; + SMBIOS_TABLE_TYPE4 *SmbiosRecord; + UINTN SmbiosRecordSize; + STRING_TABLE StrTable; + UINT32 NumProcessors; + SMBIOS_STRUCTURE **TableList; + CM_OBJECT_TOKEN *CmObjectList; + UINTN Index; + + ASSERT (Generator != NULL); + ASSERT (SmbiosTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (TableCount != NULL); + ASSERT (SmbiosTableInfo->TableGeneratorId == Generator->GeneratorID); + + // + // Retrieve processor info from CM object + // + *Table = NULL; + Status = GetESmbiosObjProcessorInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &ProcessorInfo, + &NumProcessors + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to get Processor CM Object %r\n", + Status + )); + return Status; + } + + TableList = (SMBIOS_STRUCTURE **)AllocateZeroPool (sizeof (SMBIOS_STRUCTURE *) * NumProcessors); + if (TableList == NULL) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to alloc memory for %u devices table\n", + __FUNCTION__, + NumProcessors + )); + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + CmObjectList = (CM_OBJECT_TOKEN *)AllocateZeroPool (sizeof (CM_OBJECT_TOKEN *) * NumProcessors); + if (CmObjectList == NULL) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to alloc memory for %u CMObjects\n", + __FUNCTION__, + NumProcessors + )); + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + for (Index = 0; Index < NumProcessors; Index++) { + // + // Copy strings to SMBIOS table + // + Status = StringTableInitialize (&StrTable, SMBIOS_TYPE4_MAX_STRINGS); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to initialize string table %r\n", __FUNCTION__, Status)); + return Status; + } + + if (ProcessorInfo[Index].SocketDesignation != NULL) { + STRING_TABLE_ADD_STRING (StrTable, ProcessorInfo[Index].SocketDesignation, SocketDesignationRef); + } + + if (ProcessorInfo[Index].ProcessorManufacturer != NULL) { + STRING_TABLE_ADD_STRING (StrTable, ProcessorInfo[Index].ProcessorManufacturer, ProcessorManufacturerRef); + } + + if (ProcessorInfo[Index].ProcessorVersion != NULL) { + STRING_TABLE_ADD_STRING (StrTable, ProcessorInfo[Index].ProcessorVersion, ProcessorVersionRef); + } + + if (ProcessorInfo[Index].SerialNumber != NULL) { + STRING_TABLE_ADD_STRING (StrTable, ProcessorInfo[Index].SerialNumber, SerialNumberRef); + } + + if (ProcessorInfo[Index].AssetTag != NULL) { + STRING_TABLE_ADD_STRING (StrTable, ProcessorInfo[Index].AssetTag, AssetTagRef); + } + + if (ProcessorInfo[Index].PartNumber != NULL) { + STRING_TABLE_ADD_STRING (StrTable, ProcessorInfo[Index].PartNumber, PartNumberRef); + } + + SmbiosRecordSize = sizeof (SMBIOS_TABLE_TYPE4) + + StringTableGetStringSetSize (&StrTable); + SmbiosRecord = (SMBIOS_TABLE_TYPE4 *)AllocateZeroPool (SmbiosRecordSize); + if (SmbiosRecord == NULL) { + DEBUG ((DEBUG_ERROR, "%a: memory allocation failed for smbios type4 record\n", __FUNCTION__)); + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + SmbiosRecord->Socket = SocketDesignationRef; + SmbiosRecord->ProcessorManufacturer = ProcessorManufacturerRef; + SmbiosRecord->ProcessorVersion = ProcessorVersionRef; + SmbiosRecord->SerialNumber = SerialNumberRef; + SmbiosRecord->AssetTag = AssetTagRef; + SmbiosRecord->PartNumber = PartNumberRef; + + OptionalStrings = (CHAR8 *)(SmbiosRecord + 1); + // publish the string set + StringTablePublishStringSet ( + &StrTable, + OptionalStrings, + (SmbiosRecordSize - sizeof (SMBIOS_TABLE_TYPE4)) + ); + + // + // Fill in other fields of SMBIOS table + // + SmbiosRecord->ProcessorType = ProcessorInfo[Index].ProcessorType; + SmbiosRecord->ProcessorFamily = ProcessorInfo[Index].ProcessorFamily; + SmbiosRecord->ProcessorId = ProcessorInfo[Index].ProcessorId; + SmbiosRecord->Voltage = ProcessorInfo[Index].Voltage; + SmbiosRecord->ExternalClock = ProcessorInfo[Index].ExternalClock; + SmbiosRecord->MaxSpeed = ProcessorInfo[Index].MaxSpeed; + SmbiosRecord->CurrentSpeed = ProcessorInfo[Index].CurrentSpeed; + SmbiosRecord->Status = ProcessorInfo[Index].Status; + SmbiosRecord->ProcessorUpgrade = ProcessorInfo[Index].ProcessorUpgrade; + SmbiosRecord->CoreCount = ProcessorInfo[Index].CoreCount; + SmbiosRecord->EnabledCoreCount = ProcessorInfo[Index].EnabledCoreCount; + SmbiosRecord->ThreadCount = ProcessorInfo[Index].ThreadCount; + SmbiosRecord->ProcessorCharacteristics = ProcessorInfo[Index].ProcessorCharacteristics; + SmbiosRecord->ProcessorFamily2 = ProcessorInfo[Index].ProcessorFamily2; + SmbiosRecord->CoreCount2 = ProcessorInfo[Index].CoreCount2; + SmbiosRecord->EnabledCoreCount2 = ProcessorInfo[Index].EnabledCoreCount2; + SmbiosRecord->ThreadCount2 = ProcessorInfo[Index].ThreadCount2; + SmbiosRecord->ThreadEnabled = ProcessorInfo[Index].ThreadEnabled; + + AddCacheInfoHandle ( + TableFactoryProtocol, + ProcessorInfo[Index].CacheInfoTokenL1, + ProcessorInfo[Index].CacheInfoTokenL2, + ProcessorInfo[Index].CacheInfoTokenL3, + SmbiosRecord + ); + + // + // Setup SMBIOS header + // + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE4); + TableList[Index] = (SMBIOS_STRUCTURE *)SmbiosRecord; + CmObjectList[Index] = ProcessorInfo[Index].ProcessorInfoToken; + StringTableFree (&StrTable); + } + + *Table = TableList; + *CmObjToken = CmObjectList; + *TableCount = NumProcessors; + Status = EFI_SUCCESS; + +ErrorExit: + // free string table + StringTableFree (&StrTable); + return Status; +} + +/** The interface for the SMBIOS Type4 Table Generator. +*/ +STATIC +CONST +SMBIOS_TABLE_GENERATOR SmbiosType4Generator = { + // Generator ID + CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdType04), + // Generator Description + L"SMBIOS.TYPE4.GENERATOR", + // SMBIOS Table Type + EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, + NULL, + NULL, + // Build table function + BuildSmbiosType4TableEx, + // Free function + FreeSmbiosType4TableEx +}; + +/** Register the Generator with the SMBIOS Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +SmbiosType4LibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterSmbiosTableGenerator (&SmbiosType4Generator); + DEBUG (( + DEBUG_INFO, + "SMBIOS Type 4: Register Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** Deregister the Generator from the SMBIOS Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +SmbiosType4LibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterSmbiosTableGenerator (&SmbiosType4Generator); + DEBUG (( + DEBUG_INFO, + "SMBIOS Type4: Deregister Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosType4Lib/SmbiosType4Lib.inf b/DynamicTablesPkg/Library/Smbios/SmbiosType4Lib/SmbiosType4Lib.inf new file mode 100644 index 0000000000..8ad96fad3b --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosType4Lib/SmbiosType4Lib.inf @@ -0,0 +1,37 @@ +## @file +# SMBIOS Type 4 Table Generator +# +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = SmbiosType4Lib + FILE_GUID = 91347599-ede9-400c-b310-76a07c80e059 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = SmbiosType4LibConstructor + DESTRUCTOR = SmbiosType4LibDestructor + +[Sources] + SmbiosType4Generator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[Protocols] + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[LibraryClasses] + BaseLib + DebugLib + SmbiosStringTableLib + MemoryAllocationLib diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosType7Lib/SmbiosType7Generator.c b/DynamicTablesPkg/Library/Smbios/SmbiosType7Lib/SmbiosType7Generator.c new file mode 100644 index 0000000000..ba851c6066 --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosType7Lib/SmbiosType7Generator.c @@ -0,0 +1,313 @@ +/** @file + SMBIOS Type7 Table Generator. + + Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include + +#define SMBIOS_TYPE7_MAX_STRINGS (1) + +/** This macro expands to a function that retrieves the Memory Device + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceSmbios, + ESmbiosObjCacheInfo, + CM_SMBIOS_CACHE_INFO + ) + +/** This function pointer describes the interface to used by the + Table Manager to give the generator an opportunity to free + any resources allocated for building the SMBIOS table. + + @param [in] Generator Pointer to the SMBIOS table generator. + @param [in] TableFactoryProtocol Pointer to the Table Factory protocol. + @param [in] SmbiosTableInfo Pointer to the SMBIOS table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [in] Table Pointer to the generated SMBIOS table. + @param [in] CmObjectToken Pointer to the CM ObjectToken Array. + @param [in] TableCount Number of SMBIOS tables. + + @return EFI_SUCCESS If freed successfully or other failure codes + as returned by the generator. +**/ +EFI_STATUS +FreeSmbiosType7TableEx ( + IN CONST SMBIOS_TABLE_GENERATOR *Generator, + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN SMBIOS_STRUCTURE ***CONST Table, + IN CM_OBJECT_TOKEN **CmObjectToken, + IN CONST UINTN TableCount + ) +{ + UINTN Index; + SMBIOS_STRUCTURE **TableList; + + TableList = *Table; + for (Index = 0; Index < TableCount; Index++) { + if (TableList[Index] != NULL) { + FreePool (TableList[Index]); + } + } + + if (*CmObjectToken != NULL) { + FreePool (*CmObjectToken); + } + + if (TableList != NULL) { + FreePool (TableList); + } + + return EFI_SUCCESS; +} + +/** This function pointer describes the interface to SMBIOS table build + functions provided by the SMBIOS table generator and called by the + Table Manager to build an SMBIOS table. + + @param [in] Generator Pointer to the SMBIOS table generator. + @param [in] TableFactoryProtocol Pointer to the Table Factory protocol. + @param [in] SmbiosTableInfo Pointer to the SMBIOS table information. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol interface. + @param [out] Table Pointer to the generated SMBIOS table. + @param [in] CmObjectToken Pointer to the CM object token. + + @return EFI_SUCCESS If the table is generated successfully or other + failure codes as returned by the generator. +**/ +EFI_STATUS +BuildSmbiosType7TableEx ( + IN CONST SMBIOS_TABLE_GENERATOR *Generator, + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT SMBIOS_STRUCTURE ***Table, + OUT CM_OBJECT_TOKEN **CmObjToken, + OUT UINTN *CONST TableCount + ) +{ + EFI_STATUS Status; + CM_SMBIOS_CACHE_INFO *CacheInfo; + UINT8 SocketDesignationRef; + CHAR8 *OptionalStrings; + SMBIOS_TABLE_TYPE7 *SmbiosRecord; + UINTN SmbiosRecordSize; + STRING_TABLE StrTable; + UINT32 NumCacheTable; + SMBIOS_STRUCTURE **TableList; + CM_OBJECT_TOKEN *CmObjectList; + UINTN Index; + + ASSERT (Generator != NULL); + ASSERT (SmbiosTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (TableCount != NULL); + ASSERT (SmbiosTableInfo->TableGeneratorId == Generator->GeneratorID); + + // + // Retrieve cache info from CM object + // + *Table = NULL; + Status = GetESmbiosObjCacheInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &CacheInfo, + &NumCacheTable + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "Failed to get Cache CM Object %r\n", + Status + )); + return Status; + } + + TableList = (SMBIOS_STRUCTURE **)AllocateZeroPool (sizeof (SMBIOS_STRUCTURE *) * NumCacheTable); + if (TableList == NULL) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to alloc memory for %u devices table\n", + __FUNCTION__, + NumCacheTable + )); + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + CmObjectList = (CM_OBJECT_TOKEN *)AllocateZeroPool (sizeof (CM_OBJECT_TOKEN *) * NumCacheTable); + if (CmObjectList == NULL) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to alloc memory for %u CMObjects\n", + __FUNCTION__, + NumCacheTable + )); + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + for (Index = 0; Index < NumCacheTable; Index++) { + // + // Copy strings to SMBIOS table + // + Status = StringTableInitialize (&StrTable, SMBIOS_TYPE7_MAX_STRINGS); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to initialize string table %r\n", __FUNCTION__, Status)); + return Status; + } + + if (CacheInfo[Index].SocketDesignation != NULL) { + STRING_TABLE_ADD_STRING (StrTable, CacheInfo[Index].SocketDesignation, SocketDesignationRef); + } + + SmbiosRecordSize = sizeof (SMBIOS_TABLE_TYPE7) + + StringTableGetStringSetSize (&StrTable); + SmbiosRecord = (SMBIOS_TABLE_TYPE7 *)AllocateZeroPool (SmbiosRecordSize); + if (SmbiosRecord == NULL) { + DEBUG ((DEBUG_ERROR, "%a: memory allocation failed for smbios type7 record\n", __FUNCTION__)); + Status = EFI_OUT_OF_RESOURCES; + goto ErrorExit; + } + + SmbiosRecord->SocketDesignation = SocketDesignationRef; + + OptionalStrings = (CHAR8 *)(SmbiosRecord + 1); + // publish the string set + StringTablePublishStringSet ( + &StrTable, + OptionalStrings, + (SmbiosRecordSize - sizeof (SMBIOS_TABLE_TYPE7)) + ); + + // + // Fill in other fields of SMBIOS table + // + SmbiosRecord->CacheConfiguration = CacheInfo[Index].CacheConfiguration; + SmbiosRecord->MaximumCacheSize = CacheInfo[Index].MaximumCacheSize; + SmbiosRecord->InstalledSize = CacheInfo[Index].InstalledSize; + SmbiosRecord->SupportedSRAMType = CacheInfo[Index].SupportedSRAMType; + SmbiosRecord->CurrentSRAMType = CacheInfo[Index].CurrentSRAMType; + SmbiosRecord->CacheSpeed = CacheInfo[Index].CacheSpeed; + SmbiosRecord->ErrorCorrectionType = CacheInfo[Index].ErrorCorrectionType; + SmbiosRecord->SystemCacheType = CacheInfo[Index].SystemCacheType; + SmbiosRecord->Associativity = CacheInfo[Index].Associativity; + SmbiosRecord->MaximumCacheSize2 = CacheInfo[Index].MaximumCacheSize2; + SmbiosRecord->InstalledSize2 = CacheInfo[Index].InstalledSize2; + // + // Setup SMBIOS header + // + SmbiosRecord->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION; + SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE7); + + TableList[Index] = (SMBIOS_STRUCTURE *)SmbiosRecord; + CmObjectList[Index] = CacheInfo[Index].CacheInfoToken; + StringTableFree (&StrTable); + } + + *Table = TableList; + *CmObjToken = CmObjectList; + *TableCount = NumCacheTable; + Status = EFI_SUCCESS; + +ErrorExit: + // free string table + StringTableFree (&StrTable); + return Status; +} + +/** The interface for the SMBIOS Type7 Table Generator. +*/ +STATIC +CONST +SMBIOS_TABLE_GENERATOR SmbiosType7Generator = { + // Generator ID + CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdType07), + // Generator Description + L"SMBIOS.TYPE7.GENERATOR", + // SMBIOS Table Type + EFI_SMBIOS_TYPE_CACHE_INFORMATION, + NULL, + NULL, + // Build table function + BuildSmbiosType7TableEx, + // Free function + FreeSmbiosType7TableEx +}; + +/** Register the Generator with the SMBIOS Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +SmbiosType7LibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterSmbiosTableGenerator (&SmbiosType7Generator); + DEBUG (( + DEBUG_INFO, + "SMBIOS Type 7: Register Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** Deregister the Generator from the SMBIOS Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +SmbiosType7LibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterSmbiosTableGenerator (&SmbiosType7Generator); + DEBUG (( + DEBUG_INFO, + "SMBIOS Type7: Deregister Generator. Status = %r\n", + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosType7Lib/SmbiosType7Lib.inf b/DynamicTablesPkg/Library/Smbios/SmbiosType7Lib/SmbiosType7Lib.inf new file mode 100644 index 0000000000..b603a7b14a --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosType7Lib/SmbiosType7Lib.inf @@ -0,0 +1,37 @@ +## @file +# SMBIOS Type 7 Table Generator +# +# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = SmbiosType7Lib + FILE_GUID = 4f1183e5-45e7-4e12-b6b0-aa12c4043400 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = SmbiosType7LibConstructor + DESTRUCTOR = SmbiosType7LibDestructor + +[Sources] + SmbiosType7Generator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[Protocols] + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED + +[LibraryClasses] + BaseLib + DebugLib + SmbiosStringTableLib + MemoryAllocationLib