|
@@ -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;
|
|
|
+}
|