From: "Chang, Abner via groups.io" <abner.chang=amd.com@groups.io>
To: <devel@edk2.groups.io>
Cc: Nickle Wang <nicklew@nvidia.com>, Igor Kulchytskyy <igork@ami.com>
Subject: [edk2-devel] [PATCH V3 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization
Date: Thu, 4 Apr 2024 18:17:53 +0800 [thread overview]
Message-ID: <20240404101758.84-2-abner.chang@amd.com> (raw)
In-Reply-To: <20240404101758.84-1-abner.chang@amd.com>
From: abnchang <abnchang@amd.com>
Build up the x-uefi-redfish string database for the Redfish confg
language searching, instead of using HII String protocol.
This can improve the time consumption lot on searching strings.
Signed-off-by: Abner Chang <abner.chang@amd.com>
Co-authored-by: Nickle Wang <nicklew@nvidia.com>
Cc: Igor Kulchytskyy <igork@ami.com>
Reviewed-by: Nickle Wang <nicklew@nvidia.com>
---
.../RedfishPlatformConfigImpl.h | 107 ++-
.../RedfishPlatformConfigDxe.c | 23 +-
.../RedfishPlatformConfigImpl.c | 819 +++++++++++++++++-
3 files changed, 877 insertions(+), 72 deletions(-)
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
index 9f4312decf5..8b8c544d58e 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
@@ -2,7 +2,8 @@
This file defines the EDKII Redfish Platform Config Protocol private structure.
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
- Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -30,6 +31,10 @@
#define ENGLISH_LANGUAGE_CODE "en-US"
#define X_UEFI_SCHEMA_PREFIX "x-uefi-redfish-"
+#define MAX_X_UEFI_REDFISH_STRING_SIZE (128 * 2)// 128 character in UCS.
+
+typedef struct _REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
+
//
// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
//
@@ -46,17 +51,49 @@ typedef struct {
CHAR8 **SchemaList; // Schema list
} REDFISH_PLATFORM_CONFIG_SCHEMA;
+// Defines the number of elements in array
+#define X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER 1024
+
+//
+// Definition of x-uefi-redfish string element.
+//
+typedef struct {
+ EFI_STRING_ID StringId;
+ CHAR16 *UcsString;
+} REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT;
+
+//
+// Discrete string array buffer, each has X_UEFI_REDFISH_STRING_ARRAY_NUMBER element.
+//
+typedef struct {
+ LIST_ENTRY NextArray;
+ REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT *ArrayEntryAddress;
+} REDFISH_X_UEFI_STRINGS_ARRAY;
+
+//
+// x-uefi-redfish string database, x-uefi-redfish language based.
+//
+typedef struct {
+ LIST_ENTRY NextXuefiRedfishLanguage; // Link to the next suppoted x-uefi-Redfish language.
+ CHAR8 *XuefiRedfishLanguage; // x-uefi-redfish language.
+ UINTN StringsArrayBlocks; // Number of the array blocks that accommodate X_UEFI_REDFISH_STRING_ARRAY_NUMBER
+ // elements in each.
+ LIST_ENTRY XuefiRedfishStringArrays; // Link entry of x-uefi-redfish string array.
+} REDFISH_X_UEFI_STRING_DATABASE;
+
//
// Definition of REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE
//
typedef struct {
LIST_ENTRY Link;
- HII_FORMSET *HiiFormSet; // Pointer to HII formset data.
- EFI_GUID Guid; // Formset GUID.
- EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
- LIST_ENTRY HiiFormList; // Form list that keep form data under this formset.
- CHAR16 *DevicePathStr; // Device path of this formset.
- REDFISH_PLATFORM_CONFIG_SCHEMA SupportedSchema; // Schema that is supported in this formset.
+ HII_FORMSET *HiiFormSet; // Pointer to HII formset data.
+ EFI_GUID Guid; // Formset GUID.
+ EFI_HII_HANDLE HiiHandle; // Hii Handle of this formset.
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader; // Hii Package list header.
+ LIST_ENTRY HiiFormList; // Form list that keep form data under this formset.
+ CHAR16 *DevicePathStr; // Device path of this formset.
+ REDFISH_PLATFORM_CONFIG_SCHEMA SupportedSchema; // Schema that is supported in this formset.
+ LIST_ENTRY XuefiRedfishStringDatabase; // x-uefi-redfish string/Id data base;
} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a) BASE_CR (a, REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE, Link)
@@ -90,19 +127,19 @@ typedef struct {
//
// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
//
-typedef struct {
+struct _REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE {
LIST_ENTRY Link;
REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *ParentForm;
- HII_STATEMENT *HiiStatement; // Pointer to HII statement data.
- EFI_QUESTION_ID QuestionId; // Question ID of this statement.
- EFI_STRING_ID Description; // String token of this question.
- EFI_STRING_ID Help; // String token of help message.
- EFI_STRING DesStringCache; // The string cache for search function.
- UINT8 Flags; // The statement flag.
- REDFISH_PLATFORM_CONFIG_STATEMENT_DATA StatementData; // The max/min for statement value.
- BOOLEAN Suppressed; // Statement is suppressed.
- BOOLEAN GrayedOut; // Statement is GrayedOut.
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
+ HII_STATEMENT *HiiStatement; // Pointer to HII statement data.
+ EFI_QUESTION_ID QuestionId; // Question ID of this statement.
+ EFI_STRING_ID Description; // String token of this question.
+ CHAR16 *XuefiRedfishStr; // x-uefi-redfish string of this question.
+ EFI_STRING_ID Help; // String token of help message.
+ UINT8 Flags; // The statement flag.
+ REDFISH_PLATFORM_CONFIG_STATEMENT_DATA StatementData; // The max/min for statement value.
+ BOOLEAN Suppressed; // Statement is suppressed.
+ BOOLEAN GrayedOut; // Statement is GrayedOut.
+};
#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a) BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
@@ -347,4 +384,38 @@ ReleaseStatementList (
IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList
);
+/**
+ Return the HII string length. We don't check word alignment
+ of the input string as the same as the checking in StrLen
+ function. Because the HII string in the database is compact
+ at the byte alignment.
+
+ @param[in] String Input UCS format string.
+
+ @retval Length of
+
+**/
+UINTN
+EFIAPI
+HiiStrLen (
+ IN CONST CHAR16 *String
+ );
+
+/**
+ Return the HII string size. We don't check word alignment
+ of the input string as the same as the checking in StrLen
+ function. Because the HII string in the database is compact
+ at the byte alignment.
+
+ @param[in] String Input UCS format string.
+
+ @retval Size of the string.
+
+**/
+UINTN
+EFIAPI
+HiiStrSize (
+ IN CONST CHAR16 *String
+ );
+
#endif
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
index f970e317b3f..0d1c96e7125 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
@@ -2,7 +2,8 @@
The implementation of EDKII Redfish Platform Config Protocol.
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
- Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -928,6 +929,10 @@ HiiStringToOneOfOptionValue (
Option = HII_QUESTION_OPTION_FROM_LINK (Link);
TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString == NULL) {
+ TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, ENGLISH_LANGUAGE_CODE, Option->Text);
+ }
+
if (TmpString != NULL) {
if (StrCmp (TmpString, HiiString) == 0) {
CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
@@ -1227,6 +1232,10 @@ HiiStringToOrderedListOptionValue (
Option = HII_QUESTION_OPTION_FROM_LINK (Link);
TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
+ if (TmpString == NULL) {
+ TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, ENGLISH_LANGUAGE_CODE, Option->Text);
+ }
+
if (TmpString != NULL) {
if (StrCmp (TmpString, HiiString) == 0) {
*Value = ExtendHiiValueToU64 (&Option->Value);
@@ -1491,7 +1500,7 @@ StrToAsciiStr (
return NULL;
}
- StringLen = StrLen (UnicodeString) + 1;
+ StringLen = HiiStrLen (UnicodeString) + 1;
Buffer = AllocatePool (StringLen * sizeof (CHAR8));
if (Buffer == NULL) {
return NULL;
@@ -2000,7 +2009,6 @@ RedfishPlatformConfigProtocolGetConfigureLang (
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST StatementList;
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
LIST_ENTRY *NextLink;
- EFI_STRING TmpString;
EFI_STRING *TmpConfigureLangList;
UINTN Index;
CHAR8 *FullSchema;
@@ -2054,12 +2062,9 @@ RedfishPlatformConfigProtocolGetConfigureLang (
ASSERT (StatementRef->Statement->Description != 0);
if (StatementRef->Statement->Description != 0) {
- TmpString = HiiGetRedfishString (StatementRef->Statement->ParentForm->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Description);
- ASSERT (TmpString != NULL);
- if (TmpString != NULL) {
- TmpConfigureLangList[Index] = TmpString;
- ++Index;
- }
+ ASSERT (StatementRef->Statement->XuefiRedfishStr != NULL);
+ TmpConfigureLangList[Index] = AllocateCopyPool (HiiStrSize (StatementRef->Statement->XuefiRedfishStr), (VOID *)StatementRef->Statement->XuefiRedfishStr);
+ ++Index;
}
}
}
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
index 47d35abc088..36e5da24f0a 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
@@ -3,6 +3,7 @@
(C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -143,6 +144,88 @@ DumpFormsetList (
return EFI_SUCCESS;
}
+/**
+ Return the HII string length. We don't check word alignment
+ of the input string as same as the checking in StrLen
+ function, because the HII string in the database is compact
+ at the byte alignment.
+
+ @param[in] String Input UCS format string.
+
+ @retval Length of the string.
+
+**/
+UINTN
+EFIAPI
+HiiStrLen (
+ IN CONST CHAR16 *String
+ )
+{
+ UINTN Length;
+
+ ASSERT (String != NULL);
+
+ for (Length = 0; *String != L'\0'; String++, Length++) {
+ }
+
+ return Length;
+}
+
+/**
+ Return the HII string size. We don't check word alignment
+ of the input string as same as the checking in StrLen
+ function, because the HII string in the database is compact
+ at the byte alignment.
+
+ @param[in] String Input UCS format string.
+
+ @retval Size of the string.
+
+**/
+UINTN
+EFIAPI
+HiiStrSize (
+ IN CONST CHAR16 *String
+ )
+{
+ return (HiiStrLen (String) + 1) * sizeof (*String);
+}
+
+/**
+ Compare two HII strings. We don't check word alignment
+ of the input string as same as the checking in StrLen
+ function, because the HII string in the database is compact
+ at the byte alignment.
+
+ @param[in] FirstString Input UCS format of string to search.
+ @param[in] SecondString Input UCS format of string to look for in
+ FirstString;
+
+ @retval 0 The strings are identical.
+ !0 The strings are not identical.
+
+**/
+INTN
+EFIAPI
+HiiStrCmp (
+ IN CONST CHAR16 *FirstString,
+ IN CONST CHAR16 *SecondString
+ )
+{
+ //
+ // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
+ //
+ ASSERT (HiiStrSize (FirstString) != 0);
+ ASSERT (HiiStrSize (SecondString) != 0);
+
+ while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
+ FirstString++;
+ SecondString++;
+ }
+
+ return *FirstString - *SecondString;
+}
+
/**
Delete a string from HII Package List by given HiiHandle.
@@ -301,28 +384,6 @@ HiiGetRedfishAsciiString (
return AsciiString;
}
-/**
- Get string from HII database in English language. The returned string is allocated
- using AllocatePool(). The caller is responsible for freeing the allocated buffer using
- FreePool().
-
- @param[in] HiiHandle A handle that was previously registered in the HII Database.
- @param[in] StringId The identifier of the string to retrieved from the string
- package associated with HiiHandle.
-
- @retval NULL The string specified by StringId is not present in the string package.
- @retval Other The string was returned.
-
-**/
-EFI_STRING
-HiiGetEnglishString (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_STRING_ID StringId
- )
-{
- return HiiGetRedfishString (HiiHandle, ENGLISH_LANGUAGE_CODE, StringId);
-}
-
/**
Get ASCII string from HII database in English language. The returned string is allocated
using AllocatePool(). The caller is responsible for freeing the allocated buffer using
@@ -562,7 +623,7 @@ GetStatementPrivateByConfigureLangRegex (
HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
if ((HiiStatementPrivate->Description != 0) && !HiiStatementPrivate->Suppressed) {
- TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
+ TmpString = HiiStatementPrivate->XuefiRedfishStr;
if (TmpString != NULL) {
Status = RegularExpressionProtocol->MatchString (
RegularExpressionProtocol,
@@ -592,8 +653,9 @@ GetStatementPrivateByConfigureLangRegex (
InsertTailList (&StatementList->StatementList, &StatementRef->Link);
++StatementList->Count;
}
-
- FreePool (TmpString);
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->XuefiRedfishStr is NULL, x-uefi-string has something wrong.\n", __func__));
+ ASSERT (FALSE);
}
}
@@ -676,14 +738,11 @@ GetStatementPrivateByConfigureLang (
);
if (HiiStatementPrivate->Description != 0) {
- TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
+ TmpString = HiiStatementPrivate->XuefiRedfishStr;
if (TmpString != NULL) {
- if (StrCmp (TmpString, ConfigureLang) == 0) {
- FreePool (TmpString);
+ if (HiiStrCmp (TmpString, ConfigureLang) == 0) {
return HiiStatementPrivate;
}
-
- FreePool (TmpString);
}
}
@@ -741,10 +800,74 @@ GetFormsetPrivateByHiiHandle (
return NULL;
}
+/**
+ Release x-uefi-string related information.
+
+ @param[in] FormsetPrivate Pointer to HII form-set private instance.
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseXuefiStringDatabase (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
+ )
+{
+ REDFISH_X_UEFI_STRING_DATABASE *ThisDatabase;
+ REDFISH_X_UEFI_STRING_DATABASE *PreDatabase;
+ REDFISH_X_UEFI_STRINGS_ARRAY *ThisStringArray;
+ REDFISH_X_UEFI_STRINGS_ARRAY *PreStringArray;
+ BOOLEAN EndDatabase;
+ BOOLEAN EndArray;
+
+ if (FormsetPrivate->HiiPackageListHeader != NULL) {
+ FreePool (FormsetPrivate->HiiPackageListHeader);
+ }
+
+ // Walk through x-uefi-redfish string database.
+ if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
+ EndDatabase = FALSE;
+ ThisDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
+ while (!EndDatabase) {
+ // Walk through string arrays.
+ if (!IsListEmpty (&ThisDatabase->XuefiRedfishStringArrays)) {
+ EndArray = FALSE;
+ ThisStringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&ThisDatabase->XuefiRedfishStringArrays);
+ while (!EndArray) {
+ // Remove this array
+ FreePool (ThisStringArray->ArrayEntryAddress);
+ EndArray = IsNodeAtEnd (&ThisDatabase->XuefiRedfishStringArrays, &ThisStringArray->NextArray);
+ PreStringArray = ThisStringArray;
+ if (!EndArray) {
+ ThisStringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&ThisDatabase->XuefiRedfishStringArrays, &ThisStringArray->NextArray);
+ }
+
+ RemoveEntryList (&PreStringArray->NextArray);
+ FreePool (PreStringArray);
+ }
+ }
+
+ //
+ // Remove this database
+ //
+ EndDatabase = IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &ThisDatabase->NextXuefiRedfishLanguage);
+ PreDatabase = ThisDatabase;
+ if (!EndDatabase) {
+ ThisDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&FormsetPrivate->XuefiRedfishStringDatabase, &ThisDatabase->NextXuefiRedfishLanguage);
+ }
+
+ RemoveEntryList (&PreDatabase->NextXuefiRedfishLanguage);
+ FreePool (PreDatabase);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
/**
Release formset and all the forms and statements that belong to this formset.
- @param[in] FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
+ @param[in] FormsetPrivate Pointer to HII form-set private instance.
@retval EFI_STATUS
@@ -779,12 +902,6 @@ ReleaseFormset (
//
// HiiStatementPrivate->HiiStatement will be released in DestroyFormSet().
//
-
- if (HiiStatementPrivate->DesStringCache != NULL) {
- FreePool (HiiStatementPrivate->DesStringCache);
- HiiStatementPrivate->DesStringCache = NULL;
- }
-
RemoveEntryList (&HiiStatementPrivate->Link);
FreePool (HiiStatementPrivate);
HiiStatementLink = HiiNextStatementLink;
@@ -821,6 +938,8 @@ ReleaseFormset (
FormsetPrivate->SupportedSchema.Count = 0;
}
+ ReleaseXuefiStringDatabase (FormsetPrivate);
+
return EFI_SUCCESS;
}
@@ -846,17 +965,606 @@ NewFormsetPrivate (
// Initial newly created formset private data.
//
InitializeListHead (&NewFormsetPrivate->HiiFormList);
+ InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);
return NewFormsetPrivate;
}
+/**
+ Create new x-uefi-redfish string array.
+
+ @param[in] XuefiRedfishStringDatabase The x-uefi-redfish string database.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory for creating a new array.
+ EFI_SUCCESS New array is created successfully.
+
+**/
+EFI_STATUS
+NewRedfishXuefiStringArray (
+ IN REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase
+ )
+{
+ REDFISH_X_UEFI_STRINGS_ARRAY *ArrayAddress;
+
+ // Initial first REDFISH_X_UEFI_STRINGS_ARRAY memory.
+ ArrayAddress = (REDFISH_X_UEFI_STRINGS_ARRAY *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRINGS_ARRAY));
+ if (ArrayAddress == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to allocate REDFISH_X_UEFI_STRINGS_ARRAY.\n", __func__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InitializeListHead (&ArrayAddress->NextArray);
+
+ // Allocate memory buffer for REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT elements.
+ ArrayAddress->ArrayEntryAddress = \
+ (REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT) * X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER);
+ if (ArrayAddress->ArrayEntryAddress == NULL) {
+ FreePool (ArrayAddress);
+ DEBUG ((DEBUG_ERROR, "%a: Failed to allocate array for REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENTs.\n", __func__));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ XuefiRedfishStringDatabase->StringsArrayBlocks++;
+ InsertTailList (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &ArrayAddress->NextArray);
+ return EFI_SUCCESS;
+}
+
+/**
+ Get the pointer of x-uefi-redfish database or create a new database.
+
+ @param[in] FormsetPrivate Pointer to HII form-set private instance.
+ @param[in] HiiStringPackageHeader HII string package header.
+
+ @retval Pointer to REDFISH_X_UEFI_STRING_DATABASE.
+ If NULL, it fails to obtain x-uefi-redfish database.
+
+**/
+REDFISH_X_UEFI_STRING_DATABASE *
+GetExitOrCreateXuefiStringDatabase (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
+ IN EFI_HII_STRING_PACKAGE_HDR *HiiStringPackageHeader
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN CreateNewOne;
+ REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase;
+
+ DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__));
+
+ CreateNewOne = TRUE;
+ XuefiRedfishStringDatabase = NULL;
+ if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
+ XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
+
+ while (TRUE) {
+ if (AsciiStriCmp (XuefiRedfishStringDatabase->XuefiRedfishLanguage, HiiStringPackageHeader->Language) == 0) {
+ CreateNewOne = FALSE;
+ break;
+ }
+
+ if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage)) {
+ break;
+ }
+
+ XuefiRedfishStringDatabase = \
+ (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
+ }
+ }
+
+ if (CreateNewOne) {
+ DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, " Creating x-uefi-redfish (%a) string database...\n", HiiStringPackageHeader->Language));
+ XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)AllocateZeroPool (sizeof (REDFISH_X_UEFI_STRING_DATABASE));
+ if (XuefiRedfishStringDatabase == NULL) {
+ DEBUG ((DEBUG_ERROR, " Failed to allocate REDFISH_X_UEFI_STRING_DATABASE.\n"));
+ return NULL;
+ }
+
+ InitializeListHead (&XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
+ InitializeListHead (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
+ XuefiRedfishStringDatabase->StringsArrayBlocks = 0;
+ XuefiRedfishStringDatabase->XuefiRedfishLanguage = HiiStringPackageHeader->Language;
+
+ Status = NewRedfishXuefiStringArray (XuefiRedfishStringDatabase);
+ if (EFI_ERROR (Status)) {
+ FreePool (XuefiRedfishStringDatabase);
+ return NULL;
+ }
+
+ DEBUG ((
+ REDFISH_PLATFORM_CONFIG_DEBUG,
+ " x-uefi-redfish (%a):\n String array is added to XuefiRedfishStringDatabase, total %d arrays now.\n",
+ XuefiRedfishStringDatabase->XuefiRedfishLanguage,
+ XuefiRedfishStringDatabase->StringsArrayBlocks
+ ));
+
+ // Link string database to FormsetPrivate.
+ InsertTailList (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage);
+ }
+
+ return XuefiRedfishStringDatabase;
+}
+
+/**
+ Check and allocate a new x-uefi-redfish array if it is insufficient for the
+ newly added x-uefi-redfish string.
+
+ @param[in] FormsetPrivate Pointer to HII form-set private instance.
+ @param[in] XuefiRedfishStringDatabase Pointer to the x-uefi-redfish database.
+ @param[in] StringId String ID added to database.
+
+ @retval EFI_SUCCESS The size of x-uefi-string array is adjusted or
+ is not required to be adjusted.
+ Otherwise, refer to the error code returned from NewRedfishXuefiStringArray().
+
+**/
+EFI_STATUS
+RedfishXuefiStringAdjustArrays (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
+ IN REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase,
+ IN EFI_STRING_ID StringId
+ )
+{
+ EFI_STATUS Status;
+
+ while (((StringId + X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) / X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) > (UINT16)XuefiRedfishStringDatabase->StringsArrayBlocks) {
+ Status = NewRedfishXuefiStringArray (XuefiRedfishStringDatabase);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to adjust x-uefi-string array", __func__));
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Insert a x-uefi-redfish string to database.
+
+ @param[in] FormsetPrivate Pointer to HII form-set private instance.
+ @param[in] HiiStringPackageHeader Pointer to HII string package.
+ @param[in] StringId The HII string ID
+ @param[in] StringTextPtr Pointer to HII string text.
+
+ @retval EFI_SUCCESS The HII string is added to database.
+ EFI_LOAD_ERROR Something wrong when insert an HII string
+ to database.
+
+**/
+EFI_STATUS
+RedfishXuefiStringInsertDatabase (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
+ IN EFI_HII_STRING_PACKAGE_HDR *HiiStringPackageHeader,
+ IN EFI_STRING_ID StringId,
+ IN CHAR16 *StringTextPtr
+ )
+{
+ EFI_STATUS Status;
+ UINTN StringIdOffset;
+ REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase;
+ REDFISH_X_UEFI_STRINGS_ARRAY *ThisArray;
+
+ XuefiRedfishStringDatabase = GetExitOrCreateXuefiStringDatabase (FormsetPrivate, HiiStringPackageHeader);
+ if (XuefiRedfishStringDatabase == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get REDFISH_X_UEFI_STRING_DATABASE of x-uefi-redfish language %a.\n", __func__, HiiStringPackageHeader->Language));
+ ReleaseXuefiStringDatabase (FormsetPrivate);
+ return EFI_LOAD_ERROR;
+ }
+
+ Status = RedfishXuefiStringAdjustArrays (FormsetPrivate, XuefiRedfishStringDatabase, StringId);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to adjust x-uefi-redfish string array.\n", __func__));
+ ReleaseXuefiStringDatabase (FormsetPrivate);
+ return EFI_LOAD_ERROR;
+ }
+
+ // Insert string to x-uefi-redfish string array.
+ StringIdOffset = (UINTN)StringId;
+ ThisArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
+ while (StringIdOffset >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
+ ThisArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &ThisArray->NextArray);
+ StringIdOffset -= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER;
+ }
+
+ // Insert string
+ (ThisArray->ArrayEntryAddress + StringIdOffset)->StringId = StringId;
+ (ThisArray->ArrayEntryAddress + StringIdOffset)->UcsString = StringTextPtr;
+
+ DEBUG ((
+ REDFISH_PLATFORM_CONFIG_DEBUG,
+ " Insert string ID: (%d) to database\n x-uefi-string: \"%s\"\n Language: %a.\n",
+ StringId,
+ StringTextPtr,
+ HiiStringPackageHeader->Language
+ ));
+ return EFI_SUCCESS;
+}
+
+/**
+ Get x-uefi-redfish string and language by string ID.
+
+ @param[in] FormsetPrivate Pointer to HII form-set private instance.
+ @param[in] HiiStringPackageHeader HII string package header.
+
+ @retval TRUE x-uefi-redfish string and ID map is inserted to database.
+ FALSE Something is wrong when insert x-uefi-redfish string and ID map.
+
+**/
+BOOLEAN
+CreateXuefiLanguageStringIdMap (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
+ IN EFI_HII_STRING_PACKAGE_HDR *HiiStringPackageHeader
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *BlockHdr;
+ EFI_STRING_ID CurrentStringId;
+ UINTN BlockSize;
+ UINTN Index;
+ UINT8 *StringTextPtr;
+ UINTN Offset;
+ UINT16 StringCount;
+ UINT16 SkipCount;
+ UINT8 Length8;
+ EFI_HII_SIBT_EXT2_BLOCK Ext2;
+ UINT32 Length32;
+ UINT8 *StringBlockInfo;
+
+ //
+ // Parse the string blocks to get the string text and font.
+ //
+ StringBlockInfo = (UINT8 *)((UINTN)HiiStringPackageHeader + HiiStringPackageHeader->StringInfoOffset);
+ BlockHdr = StringBlockInfo;
+ BlockSize = 0;
+ Offset = 0;
+ CurrentStringId = 1;
+ while (*BlockHdr != EFI_HII_SIBT_END) {
+ switch (*BlockHdr) {
+ case EFI_HII_SIBT_STRING_SCSU:
+ Offset = sizeof (EFI_HII_STRING_BLOCK);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRING_SCSU_FONT:
+ Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset + AsciiStrSize ((CHAR8 *)StringTextPtr);
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRINGS_SCSU:
+ CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
+ StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8));
+ BlockSize += StringTextPtr - BlockHdr;
+
+ for (Index = 0; Index < StringCount; Index++) {
+ BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
+ StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
+ CurrentStringId++;
+ }
+
+ break;
+
+ case EFI_HII_SIBT_STRINGS_SCSU_FONT:
+ CopyMem (
+ &StringCount,
+ (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
+ sizeof (UINT16)
+ );
+ StringTextPtr = (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8));
+ BlockSize += StringTextPtr - BlockHdr;
+
+ for (Index = 0; Index < StringCount; Index++) {
+ BlockSize += AsciiStrSize ((CHAR8 *)StringTextPtr);
+ StringTextPtr = StringTextPtr + AsciiStrSize ((CHAR8 *)StringTextPtr);
+ CurrentStringId++;
+ }
+
+ break;
+
+ case EFI_HII_SIBT_STRING_UCS2:
+ Offset = sizeof (EFI_HII_STRING_BLOCK);
+ StringTextPtr = BlockHdr + Offset;
+
+ // x-uefi-redfish string is always encoded as UCS and started with '/'.
+ if (*StringTextPtr == (UINT16)'/') {
+ Status = RedfishXuefiStringInsertDatabase (
+ FormsetPrivate,
+ HiiStringPackageHeader,
+ CurrentStringId,
+ (CHAR16 *)StringTextPtr
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to insert x-uefi-redfish string %s.\n", __func__, StringTextPtr));
+ return FALSE;
+ }
+ }
+
+ BlockSize += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr));
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRING_UCS2_FONT:
+ Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr));
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_STRINGS_UCS2:
+ Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset;
+ CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
+ for (Index = 0; Index < StringCount; Index++) {
+ BlockSize += HiiStrSize ((CHAR16 *)StringTextPtr);
+ StringTextPtr = StringTextPtr + HiiStrSize ((CHAR16 *)StringTextPtr);
+ CurrentStringId++;
+ }
+
+ break;
+
+ case EFI_HII_SIBT_STRINGS_UCS2_FONT:
+ Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
+ StringTextPtr = BlockHdr + Offset;
+ BlockSize += Offset;
+ CopyMem (
+ &StringCount,
+ (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
+ sizeof (UINT16)
+ );
+ for (Index = 0; Index < StringCount; Index++) {
+ BlockSize += HiiStrSize ((CHAR16 *)StringTextPtr);
+ StringTextPtr = StringTextPtr + HiiStrSize ((CHAR16 *)StringTextPtr);
+ CurrentStringId++;
+ }
+
+ break;
+
+ case EFI_HII_SIBT_DUPLICATE:
+ BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
+ CurrentStringId++;
+ break;
+
+ case EFI_HII_SIBT_SKIP1:
+ SkipCount = (UINT16)(*(UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
+ CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
+ BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
+ break;
+
+ case EFI_HII_SIBT_SKIP2:
+ CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
+ CurrentStringId = (UINT16)(CurrentStringId + SkipCount);
+ BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
+ break;
+
+ case EFI_HII_SIBT_EXT1:
+ CopyMem (
+ &Length8,
+ (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
+ sizeof (UINT8)
+ );
+ BlockSize += Length8;
+ break;
+
+ case EFI_HII_SIBT_EXT2:
+ CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
+ BlockSize += Ext2.Length;
+ break;
+
+ case EFI_HII_SIBT_EXT4:
+ CopyMem (
+ &Length32,
+ (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8)),
+ sizeof (UINT32)
+ );
+
+ BlockSize += Length32;
+ break;
+
+ default:
+ break;
+ }
+
+ BlockHdr = (UINT8 *)(StringBlockInfo + BlockSize);
+ }
+
+ return TRUE;
+}
+
+/**
+ Get x-uefi-redfish string and language by string ID.
+
+ @param[in] FormsetPrivate Pointer to HII form-set private instance.
+ @param[in] StringId The HII string ID.
+ @param[out] String Optionally return USC string.
+ @param[out] Language Optionally return x-uefi-redfish language.
+ @param[out] XuefiStringDatabase Optionally return x-uefi-redfish database.
+
+ @retval EFI_SUCCESS String information is returned.
+ EFI_INVALID_PARAMETER One of the given parameters to this function is
+ invalid.
+ EFI_NOT_FOUND String is not found.
+
+**/
+EFI_STATUS
+GetXuefiStringAndLangByStringId (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate,
+ IN EFI_STRING_ID StringId,
+ OUT CHAR16 **String OPTIONAL,
+ OUT CHAR8 **Language OPTIONAL,
+ OUT REDFISH_X_UEFI_STRING_DATABASE **XuefiStringDatabase OPTIONAL
+ )
+{
+ REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase;
+ REDFISH_X_UEFI_STRINGS_ARRAY *StringArray;
+ UINT16 StringIndex;
+
+ if ((String == NULL) && (Language == NULL) && (XuefiStringDatabase == NULL)) {
+ DEBUG ((DEBUG_ERROR, "%a: Invalid parameters for this function.\n", __func__));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
+ return EFI_NOT_FOUND;
+ }
+
+ XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&FormsetPrivate->XuefiRedfishStringDatabase);
+ while (TRUE) {
+ if (Language != NULL) {
+ *Language = XuefiRedfishStringDatabase->XuefiRedfishLanguage;
+ }
+
+ StringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays);
+
+ // Loop to the correct string array.
+ StringIndex = StringId;
+ while (StringIndex >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
+ if (IsNodeAtEnd (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray)) {
+ goto ErrorEixt;
+ }
+
+ StringArray = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray);
+ StringIndex -= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER;
+ }
+
+ //
+ // NOTE: The string ID in the formset is a unique number.
+ // If the string in the array is NULL, then the matched string ID
+ // should be in another x-uefi-redfish database.
+ //
+ if ((StringArray->ArrayEntryAddress + StringIndex)->UcsString != NULL) {
+ //
+ // String ID is belong to this x-uef-redfish language database.
+ //
+ if (String != NULL) {
+ *String = (StringArray->ArrayEntryAddress + StringIndex)->UcsString;
+ }
+
+ if (XuefiStringDatabase != NULL) {
+ *XuefiStringDatabase = XuefiRedfishStringDatabase;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage)) {
+ return EFI_NOT_FOUND;
+ }
+
+ XuefiRedfishStringDatabase = (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (
+ &FormsetPrivate->XuefiRedfishStringDatabase,
+ &XuefiRedfishStringDatabase->NextXuefiRedfishLanguage
+ );
+ }
+
+ErrorEixt:;
+ DEBUG ((DEBUG_ERROR, "%a: String ID (%d) is not in any x-uef-redfish string databases.\n", __func__, StringId));
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Build a x-uefi-redfish database for the newly added x-uefi-redfish language.
+
+ @param[in] FormsetPrivate Pointer to HII form-set private instance.
+
+**/
+VOID
+BuildXUefiRedfishStringDatabase (
+ IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ EFI_HII_PACKAGE_HEADER *PackageHeader;
+ UINTN EndingPackageAddress;
+ EFI_HII_STRING_PACKAGE_HDR *HiiStringPackageHeader;
+ UINTN SupportedSchemaLangCount;
+ CHAR8 **SupportedSchemaLang;
+ BOOLEAN StringIdMapIsBuilt;
+
+ DEBUG ((DEBUG_INFO, "%a: Building x-uefi-redfish string database, HII Formset GUID - %g.\n", __func__, FormsetPrivate->Guid));
+
+ BufferSize = 0;
+ Status = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ FormsetPrivate->HiiHandle,
+ &BufferSize,
+ FormsetPrivate->HiiPackageListHeader
+ );
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ DEBUG ((DEBUG_ERROR, " Failed to export package list.\n"));
+ return;
+ }
+
+ FormsetPrivate->HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *)AllocateZeroPool (BufferSize);
+ if (FormsetPrivate->HiiPackageListHeader == NULL) {
+ DEBUG ((DEBUG_ERROR, " Failed to allocate memory for the exported package list.\n"));
+ return;
+ }
+
+ Status = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
+ mRedfishPlatformConfigPrivate->HiiDatabase,
+ FormsetPrivate->HiiHandle,
+ &BufferSize,
+ FormsetPrivate->HiiPackageListHeader
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // Finding the string package.
+ //
+ EndingPackageAddress = (UINTN)FormsetPrivate->HiiPackageListHeader + FormsetPrivate->HiiPackageListHeader->PackageLength;
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *)(FormsetPrivate->HiiPackageListHeader + 1);
+ SupportedSchemaLang = FormsetPrivate->SupportedSchema.SchemaList;
+ while ((UINTN)PackageHeader < EndingPackageAddress) {
+ switch (PackageHeader->Type) {
+ case EFI_HII_PACKAGE_STRINGS:
+ StringIdMapIsBuilt = FALSE;
+ HiiStringPackageHeader = (EFI_HII_STRING_PACKAGE_HDR *)PackageHeader;
+
+ // Check if this is the string package for x-uefi-redfish
+ for (SupportedSchemaLangCount = 0;
+ SupportedSchemaLangCount < FormsetPrivate->SupportedSchema.Count;
+ SupportedSchemaLangCount++
+ )
+ {
+ if (AsciiStrnCmp (
+ *(SupportedSchemaLang + SupportedSchemaLangCount),
+ HiiStringPackageHeader->Language,
+ AsciiStrLen (HiiStringPackageHeader->Language)
+ ) == 0)
+ {
+ StringIdMapIsBuilt = CreateXuefiLanguageStringIdMap (FormsetPrivate, HiiStringPackageHeader);
+ break;
+ }
+ }
+
+ if (StringIdMapIsBuilt == FALSE) {
+ if (AsciiStrStr (HiiStringPackageHeader->Language, X_UEFI_SCHEMA_PREFIX) == NULL) {
+ DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, " No need to build x-uefi-redfish string ID map for HII language %a\n", HiiStringPackageHeader->Language));
+ } else {
+ DEBUG ((DEBUG_ERROR, " Failed to build x-uefi-redfish string ID map of HII language %a\n", HiiStringPackageHeader->Language));
+ }
+ }
+
+ default:
+ PackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)PackageHeader + PackageHeader->Length);
+ }
+ }
+}
+
/**
Load the HII formset from the given HII handle.
@param[in] HiiHandle Target HII handle to load.
@param[out] FormsetPrivate The formset private data.
- @retval EFI_STATUS
+ @retval EFI_STATUS The formset is loaded successfully.
+ @retval EFI_UNSUPPORTED This formset doesn't have any x-uefi-redfish configuration.
**/
EFI_STATUS
@@ -875,6 +1583,7 @@ LoadFormset (
REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
EFI_GUID ZeroGuid;
EXPRESS_RESULT ExpressionResult;
+ CHAR16 *String;
if ((HiiHandle == NULL) || (FormsetPrivate == NULL)) {
return EFI_INVALID_PARAMETER;
@@ -882,6 +1591,7 @@ LoadFormset (
HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
if (HiiFormSet == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: No memory resource for HII_FORMSET - %g\n", __func__, FormsetPrivate->Guid));
return EFI_OUT_OF_RESOURCES;
}
@@ -891,6 +1601,7 @@ LoadFormset (
ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
+ DEBUG ((DEBUG_ERROR, "%a: Formset not found by HII handle - %g\n", __func__, FormsetPrivate->Guid));
Status = EFI_NOT_FOUND;
goto ErrorExit;
}
@@ -909,7 +1620,11 @@ LoadFormset (
FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet->DevicePath, FALSE, FALSE);
Status = GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivate->SupportedSchema);
if (EFI_ERROR (Status)) {
- DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: No schema from HII handle: 0x%x found: %r\n", __func__, FormsetPrivate->HiiHandle, Status));
+ DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: No x-uefi-redfish configuration found on the formset - %g\n", __func__, FormsetPrivate->Guid));
+ return EFI_UNSUPPORTED; // Can't build AttributeRegistry Meni path with returning EFI_UNSUPPORTED.
+ } else {
+ // Building x-uefi-redfish string database
+ BuildXUefiRedfishStringDatabase (FormsetPrivate);
}
HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
@@ -919,6 +1634,7 @@ LoadFormset (
HiiFormPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
if (HiiFormPrivate == NULL) {
Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_CONFIG_FORM_PRIVATE.\n", __func__));
goto ErrorExit;
}
@@ -944,6 +1660,7 @@ LoadFormset (
HiiStatementPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
if (HiiStatementPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE.\n", __func__));
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
@@ -981,10 +1698,18 @@ LoadFormset (
}
}
- //
- // Attach to statement list.
- //
- InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
+ // Get x-uefi-redfish string using String ID.
+ Status = GetXuefiStringAndLangByStringId (FormsetPrivate, HiiStatementPrivate->Description, &String, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ HiiStatementPrivate->XuefiRedfishStr = String;
+ //
+ // Attach to statement list.
+ //
+ InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
+ } else {
+ FreePool (HiiStatementPrivate);
+ }
+
HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
}
@@ -1052,7 +1777,7 @@ LoadFormsetList (
//
Status = LoadFormset (HiiHandle, FormsetPrivate);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: failed to load formset: %r\n", __func__, Status));
+ DEBUG ((DEBUG_ERROR, "%a: Formset is not loaded for edk2 redfish: %r\n", __func__, Status));
FreePool (FormsetPrivate);
return Status;
}
@@ -1325,7 +2050,11 @@ ProcessPendingList (
Status = LoadFormsetList (Target->HiiHandle, FormsetList);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: load formset from HII handle: 0x%x failed: %r\n", __func__, Target->HiiHandle, Status));
+ if (Status == EFI_UNSUPPORTED) {
+ DEBUG ((DEBUG_ERROR, " The formset has no x-uefi-redfish configurations.\n"));
+ } else {
+ DEBUG ((DEBUG_ERROR, " load formset from HII handle: 0x%x failed: %r\n", Target->HiiHandle, Status));
+ }
}
}
--
2.37.1.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117425): https://edk2.groups.io/g/devel/message/117425
Mute This Topic: https://groups.io/mt/105326104/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2024-04-04 10:18 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-04 10:17 [edk2-devel] [PATCH V3 0/6] Config language searching algorithm enhancement and the bug fixes Chang, Abner via groups.io
2024-04-04 10:17 ` Chang, Abner via groups.io [this message]
2024-04-04 13:34 ` [edk2-devel] [PATCH V3 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization Igor Kulchytskyy via groups.io
2024-04-04 10:17 ` [edk2-devel] [PATCH V3 2/6] RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro Chang, Abner via groups.io
2024-04-04 13:33 ` Igor Kulchytskyy via groups.io
2024-04-04 10:17 ` [edk2-devel] [PATCH V3 3/6] RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support Chang, Abner via groups.io
2024-04-04 13:33 ` Igor Kulchytskyy via groups.io
2024-04-04 10:17 ` [edk2-devel] [PATCH V3 4/6] RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted unexpectedly Chang, Abner via groups.io
2024-04-04 13:34 ` Igor Kulchytskyy via groups.io
2024-04-04 10:17 ` [edk2-devel] [PATCH V3 5/6] EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs Chang, Abner via groups.io
2024-04-04 10:17 ` [edk2-devel] [PATCH V3 6/6] RedfishPkg/RedfishPlatformConfigDxe: support menu path report Chang, Abner via groups.io
2024-04-04 13:34 ` Igor Kulchytskyy via groups.io
2024-04-04 13:33 ` [edk2-devel] [PATCH V3 0/6] Config language searching algorithm enhancement and the bug fixes Igor Kulchytskyy via groups.io
2024-04-04 14:26 ` Chang, Abner via groups.io
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240404101758.84-2-abner.chang@amd.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox