DynamicTablesPkg: Add SMBIOS String table helper library

The Section 6.1.3, SMBIOS specification version 3.6.0 describes the
handling of test strings in SMBIOS tables.

Text strings are added at the end of the formatted portion of the SMBIOS
structure and are referenced by index in the SMBIOS structure.

Therefore, introduce a SmbiosStringTableLib to simplify the publishing
of the string set.

SmbiosStringTableLib introduces a concept of string table which records
the references to the SMBIOS strings as they are added and returns an
string reference which is then assigned to the string field in the
formatted portion of the SMBIOS structure. Once all strings are added,
the library provides an interface to get the required size for the string
set. This allows sufficient memory to be allocated for the SMBIOS table.
The library also provides an interface to publish the string set in
accordance with the SMBIOS specification.

Example:
EFI_STATUS
BuildSmbiosType17Table () {
  STRING_TABLE         StrTable;
  UINT8                DevLocatorRef;
  UINT8                BankLocatorRef;
  SMBIOS_TABLE_TYPE17  *SmbiosRecord;
  CHAR8                *StringSet;
  ...

  // Initialize string table for 7 strings
  StringTableInitialize (&StrTable, 7);

  StringTableAddString (&StrTable, "SIMM 3", &DevLocatorRef);
  StringTableAddString (&StrTable, "Bank 0", &BankLocatorRef);
  ...

  SmbiosRecord = AllocateZeroPool (
                   sizeof (SMBIOS_TABLE_TYPE17) +
                     StringTableGetStringSetSize (&StrTable)
                   );
  ...
  SmbiosRecord->DeviceLocator = DevLocatorRef;
  SmbiosRecord->BankLocator = BankLocatorRef;
  ...
  // get the string set area
  StringSet = (CHAR8*)(SmbiosRecord + 1);

  // publish the string set
  StringTablePublishStringSet (
    &StrTable,
    StringSet,
    StringTableGetStringSetSize (&StrTable)
    );

  // free string table
  StringTableFree (&StrTable);

  return EFI_SUCCESS;
}

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Reviewed-by: Pierre Gondois <pierre.gondois@arm.com>
Cc: Alexei Fedorov <Alexei.Fedorov@arm.com>
Cc: Pierre Gondois <pierre.gondois@arm.com>
Cc: Girish Mahadevan <gmahadevan@nvidia.com>
Cc: Jeff Brasen <jbrasen@nvidia.com>
Cc: Ashish Singhal <ashishsingha@nvidia.com>
Cc: Nick Ramirez <nramirez@nvidia.com>
Cc: William Watson <wwatson@nvidia.com>
Cc: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com>
This commit is contained in:
Sami Mujawar 2022-09-08 18:35:50 +01:00 committed by mergify[bot]
parent a4c9c2b0f0
commit 9b94ebb0c8
6 changed files with 378 additions and 2 deletions

View File

@ -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]
#

View File

@ -1,7 +1,7 @@
## @file
# dec file for Dynamic Tables Framework.
#
# Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>
# Copyright (c) 2017 - 2022, Arm Limited. All rights reserved.<BR>
#
# 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 } }

View File

@ -2,7 +2,7 @@
# Dsc file for Dynamic Tables Framework.
#
# Copyright (c) 2019, Linaro Limited. All rights reserved.<BR>
# Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.<BR>
# Copyright (c) 2019 - 2022, Arm Limited. All rights reserved.<BR>
#
# 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

View File

@ -0,0 +1,119 @@
/** @file
SMBIOS String Table Helper library.
Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
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_

View File

@ -0,0 +1,227 @@
/** @file
SMBIOS String Table Helper
Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@par Reference(s):
- DSP0134 - SMBIOS Specification Version 3.6.0, 2022-06-17
**/
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/SmbiosStringTableLib.h>
/** 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;
}

View File

@ -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