diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc index 3e38fa0d0d..9d4312c4e8 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -18,6 +18,7 @@ SsdtPcieSupportLib|DynamicTablesPkg/Library/Common/SsdtPcieSupportLib/SsdtPcieSupportLib.inf SsdtSerialPortFixupLib|DynamicTablesPkg/Library/Common/SsdtSerialPortFixupLib/SsdtSerialPortFixupLib.inf TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf + SmbiosStringTableLib|DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf [Components.common] # diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec b/DynamicTablesPkg/DynamicTablesPkg.dec index adc2e67cbf..cfbcbb9569 100644 --- a/DynamicTablesPkg/DynamicTablesPkg.dec +++ b/DynamicTablesPkg/DynamicTablesPkg.dec @@ -1,7 +1,7 @@ ## @file # dec file for Dynamic Tables Framework. # -# Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -39,6 +39,9 @@ ## @libraryclass Defines a set of helper methods. TableHelperLib|Include/Library/TableHelperLib.h + ## @libraryclass Defines a set of SMBIOS string helper methods. + SmbiosStringTableLib|Include/Library/SmbiosStringTableLib.h + [Protocols] # Configuration Manager Protocol GUID gEdkiiConfigurationManagerProtocolGuid = { 0xd85a4835, 0x5a82, 0x4894, { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } } diff --git a/DynamicTablesPkg/DynamicTablesPkg.dsc b/DynamicTablesPkg/DynamicTablesPkg.dsc index 07cc837552..bd5084a900 100644 --- a/DynamicTablesPkg/DynamicTablesPkg.dsc +++ b/DynamicTablesPkg/DynamicTablesPkg.dsc @@ -2,7 +2,7 @@ # Dsc file for Dynamic Tables Framework. # # Copyright (c) 2019, Linaro Limited. All rights reserved.
-# Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2019 - 2022, Arm Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -46,6 +46,7 @@ DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParserLib.inf DynamicTablesPkg/Library/Common/DynamicPlatRepoLib/DynamicPlatRepoLib.inf + DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf [BuildOptions] *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES diff --git a/DynamicTablesPkg/Include/Library/SmbiosStringTableLib.h b/DynamicTablesPkg/Include/Library/SmbiosStringTableLib.h new file mode 100644 index 0000000000..fb183d427f --- /dev/null +++ b/DynamicTablesPkg/Include/Library/SmbiosStringTableLib.h @@ -0,0 +1,119 @@ +/** @file + SMBIOS String Table Helper library. + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef SMBIOS_STRING_TABLE_H_ +#define SMBIOS_STRING_TABLE_H_ + +/** A structure representing a string in the string table. +*/ +typedef struct StringElement { + /// Length of the string (does not include the NULL termination) + UINTN StringLen; + + /// Reference to the string + CONST CHAR8 *String; +} STRING_ELEMENT; + +/** A structure representing a string table. +*/ +typedef struct StringTable { + /// Count of strings in the table + UINT8 StrCount; + + /// Total length of all strings in the table (does not include + // the NULL termination for each string) + UINTN TotalStrLen; + + /// Maximum string count + UINT8 MaxStringElements; + + /// Pointer to the string table elements + STRING_ELEMENT *Elements; +} STRING_TABLE; + +/** Add a string to the string table + + @param[in] StrTable Pointer to the string table + @param[in] Str Pointer to the string + @param[out] StrRef Optional pointer to retrieve the string field + reference of the string in the string table + + @return EFI_SUCCESS Success + @return EFI_INVALID_PARAMETER Invalid string table pointer + @return EFI_BUFFER_TOO_SMALL Insufficient space to add string +**/ +EFI_STATUS +EFIAPI +StringTableAddString ( + IN STRING_TABLE *CONST StrTable, + IN CONST CHAR8 *Str, + OUT UINT8 *StrRef OPTIONAL + ); + +/** Returns the total size required to publish the strings to the SMBIOS + string area. + + @param[in] StrTable Pointer to the string table + + @return Total size required to publish the strings in the SMBIOS string area. +**/ +UINTN +EFIAPI +StringTableGetStringSetSize ( + IN STRING_TABLE *CONST StrTable + ); + +/** Iterate through the string table and publish the strings in the SMBIOS + string area. + + @param[in] StrTable Pointer to the string table + @param[in] SmbiosStringAreaStart Start address of the SMBIOS string area. + @param[in] SmbiosStringAreaSize Size of the SMBIOS string area. + + @return EFI_SUCCESS Success + @return EFI_INVALID_PARAMETER Invalid string table pointer + @return EFI_BUFFER_TOO_SMALL Insufficient space to publish strings +**/ +EFI_STATUS +EFIAPI +StringTablePublishStringSet ( + IN STRING_TABLE *CONST StrTable, + IN CHAR8 *CONST SmbiosStringAreaStart, + IN CONST UINTN SmbiosStringAreaSize + ); + +/** Initialise the string table and allocate memory for the string elements. + + @param[in] StrTable Pointer to the string table + @param[in] MaxStringElements Maximum number of strings that the string + table can hold. + + @return EFI_SUCCESS Success + @return EFI_INVALID_PARAMETER Invalid string table pointer + @return EFI_OUT_OF_RESOURCES Failed to allocate memory for string elements +**/ +EFI_STATUS +EFIAPI +StringTableInitialize ( + IN STRING_TABLE *CONST StrTable, + IN UINTN MaxStringElements + ); + +/** Free memory allocated for the string elements in the string table. + + @param[in] StrTable Pointer to the string table + + @return EFI_SUCCESS Success + @return EFI_INVALID_PARAMETER Invalid string table pointer or string elements +**/ +EFI_STATUS +EFIAPI +StringTableFree ( + IN STRING_TABLE *CONST StrTable + ); + +#endif // SMBIOS_STRING_TABLE_H_ diff --git a/DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.c b/DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.c new file mode 100644 index 0000000000..9eb4a7b22d --- /dev/null +++ b/DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.c @@ -0,0 +1,227 @@ +/** @file + SMBIOS String Table Helper + + Copyright (c) 2022, Arm Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - DSP0134 - SMBIOS Specification Version 3.6.0, 2022-06-17 +**/ + +#include +#include +#include +#include +#include + +/** Add a string to the string table. + + @param[in] StrTable Pointer to the string table + @param[in] Str Pointer to the string + @param[out] StrRef Optional pointer to retrieve the string field + reference of the string in the string table + + @return EFI_SUCCESS Success + @return EFI_INVALID_PARAMETER Invalid string table pointer + @return EFI_BUFFER_TOO_SMALL Insufficient space to add string +**/ +EFI_STATUS +EFIAPI +StringTableAddString ( + IN STRING_TABLE *CONST StrTable, + IN CONST CHAR8 *Str, + OUT UINT8 *StrRef OPTIONAL + ) +{ + UINTN StrLength; + STRING_ELEMENT *StrElement; + + if ((StrTable == NULL) || (Str == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (StrTable->StrCount >= StrTable->MaxStringElements) { + return EFI_BUFFER_TOO_SMALL; + } + + StrLength = AsciiStrLen (Str); + if (StrLength == 0) { + return EFI_INVALID_PARAMETER; + } + + // Update the string element + StrElement = &StrTable->Elements[StrTable->StrCount]; + StrElement->StringLen = StrLength; + StrElement->String = Str; + + // Update String table information + StrTable->TotalStrLen += StrLength; + StrTable->StrCount++; + + // Return the index of the string in the string table if requested + if (StrRef != NULL) { + // Note: SMBIOS string field references start at 1. So, return the + // StrCount as the string reference after it is updated. + *StrRef = StrTable->StrCount; + } + + return EFI_SUCCESS; +} + +/** Returns the total size required to publish the strings to the SMBIOS + string area. + + @param[in] StrTable Pointer to the string table + + @return Total size required to publish the strings in the SMBIOS string area. +**/ +UINTN +EFIAPI +StringTableGetStringSetSize ( + IN STRING_TABLE *CONST StrTable + ) +{ + if (StrTable == NULL) { + ASSERT (0); + return 0; + } + + // See Section 6.1.3 Text strings, SMBIOS Specification Version 3.6.0 + // - If the formatted portion of the structure contains string-reference + // fields and all the string fields are set to 0 (no string references), + // the formatted section of the structure is followed by two null (00h) + // BYTES. + // - Each string is terminated with a null (00h) BYTE + // - and the set of strings is terminated with an additional null (00h) BYTE. + + // Therefore, if string count = 0, return 2 + // if string count > 0, the string set size = + // StrTable->TotalStrLen (total length of the strings in the string table) + // + StrTable->StrCount (add string count to include '\0' for each string) + // +1 (an additional '\0' is required at the end of the string set). + return (StrTable->StrCount == 0) ? 2 : + (StrTable->TotalStrLen + StrTable->StrCount + 1); +} + +/** Iterate through the string table and publish the strings in the SMBIOS + string area. + + @param[in] StrTable Pointer to the string table + @param[in] SmbiosStringAreaStart Start address of the SMBIOS string area. + @param[in] SmbiosStringAreaSize Size of the SMBIOS string area. + + @return EFI_SUCCESS Success + @return EFI_INVALID_PARAMETER Invalid string table pointer + @return EFI_BUFFER_TOO_SMALL Insufficient space to publish strings +**/ +EFI_STATUS +EFIAPI +StringTablePublishStringSet ( + IN STRING_TABLE *CONST StrTable, + IN CHAR8 *CONST SmbiosStringAreaStart, + IN CONST UINTN SmbiosStringAreaSize + ) +{ + UINT8 Index; + STRING_ELEMENT *StrElement; + CHAR8 *SmbiosString; + UINTN BytesRemaining; + UINTN BytesCopied; + + if ((StrTable == NULL) || (SmbiosStringAreaStart == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (SmbiosStringAreaSize < StringTableGetStringSetSize (StrTable)) { + return EFI_BUFFER_TOO_SMALL; + } + + SmbiosString = SmbiosStringAreaStart; + BytesRemaining = SmbiosStringAreaSize; + + if (StrTable->StrCount == 0) { + // See Section 6.1.3 Text strings, SMBIOS Specification Version 3.6.0 + // If the formatted portion of the structure contains string-reference + // fields and all the string fields are set to 0 (no string references), + // the formatted section of the structure is followed by two null (00h) + // BYTES. + *SmbiosString++ = '\0'; + } else { + for (Index = 0; Index < StrTable->StrCount; Index++) { + StrElement = &StrTable->Elements[Index]; + AsciiStrCpyS (SmbiosString, BytesRemaining, StrElement->String); + + // See Section 6.1.3 Text strings, SMBIOS Specification Version 3.6.0 + // - Each string is terminated with a null (00h) BYTE + // Bytes Copied = String length + 1 for the string NULL terminator. + BytesCopied = StrElement->StringLen + 1; + BytesRemaining -= BytesCopied; + SmbiosString += BytesCopied; + } + } + + // See Section 6.1.3 Text strings, SMBIOS Specification Version 3.6.0 + // - the set of strings is terminated with an additional null (00h) BYTE. + *SmbiosString = '\0'; + return EFI_SUCCESS; +} + +/** Initialise the string table and allocate memory for the string elements. + + @param[in] StrTable Pointer to the string table + @param[in] MaxStringElements Maximum number of strings that the string + table can hold. + + @return EFI_SUCCESS Success + @return EFI_INVALID_PARAMETER Invalid string table pointer + @return EFI_OUT_OF_RESOURCES Failed to allocate memory for string elements +**/ +EFI_STATUS +EFIAPI +StringTableInitialize ( + IN STRING_TABLE *CONST StrTable, + IN UINTN MaxStringElements + ) +{ + STRING_ELEMENT *Elements; + + if ((StrTable == NULL) || (MaxStringElements > MAX_UINT8)) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (StrTable, sizeof (STRING_TABLE)); + + Elements = (STRING_ELEMENT *)AllocateZeroPool ( + sizeof (STRING_ELEMENT) * MaxStringElements + ); + if (Elements == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + StrTable->Elements = Elements; + StrTable->MaxStringElements = (UINT8)MaxStringElements; + return EFI_SUCCESS; +} + +/** Free memory allocated for the string elements in the string table. + + @param[in] StrTable Pointer to the string table + + @return EFI_SUCCESS Success + @return EFI_INVALID_PARAMETER Invalid string table pointer or string elements +**/ +EFI_STATUS +EFIAPI +StringTableFree ( + IN STRING_TABLE *CONST StrTable + ) +{ + if ((StrTable == NULL) || (StrTable->Elements == NULL)) { + return EFI_INVALID_PARAMETER; + } + + FreePool (StrTable->Elements); + ZeroMem (StrTable, sizeof (STRING_TABLE)); + return EFI_SUCCESS; +} diff --git a/DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf b/DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf new file mode 100644 index 0000000000..88624c50e3 --- /dev/null +++ b/DynamicTablesPkg/Library/Common/SmbiosStringTableLib/SmbiosStringTableLib.inf @@ -0,0 +1,25 @@ +## @file +# SMBIOS String Table Helper library. +# +# Copyright (c) 2022, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = SmbiosStringTableLib + FILE_GUID = 8C570DD8-531E-473F-85C6-9252746DBAC1 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = SmbiosStringTableLib + +[Sources] + SmbiosStringTableLib.c + +[Packages] + MdePkg/MdePkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + +[LibraryClasses] + BaseLib