From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from hqnvemgate24.nvidia.com (hqnvemgate24.nvidia.com [216.228.121.143]) by mx.groups.io with SMTP id smtpd.web10.10980.1604665720497364082 for ; Fri, 06 Nov 2020 04:28:40 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@nvidia.com header.s=n1 header.b=Lb8tRJDf; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: nvidia.com, ip: 216.228.121.143, mailfrom: ipark@nvidia.com) Received: from hqmail.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate24.nvidia.com (using TLS: TLSv1.2, AES256-SHA) id ; Fri, 06 Nov 2020 04:28:42 -0800 Received: from HQMAIL107.nvidia.com (172.20.187.13) by HQMAIL111.nvidia.com (172.20.187.18) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Fri, 6 Nov 2020 12:28:39 +0000 Received: from ipark-ubuntu.nvidia.com (172.20.13.39) by mail.nvidia.com (172.20.187.13) with Microsoft SMTP Server id 15.0.1473.3 via Frontend Transport; Fri, 6 Nov 2020 12:28:38 +0000 From: "Irene Park" To: CC: Irene Park Subject: [PATCH] DynamicTablesPkg: Add library for SMBIOS table generation Date: Fri, 6 Nov 2020 07:27:31 -0500 Message-ID: <599abd707abbdc72b8c26e060b8b2d00e651070b.1604665488.git.ipark@nvidia.com> X-Mailer: git-send-email 2.7.4 X-NVConfidentiality: public Return-Path: ipark@nvidia.com MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1604665722; bh=D50KgPXQKNzj4o8uAnzbTc7pE0N1F1/LS9Sl/1wBEhQ=; h=From:To:CC:Subject:Date:Message-ID:X-Mailer:X-NVConfidentiality: MIME-Version:Content-Type; b=Lb8tRJDfJg1YK6Z7cijl9b0lQIOpGx2D91TfvY2wffoN9SNIl17HuU91PXKdln6NC s+VzB8AgveAPvFptxA93djND3l9TC8W8aRoEilQT6b9Y9fQbKPKoSRxG/1ps73POg0 ibkco8EJTo26QL784LfXush+bkwAMuQyZlUwwesZI8Ew93gALXA6zBrjRUqaXHvqPI YwXuzGuxoI2cfSGfjrU3XT3Z3XB8VU0UwWkioTDMYNQREL+QipUy+5n7oovHzKhcEW N9jD8623SBwZafjbGzDVdB7vRfewxVb0klNCyrSSJ62c0Un6bzfvRcwN69O7KX0LN/ 2D2tE21tYJw6w== Content-Type: text/plain From: Irene Park The Configuration Manager supports the ACPI generation but the SMBIOS has been out of its coverage. This adds the SMBIOS table generation in the table type of 0,1,2,3,4,7,8,9,11,13,15,16,17,19,32,38,41 which are required or recommended to meet the SBBR spec. This provides the following features. - Support RAW table generation in any SMBIOS version - Support table generation for SBBR where SMBIOS version >= 3.2 - Use string in place of a string index - Use CM_OBJECT_TOKEN in place of a direct handle assignment - Use a universal data type to describe any capacity Signed-off-by: Irene Park --- .../DynamicTableManagerDxe/DynamicTableManager.h | 25 + .../DynamicTableManagerDxe.c | 13 + .../DynamicTableManagerDxe.inf | 6 +- .../DynamicTableManagerSmbios.c | 505 +++++++++ .../Include/ConfigurationManagerObject.h | 34 + DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h | 559 ++++++++++ DynamicTablesPkg/Include/SmbiosTableGenerator.h | 179 +++- .../Include/StandardNameSpaceObjects.h | 6 +- .../Library/Smbios/SmbiosBasicLib/BasicGenerator.c | 554 ++++++++++ .../Library/Smbios/SmbiosBasicLib/BasicGenerator.h | 171 ++++ .../Library/Smbios/SmbiosBasicLib/BasicObjects.c | 1077 ++++++++++++++++++++ .../Library/Smbios/SmbiosBasicLib/BasicObjects.h | 102 ++ .../Smbios/SmbiosBasicLib/SmbiosBasicLib.inf | 39 + .../Library/Smbios/SmbiosRawLib/RawGenerator.c | 136 +++ .../Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf | 36 + 15 files changed, 3385 insertions(+), 57 deletions(-) create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManager.h create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerSmbios.c create mode 100644 DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.c create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.h create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.c create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.h create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/SmbiosBasicLib.inf create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosRawLib/RawGenerator.c create mode 100644 DynamicTablesPkg/Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManager.h b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManager.h new file mode 100644 index 0000000..efa11ee --- /dev/null +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManager.h @@ -0,0 +1,25 @@ +/** @file + + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Std - Standard + - ACPI - Advanced Configuration and Power Interface + - SMBIOS - System Management BIOS + - DT - Device Tree +**/ + +#ifndef DYNAMIC_TABLE_MANAGER_H_ +#define DYNAMIC_TABLE_MANAGER_H_ + +EFI_STATUS +EFIAPI +ProcessSmbiosTables ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol + ); + +#endif // DYNAMIC_TABLE_MANAGER_H_ diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c index e27dcaf..c783cac 100644 --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c @@ -1,6 +1,7 @@ /** @file Dynamic Table Manager Dxe + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -22,6 +23,8 @@ #include #include +#include "DynamicTableManager.h" + /** This macro expands to a function that retrieves the ACPI Table List from the Configuration Manager. */ @@ -724,6 +727,16 @@ DynamicTableManagerDxeInitialize ( "ERROR: ACPI Table processing failure. Status = %r\n", Status )); + return Status; + } + + Status = ProcessSmbiosTables (TableFactoryProtocol, CfgMgrProtocol); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SMBIOS processing failure. Status = %r\n", + Status + )); } return Status; } diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf index 028c3d4..b15a9e9 100644 --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf @@ -1,6 +1,7 @@ ## @file # Module that drives the table generation and installation process. # +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. # Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -22,6 +23,7 @@ [Sources] DynamicTableManagerDxe.c + DynamicTableManagerSmbios.c [Packages] MdePkg/MdePkg.dec @@ -36,12 +38,12 @@ [Protocols] gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED - + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEdkiiConfigurationManagerProtocolGuid # PROTOCOL ALWAYS_CONSUMED gEdkiiDynamicTableFactoryProtocolGuid # PROTOCOL ALWAYS_CONSUMED [Depex] gEfiAcpiTableProtocolGuid AND + gEfiSmbiosProtocolGuid AND gEdkiiConfigurationManagerProtocolGuid AND gEdkiiDynamicTableFactoryProtocolGuid - diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerSmbios.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerSmbios.c new file mode 100644 index 0000000..d210fa4 --- /dev/null +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerSmbios.c @@ -0,0 +1,505 @@ +/** @file + Dynamic Table Manager for SMBIOS + + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + Copyright (c) 2017 - 2020, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include + +/** This macro expands to a function that retrieves the SMBIOS Table + List from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceStandard, + EStdObjSmbiosTableList, + CM_STD_OBJ_SMBIOS_TABLE_INFO + ) + +/** A helper function to build and install a single SMBIOS table. + + This is a helper function that invokes the Table generator interface + for building an SMBIOS table. It uses the SmbiosTableProtocol to install the + table, then frees the resources allocated for generating it. + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Generator Pointer to the SmbiosTable generator. + @param [in] SmbiosTableProtocol Pointer to the SmbiosTable protocol. + @param [in] SmbiosTableInfo Pointer to the SMBIOS table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Required object is not found. + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager + is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildAndInstallSingleSmbiosTable ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator, + IN EFI_SMBIOS_PROTOCOL * SmbiosTableProtocol, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST SmbiosTableInfo + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + EFI_SMBIOS_TABLE_HEADER * SmbiosTable; + UINTN TableCount; + + SmbiosTable = NULL; + TableCount = 0; + Status = Generator->BuildSmbiosTable ( + Generator, + SmbiosTableInfo, + CfgMgrProtocol, + &SmbiosTable + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Build Table." \ + " TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + if (SmbiosTable == NULL) { + Status = EFI_NOT_FOUND; + goto exit_handler; + } + + // Dump SMBIOS Table Header + DUMP_SMBIOS_TABLE_HEADER (SmbiosTable); + + // Install SMBIOS table + Status = SmbiosTableProtocol->Add ( + SmbiosTableProtocol, + NULL, + &SmbiosTable->Handle, + SmbiosTable + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Install SMBIOS Table. Status = %r\n", + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + + DEBUG (( + DEBUG_INFO, + "INFO: SMBIOS Table installed. Status = %r\n", + Status + )); + +exit_handler: + // Free any resources allocated for generating the tables. + if (Generator->FreeTableResources != NULL) { + Status1 = Generator->FreeTableResources ( + Generator, + SmbiosTableInfo, + CfgMgrProtocol, + &SmbiosTable + ); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Free Table Resources." \ + "TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status1 + )); + } + + // Return the first error status in case of failure + if (!EFI_ERROR (Status)) { + Status = Status1; + } + } + return Status; +} + +/** A helper function to build and install multiple SMBIOS tables. + + This is a helper function that invokes the Table generator interface + for building an SMBIOS table. It uses the SmbiosTableProtocol to install the + table, then frees the resources allocated for generating it. + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Generator Pointer to the SmbiosTable generator. + @param [in] SmbiosTableProtocol Pointer to the SmbiosTable protocol. + @param [in] SmbiosTableInfo Pointer to the SMBIOS table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Required object is not found. + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager + is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildAndInstallMultipleSmbiosTable ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator, + IN EFI_SMBIOS_PROTOCOL * SmbiosTableProtocol, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST SmbiosTableInfo + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + EFI_SMBIOS_TABLE_HEADER ** SmbiosTable; + UINTN TableCount; + UINTN Index; + + SmbiosTable = NULL; + TableCount = 0; + Status = Generator->BuildSmbiosTableEx ( + Generator, + SmbiosTableInfo, + CfgMgrProtocol, + &SmbiosTable, + &TableCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Build Table." \ + " TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + if ((SmbiosTable == NULL) || (TableCount == 0)) { + Status = EFI_NOT_FOUND; + goto exit_handler; + } + + for (Index = 0; Index < TableCount; Index++) { + // Dump SMBIOS Table Header + DUMP_SMBIOS_TABLE_HEADER (SmbiosTable[Index]); + // Install SMBIOS table + Status = SmbiosTableProtocol->Add ( + SmbiosTableProtocol, + NULL, + &SmbiosTable[Index]->Handle, + SmbiosTable[Index] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Install SMBIOS Table. Status = %r\n", + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + DEBUG (( + DEBUG_INFO, + "INFO: SMBIOS Table installed. Status = %r\n", + Status + )); + } + +exit_handler: + // Free any resources allocated for generating the tables. + if (Generator->FreeTableResourcesEx != NULL) { + Status1 = Generator->FreeTableResourcesEx ( + Generator, + SmbiosTableInfo, + CfgMgrProtocol, + &SmbiosTable, + TableCount + ); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Free Table Resources." \ + "TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status1 + )); + } + + // Return the first error status in case of failure + if (!EFI_ERROR (Status)) { + Status = Status1; + } + } + return Status; +} + +/** A helper function to invoke a Table generator + + This is a helper function that invokes the Table generator interface + for building an SMBIOS table. It uses the SmbiosTableProtocol to install the + table, then frees the resources allocated for generating it. + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] SmbiosTableProtocol Pointer to the SmbiosTable protocol. + @param [in] SmbiosTableInfo Pointer to the SMBIOS table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Required object is not found. + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager + is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildAndInstallSmbiosTable ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + IN EFI_SMBIOS_PROTOCOL * SmbiosTableProtocol, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST SmbiosTableInfo + ) +{ + EFI_STATUS Status; + CONST SMBIOS_TABLE_GENERATOR * Generator; + + ASSERT (TableFactoryProtocol != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (SmbiosTableProtocol != NULL); + ASSERT (SmbiosTableInfo != NULL); + + DEBUG (( + DEBUG_INFO, + "INFO: EStdObjSmbiosTableList: Address = 0x%p," \ + " TableGeneratorId = 0x%x\n", + SmbiosTableInfo, + SmbiosTableInfo->TableGeneratorId + )); + + Generator = NULL; + Status = TableFactoryProtocol->GetSmbiosTableGenerator ( + TableFactoryProtocol, + SmbiosTableInfo->TableGeneratorId, + &Generator + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Table Generator not found." \ + " TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status + )); + return Status; + } + + if (Generator == NULL) { + return EFI_NOT_FOUND; + } + + DEBUG (( + DEBUG_INFO, + "INFO: Generator found : %s\n", + Generator->Description + )); + + if (Generator->BuildSmbiosTableEx != NULL) { + Status = BuildAndInstallMultipleSmbiosTable ( + TableFactoryProtocol, + CfgMgrProtocol, + Generator, + SmbiosTableProtocol, + SmbiosTableInfo + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find build and install multiple SMBIOS Tables." \ + " Status = %r\n", + Status + )); + } + } else if (Generator->BuildSmbiosTable != NULL) { + Status = BuildAndInstallSingleSmbiosTable ( + TableFactoryProtocol, + CfgMgrProtocol, + Generator, + SmbiosTableProtocol, + SmbiosTableInfo + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find build and install a single SMBIOS Table." \ + " Status = %r\n", + Status + )); + } + } else { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: Table Generator does not implement the" \ + " SMBIOS_TABLE_GENERATOR_BUILD_TABLE interface." \ + " TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status + )); + } + + return Status; +} + +/** Generate and install SMBIOS tables. + + The function gathers the information necessary for installing the + SMBIOS tables from the Configuration Manager, invokes the generators + and installs them (via BuildAndInstallSmbiosTable). + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + + @retval EFI_SUCCESS Success. + @retval EFI_NOT_FOUND If a mandatory table or a generator is not found. +**/ +EFI_STATUS +EFIAPI +ProcessSmbiosTables ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol + ) +{ + EFI_STATUS Status; + EFI_SMBIOS_PROTOCOL * SmbiosTableProtocol; + CM_STD_OBJ_SMBIOS_TABLE_INFO * SmbiosTableInfo; + UINT32 SmbiosTableCount; + UINT32 Idx; + + ASSERT (TableFactoryProtocol != NULL); + ASSERT (CfgMgrProtocol != NULL); + + // Find the SmbiosTable protocol + Status = gBS->LocateProtocol ( + &gEfiSmbiosProtocolGuid, + NULL, + (VOID**)&SmbiosTableProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find SmbiosTable protocol. Status = %r\n", + Status + )); + return Status; + } + + Status = GetEStdObjSmbiosTableList ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &SmbiosTableInfo, + &SmbiosTableCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to get SMBIOS Table List. Status = %r\n", + Status + )); + return Status; + } + + if (0 == SmbiosTableCount) { + DEBUG (( + DEBUG_ERROR, + "ERROR: EStdObjSmbiosTableList: SmbiosTableCount = %d\n", + SmbiosTableCount + )); + return EFI_NOT_FOUND; + } + + DEBUG (( + DEBUG_INFO, + "INFO: EStdObjSmbiosTableList: SmbiosTableCount = %d\n", + SmbiosTableCount + )); + + // Add remaining SMBIOS Tables + for (Idx = 0; Idx < SmbiosTableCount; Idx++) { + DEBUG (( + DEBUG_INFO, + "INFO: SmbiosTableInfo[%d].TableGeneratorId = 0x%x\n", + Idx, + SmbiosTableInfo[Idx].TableGeneratorId + )); + + // Skip the Reserved table Generator ID for standard generators + if ((IS_GENERATOR_NAMESPACE_STD (SmbiosTableInfo[Idx].TableGeneratorId)) && + ((CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdReserved) >= + SmbiosTableInfo[Idx].TableGeneratorId) || + (CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdMax) <= + SmbiosTableInfo[Idx].TableGeneratorId))) { + DEBUG (( + DEBUG_WARN, + "WARNING: Invalid SMBIOS Generator table ID = 0x%x, Skipping...\n", + SmbiosTableInfo[Idx].TableGeneratorId + )); + continue; + } + + Status = BuildAndInstallSmbiosTable ( + TableFactoryProtocol, + CfgMgrProtocol, + SmbiosTableProtocol, + &SmbiosTableInfo[Idx] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find, build, and install SMBIOS Table." \ + " Status = %r\n", + Status + )); + return Status; + } + } // for + + return Status; +} diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h index b0d3e70..2439035 100644 --- a/DynamicTablesPkg/Include/ConfigurationManagerObject.h +++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h @@ -1,5 +1,6 @@ /** @file + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -14,6 +15,7 @@ #include #include +#include #pragma pack(1) @@ -30,6 +32,7 @@ _______________________________________________________________________________ Bits: [31:28] - Name Space ID 0000 - Standard 0001 - ARM + 0010 - Smbios 1000 - Custom/OEM All other values are reserved. @@ -81,6 +84,26 @@ Object ID's in the ARM Namespace: 28 - Cache Info 29 - Processor Hierarchy Node ID Info 30 - CM Object Reference + +Object ID's in the Smbios Namespace: + 0 - Reserved + 1 - Bios Info + 2 - System Info + 3 - Baseboard Info + 4 - System Enclosure + 5 - Processor Info + 6 - Cache Info + 7 - Port Connector Info + 8 - System Slots + 9 - Oem Strings + 10 - Bios Language Info + 11 - System Event Log + 12 - Physical Memory Array + 13 - Memory Device + 14 - Memory Array Mapped Address + 15 - System Boot Info + 16 - Ipmi Device Info + 17 - Onboard Devices Extended Info */ typedef UINT32 CM_OBJECT_ID; @@ -102,6 +125,7 @@ typedef UINT32 CM_OBJECT_ID; typedef enum ObjectNameSpaceID { EObjNameSpaceStandard, ///< Standard Objects Namespace EObjNameSpaceArm, ///< ARM Objects Namespace + EObjNameSpaceSmbios, ///< Smbios Objects Namespace EObjNameSpaceOem = 0x8, ///< OEM Objects Namespace EObjNameSpaceMax } EOBJECT_NAMESPACE_ID; @@ -178,6 +202,16 @@ typedef struct CmObjDescriptor { (CREATE_CM_OBJECT_ID (EObjNameSpaceArm, ObjectId)) /** This macro returns a Configuration Manager Object ID + in the Smbios Object Namespace. + + @param [in] ObjectId The Object ID. + + @retval Returns an Smbios Configuration Manager Object ID. +**/ +#define CREATE_CM_SMBIOS_OBJECT_ID(ObjectId) \ + (CREATE_CM_OBJECT_ID (EObjNameSpaceSmbios, ObjectId)) + +/** This macro returns a Configuration Manager Object ID in the OEM Object Namespace. @param [in] ObjectId The Object ID. diff --git a/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h b/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h new file mode 100644 index 0000000..6298723 --- /dev/null +++ b/DynamicTablesPkg/Include/SmbiosNameSpaceObjects.h @@ -0,0 +1,559 @@ +/** @file + + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + Copyright (c) 2017 - 2020, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object + - Std or STD - Standard +**/ + +#ifndef SMBIOS_NAMESPACE_OBJECTS_H_ +#define SMBIOS_NAMESPACE_OBJECTS_H_ + +#include + +#pragma pack(1) + +/** The ESMBIOS_OBJECT_ID enum describes the Object IDs + in the SMBIOS Namespace +*/ +typedef enum SmbiosObjectID { + ESmbiosObjReserved, ///< 0 - Reserved + /// + /// SMBIOS table ObjectIDs required or recommended + /// + ESmbiosObjBiosInfo, ///< 1 - Type 0 + ESmbiosObjSystemInfo, ///< 2 - Type 1 + ESmbiosObjBaseboardInfo, ///< 3 - Type 2 + ESmbiosObjSystemEnclosure, ///< 4 - Type 3 + ESmbiosObjProcessorInfo, ///< 5 - Type 4 + ESmbiosObjCacheInfo, ///< 6 - Type 7 + ESmbiosObjPortConnectorInfo, ///< 7 - Type 8 + ESmbiosObjSystemSlots, ///< 8 - Type 9 + ESmbiosObjOemStrings, ///< 9 - Type 11 + ESmbiosObjBiosLanguageInfo, ///< 10 - Type 13 + ESmbiosObjSystemEventLog, ///< 11 - Type 15 + ESmbiosObjPhysicalMemoryArray, ///< 12 - Type 16 + ESmbiosObjMemoryDevice, ///< 13 - Type 17 + ESmbiosObjMemoryArrayMappedAddress, ///< 14 - Type 19 + ESmbiosObjSystemBootInfo, ///< 15 - Type 32 + ESmbiosObjIpmiDeviceInfo, ///< 16 - Type 38 + ESmbiosObjOnboardDevicesExtendedInfo, ///< 17 - Type 41 + ESmbiosObjMax +} ESMBIOS_OBJECT_ID; + + +/// +/// BIOS Information +/// Type 0: ESmbiosObjBiosInfo +/// +typedef struct CmSmbiosBiosInfo { + CONST CHAR8* Vendor; + CONST CHAR8* BiosVersion; + CONST CHAR8* BiosReleaseDate; + UINT32 BiosSize; // 64KB granule + UINT16 BiosSegment; + UINT64 BiosCharacteristics; + UINT8 BiosCharacteristicsExtensionByte1; + UINT8 BiosCharacteristicsExtensionByte2; + UINT16 SystemBiosRelease; + UINT16 EmbeddedControllerFirmwareRelease; +} CM_SMBIOS_BIOS_INFO; + +/// +/// System Information +/// Type 1: ESmbiosObjSystemInfo +/// +typedef struct CmSmbiosSystemInfo { + CONST CHAR8* Manufacturer; + CONST CHAR8* ProductName; + CONST CHAR8* Version; + CONST CHAR8* SerialNumber; + CONST CHAR8* SKUNumber; + CONST CHAR8* Family; + GUID Uuid; + UINT8 WakeUpType; ///< MISC_SYSTEM_WAKEUP_TYPE. +} CM_SMBIOS_SYSTEM_INFO; + +/// +/// Base Board Information +/// Type 2: ESmbiosObjBaseboardInfo +/// +typedef struct CmSmbiosBaseboardInfo { + CONST CHAR8* Manufacturer; + CONST CHAR8* ProductName; + CONST CHAR8* Version; + CONST CHAR8* SerialNumber; + CONST CHAR8* AssetTag; + CONST CHAR8* LocationInChassis; + CM_OBJECT_TOKEN ReferenceToken; + CM_OBJECT_TOKEN ChassisHandle; + UINT8 FeatureFlag; + UINT8 BoardType; ///< BASE_BOARD_TYPE. + UINT8 NumberOfContainedObjectHandles; + CM_OBJECT_TOKEN ContainedObjectHandles; +} CM_SMBIOS_BASEBOARD_INFO; + +/// +/// System Enclosure or Chassis +/// Type 3: ESmbiosObjSystemEnclosure +/// +typedef struct CmSmbiosSystemEnclosure { + CONST CHAR8* Manufacturer; + CONST CHAR8* Version; + CONST CHAR8* SerialNumber; + CONST CHAR8* AssetTag; + CONST CHAR8* SKUNumber; + CM_OBJECT_TOKEN ReferenceToken; + UINT8 Type; + UINT8 BootupState; ///< MISC_CHASSIS_STATE. + UINT8 PowerSupplyState; ///< MISC_CHASSIS_STATE. + UINT8 ThermalState; ///< MISC_CHASSIS_STATE. + UINT8 SecurityStatus; ///< MISC_CHASSIS_SECURITY_STATE. + UINT32 OemDefined; + UINT8 Height; + UINT8 NumberofPowerCords; + UINT8 ContainedElementCount; + UINT8 ContainedElementRecordLength; + CONTAINED_ELEMENT *ContainedElements; + // Since ContainedElements has a variable number of entries, must not define SKUNumber in + // the structure. Need to reference it by starting at offset 0x15 and adding + // (ContainedElementCount * ContainedElementRecordLength) bytes. + // +} CM_SMBIOS_SYSTEM_ENCLOSURE; + +/// +/// Processor Information +/// Type 4: ESmbiosObjProcessorInfo +/// +typedef struct CmSmbiosProcessorInfo { + CONST CHAR8* Socket; + CONST CHAR8* ProcessorManufacture; + CONST CHAR8* ProcessorVersion; + CONST CHAR8* SerialNumber; + CONST CHAR8* AssetTag; + CONST CHAR8* PartNumber; + CM_OBJECT_TOKEN ReferenceToken; + UINT8 ProcessorType; ///< PROCESSOR_TYPE_DATA. + UINT8 ProcessorFamily; ///< PROCESSOR_FAMILY_DATA. + UINT32 ProcessorId[2]; + UINT8 Voltage; + UINT16 ExternalClock; + UINT16 MaxSpeed; + UINT16 CurrentSpeed; + UINT8 Status; + UINT8 ProcessorUpgrade; ///< PROCESSOR_UPGRADE. + CM_OBJECT_TOKEN L1CacheHandle; + CM_OBJECT_TOKEN L2CacheHandle; + CM_OBJECT_TOKEN L3CacheHandle; + UINT8 CoreCount; + UINT8 EnabledCoreCount; + UINT8 ThreadCount; + UINT16 ProcessorCharacteristics; + UINT16 ProcessorFamily2; + UINT16 CoreCount2; + UINT16 EnabledCoreCount2; + UINT16 ThreadCount2; +} CM_SMBIOS_PROCESSOR_INFO; + +/// +/// Cache Information +/// Type 7: ESmbiosObjCacheInfo +/// +typedef struct CmSmbiosCacheInfo { + CONST CHAR8* SocketDesignation; + CM_OBJECT_TOKEN ReferenceToken; + UINT16 CacheConfiguration; + UINT16 MaximumCacheSize; + UINT16 InstalledSize; + UINT16 SupportedSRAMType; + UINT16 CurrentSRAMType; + UINT8 CacheSpeed; + UINT8 ErrorCorrectionType; ///< CACHE_ERROR_TYPE_DATA. + UINT8 SystemCacheType; ///< CACHE_TYPE_DATA. + UINT8 Associativity; ///< CACHE_ASSOCIATIVITY_DATA. + UINT32 MaximumCacheSize2; + UINT32 InstalledSize2; +} CM_SMBIOS_CACHE_INFO; + +/// +/// Port Connector Information +/// Type 8: ESmbiosObjPortConnectorInfo +/// +typedef struct CmSmbiosPortConnectorInfo { + CONST CHAR8* InternalReferenceDesignator; + CONST CHAR8* ExternalReferenceDesignator; + CM_OBJECT_TOKEN ReferenceToken; + UINT8 InternalConnectorType; ///< MISC_PORT_CONNECTOR_TYPE. + UINT8 ExternalConnectorType; ///< MISC_PORT_CONNECTOR_TYPE. + UINT8 PortType; ///< MISC_PORT_TYPE. +} CM_SMBIOS_PORT_CONNECTOR_INFO; + +/// +/// System Slots +/// Type 9: ESmbiosObjSystemSlots +/// +typedef struct CmSmbiosSystemSlots { + CONST CHAR8* SlotDesignation; + CM_OBJECT_TOKEN ReferenceToken; + UINT8 SlotType; ///< MISC_SLOT_TYPE. + UINT8 SlotDataBusWidth; ///< MISC_SLOT_DATA_BUS_WIDTH. + UINT8 CurrentUsage; ///< MISC_SLOT_USAGE. + UINT8 SlotLength; ///< MISC_SLOT_LENGTH. + UINT16 SlotID; + UINT8 SlotCharacteristics1; + UINT8 SlotCharacteristics2; + UINT16 SegmentGroupNum; + UINT8 BusNum; + UINT8 DevFuncNum; + UINT8 DataBusWidth; + UINT8 PeerGroupingCount; + MISC_SLOT_PEER_GROUP *PeerGroups; +} CM_SMBIOS_SYSTEM_SLOTS; + +/// +/// OEM Strings +/// Type 11: ESmbiosObjOemStrings +/// +typedef struct CmSmbiosOemStrings { + CONST CHAR8* Strings; // NULL separated strings + UINT8 StringCount; +} CM_SMBIOS_OEM_STRINGS; + +/// +/// BIOS Language Information +/// Type 13: ESmbiosObjBiosLanguageInfo +/// +typedef struct CmSmbiosBiosLanguageInfo { + CONST CHAR8* Languages; // NULL separated strings + UINT8 InstallableLanguages; + UINT8 Flags; + UINT8 CurrentLanguages; +} CM_SMBIOS_BIOS_LANGUAGE_INFO; + +/// +/// System Event Log +/// Type 15: ESmbiosObjSystemEventLog +/// +typedef struct CmSmbiosSystemEventLog { + UINT16 LogAreaLength; + UINT16 LogHeaderStartOffset; + UINT16 LogDataStartOffset; + UINT8 AccessMethod; + UINT8 LogStatus; + UINT32 LogChangeToken; + UINT32 AccessMethodAddress; + UINT8 LogHeaderFormat; + UINT8 NumberOfSupportedLogTypeDescriptors; + UINT8 LengthOfLogTypeDescriptor; + EVENT_LOG_TYPE *EventLogTypeDescriptors; +} CM_SMBIOS_SYSTEM_EVENT_LOG; + +/// +/// Physical Memory Array +/// Type 16: ESmbiosObjPhysicalMemoryArray +/// +typedef struct CmSmbiosPhysicalMemoryArray { + CM_OBJECT_TOKEN ReferenceToken; + UINT8 Location; ///< MEMORY_ARRAY_LOCATION. + UINT8 Use; ///< MEMORY_ARRAY_USE. + UINT8 MemoryErrorCorrection; ///< MEMORY_ERROR_CORRECTION. + UINT64 MaximumCapacity; ///< in Bytes + CM_OBJECT_TOKEN MemoryErrorInformationHandle; + UINT16 NumberOfMemoryDevices; +} CM_SMBIOS_PHYSICAL_MEMORY_ARRAY; + +/// +/// Memory Device +/// Type 17: ESmbiosObjMemoryDevice +/// +typedef struct CmSmbiosMemoryDevice { + CONST CHAR8* DeviceLocator; + CONST CHAR8* BankLocator; + CONST CHAR8* Manufacturer; + CONST CHAR8* SerialNumber; + CONST CHAR8* AssetTag; + CONST CHAR8* PartNumber; + CONST CHAR8* FirwareVersion; + CM_OBJECT_TOKEN ReferenceToken; + CM_OBJECT_TOKEN MemoryArrayHandle; + CM_OBJECT_TOKEN MemoryErrorInformationHandle; + UINT16 TotalWidth; + UINT16 DataWidth; + UINT64 Size; ///< in Bytes + UINT8 FormFactor; ///< MEMORY_FORM_FACTOR. + UINT8 DeviceSet; + UINT8 MemoryType; ///< MEMORY_DEVICE_TYPE. + UINT16 TypeDetail; + UINT8 Attributes; + UINT32 Speed; ///< Transfer rate + UINT32 ConfiguredMemorySpeed; ///< Transfer rate + UINT16 MinimumVoltage; + UINT16 MaximumVoltage; + UINT16 ConfiguredVoltage; + UINT8 MemoryTechnology; ///< MEMORY_DEVICE_TECHNOLOGY + UINT16 MemoryOperatingModeCapability; + UINT16 ModuleManufacturerID; + UINT16 ModuleProductID; + UINT16 MemorySubsystemControllerManufacturerID; + UINT16 MemorySubsystemControllerProductID; + UINT64 NonVolatileSize; + UINT64 VolatileSize; + UINT64 CacheSize; + UINT64 LogicalSize; +} CM_SMBIOS_MEMORY_DEVICE; + + +/// +/// Memory Array Mapped Address +/// Type 19: ESmbiosObjMemoryArrayMappedAddress +/// +typedef struct CmSmbiosMemoryArrayMappedAddress { + CM_OBJECT_TOKEN ReferenceToken; + UINT64 StartingAddress; + UINT64 EndingAddress; + CM_OBJECT_TOKEN MemoryArrayHandle; + UINT8 PartitionWidth; +} CM_SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS; + +/// +/// System Boot Information +/// Type 32: ESmbiosObjSystemBootInfo +/// +typedef struct CmSmbiosSystemBootInfo { + UINT8 BootStatus; ///< MISC_BOOT_INFORMATION_STATUS_DATA_TYPE. +} CM_SMBIOS_SYSTEM_BOOT_INFO; + +/// +/// IPMI Device Information +/// Type 38: ESmbiosObjIpmiDeviceInfo +/// +typedef struct CmSmbiosIpmiDeviceInfo { + UINT8 InterfaceType; ///< BMC_INTERFACE_TYPE. + UINT8 IPMISpecificationRevision; + UINT8 I2CSlaveAddress; + UINT8 NVStorageDeviceAddress; + UINT8 BaseAddressModifier_InterruptInfo; + UINT8 InterruptNumber; + UINT64 BaseAddress; +} CM_SMBIOS_IPMI_DEVICE_INFO; + +/// +/// Onboard Devices Extended Information +/// Type 41: ESmbiosObjOnboardDevicesExtendedInfo +/// +typedef struct CmSmbiosOnboardDevicesExtendedInfo { + CONST CHAR8* ReferenceDesignation; + UINT8 DeviceType; ///< ONBOARD_DEVICE_EXTENDED_INFO_TYPE + UINT8 DeviceTypeInstance; + UINT16 SegmentGroupNum; + UINT8 BusNum; + UINT8 DevFuncNum; +} CM_SMBIOS_ONBOARD_DEVICES_EXTENDED_INFO; + +#pragma pack() + + +/// +/// Index of SMBIOS_TABLE_STRING +/// +#define SMBIOS_TABLE_STRING_NULL 0x00 +#define SMBIOS_TABLE_STRING_0 0x00 +#define SMBIOS_TABLE_STRING_1 0x01 +#define SMBIOS_TABLE_STRING_2 0x02 +#define SMBIOS_TABLE_STRING_3 0x03 +#define SMBIOS_TABLE_STRING_4 0x04 +#define SMBIOS_TABLE_STRING_5 0x05 +#define SMBIOS_TABLE_STRING_6 0x06 +#define SMBIOS_TABLE_STRING_7 0x07 +#define SMBIOS_TABLE_STRING_8 0x08 + +/// +/// CM_OBJEC_TOKEN +/// +#define CM_OBJECT_TOKEN_NONE 0xFFFFFFFFFFFFUL +#define CM_OBJECT_TOKEN_NO_ERR_DETECTED 0xFFFFFFFFFFFFUL +#define CM_OBJECT_TOKEN_NO_ERR_INFO 0xFFFEFFFEFFFEUL + +/// +/// SMBIOS Table Revisions +/// +#define EFI_SMBIOS_3_0_FIXED_SMBIOS_TABLE_REVISION 0x0300 +#define EFI_SMBIOS_3_1_FIXED_SMBIOS_TABLE_REVISION 0x0301 +#define EFI_SMBIOS_3_2_FIXED_SMBIOS_TABLE_REVISION 0x0302 +#define EFI_SMBIOS_3_3_FIXED_SMBIOS_TABLE_REVISION 0x0303 +#define EFI_SMBIOS_3_4_FIXED_SMBIOS_TABLE_REVISION 0x0304 + + +/// +/// BIOS Characteristics +/// +#define EFI_SMBIOS_CHARACT_UNKNOWN BIT2 +#define EFI_SMBIOS_CHARACT_BIOS_CHARACTERISTICS_NOT_SUPPORTED BIT3 +#define EFI_SMBIOS_CHARACT_ISA_SUPPORTED BIT4 +#define EFI_SMBIOS_CHARACT_MCA_SUPPORTED BIT5 +#define EFI_SMBIOS_CHARACT_EISA_SUPPORTED BIT6 +#define EFI_SMBIOS_CHARACT_PCI_SUPPORTED BIT7 +#define EFI_SMBIOS_CHARACT_PCMCIA_SUPPORTED BIT8 +#define EFI_SMBIOS_CHARACT_PLUGANDPLAY_SUPPORTED BIT9 +#define EFI_SMBIOS_CHARACT_APM_SUPPORTED BIT10 +#define EFI_SMBIOS_CHARACT_BIOS_UPGRADABLE BIT11 +#define EFI_SMBIOS_CHARACT_BIOS_SHADOWING_ALLOWED BIT12 +#define EFI_SMBIOS_CHARACT_VLVESA_SUPPORTED BIT13 +#define EFI_SMBIOS_CHARACT_ESCD_SUPPORT_AVAILABLE BIT14 +#define EFI_SMBIOS_CHARACT_BOOTFROMCD_SUPPORTED BIT15 +#define EFI_SMBIOS_CHARACT_SELECTABLEBOOT_SUPPORTED BIT16 +#define EFI_SMBIOS_CHARACT_ROMBIOS_SOCKETED BIT17 +#define EFI_SMBIOS_CHARACT_BOOTFROMPCMCIA_SUPPORTED BIT18 +#define EFI_SMBIOS_CHARACT_EDD_SPECIFICATION_SUPPORTED BIT19 +#define EFI_SMBIOS_CHARACT_JAPANESE_NEC_FLOPPY_SUPPORTED BIT20 +#define EFI_SMBIOS_CHARACT_JAPANESE_TOSHIBA_FLOPPY_SUPPORTED BIT21 +#define EFI_SMBIOS_CHARACT_FLOPPY525_360_SUPPORTED BIT22 +#define EFI_SMBIOS_CHARACT_FLOPPY525_12_SUPPORTED BIT23 +#define EFI_SMBIOS_CHARACT_FLOPPY35_720_SUPPORTED BIT24 +#define EFI_SMBIOS_CHARACT_FLOPPY35_288_SUPPORTED BIT25 +#define EFI_SMBIOS_CHARACT_PRINTSCREEN_SUPPORTED BIT26 +#define EFI_SMBIOS_CHARACT_KEYBOARD8042_SUPPORTED BIT27 +#define EFI_SMBIOS_CHARACT_SERIAL_SUPPORTED BIT28 +#define EFI_SMBIOS_CHARACT_PRINTER_SUPPORTED BIT29 +#define EFI_SMBIOS_CHARACT_CGAMONO_SUPPORTED BIT30 +#define EFI_SMBIOS_CHARACT_NECPC98 BIT31 + +/// +/// BIOS Characteristics Extension Byte 1. +/// +#define EFI_SMBIOS_CHARACT_EXT1_ACPI_SUPPORTED BIT0 +#define EFI_SMBIOS_CHARACT_EXT1_USB_LEGACY_SUPPORTED BIT1 +#define EFI_SMBIOS_CHARACT_EXT1_AGP_SUPPORTED BIT2 +#define EFI_SMBIOS_CHARACT_EXT1_I2OBOOT_SUPPORTED BIT3 +#define EFI_SMBIOS_CHARACT_EXT1_LS120BOOT_SUPPORTED BIT4 +#define EFI_SMBIOS_CHARACT_EXT1_ATAPIZIP_DRIVEBOOT_SUPPORTED BIT5 +#define EFI_SMBIOS_CHARACT_EXT1_BOOT1394_SUPPORTED BIT6 +#define EFI_SMBIOS_CHARACT_EXT1_SMARTBATTERY_SUPPORTED BIT7 + +/// +/// BIOS Characteristics Extension Byte 2. +/// +#define EFI_SMBIOS_CHARACT_EXT2_BIOS_BOOT_SPEC_SUPPORTED BIT0 +#define EFI_SMBIOS_CHARACT_EXT2_FUNCTION_KEY_NETWORK_BOOT_SUPPORTED BIT1 +#define EFI_SMBIOS_CHARACT_EXT2_TARGET_CONTENT_DISTRIBUTION_ENABLED BIT2 +#define EFI_SMBIOS_CHARACT_EXT2_UEFI_SPECIFICATION_SUPPORTED BIT3 +#define EFI_SMBIOS_CHARACT_EXT2_VIRTUAL_MACHINE_SUPPORTED BIT4 + +/// +/// BIOS Extended ROM size. +/// +#define EFI_SMBIOS_EXTENDED_BIOS_ROM_SIZE_IN_1MB 0 +#define EFI_SMBIOS_EXTENDED_BIOS_ROM_SIZE_IN_1GB BIT0 + +/// +/// Base Board - Feature Flags. +/// +#define EFI_SMBIOS_BASE_BOARD_FEATURE_MOTHER_BOARD BIT0 +#define EFI_SMBIOS_BASE_BOARD_FEATURE_REQUIRES_DAUGHTER_CARD BIT1 +#define EFI_SMBIOS_BASE_BOARD_FEATURE_REMOVABLE BIT2 +#define EFI_SMBIOS_BASE_BOARD_FEATURE_REPLACEABLE BIT3 +#define EFI_SMBIOS_BASE_BOARD_FEATURE_HOT_SWAPPABLE BIT4 + +/// +/// Processor Information - Voltage. +/// +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_CAPABILITY5V BIT0 +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_CAPABILITY3_3V BIT1 +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_CAPABILITY2_9V BIT2 +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_LEGACY 0x00 +#define EFI_SMBIOS_PROCESSOR_VOLTAGE_NON_LEGACY BIT7 + + +/// +/// Processor Information - Characteristics. +/// +#define EFI_SMBIOS_PROCESSOR_CHARACT_RESERVED1 BIT0 +#define EFI_SMBIOS_PROCESSOR_CHARACT_UNKNOWN BIT1 +#define EFI_SMBIOS_PROCESSOR_CHARACT_64BIT_CAPBLE BIT2 +#define EFI_SMBIOS_PROCESSOR_CHARACT_MULTICORE BIT3 +#define EFI_SMBIOS_PROCESSOR_CHARACT_HARDWARE_THREAD BIT4 +#define EFI_SMBIOS_PROCESSOR_CHARACT_EXECUTE_PROTECTION BIT5 +#define EFI_SMBIOS_PROCESSOR_CHARACT_ENHANCED_VIRTULIZATION BIT6 +#define EFI_SMBIOS_PROCESSOR_CHARACT_POWER_PERFORMANCE_CTRL BIT7 +#define EFI_SMBIOS_PROCESSOR_CHARACT_128BIT_CAPBLE BIT8 +#define EFI_SMBIOS_PROCESSOR_CHARACT_ARM64_SOC_ID BIT9 // 3.4 + +/// +/// Processor Information - Status. +/// +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_UNKNOWN 0x00 +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_ENABLED 0x01 +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_DISABLED_BY_USER 0x02 +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_DISABLED_BY_BIOS 0x03 +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_IDLE 0x04 +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_OTHER 0x07 +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_SOCKET_POPULATED BIT6 +#define EFI_SMBIOS_PROCESSOR_STATUS_CPU_SOCKET_NOT_POPULATED 0x00 + + +/// +/// Cache SRAM type data +/// +#define EFI_SMBIOS_CACHE_SRAM_TYPE_OTHER BIT0 +#define EFI_SMBIOS_CACHE_SRAM_TYPE_UNKNOWN BIT1 +#define EFI_SMBIOS_CACHE_SRAM_TYPE_NONBURST BIT2 +#define EFI_SMBIOS_CACHE_SRAM_TYPE_BURST BIT3 +#define EFI_SMBIOS_CACHE_SRAM_TYPE_PIPELINEBURST BIT4 +#define EFI_SMBIOS_CACHE_SRAM_TYPE_SYNCHRONOUS BIT5 +#define EFI_SMBIOS_CACHE_SRAM_TYPE_ASYNCHRONOUS BIT6 + +/// +/// System Slots - Slot Characteristics 1. +/// +#define EFI_SMBIOS_SLOT_CHARACT1_CHARACTERISTICS_UNKNOWN BIT0 +#define EFI_SMBIOS_SLOT_CHARACT1_PROVIDE_50VOLTS BIT1 +#define EFI_SMBIOS_SLOT_CHARACT1_PROVIDE_33VOLTS BIT2 +#define EFI_SMBIOS_SLOT_CHARACT1_SHARED_SLOT BIT3 +#define EFI_SMBIOS_SLOT_CHARACT1_PCCARD16_SUPPORTED BIT4 +#define EFI_SMBIOS_SLOT_CHARACT1_CARDBUS_SUPPORTED BIT5 +#define EFI_SMBIOS_SLOT_CHARACT1_ZOOMVIDEO_SUPPORTED BIT6 +#define EFI_SMBIOS_SLOT_CHARACT1_MODEMRINGRESUME_SUPPORTED BIT7 + +/// +/// System Slots - Slot Characteristics 2. +/// +#define EFI_SMBIOS_SLOT_CHARACT2_PMESIGNAL_SUPPORTED BIT0 +#define EFI_SMBIOS_SLOT_CHARACT2_HOTPLUGDEVICES_SUPPORTED BIT1 +#define EFI_SMBIOS_SLOT_CHARACT2_SMBUSSIGNAL_SUPPORTED BIT2 +#define EFI_SMBIOS_SLOT_CHARACT2_BIFURCATION_SUPPORTED BIT3 + +/// +/// Memory Device - Type Detail +/// +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_RESERVED BIT0 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_OTHER BIT1 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_UNKNOWN BIT2 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_FASTPAGED BIT3 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_STATICCOLUMN BIT4 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_PSEUDOSTATIC BIT5 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_RAMBUS BIT6 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_SYNCHRONOUS BIT7 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_CMOS BIT8 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_EDO BIT9 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_WINDOWDRAM BIT10 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_CACHEDRAM BIT11 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_NONVOLATILE BIT12 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_REGISTERED BIT13 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_UNBUFFERED BIT14 +#define EFI_SMBIOS_MEMORY_DEVICE_TYPE_LRDIMM BIT15 + +/// +/// Memory Device - Memory Operating Mode Capability +/// +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_OTHER BIT1 +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_UNKNOWN BIT2 +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_VOLATILE_MEMORY BIT3 +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_BYTE_ACCESS_PERSISTENT_MEMORY BIT4 +#define EFI_SMBIOS_MEMORY_DEVICE_OP_MODE_BLOCK_ACCESS_PERSISTENT_MEMORY BIT5 + +#endif // SMBIOS_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Include/SmbiosTableGenerator.h b/DynamicTablesPkg/Include/SmbiosTableGenerator.h index 9fbf9fc..2a1656d 100644 --- a/DynamicTablesPkg/Include/SmbiosTableGenerator.h +++ b/DynamicTablesPkg/Include/SmbiosTableGenerator.h @@ -1,5 +1,6 @@ /** @file + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -27,58 +28,35 @@ typedef TABLE_GENERATOR_ID SMBIOS_TABLE_GENERATOR_ID; */ typedef enum StdSmbiosTableGeneratorId { EStdSmbiosTableIdReserved = 0x0000, - EStdSmbiosTableIdRAW, - EStdSmbiosTableIdType00, - EStdSmbiosTableIdType01, - EStdSmbiosTableIdType02, - EStdSmbiosTableIdType03, - EStdSmbiosTableIdType04, - EStdSmbiosTableIdType05, - EStdSmbiosTableIdType06, - EStdSmbiosTableIdType07, - EStdSmbiosTableIdType08, - EStdSmbiosTableIdType09, - EStdSmbiosTableIdType10, - EStdSmbiosTableIdType11, - EStdSmbiosTableIdType12, - EStdSmbiosTableIdType13, - EStdSmbiosTableIdType14, - EStdSmbiosTableIdType15, - EStdSmbiosTableIdType16, - EStdSmbiosTableIdType17, - EStdSmbiosTableIdType18, - EStdSmbiosTableIdType19, - EStdSmbiosTableIdType20, - EStdSmbiosTableIdType21, - EStdSmbiosTableIdType22, - EStdSmbiosTableIdType23, - EStdSmbiosTableIdType24, - EStdSmbiosTableIdType25, - EStdSmbiosTableIdType26, - EStdSmbiosTableIdType27, - EStdSmbiosTableIdType28, - EStdSmbiosTableIdType29, - EStdSmbiosTableIdType30, - EStdSmbiosTableIdType31, - EStdSmbiosTableIdType32, - EStdSmbiosTableIdType33, - EStdSmbiosTableIdType34, - EStdSmbiosTableIdType35, - EStdSmbiosTableIdType36, - EStdSmbiosTableIdType37, - EStdSmbiosTableIdType38, - EStdSmbiosTableIdType39, - EStdSmbiosTableIdType40, - EStdSmbiosTableIdType41, - EStdSmbiosTableIdType42, - - // IDs 43 - 125 are reserved - - EStdSmbiosTableIdType126 = (EStdSmbiosTableIdType00 + 126), - EStdSmbiosTableIdType127, - EStdSmbiosTableIdMax + EStdSmbiosTableIdRaw, ///< RAW Generator + EStdSmbiosTableIdBasic, ///< Basic Generator for the required or recommended tables + EStdSmbiosTableIdMax } ESTD_SMBIOS_TABLE_ID; + +#define EFI_SMBIOS_TABLE_TYPES_MANDATORY ( \ + BIT0 /* BIOS info */ | \ + BIT1 /* System info */ | \ + BIT3 /* System chassis */ | \ + BIT4 /* Processor info */ | \ + BIT7 /* Cache info */ | \ + BIT9 /* System slot */ | \ + BIT16 /* Physical memory array */ | \ + BIT17 /* Memory device */ | \ + BIT19 /* Memory array mapped address */ | \ + BIT32 /* System boot info */ \ + ) + +#define EFI_SMBIOS_TABLE_TYPES_OPTIONAL ( \ + BIT2 /* Baseboard info */ | \ + BIT8 /* Port connector info */ | \ + BIT11 /* OEM string */ | \ + BIT13 /* BIOS language info */ | \ + BIT15 /* System event log */ | \ + BIT38 /* IPMI device info */ | \ + BIT41 /* Onboard device extended info */ \ + ) + /** This macro checks if the Table Generator ID is for an SMBIOS Table Generator. @@ -122,6 +100,44 @@ typedef enum StdSmbiosTableGeneratorId { TableId \ ) +/** This macro creates an OEM SMBIOS Table Generator ID. + + @param [in] TableId The table generator ID. + + @return an OEM SMBIOS table generator ID. +**/ +#define CREATE_OEM_SMBIOS_TABLE_GEN_ID(TableId) \ + CREATE_TABLE_GEN_ID ( \ + ETableGeneratorTypeSmbios, \ + ETableGeneratorNameSpaceOem, \ + TableId \ + ) + +/** A macro to initialise the common header part of EFI SMBIOS tables as + defined by the EFI_SMBIOS_TABLE_HEADER structure. + + @param [in] Type The SMBIOS table type. + @param [in] Length The SMBIOS table length. + @param [in] Handle The SMBIOS table handle. +**/ +#define SMBIOS_HEADER(Type, Length, Handle) { \ + Type, /* UINT8 Type */ \ + Length, /* UINT8 Length */ \ + Handle /* UINT16 Handle */ \ + } + +/** A macro to dump the common header part of EFI SMBIOS tables as + defined by the EFI_SMBIOS_TABLE_HEADER structure. + + @param [in] Header The pointer to the SMBIOS table header. +**/ +#define DUMP_SMBIOS_TABLE_HEADER(Header) \ + DEBUG (( \ + DEBUG_INFO, \ + "SMBIOS: Type %d, Length 0x%x, Handle 0x%x\n", \ + Header->Type, Header->Length, Header->Handle \ + )); + /** Forward declarations. */ typedef struct ConfigurationManagerProtocol EDKII_CONFIGURATION_MANAGER_PROTOCOL; @@ -168,6 +184,48 @@ typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_FREE_TABLE) ( IN SMBIOS_STRUCTURE ** Table ); +/** 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] 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. + + @return EFI_SUCCESS If the table is generated successfully or other + failure codes as returned by the generator. +**/ +typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_BUILD_TABLEEX) ( + IN CONST SMBIOS_TABLE_GENERATOR * Generator, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST SmbiosTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + OUT SMBIOS_STRUCTURE *** Table, + OUT UINTN * TableCount + ); + +/** 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] 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. + + @return EFI_SUCCESS If freed successfully or other failure codes + as returned by the generator. +**/ +typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_FREE_TABLEEX) ( + IN CONST SMBIOS_TABLE_GENERATOR * Generator, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST SmbiosTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + IN SMBIOS_STRUCTURE *** Table, + IN UINTN TableCount + ); + /** The SMBIOS_TABLE_GENERATOR structure provides an interface that the Table Manager can use to invoke the functions to build SMBIOS tables. */ @@ -175,12 +233,17 @@ typedef struct SmbiosTableGenerator { /// The SMBIOS table generator ID. SMBIOS_TABLE_GENERATOR_ID GeneratorID; - /// String describing the DT table - /// generator. + /// String describing the SMBIOS table generator. CONST CHAR16* Description; + /// The SMBIOS table revision + UINT16 SmbiosTableRevision; + + /// The minimum supported SMBIOS table revision. + UINT16 MinSmbiosTableRevision; + /// The SMBIOS table type. - SMBIOS_TYPE Type; + /// SMBIOS_TYPE Type; /// SMBIOS table build function pointer. SMBIOS_TABLE_GENERATOR_BUILD_TABLE BuildSmbiosTable; @@ -189,6 +252,15 @@ typedef struct SmbiosTableGenerator { allocated for building the SMBIOS table. */ SMBIOS_TABLE_GENERATOR_FREE_TABLE FreeTableResources; + + /// SMBIOS table extended build function pointer. + SMBIOS_TABLE_GENERATOR_BUILD_TABLEEX BuildSmbiosTableEx; + + /** The function to free any resources + allocated for building the SMBIOS table + using the extended interface. + */ + SMBIOS_TABLE_GENERATOR_FREE_TABLEEX FreeTableResourcesEx; } SMBIOS_TABLE_GENERATOR; /** Register SMBIOS table factory generator. @@ -231,4 +303,3 @@ DeregisterSmbiosTableGenerator ( #pragma pack() #endif // SMBIOS_TABLE_GENERATOR_H_ - diff --git a/DynamicTablesPkg/Include/StandardNameSpaceObjects.h b/DynamicTablesPkg/Include/StandardNameSpaceObjects.h index 0ba6b16..03faac3 100644 --- a/DynamicTablesPkg/Include/StandardNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/StandardNameSpaceObjects.h @@ -1,5 +1,6 @@ /** @file + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -122,8 +123,11 @@ typedef struct CmStdObjSmbiosTableInfo { /// The SMBIOS Table Generator ID SMBIOS_TABLE_GENERATOR_ID TableGeneratorId; + /// The SMBIOS table revision + UINT16 SmbiosTableRevision; + /// Optional pointer to the SMBIOS table data - SMBIOS_STRUCTURE * SmbiosTableData; + SMBIOS_STRUCTURE * SmbiosTableData; } CM_STD_OBJ_SMBIOS_TABLE_INFO; #pragma pack() diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.c b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.c new file mode 100644 index 0000000..fd06a80 --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.c @@ -0,0 +1,554 @@ +/** @file + Generator of the required or recommended SMBIOS tables + + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + Copyright (c) 2017 - 2020, 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 "BasicGenerator.h" + + +/** The pre-populated data of the SMBIOS tables and the associated Configuration + Manager Object to interface the Basic Table Generator. +*/ +STATIC SMBIOS_OBJECT_INFO BasicGeneratorHelper[] = { + CREATE_SMBIOS_OBJECT_INFO (0, TRUE, 0x03, BiosInfo), + CREATE_SMBIOS_OBJECT_INFO (1, TRUE, 0x06, SystemInfo), + CREATE_SMBIOS_OBJECT_INFO (2, FALSE, 0x06, BaseboardInfo), + CREATE_SMBIOS_OBJECT_INFO (3, TRUE, 0x05, SystemEnclosure), + CREATE_SMBIOS_OBJECT_INFO (4, TRUE, 0x06, ProcessorInfo), + CREATE_SMBIOS_OBJECT_INFO (7, TRUE, 0x01, CacheInfo), + CREATE_SMBIOS_OBJECT_INFO (8, FALSE, 0x02, PortConnectorInfo), + CREATE_SMBIOS_OBJECT_INFO (9, TRUE, 0x01, SystemSlots), + CREATE_SMBIOS_OBJECT_INFO (11, FALSE, 0xFF, OemStrings), + CREATE_SMBIOS_OBJECT_INFO (13, FALSE, 0xFF, BiosLanguageInfo), + CREATE_SMBIOS_OBJECT_INFO (15, FALSE, 0x00, SystemEventLog), + CREATE_SMBIOS_OBJECT_INFO (16, TRUE, 0x00, PhysicalMemoryArray), + CREATE_SMBIOS_OBJECT_INFO (17, TRUE, 0x07, MemoryDevice), + CREATE_SMBIOS_OBJECT_INFO (19, TRUE, 0x00, MemoryArrayMappedAddress), + CREATE_SMBIOS_OBJECT_INFO (32, TRUE, 0x00, SystemBootInfo), + CREATE_SMBIOS_OBJECT_INFO (38, FALSE, 0x00, IpmiDeviceInfo), + CREATE_SMBIOS_OBJECT_INFO (41, FALSE, 0x01, OnboardDevicesExtendedInfo), +}; + + +/** Retrieve an object or an object list from the Configuration Manager using + the Configuration Manager Protocol interface. +**/ +STATIC +EFI_STATUS +GetCmObjectList ( + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, + IN OUT CM_OBJECT_TYPE_INFO * CmObjectInfo + ) +{ + EFI_STATUS Status; + ESMBIOS_OBJECT_ID CmObjectId; + CM_OBJ_DESCRIPTOR CmObjectDesc; + UINTN CmObjectSize; + UINT32 ObjCount; + VOID **List; + + ObjCount = 0; + CmObjectId = CmObjectInfo->Id; + CmObjectSize = CmObjectInfo->Size; + List = &CmObjectInfo->Data; + + ASSERT (List != NULL); + + Status = CfgMgrProtocol->GetObject ( + CfgMgrProtocol, + CREATE_CM_OBJECT_ID (EObjNameSpaceSmbios, CmObjectId), + Token, + &CmObjectDesc + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_INFO, + "INFO: Get CmObjectId 0x%x: Not implemented. Status = %r\n", + CmObjectId, Status + )); + *List = NULL; + goto error_handler; + } + + if (CmObjectDesc.ObjectId != CREATE_CM_OBJECT_ID (EObjNameSpaceSmbios, CmObjectId)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Get CmObjectId 0x%x: Invalid, Expected - 0x%x\n", + CmObjectDesc.ObjectId, CREATE_CM_OBJECT_ID (EObjNameSpaceSmbios, CmObjectId) + )); + ASSERT (FALSE); + Status = EFI_INVALID_PARAMETER; + goto error_handler; + } + + if (CmObjectDesc.Size < (CmObjectSize * CmObjectDesc.Count)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: GetCmObjectId 0x%x: Buffer too small, size = 0x%x\n", + CmObjectId, CmObjectDesc.Size + )); + ASSERT (FALSE); + Status = EFI_BAD_BUFFER_SIZE; + goto error_handler; + } + + ObjCount = CmObjectDesc.Count; + *List = (VOID *)CmObjectDesc.Data; + +error_handler: + if (*List != NULL) { + CmObjectInfo->Count = ObjCount; + } + return Status; +} + +/** Populate the additional size of variable SMBIOS tables. + + This function calculates the length of a variable data structure present + in some SMBIOS tables and helps get the total size of a table. +**/ +STATIC +UINTN +GetSmbiosObjectSize ( + IN UINT16 TableRevision, + IN VOID * SrcObject, + IN ESMBIOS_OBJECT_ID CmObjectId + ) +{ + UINTN Len; + + switch (CmObjectId) { + case ESmbiosObjBaseboardInfo: + Len = GetSmbiosSizeBaseboardInfo (TableRevision, SrcObject); + break; + + case ESmbiosObjSystemEnclosure: + Len = GetSmbiosSizeSystemEnclosure (TableRevision, SrcObject); + break; + + case ESmbiosObjSystemSlots: + Len = GetSmbiosSizeSystemSlots (TableRevision, SrcObject); + break; + + case ESmbiosObjSystemEventLog: + Len = GetSmbiosSizeSystemEventLog (TableRevision, SrcObject); + break; + + default: + Len = 0; + } + return Len; +} + +/** Populate the size of strings attached to a SMBIOS table. + + This function calculates the size of strings to be contained in + a table and helps get the total size of a table. +**/ +STATIC +UINTN +GetSmbiosStringLength ( + IN SMBIOS_OBJECT_TYPE_INFO * SmbiosObjectInfo, + IN VOID * Object + ) +{ + UINTN Index; + UINTN Len; + UINTN Size; + CONST CHAR8 * Strings; + CONST CHAR8 ** StringArray; + + ASSERT (SmbiosObjectInfo != NULL); + ASSERT (Object != NULL); + + Len = 0; + + switch (SmbiosObjectInfo->NumStrings) { + case (0x00): + break; + + case (0xFF): + Strings = (CONST CHAR8 *)Object; + // One pointer contains multiple NULL-terminated strings + while (*Strings != '\0') { + Size = AsciiStrSize (Strings); + Len += Size; + Strings += Size; + } + Len++; // The last NULL + break; + + default: + StringArray = (CONST CHAR8 **)Object; + for (Index = 0; Index < SmbiosObjectInfo->NumStrings; Index++) { + if (StringArray[Index] != NULL) { + Len += AsciiStrSize (StringArray[Index]); + } + } + Len++; // The last NULL + } + return Len; +} + + +/** Populate SMBIOS table(s) based on the given information of the + Configuration Manager Object description and the pre-populated data + of a SMBIOS table type. +**/ +EFI_STATUS +BuildSmbiosObject ( + IN UINT16 TableRevision, + IN VOID * ObjectTableInfo, + OUT EFI_SMBIOS_TABLE_HEADER ** Table + ) +{ + EFI_STATUS Status; + SMBIOS_OBJECT_INFO * ObjectInfo; + SMBIOS_OBJECT_TYPE_INFO * SmbiosObjectInfo; + CM_OBJECT_TYPE_INFO * CmObjectInfo; + VOID * SrcObject; + EFI_SMBIOS_TABLE_HEADER * DstObject; + UINTN Index; + UINTN ObjLen; + UINTN StrLen; + + ASSERT (Table != NULL); + ASSERT (ObjectTableInfo != NULL); + + ObjectInfo = (SMBIOS_OBJECT_INFO *)ObjectTableInfo; + CmObjectInfo = &ObjectInfo->CmObjectInfo; + SmbiosObjectInfo = &ObjectInfo->SmbiosObjectInfo; + + for (Index = 0; Index < CmObjectInfo->Count; Index++) { + SrcObject = CmObjectInfo->Data + (Index * CmObjectInfo->Size); + + ObjLen = SmbiosObjectInfo->Length; + ObjLen += GetSmbiosObjectSize (TableRevision, SrcObject, CmObjectInfo->Id); + StrLen = GetSmbiosStringLength (SmbiosObjectInfo, SrcObject); + + DstObject = (EFI_SMBIOS_TABLE_HEADER *)AllocateZeroPool (ObjLen + StrLen); + if (DstObject == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to allocate memory for %d th SMBIOS Table" + " of Id %x, Status = %r\n", + Index, + CmObjectInfo->Id, + Status + )); + goto error_handler; + } + + // Update the table type and the length in the header + DstObject->Type = SmbiosObjectInfo->Type; + DstObject->Length = ObjLen; + + // Build this specific object of the SMBIOS table + Status = ObjectInfo->BuildObject (TableRevision, + (VOID *)SrcObject, + (VOID *)DstObject + ); + if (EFI_ERROR (Status)) { + goto error_handler; + } + Table[Index] = DstObject; + } + +error_handler: + return Status; +} + + +/** Free the resources allocated for building the SMBIOS tables. +**/ +STATIC +VOID +FreeSmbiosBasicTable ( + IN EFI_SMBIOS_TABLE_HEADER *** Table, + IN UINTN TableCount + ) +{ + UINTN Index; + EFI_SMBIOS_TABLE_HEADER ** SmbiosTable; + + ASSERT (Table != NULL); + + SmbiosTable = *Table; + if (SmbiosTable != NULL) { + for (Index = 0; Index < TableCount; Index++) { + if (SmbiosTable[Index] != NULL) { + FreePool (SmbiosTable[Index]); + } + } + FreePool (SmbiosTable); + } +} + +/** Construct the SMBIOS table using the SMBIOS table data provided. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the SMBIOS + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] SmbiosTableInfo Pointer to the SMBIOS Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed SMBIOS Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildBasicTable ( + IN CONST SMBIOS_TABLE_GENERATOR * CONST This, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST SmbiosTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + OUT EFI_SMBIOS_TABLE_HEADER *** Table, + OUT UINTN * TableCount + ) +{ + EFI_STATUS Status; + SMBIOS_OBJECT_INFO *ObjectInfo; + CM_OBJECT_TYPE_INFO *CmObjectInfo; + UINTN Index; + UINTN LocalTableCount; + EFI_SMBIOS_TABLE_HEADER **LocalTable; + UINT16 TableRevision; + + ASSERT (This != NULL); + ASSERT (SmbiosTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (TableCount != NULL); + ASSERT (SmbiosTableInfo->TableGeneratorId == This->GeneratorID); + + TableRevision = SmbiosTableInfo->SmbiosTableRevision; + + if ((TableRevision < This->MinSmbiosTableRevision) || + (TableRevision > This->SmbiosTableRevision)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SMBIOS Basic: Requested table rev = %d, is not supported." + "Supported table rev: Min = %d, Max = %d\n", + TableRevision, + This->MinSmbiosTableRevision, + This->SmbiosTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + *Table = NULL; + *TableCount = 0; + LocalTableCount = 0; + + // Collect the required data prior to allocating a space for SMBIOS tables + for (Index = 0; Index < ARRAY_SIZE (BasicGeneratorHelper); Index++) { + CmObjectInfo = &BasicGeneratorHelper[Index].CmObjectInfo; + // Get the pointer to CmObject data and their count + Status = GetCmObjectList (CfgMgrProtocol, CM_NULL_TOKEN, CmObjectInfo); + if (EFI_ERROR (Status)) { + continue; + } + // Count the number of the SMBIOS tables to be installed + LocalTableCount += CmObjectInfo->Count; + } + + // Allocate a space for the entire SMBIOS tables + LocalTable = (EFI_SMBIOS_TABLE_HEADER **)AllocateZeroPool (LocalTableCount + * sizeof (EFI_SMBIOS_TABLE_HEADER *)); + if (LocalTable == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to allocate memory for %d SMBIOS Tables," + " Status = %r\n", + LocalTableCount, + Status + )); + goto error_handler; + } + *Table = LocalTable; + *TableCount = LocalTableCount; + + // Create a space to assign the SMBIOS handles prior to building each table + Status = BuildSmbiosHandleTable (LocalTableCount); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + // Build all basic SMBIOS tables + for (Index = 0; Index < ARRAY_SIZE (BasicGeneratorHelper); Index++) { + ObjectInfo = &BasicGeneratorHelper[Index]; + + if (ObjectInfo->CmObjectInfo.Count != 0) { + Status = BuildSmbiosObject (TableRevision, ObjectInfo, LocalTable); + if (EFI_ERROR (Status)) { + goto error_handler; + } + + if ((UINTN)LocalTable >= (UINTN)(*Table + LocalTableCount)) { + Status = EFI_BAD_BUFFER_SIZE; + goto error_handler; + } + LocalTable += ObjectInfo->CmObjectInfo.Count; + } + } + if ((UINTN)LocalTable != (UINTN)(*Table + LocalTableCount)) { + Status = EFI_BAD_BUFFER_SIZE; + goto error_handler; + } + +error_handler: + if (EFI_ERROR (Status)) { + FreeSmbiosHandleTable (); + FreeSmbiosBasicTable (Table, *TableCount); + + *Table = NULL; + *TableCount = 0; + } + + return Status; +} + +/** Free any resources allocated for constructing the tables. + + @param [in] This Pointer to the SMBIOS table generator. + @param [in] SmbiosTableInfo Pointer to the SMBIOS Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to an array of pointers + to SMBIOS Table(s). + @param [in] TableCount Number of SMBIOS table(s). + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +FreeBasicTable ( + IN CONST SMBIOS_TABLE_GENERATOR * This, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST SmbiosTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + IN SMBIOS_STRUCTURE *** Table, + IN UINTN TableCount +) +{ + + ASSERT (This != NULL); + ASSERT (SmbiosTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (SmbiosTableInfo->TableGeneratorId == This->GeneratorID); + + + if (Table == NULL) { + DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + FreeSmbiosHandleTable (); + FreeSmbiosBasicTable (Table, TableCount); + + return EFI_SUCCESS; +} + + +/** This macro defines the Raw Generator revision. +*/ +#define RAW_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the Raw Table Generator. +*/ +STATIC +CONST +SMBIOS_TABLE_GENERATOR BasicGenerator = { + // Generator ID + CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdBasic), + // Generator Description + L"SMBIOS.STD.BASIC.GENERATOR", + // SMBIOS Table Revision supported by this Generator + EFI_SMBIOS_3_4_FIXED_SMBIOS_TABLE_REVISION, + // Minimum supported SMBIOS Table Revision + EFI_SMBIOS_3_2_FIXED_SMBIOS_TABLE_REVISION, + // SMBIOS Table Type + // 0, + // Build Table function + NULL, + // No additional resources are allocated by the generator. + // Hence the Free Resource function is not required. + NULL, + // Build TableEx function + BuildBasicTable, + // Free ResouceEx function + FreeBasicTable, +}; + +/** 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 +EFIAPI +SmbiosBasicLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable + ) +{ + EFI_STATUS Status; + Status = RegisterSmbiosTableGenerator (&BasicGenerator); + DEBUG ((DEBUG_INFO, "Basic: 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 +EFIAPI +SmbiosBasicLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable + ) +{ + EFI_STATUS Status; + Status = DeregisterSmbiosTableGenerator (&BasicGenerator); + DEBUG ((DEBUG_INFO, "Basic: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.h b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.h new file mode 100644 index 0000000..edcd404 --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicGenerator.h @@ -0,0 +1,171 @@ +/** @file + Basic Generator of the required or recommended SMBIOS tables + + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + Copyright (c) 2017 - 2020, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + + +#ifndef SMBIOS_BASIC_GENERATOR_H_ +#define SMBIOS_BASIC_GENERATOR_H_ + +#include "BasicObjects.h" + + + +EFI_STATUS +BuildSmbiosHandleTable ( + IN UINTN TableCount + ); + +VOID +FreeSmbiosHandleTable ( + VOID + ); + +UINTN +GetSmbiosSizeBaseboardInfo ( + IN UINT16 Revision, + IN VOID * SrcObject + ); + +UINTN +GetSmbiosSizeSystemEnclosure ( + IN UINT16 Revision, + IN VOID * SrcObject + ); + +UINTN +GetSmbiosSizeSystemSlots ( + IN UINT16 Revision, + IN VOID * SrcObject + ); + +UINTN +GetSmbiosSizeSystemEventLog ( + IN UINT16 Revision, + IN VOID * SrcObject + ); + +EFI_STATUS +BuildSmbiosBiosInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosSystemInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosBaseboardInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosSystemEnclosure ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosProcessorInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosCacheInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosPortConnectorInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosSystemSlots ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosOemStrings ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosBiosLanguageInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosSystemEventLog ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosPhysicalMemoryArray ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosMemoryDevice ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosMemoryArrayMappedAddress ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosSystemBootInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosIpmiDeviceInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +EFI_STATUS +BuildSmbiosOnboardDevicesExtendedInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + +#endif \ No newline at end of file diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.c b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.c new file mode 100644 index 0000000..3030527 --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.c @@ -0,0 +1,1077 @@ +/** @file + Generator of the required or recommended SMBIOS table objects + + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + Copyright (c) 2017 - 2019, 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 "BasicObjects.h" + + +/** A local data to retain the mapping from a reference token to a handle +**/ +STATIC SMBIOS_OBJECT_HANDLE mHandle; + + +/** Allocate a resource for a table to map a reference token to a handle +**/ +EFI_STATUS +BuildSmbiosHandleTable ( + IN UINTN TableCount + ) +{ + if (TableCount != 0) { + mHandle.Count = TableCount; + mHandle.Base = 0x1000; + // TODO: Get mHandle.Base from PCD + if (((UINTN)mHandle.Base + mHandle.Count) >= (UINTN)SMBIOS_HANDLE_RESERVED_BEGIN) { + return EFI_INVALID_PARAMETER; + } + + mHandle.Table = AllocateZeroPool (mHandle.Count * sizeof (SMBIOS_HANDLE_MAPPING)); + if (mHandle.Table == NULL) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to allocate memory for %d SMBIOS HandleTable\n", + mHandle.Count + )); + return EFI_OUT_OF_RESOURCES; + } + } + return EFI_SUCCESS; +} + +/** Free a resouce allocated for a mapping table of the reference token and the handle. +**/ +VOID +FreeSmbiosHandleTable ( + VOID + ) +{ + if (mHandle.Table != NULL) { + DEBUG ((DEBUG_ERROR, "Freeing SMBIOS handle table\n")); + FreePool (mHandle.Table); + } +} + + +/** Map a reference token to a handle. +**/ +STATIC +SMBIOS_HANDLE +GetSmbiosHandle ( + CM_OBJECT_TOKEN RefToken +) +{ + STATIC UINTN IndexTop; + UINTN Index; + SMBIOS_HANDLE_MAPPING * Object; + + Object = mHandle.Table; + Index = 0; + + if (RefToken == CM_OBJECT_TOKEN_NONE) { + return SMBIOS_TABLE_MAX_LENGTH; + } else if (RefToken == CM_OBJECT_TOKEN_NO_ERR_INFO) { + return SMBIOS_HANDLE_PI_RESERVED; + } + + if (IndexTop == 0) { + Object->RefToken = RefToken; + Object->Handle = mHandle.Base; + IndexTop++; + mHandle.Base++; + + } else if (IndexTop <= mHandle.Count) { + while (Index < IndexTop) { + if (Object->RefToken == RefToken) { + goto assign_handle; // return (Object->Handle); + } + Object++; + Index++; + } + if ((Index == IndexTop) && (IndexTop < mHandle.Count)) { + Object->RefToken = RefToken; + Object->Handle = mHandle.Base; + IndexTop++; + mHandle.Base++; + } else { + // This shouldn't happen + DEBUG (( + DEBUG_ERROR, + "ERROR: SMBIOS HandleTable is Out of Range %d\n", + mHandle.Count + )); + ASSERT (FALSE); + } + } + +assign_handle: + DEBUG ((DEBUG_ERROR, "RefToken %p set to [%02x] %04x\n", RefToken, Index, Object->Handle)); + return (Object->Handle); +} + + +/** Copy a string from a given pointer to a space reserved for a string + within a SMBIOS table and set SMBIOS_TABLE_STRING accordingly. +**/ +STATIC +UINTN +SetSmbiosTableString ( + IN OUT UINT8 * StrIndex, + IN OUT CHAR8 ** StringsOut, + OUT UINT8 * SmbiosStringIndex, + IN CONST CHAR8 * StringsIn + ) +{ + UINTN Len = 0; + UINT8 StrInx; + + ASSERT (StrIndex != NULL); + ASSERT (StringsOut != NULL); + ASSERT (SmbiosStringIndex != NULL); + + StrInx = *StrIndex; + if (StringsIn != NULL) { + Len = AsciiStrSize (StringsIn); + AsciiStrCpyS (*StringsOut, Len, StringsIn); + *StringsOut += Len; + *SmbiosStringIndex = StrInx++; + *StrIndex = StrInx; + } + return Len; +} + +/** Get the length of a variable data structure of Baseboard Info, + SMBIOS type 2 +**/ +UINTN +GetSmbiosSizeBaseboardInfo ( + IN UINT16 Revision, + IN VOID * SrcObject + ) +{ + CM_SMBIOS_BASEBOARD_INFO * Src; + + ASSERT (SrcObject != NULL); + + Src = SrcObject; + if (Src->NumberOfContainedObjectHandles != 0) { + ASSERT (Src->ContainedObjectHandles != 0); + } + + // This will leave one 16bit space blank + return (Src->NumberOfContainedObjectHandles * sizeof (SMBIOS_HANDLE)); +} + +/** Get the length of a variable data structure of System Enclose, + SMBIOS type 3 +**/ +UINTN +GetSmbiosSizeSystemEnclosure ( + IN UINT16 Revision, + IN VOID * SrcObject + ) +{ + CM_SMBIOS_SYSTEM_ENCLOSURE * Src; + UINTN Len; + + ASSERT (SrcObject != NULL); + + Src = SrcObject; + Len = sizeof (SMBIOS_TABLE_STRING); // String number for SKUNumber + + if (Src->ContainedElementCount != 0) { + ASSERT (Src->ContainedElements != NULL); + ASSERT (Src->ContainedElementRecordLength == sizeof (CONTAINED_ELEMENT)); + } + + return (Len + (Src->ContainedElementCount * sizeof (CONTAINED_ELEMENT))); +} + +/** Get the length of a variable data structure of System Slots, + SMBIOS type 9 +**/ +UINTN +GetSmbiosSizeSystemSlots ( + IN UINT16 Revision, + IN VOID * SrcObject + ) +{ + CM_SMBIOS_SYSTEM_SLOTS * Src; + UINTN Len; + + ASSERT (SrcObject != NULL); + + Src = SrcObject; + Len = 0; + + if (Src->PeerGroupingCount != 0) { + ASSERT (Src->PeerGroups != NULL); + } + if (Revision >= EFI_SMBIOS_3_4_FIXED_SMBIOS_TABLE_REVISION) { + Len += 4; // SlotInfo (1) + SlotWidth (1) + SlotPitch (2) + } + + return (Len + (Src->PeerGroupingCount * sizeof (MISC_SLOT_PEER_GROUP))); +} + +/** Get the length of a variable data structure of System Event Log, + SMBIOS type 15 +**/ +UINTN +GetSmbiosSizeSystemEventLog ( + IN UINT16 Revision, + IN VOID * SrcObject + ) +{ + CM_SMBIOS_SYSTEM_EVENT_LOG * Src; + + ASSERT (SrcObject != NULL); + + Src = SrcObject; + ASSERT (Src->LengthOfLogTypeDescriptor != sizeof (EVENT_LOG_TYPE)); + if (Src->NumberOfSupportedLogTypeDescriptors != 0) { + ASSERT (Src->EventLogTypeDescriptors != NULL); + } + + return (Src->NumberOfSupportedLogTypeDescriptors + sizeof (EVENT_LOG_TYPE)); +} + + +/** Set up the SMBIOS table of Bios Info, + SMBIOS type 0 +**/ +EFI_STATUS +BuildSmbiosBiosInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_BIOS_INFO * Src; + SMBIOS_TABLE_TYPE0 * Dst; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + UINT32 BiosSize; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED; + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update the strings + Len += SET_SMBIOS_TABLE_STRING (Vendor); + Len += SET_SMBIOS_TABLE_STRING (BiosVersion); + Len += SET_SMBIOS_TABLE_STRING (BiosReleaseDate); + + Dst->BiosSegment = Src->BiosSegment; + + // Src->BiosSize in 64KB granule + // 8bit in 64KB, max 16MB + // 14bit in 1MB, max 16GB + // 14bit in 1GB, max 16TB + if (Src->BiosSize < SIZE_16MB_BY_64KB) { + Dst->BiosSize = (UINT8)Src->BiosSize; + Dst->ExtendedBiosSize.Size = 0; + } else if (Src->BiosSize < SIZE_16GB_BY_64KB) { + SET_EXTENDED_BIOS_ROM_SIZE (Dst, Src, BiosSize, 1MB); + } else { + SET_EXTENDED_BIOS_ROM_SIZE (Dst, Src, BiosSize, 1GB); + } + + BiosSize = sizeof (Dst->BiosCharacteristics) + + sizeof (Dst->BIOSCharacteristicsExtensionBytes) * 2; + CopyMem (&Dst->BiosCharacteristics, &Src->BiosCharacteristics, BiosSize); + + Dst->SystemBiosMajorRelease = GET_MAJOR_REV_NUM (Src->SystemBiosRelease); + Dst->SystemBiosMinorRelease = GET_MINOR_REV_NUM (Src->SystemBiosRelease); + Dst->EmbeddedControllerFirmwareMajorRelease = + GET_MAJOR_REV_NUM (Src->EmbeddedControllerFirmwareRelease); + Dst->EmbeddedControllerFirmwareMinorRelease = + GET_MINOR_REV_NUM (Src->EmbeddedControllerFirmwareRelease); + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of System Info, + SMBIOS type 1 +**/ +EFI_STATUS +BuildSmbiosSystemInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_SYSTEM_INFO * Src; + SMBIOS_TABLE_TYPE1 * Dst; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED; + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update the strings + Len += SET_SMBIOS_TABLE_STRING (Manufacturer); + Len += SET_SMBIOS_TABLE_STRING (ProductName); + Len += SET_SMBIOS_TABLE_STRING (Version); + Len += SET_SMBIOS_TABLE_STRING (SerialNumber); + Len += SET_SMBIOS_TABLE_STRING (SKUNumber); + Len += SET_SMBIOS_TABLE_STRING (Family); + + CopyMem (&Dst->Uuid, &Src->Uuid, sizeof (Dst->Uuid)); + Dst->WakeUpType = Src->WakeUpType; + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Baseboard Info, + SMBIOS type 2 +**/ +EFI_STATUS +BuildSmbiosBaseboardInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_BASEBOARD_INFO * Src; + SMBIOS_TABLE_TYPE2 * Dst; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + SMBIOS_HANDLE * Handle; + CM_OBJECT_TOKEN * ContainedObjectHandles; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken); + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update the strings + Len += SET_SMBIOS_TABLE_STRING (Manufacturer); + Len += SET_SMBIOS_TABLE_STRING (ProductName); + Len += SET_SMBIOS_TABLE_STRING (Version); + Len += SET_SMBIOS_TABLE_STRING (SerialNumber); + Len += SET_SMBIOS_TABLE_STRING (AssetTag); + Len += SET_SMBIOS_TABLE_STRING (LocationInChassis); + + CopyMem (&Dst->FeatureFlag, &Src->FeatureFlag, sizeof (Dst->FeatureFlag)); + + Dst->ChassisHandle = GetSmbiosHandle (Src->ChassisHandle); + Dst->BoardType = Src->BoardType; + Dst->NumberOfContainedObjectHandles = Src->NumberOfContainedObjectHandles; + + Handle = Dst->ContainedObjectHandles; + ContainedObjectHandles = (CM_OBJECT_TOKEN *)Src->ContainedObjectHandles; + for (Len = 0; Len < Src->NumberOfContainedObjectHandles; Len++) { + *Handle++ = GetSmbiosHandle (*ContainedObjectHandles++); + } + return EFI_SUCCESS; +} + + +/** Set up the SMBIOS table of System Enclure, + SMBIOS type 3 +**/ +EFI_STATUS +BuildSmbiosSystemEnclosure ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_SYSTEM_ENCLOSURE * Src; + SMBIOS_TABLE_TYPE3 * Dst; + SMBIOS_TABLE_STRING * SKUNumber; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + UINTN Size; + CONTAINED_ELEMENT * ContainedElements; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken); + + SKUNumber = (SMBIOS_TABLE_STRING *)(DstObject + Dst->Hdr.Length - 1); + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update the strings + Len = SET_SMBIOS_TABLE_STRING (Manufacturer); + Len = SET_SMBIOS_TABLE_STRING (Version); + Len = SET_SMBIOS_TABLE_STRING (SerialNumber); + Len = SET_SMBIOS_TABLE_STRING (AssetTag); + Len = SetSmbiosTableString (&StrIndex, &Strings, SKUNumber, Src->SKUNumber); + + Dst->Type = Src->Type; + Size = sizeof (Dst->BootupState) + + sizeof (Dst->PowerSupplyState) + + sizeof (Dst->ThermalState) + + sizeof (Dst->SecurityStatus) + + sizeof (Dst->OemDefined[0]) * 4 + + sizeof (Dst->Height) + + sizeof (Dst->NumberofPowerCords) + + sizeof (Dst->ContainedElementCount) + + sizeof (Dst->ContainedElementRecordLength); + CopyMem (&Dst->BootupState, &Src->BootupState, Size); + + ContainedElements = Dst->ContainedElements; + for (Len = 0; Len < Src->ContainedElementCount; Len++) { + CopyMem (ContainedElements++, Src->ContainedElements++, sizeof (CONTAINED_ELEMENT)); + } + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Processor Info, + SMBIOS type 4 +**/ +EFI_STATUS +BuildSmbiosProcessorInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_PROCESSOR_INFO * Src; + SMBIOS_TABLE_TYPE4 * Dst; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + UINTN Size; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken); + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update the strings + Len = SET_SMBIOS_TABLE_STRING (Socket); + Len = SET_SMBIOS_TABLE_STRING (ProcessorManufacture); + Len = SET_SMBIOS_TABLE_STRING (ProcessorVersion); + Len = SET_SMBIOS_TABLE_STRING (SerialNumber); + Len = SET_SMBIOS_TABLE_STRING (AssetTag); + Len = SET_SMBIOS_TABLE_STRING (PartNumber); + + Dst->ProcessorType = Src->ProcessorType; + Dst->ProcessorFamily = Src->ProcessorFamily; + + CopyMem (&Dst->ProcessorId, Src->ProcessorId, sizeof (Dst->ProcessorId)); + + Size = sizeof (Dst->Voltage) + + sizeof (Dst->ExternalClock) + + sizeof (Dst->MaxSpeed) + + sizeof (Dst->CurrentSpeed) + + sizeof (Dst->Status) + + sizeof (Dst->ProcessorUpgrade); + CopyMem (&Dst->Voltage, &Src->Voltage, Size); + + Dst->L1CacheHandle = GetSmbiosHandle (Src->L1CacheHandle); + Dst->L2CacheHandle = GetSmbiosHandle (Src->L2CacheHandle); + Dst->L3CacheHandle = GetSmbiosHandle (Src->L3CacheHandle); + + Size = sizeof (Dst->CoreCount) + + sizeof (Dst->EnabledCoreCount) + + sizeof (Dst->ThreadCount) + + sizeof (Dst->ProcessorCharacteristics) + + sizeof (Dst->ProcessorFamily2) + + sizeof (Dst->CoreCount2) + + sizeof (Dst->EnabledCoreCount2) + + sizeof (Dst->ThreadCount2); + CopyMem (&Dst->CoreCount, &Src->CoreCount, Size); + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Cache Info, + SMBIOS type 7 +**/ +EFI_STATUS +BuildSmbiosCacheInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_CACHE_INFO * Src; + SMBIOS_TABLE_TYPE7 * Dst; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + UINTN Size; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken); + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update the strings + Len = SET_SMBIOS_TABLE_STRING (SocketDesignation); + + Size = sizeof (Dst->CacheConfiguration) + + sizeof (Dst->MaximumCacheSize) + + sizeof (Dst->InstalledSize) + + sizeof (Dst->SupportedSRAMType) + + sizeof (Dst->CurrentSRAMType) + + sizeof (Dst->CacheSpeed) + + sizeof (Dst->ErrorCorrectionType) + + sizeof (Dst->SystemCacheType) + + sizeof (Dst->Associativity) + + sizeof (Dst->MaximumCacheSize2) + + sizeof (Dst->InstalledSize2); + CopyMem (&Dst->CacheConfiguration, &Src->CacheConfiguration, Size); + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Port Connector Info, + SMBIOS type 8 +**/ +EFI_STATUS +BuildSmbiosPortConnectorInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_PORT_CONNECTOR_INFO * Src; + SMBIOS_TABLE_TYPE8 * Dst; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken); + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update the strings + Len = SET_SMBIOS_TABLE_STRING (InternalReferenceDesignator); + Len = SET_SMBIOS_TABLE_STRING (ExternalReferenceDesignator); + + Dst->InternalConnectorType = Src->InternalConnectorType; + Dst->ExternalConnectorType = Src->ExternalConnectorType; + Dst->PortType = Src->PortType; + + return EFI_SUCCESS; +} + + +/** Set up the SMBIOS table of System Slots, + SMBIOS type 9 +**/ +EFI_STATUS +BuildSmbiosSystemSlots ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_SYSTEM_SLOTS * Src; + SMBIOS_TABLE_TYPE9 * Dst; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + UINTN Size; + MISC_SLOT_PEER_GROUP * PeerGroups; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken); + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update the strings + Len = SET_SMBIOS_TABLE_STRING (SlotDesignation); + + Size = sizeof (Dst->SlotType) + + sizeof (Dst->SlotDataBusWidth) + + sizeof (Dst->CurrentUsage) + + sizeof (Dst->SlotLength) + + sizeof (Dst->SlotID) + + sizeof (Dst->SlotCharacteristics1) + + sizeof (Dst->SlotCharacteristics2) + + sizeof (Dst->SegmentGroupNum) + + sizeof (Dst->BusNum) + + sizeof (Dst->DevFuncNum) + + sizeof (Dst->DataBusWidth) + + sizeof (Dst->PeerGroupingCount); + CopyMem (&Dst->SlotType, &Src->SlotType, Size); + + PeerGroups = Dst->PeerGroups; + for (Len = 0; Len < Src->PeerGroupingCount; Len++) { + CopyMem (PeerGroups++, Src->PeerGroups++, sizeof (MISC_SLOT_PEER_GROUP)); + } + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of OEM Strings, + SMBIOS type 11 +**/ +EFI_STATUS +BuildSmbiosOemStrings ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_OEM_STRINGS * Src; + SMBIOS_TABLE_TYPE11 * Dst; + CONST CHAR8 * StringSrc; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + UINTN Index; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED; + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + + Dst->StringCount = Src->StringCount; + StringSrc = Src->Strings; + // Update the strings + for (Index = 0; Index < Src->StringCount; Index++) { + Len = AsciiStrSize (StringSrc); + CopyMem (Strings, StringSrc, Len); + Strings += Len; + StringSrc += Len; + } + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Bios Language Info, + SMBIOS type 13 +**/ +EFI_STATUS +BuildSmbiosBiosLanguageInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_BIOS_LANGUAGE_INFO * Src; + SMBIOS_TABLE_TYPE13 * Dst; + CONST CHAR8 * StringSrc; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + UINTN Index; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED; + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + + Dst->Flags = Src->Flags; + Dst->CurrentLanguages = Src->CurrentLanguages; + Dst->InstallableLanguages = Src->InstallableLanguages; + StringSrc = Src->Languages; + // Update the strings + for (Index = 0; Index < Src->InstallableLanguages; Index++) { + Len = AsciiStrSize (StringSrc); + CopyMem (Strings, StringSrc, Len); + Strings += Len; + StringSrc += Len; + } + + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of System Event Log, + SMBIOS type 15 +**/ +EFI_STATUS +BuildSmbiosSystemEventLog ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_SYSTEM_EVENT_LOG * Src; + SMBIOS_TABLE_TYPE15 * Dst; + UINTN Len; + EVENT_LOG_TYPE * EventLogTypeDescriptors; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED; + + // No strings + Len = Dst->Hdr.Length - sizeof (Dst->Hdr) - sizeof (EVENT_LOG_TYPE); + CopyMem (&Dst->LogAreaLength, &Src->LogAreaLength, Len); + + EventLogTypeDescriptors = Dst->EventLogTypeDescriptors; + for (Len = 0; Len < Src->NumberOfSupportedLogTypeDescriptors; Len++) { + CopyMem (EventLogTypeDescriptors++, Src->EventLogTypeDescriptors++, sizeof (EVENT_LOG_TYPE)); + } + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Physical Memory Array, + SMBIOS type 16 +**/ +EFI_STATUS +BuildSmbiosPhysicalMemoryArray ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_PHYSICAL_MEMORY_ARRAY * Src; + SMBIOS_TABLE_TYPE16 * Dst; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken); + // No strings + + Dst->Location = Src->Location; + Dst->Use = Src->Use; + Dst->MemoryErrorCorrection = Src->MemoryErrorCorrection; + Dst->NumberOfMemoryDevices = Src->NumberOfMemoryDevices; + + // Use MaximumCapacity when less than 2TB + if (Src->MaximumCapacity < 0x020000000000UL) { + Dst->MaximumCapacity = (Src->MaximumCapacity >> 10); + if (Src->MaximumCapacity & (BIT10 - 1)) { + Dst->MaximumCapacity++; + } + Dst->ExtendedMaximumCapacity = 0; + } else { + Dst->MaximumCapacity = 0x80000000; + Dst->ExtendedMaximumCapacity = Src->MaximumCapacity; + } + + Dst->MemoryErrorInformationHandle = GetSmbiosHandle (Src->MemoryErrorInformationHandle); + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Memory Device, + SMBIOS type 17 +**/ +EFI_STATUS +BuildSmbiosMemoryDevice ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_MEMORY_DEVICE * Src; + SMBIOS_TABLE_TYPE17 * Dst; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + UINTN Size; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken); + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update the strings + Len += SET_SMBIOS_TABLE_STRING (DeviceLocator); + Len += SET_SMBIOS_TABLE_STRING (BankLocator); + Len += SET_SMBIOS_TABLE_STRING (Manufacturer); + Len += SET_SMBIOS_TABLE_STRING (SerialNumber); + Len += SET_SMBIOS_TABLE_STRING (AssetTag); + Len += SET_SMBIOS_TABLE_STRING (PartNumber); + Len += SET_SMBIOS_TABLE_STRING (FirwareVersion); + + Dst->MemoryArrayHandle = GetSmbiosHandle (Src->MemoryArrayHandle); + Dst->MemoryErrorInformationHandle = GetSmbiosHandle (Src->MemoryErrorInformationHandle); + + Dst->TotalWidth = Src->TotalWidth; + Dst->DataWidth = Src->DataWidth; + Dst->FormFactor = Src->FormFactor; + Dst->DeviceSet = Src->DeviceSet; + Dst->Attributes = Src->Attributes; + + if (Src->Size < 0x0200000UL) { + // Less than 32MB, so it's in 1KB + Dst->Size = (Src->Size >> 10) | BIT15; + if (Src->Size & (BIT10 - 1)) { + Dst->Size++; + } + Dst->ExtendedSize = 0; + } else if (Src->Size < 0x800000000UL) { + // Less than 32GB, so it's in 1MB + Dst->Size = (Src->Size >> 20); + if (Src->Size & (BIT20 - 1)) { + Dst->Size++; + } + Dst->ExtendedSize = 0; + } else { + // Equal to or greater than 32GB, so it's in 1MB + Dst->Size = 0x7FFF; + Dst->ExtendedSize = (Src->Size >> 20); + if (Src->Size & (BIT20 - 1)) { + Dst->ExtendedSize++; + } + // No check of BIT31 as no way to get a device in PETA + } + + if (Src->Speed < 0x10000) { + // Slower than 65,536 MT/s + Dst->Speed = Src->Speed; + Dst->ExtendedSpeed = 0; + } else { + Dst->Speed = 0xFFFF; + Dst->ExtendedSpeed = Src->Speed; + } + + if (Src->ConfiguredMemorySpeed < 0x10000) { + // Slower than 65,536 MT/s + Dst->ConfiguredMemoryClockSpeed = Src->ConfiguredMemorySpeed; + Dst->ExtendedConfiguredMemorySpeed = 0; + } else { + Dst->ConfiguredMemoryClockSpeed = 0xFFFF; + Dst->ExtendedConfiguredMemorySpeed = Src->ConfiguredMemorySpeed; + } + + Size = sizeof (Dst->MemoryType) + + sizeof (Dst->TypeDetail); + CopyMem (&Dst->MemoryType, &Src->MemoryType, Size); + + Size = sizeof (Dst->MinimumVoltage) + + sizeof (Dst->MaximumVoltage) + + sizeof (Dst->ConfiguredVoltage) + + sizeof (Dst->MemoryTechnology) + + sizeof (Dst->MemoryOperatingModeCapability); + CopyMem (&Dst->MinimumVoltage, &Src->MinimumVoltage, Size); + + Size = sizeof (Dst->ModuleManufacturerID) + + sizeof (Dst->ModuleProductID) + + sizeof (Dst->MemorySubsystemControllerManufacturerID) + + sizeof (Dst->MemorySubsystemControllerProductID) + + sizeof (Dst->NonVolatileSize) + + sizeof (Dst->VolatileSize) + + sizeof (Dst->CacheSize) + + sizeof (Dst->LogicalSize); + CopyMem (&Dst->ModuleManufacturerID, &Src->ModuleManufacturerID, Size); + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Memory Array Mapped Address, + SMBIOS type 19 +**/ +EFI_STATUS +BuildSmbiosMemoryArrayMappedAddress ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS * Src; + SMBIOS_TABLE_TYPE19 * Dst; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = GetSmbiosHandle (Src->ReferenceToken); + // No strings + + if ((Src->StartingAddress < 0x040000000000UL) && + (Src->EndingAddress < 0x040000000000UL)) { + // Lower than 4TB, then it's in 1KB + Dst->StartingAddress = (Src->StartingAddress >> 10); + if (Src->StartingAddress & (BIT10 -1)) { + Dst->StartingAddress++; + } + Dst->EndingAddress = (Src->EndingAddress >> 10); + if (Src->EndingAddress & (BIT10 -1)) { + Dst->EndingAddress++; + } + Dst->ExtendedStartingAddress = 0; + Dst->ExtendedEndingAddress = 0; + } else { + Dst->StartingAddress = 0xFFFFFFFF; + Dst->EndingAddress = 0xFFFFFFFF; + Dst->ExtendedStartingAddress = Src->StartingAddress; + Dst->ExtendedEndingAddress = Src->EndingAddress; + } + + Dst->PartitionWidth = Src->PartitionWidth; + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of System Boot Info, + SMBIOS type 32 +**/ +EFI_STATUS +BuildSmbiosSystemBootInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_SYSTEM_BOOT_INFO * Src; + SMBIOS_TABLE_TYPE32 * Dst; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED; + + Dst->BootStatus = Src->BootStatus; + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Ipmi Device Info, + SMBIOS type 38 +**/ +EFI_STATUS +BuildSmbiosIpmiDeviceInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_IPMI_DEVICE_INFO * Src; + SMBIOS_TABLE_TYPE38 * Dst; + UINTN Len; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED; + + // No strings + Len = Dst->Hdr.Length - sizeof (Dst->Hdr); + CopyMem (&Dst->InterfaceType, &Src->InterfaceType, Len); + + return EFI_SUCCESS; +} + +/** Set up the SMBIOS table of Onboard Devices Extended Info, + SMBIOS type 41 +**/ +EFI_STATUS +BuildSmbiosOnboardDevicesExtendedInfo ( + IN UINT16 Revision, + IN VOID * SrcObject, + OUT VOID * DstObject + ) +{ + CM_SMBIOS_ONBOARD_DEVICES_EXTENDED_INFO * Src; + SMBIOS_TABLE_TYPE41 * Dst; + CHAR8 * Strings; + UINT8 StrIndex; + UINTN Len; + UINTN Size; + + ASSERT (SrcObject != NULL); + ASSERT (DstObject != NULL); + + Src = SrcObject; + Dst = DstObject; + Dst->Hdr.Handle = SMBIOS_HANDLE_PI_RESERVED; + + Len = 0; + StrIndex = 0; + Strings = (CHAR8 *)(UINTN)Dst + Dst->Hdr.Length; + // Update strings + Len += SET_SMBIOS_TABLE_STRING (ReferenceDesignation); + + Size = sizeof (Dst->DeviceType) + + sizeof (Dst->DeviceTypeInstance) + + sizeof (Dst->SegmentGroupNum) + + sizeof (Dst->BusNum) + + sizeof (Dst->DevFuncNum); + CopyMem (&Dst->DeviceType, &Src->DeviceType, Size); + + return EFI_SUCCESS; +} diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.h b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.h new file mode 100644 index 0000000..835ff76 --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/BasicObjects.h @@ -0,0 +1,102 @@ +/** @file + Generator of basic SMBIOS tables + + Copyright (c) 2020, NVIDIA Corporation. All rights reserved. + Copyright (c) 2017 - 2020, ARM Limited. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef SMBIOS_BASIC_OBJECTS_H_ +#define SMBIOS_BASIC_OBJECTS_H_ + + +typedef EFI_STATUS (*SMBIOS_BUILD_OBJECT) ( + IN UINT16 TableRevision, + IN VOID * SrcObject, + OUT VOID * DstObject + ); + + +#pragma pack(1) + +typedef struct { + ESMBIOS_OBJECT_ID Id; + UINT16 Size; + UINT16 Count; + VOID * Data; +} CM_OBJECT_TYPE_INFO; + +// Helpful information to calculate the size of a particular SMBIOS table +typedef struct { + SMBIOS_TYPE Type; + UINT8 Length; + UINT8 NumStrings; +} SMBIOS_OBJECT_TYPE_INFO; + +typedef struct { + BOOLEAN IsMandatory; + SMBIOS_OBJECT_TYPE_INFO SmbiosObjectInfo; + CM_OBJECT_TYPE_INFO CmObjectInfo; + SMBIOS_BUILD_OBJECT BuildObject; + CONST CHAR16 * Description; +} SMBIOS_OBJECT_INFO; + + +#define CREATE_SMBIOS_OBJECT_INFO(HdrType, Mandatory, StrCnt, ObjName) \ +{ \ + .IsMandatory = (BOOLEAN)Mandatory, \ + .CmObjectInfo = { \ + .Id = ESmbiosObj##ObjName, \ + .Size = (UINT16)sizeof (struct CmSmbios##ObjName), \ + }, \ + .SmbiosObjectInfo = { \ + .Type = (SMBIOS_TYPE)HdrType, \ + .Length = (UINT8)sizeof (SMBIOS_TABLE_TYPE##HdrType), \ + .NumStrings = (UINT16)StrCnt, \ + }, \ + .BuildObject = BuildSmbios##ObjName, \ + .Description = L"Smbios" #ObjName , \ +} + +typedef struct { + CM_OBJECT_TOKEN RefToken; + SMBIOS_HANDLE Handle; +} SMBIOS_HANDLE_MAPPING; + +typedef struct { + SMBIOS_HANDLE_MAPPING * Table; + SMBIOS_HANDLE Base; + UINTN Count; +} SMBIOS_OBJECT_HANDLE; + +#pragma pack() + + +#define SHFT_1MB_BY_64KB (20-16) +#define SHFT_1GB_BY_64KB (30-16) +#define MASK_1MB_BY_64KB ((1 << SHFT_1MB_BY_64KB) - 1) +#define MASK_1GB_BY_64KB ((1 << SHFT_1GB_BY_64KB) - 1) + +#define SIZE_16MB_BY_64KB (1 << (24-16)) +#define SIZE_16GB_BY_64KB (1 << (34-16)) +#define SIZE_16TB_BY_64KB (1 << (44-16)) + + +#define SET_EXTENDED_BIOS_ROM_SIZE(Dst, Src, BiosSize, Granule) \ +{ \ + BiosSize = (Src->BiosSize >> SHFT_##Granule##_BY_64KB); \ + BiosSize = ((Src->BiosSize & MASK_##Granule##_BY_64KB) != 0) ? \ + (BiosSize + 1): (BiosSize); \ + Dst->BiosSize = 0xFF; \ + Dst->ExtendedBiosSize.Size = BiosSize; \ + Dst->ExtendedBiosSize.Unit = EFI_SMBIOS_EXTENDED_BIOS_ROM_SIZE_IN_##Granule;\ +} + +#define SET_SMBIOS_TABLE_STRING(Variable) \ + SetSmbiosTableString (&StrIndex, &Strings, &Dst->Variable, Src->Variable) + +#define GET_MAJOR_REV_NUM(Revision) ((Revision >> 8) & 0xFF) +#define GET_MINOR_REV_NUM(Revision) (Revision & 0xFF) + +#endif // SMBIOS_BASIC_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/SmbiosBasicLib.inf b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/SmbiosBasicLib.inf new file mode 100644 index 0000000..e5d7104 --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosBasicLib/SmbiosBasicLib.inf @@ -0,0 +1,39 @@ +## @file +# Basic Table Generator +# +# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. +# Copyright (c) 2017 - 2020, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = SmbiosBasicLib + FILE_GUID = aa8a7c50-2686-40b3-920a-af898a3213ad + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = SmbiosBasicLibConstructor + DESTRUCTOR = SmbiosBasicLibDestructor + +[Sources] + BasicGenerator.c + BasicObjects.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + +[Pcd] + +[Protocols] + +[Guids] + diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/RawGenerator.c b/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/RawGenerator.c new file mode 100644 index 0000000..7551c3f --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/RawGenerator.c @@ -0,0 +1,136 @@ +/** @file + MCFG Table Generator + + Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include + +// Module specific include files. +#include +#include +#include + +/** Construct the SMBIOS table using the SMBIOS table data provided. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the SMBIOS + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] SmbiosTableInfo Pointer to the SMBIOS Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed SMBIOS Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildRawTable ( + IN CONST SMBIOS_TABLE_GENERATOR * CONST This, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST SmbiosTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + OUT EFI_SMBIOS_TABLE_HEADER ** CONST Table + ) +{ + ASSERT (This != NULL); + ASSERT (SmbiosTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (Table != NULL); + ASSERT (SmbiosTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (SmbiosTableInfo->SmbiosTableData != NULL); + + if (SmbiosTableInfo->SmbiosTableData == NULL) { + *Table = NULL; + return EFI_INVALID_PARAMETER; + } + + *Table = SmbiosTableInfo->SmbiosTableData; + + return EFI_SUCCESS; +} + +/** This macro defines the Raw Generator revision. +*/ +#define RAW_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the Raw Table Generator. +*/ +STATIC +CONST +SMBIOS_TABLE_GENERATOR RawGenerator = { + // Generator ID + CREATE_STD_SMBIOS_TABLE_GEN_ID (EStdSmbiosTableIdRaw), + // Generator Description + L"SMBIOS.STD.RAW.GENERATOR", + // SMBIOS Table Revision supported by this Generator + 0, + // Minimum supported SMBIOS Table Revision + 0, + // SMBIOS Table Type + // 0, + // Build Table function + BuildRawTable, + // No additional resources are allocated by the generator. + // Hence the Free Resource function is not required. + NULL, + // Build TableEx function + NULL, + // Free Table ResourceEx + NULL, +}; + +/** 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 +EFIAPI +SmbiosRawLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable + ) +{ + EFI_STATUS Status; + Status = RegisterSmbiosTableGenerator (&RawGenerator); + DEBUG ((DEBUG_INFO, "RAW: 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 +EFIAPI +SmbiosRawLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE * SystemTable + ) +{ + EFI_STATUS Status; + Status = DeregisterSmbiosTableGenerator (&RawGenerator); + DEBUG ((DEBUG_INFO, "RAW: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf b/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf new file mode 100644 index 0000000..2350d09 --- /dev/null +++ b/DynamicTablesPkg/Library/Smbios/SmbiosRawLib/SmbiosRawLib.inf @@ -0,0 +1,36 @@ +## @file +# Raw Table Generator +# +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = SmbiosRawLib + FILE_GUID = a6a0a14e-9de7-40a1-b97b-06ee0a992b3c + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = SmbiosRawLibConstructor + DESTRUCTOR = SmbiosRawLibDestructor + +[Sources] + RawGenerator.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + BaseLib + +[Pcd] + +[Protocols] + +[Guids] + -- 2.7.4