mirror of https://github.com/acidanthera/audk.git
228 lines
7.1 KiB
C
228 lines
7.1 KiB
C
/** @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;
|
|
}
|