public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes
@ 2024-03-26 15:14 Chang, Abner via groups.io
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization Chang, Abner via groups.io
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-03-26 15:14 UTC (permalink / raw)
  To: devel; +Cc: Nickle Wang, Igor Kulchytskyy

From: Abner Chang <abner.chang@amd.com>

PR # 5491

In V2, add patch 6/6 contibuted by Nvidia for updating BIOS
menu path implementation based on the performance improvement.

In this patch set,
1 We enhance the config language searching algorithm.
  As the performance of searching config language using HII GetString is
  pretty slow. For the example, 1800 HII BIOS options takes over 30 mins
  to build up the metadata required for Redfish BIOS resource. With this
  improvement, it only takes 4 seconds.

2.Introduce the Redfish debug framework, there are three edk2 Redfish
  debug scopes.
  a. PcdDebugPrintErrorLevel, DEBUG_MANAGEABILITY to enable debug message
     for edk2 Redfish.
  b. PcdRedfishDebugCategory, enablement of individule edk2 Redfish
     component. Currently we only support RedfishPlatformConfigDxe
     module.
  c. PcdRedfishPlatformConfigDebugProperty, edk2 Redfish module debug
     scope. This PCD is used by RedfishPlatformConfigDxe debug enablement.

3 This patch set also fixes an issue that deletes HII string unexpectedly.

Signed-off-by: Abner Chang <abner.chang@amd.com>
Co-authored-by: Nickle Wang <nicklew@nvidia.com>
Cc: Igor Kulchytskyy <igork@ami.com>

Abner Chang (4):
  RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro
  RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support
  RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted
    unexpectedly
  EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs

Nickle Wang (1):
  RedfishPkg/RedfishPlatformConfigDxe: support menu path report

abnchang (1):
  RedfishPkg/RedfishPlatformConfigDxe: Config language searching
    optimization

 RedfishPkg/RedfishPkg.dec                     |  24 +
 EmulatorPkg/EmulatorPkg.dsc                   |  21 +
 .../RedfishDebugLib/RedfishDebugLib.inf       |   4 +
 .../RedfishPlatformConfigDxe.inf              |   8 +
 RedfishPkg/Include/Library/RedfishDebugLib.h  |  43 +-
 .../RedfishPlatformConfigDxe.h                |  48 +-
 .../RedfishPlatformConfigImpl.h               | 135 ++-
 .../Library/RedfishDebugLib/RedfishDebugLib.c |  55 +-
 .../RedfishPlatformConfigCapability.c         |  58 ++
 .../RedfishPlatformConfigDxe.c                |  89 +-
 .../RedfishPlatformConfigImpl.c               | 928 ++++++++++++++++--
 11 files changed, 1240 insertions(+), 173 deletions(-)
 create mode 100644 RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c

-- 
2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117122): https://edk2.groups.io/g/devel/message/117122
Mute This Topic: https://groups.io/mt/105159781/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization
  2024-03-26 15:14 [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Chang, Abner via groups.io
@ 2024-03-26 15:14 ` Chang, Abner via groups.io
  2024-03-27  2:40   ` Nickle Wang via groups.io
                     ` (2 more replies)
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 2/6] RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro Chang, Abner via groups.io
                   ` (5 subsequent siblings)
  6 siblings, 3 replies; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-03-26 15:14 UTC (permalink / raw)
  To: devel; +Cc: Nickle Wang, Igor Kulchytskyy

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>
---
 .../RedfishPlatformConfigImpl.h               | 107 ++-
 .../RedfishPlatformConfigDxe.c                |  23 +-
 .../RedfishPlatformConfigImpl.c               | 820 +++++++++++++++++-
 3 files changed, 878 insertions(+), 72 deletions(-)

diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
index 9f4312decf5..6e6c7fdb8a9 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                                    *DescriptionStr;  // 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..664b48eb50e 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->DescriptionStr != NULL);
+        TmpConfigureLangList[Index] = AllocateCopyPool (HiiStrSize (StatementRef->Statement->DescriptionStr), (VOID *)StatementRef->Statement->DescriptionStr);
+        ++Index;
       }
     }
   }
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
index 47d35abc088..8b1ddf4360a 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->DescriptionStr;
           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->DescriptionStr 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->DescriptionStr;
           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,607 @@ NewFormsetPrivate (
   // Initial newly created formset private data.
   //
   InitializeListHead (&NewFormsetPrivate->HiiFormList);
+  InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);
 
   return NewFormsetPrivate;
 }
 
+/**
+  Create new x-uefi-redfish string array.
+
+  @param[in]      FormsetPrivate              Pointer to HII form-set private instance.
+  @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_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
+  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 (FormsetPrivate, 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 (FormsetPrivate, 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__));
+    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 +1584,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 +1592,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 +1602,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 +1621,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 +1635,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 +1661,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 +1699,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->DescriptionStr = String;
+        //
+        // Attach to statement list.
+        //
+        InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
+      } else {
+        FreePool (HiiStatementPrivate);
+      }
+
       HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
     }
 
@@ -1052,7 +1778,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 +2051,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 (#117123): https://edk2.groups.io/g/devel/message/117123
Mute This Topic: https://groups.io/mt/105159783/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [edk2-devel] [PATCH V2 2/6] RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro
  2024-03-26 15:14 [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Chang, Abner via groups.io
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization Chang, Abner via groups.io
@ 2024-03-26 15:14 ` Chang, Abner via groups.io
  2024-03-27  7:38   ` Nickle Wang via groups.io
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 3/6] RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support Chang, Abner via groups.io
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-03-26 15:14 UTC (permalink / raw)
  To: devel; +Cc: Nickle Wang, Igor Kulchytskyy

From: Abner Chang <abner.chang@amd.com>

Introduce DEBUG_REDFISH macro for the debug message
of edk2 Redfish components.
DEBUG_REDFISH can be used in any edk2 Redfish component
with Redfish DebugCatagory as the first parameter.
Whether the debug message is output or not depends on
the platform setting of PcdRedfishDebugCatagory.

Signed-off-by: Abner Chang <abner.chang@amd.com>
Cc: Nickle Wang <nicklew@nvidia.com>
Cc: Igor Kulchytskyy <igork@ami.com>
---
 RedfishPkg/RedfishPkg.dec                     |  9 +++
 .../RedfishDebugLib/RedfishDebugLib.inf       |  4 ++
 RedfishPkg/Include/Library/RedfishDebugLib.h  | 43 +++++++++++----
 .../Library/RedfishDebugLib/RedfishDebugLib.c | 55 ++++---------------
 4 files changed, 57 insertions(+), 54 deletions(-)

diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
index 1a9c9ed7bc5..a9665ff68ef 100644
--- a/RedfishPkg/RedfishPkg.dec
+++ b/RedfishPkg/RedfishPkg.dec
@@ -5,6 +5,7 @@
 # (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
 # Copyright (c) 2023, American Megatrends International LLC.
 # Copyright (c) 2023-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
 ##
@@ -184,3 +185,11 @@
   gEfiRedfishPkgTokenSpaceGuid.PcdHttpRetryWaitInSecond|1|UINT16|0x00001010
   ## This is used to disable Redfish HTTP cache function and every request will be sent to Redfish service.
   gEfiRedfishPkgTokenSpaceGuid.PcdHttpCacheDisabled|FALSE|BOOLEAN|0x00001011
+  #
+  # Redfish debug catagories
+  # To enable the debug message for the entire edk2 Redfish implementation, below PCDs must be set.
+  # DEBUG_MANAGEABILITY must be set PcdDebugPrintErrorLevel.
+  #
+  #   0x0000000000000001  RedfishPlatformConfigDxe driver debug enabled.
+  #
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory|0|UINT64|0x00001012
diff --git a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf
index d468bb213b6..42ff321b48e 100644
--- a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf
+++ b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf
@@ -2,6 +2,7 @@
 #  INF file for Redfish debug library.
 #
 #  Copyright (c) 2023-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
 #
@@ -35,5 +36,8 @@
   RedfishHttpLib
   UefiLib
 
+[FixedPcd]
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory
+
 [Depex]
   TRUE
diff --git a/RedfishPkg/Include/Library/RedfishDebugLib.h b/RedfishPkg/Include/Library/RedfishDebugLib.h
index ad7a6975867..19e5a895cc8 100644
--- a/RedfishPkg/Include/Library/RedfishDebugLib.h
+++ b/RedfishPkg/Include/Library/RedfishDebugLib.h
@@ -2,6 +2,7 @@
   This file defines the Redfish debug library interface.
 
   Copyright (c) 2023-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
 
@@ -11,28 +12,48 @@
 #define REDFISH_DEBUG_LIB_H_
 
 #include <Uefi.h>
+#include <Library/DebugLib.h>
 #include <RedfishServiceData.h>
 #include <Library/HiiUtilityLib.h>
 #include <Library/JsonLib.h>
 
 #include <Protocol/EdkIIRedfishPlatformConfig.h>
 
-#define DEBUG_REDFISH_NETWORK         DEBUG_MANAGEABILITY   ///< Debug error level for Redfish networking function
-#define DEBUG_REDFISH_HOST_INTERFACE  DEBUG_MANAGEABILITY   ///< Debug error level for Redfish networking function
+// Used with MdePKg DEBUG macro.
+#define DEBUG_REDFISH_NETWORK          DEBUG_MANAGEABILITY          ///< Debug error level for Redfish networking function
+#define DEBUG_REDFISH_HOST_INTERFACE   DEBUG_MANAGEABILITY          ///< Debug error level for Redfish Host INterface
+#define DEBUG_REDFISH_PLATFORM_CONFIG  DEBUG_MANAGEABILITY          ///< Debug error level for Redfish Platform Configure Driver
+
+//
+// Definitions of Redfish debug capability in Redfish component scope, used with DEBUG_REDFISH macro
+// For example, Redfish Platform Config Driver
+//   DEBUG_REDFISH(DEBUG_REDFISH_PLATFORM_CONFIG_DXE, ...)
+//
+#define DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE  0x00000001
+
+#define DEBUG_REDFISH(DebugCategory, ...) \
+    do {                                                \
+      if (!DebugPrintEnabled()) {                       \
+        break;                                          \
+      }                                                 \
+      if (!DebugRedfishComponentEnabled (DebugCategory)) { \
+        break;                                             \
+      }                                                    \
+      DEBUG ((DEBUG_MANAGEABILITY, ##__VA_ARGS__));       \
+    } while (FALSE)
 
 /**
-  Debug print the value of StatementValue.
+  Determine whether the Redfish debug category is enabled in
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory.
 
-  @param[in]  ErrorLevel     DEBUG macro error level.
-  @param[in]  StatementValue The statement value to print.
+  @param[in]  DebugCategory  Redfish debug category.
 
-  @retval     EFI_SUCCESS            StatementValue is printed.
-  @retval     EFI_INVALID_PARAMETER  StatementValue is NULL.
+  @retval     TRUE   This debug category is enabled.
+  @retval     FALSE  This debug category is disabled..
 **/
-EFI_STATUS
-DumpHiiStatementValue (
-  IN UINTN                ErrorLevel,
-  IN HII_STATEMENT_VALUE  *StatementValue
+BOOLEAN
+DebugRedfishComponentEnabled (
+  IN  UINT64  DebugCategory
   );
 
 /**
diff --git a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
index 8b0425b8c3b..f8bb51ff532 100644
--- a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
+++ b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
@@ -2,6 +2,7 @@
   Redfish debug library to debug Redfish application.
 
   Copyright (c) 2023-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
 
@@ -25,55 +26,23 @@
 #define REDFISH_PRINT_BUFFER_BYTES_PER_ROW  16
 
 /**
-  Debug print the value of StatementValue.
+  Determine whether the Redfish debug category is enabled in
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory.
 
-  @param[in]  ErrorLevel     DEBUG macro error level.
-  @param[in]  StatementValue The statement value to print.
+  @param[in]  RedfishDebugCategory  Redfish debug category.
 
-  @retval     EFI_SUCCESS            StatementValue is printed.
-  @retval     EFI_INVALID_PARAMETER  StatementValue is NULL.
+  @retval     TRUE   This debug category is enabled.
+  @retval     FALSE  This debug category is disabled..
 **/
-EFI_STATUS
-DumpHiiStatementValue (
-  IN UINTN                ErrorLevel,
-  IN HII_STATEMENT_VALUE  *StatementValue
+BOOLEAN
+DebugRedfishComponentEnabled (
+  IN  UINT64  RedfishDebugCategory
   )
 {
-  if (StatementValue == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
+  UINT64  DebugCategory;
 
-  DEBUG ((ErrorLevel, "BufferValueType: 0x%x\n", StatementValue->BufferValueType));
-  DEBUG ((ErrorLevel, "BufferLen: 0x%x\n", StatementValue->BufferLen));
-  DEBUG ((ErrorLevel, "Buffer:    0x%p\n", StatementValue->Buffer));
-  DEBUG ((ErrorLevel, "Type:      0x%p\n", StatementValue->Type));
-
-  switch (StatementValue->Type) {
-    case EFI_IFR_TYPE_NUM_SIZE_8:
-      DEBUG ((ErrorLevel, "Value:     0x%x\n", StatementValue->Value.u8));
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_16:
-      DEBUG ((ErrorLevel, "Value:     0x%x\n", StatementValue->Value.u16));
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_32:
-      DEBUG ((ErrorLevel, "Value:     0x%x\n", StatementValue->Value.u32));
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_64:
-      DEBUG ((ErrorLevel, "Value:     0x%lx\n", StatementValue->Value.u64));
-      break;
-    case EFI_IFR_TYPE_BOOLEAN:
-      DEBUG ((ErrorLevel, "Value:     %a\n", (StatementValue->Value.b ? "true" : "false")));
-      break;
-    case EFI_IFR_TYPE_STRING:
-      DEBUG ((ErrorLevel, "Value:     0x%x\n", StatementValue->Value.string));
-      break;
-    case EFI_IFR_TYPE_TIME:
-    case EFI_IFR_TYPE_DATE:
-    default:
-      break;
-  }
-
-  return EFI_SUCCESS;
+  DebugCategory = FixedPcdGet64 (PcdRedfishDebugCategory);
+  return ((DebugCategory & RedfishDebugCategory) != 0);
 }
 
 /**
-- 
2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117124): https://edk2.groups.io/g/devel/message/117124
Mute This Topic: https://groups.io/mt/105159784/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [edk2-devel] [PATCH V2 3/6] RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support
  2024-03-26 15:14 [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Chang, Abner via groups.io
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization Chang, Abner via groups.io
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 2/6] RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro Chang, Abner via groups.io
@ 2024-03-26 15:14 ` Chang, Abner via groups.io
  2024-03-27  7:38   ` Nickle Wang via groups.io
  2024-03-26 15:15 ` [edk2-devel] [PATCH V2 4/6] RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted unexpectedly Chang, Abner via groups.io
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-03-26 15:14 UTC (permalink / raw)
  To: devel; +Cc: Nickle Wang, Igor Kulchytskyy

From: Abner Chang <abner.chang@amd.com>

Add RedfishPlatformConfigDxe debug capability that aligns
with edk2 Redfish debug mechanism.

- PcdRedfishPlatformConfigDebugProperty, add PCD to control
  RedfishPlatformConfigDxe subordinate of Redfish debug
  capabilities.
- PcdRedfishPlatformConfigFeatureProperty, add PCD to
  manage RedfishPlatformConfigDxe features.

Signed-off-by: Abner Chang <abner.chang@amd.com>
Co-authored-by: Nickle Wang <nicklew@nvidia.com>
Cc: Igor Kulchytskyy <igork@ami.com>
---
 RedfishPkg/RedfishPkg.dec                     |  15 +++
 .../RedfishPlatformConfigDxe.inf              |   8 ++
 .../RedfishPlatformConfigDxe.h                |  46 +++++++-
 .../RedfishPlatformConfigImpl.h               |  28 +++++
 .../RedfishPlatformConfigCapability.c         |  58 ++++++++++
 .../RedfishPlatformConfigDxe.c                |  59 +++++++---
 .../RedfishPlatformConfigImpl.c               | 107 +++++++++++-------
 7 files changed, 262 insertions(+), 59 deletions(-)
 create mode 100644 RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c

diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
index a9665ff68ef..c048e43f53b 100644
--- a/RedfishPkg/RedfishPkg.dec
+++ b/RedfishPkg/RedfishPkg.dec
@@ -193,3 +193,18 @@
   #   0x0000000000000001  RedfishPlatformConfigDxe driver debug enabled.
   #
   gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory|0|UINT64|0x00001012
+  #
+  # Redfish RedfishPlatformConfigDxe Debug Properties
+  #   0x00000001  x-uefi-redfish string database message enabled
+  #   0x00000002  Debug Message for dumping formset
+  #   0x00000004  Debug Message for x-uefi-redfish searching result
+  #   0x00000008  Debug Message for x-uefi-redfish Regular Expression searching result
+  #
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigDebugProperty|0|UINT32|0x00001013
+  #
+  # RedfishPlatformConfigDxe feature enablement
+  #   0x00000001  Enable building Redfish Attribute Registry menu path.
+  #   0x00000002  Allow supressed HII option to be exposed on Redfish.
+  #
+  # Redfish RedfishPlatformConfigDxe feature Properties
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty|0|UINT32|0x00001014
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
index 5a249c8c3bc..2db47c2cffc 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
@@ -3,6 +3,7 @@
 #
 #  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
 #  Copyright (c) 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
 #
@@ -23,6 +24,7 @@
   RedfishPkg/RedfishPkg.dec
 
 [Sources]
+  RedfishPlatformConfigCapability.c
   RedfishPlatformConfigDxe.h
   RedfishPlatformConfigDxe.c
   RedfishPlatformConfigImpl.h
@@ -36,7 +38,9 @@
   HiiLib
   HiiUtilityLib
   MemoryAllocationLib
+  PcdLib
   PrintLib
+  RedfishDebugLib
   UefiLib
   UefiBootServicesTableLib
   UefiRuntimeServicesTableLib
@@ -51,5 +55,9 @@
 [Guids]
   gEfiRegexSyntaxTypePerlGuid             ## CONSUMED
 
+[FixedPcd]
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigDebugProperty
+
 [Depex]
   TRUE
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
index 38adea04c5b..688f2067bff 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
@@ -3,6 +3,7 @@
 
   (C) Copyright 2021 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
 
@@ -20,7 +21,9 @@
 #include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
 #include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
 #include <Library/PrintLib.h>
+#include <Library/RedfishDebugLib.h>
 #include <Library/UefiLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiDriverEntryPoint.h>
@@ -37,6 +40,41 @@
 //
 #include <Protocol/EdkIIRedfishPlatformConfig.h>
 
+//
+// Debug message in DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE scope.
+// To enable the debug message for this module, below PCDs must be set.
+//
+// 1. DEBUG_MANAGEABILITY must be set PcdDebugPrintErrorLevel.
+//
+// 2  RedfishPlatformConfigDxe debug enablement must be set in
+//    PcdRedfishDebugCategory (defined in RedfishPkg.dec)
+//
+// 3. The suborinate debug enablement for RedfishPlatformConfigDxe
+//    must be set in PcdRedfishPlatformConfigDebugPropert (defined
+//    in RedfishPkg.dec).
+//
+#define DEBUG_REDFISH_THIS_MODULE(DebugSubordinate, ...) \
+  while (RedfishPlatformConfigDebugProp (DebugSubordinate)) { \
+    DEBUG_REDFISH(DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE, ##__VA_ARGS__); \
+    break; \
+  }
+
+#define DEBUG_REDFISH_THIS_MODULE_CODE_BEGIN(DebugSubordinate) \
+  if (RedfishPlatformConfigDebugProp (DebugSubordinate)) {
+
+#define DEBUG_REDFISH_THIS_MODULE_CODE_END()  }
+
+#define DEBUG_REDFISH_THIS_MODULE_CODE(DebugSubordinate, Expression) \
+  DEBUG_REDFISH_THIS_MODULE_CODE_BEGIN(DebugSubordinate) \
+  Expression \
+  DEBUG_REDFISH_THIS_MODULE_CODE_END()
+
+// Subordinate debug property for DEBUG_REDFISH_PLATFORM_CONFIG_DXE
+#define REDFISH_PLATFORM_CONFIG_DEBUG_STRING_DATABASE     0x00000001
+#define REDFISH_PLATFORM_CONFIG_DEBUG_DUMP_FORMSET        0x00000002
+#define REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_SEARCH  0x00000004
+#define REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_REGEX   0x00000008
+
 ///
 /// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
 ///
@@ -75,8 +113,12 @@ typedef struct {
 #define REGULAR_EXPRESSION_INCLUDE_ALL   L".*"
 #define CONFIGURE_LANGUAGE_PREFIX        "x-uefi-redfish-"
 #define REDFISH_PLATFORM_CONFIG_VERSION  0x00010000
-#define REDFISH_PLATFORM_CONFIG_DEBUG    DEBUG_MANAGEABILITY
-#define REDFISH_MENU_PATH_SIZE           8
+
+#define REDFISH_MENU_PATH_SIZE  8
+
+// Definitions of Redfish platform config capbility
+#define REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH   0x000000001
+#define REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED  0x000000002
 
 /**
   Convert input unicode string to ascii string. It's caller's
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
index 6e6c7fdb8a9..09d9789f574 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
@@ -418,4 +418,32 @@ HiiStrSize (
   IN      CONST CHAR16  *String
   );
 
+/**
+  Check if the debug property is enabled or not.
+
+  @param[in]  DebugType  Debug enablement type
+
+  @retval TRUE, the debug property is enabled.
+          FALSE, the debug property is not enabled.
+
+**/
+BOOLEAN
+RedfishPlatformConfigDebugProp (
+  IN UINT64  DebugProp
+  );
+
+/**
+  Check if the Platform Configure feature is enabled or not.
+
+  @param[in]  FeatureType  Redfish platform config feature enablement
+
+  @retval TRUE, the feature is enabled.
+          FALSE, the feature is not enabled.
+
+**/
+BOOLEAN
+RedfishPlatformConfigFeatureProp (
+  IN UINT64  FeatureProp
+  );
+
 #endif
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c
new file mode 100644
index 00000000000..753c4d393f3
--- /dev/null
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c
@@ -0,0 +1,58 @@
+/** @file
+  The implementation of EDKII Redfish Platform Config Capability.
+  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RedfishPlatformConfigDxe.h"
+#include "RedfishPlatformConfigImpl.h"
+
+/**
+  Check if the debug property is enabled or not.
+
+  @param[in]  DebugType  Debug enablement type
+
+  @retval TRUE, the debug property is enabled.
+          FALSE, the debug property is not enabled.
+
+**/
+BOOLEAN
+RedfishPlatformConfigDebugProp (
+  IN UINT64  DebugType
+  )
+{
+  UINT64  DebugProp;
+
+  DebugProp = FixedPcdGet64 (PcdRedfishPlatformConfigDebugProperty);
+  if ((DebugProp & DebugType) != 0) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  Check if the Platform Configure feature is enabled or not.
+
+  @param[in]  FeatureType  Redfish platform config feature enablement
+
+  @retval TRUE, the feature is enabled.
+          FALSE, the feature is not enabled.
+
+**/
+BOOLEAN
+RedfishPlatformConfigFeatureProp (
+  IN UINT64  FeatureType
+  )
+{
+  UINT64  FeatureProp;
+
+  FeatureProp = FixedPcdGet64 (PcdRedfishPlatformConfigFeatureProperty);
+  if ((FeatureProp & FeatureType) != 0) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
index 664b48eb50e..8a02c839035 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
@@ -315,7 +315,7 @@ DumpHiiStatementPrompt (
 
 **/
 CHAR8 *
-BuildMenPath (
+BuildMenuPath (
   IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *StatementPrivate
   )
 {
@@ -345,7 +345,7 @@ BuildMenPath (
   }
 
   do {
-    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "F(%d) <-", FormPrivate->Id));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "F(%d) <-", FormPrivate->Id));
     FormPrivate = FindFormLinkToThis (FormPrivate);
     if (FormPrivate == NULL) {
       break;
@@ -387,7 +387,7 @@ BuildMenPath (
       AsciiStrCatS (Buffer, OldBufferSize, "/");
       AsciiStrCatS (Buffer, OldBufferSize, FormTitle);
       FreePool (FormTitle);
-      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, " %a\n", Buffer));
+      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, " %a\n", Buffer));
     }
 
     FormPrivate = (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE *)PopRedfishStack (FormStack);
@@ -1061,12 +1061,12 @@ DumpOrderedListValue (
     return;
   }
 
-  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.Type= 0x%x\n", OrderedListStatement->Value.Type));
-  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.BufferValueType= 0x%x\n", OrderedListStatement->Value.BufferValueType));
-  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.BufferLen= 0x%x\n", OrderedListStatement->Value.BufferLen));
-  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.Buffer= 0x%x\n", OrderedListStatement->Value.Buffer));
-  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.MaxContainers= 0x%x\n", OrderedListStatement->ExtraData.OrderListData.MaxContainers));
-  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "StorageWidth= 0x%x\n", OrderedListStatement->StorageWidth));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.Type= 0x%x\n", OrderedListStatement->Value.Type));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.BufferValueType= 0x%x\n", OrderedListStatement->Value.BufferValueType));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.BufferLen= 0x%x\n", OrderedListStatement->Value.BufferLen));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.Buffer= 0x%x\n", OrderedListStatement->Value.Buffer));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.MaxContainers= 0x%x\n", OrderedListStatement->ExtraData.OrderListData.MaxContainers));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "StorageWidth= 0x%x\n", OrderedListStatement->StorageWidth));
 
   if (OrderedListStatement->Value.Buffer == NULL) {
     return;
@@ -1083,7 +1083,7 @@ DumpOrderedListValue (
       Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
       Count  = OrderedListStatement->StorageWidth / sizeof (UINT8);
       for (Index = 0; Index < Count; Index++) {
-        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value8[Index]));
+        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value8[Index]));
       }
 
       break;
@@ -1091,7 +1091,7 @@ DumpOrderedListValue (
       Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
       Count   = OrderedListStatement->StorageWidth / sizeof (UINT16);
       for (Index = 0; Index < Count; Index++) {
-        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value16[Index]));
+        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value16[Index]));
       }
 
       break;
@@ -1099,7 +1099,7 @@ DumpOrderedListValue (
       Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
       Count   = OrderedListStatement->StorageWidth / sizeof (UINT32);
       for (Index = 0; Index < Count; Index++) {
-        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value32[Index]));
+        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value32[Index]));
       }
 
       break;
@@ -1107,7 +1107,7 @@ DumpOrderedListValue (
       Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
       Count   = OrderedListStatement->StorageWidth / sizeof (UINT64);
       for (Index = 0; Index < Count; Index++) {
-        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value64[Index]));
+        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value64[Index]));
       }
 
       break;
@@ -1115,13 +1115,13 @@ DumpOrderedListValue (
       Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
       Count  = OrderedListStatement->StorageWidth / sizeof (UINT8);
       for (Index = 0; Index < Count; Index++) {
-        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value8[Index]));
+        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value8[Index]));
       }
 
       break;
   }
 
-  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "\n"));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
 }
 
 /**
@@ -2013,6 +2013,8 @@ RedfishPlatformConfigProtocolGetConfigureLang (
   UINTN                                           Index;
   CHAR8                                           *FullSchema;
 
+  DEBUG ((DEBUG_INFO, "%a: Harvest config language of %a_%a (Regex: %s).\n", __func__, Schema, Version, RegexPattern));
+
   if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || (Count == NULL) || (ConfigureLangList == NULL) || IS_EMPTY_STRING (RegexPattern)) {
     return EFI_INVALID_PARAMETER;
   }
@@ -2072,6 +2074,22 @@ RedfishPlatformConfigProtocolGetConfigureLang (
   *Count             = StatementList.Count;
   *ConfigureLangList = TmpConfigureLangList;
 
+  DEBUG_REDFISH_THIS_MODULE (
+    REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_REGEX,
+    "%a: Number of configure language strings harvested: %d\n",
+    __func__,
+    StatementList.Count
+    );
+
+  DEBUG_REDFISH_THIS_MODULE_CODE (
+    REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_REGEX,
+    DEBUG_REDFISH (DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE, "%a: Number of configure language strings harvested: %d\n", __func__, StatementList.Count);
+    for (Index = 0; Index < *Count; Index++) {
+    DEBUG_REDFISH (DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE, "   (%d) %s\n", Index, TmpConfigureLangList[Index]);
+  }
+
+    );
+
 RELEASE_RESOURCE:
 
   if (FullSchema != NULL) {
@@ -2082,6 +2100,7 @@ RELEASE_RESOURCE:
     ReleaseStatementList (&StatementList);
   }
 
+  DEBUG ((DEBUG_INFO, "%a: exit.\n", __func__));
   return Status;
 }
 
@@ -2296,6 +2315,7 @@ RedfishPlatformConfigProtocolGetAttribute (
   CHAR8                                      *FullSchema;
   CHAR8                                      *Buffer;
 
+  DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__));
   if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || (AttributeValue == NULL)) {
     return EFI_INVALID_PARAMETER;
   }
@@ -2337,9 +2357,11 @@ RedfishPlatformConfigProtocolGetAttribute (
   //
   // Build up menu path
   //
-  AttributeValue->MenuPath = BuildMenPath (TargetStatement);
-  if (AttributeValue->MenuPath == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a: failed to build menu path for \"%a\"\n", __func__, AttributeValue->AttributeName));
+  if (RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
+    AttributeValue->MenuPath = BuildMenuPath (TargetStatement);
+    if (AttributeValue->MenuPath == NULL) {
+      DEBUG ((DEBUG_ERROR, "%a: failed to build menu path for \"%a\"\n", __func__, AttributeValue->AttributeName));
+    }
   }
 
   //
@@ -2370,6 +2392,7 @@ RELEASE_RESOURCE:
     FreePool (FullSchema);
   }
 
+  DEBUG ((DEBUG_INFO, "%a: Exit\n", __func__));
   return Status;
 }
 
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
index 8b1ddf4360a..537ce09a2d3 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
@@ -32,7 +32,7 @@ DumpHiiString (
   EFI_STRING  String;
 
   if ((HiiHandle == NULL) || (StringId == 0)) {
-    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "???"));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "???"));
     return EFI_INVALID_PARAMETER;
   }
 
@@ -41,7 +41,7 @@ DumpHiiString (
     return EFI_NOT_FOUND;
   }
 
-  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%s", String));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%s", String));
   FreePool (String);
 
   return EFI_SUCCESS;
@@ -79,18 +79,18 @@ DumpFormset (
     HiiFormPrivate  = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
     HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
 
-    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "  [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
     DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
-    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "\n"));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
 
     HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
     while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
       HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
       HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
 
-      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "    QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
+      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "    QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
       DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Description);
-      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "\n"));
+      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
 
       HiiStatementLink = HiiNextStatementLink;
     }
@@ -125,7 +125,7 @@ DumpFormsetList (
   }
 
   if (IsListEmpty (FormsetList)) {
-    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: Empty formset list\n", __func__));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Empty formset list\n", __func__));
     return EFI_SUCCESS;
   }
 
@@ -135,7 +135,7 @@ DumpFormsetList (
     HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
     HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
 
-    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
     DumpFormset (HiiFormsetPrivate);
 
     HiiFormsetLink = HiiFormsetNextLink;
@@ -622,7 +622,9 @@ GetStatementPrivateByConfigureLangRegex (
         HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
         HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
 
-        if ((HiiStatementPrivate->Description != 0) && !HiiStatementPrivate->Suppressed) {
+        if ((HiiStatementPrivate->Description != 0) &&
+            (RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate->Suppressed))
+        {
           TmpString = HiiStatementPrivate->DescriptionStr;
           if (TmpString != NULL) {
             Status = RegularExpressionProtocol->MatchString (
@@ -698,6 +700,7 @@ GetStatementPrivateByConfigureLang (
   LIST_ENTRY                                 *HiiNextStatementLink;
   REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *HiiStatementPrivate;
   EFI_STRING                                 TmpString;
+  UINTN                                      Index;
 
   if ((FormsetList == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang)) {
     return NULL;
@@ -707,6 +710,7 @@ GetStatementPrivateByConfigureLang (
     return NULL;
   }
 
+  Index          = 0;
   HiiFormsetLink = GetFirstNode (FormsetList);
   while (!IsNull (FormsetList, HiiFormsetLink)) {
     HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
@@ -731,15 +735,22 @@ GetStatementPrivateByConfigureLang (
         HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
         HiiStatementPrivate  = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
 
-        DEBUG_CODE (
-          STATIC UINTN Index = 0;
-          Index++;
-          DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: [%d] search %s in QID: 0x%x form: 0x%x formset: %g\n", __func__, Index, ConfigureLang, HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate->Guid));
-          );
-
-        if (HiiStatementPrivate->Description != 0) {
+        if ((HiiStatementPrivate->Description != 0) &&
+            (RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate->Suppressed))
+        {
           TmpString = HiiStatementPrivate->DescriptionStr;
           if (TmpString != NULL) {
+            Index++;
+            DEBUG_REDFISH_THIS_MODULE (
+              REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_SEARCH,
+              "%a: [%d] check %s in QID: 0x%x form: 0x%x formset: %g\n",
+              __func__,
+              Index,
+              ConfigureLang,
+              HiiStatementPrivate->QuestionId,
+              HiiFormPrivate->Id,
+              &HiiFormsetPrivate->Guid
+              );
             if (HiiStrCmp (TmpString, ConfigureLang) == 0) {
               return HiiStatementPrivate;
             }
@@ -1022,7 +1033,7 @@ NewRedfishXuefiStringArray (
 
 **/
 REDFISH_X_UEFI_STRING_DATABASE *
-GetExitOrCreateXuefiStringDatabase (
+GetExistOrCreateXuefiStringDatabase (
   IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
   IN  EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader
   )
@@ -1031,8 +1042,6 @@ GetExitOrCreateXuefiStringDatabase (
   BOOLEAN                         CreateNewOne;
   REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;
 
-  DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__));
-
   CreateNewOne               = TRUE;
   XuefiRedfishStringDatabase = NULL;
   if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) {
@@ -1054,7 +1063,7 @@ GetExitOrCreateXuefiStringDatabase (
   }
 
   if (CreateNewOne) {
-    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "  Creating x-uefi-redfish (%a) string database...\n", HiiStringPackageHeader->Language));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  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"));
@@ -1073,7 +1082,7 @@ GetExitOrCreateXuefiStringDatabase (
     }
 
     DEBUG ((
-      REDFISH_PLATFORM_CONFIG_DEBUG,
+      DEBUG_REDFISH_PLATFORM_CONFIG,
       "  x-uefi-redfish (%a):\n    String array is added to XuefiRedfishStringDatabase, total %d arrays now.\n",
       XuefiRedfishStringDatabase->XuefiRedfishLanguage,
       XuefiRedfishStringDatabase->StringsArrayBlocks
@@ -1145,7 +1154,7 @@ RedfishXuefiStringInsertDatabase (
   REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;
   REDFISH_X_UEFI_STRINGS_ARRAY    *ThisArray;
 
-  XuefiRedfishStringDatabase = GetExitOrCreateXuefiStringDatabase (FormsetPrivate, HiiStringPackageHeader);
+  XuefiRedfishStringDatabase = GetExistOrCreateXuefiStringDatabase (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);
@@ -1170,21 +1179,22 @@ RedfishXuefiStringInsertDatabase (
   (ThisArray->ArrayEntryAddress + StringIdOffset)->StringId  = StringId;
   (ThisArray->ArrayEntryAddress + StringIdOffset)->UcsString = StringTextPtr;
 
-  DEBUG ((
-    REDFISH_PLATFORM_CONFIG_DEBUG,
+  DEBUG_REDFISH_THIS_MODULE (
+    REDFISH_PLATFORM_CONFIG_DEBUG_STRING_DATABASE,
     "  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.
+  @param[in]       FormsetPrivate          Pointer to HII form-set private instance.
+  @param[in]       HiiStringPackageHeader  HII string package header.
+  @param[out]      TotalStringAdded        Return the total strings added to database.
 
   @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.
@@ -1192,8 +1202,9 @@ RedfishXuefiStringInsertDatabase (
 **/
 BOOLEAN
 CreateXuefiLanguageStringIdMap (
-  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
-  IN  EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader
+  IN   REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
+  IN   EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader,
+  OUT  UINTN                                     *TotalStringAdded
   )
 {
   EFI_STATUS               Status;
@@ -1209,6 +1220,9 @@ CreateXuefiLanguageStringIdMap (
   EFI_HII_SIBT_EXT2_BLOCK  Ext2;
   UINT32                   Length32;
   UINT8                    *StringBlockInfo;
+  UINTN                    StringsAdded;
+
+  StringsAdded = 0;
 
   //
   // Parse the string blocks to get the string text and font.
@@ -1280,6 +1294,8 @@ CreateXuefiLanguageStringIdMap (
             DEBUG ((DEBUG_ERROR, "%a: Failed to insert x-uefi-redfish string %s.\n", __func__, StringTextPtr));
             return FALSE;
           }
+
+          StringsAdded++;
         }
 
         BlockSize += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr));
@@ -1371,6 +1387,7 @@ CreateXuefiLanguageStringIdMap (
     BlockHdr = (UINT8 *)(StringBlockInfo + BlockSize);
   }
 
+  *TotalStringAdded = StringsAdded;
   return TRUE;
 }
 
@@ -1484,6 +1501,8 @@ BuildXUefiRedfishStringDatabase (
   UINTN                       SupportedSchemaLangCount;
   CHAR8                       **SupportedSchemaLang;
   BOOLEAN                     StringIdMapIsBuilt;
+  UINTN                       TotalStringsAdded;
+  UINTN                       NumberPackageStrings;
 
   DEBUG ((DEBUG_INFO, "%a: Building x-uefi-redfish string database, HII Formset GUID - %g.\n", __func__, FormsetPrivate->Guid));
 
@@ -1515,6 +1534,7 @@ BuildXUefiRedfishStringDatabase (
     return;
   }
 
+  TotalStringsAdded = 0;
   //
   // Finding the string package.
   //
@@ -1539,14 +1559,18 @@ BuildXUefiRedfishStringDatabase (
                 AsciiStrLen (HiiStringPackageHeader->Language)
                 ) == 0)
           {
-            StringIdMapIsBuilt = CreateXuefiLanguageStringIdMap (FormsetPrivate, HiiStringPackageHeader);
+            StringIdMapIsBuilt = CreateXuefiLanguageStringIdMap (FormsetPrivate, HiiStringPackageHeader, &NumberPackageStrings);
+            if (StringIdMapIsBuilt) {
+              TotalStringsAdded += NumberPackageStrings;
+            }
+
             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));
+            DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  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));
           }
@@ -1556,6 +1580,8 @@ BuildXUefiRedfishStringDatabase (
         PackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)PackageHeader + PackageHeader->Length);
     }
   }
+
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  Total %d x-uefi-redfish config language are added.\n", TotalStringsAdded));
 }
 
 /**
@@ -1621,7 +1647,7 @@ 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 x-uefi-redfish configuration found on the formset - %g\n", __func__, FormsetPrivate->Guid));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%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
@@ -1789,7 +1815,10 @@ LoadFormsetList (
   InsertTailList (FormsetList, &FormsetPrivate->Link);
 
   DEBUG_CODE (
+    if (RedfishPlatformConfigDebugProp (REDFISH_PLATFORM_CONFIG_DEBUG_DUMP_FORMSET)) {
     DumpFormsetList (FormsetList);
+  }
+
     );
 
   return EFI_SUCCESS;
@@ -1909,7 +1938,7 @@ NotifyFormsetUpdate (
   if (TargetPendingList != NULL) {
     TargetPendingList->IsDeleted = FALSE;
     DEBUG_CODE (
-      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is updated\n", __func__, HiiHandle));
+      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is updated\n", __func__, HiiHandle));
       );
     return EFI_SUCCESS;
   }
@@ -1925,7 +1954,7 @@ NotifyFormsetUpdate (
   InsertTailList (PendingList, &TargetPendingList->Link);
 
   DEBUG_CODE (
-    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is created\n", __func__, HiiHandle));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is created\n", __func__, HiiHandle));
     );
 
   return EFI_SUCCESS;
@@ -1962,7 +1991,7 @@ NotifyFormsetDeleted (
   if (TargetPendingList != NULL) {
     TargetPendingList->IsDeleted = TRUE;
     DEBUG_CODE (
-      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is updated and deleted\n", __func__, HiiHandle));
+      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is updated and deleted\n", __func__, HiiHandle));
       );
     return EFI_SUCCESS;
   }
@@ -1978,7 +2007,7 @@ NotifyFormsetDeleted (
   InsertTailList (PendingList, &TargetPendingList->Link);
 
   DEBUG_CODE (
-    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is deleted\n", __func__, HiiHandle));
+    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is deleted\n", __func__, HiiHandle));
     );
 
   return EFI_SUCCESS;
@@ -2027,12 +2056,12 @@ ProcessPendingList (
       //
       FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
       if (FormsetPrivate != NULL) {
-        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: formset: %g is removed because driver release HII resource it already\n", __func__, FormsetPrivate->Guid));
+        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is removed because driver release HII resource it already\n", __func__, FormsetPrivate->Guid));
         RemoveEntryList (&FormsetPrivate->Link);
         ReleaseFormset (FormsetPrivate);
         FreePool (FormsetPrivate);
       } else {
-        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: formset on HII handle 0x%x was removed already\n", __func__, Target->HiiHandle));
+        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset on HII handle 0x%x was removed already\n", __func__, Target->HiiHandle));
       }
     } else {
       //
@@ -2043,7 +2072,7 @@ ProcessPendingList (
         //
         // HII formset already exist, release it and query again.
         //
-        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: formset: %g is updated. Release current formset\n", __func__, &FormsetPrivate->Guid));
+        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is updated. Release current formset\n", __func__, &FormsetPrivate->Guid));
         RemoveEntryList (&FormsetPrivate->Link);
         ReleaseFormset (FormsetPrivate);
         FreePool (FormsetPrivate);
-- 
2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117126): https://edk2.groups.io/g/devel/message/117126
Mute This Topic: https://groups.io/mt/105159787/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [edk2-devel] [PATCH V2 4/6] RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted unexpectedly
  2024-03-26 15:14 [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Chang, Abner via groups.io
                   ` (2 preceding siblings ...)
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 3/6] RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support Chang, Abner via groups.io
@ 2024-03-26 15:15 ` Chang, Abner via groups.io
  2024-03-27  7:39   ` Nickle Wang via groups.io
  2024-03-26 15:15 ` [edk2-devel] [PATCH V2 5/6] EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs Chang, Abner via groups.io
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-03-26 15:15 UTC (permalink / raw)
  To: devel; +Cc: Nickle Wang, Igor Kulchytskyy

From: Abner Chang <abner.chang@amd.com>

Add the condition check when delete HII string.
Only when the HiiStatement operand equal to "EFI_IFR_STRING_OP"
and the statement value type = EFI_IFR_TYPE_STRING.

Signed-off-by: Abner Chang <abner.chang@amd.com>
Co-authored-by: Nickle Wang <nicklew@nvidia.com>
Cc: Igor Kulchytskyy <igork@ami.com>
---
 .../RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c    | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
index 8a02c839035..d165799f9a1 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
@@ -1873,8 +1873,11 @@ RedfishPlatformConfigSetStatementCommon (
     DEBUG ((DEBUG_ERROR, "%a: failed to save question value: %r\n", __func__, Status));
   }
 
-  if (StatementValue->Value.string != 0) {
-    HiiDeleteString (StatementValue->Value.string, TargetStatement->ParentForm->ParentFormset->HiiHandle);
+  if ((TargetStatement->HiiStatement->Operand == EFI_IFR_STRING_OP) && (StatementValue->Type == EFI_IFR_TYPE_STRING)) {
+    if (StatementValue->Value.string != 0) {
+      // Delete HII string which was created for HII statement operand = EFI_IFR_STRING_OP and Type = EFI_IFR_TYPE_STRING.
+      HiiDeleteString (StatementValue->Value.string, TargetStatement->ParentForm->ParentFormset->HiiHandle);
+    }
   }
 
   return Status;
-- 
2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117125): https://edk2.groups.io/g/devel/message/117125
Mute This Topic: https://groups.io/mt/105159786/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [edk2-devel] [PATCH V2 5/6] EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs
  2024-03-26 15:14 [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Chang, Abner via groups.io
                   ` (3 preceding siblings ...)
  2024-03-26 15:15 ` [edk2-devel] [PATCH V2 4/6] RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted unexpectedly Chang, Abner via groups.io
@ 2024-03-26 15:15 ` Chang, Abner via groups.io
  2024-03-27  7:39   ` Nickle Wang via groups.io
  2024-03-26 15:15 ` [edk2-devel] [PATCH V2 6/6] RedfishPkg/RedfishPlatformConfigDxe: support menu path report Chang, Abner via groups.io
  2024-03-27  7:41 ` [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Nickle Wang via groups.io
  6 siblings, 1 reply; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-03-26 15:15 UTC (permalink / raw)
  To: devel; +Cc: Nickle Wang

From: Abner Chang <abner.chang@amd.com>

Signed-off-by: Abner Chang <abner.chang@amd.com>
Cc: Nickle Wang <nicklew@nvidia.com>
---
 EmulatorPkg/EmulatorPkg.dsc | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc
index 85134b07816..5fa1ed345a3 100644
--- a/EmulatorPkg/EmulatorPkg.dsc
+++ b/EmulatorPkg/EmulatorPkg.dsc
@@ -278,6 +278,27 @@
   gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath.DevicePath|{DEVICE_PATH("MAC(000000000000,0x1)")}
   gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBand|False
   gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDiscoverAccessModeInBand|False
+
+  gEmulatorPkgTokenSpaceGuid.PcdRedfishServiceStopIfSecureBootDisabled|False
+  gEmulatorPkgTokenSpaceGuid.PcdRedfishServiceStopIfExitbootService|False
+
+  gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishServiceEtagSupported|False
+
+  #
+  # Redfish Debug enablement
+  #
+  # 0x0000000000000001  RedfishPlatformConfigDxe driver debug enabled.
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory|0
+  #   0x00000001  x-uefi-redfish string database message enabled
+  #   0x00000002  Debug Message for dumping formset
+  #   0x00000004  Debug Message for x-uefi-redfish searching result
+  #   0x00000008  Debug Message for x-uefi-redfish Regular Expression searching result
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigDebugProperty|0
+
+  # Redfish Platform Configure DXE driver feature enablement
+  #   0x00000001  Enable building Redfish Attribute Registry menu path.
+  #   0x00000002  Allow supressed HII option to be exposed on Redfish.
+  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty|0
 !endif
 
 [PcdsDynamicDefault.common.DEFAULT]
-- 
2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117127): https://edk2.groups.io/g/devel/message/117127
Mute This Topic: https://groups.io/mt/105159788/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [edk2-devel] [PATCH V2 6/6] RedfishPkg/RedfishPlatformConfigDxe: support menu path report
  2024-03-26 15:14 [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Chang, Abner via groups.io
                   ` (4 preceding siblings ...)
  2024-03-26 15:15 ` [edk2-devel] [PATCH V2 5/6] EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs Chang, Abner via groups.io
@ 2024-03-26 15:15 ` Chang, Abner via groups.io
  2024-03-27  7:39   ` Nickle Wang via groups.io
  2024-03-27  7:41 ` [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Nickle Wang via groups.io
  6 siblings, 1 reply; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-03-26 15:15 UTC (permalink / raw)
  To: devel; +Cc: Abner Chang, Igor Kulchytskyy

From: Nickle Wang <nicklew@nvidia.com>

"MenuPath" is the attribute in BIOS attribute registry. To support
reporting this attribute, we need to include the formset without
x-uefi-redfish support in database. So driver can find menu path to
target attribute in BIOS menu.

Signed-off-by: Nickle Wang <nicklew@nvidia.com>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Igor Kulchytskyy <igork@ami.com>
Signed-off-by: Abner Chang <abner.chang@amd.com>
---
 .../RedfishPlatformConfigDxe.h                |  8 +--
 .../RedfishPlatformConfigDxe.c                |  8 +--
 .../RedfishPlatformConfigImpl.c               | 51 +++++++++++++++----
 3 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
index 688f2067bff..8eb7b0dc2aa 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
@@ -2,7 +2,7 @@
   This file defines the EDKII Redfish Platform Config Protocol interface.
 
   (C) Copyright 2021 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
@@ -49,8 +49,8 @@
 // 2  RedfishPlatformConfigDxe debug enablement must be set in
 //    PcdRedfishDebugCategory (defined in RedfishPkg.dec)
 //
-// 3. The suborinate debug enablement for RedfishPlatformConfigDxe
-//    must be set in PcdRedfishPlatformConfigDebugPropert (defined
+// 3. The subordinate debug enablement for RedfishPlatformConfigDxe
+//    must be set in PcdRedfishPlatformConfigDebugProperty (defined
 //    in RedfishPkg.dec).
 //
 #define DEBUG_REDFISH_THIS_MODULE(DebugSubordinate, ...) \
@@ -116,7 +116,7 @@ typedef struct {
 
 #define REDFISH_MENU_PATH_SIZE  8
 
-// Definitions of Redfish platform config capbility
+// Definitions of Redfish platform config capability
 #define REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH   0x000000001
 #define REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED  0x000000002
 
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
index d165799f9a1..7821146e901 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
@@ -2016,7 +2016,7 @@ RedfishPlatformConfigProtocolGetConfigureLang (
   UINTN                                           Index;
   CHAR8                                           *FullSchema;
 
-  DEBUG ((DEBUG_INFO, "%a: Harvest config language of %a_%a (Regex: %s).\n", __func__, Schema, Version, RegexPattern));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Harvest config language of %a_%a (Regex: %s).\n", __func__, Schema, Version, RegexPattern));
 
   if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || (Count == NULL) || (ConfigureLangList == NULL) || IS_EMPTY_STRING (RegexPattern)) {
     return EFI_INVALID_PARAMETER;
@@ -2103,7 +2103,7 @@ RELEASE_RESOURCE:
     ReleaseStatementList (&StatementList);
   }
 
-  DEBUG ((DEBUG_INFO, "%a: exit.\n", __func__));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: exit.\n", __func__));
   return Status;
 }
 
@@ -2318,7 +2318,7 @@ RedfishPlatformConfigProtocolGetAttribute (
   CHAR8                                      *FullSchema;
   CHAR8                                      *Buffer;
 
-  DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Entry\n", __func__));
   if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || (AttributeValue == NULL)) {
     return EFI_INVALID_PARAMETER;
   }
@@ -2395,7 +2395,7 @@ RELEASE_RESOURCE:
     FreePool (FullSchema);
   }
 
-  DEBUG ((DEBUG_INFO, "%a: Exit\n", __func__));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Exit\n", __func__));
   return Status;
 }
 
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
index 537ce09a2d3..86f3aa529c5 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
@@ -2,7 +2,7 @@
   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
@@ -656,8 +656,10 @@ GetStatementPrivateByConfigureLangRegex (
               ++StatementList->Count;
             }
           } else {
-            DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->DescriptionStr is NULL, x-uefi-string has something wrong.\n", __func__));
-            ASSERT (FALSE);
+            if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
+              DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->DescriptionStr is NULL, x-uefi-string has something wrong.\n", __func__));
+              ASSERT (FALSE);
+            }
           }
         }
 
@@ -754,6 +756,11 @@ GetStatementPrivateByConfigureLang (
             if (HiiStrCmp (TmpString, ConfigureLang) == 0) {
               return HiiStatementPrivate;
             }
+          } else {
+            if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
+              DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->DescriptionStr is NULL, x-uefi-string has something wrong.\n", __func__));
+              ASSERT (FALSE);
+            }
           }
         }
 
@@ -1440,7 +1447,7 @@ GetXuefiStringAndLangByStringId (
     StringIndex = StringId;
     while (StringIndex >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
       if (IsNodeAtEnd (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray)) {
-        goto ErrorEixt;
+        goto ErrorExit;
       }
 
       StringArray  = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray);
@@ -1477,8 +1484,8 @@ GetXuefiStringAndLangByStringId (
                                                                      );
   }
 
-ErrorEixt:;
-  DEBUG ((DEBUG_ERROR, "%a: String ID (%d) is not in any x-uef-redfish string databases.\n", __func__, StringId));
+ErrorExit:;
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: String ID (%d) is not in any x-uef-redfish string databases.\n", __func__, StringId));
   return EFI_NOT_FOUND;
 }
 
@@ -1504,7 +1511,7 @@ BuildXUefiRedfishStringDatabase (
   UINTN                       TotalStringsAdded;
   UINTN                       NumberPackageStrings;
 
-  DEBUG ((DEBUG_INFO, "%a: Building x-uefi-redfish string database, HII Formset GUID - %g.\n", __func__, FormsetPrivate->Guid));
+  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Building x-uefi-redfish string database, HII Formset GUID - %g.\n", __func__, FormsetPrivate->Guid));
 
   BufferSize = 0;
   Status     = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
@@ -1531,6 +1538,8 @@ BuildXUefiRedfishStringDatabase (
                                                          FormsetPrivate->HiiPackageListHeader
                                                          );
   if (EFI_ERROR (Status)) {
+    FreePool (FormsetPrivate->HiiPackageListHeader);
+    FormsetPrivate->HiiPackageListHeader = NULL;
     return;
   }
 
@@ -1647,8 +1656,14 @@ LoadFormset (
   FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet->DevicePath, FALSE, FALSE);
   Status                        = GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivate->SupportedSchema);
   if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%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.
+    if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
+      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: No x-uefi-redfish configuration found on the formset - %g\n", __func__, FormsetPrivate->Guid));
+      //
+      // If there is no x-uefi-redfish language in this form-set, we don't add formset
+      // since we don't need to build menu path for attribute registry.
+      //
+      return EFI_UNSUPPORTED;
+    }
   } else {
     // Building x-uefi-redfish string database
     BuildXUefiRedfishStringDatabase (FormsetPrivate);
@@ -1734,7 +1749,23 @@ LoadFormset (
         //
         InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
       } else {
-        FreePool (HiiStatementPrivate);
+        if (!RedfishPlatformConfigFeatureProp (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
+          //
+          // If there is no x-uefi-redfish language for this statement, we don't add this statement
+          // since we don't need to build menu path for attribute registry.
+          //
+          FreePool (HiiStatementPrivate);
+        } else {
+          //
+          // This is not x-uefi-redfish string and we don't cache its string for searching Redfish configure language.
+          // When caller wants the string, we will read English string by calling HiiGetString().
+          //
+          HiiStatementPrivate->DescriptionStr = NULL;
+          //
+          // Attach to statement list.
+          //
+          InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
+        }
       }
 
       HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
-- 
2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117128): https://edk2.groups.io/g/devel/message/117128
Mute This Topic: https://groups.io/mt/105159789/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization Chang, Abner via groups.io
@ 2024-03-27  2:40   ` Nickle Wang via groups.io
  2024-04-04  3:02     ` Chang, Abner via groups.io
       [not found]   ` <17C07EC03FCD57FF.6405@groups.io>
  2024-04-04  0:44   ` Igor Kulchytskyy via groups.io
  2 siblings, 1 reply; 20+ messages in thread
From: Nickle Wang via groups.io @ 2024-03-27  2:40 UTC (permalink / raw)
  To: abner.chang, devel; +Cc: Igor Kulchytskyy

Hi Abner,

Could we change "DescriptionStr" below to something like "XuefiString", so people don't think it is a regular English string of HII statement?

> +  EFI_STRING_ID                             Description;      // String token of this question.
> +  CHAR16                                    *DescriptionStr;  // String of this question.
> +  EFI_STRING_ID                             Help;             // String token of help message.


Thanks,
Nickle

> -----Original Message-----
> From: abner.chang@amd.com <abner.chang@amd.com>
> Sent: Tuesday, March 26, 2024 11:15 PM
> To: devel@edk2.groups.io
> Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> Subject: [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language
> searching optimization
> 
> External email: Use caution opening links or attachments
> 
> 
> 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>
> ---
>  .../RedfishPlatformConfigImpl.h               | 107 ++-
>  .../RedfishPlatformConfigDxe.c                |  23 +-
>  .../RedfishPlatformConfigImpl.c               | 820 +++++++++++++++++-
>  3 files changed, 878 insertions(+), 72 deletions(-)
> 
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> index 9f4312decf5..6e6c7fdb8a9 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                                    *DescriptionStr;  // 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..664b48eb50e 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->DescriptionStr != NULL);
> +        TmpConfigureLangList[Index] = AllocateCopyPool (HiiStrSize (StatementRef-
> >Statement->DescriptionStr), (VOID *)StatementRef->Statement-
> >DescriptionStr);
> +        ++Index;
>        }
>      }
>    }
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> index 47d35abc088..8b1ddf4360a 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->DescriptionStr;
>            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->DescriptionStr 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->DescriptionStr;
>            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,607 @@ NewFormsetPrivate (
>    // Initial newly created formset private data.
>    //
>    InitializeListHead (&NewFormsetPrivate->HiiFormList);
> +  InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);
> 
>    return NewFormsetPrivate;
>  }
> 
> +/**
> +  Create new x-uefi-redfish string array.
> +
> +  @param[in]      FormsetPrivate              Pointer to HII form-set private instance.
> +  @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_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
> +  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 (FormsetPrivate,
> 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 (FormsetPrivate,
> 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__));
> +    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 +1584,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 +1592,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 +1602,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 +1621,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 +1635,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 +1661,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 +1699,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->DescriptionStr = String;
> +        //
> +        // Attach to statement list.
> +        //
> +        InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> >Link);
> +      } else {
> +        FreePool (HiiStatementPrivate);
> +      }
> +
>        HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> HiiStatementLink);
>      }
> 
> @@ -1052,7 +1778,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 +2051,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 (#117145): https://edk2.groups.io/g/devel/message/117145
Mute This Topic: https://groups.io/mt/105159783/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization
       [not found]   ` <17C07EC03FCD57FF.6405@groups.io>
@ 2024-03-27  7:37     ` Nickle Wang via groups.io
  0 siblings, 0 replies; 20+ messages in thread
From: Nickle Wang via groups.io @ 2024-03-27  7:37 UTC (permalink / raw)
  To: devel, Nickle Wang, abner.chang; +Cc: Igor Kulchytskyy

Per offline discussion with Abner, this will be addressed by separated patch since there is no function impact to performance improvements.

Reviewed-by: Nickle Wang <nicklew@nvidia.com>

Regards,
Nickle

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Nickle Wang
> via groups.io
> Sent: Wednesday, March 27, 2024 10:40 AM
> To: abner.chang@amd.com; devel@edk2.groups.io
> Cc: Igor Kulchytskyy <igork@ami.com>
> Subject: Re: [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe:
> Config language searching optimization
> 
> External email: Use caution opening links or attachments
> 
> 
> Hi Abner,
> 
> Could we change "DescriptionStr" below to something like "XuefiString", so
> people don't think it is a regular English string of HII statement?
> 
> > +  EFI_STRING_ID                             Description;      // String token of this
> question.
> > +  CHAR16                                    *DescriptionStr;  // String of this question.
> > +  EFI_STRING_ID                             Help;             // String token of help message.
> 
> 
> Thanks,
> Nickle
> 
> > -----Original Message-----
> > From: abner.chang@amd.com <abner.chang@amd.com>
> > Sent: Tuesday, March 26, 2024 11:15 PM
> > To: devel@edk2.groups.io
> > Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> > Subject: [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language
> > searching optimization
> >
> > External email: Use caution opening links or attachments
> >
> >
> > 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>
> > ---
> >  .../RedfishPlatformConfigImpl.h               | 107 ++-
> >  .../RedfishPlatformConfigDxe.c                |  23 +-
> >  .../RedfishPlatformConfigImpl.c               | 820 +++++++++++++++++-
> >  3 files changed, 878 insertions(+), 72 deletions(-)
> >
> > diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> > b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> > index 9f4312decf5..6e6c7fdb8a9 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                                    *DescriptionStr;  // 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..664b48eb50e 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->DescriptionStr != NULL);
> > +        TmpConfigureLangList[Index] = AllocateCopyPool (HiiStrSize
> (StatementRef-
> > >Statement->DescriptionStr), (VOID *)StatementRef->Statement-
> > >DescriptionStr);
> > +        ++Index;
> >        }
> >      }
> >    }
> > diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> > b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> > index 47d35abc088..8b1ddf4360a 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->DescriptionStr;
> >            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->DescriptionStr 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->DescriptionStr;
> >            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,607 @@ NewFormsetPrivate (
> >    // Initial newly created formset private data.
> >    //
> >    InitializeListHead (&NewFormsetPrivate->HiiFormList);
> > +  InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);
> >
> >    return NewFormsetPrivate;
> >  }
> >
> > +/**
> > +  Create new x-uefi-redfish string array.
> > +
> > +  @param[in]      FormsetPrivate              Pointer to HII form-set private
> instance.
> > +  @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_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
> > +  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 (FormsetPrivate,
> > 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 (FormsetPrivate,
> > 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__));
> > +    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 +1584,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 +1592,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 +1602,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 +1621,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
> +1635,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 +1661,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 +1699,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->DescriptionStr = String;
> > +        //
> > +        // Attach to statement list.
> > +        //
> > +        InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> > >Link);
> > +      } else {
> > +        FreePool (HiiStatementPrivate);
> > +      }
> > +
> >        HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> > HiiStatementLink);
> >      }
> >
> > @@ -1052,7 +1778,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 +2051,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 (#117151): https://edk2.groups.io/g/devel/message/117151
Mute This Topic: https://groups.io/mt/105159783/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 2/6] RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 2/6] RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro Chang, Abner via groups.io
@ 2024-03-27  7:38   ` Nickle Wang via groups.io
  0 siblings, 0 replies; 20+ messages in thread
From: Nickle Wang via groups.io @ 2024-03-27  7:38 UTC (permalink / raw)
  To: abner.chang, devel; +Cc: Igor Kulchytskyy



Reviewed-by: Nickle Wang <nicklew@nvidia.com>

Regards,
Nickle

> -----Original Message-----
> From: abner.chang@amd.com <abner.chang@amd.com>
> Sent: Tuesday, March 26, 2024 11:15 PM
> To: devel@edk2.groups.io
> Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> Subject: [PATCH V2 2/6] RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG
> macro
> 
> External email: Use caution opening links or attachments
> 
> 
> From: Abner Chang <abner.chang@amd.com>
> 
> Introduce DEBUG_REDFISH macro for the debug message of edk2 Redfish
> components.
> DEBUG_REDFISH can be used in any edk2 Redfish component with Redfish
> DebugCatagory as the first parameter.
> Whether the debug message is output or not depends on the platform setting of
> PcdRedfishDebugCatagory.
> 
> Signed-off-by: Abner Chang <abner.chang@amd.com>
> Cc: Nickle Wang <nicklew@nvidia.com>
> Cc: Igor Kulchytskyy <igork@ami.com>
> ---
>  RedfishPkg/RedfishPkg.dec                     |  9 +++
>  .../RedfishDebugLib/RedfishDebugLib.inf       |  4 ++
>  RedfishPkg/Include/Library/RedfishDebugLib.h  | 43 +++++++++++----
>   .../Library/RedfishDebugLib/RedfishDebugLib.c | 55 ++++---------------
>  4 files changed, 57 insertions(+), 54 deletions(-)
> 
> diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec index
> 1a9c9ed7bc5..a9665ff68ef 100644
> --- a/RedfishPkg/RedfishPkg.dec
> +++ b/RedfishPkg/RedfishPkg.dec
> @@ -5,6 +5,7 @@
>  # (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>  #
> Copyright (c) 2023, American Megatrends International LLC.
>  # Copyright (c) 2023-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  ## @@ -184,3 +185,11 @@
> 
> gEfiRedfishPkgTokenSpaceGuid.PcdHttpRetryWaitInSecond|1|UINT16|0x000010
> 10
>    ## This is used to disable Redfish HTTP cache function and every request will be
> sent to Redfish service.
> 
> gEfiRedfishPkgTokenSpaceGuid.PcdHttpCacheDisabled|FALSE|BOOLEAN|0x0000
> 1011
> +  #
> +  # Redfish debug catagories
> +  # To enable the debug message for the entire edk2 Redfish implementation,
> below PCDs must be set.
> +  # DEBUG_MANAGEABILITY must be set PcdDebugPrintErrorLevel.
> +  #
> +  #   0x0000000000000001  RedfishPlatformConfigDxe driver debug enabled.
> +  #
> +
> +
> gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory|0|UINT64|0x000010
> + 12
> diff --git a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf
> b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf
> index d468bb213b6..42ff321b48e 100644
> --- a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf
> +++ b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.inf
> @@ -2,6 +2,7 @@
>  #  INF file for Redfish debug library.
>  #
>  #  Copyright (c) 2023-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  # @@ -35,5 +36,8 @@
>    RedfishHttpLib
>    UefiLib
> 
> +[FixedPcd]
> +  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory
> +
>  [Depex]
>    TRUE
> diff --git a/RedfishPkg/Include/Library/RedfishDebugLib.h
> b/RedfishPkg/Include/Library/RedfishDebugLib.h
> index ad7a6975867..19e5a895cc8 100644
> --- a/RedfishPkg/Include/Library/RedfishDebugLib.h
> +++ b/RedfishPkg/Include/Library/RedfishDebugLib.h
> @@ -2,6 +2,7 @@
>    This file defines the Redfish debug library interface.
> 
>    Copyright (c) 2023-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
> 
> @@ -11,28 +12,48 @@
>  #define REDFISH_DEBUG_LIB_H_
> 
>  #include <Uefi.h>
> +#include <Library/DebugLib.h>
>  #include <RedfishServiceData.h>
>  #include <Library/HiiUtilityLib.h>
>  #include <Library/JsonLib.h>
> 
>  #include <Protocol/EdkIIRedfishPlatformConfig.h>
> 
> -#define DEBUG_REDFISH_NETWORK         DEBUG_MANAGEABILITY   ///< Debug
> error level for Redfish networking function
> -#define DEBUG_REDFISH_HOST_INTERFACE  DEBUG_MANAGEABILITY   ///<
> Debug error level for Redfish networking function
> +// Used with MdePKg DEBUG macro.
> +#define DEBUG_REDFISH_NETWORK          DEBUG_MANAGEABILITY          ///<
> Debug error level for Redfish networking function
> +#define DEBUG_REDFISH_HOST_INTERFACE   DEBUG_MANAGEABILITY
> ///< Debug error level for Redfish Host INterface
> +#define DEBUG_REDFISH_PLATFORM_CONFIG  DEBUG_MANAGEABILITY
> ///< Debug error level for Redfish Platform Configure Driver
> +
> +//
> +// Definitions of Redfish debug capability in Redfish component scope,
> +used with DEBUG_REDFISH macro // For example, Redfish Platform Config
> Driver
> +//   DEBUG_REDFISH(DEBUG_REDFISH_PLATFORM_CONFIG_DXE, ...)
> +//
> +#define DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE
> 0x00000001
> +
> +#define DEBUG_REDFISH(DebugCategory, ...) \
> +    do {                                                \
> +      if (!DebugPrintEnabled()) {                       \
> +        break;                                          \
> +      }                                                 \
> +      if (!DebugRedfishComponentEnabled (DebugCategory)) { \
> +        break;                                             \
> +      }                                                    \
> +      DEBUG ((DEBUG_MANAGEABILITY, ##__VA_ARGS__));       \
> +    } while (FALSE)
> 
>  /**
> -  Debug print the value of StatementValue.
> +  Determine whether the Redfish debug category is enabled in
> + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory.
> 
> -  @param[in]  ErrorLevel     DEBUG macro error level.
> -  @param[in]  StatementValue The statement value to print.
> +  @param[in]  DebugCategory  Redfish debug category.
> 
> -  @retval     EFI_SUCCESS            StatementValue is printed.
> -  @retval     EFI_INVALID_PARAMETER  StatementValue is NULL.
> +  @retval     TRUE   This debug category is enabled.
> +  @retval     FALSE  This debug category is disabled..
>  **/
> -EFI_STATUS
> -DumpHiiStatementValue (
> -  IN UINTN                ErrorLevel,
> -  IN HII_STATEMENT_VALUE  *StatementValue
> +BOOLEAN
> +DebugRedfishComponentEnabled (
> +  IN  UINT64  DebugCategory
>    );
> 
>  /**
> diff --git a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
> b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
> index 8b0425b8c3b..f8bb51ff532 100644
> --- a/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
> +++ b/RedfishPkg/Library/RedfishDebugLib/RedfishDebugLib.c
> @@ -2,6 +2,7 @@
>    Redfish debug library to debug Redfish application.
> 
>    Copyright (c) 2023-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
> 
> @@ -25,55 +26,23 @@
>  #define REDFISH_PRINT_BUFFER_BYTES_PER_ROW  16
> 
>  /**
> -  Debug print the value of StatementValue.
> +  Determine whether the Redfish debug category is enabled in
> + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory.
> 
> -  @param[in]  ErrorLevel     DEBUG macro error level.
> -  @param[in]  StatementValue The statement value to print.
> +  @param[in]  RedfishDebugCategory  Redfish debug category.
> 
> -  @retval     EFI_SUCCESS            StatementValue is printed.
> -  @retval     EFI_INVALID_PARAMETER  StatementValue is NULL.
> +  @retval     TRUE   This debug category is enabled.
> +  @retval     FALSE  This debug category is disabled..
>  **/
> -EFI_STATUS
> -DumpHiiStatementValue (
> -  IN UINTN                ErrorLevel,
> -  IN HII_STATEMENT_VALUE  *StatementValue
> +BOOLEAN
> +DebugRedfishComponentEnabled (
> +  IN  UINT64  RedfishDebugCategory
>    )
>  {
> -  if (StatementValue == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> +  UINT64  DebugCategory;
> 
> -  DEBUG ((ErrorLevel, "BufferValueType: 0x%x\n", StatementValue-
> >BufferValueType));
> -  DEBUG ((ErrorLevel, "BufferLen: 0x%x\n", StatementValue->BufferLen));
> -  DEBUG ((ErrorLevel, "Buffer:    0x%p\n", StatementValue->Buffer));
> -  DEBUG ((ErrorLevel, "Type:      0x%p\n", StatementValue->Type));
> -
> -  switch (StatementValue->Type) {
> -    case EFI_IFR_TYPE_NUM_SIZE_8:
> -      DEBUG ((ErrorLevel, "Value:     0x%x\n", StatementValue->Value.u8));
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_16:
> -      DEBUG ((ErrorLevel, "Value:     0x%x\n", StatementValue->Value.u16));
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_32:
> -      DEBUG ((ErrorLevel, "Value:     0x%x\n", StatementValue->Value.u32));
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_64:
> -      DEBUG ((ErrorLevel, "Value:     0x%lx\n", StatementValue->Value.u64));
> -      break;
> -    case EFI_IFR_TYPE_BOOLEAN:
> -      DEBUG ((ErrorLevel, "Value:     %a\n", (StatementValue->Value.b ? "true" :
> "false")));
> -      break;
> -    case EFI_IFR_TYPE_STRING:
> -      DEBUG ((ErrorLevel, "Value:     0x%x\n", StatementValue->Value.string));
> -      break;
> -    case EFI_IFR_TYPE_TIME:
> -    case EFI_IFR_TYPE_DATE:
> -    default:
> -      break;
> -  }
> -
> -  return EFI_SUCCESS;
> +  DebugCategory = FixedPcdGet64 (PcdRedfishDebugCategory);  return
> + ((DebugCategory & RedfishDebugCategory) != 0);
>  }
> 
>  /**
> --
> 2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117152): https://edk2.groups.io/g/devel/message/117152
Mute This Topic: https://groups.io/mt/105159784/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 3/6] RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 3/6] RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support Chang, Abner via groups.io
@ 2024-03-27  7:38   ` Nickle Wang via groups.io
  0 siblings, 0 replies; 20+ messages in thread
From: Nickle Wang via groups.io @ 2024-03-27  7:38 UTC (permalink / raw)
  To: abner.chang, devel; +Cc: Igor Kulchytskyy



Reviewed-by: Nickle Wang <nicklew@nvidia.com>

Regards,
Nickle

> -----Original Message-----
> From: abner.chang@amd.com <abner.chang@amd.com>
> Sent: Tuesday, March 26, 2024 11:15 PM
> To: devel@edk2.groups.io
> Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> Subject: [PATCH V2 3/6] RedfishPkg/RedfishPlatformConfigDxe:Add
> RefishDebugLib support
> 
> External email: Use caution opening links or attachments
> 
> 
> From: Abner Chang <abner.chang@amd.com>
> 
> Add RedfishPlatformConfigDxe debug capability that aligns with edk2 Redfish
> debug mechanism.
> 
> - PcdRedfishPlatformConfigDebugProperty, add PCD to control
>   RedfishPlatformConfigDxe subordinate of Redfish debug
>   capabilities.
> - PcdRedfishPlatformConfigFeatureProperty, add PCD to
>   manage RedfishPlatformConfigDxe features.
> 
> Signed-off-by: Abner Chang <abner.chang@amd.com>
> Co-authored-by: Nickle Wang <nicklew@nvidia.com>
> Cc: Igor Kulchytskyy <igork@ami.com>
> ---
>  RedfishPkg/RedfishPkg.dec                     |  15 +++
>  .../RedfishPlatformConfigDxe.inf              |   8 ++
>  .../RedfishPlatformConfigDxe.h                |  46 +++++++-
>  .../RedfishPlatformConfigImpl.h               |  28 +++++
>  .../RedfishPlatformConfigCapability.c         |  58 ++++++++++
>  .../RedfishPlatformConfigDxe.c                |  59 +++++++---
>  .../RedfishPlatformConfigImpl.c               | 107 +++++++++++-------
>  7 files changed, 262 insertions(+), 59 deletions(-)  create mode 100644
> RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c
> 
> diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec index
> a9665ff68ef..c048e43f53b 100644
> --- a/RedfishPkg/RedfishPkg.dec
> +++ b/RedfishPkg/RedfishPkg.dec
> @@ -193,3 +193,18 @@
>    #   0x0000000000000001  RedfishPlatformConfigDxe driver debug enabled.
>    #
> 
> gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory|0|UINT64|0x0000101
> 2
> +  #
> +  # Redfish RedfishPlatformConfigDxe Debug Properties
> +  #   0x00000001  x-uefi-redfish string database message enabled
> +  #   0x00000002  Debug Message for dumping formset
> +  #   0x00000004  Debug Message for x-uefi-redfish searching result
> +  #   0x00000008  Debug Message for x-uefi-redfish Regular Expression searching
> result
> +  #
> +
> + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigDebugProperty|0|U
> + INT32|0x00001013
> +  #
> +  # RedfishPlatformConfigDxe feature enablement
> +  #   0x00000001  Enable building Redfish Attribute Registry menu path.
> +  #   0x00000002  Allow supressed HII option to be exposed on Redfish.
> +  #
> +  # Redfish RedfishPlatformConfigDxe feature Properties
> +
> + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty|0
> + |UINT32|0x00001014
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
> index 5a249c8c3bc..2db47c2cffc 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
> @@ -3,6 +3,7 @@
>  #
>  #  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>  #
> Copyright (c) 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  # @@ -23,6 +24,7 @@
>    RedfishPkg/RedfishPkg.dec
> 
>  [Sources]
> +  RedfishPlatformConfigCapability.c
>    RedfishPlatformConfigDxe.h
>    RedfishPlatformConfigDxe.c
>    RedfishPlatformConfigImpl.h
> @@ -36,7 +38,9 @@
>    HiiLib
>    HiiUtilityLib
>    MemoryAllocationLib
> +  PcdLib
>    PrintLib
> +  RedfishDebugLib
>    UefiLib
>    UefiBootServicesTableLib
>    UefiRuntimeServicesTableLib
> @@ -51,5 +55,9 @@
>  [Guids]
>    gEfiRegexSyntaxTypePerlGuid             ## CONSUMED
> 
> +[FixedPcd]
> + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty
> + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigDebugProperty
> +
>  [Depex]
>    TRUE
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> index 38adea04c5b..688f2067bff 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> @@ -3,6 +3,7 @@
> 
>    (C) Copyright 2021 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
> 
> @@ -20,7 +21,9 @@
>  #include <Library/BaseMemoryLib.h>
>  #include <Library/DebugLib.h>
>  #include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
>  #include <Library/PrintLib.h>
> +#include <Library/RedfishDebugLib.h>
>  #include <Library/UefiLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>  #include <Library/UefiDriverEntryPoint.h> @@ -37,6 +40,41 @@  //  #include
> <Protocol/EdkIIRedfishPlatformConfig.h>
> 
> +//
> +// Debug message in DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE
> scope.
> +// To enable the debug message for this module, below PCDs must be set.
> +//
> +// 1. DEBUG_MANAGEABILITY must be set PcdDebugPrintErrorLevel.
> +//
> +// 2  RedfishPlatformConfigDxe debug enablement must be set in
> +//    PcdRedfishDebugCategory (defined in RedfishPkg.dec)
> +//
> +// 3. The suborinate debug enablement for RedfishPlatformConfigDxe
> +//    must be set in PcdRedfishPlatformConfigDebugPropert (defined
> +//    in RedfishPkg.dec).
> +//
> +#define DEBUG_REDFISH_THIS_MODULE(DebugSubordinate, ...) \
> +  while (RedfishPlatformConfigDebugProp (DebugSubordinate)) { \
> +    DEBUG_REDFISH(DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE,
> ##__VA_ARGS__); \
> +    break; \
> +  }
> +
> +#define DEBUG_REDFISH_THIS_MODULE_CODE_BEGIN(DebugSubordinate) \
> +  if (RedfishPlatformConfigDebugProp (DebugSubordinate)) {
> +
> +#define DEBUG_REDFISH_THIS_MODULE_CODE_END()  }
> +
> +#define DEBUG_REDFISH_THIS_MODULE_CODE(DebugSubordinate, Expression)
> \
> +  DEBUG_REDFISH_THIS_MODULE_CODE_BEGIN(DebugSubordinate) \
> +  Expression \
> +  DEBUG_REDFISH_THIS_MODULE_CODE_END()
> +
> +// Subordinate debug property for DEBUG_REDFISH_PLATFORM_CONFIG_DXE
> +#define REDFISH_PLATFORM_CONFIG_DEBUG_STRING_DATABASE
> 0x00000001
> +#define REDFISH_PLATFORM_CONFIG_DEBUG_DUMP_FORMSET
> 0x00000002
> +#define REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_SEARCH
> 0x00000004
> +#define REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_REGEX
> 0x00000008
> +
>  ///
>  /// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
>  ///
> @@ -75,8 +113,12 @@ typedef struct {
>  #define REGULAR_EXPRESSION_INCLUDE_ALL   L".*"
>  #define CONFIGURE_LANGUAGE_PREFIX        "x-uefi-redfish-"
>  #define REDFISH_PLATFORM_CONFIG_VERSION  0x00010000
> -#define REDFISH_PLATFORM_CONFIG_DEBUG    DEBUG_MANAGEABILITY
> -#define REDFISH_MENU_PATH_SIZE           8
> +
> +#define REDFISH_MENU_PATH_SIZE  8
> +
> +// Definitions of Redfish platform config capbility
> +#define REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH   0x000000001
> +#define REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED  0x000000002
> 
>  /**
>    Convert input unicode string to ascii string. It's caller's diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> index 6e6c7fdb8a9..09d9789f574 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> @@ -418,4 +418,32 @@ HiiStrSize (
>    IN      CONST CHAR16  *String
>    );
> 
> +/**
> +  Check if the debug property is enabled or not.
> +
> +  @param[in]  DebugType  Debug enablement type
> +
> +  @retval TRUE, the debug property is enabled.
> +          FALSE, the debug property is not enabled.
> +
> +**/
> +BOOLEAN
> +RedfishPlatformConfigDebugProp (
> +  IN UINT64  DebugProp
> +  );
> +
> +/**
> +  Check if the Platform Configure feature is enabled or not.
> +
> +  @param[in]  FeatureType  Redfish platform config feature enablement
> +
> +  @retval TRUE, the feature is enabled.
> +          FALSE, the feature is not enabled.
> +
> +**/
> +BOOLEAN
> +RedfishPlatformConfigFeatureProp (
> +  IN UINT64  FeatureProp
> +  );
> +
>  #endif
> diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c
> new file mode 100644
> index 00000000000..753c4d393f3
> --- /dev/null
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapabilit
> +++ y.c
> @@ -0,0 +1,58 @@
> +/** @file
> +  The implementation of EDKII Redfish Platform Config Capability.
> +  Copyright (C) 2024 Advanced Micro Devices, Inc. All rights
> +reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "RedfishPlatformConfigDxe.h"
> +#include "RedfishPlatformConfigImpl.h"
> +
> +/**
> +  Check if the debug property is enabled or not.
> +
> +  @param[in]  DebugType  Debug enablement type
> +
> +  @retval TRUE, the debug property is enabled.
> +          FALSE, the debug property is not enabled.
> +
> +**/
> +BOOLEAN
> +RedfishPlatformConfigDebugProp (
> +  IN UINT64  DebugType
> +  )
> +{
> +  UINT64  DebugProp;
> +
> +  DebugProp = FixedPcdGet64 (PcdRedfishPlatformConfigDebugProperty);
> +  if ((DebugProp & DebugType) != 0) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Check if the Platform Configure feature is enabled or not.
> +
> +  @param[in]  FeatureType  Redfish platform config feature enablement
> +
> +  @retval TRUE, the feature is enabled.
> +          FALSE, the feature is not enabled.
> +
> +**/
> +BOOLEAN
> +RedfishPlatformConfigFeatureProp (
> +  IN UINT64  FeatureType
> +  )
> +{
> +  UINT64  FeatureProp;
> +
> +  FeatureProp = FixedPcdGet64
> + (PcdRedfishPlatformConfigFeatureProperty);
> +  if ((FeatureProp & FeatureType) != 0) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> index 664b48eb50e..8a02c839035 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> @@ -315,7 +315,7 @@ DumpHiiStatementPrompt (
> 
>  **/
>  CHAR8 *
> -BuildMenPath (
> +BuildMenuPath (
>    IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *StatementPrivate
>    )
>  {
> @@ -345,7 +345,7 @@ BuildMenPath (
>    }
> 
>    do {
> -    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "F(%d) <-", FormPrivate->Id));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "F(%d) <-",
> + FormPrivate->Id));
>      FormPrivate = FindFormLinkToThis (FormPrivate);
>      if (FormPrivate == NULL) {
>        break;
> @@ -387,7 +387,7 @@ BuildMenPath (
>        AsciiStrCatS (Buffer, OldBufferSize, "/");
>        AsciiStrCatS (Buffer, OldBufferSize, FormTitle);
>        FreePool (FormTitle);
> -      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, " %a\n", Buffer));
> +      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, " %a\n", Buffer));
>      }
> 
>      FormPrivate = (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE
> *)PopRedfishStack (FormStack); @@ -1061,12 +1061,12 @@
> DumpOrderedListValue (
>      return;
>    }
> 
> -  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.Type= 0x%x\n",
> OrderedListStatement->Value.Type));
> -  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.BufferValueType=
> 0x%x\n", OrderedListStatement->Value.BufferValueType));
> -  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.BufferLen= 0x%x\n",
> OrderedListStatement->Value.BufferLen));
> -  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.Buffer= 0x%x\n",
> OrderedListStatement->Value.Buffer));
> -  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "Value.MaxContainers=
> 0x%x\n", OrderedListStatement->ExtraData.OrderListData.MaxContainers));
> -  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "StorageWidth= 0x%x\n",
> OrderedListStatement->StorageWidth));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.Type= 0x%x\n",
> + OrderedListStatement->Value.Type));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.BufferValueType=
> + 0x%x\n", OrderedListStatement->Value.BufferValueType));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.BufferLen= 0x%x\n",
> + OrderedListStatement->Value.BufferLen));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.Buffer= 0x%x\n",
> + OrderedListStatement->Value.Buffer));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "Value.MaxContainers=
> 0x%x\n",
> + OrderedListStatement->ExtraData.OrderListData.MaxContainers));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "StorageWidth= 0x%x\n",
> + OrderedListStatement->StorageWidth));
> 
>    if (OrderedListStatement->Value.Buffer == NULL) {
>      return;
> @@ -1083,7 +1083,7 @@ DumpOrderedListValue (
>        Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
>        Count  = OrderedListStatement->StorageWidth / sizeof (UINT8);
>        for (Index = 0; Index < Count; Index++) {
> -        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value8[Index]));
> +        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value8[Index]));
>        }
> 
>        break;
> @@ -1091,7 +1091,7 @@ DumpOrderedListValue (
>        Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
>        Count   = OrderedListStatement->StorageWidth / sizeof (UINT16);
>        for (Index = 0; Index < Count; Index++) {
> -        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value16[Index]));
> +        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value16[Index]));
>        }
> 
>        break;
> @@ -1099,7 +1099,7 @@ DumpOrderedListValue (
>        Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
>        Count   = OrderedListStatement->StorageWidth / sizeof (UINT32);
>        for (Index = 0; Index < Count; Index++) {
> -        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value32[Index]));
> +        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value32[Index]));
>        }
> 
>        break;
> @@ -1107,7 +1107,7 @@ DumpOrderedListValue (
>        Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
>        Count   = OrderedListStatement->StorageWidth / sizeof (UINT64);
>        for (Index = 0; Index < Count; Index++) {
> -        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value64[Index]));
> +        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value64[Index]));
>        }
> 
>        break;
> @@ -1115,13 +1115,13 @@ DumpOrderedListValue (
>        Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
>        Count  = OrderedListStatement->StorageWidth / sizeof (UINT8);
>        for (Index = 0; Index < Count; Index++) {
> -        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%d ", Value8[Index]));
> +        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%d ", Value8[Index]));
>        }
> 
>        break;
>    }
> 
> -  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "\n"));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
>  }
> 
>  /**
> @@ -2013,6 +2013,8 @@ RedfishPlatformConfigProtocolGetConfigureLang (
>    UINTN                                           Index;
>    CHAR8                                           *FullSchema;
> 
> +  DEBUG ((DEBUG_INFO, "%a: Harvest config language of %a_%a (Regex:
> + %s).\n", __func__, Schema, Version, RegexPattern));
> +
>    if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || (Count == NULL) || (ConfigureLangList == NULL) ||
> IS_EMPTY_STRING (RegexPattern)) {
>      return EFI_INVALID_PARAMETER;
>    }
> @@ -2072,6 +2074,22 @@ RedfishPlatformConfigProtocolGetConfigureLang (
>    *Count             = StatementList.Count;
>    *ConfigureLangList = TmpConfigureLangList;
> 
> +  DEBUG_REDFISH_THIS_MODULE (
> +    REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_REGEX,
> +    "%a: Number of configure language strings harvested: %d\n",
> +    __func__,
> +    StatementList.Count
> +    );
> +
> +  DEBUG_REDFISH_THIS_MODULE_CODE (
> +    REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_REGEX,
> +    DEBUG_REDFISH (DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE,
> "%a: Number of configure language strings harvested: %d\n", __func__,
> StatementList.Count);
> +    for (Index = 0; Index < *Count; Index++) {
> +    DEBUG_REDFISH (DEBUG_REDFISH_COMPONENT_PLATFORM_CONFIG_DXE,
> "   (%d) %s\n", Index, TmpConfigureLangList[Index]);
> +  }
> +
> +    );
> +
>  RELEASE_RESOURCE:
> 
>    if (FullSchema != NULL) {
> @@ -2082,6 +2100,7 @@ RELEASE_RESOURCE:
>      ReleaseStatementList (&StatementList);
>    }
> 
> +  DEBUG ((DEBUG_INFO, "%a: exit.\n", __func__));
>    return Status;
>  }
> 
> @@ -2296,6 +2315,7 @@ RedfishPlatformConfigProtocolGetAttribute (
>    CHAR8                                      *FullSchema;
>    CHAR8                                      *Buffer;
> 
> +  DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__));
>    if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang) || (AttributeValue == NULL)) {
>      return EFI_INVALID_PARAMETER;
>    }
> @@ -2337,9 +2357,11 @@ RedfishPlatformConfigProtocolGetAttribute (
>    //
>    // Build up menu path
>    //
> -  AttributeValue->MenuPath = BuildMenPath (TargetStatement);
> -  if (AttributeValue->MenuPath == NULL) {
> -    DEBUG ((DEBUG_ERROR, "%a: failed to build menu path for \"%a\"\n",
> __func__, AttributeValue->AttributeName));
> +  if (RedfishPlatformConfigFeatureProp
> (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
> +    AttributeValue->MenuPath = BuildMenuPath (TargetStatement);
> +    if (AttributeValue->MenuPath == NULL) {
> +      DEBUG ((DEBUG_ERROR, "%a: failed to build menu path for \"%a\"\n",
> __func__, AttributeValue->AttributeName));
> +    }
>    }
> 
>    //
> @@ -2370,6 +2392,7 @@ RELEASE_RESOURCE:
>      FreePool (FullSchema);
>    }
> 
> +  DEBUG ((DEBUG_INFO, "%a: Exit\n", __func__));
>    return Status;
>  }
> 
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> index 8b1ddf4360a..537ce09a2d3 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> @@ -32,7 +32,7 @@ DumpHiiString (
>    EFI_STRING  String;
> 
>    if ((HiiHandle == NULL) || (StringId == 0)) {
> -    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "???"));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "???"));
>      return EFI_INVALID_PARAMETER;
>    }
> 
> @@ -41,7 +41,7 @@ DumpHiiString (
>      return EFI_NOT_FOUND;
>    }
> 
> -  DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%s", String));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%s", String));
>    FreePool (String);
> 
>    return EFI_SUCCESS;
> @@ -79,18 +79,18 @@ DumpFormset (
>      HiiFormPrivate  = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
>      HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
> 
> -    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "  [%d] form: %d title: ",
> ++Index, HiiFormPrivate->Id));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  [%d] form: %d title: ",
> + ++Index, HiiFormPrivate->Id));
>      DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
> -    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "\n"));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
> 
>      HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
>      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
>        HiiStatementPrivate  =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
>        HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> 
> -      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "    QID: 0x%x Prompt: ",
> HiiStatementPrivate->QuestionId));
> +      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "    QID: 0x%x Prompt: ",
> HiiStatementPrivate->QuestionId));
>        DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
> >Description);
> -      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "\n"));
> +      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "\n"));
> 
>        HiiStatementLink = HiiNextStatementLink;
>      }
> @@ -125,7 +125,7 @@ DumpFormsetList (
>    }
> 
>    if (IsListEmpty (FormsetList)) {
> -    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: Empty formset list\n",
> __func__));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Empty formset list\n",
> + __func__));
>      return EFI_SUCCESS;
>    }
> 
> @@ -135,7 +135,7 @@ DumpFormsetList (
>      HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
>      HiiFormsetPrivate  = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK
> (HiiFormsetLink);
> 
> -    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "[%d] HII Handle: 0x%x
> formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle,
> &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "[%d] HII Handle: 0x%x
> + formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle,
> + &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
>      DumpFormset (HiiFormsetPrivate);
> 
>      HiiFormsetLink = HiiFormsetNextLink; @@ -622,7 +622,9 @@
> GetStatementPrivateByConfigureLangRegex (
>          HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
>          HiiStatementPrivate  =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> 
> -        if ((HiiStatementPrivate->Description != 0) && !HiiStatementPrivate-
> >Suppressed) {
> +        if ((HiiStatementPrivate->Description != 0) &&
> +            (RedfishPlatformConfigFeatureProp
> (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate-
> >Suppressed))
> +        {
>            TmpString = HiiStatementPrivate->DescriptionStr;
>            if (TmpString != NULL) {
>              Status = RegularExpressionProtocol->MatchString ( @@ -698,6 +700,7
> @@ GetStatementPrivateByConfigureLang (
>    LIST_ENTRY                                 *HiiNextStatementLink;
>    REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  *HiiStatementPrivate;
>    EFI_STRING                                 TmpString;
> +  UINTN                                      Index;
> 
>    if ((FormsetList == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (ConfigureLang)) {
>      return NULL;
> @@ -707,6 +710,7 @@ GetStatementPrivateByConfigureLang (
>      return NULL;
>    }
> 
> +  Index          = 0;
>    HiiFormsetLink = GetFirstNode (FormsetList);
>    while (!IsNull (FormsetList, HiiFormsetLink)) {
>      HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink); @@ -
> 731,15 +735,22 @@ GetStatementPrivateByConfigureLang (
>          HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
>          HiiStatementPrivate  =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> 
> -        DEBUG_CODE (
> -          STATIC UINTN Index = 0;
> -          Index++;
> -          DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: [%d] search %s in
> QID: 0x%x form: 0x%x formset: %g\n", __func__, Index, ConfigureLang,
> HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate-
> >Guid));
> -          );
> -
> -        if (HiiStatementPrivate->Description != 0) {
> +        if ((HiiStatementPrivate->Description != 0) &&
> +            (RedfishPlatformConfigFeatureProp
> (REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED) || !HiiStatementPrivate-
> >Suppressed))
> +        {
>            TmpString = HiiStatementPrivate->DescriptionStr;
>            if (TmpString != NULL) {
> +            Index++;
> +            DEBUG_REDFISH_THIS_MODULE (
> +              REDFISH_PLATFORM_CONFIG_DEBUG_CONFIG_LANG_SEARCH,
> +              "%a: [%d] check %s in QID: 0x%x form: 0x%x formset: %g\n",
> +              __func__,
> +              Index,
> +              ConfigureLang,
> +              HiiStatementPrivate->QuestionId,
> +              HiiFormPrivate->Id,
> +              &HiiFormsetPrivate->Guid
> +              );
>              if (HiiStrCmp (TmpString, ConfigureLang) == 0) {
>                return HiiStatementPrivate;
>              }
> @@ -1022,7 +1033,7 @@ NewRedfishXuefiStringArray (
> 
>  **/
>  REDFISH_X_UEFI_STRING_DATABASE *
> -GetExitOrCreateXuefiStringDatabase (
> +GetExistOrCreateXuefiStringDatabase (
>    IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
>    IN  EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader
>    )
> @@ -1031,8 +1042,6 @@ GetExitOrCreateXuefiStringDatabase (
>    BOOLEAN                         CreateNewOne;
>    REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;
> 
> -  DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__));
> -
>    CreateNewOne               = TRUE;
>    XuefiRedfishStringDatabase = NULL;
>    if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) { @@ -1054,7
> +1063,7 @@ GetExitOrCreateXuefiStringDatabase (
>    }
> 
>    if (CreateNewOne) {
> -    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "  Creating x-uefi-redfish
> (%a) string database...\n", HiiStringPackageHeader->Language));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  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"));
> @@ -1073,7 +1082,7 @@ GetExitOrCreateXuefiStringDatabase (
>      }
> 
>      DEBUG ((
> -      REDFISH_PLATFORM_CONFIG_DEBUG,
> +      DEBUG_REDFISH_PLATFORM_CONFIG,
>        "  x-uefi-redfish (%a):\n    String array is added to XuefiRedfishStringDatabase,
> total %d arrays now.\n",
>        XuefiRedfishStringDatabase->XuefiRedfishLanguage,
>        XuefiRedfishStringDatabase->StringsArrayBlocks
> @@ -1145,7 +1154,7 @@ RedfishXuefiStringInsertDatabase (
>    REDFISH_X_UEFI_STRING_DATABASE  *XuefiRedfishStringDatabase;
>    REDFISH_X_UEFI_STRINGS_ARRAY    *ThisArray;
> 
> -  XuefiRedfishStringDatabase = GetExitOrCreateXuefiStringDatabase
> (FormsetPrivate, HiiStringPackageHeader);
> +  XuefiRedfishStringDatabase = GetExistOrCreateXuefiStringDatabase
> + (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); @@ -1170,21 +1179,22 @@
> RedfishXuefiStringInsertDatabase (
>    (ThisArray->ArrayEntryAddress + StringIdOffset)->StringId  = StringId;
>    (ThisArray->ArrayEntryAddress + StringIdOffset)->UcsString = StringTextPtr;
> 
> -  DEBUG ((
> -    REDFISH_PLATFORM_CONFIG_DEBUG,
> +  DEBUG_REDFISH_THIS_MODULE (
> +    REDFISH_PLATFORM_CONFIG_DEBUG_STRING_DATABASE,
>      "  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.
> +  @param[in]       FormsetPrivate          Pointer to HII form-set private instance.
> +  @param[in]       HiiStringPackageHeader  HII string package header.
> +  @param[out]      TotalStringAdded        Return the total strings added to
> database.
> 
>    @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.
> @@ -1192,8 +1202,9 @@ RedfishXuefiStringInsertDatabase (  **/  BOOLEAN
> CreateXuefiLanguageStringIdMap (
> -  IN  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
> -  IN  EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader
> +  IN   REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
> +  IN   EFI_HII_STRING_PACKAGE_HDR                *HiiStringPackageHeader,
> +  OUT  UINTN                                     *TotalStringAdded
>    )
>  {
>    EFI_STATUS               Status;
> @@ -1209,6 +1220,9 @@ CreateXuefiLanguageStringIdMap (
>    EFI_HII_SIBT_EXT2_BLOCK  Ext2;
>    UINT32                   Length32;
>    UINT8                    *StringBlockInfo;
> +  UINTN                    StringsAdded;
> +
> +  StringsAdded = 0;
> 
>    //
>    // Parse the string blocks to get the string text and font.
> @@ -1280,6 +1294,8 @@ CreateXuefiLanguageStringIdMap (
>              DEBUG ((DEBUG_ERROR, "%a: Failed to insert x-uefi-redfish string %s.\n",
> __func__, StringTextPtr));
>              return FALSE;
>            }
> +
> +          StringsAdded++;
>          }
> 
>          BlockSize += (Offset + HiiStrSize ((CHAR16 *)StringTextPtr)); @@ -1371,6
> +1387,7 @@ CreateXuefiLanguageStringIdMap (
>      BlockHdr = (UINT8 *)(StringBlockInfo + BlockSize);
>    }
> 
> +  *TotalStringAdded = StringsAdded;
>    return TRUE;
>  }
> 
> @@ -1484,6 +1501,8 @@ BuildXUefiRedfishStringDatabase (
>    UINTN                       SupportedSchemaLangCount;
>    CHAR8                       **SupportedSchemaLang;
>    BOOLEAN                     StringIdMapIsBuilt;
> +  UINTN                       TotalStringsAdded;
> +  UINTN                       NumberPackageStrings;
> 
>    DEBUG ((DEBUG_INFO, "%a: Building x-uefi-redfish string database, HII Formset
> GUID - %g.\n", __func__, FormsetPrivate->Guid));
> 
> @@ -1515,6 +1534,7 @@ BuildXUefiRedfishStringDatabase (
>      return;
>    }
> 
> +  TotalStringsAdded = 0;
>    //
>    // Finding the string package.
>    //
> @@ -1539,14 +1559,18 @@ BuildXUefiRedfishStringDatabase (
>                  AsciiStrLen (HiiStringPackageHeader->Language)
>                  ) == 0)
>            {
> -            StringIdMapIsBuilt = CreateXuefiLanguageStringIdMap (FormsetPrivate,
> HiiStringPackageHeader);
> +            StringIdMapIsBuilt = CreateXuefiLanguageStringIdMap (FormsetPrivate,
> HiiStringPackageHeader, &NumberPackageStrings);
> +            if (StringIdMapIsBuilt) {
> +              TotalStringsAdded += NumberPackageStrings;
> +            }
> +
>              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));
> +            DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  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));
>            }
> @@ -1556,6 +1580,8 @@ BuildXUefiRedfishStringDatabase (
>          PackageHeader = (EFI_HII_PACKAGE_HEADER *)((UINTN)PackageHeader +
> PackageHeader->Length);
>      }
>    }
> +
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "  Total %d x-uefi-redfish
> + config language are added.\n", TotalStringsAdded));
>  }
> 
>  /**
> @@ -1621,7 +1647,7 @@ 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 x-uefi-redfish
> configuration found on the formset - %g\n", __func__, FormsetPrivate->Guid));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%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 @@ -1789,7 +1815,10 @@
> LoadFormsetList (
>    InsertTailList (FormsetList, &FormsetPrivate->Link);
> 
>    DEBUG_CODE (
> +    if (RedfishPlatformConfigDebugProp
> + (REDFISH_PLATFORM_CONFIG_DEBUG_DUMP_FORMSET)) {
>      DumpFormsetList (FormsetList);
> +  }
> +
>      );
> 
>    return EFI_SUCCESS;
> @@ -1909,7 +1938,7 @@ NotifyFormsetUpdate (
>    if (TargetPendingList != NULL) {
>      TargetPendingList->IsDeleted = FALSE;
>      DEBUG_CODE (
> -      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is
> updated\n", __func__, HiiHandle));
> +      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is
> + updated\n", __func__, HiiHandle));
>        );
>      return EFI_SUCCESS;
>    }
> @@ -1925,7 +1954,7 @@ NotifyFormsetUpdate (
>    InsertTailList (PendingList, &TargetPendingList->Link);
> 
>    DEBUG_CODE (
> -    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is
> created\n", __func__, HiiHandle));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is
> + created\n", __func__, HiiHandle));
>      );
> 
>    return EFI_SUCCESS;
> @@ -1962,7 +1991,7 @@ NotifyFormsetDeleted (
>    if (TargetPendingList != NULL) {
>      TargetPendingList->IsDeleted = TRUE;
>      DEBUG_CODE (
> -      DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is
> updated and deleted\n", __func__, HiiHandle));
> +      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is
> + updated and deleted\n", __func__, HiiHandle));
>        );
>      return EFI_SUCCESS;
>    }
> @@ -1978,7 +2007,7 @@ NotifyFormsetDeleted (
>    InsertTailList (PendingList, &TargetPendingList->Link);
> 
>    DEBUG_CODE (
> -    DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: HII handle: 0x%x is
> deleted\n", __func__, HiiHandle));
> +    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: HII handle: 0x%x is
> + deleted\n", __func__, HiiHandle));
>      );
> 
>    return EFI_SUCCESS;
> @@ -2027,12 +2056,12 @@ ProcessPendingList (
>        //
>        FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
>        if (FormsetPrivate != NULL) {
> -        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: formset: %g is
> removed because driver release HII resource it already\n", __func__,
> FormsetPrivate->Guid));
> +        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is
> + removed because driver release HII resource it already\n", __func__,
> + FormsetPrivate->Guid));
>          RemoveEntryList (&FormsetPrivate->Link);
>          ReleaseFormset (FormsetPrivate);
>          FreePool (FormsetPrivate);
>        } else {
> -        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: formset on HII handle
> 0x%x was removed already\n", __func__, Target->HiiHandle));
> +        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset on HII
> + handle 0x%x was removed already\n", __func__, Target->HiiHandle));
>        }
>      } else {
>        //
> @@ -2043,7 +2072,7 @@ ProcessPendingList (
>          //
>          // HII formset already exist, release it and query again.
>          //
> -        DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, "%a: formset: %g is
> updated. Release current formset\n", __func__, &FormsetPrivate->Guid));
> +        DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: formset: %g is
> + updated. Release current formset\n", __func__,
> + &FormsetPrivate->Guid));
>          RemoveEntryList (&FormsetPrivate->Link);
>          ReleaseFormset (FormsetPrivate);
>          FreePool (FormsetPrivate);
> --
> 2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117153): https://edk2.groups.io/g/devel/message/117153
Mute This Topic: https://groups.io/mt/105159787/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 4/6] RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted unexpectedly
  2024-03-26 15:15 ` [edk2-devel] [PATCH V2 4/6] RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted unexpectedly Chang, Abner via groups.io
@ 2024-03-27  7:39   ` Nickle Wang via groups.io
  0 siblings, 0 replies; 20+ messages in thread
From: Nickle Wang via groups.io @ 2024-03-27  7:39 UTC (permalink / raw)
  To: abner.chang, devel; +Cc: Igor Kulchytskyy

Thanks for addressing this issue.


Reviewed-by: Nickle Wang <nicklew@nvidia.com>

Regards,
Nickle

> -----Original Message-----
> From: abner.chang@amd.com <abner.chang@amd.com>
> Sent: Tuesday, March 26, 2024 11:15 PM
> To: devel@edk2.groups.io
> Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> Subject: [PATCH V2 4/6] RedfishPkg/RedfishPlatformConfigDxe: HII string is
> deleted unexpectedly
> 
> External email: Use caution opening links or attachments
> 
> 
> From: Abner Chang <abner.chang@amd.com>
> 
> Add the condition check when delete HII string.
> Only when the HiiStatement operand equal to "EFI_IFR_STRING_OP"
> and the statement value type = EFI_IFR_TYPE_STRING.
> 
> Signed-off-by: Abner Chang <abner.chang@amd.com>
> Co-authored-by: Nickle Wang <nicklew@nvidia.com>
> Cc: Igor Kulchytskyy <igork@ami.com>
> ---
>  .../RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c    | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> index 8a02c839035..d165799f9a1 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> @@ -1873,8 +1873,11 @@ RedfishPlatformConfigSetStatementCommon (
>      DEBUG ((DEBUG_ERROR, "%a: failed to save question value: %r\n", __func__,
> Status));
>    }
> 
> -  if (StatementValue->Value.string != 0) {
> -    HiiDeleteString (StatementValue->Value.string, TargetStatement-
> >ParentForm->ParentFormset->HiiHandle);
> +  if ((TargetStatement->HiiStatement->Operand == EFI_IFR_STRING_OP) &&
> (StatementValue->Type == EFI_IFR_TYPE_STRING)) {
> +    if (StatementValue->Value.string != 0) {
> +      // Delete HII string which was created for HII statement operand =
> EFI_IFR_STRING_OP and Type = EFI_IFR_TYPE_STRING.
> +      HiiDeleteString (StatementValue->Value.string, TargetStatement-
> >ParentForm->ParentFormset->HiiHandle);
> +    }
>    }
> 
>    return Status;
> --
> 2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117154): https://edk2.groups.io/g/devel/message/117154
Mute This Topic: https://groups.io/mt/105159786/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 5/6] EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs
  2024-03-26 15:15 ` [edk2-devel] [PATCH V2 5/6] EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs Chang, Abner via groups.io
@ 2024-03-27  7:39   ` Nickle Wang via groups.io
  0 siblings, 0 replies; 20+ messages in thread
From: Nickle Wang via groups.io @ 2024-03-27  7:39 UTC (permalink / raw)
  To: abner.chang, devel



Reviewed-by: Nickle Wang <nicklew@nvidia.com>

Regards,
Nickle

> -----Original Message-----
> From: abner.chang@amd.com <abner.chang@amd.com>
> Sent: Tuesday, March 26, 2024 11:15 PM
> To: devel@edk2.groups.io
> Cc: Nickle Wang <nicklew@nvidia.com>
> Subject: [PATCH V2 5/6] EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs
> 
> External email: Use caution opening links or attachments
> 
> 
> From: Abner Chang <abner.chang@amd.com>
> 
> Signed-off-by: Abner Chang <abner.chang@amd.com>
> Cc: Nickle Wang <nicklew@nvidia.com>
> ---
>  EmulatorPkg/EmulatorPkg.dsc | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index
> 85134b07816..5fa1ed345a3 100644
> --- a/EmulatorPkg/EmulatorPkg.dsc
> +++ b/EmulatorPkg/EmulatorPkg.dsc
> @@ -278,6 +278,27 @@
> 
> gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath.DevicePath|{
> DEVICE_PATH("MAC(000000000000,0x1)")}
> 
> gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBand|Fals
> e
>    gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDiscoverAccessModeInBand|False
> +
> +
> + gEmulatorPkgTokenSpaceGuid.PcdRedfishServiceStopIfSecureBootDisabled|F
> + alse
> + gEmulatorPkgTokenSpaceGuid.PcdRedfishServiceStopIfExitbootService|Fals
> + e
> +
> +
> + gEfiRedfishClientPkgTokenSpaceGuid.PcdRedfishServiceEtagSupported|Fals
> + e
> +
> +  #
> +  # Redfish Debug enablement
> +  #
> +  # 0x0000000000000001  RedfishPlatformConfigDxe driver debug enabled.
> +  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDebugCategory|0
> +  #   0x00000001  x-uefi-redfish string database message enabled
> +  #   0x00000002  Debug Message for dumping formset
> +  #   0x00000004  Debug Message for x-uefi-redfish searching result
> +  #   0x00000008  Debug Message for x-uefi-redfish Regular Expression searching
> result
> +  gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigDebugProperty|0
> +
> +  # Redfish Platform Configure DXE driver feature enablement
> +  #   0x00000001  Enable building Redfish Attribute Registry menu path.
> +  #   0x00000002  Allow supressed HII option to be exposed on Redfish.
> +
> + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishPlatformConfigFeatureProperty|0
>  !endif
> 
>  [PcdsDynamicDefault.common.DEFAULT]
> --
> 2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117155): https://edk2.groups.io/g/devel/message/117155
Mute This Topic: https://groups.io/mt/105159788/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 6/6] RedfishPkg/RedfishPlatformConfigDxe: support menu path report
  2024-03-26 15:15 ` [edk2-devel] [PATCH V2 6/6] RedfishPkg/RedfishPlatformConfigDxe: support menu path report Chang, Abner via groups.io
@ 2024-03-27  7:39   ` Nickle Wang via groups.io
  0 siblings, 0 replies; 20+ messages in thread
From: Nickle Wang via groups.io @ 2024-03-27  7:39 UTC (permalink / raw)
  To: devel, abner.chang; +Cc: Igor Kulchytskyy



Reviewed-by: Nickle Wang <nicklew@nvidia.com>

Regards,
Nickle

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chang, Abner
> via groups.io
> Sent: Tuesday, March 26, 2024 11:15 PM
> To: devel@edk2.groups.io
> Cc: Abner Chang <abner.chang@amd.com>; Igor Kulchytskyy <igork@ami.com>
> Subject: [edk2-devel] [PATCH V2 6/6] RedfishPkg/RedfishPlatformConfigDxe:
> support menu path report
> 
> External email: Use caution opening links or attachments
> 
> 
> From: Nickle Wang <nicklew@nvidia.com>
> 
> "MenuPath" is the attribute in BIOS attribute registry. To support reporting this
> attribute, we need to include the formset without x-uefi-redfish support in
> database. So driver can find menu path to target attribute in BIOS menu.
> 
> Signed-off-by: Nickle Wang <nicklew@nvidia.com>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Igor Kulchytskyy <igork@ami.com>
> Signed-off-by: Abner Chang <abner.chang@amd.com>
> ---
>  .../RedfishPlatformConfigDxe.h                |  8 +--
>  .../RedfishPlatformConfigDxe.c                |  8 +--
>  .../RedfishPlatformConfigImpl.c               | 51 +++++++++++++++----
>  3 files changed, 49 insertions(+), 18 deletions(-)
> 
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> index 688f2067bff..8eb7b0dc2aa 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> @@ -2,7 +2,7 @@
>    This file defines the EDKII Redfish Platform Config Protocol interface.
> 
>    (C) Copyright 2021 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 @@ -49,8 +49,8 @@  // 2
> RedfishPlatformConfigDxe debug enablement must be set in
>  //    PcdRedfishDebugCategory (defined in RedfishPkg.dec)
>  //
> -// 3. The suborinate debug enablement for RedfishPlatformConfigDxe
> -//    must be set in PcdRedfishPlatformConfigDebugPropert (defined
> +// 3. The subordinate debug enablement for RedfishPlatformConfigDxe
> +//    must be set in PcdRedfishPlatformConfigDebugProperty (defined
>  //    in RedfishPkg.dec).
>  //
>  #define DEBUG_REDFISH_THIS_MODULE(DebugSubordinate, ...) \ @@ -116,7
> +116,7 @@ typedef struct {
> 
>  #define REDFISH_MENU_PATH_SIZE  8
> 
> -// Definitions of Redfish platform config capbility
> +// Definitions of Redfish platform config capability
>  #define REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH   0x000000001
>  #define REDFISH_PLATFORM_CONFIG_ALLOW_SUPPRESSED  0x000000002
> 
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> index d165799f9a1..7821146e901 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> @@ -2016,7 +2016,7 @@ RedfishPlatformConfigProtocolGetConfigureLang (
>    UINTN                                           Index;
>    CHAR8                                           *FullSchema;
> 
> -  DEBUG ((DEBUG_INFO, "%a: Harvest config language of %a_%a (Regex:
> %s).\n", __func__, Schema, Version, RegexPattern));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Harvest config language
> + of %a_%a (Regex: %s).\n", __func__, Schema, Version, RegexPattern));
> 
>    if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || (Count == NULL) || (ConfigureLangList == NULL) ||
> IS_EMPTY_STRING (RegexPattern)) {
>      return EFI_INVALID_PARAMETER;
> @@ -2103,7 +2103,7 @@ RELEASE_RESOURCE:
>      ReleaseStatementList (&StatementList);
>    }
> 
> -  DEBUG ((DEBUG_INFO, "%a: exit.\n", __func__));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: exit.\n", __func__));
>    return Status;
>  }
> 
> @@ -2318,7 +2318,7 @@ RedfishPlatformConfigProtocolGetAttribute (
>    CHAR8                                      *FullSchema;
>    CHAR8                                      *Buffer;
> 
> -  DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Entry\n", __func__));
>    if ((This == NULL) || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang) || (AttributeValue == NULL)) {
>      return EFI_INVALID_PARAMETER;
>    }
> @@ -2395,7 +2395,7 @@ RELEASE_RESOURCE:
>      FreePool (FullSchema);
>    }
> 
> -  DEBUG ((DEBUG_INFO, "%a: Exit\n", __func__));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Exit\n", __func__));
>    return Status;
>  }
> 
> diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> index 537ce09a2d3..86f3aa529c5 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> @@ -2,7 +2,7 @@
>    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 @@ -656,8 +656,10 @@
> GetStatementPrivateByConfigureLangRegex (
>                ++StatementList->Count;
>              }
>            } else {
> -            DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->DescriptionStr is
> NULL, x-uefi-string has something wrong.\n", __func__));
> -            ASSERT (FALSE);
> +            if (!RedfishPlatformConfigFeatureProp
> (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
> +              DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->DescriptionStr is
> NULL, x-uefi-string has something wrong.\n", __func__));
> +              ASSERT (FALSE);
> +            }
>            }
>          }
> 
> @@ -754,6 +756,11 @@ GetStatementPrivateByConfigureLang (
>              if (HiiStrCmp (TmpString, ConfigureLang) == 0) {
>                return HiiStatementPrivate;
>              }
> +          } else {
> +            if (!RedfishPlatformConfigFeatureProp
> (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
> +              DEBUG ((DEBUG_ERROR, "%a: HiiStatementPrivate->DescriptionStr is
> NULL, x-uefi-string has something wrong.\n", __func__));
> +              ASSERT (FALSE);
> +            }
>            }
>          }
> 
> @@ -1440,7 +1447,7 @@ GetXuefiStringAndLangByStringId (
>      StringIndex = StringId;
>      while (StringIndex >= X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) {
>        if (IsNodeAtEnd (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays,
> &StringArray->NextArray)) {
> -        goto ErrorEixt;
> +        goto ErrorExit;
>        }
> 
>        StringArray  = (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode
> (&XuefiRedfishStringDatabase->XuefiRedfishStringArrays, &StringArray-
> >NextArray); @@ -1477,8 +1484,8 @@ GetXuefiStringAndLangByStringId (
>                                                                       );
>    }
> 
> -ErrorEixt:;
> -  DEBUG ((DEBUG_ERROR, "%a: String ID (%d) is not in any x-uef-redfish string
> databases.\n", __func__, StringId));
> +ErrorExit:;
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: String ID (%d) is not in
> +any x-uef-redfish string databases.\n", __func__, StringId));
>    return EFI_NOT_FOUND;
>  }
> 
> @@ -1504,7 +1511,7 @@ BuildXUefiRedfishStringDatabase (
>    UINTN                       TotalStringsAdded;
>    UINTN                       NumberPackageStrings;
> 
> -  DEBUG ((DEBUG_INFO, "%a: Building x-uefi-redfish string database, HII
> Formset GUID - %g.\n", __func__, FormsetPrivate->Guid));
> +  DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: Building x-uefi-redfish
> + string database, HII Formset GUID - %g.\n", __func__,
> + FormsetPrivate->Guid));
> 
>    BufferSize = 0;
>    Status     = mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageLists (
> @@ -1531,6 +1538,8 @@ BuildXUefiRedfishStringDatabase (
>                                                           FormsetPrivate->HiiPackageListHeader
>                                                           );
>    if (EFI_ERROR (Status)) {
> +    FreePool (FormsetPrivate->HiiPackageListHeader);
> +    FormsetPrivate->HiiPackageListHeader = NULL;
>      return;
>    }
> 
> @@ -1647,8 +1656,14 @@ LoadFormset (
>    FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
> >DevicePath, FALSE, FALSE);
>    Status                        = GetSupportedSchema (FormsetPrivate->HiiHandle,
> &FormsetPrivate->SupportedSchema);
>    if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%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.
> +    if (!RedfishPlatformConfigFeatureProp
> (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
> +      DEBUG ((DEBUG_REDFISH_PLATFORM_CONFIG, "%a: No x-uefi-redfish
> configuration found on the formset - %g\n", __func__, FormsetPrivate->Guid));
> +      //
> +      // If there is no x-uefi-redfish language in this form-set, we don't add formset
> +      // since we don't need to build menu path for attribute registry.
> +      //
> +      return EFI_UNSUPPORTED;
> +    }
>    } else {
>      // Building x-uefi-redfish string database
>      BuildXUefiRedfishStringDatabase (FormsetPrivate); @@ -1734,7 +1749,23 @@
> LoadFormset (
>          //
>          InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
>        } else {
> -        FreePool (HiiStatementPrivate);
> +        if (!RedfishPlatformConfigFeatureProp
> (REDFISH_PLATFORM_CONFIG_BUILD_MENU_PATH)) {
> +          //
> +          // If there is no x-uefi-redfish language for this statement, we don't add
> this statement
> +          // since we don't need to build menu path for attribute registry.
> +          //
> +          FreePool (HiiStatementPrivate);
> +        } else {
> +          //
> +          // This is not x-uefi-redfish string and we don't cache its string for
> searching Redfish configure language.
> +          // When caller wants the string, we will read English string by calling
> HiiGetString().
> +          //
> +          HiiStatementPrivate->DescriptionStr = NULL;
> +          //
> +          // Attach to statement list.
> +          //
> +          InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> >Link);
> +        }
>        }
> 
>        HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> HiiStatementLink);
> --
> 2.37.1.windows.1
> 
> 
> 
> 
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117156): https://edk2.groups.io/g/devel/message/117156
Mute This Topic: https://groups.io/mt/105159789/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes
  2024-03-26 15:14 [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Chang, Abner via groups.io
                   ` (5 preceding siblings ...)
  2024-03-26 15:15 ` [edk2-devel] [PATCH V2 6/6] RedfishPkg/RedfishPlatformConfigDxe: support menu path report Chang, Abner via groups.io
@ 2024-03-27  7:41 ` Nickle Wang via groups.io
  2024-03-27  7:43   ` Chang, Abner via groups.io
  6 siblings, 1 reply; 20+ messages in thread
From: Nickle Wang via groups.io @ 2024-03-27  7:41 UTC (permalink / raw)
  To: abner.chang, devel; +Cc: Igor Kulchytskyy

I have tested this patch series on my system and got a lot of performance improvements too. 

Great work, Abner!

Regards,
Nickle

> -----Original Message-----
> From: abner.chang@amd.com <abner.chang@amd.com>
> Sent: Tuesday, March 26, 2024 11:15 PM
> To: devel@edk2.groups.io
> Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> Subject: [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm
> enhancement and the bug fixes
> 
> External email: Use caution opening links or attachments
> 
> 
> From: Abner Chang <abner.chang@amd.com>
> 
> PR # 5491
> 
> In V2, add patch 6/6 contibuted by Nvidia for updating BIOS menu path
> implementation based on the performance improvement.
> 
> In this patch set,
> 1 We enhance the config language searching algorithm.
>   As the performance of searching config language using HII GetString is
>   pretty slow. For the example, 1800 HII BIOS options takes over 30 mins
>   to build up the metadata required for Redfish BIOS resource. With this
>   improvement, it only takes 4 seconds.
> 
> 2.Introduce the Redfish debug framework, there are three edk2 Redfish
>   debug scopes.
>   a. PcdDebugPrintErrorLevel, DEBUG_MANAGEABILITY to enable debug message
>      for edk2 Redfish.
>   b. PcdRedfishDebugCategory, enablement of individule edk2 Redfish
>      component. Currently we only support RedfishPlatformConfigDxe
>      module.
>   c. PcdRedfishPlatformConfigDebugProperty, edk2 Redfish module debug
>      scope. This PCD is used by RedfishPlatformConfigDxe debug enablement.
> 
> 3 This patch set also fixes an issue that deletes HII string unexpectedly.
> 
> Signed-off-by: Abner Chang <abner.chang@amd.com>
> Co-authored-by: Nickle Wang <nicklew@nvidia.com>
> Cc: Igor Kulchytskyy <igork@ami.com>
> 
> Abner Chang (4):
>   RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro
>   RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support
>   RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted
>     unexpectedly
>   EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs
> 
> Nickle Wang (1):
>   RedfishPkg/RedfishPlatformConfigDxe: support menu path report
> 
> abnchang (1):
>   RedfishPkg/RedfishPlatformConfigDxe: Config language searching
>     optimization
> 
>  RedfishPkg/RedfishPkg.dec                     |  24 +
>  EmulatorPkg/EmulatorPkg.dsc                   |  21 +
>  .../RedfishDebugLib/RedfishDebugLib.inf       |   4 +
>  .../RedfishPlatformConfigDxe.inf              |   8 +
>  RedfishPkg/Include/Library/RedfishDebugLib.h  |  43 +-
>  .../RedfishPlatformConfigDxe.h                |  48 +-
>  .../RedfishPlatformConfigImpl.h               | 135 ++-
>  .../Library/RedfishDebugLib/RedfishDebugLib.c |  55 +-
>  .../RedfishPlatformConfigCapability.c         |  58 ++
>  .../RedfishPlatformConfigDxe.c                |  89 +-
>  .../RedfishPlatformConfigImpl.c               | 928 ++++++++++++++++--
>  11 files changed, 1240 insertions(+), 173 deletions(-)  create mode 100644
> RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c
> 
> --
> 2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117157): https://edk2.groups.io/g/devel/message/117157
Mute This Topic: https://groups.io/mt/105159781/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes
  2024-03-27  7:41 ` [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Nickle Wang via groups.io
@ 2024-03-27  7:43   ` Chang, Abner via groups.io
  2024-03-29 11:11     ` Igor Kulchytskyy via groups.io
  0 siblings, 1 reply; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-03-27  7:43 UTC (permalink / raw)
  To: Nickle Wang, devel; +Cc: Igor Kulchytskyy

[AMD Official Use Only - General]

Hi Igor,
If time is allowed, please also review this patch set.
Thanks
Abner

> -----Original Message-----
> From: Nickle Wang <nicklew@nvidia.com>
> Sent: Wednesday, March 27, 2024 3:42 PM
> To: Chang, Abner <Abner.Chang@amd.com>; devel@edk2.groups.io
> Cc: Igor Kulchytskyy <igork@ami.com>
> Subject: RE: [PATCH V2 0/6] [PATCH V2 0/5] Config language searching
> algorithm enhancement and the bug fixes
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> I have tested this patch series on my system and got a lot of performance
> improvements too.
>
> Great work, Abner!
>
> Regards,
> Nickle
>
> > -----Original Message-----
> > From: abner.chang@amd.com <abner.chang@amd.com>
> > Sent: Tuesday, March 26, 2024 11:15 PM
> > To: devel@edk2.groups.io
> > Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> > Subject: [PATCH V2 0/6] [PATCH V2 0/5] Config language searching
> algorithm
> > enhancement and the bug fixes
> >
> > External email: Use caution opening links or attachments
> >
> >
> > From: Abner Chang <abner.chang@amd.com>
> >
> > PR # 5491
> >
> > In V2, add patch 6/6 contibuted by Nvidia for updating BIOS menu path
> > implementation based on the performance improvement.
> >
> > In this patch set,
> > 1 We enhance the config language searching algorithm.
> >   As the performance of searching config language using HII GetString is
> >   pretty slow. For the example, 1800 HII BIOS options takes over 30 mins
> >   to build up the metadata required for Redfish BIOS resource. With this
> >   improvement, it only takes 4 seconds.
> >
> > 2.Introduce the Redfish debug framework, there are three edk2 Redfish
> >   debug scopes.
> >   a. PcdDebugPrintErrorLevel, DEBUG_MANAGEABILITY to enable debug
> message
> >      for edk2 Redfish.
> >   b. PcdRedfishDebugCategory, enablement of individule edk2 Redfish
> >      component. Currently we only support RedfishPlatformConfigDxe
> >      module.
> >   c. PcdRedfishPlatformConfigDebugProperty, edk2 Redfish module debug
> >      scope. This PCD is used by RedfishPlatformConfigDxe debug enablement.
> >
> > 3 This patch set also fixes an issue that deletes HII string unexpectedly.
> >
> > Signed-off-by: Abner Chang <abner.chang@amd.com>
> > Co-authored-by: Nickle Wang <nicklew@nvidia.com>
> > Cc: Igor Kulchytskyy <igork@ami.com>
> >
> > Abner Chang (4):
> >   RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro
> >   RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support
> >   RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted
> >     unexpectedly
> >   EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs
> >
> > Nickle Wang (1):
> >   RedfishPkg/RedfishPlatformConfigDxe: support menu path report
> >
> > abnchang (1):
> >   RedfishPkg/RedfishPlatformConfigDxe: Config language searching
> >     optimization
> >
> >  RedfishPkg/RedfishPkg.dec                     |  24 +
> >  EmulatorPkg/EmulatorPkg.dsc                   |  21 +
> >  .../RedfishDebugLib/RedfishDebugLib.inf       |   4 +
> >  .../RedfishPlatformConfigDxe.inf              |   8 +
> >  RedfishPkg/Include/Library/RedfishDebugLib.h  |  43 +-
> >  .../RedfishPlatformConfigDxe.h                |  48 +-
> >  .../RedfishPlatformConfigImpl.h               | 135 ++-
> >  .../Library/RedfishDebugLib/RedfishDebugLib.c |  55 +-
> >  .../RedfishPlatformConfigCapability.c         |  58 ++
> >  .../RedfishPlatformConfigDxe.c                |  89 +-
> >  .../RedfishPlatformConfigImpl.c               | 928 ++++++++++++++++--
> >  11 files changed, 1240 insertions(+), 173 deletions(-)  create mode 100644
> > RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c
> >
> > --
> > 2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117158): https://edk2.groups.io/g/devel/message/117158
Mute This Topic: https://groups.io/mt/105159781/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes
  2024-03-27  7:43   ` Chang, Abner via groups.io
@ 2024-03-29 11:11     ` Igor Kulchytskyy via groups.io
  0 siblings, 0 replies; 20+ messages in thread
From: Igor Kulchytskyy via groups.io @ 2024-03-29 11:11 UTC (permalink / raw)
  To: Chang, Abner, Nickle Wang, devel

[-- Attachment #1: Type: text/plain, Size: 5512 bytes --]

Hi Abner,
I'm very sorry, so busy those days with release.
I will be able to check it next week only.
Best regards,
Igor

Get Outlook for Android<https://aka.ms/AAb9ysg>
________________________________
From: Chang, Abner <Abner.Chang@amd.com>
Sent: Wednesday, March 27, 2024 3:43:55 AM
To: Nickle Wang <nicklew@nvidia.com>; devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Igor Kulchytskyy <igork@ami.com>
Subject: [EXTERNAL] RE: [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes


**CAUTION: The e-mail below is from an external source. Please exercise caution before opening attachments, clicking links, or following guidance.**

[AMD Official Use Only - General]

Hi Igor,
If time is allowed, please also review this patch set.
Thanks
Abner

> -----Original Message-----
> From: Nickle Wang <nicklew@nvidia.com>
> Sent: Wednesday, March 27, 2024 3:42 PM
> To: Chang, Abner <Abner.Chang@amd.com>; devel@edk2.groups.io
> Cc: Igor Kulchytskyy <igork@ami.com>
> Subject: RE: [PATCH V2 0/6] [PATCH V2 0/5] Config language searching
> algorithm enhancement and the bug fixes
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> I have tested this patch series on my system and got a lot of performance
> improvements too.
>
> Great work, Abner!
>
> Regards,
> Nickle
>
> > -----Original Message-----
> > From: abner.chang@amd.com <abner.chang@amd.com>
> > Sent: Tuesday, March 26, 2024 11:15 PM
> > To: devel@edk2.groups.io
> > Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> > Subject: [PATCH V2 0/6] [PATCH V2 0/5] Config language searching
> algorithm
> > enhancement and the bug fixes
> >
> > External email: Use caution opening links or attachments
> >
> >
> > From: Abner Chang <abner.chang@amd.com>
> >
> > PR # 5491
> >
> > In V2, add patch 6/6 contibuted by Nvidia for updating BIOS menu path
> > implementation based on the performance improvement.
> >
> > In this patch set,
> > 1 We enhance the config language searching algorithm.
> >   As the performance of searching config language using HII GetString is
> >   pretty slow. For the example, 1800 HII BIOS options takes over 30 mins
> >   to build up the metadata required for Redfish BIOS resource. With this
> >   improvement, it only takes 4 seconds.
> >
> > 2.Introduce the Redfish debug framework, there are three edk2 Redfish
> >   debug scopes.
> >   a. PcdDebugPrintErrorLevel, DEBUG_MANAGEABILITY to enable debug
> message
> >      for edk2 Redfish.
> >   b. PcdRedfishDebugCategory, enablement of individule edk2 Redfish
> >      component. Currently we only support RedfishPlatformConfigDxe
> >      module.
> >   c. PcdRedfishPlatformConfigDebugProperty, edk2 Redfish module debug
> >      scope. This PCD is used by RedfishPlatformConfigDxe debug enablement.
> >
> > 3 This patch set also fixes an issue that deletes HII string unexpectedly.
> >
> > Signed-off-by: Abner Chang <abner.chang@amd.com>
> > Co-authored-by: Nickle Wang <nicklew@nvidia.com>
> > Cc: Igor Kulchytskyy <igork@ami.com>
> >
> > Abner Chang (4):
> >   RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro
> >   RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support
> >   RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted
> >     unexpectedly
> >   EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs
> >
> > Nickle Wang (1):
> >   RedfishPkg/RedfishPlatformConfigDxe: support menu path report
> >
> > abnchang (1):
> >   RedfishPkg/RedfishPlatformConfigDxe: Config language searching
> >     optimization
> >
> >  RedfishPkg/RedfishPkg.dec                     |  24 +
> >  EmulatorPkg/EmulatorPkg.dsc                   |  21 +
> >  .../RedfishDebugLib/RedfishDebugLib.inf       |   4 +
> >  .../RedfishPlatformConfigDxe.inf              |   8 +
> >  RedfishPkg/Include/Library/RedfishDebugLib.h  |  43 +-
> >  .../RedfishPlatformConfigDxe.h                |  48 +-
> >  .../RedfishPlatformConfigImpl.h               | 135 ++-
> >  .../Library/RedfishDebugLib/RedfishDebugLib.c |  55 +-
> >  .../RedfishPlatformConfigCapability.c         |  58 ++
> >  .../RedfishPlatformConfigDxe.c                |  89 +-
> >  .../RedfishPlatformConfigImpl.c               | 928 ++++++++++++++++--
> >  11 files changed, 1240 insertions(+), 173 deletions(-)  create mode 100644
> > RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigCapability.c
> >
> > --
> > 2.37.1.windows.1

-The information contained in this message may be confidential and proprietary to American Megatrends (AMI). This communication is intended to be read only by the individual or entity to whom it is addressed or by their designee. If the reader of this message is not the intended recipient, you are on notice that any distribution of this message, in any form, is strictly prohibited. Please promptly notify the sender by reply e-mail or by telephone at 770-246-8600, and then delete or destroy all copies of the transmission.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117234): https://edk2.groups.io/g/devel/message/117234
Mute This Topic: https://groups.io/mt/105159781/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



[-- Attachment #2: Type: text/html, Size: 8622 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization
  2024-03-26 15:14 ` [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization Chang, Abner via groups.io
  2024-03-27  2:40   ` Nickle Wang via groups.io
       [not found]   ` <17C07EC03FCD57FF.6405@groups.io>
@ 2024-04-04  0:44   ` Igor Kulchytskyy via groups.io
  2024-04-04  3:00     ` Chang, Abner via groups.io
  2 siblings, 1 reply; 20+ messages in thread
From: Igor Kulchytskyy via groups.io @ 2024-04-04  0:44 UTC (permalink / raw)
  To: abner.chang, devel; +Cc: Nickle Wang

Hi Abner,
Sorry for that delay.
Here is a couple of remarks.
DescriptionStr was introduced and, I think, it can be used in RedfishPlatformConfigProtocolGetAttribute function instead of using HiiGetRedfishString.
Also please check my comment below in NewRedfishXuefiStringArray and RedfishXuefiStringInsertDatabase  functions.
Best regards,
Igor


-----Original Message-----
From: abner.chang@amd.com <abner.chang@amd.com>
Sent: Tuesday, March 26, 2024 11:15 AM
To: devel@edk2.groups.io
Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
Subject: [EXTERNAL] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization


**CAUTION: The e-mail below is from an external source. Please exercise caution before opening attachments, clicking links, or following guidance.**

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>
---
 .../RedfishPlatformConfigImpl.h               | 107 ++-
 .../RedfishPlatformConfigDxe.c                |  23 +-
 .../RedfishPlatformConfigImpl.c               | 820 +++++++++++++++++-
 3 files changed, 878 insertions(+), 72 deletions(-)

diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
index 9f4312decf5..6e6c7fdb8a9 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                                    *DescriptionStr;  // 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..664b48eb50e 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->DescriptionStr != NULL);
+        TmpConfigureLangList[Index] = AllocateCopyPool (HiiStrSize (StatementRef->Statement->DescriptionStr), (VOID *)StatementRef->Statement->DescriptionStr);
+        ++Index;
       }
     }
   }
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
index 47d35abc088..8b1ddf4360a 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->DescriptionStr;
           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->DescriptionStr 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->DescriptionStr;
           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,607 @@ NewFormsetPrivate (
   // Initial newly created formset private data.
   //
   InitializeListHead (&NewFormsetPrivate->HiiFormList);
+  InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);

   return NewFormsetPrivate;
 }

+/**
+  Create new x-uefi-redfish string array.
+
+  @param[in]      FormsetPrivate              Pointer to HII form-set private instance.
+  @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_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,

Igor:
FormsetPrivate parameter is not used in the function.
was it added for the future use?

+  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 (FormsetPrivate, 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 (FormsetPrivate, 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__));
+    return EFI_LOAD_ERROR;
+  }

Igor:
GetExitOrCreateXuefiStringDatabase and RedfishXuefiStringAdjustArrays could failed because of NewRedfishXuefiStringArray function failed in those functions.
In one case you call ReleaseXuefiStringDatabase and does not call in another.  Why it is different? In both cases xUefiStringDatabase would not be correct for this Formset.

+
+  // 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 +1584,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 +1592,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 +1602,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 +1621,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 +1635,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 +1661,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 +1699,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->DescriptionStr = String;
+        //
+        // Attach to statement list.
+        //
+        InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
+      } else {
+        FreePool (HiiStatementPrivate);
+      }
+
       HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
     }

@@ -1052,7 +1778,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 +2051,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

-The information contained in this message may be confidential and proprietary to American Megatrends (AMI). This communication is intended to be read only by the individual or entity to whom it is addressed or by their designee. If the reader of this message is not the intended recipient, you are on notice that any distribution of this message, in any form, is strictly prohibited. Please promptly notify the sender by reply e-mail or by telephone at 770-246-8600, and then delete or destroy all copies of the transmission.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117397): https://edk2.groups.io/g/devel/message/117397
Mute This Topic: https://groups.io/mt/105159783/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization
  2024-04-04  0:44   ` Igor Kulchytskyy via groups.io
@ 2024-04-04  3:00     ` Chang, Abner via groups.io
  0 siblings, 0 replies; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-04-04  3:00 UTC (permalink / raw)
  To: Igor Kulchytskyy, devel; +Cc: Nickle Wang

[AMD Official Use Only - General]

Hi Igor, my responses to your three comments in line.

> -----Original Message-----
> From: Igor Kulchytskyy <igork@ami.com>
> Sent: Thursday, April 4, 2024 8:44 AM
> To: Chang, Abner <Abner.Chang@amd.com>; devel@edk2.groups.io
> Cc: Nickle Wang <nicklew@nvidia.com>
> Subject: RE: [EXTERNAL] [PATCH V2 1/6]
> RedfishPkg/RedfishPlatformConfigDxe: Config language searching
> optimization
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> Hi Abner,
> Sorry for that delay.
> Here is a couple of remarks.
> DescriptionStr was introduced and, I think, it can be used in
> RedfishPlatformConfigProtocolGetAttribute function instead of using
> HiiGetRedfishString.

As DescriptionStr only captures the HII string with language x-uefi, however RedfishPlatformConfigProtocolGetAttribute needs the human understandable string in Eng language, this is why we still keep using HiiGetRedfishAsciiString. Nickle and I, we think there is still some room to enhance HiiGetRedfishAsciiString later. Also, to prevent from the confusions, Nickle also suggested to rename DescriptionStr to XuefiDescriptionStr. I will address your two comments below and Nickle's as well then send out the V3 patch set.


> Also please check my comment below in NewRedfishXuefiStringArray and
> RedfishXuefiStringInsertDatabase  functions.
> Best regards,
> Igor
>
>
> -----Original Message-----
> From: abner.chang@amd.com <abner.chang@amd.com>
> Sent: Tuesday, March 26, 2024 11:15 AM
> To: devel@edk2.groups.io
> Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> Subject: [EXTERNAL] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe:
> Config language searching optimization
>
>
> **CAUTION: The e-mail below is from an external source. Please exercise
> caution before opening attachments, clicking links, or following guidance.**
>
> 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>
> ---
>  .../RedfishPlatformConfigImpl.h               | 107 ++-
>  .../RedfishPlatformConfigDxe.c                |  23 +-
>  .../RedfishPlatformConfigImpl.c               | 820 +++++++++++++++++-
>  3 files changed, 878 insertions(+), 72 deletions(-)
>
> diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> index 9f4312decf5..6e6c7fdb8a9 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                                    *DescriptionStr;  // 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..664b48eb50e 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->DescriptionStr != NULL);
> +        TmpConfigureLangList[Index] = AllocateCopyPool (HiiStrSize
> (StatementRef->Statement->DescriptionStr), (VOID *)StatementRef-
> >Statement->DescriptionStr);
> +        ++Index;
>        }
>      }
>    }
> diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> index 47d35abc088..8b1ddf4360a 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->DescriptionStr;
>            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->DescriptionStr 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->DescriptionStr;
>            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,607 @@ NewFormsetPrivate (
>    // Initial newly created formset private data.
>    //
>    InitializeListHead (&NewFormsetPrivate->HiiFormList);
> +  InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);
>
>    return NewFormsetPrivate;
>  }
>
> +/**
> +  Create new x-uefi-redfish string array.
> +
> +  @param[in]      FormsetPrivate              Pointer to HII form-set private
> instance.
> +  @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_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
>
> Igor:
> FormsetPrivate parameter is not used in the function.
> was it added for the future use?
Ah yes, you are right. I will remove it.



>
> +  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 (FormsetPrivate,
> 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 (FormsetPrivate,
> 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__));
> +    return EFI_LOAD_ERROR;
> +  }
>
> Igor:
> GetExitOrCreateXuefiStringDatabase and RedfishXuefiStringAdjustArrays
> could failed because of NewRedfishXuefiStringArray function failed in those
> functions.
> In one case you call ReleaseXuefiStringDatabase and does not call in another.
> Why it is different? In both cases xUefiStringDatabase would not be correct for
> this Formset.

Thanks for catching this, I will add the missing ReleaseXuefiStringDatabase for NewRedfishXuefiStringArray.

Abner

>
> +
> +  // 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 +1584,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 +1592,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 +1602,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 +1621,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 +1635,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 +1661,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 +1699,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->DescriptionStr = String;
> +        //
> +        // Attach to statement list.
> +        //
> +        InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> >Link);
> +      } else {
> +        FreePool (HiiStatementPrivate);
> +      }
> +
>        HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> HiiStatementLink);
>      }
>
> @@ -1052,7 +1778,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 +2051,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
>
> -The information contained in this message may be confidential and
> proprietary to American Megatrends (AMI). This communication is intended
> to be read only by the individual or entity to whom it is addressed or by their
> designee. If the reader of this message is not the intended recipient, you are
> on notice that any distribution of this message, in any form, is strictly
> prohibited. Please promptly notify the sender by reply e-mail or by telephone
> at 770-246-8600, and then delete or destroy all copies of the transmission.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117398): https://edk2.groups.io/g/devel/message/117398
Mute This Topic: https://groups.io/mt/105159783/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization
  2024-03-27  2:40   ` Nickle Wang via groups.io
@ 2024-04-04  3:02     ` Chang, Abner via groups.io
  0 siblings, 0 replies; 20+ messages in thread
From: Chang, Abner via groups.io @ 2024-04-04  3:02 UTC (permalink / raw)
  To: Nickle Wang, devel; +Cc: Igor Kulchytskyy

[AMD Official Use Only - General]

Hi Nickle, I will rename it and send out the V3 together with Igor's comments addressed.

Thanks
Abner

> -----Original Message-----
> From: Nickle Wang <nicklew@nvidia.com>
> Sent: Wednesday, March 27, 2024 10:40 AM
> To: Chang, Abner <Abner.Chang@amd.com>; devel@edk2.groups.io
> Cc: Igor Kulchytskyy <igork@ami.com>
> Subject: RE: [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config
> language searching optimization
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> Hi Abner,
>
> Could we change "DescriptionStr" below to something like "XuefiString", so
> people don't think it is a regular English string of HII statement?
>
> > +  EFI_STRING_ID                             Description;      // String token of this
> question.
> > +  CHAR16                                    *DescriptionStr;  // String of this question.
> > +  EFI_STRING_ID                             Help;             // String token of help message.
>
>
> Thanks,
> Nickle
>
> > -----Original Message-----
> > From: abner.chang@amd.com <abner.chang@amd.com>
> > Sent: Tuesday, March 26, 2024 11:15 PM
> > To: devel@edk2.groups.io
> > Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> > Subject: [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config
> language
> > searching optimization
> >
> > External email: Use caution opening links or attachments
> >
> >
> > 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>
> > ---
> >  .../RedfishPlatformConfigImpl.h               | 107 ++-
> >  .../RedfishPlatformConfigDxe.c                |  23 +-
> >  .../RedfishPlatformConfigImpl.c               | 820 +++++++++++++++++-
> >  3 files changed, 878 insertions(+), 72 deletions(-)
> >
> > diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> > b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> > index 9f4312decf5..6e6c7fdb8a9 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                                    *DescriptionStr;  // 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..664b48eb50e 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->DescriptionStr != NULL);
> > +        TmpConfigureLangList[Index] = AllocateCopyPool (HiiStrSize
> (StatementRef-
> > >Statement->DescriptionStr), (VOID *)StatementRef->Statement-
> > >DescriptionStr);
> > +        ++Index;
> >        }
> >      }
> >    }
> > diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> > b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> > index 47d35abc088..8b1ddf4360a 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->DescriptionStr;
> >            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->DescriptionStr 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->DescriptionStr;
> >            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,607 @@ NewFormsetPrivate (
> >    // Initial newly created formset private data.
> >    //
> >    InitializeListHead (&NewFormsetPrivate->HiiFormList);
> > +  InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase);
> >
> >    return NewFormsetPrivate;
> >  }
> >
> > +/**
> > +  Create new x-uefi-redfish string array.
> > +
> > +  @param[in]      FormsetPrivate              Pointer to HII form-set private
> instance.
> > +  @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_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate,
> > +  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 (FormsetPrivate,
> > 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 (FormsetPrivate,
> > 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__));
> > +    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 +1584,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 +1592,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 +1602,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 +1621,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
> +1635,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 +1661,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 +1699,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->DescriptionStr = String;
> > +        //
> > +        // Attach to statement list.
> > +        //
> > +        InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> > >Link);
> > +      } else {
> > +        FreePool (HiiStatementPrivate);
> > +      }
> > +
> >        HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> > HiiStatementLink);
> >      }
> >
> > @@ -1052,7 +1778,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 +2051,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 (#117399): https://edk2.groups.io/g/devel/message/117399
Mute This Topic: https://groups.io/mt/105159783/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2024-04-04  3:02 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-26 15:14 [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Chang, Abner via groups.io
2024-03-26 15:14 ` [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization Chang, Abner via groups.io
2024-03-27  2:40   ` Nickle Wang via groups.io
2024-04-04  3:02     ` Chang, Abner via groups.io
     [not found]   ` <17C07EC03FCD57FF.6405@groups.io>
2024-03-27  7:37     ` Nickle Wang via groups.io
2024-04-04  0:44   ` Igor Kulchytskyy via groups.io
2024-04-04  3:00     ` Chang, Abner via groups.io
2024-03-26 15:14 ` [edk2-devel] [PATCH V2 2/6] RedfishPkg/RedfishDebugLib: Introduce Redfish DEBUG macro Chang, Abner via groups.io
2024-03-27  7:38   ` Nickle Wang via groups.io
2024-03-26 15:14 ` [edk2-devel] [PATCH V2 3/6] RedfishPkg/RedfishPlatformConfigDxe:Add RefishDebugLib support Chang, Abner via groups.io
2024-03-27  7:38   ` Nickle Wang via groups.io
2024-03-26 15:15 ` [edk2-devel] [PATCH V2 4/6] RedfishPkg/RedfishPlatformConfigDxe: HII string is deleted unexpectedly Chang, Abner via groups.io
2024-03-27  7:39   ` Nickle Wang via groups.io
2024-03-26 15:15 ` [edk2-devel] [PATCH V2 5/6] EmulatorPkg/Redfish: Use edk2 Redfish debug PCDs Chang, Abner via groups.io
2024-03-27  7:39   ` Nickle Wang via groups.io
2024-03-26 15:15 ` [edk2-devel] [PATCH V2 6/6] RedfishPkg/RedfishPlatformConfigDxe: support menu path report Chang, Abner via groups.io
2024-03-27  7:39   ` Nickle Wang via groups.io
2024-03-27  7:41 ` [edk2-devel] [PATCH V2 0/6] [PATCH V2 0/5] Config language searching algorithm enhancement and the bug fixes Nickle Wang via groups.io
2024-03-27  7:43   ` Chang, Abner via groups.io
2024-03-29 11:11     ` Igor Kulchytskyy via groups.io

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox