[edk2-devel] [edk2-staging][PATCH v3] edk2/RedfishPkg: Update Redfish Platform Config Protocol

Nickle Wang posted 1 patch 1 year, 9 months ago
Failed in applying to current master (apply log)
.../Protocol/EdkIIRedfishPlatformConfig.h     |  301 +-
.../RedfishPlatformConfigDxe.c                | 3087 ++++++++++-------
.../RedfishPlatformConfigDxe.h                |  128 +-
.../RedfishPlatformConfigDxe.inf              |  104 +-
.../RedfishPlatformConfigImpl.c               | 2528 +++++++-------
.../RedfishPlatformConfigImpl.h               |  571 +--
6 files changed, 3638 insertions(+), 3081 deletions(-)
[edk2-devel] [edk2-staging][PATCH v3] edk2/RedfishPkg: Update Redfish Platform Config Protocol
Posted by Nickle Wang 1 year, 9 months ago
Update EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL and add array type of
value support to EDKII_REDFISH_VALUE in order to support ordered list
op-code in HII. Modify corresponding function to support new type of
data structure.

Signed-off-by: Nickle Wang <nickle.wang@hpe.com>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Yang Atom <Atom.Yang@amd.com>
Cc: Nick Ramirez <nramirez@nvidia.com>
---
 .../Protocol/EdkIIRedfishPlatformConfig.h     |  301 +-
 .../RedfishPlatformConfigDxe.c                | 3087 ++++++++++-------
 .../RedfishPlatformConfigDxe.h                |  128 +-
 .../RedfishPlatformConfigDxe.inf              |  104 +-
 .../RedfishPlatformConfigImpl.c               | 2528 +++++++-------
 .../RedfishPlatformConfigImpl.h               |  571 +--
 6 files changed, 3638 insertions(+), 3081 deletions(-)

diff --git a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
index 895b010227..bbbab90b03 100644
--- a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
+++ b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
@@ -1,147 +1,154 @@
-/** @file
-  This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interface.
-
-  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_H_
-
-typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
-
-/**
-  Definition of EDKII_REDFISH_TYPE_VALUE
- **/
-typedef union {
-  INT64           Integer;
-  BOOLEAN         Boolean;
-  CHAR8           *Buffer;
-} EDKII_REDFISH_TYPE_VALUE;
-
-/**
-  Definition of EDKII_REDFISH_VALUE_TYPES
- **/
-typedef enum {
-  REDFISH_VALUE_TYPE_UNKNOWN = 0,
-  REDFISH_VALUE_TYPE_INTEGER,
-  REDFISH_VALUE_TYPE_BOOLEAN,
-  REDFISH_VALUE_TYPE_STRING,
-  REDFISH_VALUE_TYPE_MAX
-} EDKII_REDFISH_VALUE_TYPES;
-
-/**
-  Definition of EDKII_REDFISH_VALUE
- **/
-typedef struct {
-  EDKII_REDFISH_VALUE_TYPES Type;
-  EDKII_REDFISH_TYPE_VALUE  Value;
-} EDKII_REDFISH_VALUE;
-
-/**
-  Get Redfish value with the given Schema and Configure Language.
-
-  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
-  @param[in]   Schema              The Redfish schema to query.
-  @param[in]   Version             The Redfish version to query.
-  @param[in]   ConfigureLang       The target value which match this configure Language.
-  @param[out]  Value               The returned value.
-
-  @retval EFI_SUCCESS              Value is returned successfully.
-  @retval Others                   Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
-  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
-  IN     CHAR8                                  *Schema,
-  IN     CHAR8                                  *Version,
-  IN     EFI_STRING                             ConfigureLang,
-  OUT    EDKII_REDFISH_VALUE                    *Value
-  );
-
-/**
-  Set Redfish value with the given Schema and Configure Language.
-
-  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
-  @param[in]   Schema              The Redfish schema to query.
-  @param[in]   Version             The Redfish version to query.
-  @param[in]   ConfigureLang       The target value which match this configure Language.
-  @param[in]   Value               The value to set.
-
-  @retval EFI_SUCCESS              Value is returned successfully.
-  @retval Others                   Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
-  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
-  IN     CHAR8                                  *Schema,
-  IN     CHAR8                                  *Version,
-  IN     EFI_STRING                             ConfigureLang,
-  IN     EDKII_REDFISH_VALUE                    Value
-  );
-
-/**
-  Get the list of Configure Language from platform configuration by the given Schema and Pattern.
-
-  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
-  @param[in]   Schema              The Redfish schema to query.
-  @param[in]   Version             The Redfish version to query.
-  @param[in]   Pattern             The target Configure Language pattern.
-  @param[out]  ConfigureLangList   The list of Configure Language.
-  @param[out]  Count               The number of Configure Language in ConfigureLangList.
-
-  @retval EFI_SUCCESS              ConfigureLangList is returned successfully.
-  @retval Others                   Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
-  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
-  IN     CHAR8                                  *Schema,
-  IN     CHAR8                                  *Version,
-  IN     EFI_STRING                             Pattern,
-  OUT    EFI_STRING                             **ConfigureLangList,
-  OUT    UINTN                                  *Count
-  );
-
-
-/**
-  Get the list of supported Redfish schema from platform configuration on the give HII handle.
-
-  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
-  @param[in]   HiiHandle           The target handle to search. If handle is NULL,
-                                   this function returns all schema from HII database.
-  @param[out]  SupportedSchema     The supported schema list which is separated by ';'.
-                                   For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-redfish-Boot.v1_0_1"
-                                   The SupportedSchema is allocated by the callee. It's caller's
-                                   responsibility to free this buffer using FreePool().
-
-  @retval EFI_SUCCESS              Schema is returned successfully.
-  @retval Others                   Some error happened.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA) (
-  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL    *This,
-  IN     EFI_HII_HANDLE                            HiiHandle,       OPTIONAL
-  OUT    CHAR8                                     **SupportedSchema
-  );
-
-struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
-  EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE             GetValue;
-  EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE             SetValue;
-  EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG       GetConfigureLang;
-  EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA  GetSupportedSchema;
-};
-
-extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
-
-#endif
+/** @file
+  This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interface.
+
+  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_H_
+
+typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
+
+/**
+  Definition of EDKII_REDFISH_TYPE_VALUE
+ **/
+typedef union {
+  INT64           Integer;
+  BOOLEAN         Boolean;
+  CHAR8           *Buffer;
+  CHAR8           **StringArray;
+  INT64           *IntegerArray;
+  BOOLEAN         *BooleanArray;
+} EDKII_REDFISH_TYPE_VALUE;
+
+/**
+  Definition of EDKII_REDFISH_VALUE_TYPES
+ **/
+typedef enum {
+  REDFISH_VALUE_TYPE_UNKNOWN = 0,
+  REDFISH_VALUE_TYPE_INTEGER,
+  REDFISH_VALUE_TYPE_BOOLEAN,
+  REDFISH_VALUE_TYPE_STRING,
+  REDFISH_VALUE_TYPE_STRING_ARRAY,
+  REDFISH_VALUE_TYPE_INTEGER_ARRAY,
+  REDFISH_VALUE_TYPE_BOOLEAN_ARRAY,
+  REDFISH_VALUE_TYPE_MAX
+} EDKII_REDFISH_VALUE_TYPES;
+
+/**
+  Definition of EDKII_REDFISH_VALUE
+ **/
+typedef struct {
+  EDKII_REDFISH_VALUE_TYPES Type;
+  EDKII_REDFISH_TYPE_VALUE  Value;
+  UINTN                     ArrayCount;
+} EDKII_REDFISH_VALUE;
+
+/**
+  Get Redfish value with the given Schema and Configure Language.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+  @param[in]   Schema              The Redfish schema to query.
+  @param[in]   Version             The Redfish version to query.
+  @param[in]   ConfigureLang       The target value which match this configure Language.
+  @param[out]  Value               The returned value.
+
+  @retval EFI_SUCCESS              Value is returned successfully.
+  @retval Others                   Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
+  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+  IN     CHAR8                                  *Schema,
+  IN     CHAR8                                  *Version,
+  IN     EFI_STRING                             ConfigureLang,
+  OUT    EDKII_REDFISH_VALUE                    *Value
+  );
+
+/**
+  Set Redfish value with the given Schema and Configure Language.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+  @param[in]   Schema              The Redfish schema to query.
+  @param[in]   Version             The Redfish version to query.
+  @param[in]   ConfigureLang       The target value which match this configure Language.
+  @param[in]   Value               The value to set.
+
+  @retval EFI_SUCCESS              Value is returned successfully.
+  @retval Others                   Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
+  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+  IN     CHAR8                                  *Schema,
+  IN     CHAR8                                  *Version,
+  IN     EFI_STRING                             ConfigureLang,
+  IN     EDKII_REDFISH_VALUE                    Value
+  );
+
+/**
+  Get the list of Configure Language from platform configuration by the given Schema and RegexPattern.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+  @param[in]   Schema              The Redfish schema to query.
+  @param[in]   Version             The Redfish version to query.
+  @param[in]   RegexPattern        The target Configure Language pattern. This is used for regular expression matching.
+  @param[out]  ConfigureLangList   The list of Configure Language.
+  @param[out]  Count               The number of Configure Language in ConfigureLangList.
+
+  @retval EFI_SUCCESS              ConfigureLangList is returned successfully.
+  @retval Others                   Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
+  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+  IN     CHAR8                                  *Schema,
+  IN     CHAR8                                  *Version,
+  IN     EFI_STRING                             RegexPattern,
+  OUT    EFI_STRING                             **ConfigureLangList,
+  OUT    UINTN                                  *Count
+  );
+
+
+/**
+  Get the list of supported Redfish schema from platform configuration on the give HII handle.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+  @param[in]   HiiHandle           The target handle to search. If handle is NULL,
+                                   this function returns all schema from HII database.
+  @param[out]  SupportedSchema     The supported schema list which is separated by ';'.
+                                   For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-redfish-Boot.v1_0_1"
+                                   The SupportedSchema is allocated by the callee. It's caller's
+                                   responsibility to free this buffer using FreePool().
+
+  @retval EFI_SUCCESS              Schema is returned successfully.
+  @retval Others                   Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA) (
+  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL    *This,
+  IN     EFI_HII_HANDLE                            HiiHandle,       OPTIONAL
+  OUT    CHAR8                                     **SupportedSchema
+  );
+
+struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
+  EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE             GetValue;
+  EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE             SetValue;
+  EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG       GetConfigureLang;
+  EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA  GetSupportedSchema;
+};
+
+extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
+
+#endif
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
index 67818cccd2..971035f27d 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
@@ -1,1304 +1,1783 @@
-/** @file
-
-  The implementation of EDKII Redfidh Platform Config Protocol.
-
-  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "RedfishPlatformConfigDxe.h"
-#include "RedfishPlatformConfigImpl.h"
-
-REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate = NULL;
-
-/**
-  Compare two value in HII statement format.
-
-  @param[in]  Value1        Firt value to compare.
-  @param[in]  Value2        Second value to be compared.
-
-  @retval UINTN         0 is retuned when two values are equal.
-                        1 is returned when first value is greater than second value.
-                        -1 is returned when second value is greater than first value.
-
-**/
-UINTN
-CompareHiiStatementValue (
-  IN HII_STATEMENT_VALUE  *Value1,
-  IN HII_STATEMENT_VALUE  *Value2
-  )
-{
-  INTN Result;
-  UINT64 Data1;
-  UINT64 Data2;
-
-  if (Value1 == NULL || Value2 == NULL) {
-    return 0xFF;
-  }
-
-  switch (Value1->Type) {
-    case EFI_IFR_TYPE_NUM_SIZE_8:
-      Data1 = Value1->Value.u8;
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_16:
-      Data1 = Value1->Value.u16;
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_32:
-      Data1 = Value1->Value.u32;
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_64:
-      Data1 = Value1->Value.u64;
-      break;
-    case EFI_IFR_TYPE_BOOLEAN:
-      Data1 = (Value1->Value.b ? 1 : 0);
-      break;
-    default:
-      return 0xFF;
-  }
-
-  switch (Value2->Type) {
-    case EFI_IFR_TYPE_NUM_SIZE_8:
-      Data2 = Value2->Value.u8;
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_16:
-      Data2 = Value2->Value.u16;
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_32:
-      Data2 = Value2->Value.u32;
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_64:
-      Data2 = Value2->Value.u64;
-      break;
-    case EFI_IFR_TYPE_BOOLEAN:
-      Data2 = (Value2->Value.b ? 1 : 0);
-      break;
-    default:
-      return 0xFF;
-  }
-
-  Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
-
-  return Result;
-}
-
-/**
-  Convert HII value to the string in HII one-of opcode.
-
-  @param[in]  Statement     Statement private instance
-
-  @retval EFI_STRING_ID     The string ID in HII database.
-                            0 is returned when something goes wrong.
-
-**/
-EFI_STRING_ID
-HiiValueToOneOfOptionStringId (
-  IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
-  )
-{
-  LIST_ENTRY            *Link;
-  HII_QUESTION_OPTION   *Option;
-
-  if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
-    return 0;
-  }
-
-  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
-    return 0;
-  }
-
-  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
-  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
-    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
-    if (CompareHiiStatementValue (&Statement->HiiStatement->Value, &Option->Value) == 0) {
-      return Option->Text;
-    }
-
-    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
-  }
-
-  return 0;
-}
-
-/**
-  Convert HII string to the value in HII one-of opcode.
-
-  @param[in]  Statement     Statement private instance
-  @param[in]  Schema        Schema string
-  @param[in]  HiiString     Input string
-  @param[out] Value         Value returned
-
-  @retval EFI_SUCCESS       HII value is returned successfully.
-  @retval Others            Errors occur
-
-**/
-EFI_STATUS
-HiiStringToOneOfOptionValue (
-  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
-  IN  CHAR8                           *Schema,
-  IN  EFI_STRING                      HiiString,
-  OUT HII_STATEMENT_VALUE             *Value
-  )
-{
-  LIST_ENTRY            *Link;
-  HII_QUESTION_OPTION   *Option;
-  EFI_STRING            TmpString;
-  BOOLEAN               Found;
-
-  if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
-    return EFI_UNSUPPORTED;
-  }
-
-  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
-    return EFI_NOT_FOUND;
-  }
-
-  Found = FALSE;
-  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
-  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
-    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
-
-    TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
-    if (TmpString != NULL) {
-      if (StrCmp (TmpString, HiiString) == 0) {
-        CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
-        Found = TRUE;
-      }
-      FreePool (TmpString);
-    }
-
-    if (Found) {
-      return EFI_SUCCESS;
-    }
-
-    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
-  }
-
-  return EFI_NOT_FOUND;
-}
-
-/**
-  Convert HII value to numeric value in Redfish format.
-
-  @param[in]  Value         Value to be converted.
-  @param[out] RedfishValue  Value in Redfish format.
-
-  @retval EFI_SUCCESS       Redfish value is returned successfully.
-  @retval Others            Errors occur
-
-**/
-EFI_STATUS
-HiiValueToRedfishNumeric (
-  IN  HII_STATEMENT_VALUE  *Value,
-  OUT EDKII_REDFISH_VALUE  *RedfishValue
-  )
-{
-  if (Value == NULL || RedfishValue == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  switch (Value->Type) {
-    case EFI_IFR_TYPE_NUM_SIZE_8:
-      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
-      RedfishValue->Value.Integer = (INT64)Value->Value.u8;
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_16:
-      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
-      RedfishValue->Value.Integer = (INT64)Value->Value.u16;
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_32:
-      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
-      RedfishValue->Value.Integer = (INT64)Value->Value.u32;
-      break;
-    case EFI_IFR_TYPE_NUM_SIZE_64:
-      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
-      RedfishValue->Value.Integer = (INT64)Value->Value.u64;
-      break;
-    case EFI_IFR_TYPE_BOOLEAN:
-      RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
-      RedfishValue->Value.Boolean = Value->Value.b;
-      break;
-    default:
-      RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
-      break;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Convert numeric value in Redfish format to HII value.
-
-  @param[in]   RedfishValue  Value in Redfish format to be converted.
-  @param[out]  Value         HII value returned.
-
-  @retval EFI_SUCCESS       HII value is returned successfully.
-  @retval Others            Errors occur
-
-**/
-EFI_STATUS
-RedfishNumericToHiiValue (
-  IN  EDKII_REDFISH_VALUE  *RedfishValue,
-  OUT HII_STATEMENT_VALUE  *Value
-  )
-{
-  if (Value == NULL || RedfishValue == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  switch (RedfishValue->Type) {
-    case REDFISH_VALUE_TYPE_INTEGER:
-      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
-      Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
-      break;
-    case REDFISH_VALUE_TYPE_BOOLEAN:
-      Value->Type = EFI_IFR_TYPE_BOOLEAN;
-      Value->Value.b = RedfishValue->Value.Boolean;
-      break;
-    default:
-      Value->Type = EFI_IFR_TYPE_UNDEFINED;
-      break;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Return the full Redfish schema string from the given Schema and Version.
-
-  Returned schema string is: Schema + '.' + Version
-
-  @param[in]  Schema      Schema string
-  @param[in]  Version     Schema version string
-
-  @retval CHAR8 *         Schema string. NULL when errors occur.
-
-**/
-CHAR8 *
-GetFullSchemaString (
-  IN CHAR8   *Schema,
-  IN CHAR8  *Version
-  )
-{
-  UINTN Size;
-  CHAR8 *FullName;
-
-  if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
-    return NULL;
-  }
-
-  Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema) + AsciiStrSize (Version);
-
-  FullName = AllocatePool (Size);
-  if (FullName == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
-    return NULL;
-  }
-
-  AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX, Schema, Version);
-
-  return FullName;
-}
-
-/**
-  Common implementation to get statement private instance.
-
-  @param[in]   RedfishPlatformConfigPrivate   Private instance.
-  @param[in]   Schema                         Redfish schema string.
-  @param[in]   ConfigureLang                  Configure language that refers to this statement.
-  @param[out]  Statement                      Statement instance
-
-  @retval EFI_SUCCESS       HII value is returned successfully.
-  @retval Others            Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigGetStatementCommon (
-  IN     REDFISH_PLATFORM_CONFIG_PRIVATE            *RedfishPlatformConfigPrivate,
-  IN     CHAR8                                      *Schema,
-  IN     EFI_STRING                                 ConfigureLang,
-  OUT    REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  **Statement
-  )
-{
-  EFI_STATUS                      Status;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
-
-  if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  *Statement = NULL;
-
-  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
-    return Status;
-  }
-
-  TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
-  if (TargetStatement == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
-    return EFI_NOT_FOUND;
-  }
-
-  //
-  // Find current HII question value.
-  //
-  Status = GetQuestionValue (
-             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
-             TargetStatement->ParentForm->HiiForm,
-             TargetStatement->HiiStatement,
-             GetSetValueWithHiiDriver
-             );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n", __FUNCTION__, Status));
-    return Status;
-  }
-
-
-  if (TargetStatement->HiiStatement->Value.Type == EFI_IFR_TYPE_UNDEFINED) {
-    return EFI_DEVICE_ERROR;
-  }
-
-  //
-  // Return Value.
-  //
-  *Statement = TargetStatement;
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Get Redfish value with the given Schema and Configure Language.
-
-  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
-  @param[in]   Schema              The Redfish schema to query.
-  @param[in]   Version             The Redfish version to query.
-  @param[in]   ConfigureLang       The target value which match this configure Language.
-  @param[out]  Value               The returned value.
-
-  @retval EFI_SUCCESS              Value is returned successfully.
-  @retval Others                   Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetValue (
-  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
-  IN     CHAR8                                  *Schema,
-  IN     CHAR8                                  *Version,
-  IN     EFI_STRING                             ConfigureLang,
-  OUT    EDKII_REDFISH_VALUE                    *Value
-  )
-{
-  EFI_STATUS                                Status;
-  REDFISH_PLATFORM_CONFIG_PRIVATE           *RedfishPlatformConfigPrivate;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
-  EFI_STRING_ID                             StringId;
-  CHAR8                                     *FullSchema;
-  EFI_STRING                                HiiString;
-  UINTN                                     Size;
-
-  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-  Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
-  FullSchema = NULL;
-  HiiString = NULL;
-
-  FullSchema = GetFullSchemaString (Schema, Version);
-  if (FullSchema == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  Status = RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &TargetStatement);
-  if (EFI_ERROR (Status)) {
-    goto RELEASE_RESOURCE;
-  }
-
-  switch (TargetStatement->HiiStatement->Operand) {
-    case EFI_IFR_ONE_OF_OP:
-      StringId = HiiValueToOneOfOptionStringId (TargetStatement);
-      if (StringId == 0) {
-        ASSERT (FALSE);
-        Status = EFI_DEVICE_ERROR;
-        goto RELEASE_RESOURCE;
-      }
-
-      HiiString = HiiGetRedfishString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
-      if (HiiString == NULL) {
-        DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n", __FUNCTION__, StringId, FullSchema));
-        Status = EFI_NOT_FOUND;
-        goto RELEASE_RESOURCE;
-      }
-
-      Size = StrLen (HiiString) + 1;
-      Value->Value.Buffer = AllocatePool (Size);
-      if (Value->Value.Buffer == NULL) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto RELEASE_RESOURCE;
-      }
-
-      UnicodeStrToAsciiStrS (HiiString, Value->Value.Buffer, Size);
-      Value->Type = REDFISH_VALUE_TYPE_STRING;
-
-      break;
-    case EFI_IFR_STRING_OP:
-      if (TargetStatement->HiiStatement->Value.Type != EFI_IFR_TYPE_STRING) {
-        ASSERT (FALSE);
-        Status = EFI_DEVICE_ERROR;
-        goto RELEASE_RESOURCE;
-      }
-
-      Value->Type = REDFISH_VALUE_TYPE_STRING;
-      Value->Value.Buffer = AllocateCopyPool (StrSize ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer), TargetStatement->HiiStatement->Value.Buffer);
-      if (Value->Value.Buffer == NULL) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto RELEASE_RESOURCE;
-      }
-      break;
-    case EFI_IFR_CHECKBOX_OP:
-    case EFI_IFR_NUMERIC_OP:
-      Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement->Value, Value);
-      if (EFI_ERROR (Status)) {
-        DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish value: %r\n", __FUNCTION__, Status));
-        goto RELEASE_RESOURCE;
-      }
-      break;
-    default:
-      DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please contact with author if we need to support this type.\n", __FUNCTION__, TargetStatement->HiiStatement->Operand));
-      ASSERT (FALSE);
-      Status = EFI_UNSUPPORTED;
-      goto RELEASE_RESOURCE;
-  }
-
-RELEASE_RESOURCE:
-
-  if (FullSchema != NULL) {
-    FreePool (FullSchema);
-  }
-
-  if (HiiString != NULL) {
-    FreePool (HiiString);
-  }
-
-  return Status;
-}
-
-/**
-  Function to save question value into HII database.
-
-  @param[in]   HiiFormset       HII form-set instance
-  @param[in]   HiiForm          HII form instance
-  @param[in]   HiiStatement     HII statement that keeps new value.
-  @param[in]   Value            New value to applyu.
-
-  @retval EFI_SUCCESS       HII value is returned successfully.
-  @retval Others            Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigSaveQuestionValue (
-  IN  HII_FORMSET         *HiiFormset,
-  IN  HII_FORM            *HiiForm,
-  IN  HII_STATEMENT       *HiiStatement,
-  IN  HII_STATEMENT_VALUE *Value
-  )
-{
-  EFI_STATUS  Status;
-
-  if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL || Value == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Status = SetQuestionValue (
-             HiiFormset,
-             HiiForm,
-             HiiStatement,
-             Value
-             );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n", __FUNCTION__, Status));
-    return Status;
-  }
-
-  Status = SubmitForm (HiiFormset, HiiForm);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n", __FUNCTION__, Status));
-    return Status;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Common implementation to set statement private instance.
-
-  @param[in]   RedfishPlatformConfigPrivate   Private instance.
-  @param[in]   Schema                         Redfish schema string.
-  @param[in]   ConfigureLang                  Configure language that refers to this statement.
-  @param[in]   Statement                      Statement instance
-
-  @retval EFI_SUCCESS       HII value is returned successfully.
-  @retval Others            Errors occur
-
-**/
-EFI_STATUS
-RedfishPlatformConfigSetStatementCommon (
-  IN     REDFISH_PLATFORM_CONFIG_PRIVATE  *RedfishPlatformConfigPrivate,
-  IN     CHAR8                            *Schema,
-  IN     EFI_STRING                       ConfigureLang,
-  IN     HII_STATEMENT_VALUE              *StatementValue
-  )
-{
-  EFI_STATUS                                Status;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
-  EFI_STRING                                TempBuffer;
-
-  if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  TempBuffer = NULL;
-
-  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
-    return Status;
-  }
-
-  TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
-  if (TargetStatement == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
-    return EFI_NOT_FOUND;
-  }
-
-  if (StatementValue->Type != TargetStatement->HiiStatement->Value.Type) {
-    //
-    // We treat one-of type as string in Redfish. But one-of statement is not
-    // in string format from HII point of view. Do a patch here.
-    //
-    if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP && StatementValue->Type == EFI_IFR_TYPE_STRING) {
-      TempBuffer = AllocatePool (StatementValue->BufferLen * sizeof (CHAR16));
-      if (TempBuffer == NULL) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-
-      AsciiStrToUnicodeStrS (StatementValue->Buffer, TempBuffer, StatementValue->BufferLen);
-      FreePool (StatementValue->Buffer);
-      StatementValue->Buffer = NULL;
-      StatementValue->BufferLen = 0;
-
-      Status = HiiStringToOneOfOptionValue (TargetStatement, Schema, TempBuffer, StatementValue);
-      if (EFI_ERROR (Status)) {
-        DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given %s\n", __FUNCTION__, TempBuffer));
-        FreePool (TempBuffer);
-        return EFI_NOT_FOUND;
-      }
-
-      FreePool (TempBuffer);
-    } else if (TargetStatement->HiiStatement->Operand == EFI_IFR_NUMERIC_OP && StatementValue->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
-      //
-      // Redfish only has numeric value type and it does not care about the value size.
-      // Do a patch here so we have proper value size applied.
-      //
-      StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
-    } else {
-      DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type: 0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue->Type, TargetStatement->HiiStatement->Value.Type));
-      ASSERT (FALSE);
-    }
-  }
-
-  Status = RedfishPlatformConfigSaveQuestionValue (
-             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
-             TargetStatement->ParentForm->HiiForm,
-             TargetStatement->HiiStatement,
-             StatementValue
-             );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n", __FUNCTION__, Status));
-    return Status;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Set Redfish value with the given Schema and Configure Language.
-
-  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
-  @param[in]   Schema              The Redfish schema to query.
-  @param[in]   Version             The Redfish version to query.
-  @param[in]   ConfigureLang       The target value which match this configure Language.
-  @param[in]   Value               The value to set.
-
-  @retval EFI_SUCCESS              Value is returned successfully.
-  @retval Others                   Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolSetValue (
-  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
-  IN     CHAR8                                  *Schema,
-  IN     CHAR8                                  *Version,
-  IN     EFI_STRING                             ConfigureLang,
-  IN     EDKII_REDFISH_VALUE                    Value
-  )
-{
-  EFI_STATUS                                Status;
-  REDFISH_PLATFORM_CONFIG_PRIVATE           *RedfishPlatformConfigPrivate;
-  CHAR8                                     *FullSchema;
-  HII_STATEMENT_VALUE                       NewValue;
-
-  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >= REDFISH_VALUE_TYPE_MAX) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-  FullSchema = NULL;
-
-  FullSchema = GetFullSchemaString (Schema, Version);
-  if (FullSchema == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
-
-  switch (Value.Type) {
-    case REDFISH_VALUE_TYPE_INTEGER:
-    case REDFISH_VALUE_TYPE_BOOLEAN:
-      Status = RedfishNumericToHiiValue (&Value, &NewValue);
-      if (EFI_ERROR (Status)) {
-        DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii value: %r\n", __FUNCTION__, Status));
-        goto RELEASE_RESOURCE;
-      }
-      break;
-    case REDFISH_VALUE_TYPE_STRING:
-      NewValue.Type = EFI_IFR_TYPE_STRING;
-      NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
-      NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen, Value.Value.Buffer);
-      if (NewValue.Buffer == NULL) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto RELEASE_RESOURCE;
-      }
-      break;
-    default:
-      ASSERT (FALSE);
-      break;
-  }
-
-  Status = RedfishPlatformConfigSetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n", __FUNCTION__, Status));
-  }
-
-RELEASE_RESOURCE:
-
-  if (FullSchema != NULL) {
-    FreePool (FullSchema);
-  }
-
-  return Status;
-}
-
-/**
-  Get the list of Configure Language from platform configuration by the given Schema and Pattern.
-
-  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
-  @param[in]   Schema              The Redfish schema to query.
-  @param[in]   Version             The Redfish version to query.
-  @param[in]   Pattern             The target Configure Language pattern.
-  @param[out]  ConfigureLangList         The list of Configure Language.
-  @param[out]  Count               The number of Configure Language in ConfigureLangList.
-
-  @retval EFI_SUCCESS              ConfigureLangList is returned successfully.
-  @retval Others                   Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetConfigureLang (
-  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
-  IN     CHAR8                                  *Schema,
-  IN     CHAR8                                  *Version,
-  IN     EFI_STRING                             Pattern,
-  OUT    EFI_STRING                             **ConfigureLangList,
-  OUT    UINTN                                  *Count
-  )
-{
-  REDFISH_PLATFORM_CONFIG_PRIVATE                 *RedfishPlatformConfigPrivate;
-  EFI_STATUS                                      Status;
-  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;
-
-  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || Count == NULL || ConfigureLangList == NULL || IS_EMPTY_STRING (Pattern)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  *Count = 0;
-  *ConfigureLangList = NULL;
-  FullSchema = NULL;
-  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
-  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
-    return Status;
-  }
-
-  FullSchema = GetFullSchemaString (Schema, Version);
-  if (FullSchema == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  Status = GetStatementPrivateByConfigureLangRegex (
-             RedfishPlatformConfigPrivate->RegularExpressionProtocol,
-             &RedfishPlatformConfigPrivate->FormsetList,
-             FullSchema,
-             Pattern,
-             &StatementList
-             );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__, Status));
-    goto RELEASE_RESOURCE;
-  }
-
-  if (!IsListEmpty (&StatementList.StatementList)) {
-
-    TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) * StatementList.Count);
-    if (TmpConfigureLangList == NULL) {
-      Status = EFI_OUT_OF_RESOURCES;
-      goto RELEASE_RESOURCE;
-    }
-
-    Index = 0;
-    NextLink = GetFirstNode (&StatementList.StatementList);
-    while (!IsNull (&StatementList.StatementList, NextLink)) {
-      StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
-      NextLink = GetNextNode (&StatementList.StatementList, NextLink);
-
-      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] = AllocateCopyPool (StrSize (TmpString), TmpString);
-          ASSERT (TmpConfigureLangList[Index] != NULL);
-          FreePool (TmpString);
-          ++Index;
-        }
-      }
-    }
-  }
-
-  *Count = StatementList.Count;
-  *ConfigureLangList = TmpConfigureLangList;
-
-RELEASE_RESOURCE:
-
-  if (FullSchema != NULL) {
-    FreePool (FullSchema);
-  }
-
-  ReleaseStatementList (&StatementList);
-
-  return Status;
-}
-
-
-/**
-  Get the list of supported Redfish schema from paltform configuration on give HII handle.
-
-  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
-  @param[in]   HiiHandle           The target handle to search. If handle is NULL,
-                                   this function return all schema from HII database.
-  @param[out]  SupportedSchema     The supported schema list which is separated by ';'.
-                                   The SupportedSchema is allocated by the callee. It's caller's
-                                   responsibility to free this buffer using FreePool().
-
-  @retval EFI_SUCCESS              Schema is returned successfully.
-  @retval Others                   Some error happened.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigProtocolGetSupportedSchema (
-  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL   *This,
-  IN     EFI_HII_HANDLE                           HiiHandle,       OPTIONAL
-  OUT    CHAR8                                    **SupportedSchema
-  )
-{
-  REDFISH_PLATFORM_CONFIG_PRIVATE           *RedfishPlatformConfigPrivate;
-  EFI_STATUS                                Status;
-  LIST_ENTRY                                *HiiFormsetLink;
-  LIST_ENTRY                                *HiiFormsetNextLink;
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
-  UINTN                                     Index;
-  UINTN                                     StringSize;
-  CHAR8                                     *StringBuffer;
-  UINTN                                     StringIndex;
-
-  if (This == NULL || SupportedSchema == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  *SupportedSchema = NULL;
-
-  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
-
-  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
-    return Status;
-  }
-
-  if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
-    return EFI_NOT_FOUND;
-  }
-
-  //
-  // Calculate for string buffer size.
-  //
-  StringSize = 0;
-  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
-  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
-    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
-    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
-    if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
-      HiiFormsetLink = HiiFormsetNextLink;
-      continue;
-    }
-
-    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
-      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
-        StringSize += AsciiStrSize (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
-      }
-    }
-
-    HiiFormsetLink = HiiFormsetNextLink;
-  }
-
-  if (StringSize == 0) {
-    return EFI_NOT_FOUND;
-  }
-
-  StringBuffer = AllocatePool (StringSize);
-  if (StringBuffer == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  StringIndex = 0;
-  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
-  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
-    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
-    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
-    if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
-      HiiFormsetLink = HiiFormsetNextLink;
-      continue;
-    }
-
-    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
-      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
-        AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex), HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
-        StringIndex += AsciiStrLen (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
-        StringBuffer[StringIndex] = ';';
-        ++StringIndex;
-      }
-    }
-
-    HiiFormsetLink = HiiFormsetNextLink;
-  }
-
-  StringBuffer[--StringIndex] = '\0';
-
-  *SupportedSchema = StringBuffer;
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Functions which are registered to receive notification of
-  database events have this prototype. The actual event is encoded
-  in NotifyType. The following table describes how PackageType,
-  PackageGuid, Handle, and Package are used for each of the
-  notification types.
-
-  @param[in] PackageType  Package type of the notification.
-  @param[in] PackageGuid  If PackageType is
-                          EFI_HII_PACKAGE_TYPE_GUID, then this is
-                          the pointer to the GUID from the Guid
-                          field of EFI_HII_PACKAGE_GUID_HEADER.
-                          Otherwise, it must be NULL.
-  @param[in] Package      Points to the package referred to by the
-                          notification Handle The handle of the package
-                          list which contains the specified package.
-  @param[in] Handle       The HII handle.
-  @param[in] NotifyType   The type of change concerning the
-                          database. See
-                          EFI_HII_DATABASE_NOTIFY_TYPE.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigFormUpdateNotify (
-  IN UINT8                              PackageType,
-  IN CONST EFI_GUID                     *PackageGuid,
-  IN CONST EFI_HII_PACKAGE_HEADER       *Package,
-  IN EFI_HII_HANDLE                     Handle,
-  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType
-  )
-{
-  EFI_STATUS  Status;
-
-  if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
-    //
-    // HII formset on this handle is updated by driver during run-time. The formset needs to be reloaded.
-    //
-    Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate->PendingList);
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
-      return Status;
-    }
-  } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
-    //
-    // HII resource is removed. The formset is no longer exist.
-    //
-    Status = NotifyFormsetDeleted (Handle, &mRedfishPlatformConfigPrivate->PendingList);
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
-      return Status;
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  This is a EFI_HII_STRING_PROTOCOL notification event handler.
-
-  Install HII package notification.
-
-  @param[in] Event    Event whose notification function is being invoked.
-  @param[in] Context  Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-HiiStringProtocolInstalled (
-  IN  EFI_EVENT       Event,
-  IN  VOID            *Context
-  )
-{
-  EFI_STATUS  Status;
-
-  //
-  // Locate HII database protocol.
-  //
-  Status = gBS->LocateProtocol (
-                  &gEfiHiiStringProtocolGuid,
-                  NULL,
-                  (VOID **)&mRedfishPlatformConfigPrivate->HiiString
-                  );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure: %r\n", __FUNCTION__, Status));
-    return;
-  }
-
-  gBS->CloseEvent (Event);
-  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
-}
-
-/**
-  This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
-
-  Install HII package notification.
-
-  @param[in] Event    Event whose notification function is being invoked.
-  @param[in] Context  Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-HiiDatabaseProtocolInstalled (
-  IN  EFI_EVENT       Event,
-  IN  VOID            *Context
-  )
-{
-  EFI_STATUS  Status;
-
-  //
-  // Locate HII database protocol.
-  //
-  Status = gBS->LocateProtocol (
-                  &gEfiHiiDatabaseProtocolGuid,
-                  NULL,
-                  (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
-                  );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL failure: %r\n", __FUNCTION__, Status));
-    return;
-  }
-
-  //
-  // Register package notification when new form package is installed.
-  //
-  Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
-                                             mRedfishPlatformConfigPrivate->HiiDatabase,
-                                             EFI_HII_PACKAGE_FORMS,
-                                             NULL,
-                                             RedfishPlatformConfigFormUpdateNotify,
-                                             EFI_HII_DATABASE_NOTIFY_NEW_PACK,
-                                             &mRedfishPlatformConfigPrivate->NotifyHandle
-                                             );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
-  }
-
-  //
-  // Register package notification when new form package is updated.
-  //
-  Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
-                                             mRedfishPlatformConfigPrivate->HiiDatabase,
-                                             EFI_HII_PACKAGE_FORMS,
-                                             NULL,
-                                             RedfishPlatformConfigFormUpdateNotify,
-                                             EFI_HII_DATABASE_NOTIFY_ADD_PACK,
-                                             &mRedfishPlatformConfigPrivate->NotifyHandle
-                                             );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
-  }
-
-#if REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET
-  //
-  // Register package notification when new form package is removed.
-  //
-  Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
-                                             mRedfishPlatformConfigPrivate->HiiDatabase,
-                                             EFI_HII_PACKAGE_FORMS,
-                                             NULL,
-                                             RedfishPlatformConfigFormUpdateNotify,
-                                             EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
-                                             &mRedfishPlatformConfigPrivate->NotifyHandle
-                                             );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
-  }
-#endif
-
-  gBS->CloseEvent (Event);
-  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
-
-}
-
-/**
-  This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
-
-  @param[in] Event    Event whose notification function is being invoked.
-  @param[in] Context  Pointer to the notification function's context.
-
-**/
-VOID
-EFIAPI
-RegexProtocolInstalled (
-  IN  EFI_EVENT       Event,
-  IN  VOID            *Context
-  )
-{
-  EFI_STATUS  Status;
-
-  //
-  // Locate regular expression protocol.
-  //
-  Status = gBS->LocateProtocol (
-                  &gEfiRegularExpressionProtocolGuid,
-                  NULL,
-                  (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressionProtocol
-                  );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__, Status));
-    return;
-  }
-
-  gBS->CloseEvent (Event);
-  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
-
-}
-
-/**
-  Unloads an image.
-
-  @param  ImageHandle           Handle that identifies the image to be unloaded.
-
-  @retval EFI_SUCCESS           The image has been unloaded.
-  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
-
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigDxeUnload (
-  IN EFI_HANDLE  ImageHandle
-  )
-{
-  EFI_STATUS Status;
-
-  if (mRedfishPlatformConfigPrivate != NULL) {
-    Status = gBS->UninstallProtocolInterface (
-                    mRedfishPlatformConfigPrivate->ImageHandle,
-                    &gEdkIIRedfishPlatformConfigProtocolGuid,
-                    (VOID*)&mRedfishPlatformConfigPrivate->Protocol
-                    );
-    if (EFI_ERROR (Status)) {
-      DEBUG ((DEBUG_ERROR, "%a, can not uninstall gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
-      ASSERT (FALSE);
-    }
-
-    //
-    // Close events
-    //
-    if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
-      gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent);
-    }
-    if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL) {
-      gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent);
-    }
-    if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
-      gBS->CloseEvent (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent);
-    }
-
-    //
-    // Unregister package notification.
-    //
-    if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
-      mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify (
-                                          mRedfishPlatformConfigPrivate->HiiDatabase,
-                                          mRedfishPlatformConfigPrivate->NotifyHandle
-                                          );
-    }
-
-    ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
-    FreePool (mRedfishPlatformConfigPrivate);
-    mRedfishPlatformConfigPrivate = NULL;
-  }
-
-  return EFI_SUCCESS;
-}
-
-
-/**
-  This is the declaration of an EFI image entry point. This entry point is
-  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
-  both device drivers and bus drivers.
-
-  @param  ImageHandle           The firmware allocated handle for the UEFI image.
-  @param  SystemTable           A pointer to the EFI System Table.
-
-  @retval EFI_SUCCESS           The operation completed successfully.
-  @retval Others                An unexpected error occurred.
-**/
-EFI_STATUS
-EFIAPI
-RedfishPlatformConfigDxeEntryPoint (
-  IN EFI_HANDLE        ImageHandle,
-  IN EFI_SYSTEM_TABLE  *SystemTable
-  )
-{
-  EFI_STATUS  Status;
-
-  mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
-  if (mRedfishPlatformConfigPrivate == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
-    ASSERT (FALSE);
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  //
-  // Protocol initialization
-  //
-  mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
-  mRedfishPlatformConfigPrivate->Protocol.GetValue = RedfishPlatformConfigProtocolGetValue;
-  mRedfishPlatformConfigPrivate->Protocol.SetValue = RedfishPlatformConfigProtocolSetValue;
-  mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang = RedfishPlatformConfigProtocolGetConfigureLang;
-  mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema = RedfishPlatformConfigProtocolGetSupportedSchema;
-
-  InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
-  InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
-
-  Status = gBS->InstallProtocolInterface (
-                  &ImageHandle,
-                  &gEdkIIRedfishPlatformConfigProtocolGuid,
-                  EFI_NATIVE_INTERFACE,
-                  (VOID*)&mRedfishPlatformConfigPrivate->Protocol
-                  );
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, can not install gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
-    ASSERT (FALSE);
-  }
-
-  //
-  // Install protocol notification if HII database protocol is installed.
-  //
-  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
-                                                              &gEfiHiiDatabaseProtocolGuid,
-                                                              TPL_CALLBACK,
-                                                              HiiDatabaseProtocolInstalled,
-                                                              NULL,
-                                                              &mRedfishPlatformConfigPrivate->HiiDbNotify.Registration
-                                                              );
-  if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
-    ASSERT (FALSE);
-  }
-
-  //
-  // Install protocol notification if HII string protocol is installed.
-  //
-  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
-                                                                  &gEfiHiiStringProtocolGuid,
-                                                                  TPL_CALLBACK,
-                                                                  HiiStringProtocolInstalled,
-                                                                  NULL,
-                                                                  &mRedfishPlatformConfigPrivate->HiiStringNotify.Registration
-                                                                  );
-  if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiStringProtocolGuid\n", __FUNCTION__));
-    ASSERT (FALSE);
-  }
-
-  //
-  // Install protocol notification if regular expression protocol is installed.
-  //
-  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
-                                                              &gEfiRegularExpressionProtocolGuid,
-                                                              TPL_CALLBACK,
-                                                              RegexProtocolInstalled,
-                                                              NULL,
-                                                              &mRedfishPlatformConfigPrivate->RegexNotify.Registration
-                                                              );
-  if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
-    ASSERT (FALSE);
-  }
-
-  return EFI_SUCCESS;
-}
+/** @file
+
+  The implementation of EDKII Redfidh Platform Config Protocol.
+
+  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RedfishPlatformConfigDxe.h"
+#include "RedfishPlatformConfigImpl.h"
+
+REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate = NULL;
+
+
+/**
+  Zero extend integer/boolean to UINT64 for comparing.
+
+  @param  Value                  HII Value to be converted.
+
+**/
+UINT64
+ExtendHiiValueToU64 (
+  IN HII_STATEMENT_VALUE    *Value
+  )
+{
+  UINT64  Temp;
+
+  Temp = 0;
+  switch (Value->Type) {
+  case EFI_IFR_TYPE_NUM_SIZE_8:
+    Temp = Value->Value.u8;
+    break;
+
+  case EFI_IFR_TYPE_NUM_SIZE_16:
+    Temp = Value->Value.u16;
+    break;
+
+  case EFI_IFR_TYPE_NUM_SIZE_32:
+    Temp = Value->Value.u32;
+    break;
+
+  case EFI_IFR_TYPE_BOOLEAN:
+    Temp = Value->Value.b;
+    break;
+
+  case EFI_IFR_TYPE_TIME:
+  case EFI_IFR_TYPE_DATE:
+  default:
+    break;
+  }
+
+  return Temp;
+}
+
+/**
+  Set value of a data element in an Array by its Index in ordered list buffer.
+
+  @param  Array                  The data array.
+  @param  Type                   Type of the data in this array.
+  @param  Index                  Zero based index for data in this array.
+  @param  Value                  The value to be set.
+
+**/
+VOID
+OrderedListSetArrayData (
+  IN VOID                     *Array,
+  IN UINT8                    Type,
+  IN UINTN                    Index,
+  IN UINT64                   Value
+  )
+{
+
+  ASSERT (Array != NULL);
+
+  switch (Type) {
+  case EFI_IFR_TYPE_NUM_SIZE_8:
+    *(((UINT8 *) Array) + Index) = (UINT8) Value;
+    break;
+
+  case EFI_IFR_TYPE_NUM_SIZE_16:
+    *(((UINT16 *) Array) + Index) = (UINT16) Value;
+    break;
+
+  case EFI_IFR_TYPE_NUM_SIZE_32:
+    *(((UINT32 *) Array) + Index) = (UINT32) Value;
+    break;
+
+  case EFI_IFR_TYPE_NUM_SIZE_64:
+    *(((UINT64 *) Array) + Index) = (UINT64) Value;
+    break;
+
+  default:
+    break;
+  }
+}
+
+/**
+  Return data element in an Array by its Index in ordered list array buffer.
+
+  @param  Array                  The data array.
+  @param  Type                   Type of the data in this array.
+  @param  Index                  Zero based index for data in this array.
+
+  @retval Value                  The data to be returned
+
+**/
+UINT64
+OrderedListGetArrayData (
+  IN VOID                     *Array,
+  IN UINT8                    Type,
+  IN UINTN                    Index
+  )
+{
+  UINT64 Data;
+
+  ASSERT (Array != NULL);
+
+  Data = 0;
+  switch (Type) {
+  case EFI_IFR_TYPE_NUM_SIZE_8:
+    Data = (UINT64) *(((UINT8 *) Array) + Index);
+    break;
+
+  case EFI_IFR_TYPE_NUM_SIZE_16:
+    Data = (UINT64) *(((UINT16 *) Array) + Index);
+    break;
+
+  case EFI_IFR_TYPE_NUM_SIZE_32:
+    Data = (UINT64) *(((UINT32 *) Array) + Index);
+    break;
+
+  case EFI_IFR_TYPE_NUM_SIZE_64:
+    Data = (UINT64) *(((UINT64 *) Array) + Index);
+    break;
+
+  default:
+    break;
+  }
+
+  return Data;
+}
+
+/**
+  Find string ID of option if its value equals to given value.
+
+  @param[in]  HiiStatement  Statement to search.
+  @param[in]  Value         Target value.
+
+  @retval EFI_SUCCESS       HII value is returned successfully.
+  @retval Others            Errors occur
+
+**/
+EFI_STRING_ID
+OrderedListOptionValueToStringId (
+  IN  HII_STATEMENT *HiiStatement,
+  IN  UINT64        Value
+  )
+{
+  LIST_ENTRY            *Link;
+  HII_QUESTION_OPTION   *Option;
+  BOOLEAN               Found;
+  UINT64                CurrentValue;
+
+  if (HiiStatement == NULL) {
+    return 0;
+  }
+
+  if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+    return 0;
+  }
+
+  if (IsListEmpty (&HiiStatement->OptionListHead)) {
+    return 0;
+  }
+
+  Found = FALSE;
+  Link = GetFirstNode (&HiiStatement->OptionListHead);
+  while (!IsNull (&HiiStatement->OptionListHead, Link)) {
+    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+    CurrentValue = ExtendHiiValueToU64 (&Option->Value);
+    if (Value == CurrentValue) {
+      return Option->Text;
+    }
+
+    Link = GetNextNode (&HiiStatement->OptionListHead, Link);
+  }
+
+  return 0;
+}
+
+/**
+  Compare two value in HII statement format.
+
+  @param[in]  Value1        Firt value to compare.
+  @param[in]  Value2        Second value to be compared.
+
+  @retval INTN          0 is retuned when two values are equal.
+                        1 is returned when first value is greater than second value.
+                        -1 is returned when second value is greater than first value.
+
+**/
+INTN
+CompareHiiStatementValue (
+  IN HII_STATEMENT_VALUE  *Value1,
+  IN HII_STATEMENT_VALUE  *Value2
+  )
+{
+  INTN Result;
+  UINT64 Data1;
+  UINT64 Data2;
+
+  if (Value1 == NULL || Value2 == NULL) {
+    return -1;
+  }
+
+  switch (Value1->Type) {
+    case EFI_IFR_TYPE_NUM_SIZE_8:
+      Data1 = Value1->Value.u8;
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_16:
+      Data1 = Value1->Value.u16;
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_32:
+      Data1 = Value1->Value.u32;
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_64:
+      Data1 = Value1->Value.u64;
+      break;
+    case EFI_IFR_TYPE_BOOLEAN:
+      Data1 = (Value1->Value.b ? 1 : 0);
+      break;
+    default:
+      return -1;
+  }
+
+  switch (Value2->Type) {
+    case EFI_IFR_TYPE_NUM_SIZE_8:
+      Data2 = Value2->Value.u8;
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_16:
+      Data2 = Value2->Value.u16;
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_32:
+      Data2 = Value2->Value.u32;
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_64:
+      Data2 = Value2->Value.u64;
+      break;
+    case EFI_IFR_TYPE_BOOLEAN:
+      Data2 = (Value2->Value.b ? 1 : 0);
+      break;
+    default:
+      return -1;
+  }
+
+  Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
+
+  return Result;
+}
+
+/**
+  Convert HII value to the string in HII one-of opcode.
+
+  @param[in]  Statement     Statement private instance
+
+  @retval EFI_STRING_ID     The string ID in HII database.
+                            0 is returned when something goes wrong.
+
+**/
+EFI_STRING_ID
+HiiValueToOneOfOptionStringId (
+  IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
+  )
+{
+  LIST_ENTRY            *Link;
+  HII_QUESTION_OPTION   *Option;
+
+  if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
+    return 0;
+  }
+
+  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+    return 0;
+  }
+
+  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+    if (CompareHiiStatementValue (&Statement->HiiStatement->Value, &Option->Value) == 0) {
+      return Option->Text;
+    }
+
+    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+  }
+
+  return 0;
+}
+
+/**
+  Convert HII string to the value in HII one-of opcode.
+
+  @param[in]  Statement     Statement private instance
+  @param[in]  Schema        Schema string
+  @param[in]  HiiString     Input string
+  @param[out] Value         Value returned
+
+  @retval EFI_SUCCESS       HII value is returned successfully.
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+HiiStringToOneOfOptionValue (
+  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+  IN  CHAR8                           *Schema,
+  IN  EFI_STRING                      HiiString,
+  OUT HII_STATEMENT_VALUE             *Value
+  )
+{
+  LIST_ENTRY            *Link;
+  HII_QUESTION_OPTION   *Option;
+  EFI_STRING            TmpString;
+  BOOLEAN               Found;
+
+  if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Found = FALSE;
+  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+    TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
+    if (TmpString != NULL) {
+      if (StrCmp (TmpString, HiiString) == 0) {
+        CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
+        Found = TRUE;
+      }
+      FreePool (TmpString);
+    }
+
+    if (Found) {
+      return EFI_SUCCESS;
+    }
+
+    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Convert HII value to numeric value in Redfish format.
+
+  @param[in]  Value         Value to be converted.
+  @param[out] RedfishValue  Value in Redfish format.
+
+  @retval EFI_SUCCESS       Redfish value is returned successfully.
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+HiiValueToRedfishNumeric (
+  IN  HII_STATEMENT_VALUE  *Value,
+  OUT EDKII_REDFISH_VALUE  *RedfishValue
+  )
+{
+  if (Value == NULL || RedfishValue == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (Value->Type) {
+    case EFI_IFR_TYPE_NUM_SIZE_8:
+      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+      RedfishValue->Value.Integer = (INT64)Value->Value.u8;
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_16:
+      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+      RedfishValue->Value.Integer = (INT64)Value->Value.u16;
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_32:
+      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+      RedfishValue->Value.Integer = (INT64)Value->Value.u32;
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_64:
+      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
+      RedfishValue->Value.Integer = (INT64)Value->Value.u64;
+      break;
+    case EFI_IFR_TYPE_BOOLEAN:
+      RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
+      RedfishValue->Value.Boolean = Value->Value.b;
+      break;
+    default:
+      RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Convert numeric value in Redfish format to HII value.
+
+  @param[in]   RedfishValue  Value in Redfish format to be converted.
+  @param[out]  Value         HII value returned.
+
+  @retval EFI_SUCCESS       HII value is returned successfully.
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+RedfishNumericToHiiValue (
+  IN  EDKII_REDFISH_VALUE  *RedfishValue,
+  OUT HII_STATEMENT_VALUE  *Value
+  )
+{
+  if (Value == NULL || RedfishValue == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (RedfishValue->Type) {
+    case REDFISH_VALUE_TYPE_INTEGER:
+      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
+      Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
+      break;
+    case REDFISH_VALUE_TYPE_BOOLEAN:
+      Value->Type = EFI_IFR_TYPE_BOOLEAN;
+      Value->Value.b = RedfishValue->Value.Boolean;
+      break;
+    default:
+      Value->Type = EFI_IFR_TYPE_UNDEFINED;
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Dump the value in ordered list buffer.
+
+  @param[in]   OrderedListStatement Ordered list statement.
+
+**/
+VOID
+DumpOrderedListValue (
+  IN  HII_STATEMENT *OrderedListStatement
+  )
+{
+  UINT8 *Value8;
+  UINT16 *Value16;
+  UINT32 *Value32;
+  UINT64 *Value64;
+  UINTN  Count;
+  UINTN  Index;
+
+  if (OrderedListStatement == NULL || OrderedListStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+    return;
+  }
+
+  DEBUG ((DEBUG_ERROR, "Value.Type= 0x%x\n", OrderedListStatement->Value.Type));
+  DEBUG ((DEBUG_ERROR, "Value.BufferValueType= 0x%x\n", OrderedListStatement->Value.BufferValueType));
+  DEBUG ((DEBUG_ERROR, "Value.BufferLen= 0x%x\n", OrderedListStatement->Value.BufferLen));
+  DEBUG ((DEBUG_ERROR, "Value.Buffer= 0x%x\n", OrderedListStatement->Value.Buffer));
+  DEBUG ((DEBUG_ERROR, "Value.MaxContainers= 0x%x\n", OrderedListStatement->ExtraData.OrderListData.MaxContainers));
+  DEBUG ((DEBUG_ERROR, "StorageWidth= 0x%x\n", OrderedListStatement->StorageWidth));
+
+  if (OrderedListStatement->Value.Buffer == NULL) {
+    return;
+  }
+
+  Value8 = NULL;
+  Value16 = NULL;
+  Value32 = NULL;
+  Value64 = NULL;
+  Count = 0;
+
+  switch (OrderedListStatement->Value.BufferValueType) {
+    case EFI_IFR_TYPE_NUM_SIZE_8:
+      Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+      Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+      for (Index = 0; Index < Count; Index++) {
+        DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
+      }
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_16:
+      Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
+      Count = OrderedListStatement->StorageWidth / sizeof (UINT16);
+      for (Index = 0; Index < Count; Index++) {
+        DEBUG ((DEBUG_ERROR, "%d ", Value16[Index]));
+      }
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_32:
+      Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
+      Count = OrderedListStatement->StorageWidth / sizeof (UINT32);
+      for (Index = 0; Index < Count; Index++) {
+        DEBUG ((DEBUG_ERROR, "%d ", Value32[Index]));
+      }
+      break;
+    case EFI_IFR_TYPE_NUM_SIZE_64:
+      Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
+      Count = OrderedListStatement->StorageWidth / sizeof (UINT64);
+      for (Index = 0; Index < Count; Index++) {
+        DEBUG ((DEBUG_ERROR, "%d ", Value64[Index]));
+      }
+      break;
+    default:
+      Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
+      Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
+      for (Index = 0; Index < Count; Index++) {
+        DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
+      }
+      break;
+  }
+
+  DEBUG ((DEBUG_ERROR, "\n"));
+}
+
+/**
+  Convert HII value to the string in HII ordered list opcode. It's caller's
+  responsibility to free returned buffer using FreePool().
+
+  @param[in]  Statement     Statement private instance
+  @param[out] ReturnSize    The size of returned array
+
+  @retval EFI_STRING_ID     The string ID array for options in ordered list.
+
+**/
+EFI_STRING_ID *
+HiiValueToOrderedListOptionStringId (
+  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+  OUT UINTN                                     *ReturnSize
+  )
+{
+  LIST_ENTRY            *Link;
+  HII_QUESTION_OPTION   *Option;
+  UINTN                 OptionCount;
+  EFI_STRING_ID         *ReturnedArray;
+  UINTN                 Index;
+  UINT64                Value;
+
+  if (Statement == NULL || ReturnSize == NULL) {
+    return NULL;
+  }
+
+  *ReturnSize = 0;
+
+  if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+    return NULL;
+  }
+
+  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+    return NULL;
+  }
+
+  DEBUG_CODE (
+    DumpOrderedListValue (Statement->HiiStatement);
+  );
+
+  OptionCount = 0;
+  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+    ++OptionCount;
+
+    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+  }
+
+  *ReturnSize = OptionCount;
+  ReturnedArray = AllocatePool (sizeof (EFI_STRING_ID) * OptionCount);
+  if (ReturnedArray == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
+    *ReturnSize  = 0;
+    return NULL;
+  }
+
+  for (Index = 0; Index < OptionCount; Index++) {
+    Value = OrderedListGetArrayData (Statement->HiiStatement->Value.Buffer, Statement->HiiStatement->Value.BufferValueType, Index);
+    ReturnedArray[Index] = OrderedListOptionValueToStringId (Statement->HiiStatement, Value);
+  }
+
+  return ReturnedArray;
+}
+
+/**
+  Convert HII string to the value in HII ordered list opcode.
+
+  @param[in]  Statement     Statement private instance
+  @param[in]  Schema        Schema string
+  @param[in]  HiiString     Input string
+  @param[out] Value         Value returned
+
+  @retval EFI_SUCCESS       HII value is returned successfully.
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+HiiStringToOrderedListOptionValue (
+  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
+  IN  CHAR8                           *Schema,
+  IN  EFI_STRING                      HiiString,
+  OUT UINT64                          *Value
+  )
+{
+  LIST_ENTRY            *Link;
+  HII_QUESTION_OPTION   *Option;
+  EFI_STRING            TmpString;
+  BOOLEAN               Found;
+
+  if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Value = 0;
+
+  if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
+    return EFI_NOT_FOUND;
+  }
+
+  Found = FALSE;
+  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
+  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
+    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
+
+    TmpString = HiiGetRedfishString (Statement->ParentForm->ParentFormset->HiiHandle, Schema, Option->Text);
+    if (TmpString != NULL) {
+      if (StrCmp (TmpString, HiiString) == 0) {
+        *Value = ExtendHiiValueToU64 (&Option->Value);
+        Found = TRUE;
+      }
+      FreePool (TmpString);
+    }
+
+    if (Found) {
+      return EFI_SUCCESS;
+    }
+
+    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Convert input ascii string to unicode string. It's caller's
+  responsibility to free returned buffer using FreePool().
+
+  @param[in]  AsciiString     Ascii string to be converted.
+
+  @retval CHAR16 *            Unicode string on return.
+
+**/
+EFI_STRING
+StrToUnicodeStr (
+  IN  CHAR8 *AsciiString
+ )
+{
+  UINTN       StringLen;
+  EFI_STRING  Buffer;
+  EFI_STATUS  Status;
+
+  if (AsciiString == NULL || AsciiString[0] == '\0') {
+    return NULL;
+  }
+
+  StringLen = AsciiStrLen (AsciiString) + 1;
+  Buffer = AllocatePool (StringLen * sizeof (CHAR16));
+  if (Buffer == NULL) {
+    return NULL;
+  }
+
+  Status = AsciiStrToUnicodeStrS (AsciiString, Buffer, StringLen);
+  if (EFI_ERROR (Status)) {
+    FreePool (Buffer);
+    return NULL;
+  }
+
+  return Buffer;
+}
+
+/**
+  Return the full Redfish schema string from the given Schema and Version.
+
+  Returned schema string is: Schema + '.' + Version
+
+  @param[in]  Schema      Schema string
+  @param[in]  Version     Schema version string
+
+  @retval CHAR8 *         Schema string. NULL when errors occur.
+
+**/
+CHAR8 *
+GetFullSchemaString (
+  IN CHAR8   *Schema,
+  IN CHAR8  *Version
+  )
+{
+  UINTN Size;
+  CHAR8 *FullName;
+
+  if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
+    return NULL;
+  }
+
+  Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema) + AsciiStrSize (Version);
+
+  FullName = AllocatePool (Size);
+  if (FullName == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
+    return NULL;
+  }
+
+  AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX, Schema, Version);
+
+  return FullName;
+}
+
+/**
+  Common implementation to get statement private instance.
+
+  @param[in]   RedfishPlatformConfigPrivate   Private instance.
+  @param[in]   Schema                         Redfish schema string.
+  @param[in]   ConfigureLang                  Configure language that refers to this statement.
+  @param[out]  Statement                      Statement instance
+
+  @retval EFI_SUCCESS       HII value is returned successfully.
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigGetStatementCommon (
+  IN     REDFISH_PLATFORM_CONFIG_PRIVATE            *RedfishPlatformConfigPrivate,
+  IN     CHAR8                                      *Schema,
+  IN     EFI_STRING                                 ConfigureLang,
+  OUT    REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  **Statement
+  )
+{
+  EFI_STATUS                      Status;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+
+  if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Statement = NULL;
+
+  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+  if (TargetStatement == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Find current HII question value.
+  //
+  Status = GetQuestionValue (
+             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
+             TargetStatement->ParentForm->HiiForm,
+             TargetStatement->HiiStatement,
+             GetSetValueWithHiiDriver
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+
+  if (TargetStatement->HiiStatement->Value.Type == EFI_IFR_TYPE_UNDEFINED) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Return Value.
+  //
+  *Statement = TargetStatement;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get Redfish value with the given Schema and Configure Language.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+  @param[in]   Schema              The Redfish schema to query.
+  @param[in]   Version             The Redfish version to query.
+  @param[in]   ConfigureLang       The target value which match this configure Language.
+  @param[out]  Value               The returned value.
+
+  @retval EFI_SUCCESS              Value is returned successfully.
+  @retval Others                   Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetValue (
+  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+  IN     CHAR8                                  *Schema,
+  IN     CHAR8                                  *Version,
+  IN     EFI_STRING                             ConfigureLang,
+  OUT    EDKII_REDFISH_VALUE                    *Value
+  )
+{
+  EFI_STATUS                                Status;
+  REDFISH_PLATFORM_CONFIG_PRIVATE           *RedfishPlatformConfigPrivate;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+  EFI_STRING_ID                             StringId;
+  EFI_STRING_ID                             *StringIdArray;
+  CHAR8                                     *FullSchema;
+  EFI_STRING                                HiiString;
+  UINTN                                     Count;
+  UINTN                                     Index;
+
+  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+  Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+  Value->ArrayCount = 0;
+  Count = 0;
+  FullSchema = NULL;
+  HiiString = NULL;
+  StringIdArray = NULL;
+
+  FullSchema = GetFullSchemaString (Schema, Version);
+  if (FullSchema == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = RedfishPlatformConfigGetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &TargetStatement);
+  if (EFI_ERROR (Status)) {
+    goto RELEASE_RESOURCE;
+  }
+
+  switch (TargetStatement->HiiStatement->Operand) {
+    case EFI_IFR_ONE_OF_OP:
+      StringId = HiiValueToOneOfOptionStringId (TargetStatement);
+      if (StringId == 0) {
+        ASSERT (FALSE);
+        Status = EFI_DEVICE_ERROR;
+        goto RELEASE_RESOURCE;
+      }
+
+      Value->Value.Buffer = HiiGetRedfishAsciiString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
+      if (Value->Value.Buffer == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto RELEASE_RESOURCE;
+      }
+
+      Value->Type = REDFISH_VALUE_TYPE_STRING;
+      break;
+    case EFI_IFR_STRING_OP:
+      if (TargetStatement->HiiStatement->Value.Type != EFI_IFR_TYPE_STRING) {
+        ASSERT (FALSE);
+        Status = EFI_DEVICE_ERROR;
+        goto RELEASE_RESOURCE;
+      }
+
+      Value->Type = REDFISH_VALUE_TYPE_STRING;
+      Value->Value.Buffer = AllocatePool (StrLen ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer) + 1);
+      UnicodeStrToAsciiStrS ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer, Value->Value.Buffer, StrLen ((CHAR16 *)TargetStatement->HiiStatement->Value.Buffer) + 1);
+      break;
+    case EFI_IFR_CHECKBOX_OP:
+    case EFI_IFR_NUMERIC_OP:
+      Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement->Value, Value);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish value: %r\n", __FUNCTION__, Status));
+        goto RELEASE_RESOURCE;
+      }
+      break;
+    case EFI_IFR_ACTION_OP:
+      if (TargetStatement->HiiStatement->Value.Type != EFI_IFR_TYPE_ACTION) {
+        ASSERT (FALSE);
+        Status = EFI_DEVICE_ERROR;
+        goto RELEASE_RESOURCE;
+      }
+
+      //
+      // Action has no value. Just return unknown type.
+      //
+      Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
+      break;
+    case EFI_IFR_ORDERED_LIST_OP:
+      StringIdArray = HiiValueToOrderedListOptionStringId (TargetStatement, &Count);
+      if (StringIdArray == NULL) {
+        ASSERT (FALSE);
+        Status = EFI_DEVICE_ERROR;
+        goto RELEASE_RESOURCE;
+      }
+
+      Value->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
+      if (Value->Value.StringArray == NULL) {
+        ASSERT (FALSE);
+        Status = EFI_OUT_OF_RESOURCES;
+        goto RELEASE_RESOURCE;
+      }
+
+      for (Index = 0; Index < Count; Index++) {
+        ASSERT (StringIdArray[Index] != 0);
+        Value->Value.StringArray[Index] = HiiGetRedfishAsciiString (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema, StringIdArray[Index]);
+      }
+
+      Value->ArrayCount = Count;
+      Value->Type = REDFISH_VALUE_TYPE_STRING_ARRAY;
+      break;
+    default:
+      DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please contact with author if we need to support this type.\n", __FUNCTION__, TargetStatement->HiiStatement->Operand));
+      ASSERT (FALSE);
+      Status = EFI_UNSUPPORTED;
+      goto RELEASE_RESOURCE;
+  }
+
+RELEASE_RESOURCE:
+
+  if (FullSchema != NULL) {
+    FreePool (FullSchema);
+  }
+
+  if (HiiString != NULL) {
+    FreePool (HiiString);
+  }
+
+  if (StringIdArray != NULL) {
+    FreePool (StringIdArray);
+  }
+
+  return Status;
+}
+
+/**
+  Function to save question value into HII database.
+
+  @param[in]   HiiFormset       HII form-set instance
+  @param[in]   HiiForm          HII form instance
+  @param[in]   HiiStatement     HII statement that keeps new value.
+  @param[in]   Value            New value to applyu.
+
+  @retval EFI_SUCCESS       HII value is returned successfully.
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigSaveQuestionValue (
+  IN  HII_FORMSET         *HiiFormset,
+  IN  HII_FORM            *HiiForm,
+  IN  HII_STATEMENT       *HiiStatement,
+  IN  HII_STATEMENT_VALUE *Value
+  )
+{
+  EFI_STATUS  Status;
+
+  if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL || Value == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = SetQuestionValue (
+             HiiFormset,
+             HiiForm,
+             HiiStatement,
+             Value
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  Status = SubmitForm (HiiFormset, HiiForm);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Common implementation to set statement private instance.
+
+  @param[in]   RedfishPlatformConfigPrivate   Private instance.
+  @param[in]   Schema                         Redfish schema string.
+  @param[in]   ConfigureLang                  Configure language that refers to this statement.
+  @param[in]   Statement                      Statement instance
+
+  @retval EFI_SUCCESS       HII value is returned successfully.
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+RedfishPlatformConfigSetStatementCommon (
+  IN     REDFISH_PLATFORM_CONFIG_PRIVATE  *RedfishPlatformConfigPrivate,
+  IN     CHAR8                            *Schema,
+  IN     EFI_STRING                       ConfigureLang,
+  IN     HII_STATEMENT_VALUE              *StatementValue
+  )
+{
+  EFI_STATUS                                Status;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
+  EFI_STRING                                TempBuffer;
+  UINT8                                     *StringArray;
+  UINTN                                     Index;
+  UINT64                                    Value;
+  CHAR8                                     **CharArray;
+
+  if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TempBuffer = NULL;
+  StringArray = NULL;
+
+  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  TargetStatement = GetStatementPrivateByConfigureLang (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
+  if (TargetStatement == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
+    return EFI_NOT_FOUND;
+  }
+
+  if (StatementValue->Type != TargetStatement->HiiStatement->Value.Type) {
+    //
+    // We treat one-of type as string in Redfish. But one-of statement is not
+    // in string format from HII point of view. Do a patch here.
+    //
+    if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP && StatementValue->Type == EFI_IFR_TYPE_STRING) {
+
+      TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
+      if (TempBuffer == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+      FreePool (StatementValue->Buffer);
+      StatementValue->Buffer = NULL;
+      StatementValue->BufferLen = 0;
+
+      Status = HiiStringToOneOfOptionValue (TargetStatement, Schema, TempBuffer, StatementValue);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given %s\n", __FUNCTION__, TempBuffer));
+        FreePool (TempBuffer);
+        return EFI_NOT_FOUND;
+      }
+
+      FreePool (TempBuffer);
+    } else if (TargetStatement->HiiStatement->Operand == EFI_IFR_ORDERED_LIST_OP && StatementValue->Type == EFI_IFR_TYPE_STRING) {
+      //
+      // We treat ordered list type as string in Redfish. But ordered list statement is not
+      // in string format from HII point of view. Do a patch here.
+      //
+      StringArray = AllocateZeroPool (TargetStatement->HiiStatement->StorageWidth);
+      if (StringArray == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      //
+      // Arrage new option order from input string array
+      //
+      CharArray = (CHAR8 **)StatementValue->Buffer;
+      for (Index = 0; Index < StatementValue->BufferLen; Index++) {
+        TempBuffer = StrToUnicodeStr (CharArray[Index]);
+        if (TempBuffer == NULL) {
+          return EFI_OUT_OF_RESOURCES;
+        }
+
+        Status = HiiStringToOrderedListOptionValue (TargetStatement, Schema, TempBuffer, &Value);
+        if (EFI_ERROR (Status)) {
+          ASSERT (FALSE);
+          continue;
+        }
+        FreePool (TempBuffer);
+        OrderedListSetArrayData (StringArray, TargetStatement->HiiStatement->Value.BufferValueType, Index, Value);
+      }
+
+      StatementValue->Type = EFI_IFR_TYPE_BUFFER;
+      StatementValue->Buffer = StringArray;
+      StatementValue->BufferLen = TargetStatement->HiiStatement->StorageWidth;
+      StatementValue->BufferValueType = TargetStatement->HiiStatement->Value.BufferValueType;
+    } else if (TargetStatement->HiiStatement->Operand == EFI_IFR_NUMERIC_OP && StatementValue->Type == EFI_IFR_TYPE_NUM_SIZE_64) {
+      //
+      // Redfish only has numeric value type and it does not care about the value size.
+      // Do a patch here so we have proper value size applied.
+      //
+      StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
+    } else {
+      DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type: 0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue->Type, TargetStatement->HiiStatement->Value.Type));
+      ASSERT (FALSE);
+    }
+  }
+
+  Status = RedfishPlatformConfigSaveQuestionValue (
+             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
+             TargetStatement->ParentForm->HiiForm,
+             TargetStatement->HiiStatement,
+             StatementValue
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Set Redfish value with the given Schema and Configure Language.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+  @param[in]   Schema              The Redfish schema to query.
+  @param[in]   Version             The Redfish version to query.
+  @param[in]   ConfigureLang       The target value which match this configure Language.
+  @param[in]   Value               The value to set.
+
+  @retval EFI_SUCCESS              Value is returned successfully.
+  @retval Others                   Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolSetValue (
+  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+  IN     CHAR8                                  *Schema,
+  IN     CHAR8                                  *Version,
+  IN     EFI_STRING                             ConfigureLang,
+  IN     EDKII_REDFISH_VALUE                    Value
+  )
+{
+  EFI_STATUS                                Status;
+  REDFISH_PLATFORM_CONFIG_PRIVATE           *RedfishPlatformConfigPrivate;
+  CHAR8                                     *FullSchema;
+  HII_STATEMENT_VALUE                       NewValue;
+
+  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || IS_EMPTY_STRING (ConfigureLang)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >= REDFISH_VALUE_TYPE_MAX) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+  FullSchema = NULL;
+
+  FullSchema = GetFullSchemaString (Schema, Version);
+  if (FullSchema == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
+
+  switch (Value.Type) {
+    case REDFISH_VALUE_TYPE_INTEGER:
+    case REDFISH_VALUE_TYPE_BOOLEAN:
+      Status = RedfishNumericToHiiValue (&Value, &NewValue);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii value: %r\n", __FUNCTION__, Status));
+        goto RELEASE_RESOURCE;
+      }
+      break;
+    case REDFISH_VALUE_TYPE_STRING:
+      NewValue.Type = EFI_IFR_TYPE_STRING;
+      NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
+      NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen, Value.Value.Buffer);
+      if (NewValue.Buffer == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto RELEASE_RESOURCE;
+      }
+      break;
+    case REDFISH_VALUE_TYPE_STRING_ARRAY:
+      NewValue.Type = EFI_IFR_TYPE_STRING;
+      NewValue.BufferLen = (UINT16)Value.ArrayCount;
+      NewValue.Buffer = (UINT8 *)Value.Value.StringArray;
+      break;
+    default:
+      ASSERT (FALSE);
+      break;
+  }
+
+  Status = RedfishPlatformConfigSetStatementCommon (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n", __FUNCTION__, Status));
+  }
+
+RELEASE_RESOURCE:
+
+  if (FullSchema != NULL) {
+    FreePool (FullSchema);
+  }
+
+  return Status;
+}
+
+/**
+  Get the list of Configure Language from platform configuration by the given Schema and RegexPattern.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+  @param[in]   Schema              The Redfish schema to query.
+  @param[in]   Version             The Redfish version to query.
+  @param[in]   RegexPattern        The target Configure Language pattern. This is used for regular expression matching.
+  @param[out]  ConfigureLangList   The list of Configure Language.
+  @param[out]  Count               The number of Configure Language in ConfigureLangList.
+
+  @retval EFI_SUCCESS              ConfigureLangList is returned successfully.
+  @retval Others                   Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetConfigureLang (
+  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
+  IN     CHAR8                                  *Schema,
+  IN     CHAR8                                  *Version,
+  IN     EFI_STRING                             RegexPattern,
+  OUT    EFI_STRING                             **ConfigureLangList,
+  OUT    UINTN                                  *Count
+  )
+{
+  REDFISH_PLATFORM_CONFIG_PRIVATE                 *RedfishPlatformConfigPrivate;
+  EFI_STATUS                                      Status;
+  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;
+
+  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version) || Count == NULL || ConfigureLangList == NULL || IS_EMPTY_STRING (RegexPattern)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Count = 0;
+  *ConfigureLangList = NULL;
+  FullSchema = NULL;
+  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  FullSchema = GetFullSchemaString (Schema, Version);
+  if (FullSchema == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = GetStatementPrivateByConfigureLangRegex (
+             RedfishPlatformConfigPrivate->RegularExpressionProtocol,
+             &RedfishPlatformConfigPrivate->FormsetList,
+             FullSchema,
+             RegexPattern,
+             &StatementList
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__, Status));
+    goto RELEASE_RESOURCE;
+  }
+
+  if (!IsListEmpty (&StatementList.StatementList)) {
+
+    TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) * StatementList.Count);
+    if (TmpConfigureLangList == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto RELEASE_RESOURCE;
+    }
+
+    Index = 0;
+    NextLink = GetFirstNode (&StatementList.StatementList);
+    while (!IsNull (&StatementList.StatementList, NextLink)) {
+      StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
+      NextLink = GetNextNode (&StatementList.StatementList, NextLink);
+
+      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] = AllocateCopyPool (StrSize (TmpString), TmpString);
+          ASSERT (TmpConfigureLangList[Index] != NULL);
+          FreePool (TmpString);
+          ++Index;
+        }
+      }
+    }
+  }
+
+  *Count = StatementList.Count;
+  *ConfigureLangList = TmpConfigureLangList;
+
+RELEASE_RESOURCE:
+
+  if (FullSchema != NULL) {
+    FreePool (FullSchema);
+  }
+
+  ReleaseStatementList (&StatementList);
+
+  return Status;
+}
+
+/**
+  Get the list of supported Redfish schema from paltform configuration on give HII handle.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
+  @param[in]   HiiHandle           The target handle to search. If handle is NULL,
+                                   this function return all schema from HII database.
+  @param[out]  SupportedSchema     The supported schema list which is separated by ';'.
+                                   The SupportedSchema is allocated by the callee. It's caller's
+                                   responsibility to free this buffer using FreePool().
+
+  @retval EFI_SUCCESS              Schema is returned successfully.
+  @retval Others                   Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigProtocolGetSupportedSchema (
+  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL   *This,
+  IN     EFI_HII_HANDLE                           HiiHandle,       OPTIONAL
+  OUT    CHAR8                                    **SupportedSchema
+  )
+{
+  REDFISH_PLATFORM_CONFIG_PRIVATE           *RedfishPlatformConfigPrivate;
+  EFI_STATUS                                Status;
+  LIST_ENTRY                                *HiiFormsetLink;
+  LIST_ENTRY                                *HiiFormsetNextLink;
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
+  UINTN                                     Index;
+  UINTN                                     StringSize;
+  CHAR8                                     *StringBuffer;
+  UINTN                                     StringIndex;
+
+  if (This == NULL || SupportedSchema == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *SupportedSchema = NULL;
+
+  RedfishPlatformConfigPrivate = REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
+
+  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList, &RedfishPlatformConfigPrivate->PendingList);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Calculate for string buffer size.
+  //
+  StringSize = 0;
+  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
+  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
+    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
+    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+    if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+      HiiFormsetLink = HiiFormsetNextLink;
+      continue;
+    }
+
+    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
+        StringSize += AsciiStrSize (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+      }
+    }
+
+    HiiFormsetLink = HiiFormsetNextLink;
+  }
+
+  if (StringSize == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  StringBuffer = AllocatePool (StringSize);
+  if (StringBuffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  StringIndex = 0;
+  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate->FormsetList);
+  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink)) {
+    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate->FormsetList, HiiFormsetLink);
+    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+    if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
+      HiiFormsetLink = HiiFormsetNextLink;
+      continue;
+    }
+
+    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
+      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count; Index++) {
+        AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex), HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+        StringIndex += AsciiStrLen (HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
+        StringBuffer[StringIndex] = ';';
+        ++StringIndex;
+      }
+    }
+
+    HiiFormsetLink = HiiFormsetNextLink;
+  }
+
+  StringBuffer[--StringIndex] = '\0';
+
+  *SupportedSchema = StringBuffer;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Functions which are registered to receive notification of
+  database events have this prototype. The actual event is encoded
+  in NotifyType. The following table describes how PackageType,
+  PackageGuid, Handle, and Package are used for each of the
+  notification types.
+
+  @param[in] PackageType  Package type of the notification.
+  @param[in] PackageGuid  If PackageType is
+                          EFI_HII_PACKAGE_TYPE_GUID, then this is
+                          the pointer to the GUID from the Guid
+                          field of EFI_HII_PACKAGE_GUID_HEADER.
+                          Otherwise, it must be NULL.
+  @param[in] Package      Points to the package referred to by the
+                          notification Handle The handle of the package
+                          list which contains the specified package.
+  @param[in] Handle       The HII handle.
+  @param[in] NotifyType   The type of change concerning the
+                          database. See
+                          EFI_HII_DATABASE_NOTIFY_TYPE.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigFormUpdateNotify (
+  IN UINT8                              PackageType,
+  IN CONST EFI_GUID                     *PackageGuid,
+  IN CONST EFI_HII_PACKAGE_HEADER       *Package,
+  IN EFI_HII_HANDLE                     Handle,
+  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType
+  )
+{
+  EFI_STATUS  Status;
+
+  if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
+    //
+    // HII formset on this handle is updated by driver during run-time. The formset needs to be reloaded.
+    //
+    Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate->PendingList);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
+      return Status;
+    }
+  } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
+    //
+    // HII resource is removed. The formset is no longer exist.
+    //
+    Status = NotifyFormsetDeleted (Handle, &mRedfishPlatformConfigPrivate->PendingList);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII handle: 0x%x\n", __FUNCTION__, Handle));
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This is a EFI_HII_STRING_PROTOCOL notification event handler.
+
+  Install HII package notification.
+
+  @param[in] Event    Event whose notification function is being invoked.
+  @param[in] Context  Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+HiiStringProtocolInstalled (
+  IN  EFI_EVENT       Event,
+  IN  VOID            *Context
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Locate HII database protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiStringProtocolGuid,
+                  NULL,
+                  (VOID **)&mRedfishPlatformConfigPrivate->HiiString
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure: %r\n", __FUNCTION__, Status));
+    return;
+  }
+
+  gBS->CloseEvent (Event);
+  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
+}
+
+/**
+  This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
+
+  Install HII package notification.
+
+  @param[in] Event    Event whose notification function is being invoked.
+  @param[in] Context  Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+HiiDatabaseProtocolInstalled (
+  IN  EFI_EVENT       Event,
+  IN  VOID            *Context
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Locate HII database protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiDatabaseProtocolGuid,
+                  NULL,
+                  (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL failure: %r\n", __FUNCTION__, Status));
+    return;
+  }
+
+  //
+  // Register package notification when new form package is installed.
+  //
+  Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
+                                             mRedfishPlatformConfigPrivate->HiiDatabase,
+                                             EFI_HII_PACKAGE_FORMS,
+                                             NULL,
+                                             RedfishPlatformConfigFormUpdateNotify,
+                                             EFI_HII_DATABASE_NOTIFY_NEW_PACK,
+                                             &mRedfishPlatformConfigPrivate->NotifyHandle
+                                             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
+  }
+
+  //
+  // Register package notification when new form package is updated.
+  //
+  Status = mRedfishPlatformConfigPrivate->HiiDatabase->RegisterPackageNotify (
+                                             mRedfishPlatformConfigPrivate->HiiDatabase,
+                                             EFI_HII_PACKAGE_FORMS,
+                                             NULL,
+                                             RedfishPlatformConfigFormUpdateNotify,
+                                             EFI_HII_DATABASE_NOTIFY_ADD_PACK,
+                                             &mRedfishPlatformConfigPrivate->NotifyHandle
+                                             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__, Status));
+  }
+
+  gBS->CloseEvent (Event);
+  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
+
+}
+
+/**
+  This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
+
+  @param[in] Event    Event whose notification function is being invoked.
+  @param[in] Context  Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+RegexProtocolInstalled (
+  IN  EFI_EVENT       Event,
+  IN  VOID            *Context
+  )
+{
+  EFI_STATUS  Status;
+
+  //
+  // Locate regular expression protocol.
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiRegularExpressionProtocolGuid,
+                  NULL,
+                  (VOID **)&mRedfishPlatformConfigPrivate->RegularExpressionProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, locate EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__, Status));
+    return;
+  }
+
+  gBS->CloseEvent (Event);
+  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
+
+}
+
+/**
+  Unloads an image.
+
+  @param  ImageHandle           Handle that identifies the image to be unloaded.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigDxeUnload (
+  IN EFI_HANDLE  ImageHandle
+  )
+{
+  EFI_STATUS Status;
+
+  if (mRedfishPlatformConfigPrivate != NULL) {
+    Status = gBS->UninstallProtocolInterface (
+                    mRedfishPlatformConfigPrivate->ImageHandle,
+                    &gEdkIIRedfishPlatformConfigProtocolGuid,
+                    (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a, can not uninstall gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+      ASSERT (FALSE);
+    }
+
+    //
+    // Close events
+    //
+    if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
+      gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent);
+    }
+    if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL) {
+      gBS->CloseEvent (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent);
+    }
+    if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
+      gBS->CloseEvent (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent);
+    }
+
+    //
+    // Unregister package notification.
+    //
+    if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
+      mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify (
+                                          mRedfishPlatformConfigPrivate->HiiDatabase,
+                                          mRedfishPlatformConfigPrivate->NotifyHandle
+                                          );
+    }
+
+    ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
+    FreePool (mRedfishPlatformConfigPrivate);
+    mRedfishPlatformConfigPrivate = NULL;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This is the declaration of an EFI image entry point. This entry point is
+  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+  both device drivers and bus drivers.
+
+  @param  ImageHandle           The firmware allocated handle for the UEFI image.
+  @param  SystemTable           A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval Others                An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformConfigDxeEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
+  if (mRedfishPlatformConfigPrivate == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
+    ASSERT (FALSE);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Protocol initialization
+  //
+  mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
+  mRedfishPlatformConfigPrivate->Protocol.GetValue = RedfishPlatformConfigProtocolGetValue;
+  mRedfishPlatformConfigPrivate->Protocol.SetValue = RedfishPlatformConfigProtocolSetValue;
+  mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang = RedfishPlatformConfigProtocolGetConfigureLang;
+  mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema = RedfishPlatformConfigProtocolGetSupportedSchema;
+
+  InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
+  InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
+
+  Status = gBS->InstallProtocolInterface (
+                  &ImageHandle,
+                  &gEdkIIRedfishPlatformConfigProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  (VOID*)&mRedfishPlatformConfigPrivate->Protocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, can not install gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Install protocol notification if HII database protocol is installed.
+  //
+  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
+                                                              &gEfiHiiDatabaseProtocolGuid,
+                                                              TPL_CALLBACK,
+                                                              HiiDatabaseProtocolInstalled,
+                                                              NULL,
+                                                              &mRedfishPlatformConfigPrivate->HiiDbNotify.Registration
+                                                              );
+  if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Install protocol notification if HII string protocol is installed.
+  //
+  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
+                                                                  &gEfiHiiStringProtocolGuid,
+                                                                  TPL_CALLBACK,
+                                                                  HiiStringProtocolInstalled,
+                                                                  NULL,
+                                                                  &mRedfishPlatformConfigPrivate->HiiStringNotify.Registration
+                                                                  );
+  if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiHiiStringProtocolGuid\n", __FUNCTION__));
+    ASSERT (FALSE);
+  }
+
+  //
+  // Install protocol notification if regular expression protocol is installed.
+  //
+  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = EfiCreateProtocolNotifyEvent (
+                                                              &gEfiRegularExpressionProtocolGuid,
+                                                              TPL_CALLBACK,
+                                                              RegexProtocolInstalled,
+                                                              NULL,
+                                                              &mRedfishPlatformConfigPrivate->RegexNotify.Registration
+                                                              );
+  if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
+    ASSERT (FALSE);
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
index 99a613d229..d3f7af55ad 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
@@ -1,64 +1,64 @@
-/** @file
-  This file defines the EDKII Redfish Platform Config Protocol interface.
-
-  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
-
-#include <Uefi.h>
-
-//
-// Libraries
-//
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-
-//
-// Produced Protocols
-//
-#include <Protocol/EdkIIRedfishPlatformConfig.h>
-#include <Protocol/HiiDatabase.h>
-#include <Protocol/HiiString.h>
-#include <Protocol/RegularExpressionProtocol.h>
-
-//
-// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
-//
-typedef struct {
-  EFI_EVENT                   ProtocolEvent;   // Protocol notification event.
-  VOID                        *Registration;   // Protocol notification registration.
-} REDFISH_PLATFORM_CONFIG_NOTIFY;
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
-//
-typedef struct {
-  EFI_HANDLE                                ImageHandle;                // Driver image handle.
-  EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL    Protocol;
-  REDFISH_PLATFORM_CONFIG_NOTIFY            HiiDbNotify;
-  EFI_HII_DATABASE_PROTOCOL                 *HiiDatabase;               // The HII database protocol.
-  REDFISH_PLATFORM_CONFIG_NOTIFY            HiiStringNotify;
-  EFI_HII_STRING_PROTOCOL                   *HiiString;                 // HII String Protocol.
-  REDFISH_PLATFORM_CONFIG_NOTIFY            RegexNotify;
-  EFI_REGULAR_EXPRESSION_PROTOCOL           *RegularExpressionProtocol; // Regular Expression Protocol.
-  EFI_HANDLE                                NotifyHandle;               // The notify handle.
-  LIST_ENTRY                                FormsetList;                // The list to keep cached HII formset.
-  LIST_ENTRY                                PendingList;                // The list to keep updated HII handle.
-} REDFISH_PLATFORM_CONFIG_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
-#define REGULAR_EXPRESSION_INCLUDE_ALL                L".*"
-#define CONFIGURE_LANGUAGE_PREFIX                     "x-uefi-redfish-"
-
-#endif
+/** @file
+  This file defines the EDKII Redfish Platform Config Protocol interface.
+
+  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+
+//
+// Produced Protocols
+//
+#include <Protocol/EdkIIRedfishPlatformConfig.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+#include <Protocol/RegularExpressionProtocol.h>
+
+//
+// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
+//
+typedef struct {
+  EFI_EVENT                   ProtocolEvent;   // Protocol notification event.
+  VOID                        *Registration;   // Protocol notification registration.
+} REDFISH_PLATFORM_CONFIG_NOTIFY;
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
+//
+typedef struct {
+  EFI_HANDLE                                ImageHandle;                // Driver image handle.
+  EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL    Protocol;
+  REDFISH_PLATFORM_CONFIG_NOTIFY            HiiDbNotify;
+  EFI_HII_DATABASE_PROTOCOL                 *HiiDatabase;               // The HII database protocol.
+  REDFISH_PLATFORM_CONFIG_NOTIFY            HiiStringNotify;
+  EFI_HII_STRING_PROTOCOL                   *HiiString;                 // HII String Protocol.
+  REDFISH_PLATFORM_CONFIG_NOTIFY            RegexNotify;
+  EFI_REGULAR_EXPRESSION_PROTOCOL           *RegularExpressionProtocol; // Regular Expression Protocol.
+  EFI_HANDLE                                NotifyHandle;               // The notify handle.
+  LIST_ENTRY                                FormsetList;                // The list to keep cached HII formset.
+  LIST_ENTRY                                PendingList;                // The list to keep updated HII handle.
+} REDFISH_PLATFORM_CONFIG_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
+#define REGULAR_EXPRESSION_INCLUDE_ALL                L".*"
+#define CONFIGURE_LANGUAGE_PREFIX                     "x-uefi-redfish-"
+
+#endif
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
index 16739bef7a..81b22e03c3 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
@@ -1,53 +1,53 @@
-## @file
-#  Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interfaces.
-#
-#  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-#  SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
-  INF_VERSION               = 0x00010005
-  BASE_NAME                 = RedfishPlatformConfigDxe
-  FILE_GUID                 = BEAEFFE1-0633-41B5-913C-9389339C2927
-  MODULE_TYPE               = DXE_DRIVER
-  VERSION_STRING            = 1.0
-  ENTRY_POINT               = RedfishPlatformConfigDxeEntryPoint
-  UNLOAD_IMAGE              = RedfishPlatformConfigDxeUnload
-
-[Packages]
-  MdePkg/MdePkg.dec
-  MdeModulePkg/MdeModulePkg.dec
-  RedfishPkg/RedfishPkg.dec
-
-[Sources]
-  RedfishPlatformConfigDxe.h
-  RedfishPlatformConfigDxe.c
-  RedfishPlatformConfigImpl.h
-  RedfishPlatformConfigImpl.c
-
-[LibraryClasses]
-  BaseLib
-  BaseMemoryLib
-  DebugLib
-  DevicePathLib
-  HiiLib
-  HiiUtilityLib
-  MemoryAllocationLib
-  PrintLib
-  UefiLib
-  UefiBootServicesTableLib
-  UefiRuntimeServicesTableLib
-  UefiDriverEntryPoint
-
-[Protocols]
-  gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
-  gEfiHiiDatabaseProtocolGuid             ## CONSUMED
-  gEfiHiiStringProtocolGuid               ## CONSUMED
-  gEfiRegularExpressionProtocolGuid       ## CONSUMED
-
-[Guids]
-  gEfiRegexSyntaxTypePerlGuid             ## CONSUMED
-
-[Depex]
+## @file
+#  Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL interfaces.
+#
+#  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION               = 0x00010005
+  BASE_NAME                 = RedfishPlatformConfigDxe
+  FILE_GUID                 = BEAEFFE1-0633-41B5-913C-9389339C2927
+  MODULE_TYPE               = DXE_DRIVER
+  VERSION_STRING            = 1.0
+  ENTRY_POINT               = RedfishPlatformConfigDxeEntryPoint
+  UNLOAD_IMAGE              = RedfishPlatformConfigDxeUnload
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RedfishPkg/RedfishPkg.dec
+
+[Sources]
+  RedfishPlatformConfigDxe.h
+  RedfishPlatformConfigDxe.c
+  RedfishPlatformConfigImpl.h
+  RedfishPlatformConfigImpl.c
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  HiiLib
+  HiiUtilityLib
+  MemoryAllocationLib
+  PrintLib
+  UefiLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
+  gEfiHiiDatabaseProtocolGuid             ## CONSUMED
+  gEfiHiiStringProtocolGuid               ## CONSUMED
+  gEfiRegularExpressionProtocolGuid       ## CONSUMED
+
+[Guids]
+  gEfiRegexSyntaxTypePerlGuid             ## CONSUMED
+
+[Depex]
   TRUE
\ No newline at end of file
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
index d9eab6c883..525e666b6c 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
@@ -1,1240 +1,1288 @@
-/** @file
-
-  The implementation of EDKII Redfidh Platform Config Protocol.
-
-  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "RedfishPlatformConfigDxe.h"
-#include "RedfishPlatformConfigImpl.h"
-
-extern REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate;
-
-/**
-  Debug dump HII string
-
-  @param[in]  HiiHandle   HII handle instance
-  @param[in]  StringId    HII string to dump
-
-  @retval EFI_SUCCESS       Dump HII string successfully
-  @retval Others            Errors occur
-
-**/
-EFI_STATUS
-DumpHiiString (
-  IN EFI_HII_HANDLE HiiHandle,
-  IN EFI_STRING_ID  StringId
-  )
-{
-  EFI_STRING String;
-
-  if (HiiHandle == NULL || StringId == 0) {
-    DEBUG ((DEBUG_INFO, "???"));
-    return EFI_INVALID_PARAMETER;
-  }
-
-  String = HiiGetString (HiiHandle, StringId, NULL);
-  if (String == NULL) {
-    return EFI_NOT_FOUND;
-  }
-
-  DEBUG ((DEBUG_INFO, "%s", String));
-  FreePool (String);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Debug dump HII form-set data
-
-  @param[in]  FormsetPrivate    HII form-set private instance.
-
-  @retval EFI_SUCCESS       Dump form-set successfully
-  @retval Others            Errors occur
-
-**/
-EFI_STATUS
-DumpFormset (
-  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
-  )
-{
-  LIST_ENTRY                      *HiiFormLink;
-  LIST_ENTRY                      *HiiNextFormLink;
-  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
-  LIST_ENTRY                      *HiiStatementLink;
-  LIST_ENTRY                      *HiiNextStatementLink;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
-  UINTN                           Index;
-
-  if (FormsetPrivate == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Index = 0;
-  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
-  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
-    HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
-    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
-
-    DEBUG ((DEBUG_INFO, "  [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
-    DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
-    DEBUG ((DEBUG_INFO, "\n"));
-
-    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
-    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
-      HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
-
-      DEBUG ((DEBUG_INFO, "    QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
-      DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Description);
-      DEBUG ((DEBUG_INFO, "\n"));
-
-      HiiStatementLink = HiiNextStatementLink;
-    }
-
-    HiiFormLink = HiiNextFormLink;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Debug dump HII form-set list
-
-  @param[in]  FormsetList   Form-set list instance
-
-  @retval EFI_SUCCESS       Dump list successfully
-  @retval Others            Errors occur
-
-**/
-EFI_STATUS
-DumpFormsetList (
-  IN  LIST_ENTRY      *FormsetList
-  )
-{
-  LIST_ENTRY                      *HiiFormsetLink;
-  LIST_ENTRY                      *HiiFormsetNextLink;
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
-  UINTN                           Index;
-
-  if (FormsetList == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (IsListEmpty (FormsetList)) {
-    DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
-    return EFI_SUCCESS;
-  }
-
-  Index = 0;
-  HiiFormsetLink = GetFirstNode (FormsetList);
-  while (!IsNull (FormsetList, HiiFormsetLink)) {
-    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
-    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
-    DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
-    DumpFormset (HiiFormsetPrivate);
-
-    HiiFormsetLink = HiiFormsetNextLink;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Retrieves a string from a string package in a English language. The
-  returned string is allocated using AllocatePool().  The caller is responsible
-  for freeing the allocated buffer using FreePool().
-
-  If HiiHandle is NULL, then ASSERT().
-  If StringId is 0, then ASSET.
-
-  @param[in]  HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
-  @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
-HiiGetRedfishString (
-  IN EFI_HII_HANDLE           HiiHandle,
-  IN CHAR8                    *Language,
-  IN EFI_STRING_ID            StringId
-  )
-{
-  EFI_STATUS  Status;
-  UINTN       StringSize;
-  CHAR16      TempString;
-  EFI_STRING  String;
-
-  if (mRedfishPlatformConfigPrivate->HiiString == NULL || HiiHandle == NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
-    ASSERT (FALSE);
-    return NULL;
-  }
-
-  //
-  // Retrieve the size of the string in the string package for the BestLanguage
-  //
-  StringSize = 0;
-  Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
-                                             mRedfishPlatformConfigPrivate->HiiString,
-                                             Language,
-                                             HiiHandle,
-                                             StringId,
-                                             &TempString,
-                                             &StringSize,
-                                             NULL
-                                             );
-  //
-  // If GetString() returns EFI_SUCCESS for a zero size,
-  // then there are no supported languages registered for HiiHandle.  If GetString()
-  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
-  // in the HII Database
-  //
-  if (Status != EFI_BUFFER_TOO_SMALL) {
-    return NULL;
-  }
-
-  //
-  // Allocate a buffer for the return string
-  //
-  String = AllocateZeroPool (StringSize);
-  if (String == NULL) {
-    return NULL;
-  }
-
-  //
-  // Retrieve the string from the string package
-  //
-  Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
-                                             mRedfishPlatformConfigPrivate->HiiString,
-                                             Language,
-                                             HiiHandle,
-                                             StringId,
-                                             String,
-                                             &StringSize,
-                                             NULL
-                                             );
-  if (EFI_ERROR (Status)) {
-    //
-    // Free the buffer and return NULL if the supported languages can not be retrieved.
-    //
-    FreePool (String);
-    String = NULL;
-  }
-
-  //
-  // Return the Null-terminated Unicode string
-  //
-  return String;
-}
-
-/**
-  Get string from HII database in English language.
-
-  @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);
-}
-
-/**
-  Check and see if this is supported schema or not.
-
-  @param[in]  SupportedSchema   The list of supported schema.
-  @param[in]  Schema            Schema string to be checked.
-
-  @retval BOOLEAN               TRUE if this is supported schema. FALSE otherwise.
-
-**/
-BOOLEAN
-CheckSupportedSchema (
-  IN REDFISH_PLATFORM_CONFIG_SCHEMA   *SupportedSchema,
-  IN CHAR8                            *Schema
-  )
-{
-  UINTN Index;
-
-  if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
-    return FALSE;
-  }
-
-  if (SupportedSchema->Count == 0) {
-    return FALSE;
-  }
-
-  for (Index = 0; Index < SupportedSchema->Count; Index++) {
-    if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
-
-/**
-  Get the list of supported schema from the given HII handle.
-
-  @param[in]  HiiHandle         HII handle instance.
-  @param[out] SupportedSchema   Supported schema on this HII handle.
-
-  @retval EFI_SUCCESS           Schema list is returned.
-  @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema is NULL.
-  @retval EFI_NOT_FOUND         No supported schema found.
-  @retval EFI_OUT_OF_RESOURCES  System is out of memory.
-
-**/
-EFI_STATUS
-GetSupportedSchema (
-  IN  EFI_HII_HANDLE                  HiiHandle,
-  OUT REDFISH_PLATFORM_CONFIG_SCHEMA  *SupportedSchema
-  )
-{
-  CHAR8 *SupportedLanguages;
-  UINTN Index;
-  UINTN LangIndex;
-  UINTN Count;
-  UINTN StrSize;
-  UINTN ListIndex;
-
-  if (HiiHandle == NULL || SupportedSchema == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  SupportedSchema->Count = 0;
-
-  SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
-  if (SupportedLanguages == NULL) {
-    return EFI_NOT_FOUND;
-  }
-
-  Index = 0;
-  LangIndex = 0;
-  Count = 0;
-  while (TRUE) {
-    if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
-      if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
-        ++Count;
-      }
-      LangIndex = Index + 1;
-    }
-
-    if (SupportedLanguages[Index] == '\0') {
-      break;
-    }
-
-    ++Index;
-  }
-
-  if (Count == 0) {
-    return EFI_NOT_FOUND;
-  }
-
-  SupportedSchema->Count = Count;
-  SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
-  if (SupportedSchema->SchemaList == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  Index = 0;
-  LangIndex = 0;
-  ListIndex = 0;
-  while (TRUE) {
-
-    if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
-      if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
-        StrSize = Index - LangIndex;
-        SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize + 1), &SupportedLanguages[LangIndex]);
-        SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
-        ++ListIndex;
-      }
-
-      LangIndex = Index + 1;
-    }
-
-    if (SupportedLanguages[Index] == '\0') {
-      break;
-    }
-
-    ++Index;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Search and find statement private instance by given regular expression patthern
-  which describes the Configure Language.
-
-  @param[in]  RegularExpressionProtocol   Regular express protocol.
-  @param[in]  FormsetList                 Form-set list to search.
-  @param[in]  Schema                      Schema to be matched.
-  @param[in]  Pattern                     Regular expression pattern.
-  @param[out] StatementList               Statement list that match above pattern.
-
-  @retval EFI_SUCCESS             Statement list is returned.
-  @retval EFI_INVALID_PARAMETER   Input parameter is NULL.
-  @retval EFI_NOT_READY           Regular express protocol is NULL.
-  @retval EFI_NOT_FOUND           No statement is found.
-  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
-
-**/
-EFI_STATUS
-GetStatementPrivateByConfigureLangRegex (
-  IN  EFI_REGULAR_EXPRESSION_PROTOCOL                 *RegularExpressionProtocol,
-  IN  LIST_ENTRY                                      *FormsetList,
-  IN  CHAR8                                           *Schema,
-  IN  EFI_STRING                                      Pattern,
-  OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
-  )
-{
-  LIST_ENTRY                      *HiiFormsetLink;
-  LIST_ENTRY                      *HiiFormsetNextLink;
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
-  LIST_ENTRY                      *HiiFormLink;
-  LIST_ENTRY                      *HiiNextFormLink;
-  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
-  LIST_ENTRY                      *HiiStatementLink;
-  LIST_ENTRY                      *HiiNextStatementLink;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
-  EFI_STRING                      TmpString;
-  UINTN                           CaptureCount;
-  BOOLEAN                         IsMatch;
-  EFI_STATUS                      Status;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
-
-  if (FormsetList == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (RegularExpressionProtocol == NULL) {
-    return EFI_NOT_READY;
-  }
-
-  StatementList->Count = 0;
-  InitializeListHead (&StatementList->StatementList);
-
-  if (IsListEmpty (FormsetList)) {
-    return EFI_NOT_FOUND;
-  }
-
-  HiiFormsetLink = GetFirstNode (FormsetList);
-  while (!IsNull (FormsetList, HiiFormsetLink)) {
-    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
-    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
-    //
-    // Performance check.
-    // If there is no desired Redfish schema found, skip this formset.
-    //
-    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
-      HiiFormsetLink = HiiFormsetNextLink;
-      continue;
-    }
-
-    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
-    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
-      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
-      HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
-
-      HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
-      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
-        HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
-        HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-
-        if (HiiStatementPrivate->Description != 0) {
-          TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
-          if (TmpString != NULL) {
-            Status = RegularExpressionProtocol->MatchString (
-                                                  RegularExpressionProtocol,
-                                                  TmpString,
-                                                  Pattern,
-                                                  &gEfiRegexSyntaxTypePerlGuid,
-                                                  &IsMatch,
-                                                  NULL,
-                                                  &CaptureCount
-                                                  );
-            if (EFI_ERROR (Status)) {
-              DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n", __FUNCTION__, Pattern, Status));
-              ASSERT (FALSE);
-              return Status;
-            }
-
-            //
-            // Found
-            //
-            if (IsMatch) {
-              StatementRef = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
-              if (StatementRef == NULL) {
-                return EFI_OUT_OF_RESOURCES;
-              }
-
-              StatementRef->Statement = HiiStatementPrivate;
-              InsertTailList (&StatementList->StatementList, &StatementRef->Link);
-              ++StatementList->Count;
-            }
-
-            FreePool (TmpString);
-          }
-        }
-
-        HiiStatementLink = HiiNextStatementLink;
-      }
-
-      HiiFormLink = HiiNextFormLink;
-    }
-
-    HiiFormsetLink = HiiFormsetNextLink;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Get statement private instance by the given configure language.
-
-  @param[in]  FormsetList                 Form-set list to search.
-  @param[in]  Schema                      Schema to be matched.
-  @param[in]  ConfigureLang               Configure language.
-
-  @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *   Pointer to statement private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
-GetStatementPrivateByConfigureLang (
-  IN  LIST_ENTRY    *FormsetList,
-  IN  CHAR8         *Schema,
-  IN  EFI_STRING    ConfigureLang
-  )
-{
-  LIST_ENTRY                      *HiiFormsetLink;
-  LIST_ENTRY                      *HiiFormsetNextLink;
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
-  LIST_ENTRY                      *HiiFormLink;
-  LIST_ENTRY                      *HiiNextFormLink;
-  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
-  LIST_ENTRY                      *HiiStatementLink;
-  LIST_ENTRY                      *HiiNextStatementLink;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
-  EFI_STRING                      TmpString;
-
-  if (FormsetList == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang)) {
-    return NULL;
-  }
-
-  if (IsListEmpty (FormsetList)) {
-    return NULL;
-  }
-
-  HiiFormsetLink = GetFirstNode (FormsetList);
-  while (!IsNull (FormsetList, HiiFormsetLink)) {
-    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
-    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
-    //
-    // Performance check.
-    // If there is no desired Redfish schema found, skip this formset.
-    //
-    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
-      HiiFormsetLink = HiiFormsetNextLink;
-      continue;
-    }
-
-    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
-    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
-      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
-      HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
-
-      HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
-      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
-        HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
-        HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-
-        DEBUG_CODE (
-          STATIC UINTN Index = 0;
-          DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x formset: %g\n", __FUNCTION__, ++Index, ConfigureLang, HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate->Guid));
-        );
-
-        if (HiiStatementPrivate->Description != 0) {
-          TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
-          if (TmpString != NULL) {
-            if (StrCmp (TmpString, ConfigureLang) == 0) {
-              FreePool (TmpString);
-              return HiiStatementPrivate;
-            }
-
-            FreePool (TmpString);
-          }
-        }
-
-        HiiStatementLink = HiiNextStatementLink;
-      }
-
-      HiiFormLink = HiiNextFormLink;
-    }
-
-    HiiFormsetLink = HiiFormsetNextLink;
-  }
-
-  return NULL;
-}
-
-/**
-  Get form-set private instance by the given HII handle.
-
-  @param[in]  HiiHandle       HII handle instance.
-  @param[in]  FormsetList     Form-set list to search.
-
-  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to form-set private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
-GetFormsetPrivateByHiiHandle (
-  IN  EFI_HII_HANDLE  HiiHandle,
-  IN  LIST_ENTRY      *FormsetList
-  )
-{
-  LIST_ENTRY                      *HiiFormsetLink;
-  LIST_ENTRY                      *HiiFormsetNextLink;
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
-
-  if (HiiHandle == NULL || FormsetList == NULL) {
-    return NULL;
-  }
-
-  if (IsListEmpty (FormsetList)) {
-    return NULL;
-  }
-
-  HiiFormsetLink = GetFirstNode (FormsetList);
-  while (!IsNull (FormsetList, HiiFormsetLink)) {
-    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
-    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
-    if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
-      return HiiFormsetPrivate;
-    }
-
-    HiiFormsetLink = HiiFormsetNextLink;
-  }
-
-  return NULL;
-}
-
-/**
-  Release formset and all the forms and statements that belong to this formset.
-
-  @param[in]      FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
-
-  @retval         EFI_STATUS
-
-**/
-EFI_STATUS
-ReleaseFormset (
-  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
-  )
-{
-  LIST_ENTRY                      *HiiFormLink;
-  LIST_ENTRY                      *HiiNextFormLink;
-  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
-  LIST_ENTRY                      *HiiStatementLink;
-  LIST_ENTRY                      *HiiNextStatementLink;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
-  UINTN                           Index;
-
-  if (FormsetPrivate == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
-  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
-    HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
-    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
-
-    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
-    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
-      HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
-      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
-
-      //
-      // HiiStatementPrivate->HiiStatement will be released in DestroyFormSet().
-      //
-
-      if (HiiStatementPrivate->DesStringCache != NULL) {
-        FreePool (HiiStatementPrivate->DesStringCache);
-        HiiStatementPrivate->DesStringCache = NULL;
-      }
-
-      RemoveEntryList (&HiiStatementPrivate->Link);
-      FreePool (HiiStatementPrivate);
-      HiiStatementLink = HiiNextStatementLink;
-    }
-
-    //
-    // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
-    //
-
-    RemoveEntryList (&HiiFormPrivate->Link);
-    FreePool (HiiFormPrivate);
-    HiiFormLink = HiiNextFormLink;
-  }
-
-  if (FormsetPrivate->HiiFormSet != NULL) {
-    DestroyFormSet (FormsetPrivate->HiiFormSet);
-    FormsetPrivate->HiiFormSet = NULL;
-  }
-
-  FreePool (FormsetPrivate->DevicePathStr);
-
-  //
-  // Release schema list
-  //
-  if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
-    for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count; Index++) {
-      FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
-    }
-
-    FreePool (FormsetPrivate->SupportedSchema.SchemaList);
-    FormsetPrivate->SupportedSchema.SchemaList = NULL;
-    FormsetPrivate->SupportedSchema.Count = 0;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create new form-set instance.
-
-  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to newly created form-set private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *
-NewFormsetPrivate (
-  VOID
-  )
-{
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
-
-  NewFormsetPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
-  if (NewFormsetPrivate == NULL) {
-    return NULL;
-  }
-
-  //
-  // Initial newly created formset private data.
-  //
-  InitializeListHead (&NewFormsetPrivate->HiiFormList);
-
-  return NewFormsetPrivate;
-}
-
-/**
-  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
-
-**/
-EFI_STATUS
-LoadFormset (
-  IN  EFI_HII_HANDLE                  HiiHandle,
-  OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
-  )
-{
-  EFI_STATUS                      Status;
-  HII_FORMSET                     *HiiFormSet;
-  HII_FORM                        *HiiForm;
-  LIST_ENTRY                      *HiiFormLink;
-  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
-  HII_STATEMENT                   *HiiStatement;
-  LIST_ENTRY                      *HiiStatementLink;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
-  EFI_GUID                        ZeroGuid;
-
-  if (HiiHandle == NULL || FormsetPrivate == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-
-  HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
-  if (HiiFormSet == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  //
-  // Find HII formset by the given HII handle.
-  //
-  ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
-  Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
-  if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
-    Status = EFI_NOT_FOUND;
-    goto ErrorExit;
-  }
-
-  //
-  // Initialize formset
-  //
-  InitializeFormSet (HiiFormSet);
-
-  //
-  // Initialize formset private data.
-  //
-  FormsetPrivate->HiiFormSet = HiiFormSet;
-  FormsetPrivate->HiiHandle = HiiHandle;
-  CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
-  FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet->DevicePath, FALSE, FALSE);
-  Status = GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivate->SupportedSchema);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found: %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
-  }
-
-  HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
-  while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
-    HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
-
-    HiiFormPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
-    if (HiiFormPrivate == NULL) {
-      Status = EFI_OUT_OF_RESOURCES;
-      goto ErrorExit;
-    }
-
-    //
-    // Initialize form private data.
-    //
-    HiiFormPrivate->HiiForm = HiiForm;
-    HiiFormPrivate->Id = HiiForm->FormId;
-    HiiFormPrivate->Title = HiiForm->FormTitle;
-    HiiFormPrivate->ParentFormset = FormsetPrivate;
-    InitializeListHead (&HiiFormPrivate->StatementList);
-
-    HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
-    while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
-      HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
-
-      HiiStatementPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
-      if (HiiStatementPrivate == NULL) {
-        Status = EFI_OUT_OF_RESOURCES;
-        goto ErrorExit;
-      }
-      //
-      // Initialize statement private data.
-      //
-      HiiStatementPrivate->HiiStatement = HiiStatement;
-      HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
-      HiiStatementPrivate->Description = HiiStatement->Prompt;
-      HiiStatementPrivate->ParentForm = HiiFormPrivate;
-
-      //
-      // Attach to statement list.
-      //
-      InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
-      HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
-    }
-    //
-    // Attach to form list.
-    //
-    InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
-    HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
-  }
-
-  return EFI_SUCCESS;
-
-ErrorExit:
-
-  //
-  // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
-  //
-  if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != HiiFormSet) {
-    DestroyFormSet (HiiFormSet);
-  }
-
-  //
-  // Release resource when error happens.
-  //
-  ReleaseFormset (FormsetPrivate);
-
-  return Status;
-}
-
-/**
-  Release formset list and all the forms that belong to this formset.
-
-  @param[in]      FormsetList   Pointer to formst list that needs to be
-                                released.
-
-  @retval         EFI_STATUS
-
-**/
-EFI_STATUS
-LoadFormsetList (
-  IN   EFI_HII_HANDLE   *HiiHandle,
-  OUT  LIST_ENTRY       *FormsetList
-  )
-{
-  EFI_STATUS  Status;
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;
-
-  if (HiiHandle == NULL || FormsetList == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
-  if (FormsetPrivate != NULL) {
-    return EFI_ALREADY_STARTED;
-  }
-
-  FormsetPrivate =  NewFormsetPrivate ();
-  if (FormsetPrivate == NULL) {
-    DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  //
-  // Load formset on the given HII handle.
-  //
-  Status = LoadFormset (HiiHandle, FormsetPrivate);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n", __FUNCTION__, Status));
-    FreePool (FormsetPrivate);
-    return Status;
-  }
-
-  //
-  // Attach to cache list.
-  //
-  InsertTailList (FormsetList, &FormsetPrivate->Link);
-
-  DEBUG_CODE (
-    DumpFormsetList (FormsetList);
-    );
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Release formset list and all the forms that belong to this formset.
-
-  @param[in]      FormsetList   Pointer to formst list that needs to be
-                                released.
-
-  @retval         EFI_STATUS
-
-**/
-EFI_STATUS
-ReleaseFormsetList (
-  IN  LIST_ENTRY      *FormsetList
-  )
-{
-  LIST_ENTRY                      *HiiFormsetLink;
-  LIST_ENTRY                      *HiiFormsetNextLink;
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
-
-  if (FormsetList == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (IsListEmpty (FormsetList)) {
-    return EFI_SUCCESS;
-  }
-
-  HiiFormsetLink = GetFirstNode (FormsetList);
-  while (!IsNull (FormsetList, HiiFormsetLink)) {
-    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
-    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
-
-    //
-    // Detach from list.
-    //
-    RemoveEntryList (&HiiFormsetPrivate->Link);
-    ReleaseFormset (HiiFormsetPrivate);
-    FreePool (HiiFormsetPrivate);
-    HiiFormsetLink = HiiFormsetNextLink;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Get all pending list.
-
-  @param[in]  HiiHandle   HII handle instance.
-  @param[in]  PendingList Pending list to keep pending data.
-
-  @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST *   Pointer to pending list data.
-
-**/
-REDFISH_PLATFORM_CONFIG_PENDING_LIST *
-GetPendingList (
-  IN  EFI_HII_HANDLE   *HiiHandle,
-  IN  LIST_ENTRY       *PendingList
-  )
-{
-  LIST_ENTRY                 *PendingListLink;
-  REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
-
-  if (HiiHandle == NULL || PendingList == NULL) {
-    return NULL;
-  }
-
-  if (IsListEmpty (PendingList)) {
-    return NULL;
-  }
-
-  PendingListLink = GetFirstNode (PendingList);
-  while (!IsNull (PendingList, PendingListLink)) {
-    Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
-
-    if (Target->HiiHandle == HiiHandle) {
-      return Target;
-    }
-
-    PendingListLink = GetNextNode (PendingList, PendingListLink);
-  }
-
-  return NULL;
-}
-
-/**
-  When HII database is updated. Keep updated HII handle into pending list so
-  we can process them later.
-
-  @param[in]  HiiHandle   HII handle instance.
-  @param[in]  PendingList Pending list to keep HII handle which is recently updated.
-
-  @retval EFI_SUCCESS             HII handle is saved in pending list.
-  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is NULL.
-  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetUpdate (
-  IN  EFI_HII_HANDLE   *HiiHandle,
-  IN  LIST_ENTRY       *PendingList
-  )
-{
-  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;
-
-  if (HiiHandle == NULL || PendingList == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Check and see if this HII handle is processed already.
-  //
-  TargetPendingList = GetPendingList (HiiHandle, PendingList);
-  if (TargetPendingList != NULL) {
-    TargetPendingList->IsDeleted = FALSE;
-  DEBUG_CODE (
-    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n", __FUNCTION__, HiiHandle));
-    );
-    return EFI_SUCCESS;
-  }
-
-  TargetPendingList= AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
-  if (TargetPendingList == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  TargetPendingList->HiiHandle = HiiHandle;
-  TargetPendingList->IsDeleted = FALSE;
-
-  InsertTailList (PendingList, &TargetPendingList->Link);
-
-  DEBUG_CODE (
-    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n", __FUNCTION__, HiiHandle));
-    );
-
-  return EFI_SUCCESS;
-}
-
-/**
-  When HII database is updated and form-set is deleted. Keep deleted HII handle into pending list so
-  we can process them later.
-
-  @param[in]  HiiHandle   HII handle instance.
-  @param[in]  PendingList Pending list to keep HII handle which is recently updated.
-
-  @retval EFI_SUCCESS             HII handle is saved in pending list.
-  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is NULL.
-  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetDeleted (
-  IN  EFI_HII_HANDLE   *HiiHandle,
-  IN  LIST_ENTRY       *PendingList
-  )
-{
-  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;
-
-  if (HiiHandle == NULL || PendingList == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  //
-  // Check and see if this HII handle is processed already.
-  //
-  TargetPendingList = GetPendingList (HiiHandle, PendingList);
-  if (TargetPendingList != NULL) {
-    TargetPendingList->IsDeleted = TRUE;
-    DEBUG_CODE (
-      DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n", __FUNCTION__, HiiHandle));
-      );
-    return EFI_SUCCESS;
-  }
-
-  TargetPendingList= AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
-  if (TargetPendingList == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  TargetPendingList->HiiHandle = HiiHandle;
-  TargetPendingList->IsDeleted = TRUE;
-
-  InsertTailList (PendingList, &TargetPendingList->Link);
-
-  DEBUG_CODE (
-    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n", __FUNCTION__, HiiHandle));
-    );
-
-  return EFI_SUCCESS;
-}
-
-/**
-  There are HII database update and we need to process them accordingly so that we
-  won't use stale data. This function will parse updated HII handle again in order
-  to get updated data-set.
-
-  @param[in]  FormsetList   List to keep HII form-set.
-  @param[in]  PendingList   List to keep HII handle that is updated.
-
-  @retval EFI_SUCCESS             HII handle is saved in pending list.
-  @retval EFI_INVALID_PARAMETER   FormsetList is NULL or PendingList is NULL.
-
-**/
-EFI_STATUS
-ProcessPendingList (
-  IN  LIST_ENTRY       *FormsetList,
-  IN  LIST_ENTRY       *PendingList
-  )
-{
-  LIST_ENTRY                 *PendingListLink;
-  LIST_ENTRY                 *PendingListNextLink;
-  REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;
-  EFI_STATUS                      Status;
-
-
-  if (FormsetList == NULL || PendingList == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (IsListEmpty (PendingList)) {
-    return EFI_SUCCESS;
-  }
-
-  PendingListLink = GetFirstNode (PendingList);
-  while (!IsNull (PendingList, PendingListLink)) {
-    PendingListNextLink = GetNextNode (PendingList, PendingListLink);
-    Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
-
-    if (Target->IsDeleted) {
-      //
-      // The HII resource on this HII handle is removed. Release the formset.
-      //
-      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
-      if (FormsetPrivate != NULL) {
-        DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver release HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid));
-        RemoveEntryList (&FormsetPrivate->Link);
-        ReleaseFormset (FormsetPrivate);
-        FreePool (FormsetPrivate);
-      } else {
-        DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was removed already\n", __FUNCTION__, Target->HiiHandle));
-      }
-    } else {
-      //
-      // The HII resource on this HII handle is updated/removed.
-      //
-      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
-      if (FormsetPrivate != NULL) {
-        //
-        // HII formset already exist, release it and query again.
-        //
-        DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current formset\n", __FUNCTION__, &FormsetPrivate->Guid));
-        RemoveEntryList (&FormsetPrivate->Link);
-        ReleaseFormset (FormsetPrivate);
-        FreePool (FormsetPrivate);
-      }
-
-      Status = LoadFormsetList (Target->HiiHandle, FormsetList);
-      if (EFI_ERROR (Status)) {
-        DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x failed: %r\n", __FUNCTION__, Target->HiiHandle, Status));
-      }
-    }
-
-    //
-    // Detach it from list first.
-    //
-    RemoveEntryList (&Target->Link);
-    FreePool (Target);
-
-    PendingListLink = PendingListNextLink;
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Release all resource in statement list.
-
-  @param[in]  StatementList   Statement list to be released.
-
-  @retval EFI_SUCCESS             All resource are released.
-  @retval EFI_INVALID_PARAMETER   StatementList is NULL.
-
-**/
-EFI_STATUS
-ReleaseStatementList (
-  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
-  )
-{
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
-  LIST_ENTRY  *NextLink;
-
-  if (StatementList == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  if (IsListEmpty (&StatementList->StatementList)) {
-    return EFI_SUCCESS;
-  }
-
-  NextLink = GetFirstNode (&StatementList->StatementList);
-  while (!IsNull (&StatementList->StatementList, NextLink)) {
-    StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
-    NextLink = GetNextNode (&StatementList->StatementList, NextLink);
-
-    RemoveEntryList (&StatementRef->Link);
-    FreePool (StatementRef);
-  }
-
-  return EFI_SUCCESS;
-}
+/** @file
+
+  The implementation of EDKII Redfidh Platform Config Protocol.
+
+  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "RedfishPlatformConfigDxe.h"
+#include "RedfishPlatformConfigImpl.h"
+
+extern REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate;
+
+/**
+  Debug dump HII string
+
+  @param[in]  HiiHandle   HII handle instance
+  @param[in]  StringId    HII string to dump
+
+  @retval EFI_SUCCESS       Dump HII string successfully
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+DumpHiiString (
+  IN EFI_HII_HANDLE HiiHandle,
+  IN EFI_STRING_ID  StringId
+  )
+{
+  EFI_STRING String;
+
+  if (HiiHandle == NULL || StringId == 0) {
+    DEBUG ((DEBUG_INFO, "???"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  String = HiiGetString (HiiHandle, StringId, NULL);
+  if (String == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  DEBUG ((DEBUG_INFO, "%s", String));
+  FreePool (String);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Debug dump HII form-set data
+
+  @param[in]  FormsetPrivate    HII form-set private instance.
+
+  @retval EFI_SUCCESS       Dump form-set successfully
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+DumpFormset (
+  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
+  )
+{
+  LIST_ENTRY                      *HiiFormLink;
+  LIST_ENTRY                      *HiiNextFormLink;
+  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
+  LIST_ENTRY                      *HiiStatementLink;
+  LIST_ENTRY                      *HiiNextStatementLink;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
+  UINTN                           Index;
+
+  if (FormsetPrivate == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Index = 0;
+  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
+  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
+    HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
+    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
+
+    DEBUG ((DEBUG_INFO, "  [%d] form: %d title: ", ++Index, HiiFormPrivate->Id));
+    DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
+    DEBUG ((DEBUG_INFO, "\n"));
+
+    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
+    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+      HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
+
+      DEBUG ((DEBUG_INFO, "    QID: 0x%x Prompt: ", HiiStatementPrivate->QuestionId));
+      DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate->Description);
+      DEBUG ((DEBUG_INFO, "\n"));
+
+      HiiStatementLink = HiiNextStatementLink;
+    }
+
+    HiiFormLink = HiiNextFormLink;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Debug dump HII form-set list
+
+  @param[in]  FormsetList   Form-set list instance
+
+  @retval EFI_SUCCESS       Dump list successfully
+  @retval Others            Errors occur
+
+**/
+EFI_STATUS
+DumpFormsetList (
+  IN  LIST_ENTRY      *FormsetList
+  )
+{
+  LIST_ENTRY                      *HiiFormsetLink;
+  LIST_ENTRY                      *HiiFormsetNextLink;
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
+  UINTN                           Index;
+
+  if (FormsetList == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (IsListEmpty (FormsetList)) {
+    DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
+    return EFI_SUCCESS;
+  }
+
+  Index = 0;
+  HiiFormsetLink = GetFirstNode (FormsetList);
+  while (!IsNull (FormsetList, HiiFormsetLink)) {
+    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+    DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n", ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid, HiiFormsetPrivate->DevicePathStr));
+    DumpFormset (HiiFormsetPrivate);
+
+    HiiFormsetLink = HiiFormsetNextLink;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Retrieves a unicode string from a string package in a given language. The
+  returned string is allocated using AllocatePool().  The caller is responsible
+  for freeing the allocated buffer using FreePool().
+
+  If HiiHandle is NULL, then ASSERT().
+  If StringId is 0, then ASSET.
+
+  @param[in]  HiiHandle         A handle that was previously registered in the HII Database.
+  @param[in]  Language          The specified configure language to get string.
+  @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
+HiiGetRedfishString (
+  IN EFI_HII_HANDLE           HiiHandle,
+  IN CHAR8                    *Language,
+  IN EFI_STRING_ID            StringId
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       StringSize;
+  CHAR16      TempString;
+  EFI_STRING  String;
+
+  if (mRedfishPlatformConfigPrivate->HiiString == NULL || HiiHandle == NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
+    ASSERT (FALSE);
+    return NULL;
+  }
+
+  //
+  // Retrieve the size of the string in the string package for the BestLanguage
+  //
+  StringSize = 0;
+  Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
+                                             mRedfishPlatformConfigPrivate->HiiString,
+                                             Language,
+                                             HiiHandle,
+                                             StringId,
+                                             &TempString,
+                                             &StringSize,
+                                             NULL
+                                             );
+  //
+  // If GetString() returns EFI_SUCCESS for a zero size,
+  // then there are no supported languages registered for HiiHandle.  If GetString()
+  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is not present
+  // in the HII Database
+  //
+  if (Status != EFI_BUFFER_TOO_SMALL) {
+    return NULL;
+  }
+
+  //
+  // Allocate a buffer for the return string
+  //
+  String = AllocateZeroPool (StringSize);
+  if (String == NULL) {
+    return NULL;
+  }
+
+  //
+  // Retrieve the string from the string package
+  //
+  Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
+                                             mRedfishPlatformConfigPrivate->HiiString,
+                                             Language,
+                                             HiiHandle,
+                                             StringId,
+                                             String,
+                                             &StringSize,
+                                             NULL
+                                             );
+  if (EFI_ERROR (Status)) {
+    //
+    // Free the buffer and return NULL if the supported languages can not be retrieved.
+    //
+    FreePool (String);
+    String = NULL;
+  }
+
+  //
+  // Return the Null-terminated Unicode string
+  //
+  return String;
+}
+
+/**
+  Retrieves a ASCII string from a string package in a given language. The
+  returned string is allocated using AllocatePool().  The caller is responsible
+  for freeing the allocated buffer using FreePool().
+
+  If HiiHandle is NULL, then ASSERT().
+  If StringId is 0, then ASSET.
+
+  @param[in]  HiiHandle         A handle that was previously registered in the HII Database.
+  @param[in]  Language          The specified configure language to get string.
+  @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.
+
+**/
+CHAR8 *
+HiiGetRedfishAsciiString (
+  IN EFI_HII_HANDLE           HiiHandle,
+  IN CHAR8                    *Language,
+  IN EFI_STRING_ID            StringId
+  )
+{
+  EFI_STRING  HiiString;
+  UINTN       StringSize;
+  CHAR8       *AsciiString;
+
+  HiiString = HiiGetRedfishString (HiiHandle, Language, StringId);
+  if (HiiString == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n", __FUNCTION__, StringId, Language));
+    return NULL;
+  }
+
+  StringSize = (StrLen (HiiString) + 1) * sizeof (CHAR8);
+  AsciiString = AllocatePool (StringSize);
+  if (AsciiString == NULL) {
+    return NULL;
+  }
+
+  UnicodeStrToAsciiStrS (HiiString, AsciiString, StringSize);
+
+  FreePool (HiiString);
+  return AsciiString;
+}
+
+/**
+  Get string from HII database in English language.
+
+  @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);
+}
+
+/**
+  Check and see if this is supported schema or not.
+
+  @param[in]  SupportedSchema   The list of supported schema.
+  @param[in]  Schema            Schema string to be checked.
+
+  @retval BOOLEAN               TRUE if this is supported schema. FALSE otherwise.
+
+**/
+BOOLEAN
+CheckSupportedSchema (
+  IN REDFISH_PLATFORM_CONFIG_SCHEMA   *SupportedSchema,
+  IN CHAR8                            *Schema
+  )
+{
+  UINTN Index;
+
+  if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
+    return FALSE;
+  }
+
+  if (SupportedSchema->Count == 0) {
+    return FALSE;
+  }
+
+  for (Index = 0; Index < SupportedSchema->Count; Index++) {
+    if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Get the list of supported schema from the given HII handle.
+
+  @param[in]  HiiHandle         HII handle instance.
+  @param[out] SupportedSchema   Supported schema on this HII handle.
+
+  @retval EFI_SUCCESS           Schema list is returned.
+  @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema is NULL.
+  @retval EFI_NOT_FOUND         No supported schema found.
+  @retval EFI_OUT_OF_RESOURCES  System is out of memory.
+
+**/
+EFI_STATUS
+GetSupportedSchema (
+  IN  EFI_HII_HANDLE                  HiiHandle,
+  OUT REDFISH_PLATFORM_CONFIG_SCHEMA  *SupportedSchema
+  )
+{
+  CHAR8 *SupportedLanguages;
+  UINTN Index;
+  UINTN LangIndex;
+  UINTN Count;
+  UINTN StrSize;
+  UINTN ListIndex;
+
+  if (HiiHandle == NULL || SupportedSchema == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  SupportedSchema->Count = 0;
+
+  SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
+  if (SupportedLanguages == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  Index = 0;
+  LangIndex = 0;
+  Count = 0;
+  while (TRUE) {
+    if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
+      if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
+        ++Count;
+      }
+      LangIndex = Index + 1;
+    }
+
+    if (SupportedLanguages[Index] == '\0') {
+      break;
+    }
+
+    ++Index;
+  }
+
+  if (Count == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  SupportedSchema->Count = Count;
+  SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
+  if (SupportedSchema->SchemaList == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Index = 0;
+  LangIndex = 0;
+  ListIndex = 0;
+  while (TRUE) {
+
+    if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] == '\0') {
+      if (AsciiStrnCmp (&SupportedLanguages[LangIndex], X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
+        StrSize = Index - LangIndex;
+        SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize + 1), &SupportedLanguages[LangIndex]);
+        SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
+        ++ListIndex;
+      }
+
+      LangIndex = Index + 1;
+    }
+
+    if (SupportedLanguages[Index] == '\0') {
+      break;
+    }
+
+    ++Index;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Search and find statement private instance by given regular expression patthern
+  which describes the Configure Language.
+
+  @param[in]  RegularExpressionProtocol   Regular express protocol.
+  @param[in]  FormsetList                 Form-set list to search.
+  @param[in]  Schema                      Schema to be matched.
+  @param[in]  Pattern                     Regular expression pattern.
+  @param[out] StatementList               Statement list that match above pattern.
+
+  @retval EFI_SUCCESS             Statement list is returned.
+  @retval EFI_INVALID_PARAMETER   Input parameter is NULL.
+  @retval EFI_NOT_READY           Regular express protocol is NULL.
+  @retval EFI_NOT_FOUND           No statement is found.
+  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
+
+**/
+EFI_STATUS
+GetStatementPrivateByConfigureLangRegex (
+  IN  EFI_REGULAR_EXPRESSION_PROTOCOL                 *RegularExpressionProtocol,
+  IN  LIST_ENTRY                                      *FormsetList,
+  IN  CHAR8                                           *Schema,
+  IN  EFI_STRING                                      Pattern,
+  OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
+  )
+{
+  LIST_ENTRY                      *HiiFormsetLink;
+  LIST_ENTRY                      *HiiFormsetNextLink;
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
+  LIST_ENTRY                      *HiiFormLink;
+  LIST_ENTRY                      *HiiNextFormLink;
+  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
+  LIST_ENTRY                      *HiiStatementLink;
+  LIST_ENTRY                      *HiiNextStatementLink;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
+  EFI_STRING                      TmpString;
+  UINTN                           CaptureCount;
+  BOOLEAN                         IsMatch;
+  EFI_STATUS                      Status;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
+
+  if (FormsetList == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (RegularExpressionProtocol == NULL) {
+    return EFI_NOT_READY;
+  }
+
+  StatementList->Count = 0;
+  InitializeListHead (&StatementList->StatementList);
+
+  if (IsListEmpty (FormsetList)) {
+    return EFI_NOT_FOUND;
+  }
+
+  HiiFormsetLink = GetFirstNode (FormsetList);
+  while (!IsNull (FormsetList, HiiFormsetLink)) {
+    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+    //
+    // Performance check.
+    // If there is no desired Redfish schema found, skip this formset.
+    //
+    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
+      HiiFormsetLink = HiiFormsetNextLink;
+      continue;
+    }
+
+    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
+    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
+      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
+      HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
+
+      HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
+      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+        HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
+        HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+
+        if (HiiStatementPrivate->Description != 0) {
+          TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
+          if (TmpString != NULL) {
+            Status = RegularExpressionProtocol->MatchString (
+                                                  RegularExpressionProtocol,
+                                                  TmpString,
+                                                  Pattern,
+                                                  &gEfiRegexSyntaxTypePerlGuid,
+                                                  &IsMatch,
+                                                  NULL,
+                                                  &CaptureCount
+                                                  );
+            if (EFI_ERROR (Status)) {
+              DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n", __FUNCTION__, Pattern, Status));
+              ASSERT (FALSE);
+              return Status;
+            }
+
+            //
+            // Found
+            //
+            if (IsMatch) {
+              StatementRef = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
+              if (StatementRef == NULL) {
+                return EFI_OUT_OF_RESOURCES;
+              }
+
+              StatementRef->Statement = HiiStatementPrivate;
+              InsertTailList (&StatementList->StatementList, &StatementRef->Link);
+              ++StatementList->Count;
+            }
+
+            FreePool (TmpString);
+          }
+        }
+
+        HiiStatementLink = HiiNextStatementLink;
+      }
+
+      HiiFormLink = HiiNextFormLink;
+    }
+
+    HiiFormsetLink = HiiFormsetNextLink;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get statement private instance by the given configure language.
+
+  @param[in]  FormsetList                 Form-set list to search.
+  @param[in]  Schema                      Schema to be matched.
+  @param[in]  ConfigureLang               Configure language.
+
+  @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *   Pointer to statement private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
+GetStatementPrivateByConfigureLang (
+  IN  LIST_ENTRY    *FormsetList,
+  IN  CHAR8         *Schema,
+  IN  EFI_STRING    ConfigureLang
+  )
+{
+  LIST_ENTRY                      *HiiFormsetLink;
+  LIST_ENTRY                      *HiiFormsetNextLink;
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
+  LIST_ENTRY                      *HiiFormLink;
+  LIST_ENTRY                      *HiiNextFormLink;
+  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
+  LIST_ENTRY                      *HiiStatementLink;
+  LIST_ENTRY                      *HiiNextStatementLink;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
+  EFI_STRING                      TmpString;
+
+  if (FormsetList == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (ConfigureLang)) {
+    return NULL;
+  }
+
+  if (IsListEmpty (FormsetList)) {
+    return NULL;
+  }
+
+  HiiFormsetLink = GetFirstNode (FormsetList);
+  while (!IsNull (FormsetList, HiiFormsetLink)) {
+    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+    //
+    // Performance check.
+    // If there is no desired Redfish schema found, skip this formset.
+    //
+    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema, Schema)) {
+      HiiFormsetLink = HiiFormsetNextLink;
+      continue;
+    }
+
+    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
+    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
+      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList, HiiFormLink);
+      HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
+
+      HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
+      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+        HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
+        HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+
+        DEBUG_CODE (
+          STATIC UINTN Index = 0;
+          DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x formset: %g\n", __FUNCTION__, ++Index, ConfigureLang, HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate->Guid));
+        );
+
+        if (HiiStatementPrivate->Description != 0) {
+          TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle, Schema, HiiStatementPrivate->Description);
+          if (TmpString != NULL) {
+            if (StrCmp (TmpString, ConfigureLang) == 0) {
+              FreePool (TmpString);
+              return HiiStatementPrivate;
+            }
+
+            FreePool (TmpString);
+          }
+        }
+
+        HiiStatementLink = HiiNextStatementLink;
+      }
+
+      HiiFormLink = HiiNextFormLink;
+    }
+
+    HiiFormsetLink = HiiFormsetNextLink;
+  }
+
+  return NULL;
+}
+
+/**
+  Get form-set private instance by the given HII handle.
+
+  @param[in]  HiiHandle       HII handle instance.
+  @param[in]  FormsetList     Form-set list to search.
+
+  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to form-set private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
+GetFormsetPrivateByHiiHandle (
+  IN  EFI_HII_HANDLE  HiiHandle,
+  IN  LIST_ENTRY      *FormsetList
+  )
+{
+  LIST_ENTRY                      *HiiFormsetLink;
+  LIST_ENTRY                      *HiiFormsetNextLink;
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
+
+  if (HiiHandle == NULL || FormsetList == NULL) {
+    return NULL;
+  }
+
+  if (IsListEmpty (FormsetList)) {
+    return NULL;
+  }
+
+  HiiFormsetLink = GetFirstNode (FormsetList);
+  while (!IsNull (FormsetList, HiiFormsetLink)) {
+    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+    if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
+      return HiiFormsetPrivate;
+    }
+
+    HiiFormsetLink = HiiFormsetNextLink;
+  }
+
+  return NULL;
+}
+
+/**
+  Release formset and all the forms and statements that belong to this formset.
+
+  @param[in]      FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
+
+  @retval         EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseFormset (
+  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
+  )
+{
+  LIST_ENTRY                      *HiiFormLink;
+  LIST_ENTRY                      *HiiNextFormLink;
+  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
+  LIST_ENTRY                      *HiiStatementLink;
+  LIST_ENTRY                      *HiiNextStatementLink;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
+  UINTN                           Index;
+
+  if (FormsetPrivate == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
+  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
+    HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK (HiiFormLink);
+    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList, HiiFormLink);
+
+    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
+    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
+      HiiStatementPrivate = REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
+      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList, HiiStatementLink);
+
+      //
+      // HiiStatementPrivate->HiiStatement will be released in DestroyFormSet().
+      //
+
+      if (HiiStatementPrivate->DesStringCache != NULL) {
+        FreePool (HiiStatementPrivate->DesStringCache);
+        HiiStatementPrivate->DesStringCache = NULL;
+      }
+
+      RemoveEntryList (&HiiStatementPrivate->Link);
+      FreePool (HiiStatementPrivate);
+      HiiStatementLink = HiiNextStatementLink;
+    }
+
+    //
+    // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
+    //
+
+    RemoveEntryList (&HiiFormPrivate->Link);
+    FreePool (HiiFormPrivate);
+    HiiFormLink = HiiNextFormLink;
+  }
+
+  if (FormsetPrivate->HiiFormSet != NULL) {
+    DestroyFormSet (FormsetPrivate->HiiFormSet);
+    FormsetPrivate->HiiFormSet = NULL;
+  }
+
+  if (FormsetPrivate->DevicePathStr != NULL) {
+    FreePool(FormsetPrivate->DevicePathStr);
+  }
+
+  //
+  // Release schema list
+  //
+  if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
+    for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count; Index++) {
+      FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
+    }
+
+    FreePool (FormsetPrivate->SupportedSchema.SchemaList);
+    FormsetPrivate->SupportedSchema.SchemaList = NULL;
+    FormsetPrivate->SupportedSchema.Count = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Create new form-set instance.
+
+  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to newly created form-set private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *
+NewFormsetPrivate (
+  VOID
+  )
+{
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
+
+  NewFormsetPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
+  if (NewFormsetPrivate == NULL) {
+    return NULL;
+  }
+
+  //
+  // Initial newly created formset private data.
+  //
+  InitializeListHead (&NewFormsetPrivate->HiiFormList);
+
+  return NewFormsetPrivate;
+}
+
+/**
+  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
+
+**/
+EFI_STATUS
+LoadFormset (
+  IN  EFI_HII_HANDLE                  HiiHandle,
+  OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
+  )
+{
+  EFI_STATUS                      Status;
+  HII_FORMSET                     *HiiFormSet;
+  HII_FORM                        *HiiForm;
+  LIST_ENTRY                      *HiiFormLink;
+  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
+  HII_STATEMENT                   *HiiStatement;
+  LIST_ENTRY                      *HiiStatementLink;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate;
+  EFI_GUID                        ZeroGuid;
+
+  if (HiiHandle == NULL || FormsetPrivate == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+
+  HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
+  if (HiiFormSet == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Find HII formset by the given HII handle.
+  //
+  ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
+  Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
+  if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
+    Status = EFI_NOT_FOUND;
+    goto ErrorExit;
+  }
+
+  //
+  // Initialize formset
+  //
+  InitializeFormSet (HiiFormSet);
+
+  //
+  // Initialize formset private data.
+  //
+  FormsetPrivate->HiiFormSet = HiiFormSet;
+  FormsetPrivate->HiiHandle = HiiHandle;
+  CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
+  FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet->DevicePath, FALSE, FALSE);
+  Status = GetSupportedSchema (FormsetPrivate->HiiHandle, &FormsetPrivate->SupportedSchema);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found: %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
+  }
+
+  HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
+  while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
+    HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
+
+    HiiFormPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
+    if (HiiFormPrivate == NULL) {
+      Status = EFI_OUT_OF_RESOURCES;
+      goto ErrorExit;
+    }
+
+    //
+    // Initialize form private data.
+    //
+    HiiFormPrivate->HiiForm = HiiForm;
+    HiiFormPrivate->Id = HiiForm->FormId;
+    HiiFormPrivate->Title = HiiForm->FormTitle;
+    HiiFormPrivate->ParentFormset = FormsetPrivate;
+    InitializeListHead (&HiiFormPrivate->StatementList);
+
+    HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
+    while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
+      HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
+
+      HiiStatementPrivate = AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
+      if (HiiStatementPrivate == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto ErrorExit;
+      }
+      //
+      // Initialize statement private data.
+      //
+      HiiStatementPrivate->HiiStatement = HiiStatement;
+      HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
+      HiiStatementPrivate->Description = HiiStatement->Prompt;
+      HiiStatementPrivate->ParentForm = HiiFormPrivate;
+
+      //
+      // Attach to statement list.
+      //
+      InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate->Link);
+      HiiStatementLink = GetNextNode (&HiiForm->StatementListHead, HiiStatementLink);
+    }
+    //
+    // Attach to form list.
+    //
+    InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
+    HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
+  }
+
+  return EFI_SUCCESS;
+
+ErrorExit:
+
+  //
+  // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
+  //
+  if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != HiiFormSet) {
+    DestroyFormSet (HiiFormSet);
+  }
+
+  //
+  // Release resource when error happens.
+  //
+  ReleaseFormset (FormsetPrivate);
+
+  return Status;
+}
+
+/**
+  Release formset list and all the forms that belong to this formset.
+
+  @param[in]      FormsetList   Pointer to formst list that needs to be
+                                released.
+
+  @retval         EFI_STATUS
+
+**/
+EFI_STATUS
+LoadFormsetList (
+  IN   EFI_HII_HANDLE   *HiiHandle,
+  OUT  LIST_ENTRY       *FormsetList
+  )
+{
+  EFI_STATUS  Status;
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;
+
+  if (HiiHandle == NULL || FormsetList == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
+  if (FormsetPrivate != NULL) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  FormsetPrivate =  NewFormsetPrivate ();
+  if (FormsetPrivate == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Load formset on the given HII handle.
+  //
+  Status = LoadFormset (HiiHandle, FormsetPrivate);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n", __FUNCTION__, Status));
+    FreePool (FormsetPrivate);
+    return Status;
+  }
+
+  //
+  // Attach to cache list.
+  //
+  InsertTailList (FormsetList, &FormsetPrivate->Link);
+
+  DEBUG_CODE (
+    DumpFormsetList (FormsetList);
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Release formset list and all the forms that belong to this formset.
+
+  @param[in]      FormsetList   Pointer to formst list that needs to be
+                                released.
+
+  @retval         EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseFormsetList (
+  IN  LIST_ENTRY      *FormsetList
+  )
+{
+  LIST_ENTRY                      *HiiFormsetLink;
+  LIST_ENTRY                      *HiiFormsetNextLink;
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
+
+  if (FormsetList == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (IsListEmpty (FormsetList)) {
+    return EFI_SUCCESS;
+  }
+
+  HiiFormsetLink = GetFirstNode (FormsetList);
+  while (!IsNull (FormsetList, HiiFormsetLink)) {
+    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
+    HiiFormsetPrivate = REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
+
+    //
+    // Detach from list.
+    //
+    RemoveEntryList (&HiiFormsetPrivate->Link);
+    ReleaseFormset (HiiFormsetPrivate);
+    FreePool (HiiFormsetPrivate);
+    HiiFormsetLink = HiiFormsetNextLink;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get all pending list.
+
+  @param[in]  HiiHandle   HII handle instance.
+  @param[in]  PendingList Pending list to keep pending data.
+
+  @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST *   Pointer to pending list data.
+
+**/
+REDFISH_PLATFORM_CONFIG_PENDING_LIST *
+GetPendingList (
+  IN  EFI_HII_HANDLE   *HiiHandle,
+  IN  LIST_ENTRY       *PendingList
+  )
+{
+  LIST_ENTRY                 *PendingListLink;
+  REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
+
+  if (HiiHandle == NULL || PendingList == NULL) {
+    return NULL;
+  }
+
+  if (IsListEmpty (PendingList)) {
+    return NULL;
+  }
+
+  PendingListLink = GetFirstNode (PendingList);
+  while (!IsNull (PendingList, PendingListLink)) {
+    Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
+
+    if (Target->HiiHandle == HiiHandle) {
+      return Target;
+    }
+
+    PendingListLink = GetNextNode (PendingList, PendingListLink);
+  }
+
+  return NULL;
+}
+
+/**
+  When HII database is updated. Keep updated HII handle into pending list so
+  we can process them later.
+
+  @param[in]  HiiHandle   HII handle instance.
+  @param[in]  PendingList Pending list to keep HII handle which is recently updated.
+
+  @retval EFI_SUCCESS             HII handle is saved in pending list.
+  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is NULL.
+  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetUpdate (
+  IN  EFI_HII_HANDLE   *HiiHandle,
+  IN  LIST_ENTRY       *PendingList
+  )
+{
+  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;
+
+  if (HiiHandle == NULL || PendingList == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check and see if this HII handle is processed already.
+  //
+  TargetPendingList = GetPendingList (HiiHandle, PendingList);
+  if (TargetPendingList != NULL) {
+    TargetPendingList->IsDeleted = FALSE;
+  DEBUG_CODE (
+    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n", __FUNCTION__, HiiHandle));
+    );
+    return EFI_SUCCESS;
+  }
+
+  TargetPendingList= AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
+  if (TargetPendingList == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  TargetPendingList->HiiHandle = HiiHandle;
+  TargetPendingList->IsDeleted = FALSE;
+
+  InsertTailList (PendingList, &TargetPendingList->Link);
+
+  DEBUG_CODE (
+    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n", __FUNCTION__, HiiHandle));
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  When HII database is updated and form-set is deleted. Keep deleted HII handle into pending list so
+  we can process them later.
+
+  @param[in]  HiiHandle   HII handle instance.
+  @param[in]  PendingList Pending list to keep HII handle which is recently updated.
+
+  @retval EFI_SUCCESS             HII handle is saved in pending list.
+  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is NULL.
+  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetDeleted (
+  IN  EFI_HII_HANDLE   *HiiHandle,
+  IN  LIST_ENTRY       *PendingList
+  )
+{
+  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;
+
+  if (HiiHandle == NULL || PendingList == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check and see if this HII handle is processed already.
+  //
+  TargetPendingList = GetPendingList (HiiHandle, PendingList);
+  if (TargetPendingList != NULL) {
+    TargetPendingList->IsDeleted = TRUE;
+    DEBUG_CODE (
+      DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n", __FUNCTION__, HiiHandle));
+      );
+    return EFI_SUCCESS;
+  }
+
+  TargetPendingList= AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
+  if (TargetPendingList == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  TargetPendingList->HiiHandle = HiiHandle;
+  TargetPendingList->IsDeleted = TRUE;
+
+  InsertTailList (PendingList, &TargetPendingList->Link);
+
+  DEBUG_CODE (
+    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n", __FUNCTION__, HiiHandle));
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  There are HII database update and we need to process them accordingly so that we
+  won't use stale data. This function will parse updated HII handle again in order
+  to get updated data-set.
+
+  @param[in]  FormsetList   List to keep HII form-set.
+  @param[in]  PendingList   List to keep HII handle that is updated.
+
+  @retval EFI_SUCCESS             HII handle is saved in pending list.
+  @retval EFI_INVALID_PARAMETER   FormsetList is NULL or PendingList is NULL.
+
+**/
+EFI_STATUS
+ProcessPendingList (
+  IN  LIST_ENTRY       *FormsetList,
+  IN  LIST_ENTRY       *PendingList
+  )
+{
+  LIST_ENTRY                 *PendingListLink;
+  LIST_ENTRY                 *PendingListNextLink;
+  REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;
+  EFI_STATUS                      Status;
+
+
+  if (FormsetList == NULL || PendingList == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (IsListEmpty (PendingList)) {
+    return EFI_SUCCESS;
+  }
+
+  PendingListLink = GetFirstNode (PendingList);
+  while (!IsNull (PendingList, PendingListLink)) {
+    PendingListNextLink = GetNextNode (PendingList, PendingListLink);
+    Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK (PendingListLink);
+
+    if (Target->IsDeleted) {
+      //
+      // The HII resource on this HII handle is removed. Release the formset.
+      //
+      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
+      if (FormsetPrivate != NULL) {
+        DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver release HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid));
+        RemoveEntryList (&FormsetPrivate->Link);
+        ReleaseFormset (FormsetPrivate);
+        FreePool (FormsetPrivate);
+      } else {
+        DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was removed already\n", __FUNCTION__, Target->HiiHandle));
+      }
+    } else {
+      //
+      // The HII resource on this HII handle is updated/removed.
+      //
+      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle, FormsetList);
+      if (FormsetPrivate != NULL) {
+        //
+        // HII formset already exist, release it and query again.
+        //
+        DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current formset\n", __FUNCTION__, &FormsetPrivate->Guid));
+        RemoveEntryList (&FormsetPrivate->Link);
+        ReleaseFormset (FormsetPrivate);
+        FreePool (FormsetPrivate);
+      }
+
+      Status = LoadFormsetList (Target->HiiHandle, FormsetList);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x failed: %r\n", __FUNCTION__, Target->HiiHandle, Status));
+      }
+    }
+
+    //
+    // Detach it from list first.
+    //
+    RemoveEntryList (&Target->Link);
+    FreePool (Target);
+
+    PendingListLink = PendingListNextLink;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Release all resource in statement list.
+
+  @param[in]  StatementList   Statement list to be released.
+
+  @retval EFI_SUCCESS             All resource are released.
+  @retval EFI_INVALID_PARAMETER   StatementList is NULL.
+
+**/
+EFI_STATUS
+ReleaseStatementList (
+  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
+  )
+{
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
+  LIST_ENTRY  *NextLink;
+
+  if (StatementList == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (IsListEmpty (&StatementList->StatementList)) {
+    return EFI_SUCCESS;
+  }
+
+  NextLink = GetFirstNode (&StatementList->StatementList);
+  while (!IsNull (&StatementList->StatementList, NextLink)) {
+    StatementRef = REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
+    NextLink = GetNextNode (&StatementList->StatementList, NextLink);
+
+    RemoveEntryList (&StatementRef->Link);
+    FreePool (StatementRef);
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
index e0ba0fb2d3..cd7a52aef3 100644
--- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
+++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
@@ -1,274 +1,297 @@
-/** @file
-  This file defines the EDKII Redfish Platform Config Protocol interface.
-
-  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
-
-  SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
-#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
-
-#include <Uefi.h>
-
-//
-// Libraries
-//
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/HiiUtilityLib.h>
-#include <Library/HiiLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-
-#define REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET   0x00
-#define IS_EMPTY_STRING(a)                               (a == NULL || a[0] == L'\0')
-#define ENGLISH_LANGUAGE_CODE                            "en-US"
-#define X_UEFI_SCHEMA_PREFIX                             "x-uefi-redfish-"
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
-//
-typedef struct {
-  LIST_ENTRY                    Link;
-  EFI_HII_HANDLE                HiiHandle;
-  BOOLEAN                       IsDeleted;
-} REDFISH_PLATFORM_CONFIG_PENDING_LIST;
-
-#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_PENDING_LIST, Link)
-
-typedef struct {
-  UINTN   Count;                                // Number of schema in list
-  CHAR8   **SchemaList;                         // Schema list
-} REDFISH_PLATFORM_CONFIG_SCHEMA;
-
-//
-// 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.
-} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE
-//
-typedef struct {
-  LIST_ENTRY                                Link;
-  UINT16                                    Id;             // Form ID.
-  EFI_STRING_ID                             Title;          // String token of form title.
-  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *ParentFormset;
-  HII_FORM                                  *HiiForm;       // Pointer to HII form data.
-  LIST_ENTRY                                StatementList;  // Statement list that keep statement under this form.
-} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_FORM_PRIVATE, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
-//
-typedef struct {
-  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                            DesStringCache; // The string cache for search function.
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
-
-#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
-//
-typedef struct {
-  LIST_ENTRY                                Link;
-  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement;
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF;
-
-#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
-
-//
-// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
-//
-typedef struct {
-  LIST_ENTRY  StatementList;        // List of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
-  UINTN       Count;
-} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST;
-
-/**
-  Release formset list and all the forms that belong to this formset.
-
-  @param[in]      FormsetList   Pointer to formst list that needs to be
-                                released.
-
-  @retval         EFI_STATUS
-
-**/
-EFI_STATUS
-ReleaseFormsetList (
-  IN  LIST_ENTRY      *FormsetList
-  );
-
-/**
-  Release formset list and all the forms that belong to this formset.
-
-  @param[in]      FormsetList   Pointer to formst list that needs to be
-                                released.
-
-  @retval         EFI_STATUS
-
-**/
-EFI_STATUS
-LoadFormsetList (
-  IN   EFI_HII_HANDLE   *HiiHandle,
-  OUT  LIST_ENTRY       *FormsetList
-  );
-
-/**
-  When HII database is updated. Keep updated HII handle into pending list so
-  we can process them later.
-
-  @param[in]  HiiHandle   HII handle instance.
-  @param[in]  PendingList Pending list to keep HII handle which is recently updated.
-
-  @retval EFI_SUCCESS             HII handle is saved in pending list.
-  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is NULL.
-  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetUpdate (
-  IN  EFI_HII_HANDLE   *HiiHandle,
-  IN  LIST_ENTRY       *PendingList
-  );
-
-/**
-  When HII database is updated and form-set is deleted. Keep deleted HII handle into pending list so
-  we can process them later.
-
-  @param[in]  HiiHandle   HII handle instance.
-  @param[in]  PendingList Pending list to keep HII handle which is recently updated.
-
-  @retval EFI_SUCCESS             HII handle is saved in pending list.
-  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is NULL.
-  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
-
-**/
-EFI_STATUS
-NotifyFormsetDeleted (
-  IN  EFI_HII_HANDLE   *HiiHandle,
-  IN  LIST_ENTRY       *PendingList
-  );
-
-/**
-  Get statement private instance by the given configure language.
-
-  @param[in]  FormsetList                 Form-set list to search.
-  @param[in]  Schema                      Schema to be matched.
-  @param[in]  ConfigureLang               Configure language.
-
-  @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *   Pointer to statement private instance.
-
-**/
-REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
-GetStatementPrivateByConfigureLang (
-  IN  LIST_ENTRY    *FormsetList,
-  IN  CHAR8         *Schema,
-  IN  EFI_STRING    ConfigureLang
-  );
-
-/**
-  Search and find statement private instance by given regular expression patthern
-  which describes the Configure Language.
-
-  @param[in]  RegularExpressionProtocol   Regular express protocol.
-  @param[in]  FormsetList                 Form-set list to search.
-  @param[in]  Schema                      Schema to be matched.
-  @param[in]  Pattern                     Regular expression pattern.
-  @param[out] StatementList               Statement list that match above pattern.
-
-  @retval EFI_SUCCESS             Statement list is returned.
-  @retval EFI_INVALID_PARAMETER   Input parameter is NULL.
-  @retval EFI_NOT_READY           Regular express protocol is NULL.
-  @retval EFI_NOT_FOUND           No statement is found.
-  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
-
-**/
-EFI_STATUS
-GetStatementPrivateByConfigureLangRegex (
-  IN  EFI_REGULAR_EXPRESSION_PROTOCOL                 *RegularExpressionProtocol,
-  IN  LIST_ENTRY                                      *FormsetList,
-  IN  CHAR8                                           *Schema,
-  IN  EFI_STRING                                      Pattern,
-  OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
-  );
-
-/**
-  There are HII database update and we need to process them accordingly so that we
-  won't use stale data. This function will parse updated HII handle again in order
-  to get updated data-set.
-
-  @param[in]  FormsetList   List to keep HII form-set.
-  @param[in]  PendingList   List to keep HII handle that is updated.
-
-  @retval EFI_SUCCESS             HII handle is saved in pending list.
-  @retval EFI_INVALID_PARAMETER   FormsetList is NULL or PendingList is NULL.
-
-**/
-EFI_STATUS
-ProcessPendingList (
-  IN  LIST_ENTRY       *FormsetList,
-  IN  LIST_ENTRY       *PendingList
-  );
-
-/**
-  Retrieves a string from a string package in a English language. The
-  returned string is allocated using AllocatePool().  The caller is responsible
-  for freeing the allocated buffer using FreePool().
-
-  If HiiHandle is NULL, then ASSERT().
-  If StringId is 0, then ASSET.
-
-  @param[in]  HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
-  @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
-HiiGetRedfishString (
-  IN EFI_HII_HANDLE           HiiHandle,
-  IN CHAR8                    *Language,
-  IN EFI_STRING_ID            StringId
-  );
-
-/**
-  Release all resource in statement list.
-
-  @param[in]  StatementList   Statement list to be released.
-
-  @retval EFI_SUCCESS             All resource are released.
-  @retval EFI_INVALID_PARAMETER   StatementList is NULL.
-
-**/
-EFI_STATUS
-ReleaseStatementList (
-  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
-  );
-
-#endif
+/** @file
+  This file defines the EDKII Redfish Platform Config Protocol interface.
+
+  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
+#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
+
+#include <Uefi.h>
+
+//
+// Libraries
+//
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiUtilityLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+#define IS_EMPTY_STRING(a)                               (a == NULL || a[0] == L'\0')
+#define ENGLISH_LANGUAGE_CODE                            "en-US"
+#define X_UEFI_SCHEMA_PREFIX                             "x-uefi-redfish-"
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
+//
+typedef struct {
+  LIST_ENTRY                    Link;
+  EFI_HII_HANDLE                HiiHandle;
+  BOOLEAN                       IsDeleted;
+} REDFISH_PLATFORM_CONFIG_PENDING_LIST;
+
+#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_PENDING_LIST, Link)
+
+typedef struct {
+  UINTN   Count;                                // Number of schema in list
+  CHAR8   **SchemaList;                         // Schema list
+} REDFISH_PLATFORM_CONFIG_SCHEMA;
+
+//
+// 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.
+} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE
+//
+typedef struct {
+  LIST_ENTRY                                Link;
+  UINT16                                    Id;             // Form ID.
+  EFI_STRING_ID                             Title;          // String token of form title.
+  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *ParentFormset;
+  HII_FORM                                  *HiiForm;       // Pointer to HII form data.
+  LIST_ENTRY                                StatementList;  // Statement list that keep statement under this form.
+} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_FORM_PRIVATE, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
+//
+typedef struct {
+  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                            DesStringCache; // The string cache for search function.
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
+
+#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
+//
+typedef struct {
+  LIST_ENTRY                                Link;
+  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement;
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF;
+
+#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a)  BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
+
+//
+// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
+//
+typedef struct {
+  LIST_ENTRY  StatementList;        // List of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
+  UINTN       Count;
+} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST;
+
+/**
+  Release formset list and all the forms that belong to this formset.
+
+  @param[in]      FormsetList   Pointer to formst list that needs to be
+                                released.
+
+  @retval         EFI_STATUS
+
+**/
+EFI_STATUS
+ReleaseFormsetList (
+  IN  LIST_ENTRY      *FormsetList
+  );
+
+/**
+  Release formset list and all the forms that belong to this formset.
+
+  @param[in]      FormsetList   Pointer to formst list that needs to be
+                                released.
+
+  @retval         EFI_STATUS
+
+**/
+EFI_STATUS
+LoadFormsetList (
+  IN   EFI_HII_HANDLE   *HiiHandle,
+  OUT  LIST_ENTRY       *FormsetList
+  );
+
+/**
+  When HII database is updated. Keep updated HII handle into pending list so
+  we can process them later.
+
+  @param[in]  HiiHandle   HII handle instance.
+  @param[in]  PendingList Pending list to keep HII handle which is recently updated.
+
+  @retval EFI_SUCCESS             HII handle is saved in pending list.
+  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is NULL.
+  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetUpdate (
+  IN  EFI_HII_HANDLE   *HiiHandle,
+  IN  LIST_ENTRY       *PendingList
+  );
+
+/**
+  When HII database is updated and form-set is deleted. Keep deleted HII handle into pending list so
+  we can process them later.
+
+  @param[in]  HiiHandle   HII handle instance.
+  @param[in]  PendingList Pending list to keep HII handle which is recently updated.
+
+  @retval EFI_SUCCESS             HII handle is saved in pending list.
+  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is NULL.
+  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
+
+**/
+EFI_STATUS
+NotifyFormsetDeleted (
+  IN  EFI_HII_HANDLE   *HiiHandle,
+  IN  LIST_ENTRY       *PendingList
+  );
+
+/**
+  Get statement private instance by the given configure language.
+
+  @param[in]  FormsetList                 Form-set list to search.
+  @param[in]  Schema                      Schema to be matched.
+  @param[in]  ConfigureLang               Configure language.
+
+  @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *   Pointer to statement private instance.
+
+**/
+REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
+GetStatementPrivateByConfigureLang (
+  IN  LIST_ENTRY    *FormsetList,
+  IN  CHAR8         *Schema,
+  IN  EFI_STRING    ConfigureLang
+  );
+
+/**
+  Search and find statement private instance by given regular expression patthern
+  which describes the Configure Language.
+
+  @param[in]  RegularExpressionProtocol   Regular express protocol.
+  @param[in]  FormsetList                 Form-set list to search.
+  @param[in]  Schema                      Schema to be matched.
+  @param[in]  Pattern                     Regular expression pattern.
+  @param[out] StatementList               Statement list that match above pattern.
+
+  @retval EFI_SUCCESS             Statement list is returned.
+  @retval EFI_INVALID_PARAMETER   Input parameter is NULL.
+  @retval EFI_NOT_READY           Regular express protocol is NULL.
+  @retval EFI_NOT_FOUND           No statement is found.
+  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
+
+**/
+EFI_STATUS
+GetStatementPrivateByConfigureLangRegex (
+  IN  EFI_REGULAR_EXPRESSION_PROTOCOL                 *RegularExpressionProtocol,
+  IN  LIST_ENTRY                                      *FormsetList,
+  IN  CHAR8                                           *Schema,
+  IN  EFI_STRING                                      Pattern,
+  OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
+  );
+
+/**
+  There are HII database update and we need to process them accordingly so that we
+  won't use stale data. This function will parse updated HII handle again in order
+  to get updated data-set.
+
+  @param[in]  FormsetList   List to keep HII form-set.
+  @param[in]  PendingList   List to keep HII handle that is updated.
+
+  @retval EFI_SUCCESS             HII handle is saved in pending list.
+  @retval EFI_INVALID_PARAMETER   FormsetList is NULL or PendingList is NULL.
+
+**/
+EFI_STATUS
+ProcessPendingList (
+  IN  LIST_ENTRY       *FormsetList,
+  IN  LIST_ENTRY       *PendingList
+  );
+
+/**
+  Retrieves a unicode string from a string package in a given language. The
+  returned string is allocated using AllocatePool().  The caller is responsible
+  for freeing the allocated buffer using FreePool().
+
+  If HiiHandle is NULL, then ASSERT().
+  If StringId is 0, then ASSET.
+
+  @param[in]  HiiHandle         A handle that was previously registered in the HII Database.
+  @param[in]  Language          The specified configure language to get string.
+  @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
+HiiGetRedfishString (
+  IN EFI_HII_HANDLE           HiiHandle,
+  IN CHAR8                    *Language,
+  IN EFI_STRING_ID            StringId
+  );
+
+/**
+  Retrieves a ASCII string from a string package in a given language. The
+  returned string is allocated using AllocatePool().  The caller is responsible
+  for freeing the allocated buffer using FreePool().
+
+  If HiiHandle is NULL, then ASSERT().
+  If StringId is 0, then ASSET.
+
+  @param[in]  HiiHandle         A handle that was previously registered in the HII Database.
+  @param[in]  Language          The specified configure language to get string.
+  @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.
+
+**/
+CHAR8 *
+HiiGetRedfishAsciiString (
+  IN EFI_HII_HANDLE           HiiHandle,
+  IN CHAR8                    *Language,
+  IN EFI_STRING_ID            StringId
+  );
+
+/**
+  Release all resource in statement list.
+
+  @param[in]  StatementList   Statement list to be released.
+
+  @retval EFI_SUCCESS             All resource are released.
+  @retval EFI_INVALID_PARAMETER   StatementList is NULL.
+
+**/
+EFI_STATUS
+ReleaseStatementList (
+  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST  *StatementList
+  );
+
+#endif
-- 
2.32.0.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#91795): https://edk2.groups.io/g/devel/message/91795
Mute This Topic: https://groups.io/mt/92598008/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [edk2-staging][PATCH v3] edk2/RedfishPkg: Update Redfish Platform Config Protocol
Posted by Chang, Abner via groups.io 1 year, 9 months ago
[AMD Official Use Only - General]

Thanks!
Reviewed-by: Abner Chang <abner.chang@amd.com>

> -----Original Message-----
> From: Nickle Wang <nickle.wang@hpe.com>
> Sent: Monday, July 25, 2022 11:24 AM
> To: devel@edk2.groups.io
> Cc: Chang, Abner <Abner.Chang@amd.com>; Yang, Atom
> <Atom.Yang@amd.com>; Nick Ramirez <nramirez@nvidia.com>
> Subject: [edk2-staging][PATCH v3] edk2/RedfishPkg: Update Redfish
> Platform Config Protocol
> 
> [CAUTION: External Email]
> 
> Update EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL and add array type
> of
> value support to EDKII_REDFISH_VALUE in order to support ordered list
> op-code in HII. Modify corresponding function to support new type of
> data structure.
> 
> Signed-off-by: Nickle Wang <nickle.wang@hpe.com>
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Yang Atom <Atom.Yang@amd.com>
> Cc: Nick Ramirez <nramirez@nvidia.com>
> ---
>  .../Protocol/EdkIIRedfishPlatformConfig.h     |  301 +-
>  .../RedfishPlatformConfigDxe.c                | 3087 ++++++++++-------
>  .../RedfishPlatformConfigDxe.h                |  128 +-
>  .../RedfishPlatformConfigDxe.inf              |  104 +-
>  .../RedfishPlatformConfigImpl.c               | 2528 +++++++-------
>  .../RedfishPlatformConfigImpl.h               |  571 +--
>  6 files changed, 3638 insertions(+), 3081 deletions(-)
> 
> diff --git a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
> b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
> index 895b010227..bbbab90b03 100644
> --- a/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
> +++ b/RedfishPkg/Include/Protocol/EdkIIRedfishPlatformConfig.h
> @@ -1,147 +1,154 @@
> -/** @file
> -  This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
> interface.
> -
> -  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> -
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
> -#define EDKII_REDFISH_PLATFORM_CONFIG_H_
> -
> -typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
> -
> -/**
> -  Definition of EDKII_REDFISH_TYPE_VALUE
> - **/
> -typedef union {
> -  INT64           Integer;
> -  BOOLEAN         Boolean;
> -  CHAR8           *Buffer;
> -} EDKII_REDFISH_TYPE_VALUE;
> -
> -/**
> -  Definition of EDKII_REDFISH_VALUE_TYPES
> - **/
> -typedef enum {
> -  REDFISH_VALUE_TYPE_UNKNOWN = 0,
> -  REDFISH_VALUE_TYPE_INTEGER,
> -  REDFISH_VALUE_TYPE_BOOLEAN,
> -  REDFISH_VALUE_TYPE_STRING,
> -  REDFISH_VALUE_TYPE_MAX
> -} EDKII_REDFISH_VALUE_TYPES;
> -
> -/**
> -  Definition of EDKII_REDFISH_VALUE
> - **/
> -typedef struct {
> -  EDKII_REDFISH_VALUE_TYPES Type;
> -  EDKII_REDFISH_TYPE_VALUE  Value;
> -} EDKII_REDFISH_VALUE;
> -
> -/**
> -  Get Redfish value with the given Schema and Configure Language.
> -
> -  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> -  @param[in]   Schema              The Redfish schema to query.
> -  @param[in]   Version             The Redfish version to query.
> -  @param[in]   ConfigureLang       The target value which match this configure
> Language.
> -  @param[out]  Value               The returned value.
> -
> -  @retval EFI_SUCCESS              Value is returned successfully.
> -  @retval Others                   Some error happened.
> -
> -**/
> -typedef
> -EFI_STATUS
> -(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
> -  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> -  IN     CHAR8                                  *Schema,
> -  IN     CHAR8                                  *Version,
> -  IN     EFI_STRING                             ConfigureLang,
> -  OUT    EDKII_REDFISH_VALUE                    *Value
> -  );
> -
> -/**
> -  Set Redfish value with the given Schema and Configure Language.
> -
> -  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> -  @param[in]   Schema              The Redfish schema to query.
> -  @param[in]   Version             The Redfish version to query.
> -  @param[in]   ConfigureLang       The target value which match this configure
> Language.
> -  @param[in]   Value               The value to set.
> -
> -  @retval EFI_SUCCESS              Value is returned successfully.
> -  @retval Others                   Some error happened.
> -
> -**/
> -typedef
> -EFI_STATUS
> -(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
> -  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> -  IN     CHAR8                                  *Schema,
> -  IN     CHAR8                                  *Version,
> -  IN     EFI_STRING                             ConfigureLang,
> -  IN     EDKII_REDFISH_VALUE                    Value
> -  );
> -
> -/**
> -  Get the list of Configure Language from platform configuration by the given
> Schema and Pattern.
> -
> -  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> -  @param[in]   Schema              The Redfish schema to query.
> -  @param[in]   Version             The Redfish version to query.
> -  @param[in]   Pattern             The target Configure Language pattern.
> -  @param[out]  ConfigureLangList   The list of Configure Language.
> -  @param[out]  Count               The number of Configure Language in
> ConfigureLangList.
> -
> -  @retval EFI_SUCCESS              ConfigureLangList is returned successfully.
> -  @retval Others                   Some error happened.
> -
> -**/
> -typedef
> -EFI_STATUS
> -(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
> -  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> -  IN     CHAR8                                  *Schema,
> -  IN     CHAR8                                  *Version,
> -  IN     EFI_STRING                             Pattern,
> -  OUT    EFI_STRING                             **ConfigureLangList,
> -  OUT    UINTN                                  *Count
> -  );
> -
> -
> -/**
> -  Get the list of supported Redfish schema from platform configuration on
> the give HII handle.
> -
> -  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> -  @param[in]   HiiHandle           The target handle to search. If handle is NULL,
> -                                   this function returns all schema from HII database.
> -  @param[out]  SupportedSchema     The supported schema list which is
> separated by ';'.
> -                                   For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-
> redfish-Boot.v1_0_1"
> -                                   The SupportedSchema is allocated by the callee. It's caller's
> -                                   responsibility to free this buffer using FreePool().
> -
> -  @retval EFI_SUCCESS              Schema is returned successfully.
> -  @retval Others                   Some error happened.
> -
> -**/
> -typedef
> -EFI_STATUS
> -(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA)
> (
> -  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL    *This,
> -  IN     EFI_HII_HANDLE                            HiiHandle,       OPTIONAL
> -  OUT    CHAR8                                     **SupportedSchema
> -  );
> -
> -struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
> -  EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE             GetValue;
> -  EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE             SetValue;
> -  EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG
> GetConfigureLang;
> -  EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA
> GetSupportedSchema;
> -};
> -
> -extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
> -
> -#endif
> +/** @file
> +  This file defines the EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
> interface.
> +
> +  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_H_
> +#define EDKII_REDFISH_PLATFORM_CONFIG_H_
> +
> +typedef struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL;
> +
> +/**
> +  Definition of EDKII_REDFISH_TYPE_VALUE
> + **/
> +typedef union {
> +  INT64           Integer;
> +  BOOLEAN         Boolean;
> +  CHAR8           *Buffer;
> +  CHAR8           **StringArray;
> +  INT64           *IntegerArray;
> +  BOOLEAN         *BooleanArray;
> +} EDKII_REDFISH_TYPE_VALUE;
> +
> +/**
> +  Definition of EDKII_REDFISH_VALUE_TYPES
> + **/
> +typedef enum {
> +  REDFISH_VALUE_TYPE_UNKNOWN = 0,
> +  REDFISH_VALUE_TYPE_INTEGER,
> +  REDFISH_VALUE_TYPE_BOOLEAN,
> +  REDFISH_VALUE_TYPE_STRING,
> +  REDFISH_VALUE_TYPE_STRING_ARRAY,
> +  REDFISH_VALUE_TYPE_INTEGER_ARRAY,
> +  REDFISH_VALUE_TYPE_BOOLEAN_ARRAY,
> +  REDFISH_VALUE_TYPE_MAX
> +} EDKII_REDFISH_VALUE_TYPES;
> +
> +/**
> +  Definition of EDKII_REDFISH_VALUE
> + **/
> +typedef struct {
> +  EDKII_REDFISH_VALUE_TYPES Type;
> +  EDKII_REDFISH_TYPE_VALUE  Value;
> +  UINTN                     ArrayCount;
> +} EDKII_REDFISH_VALUE;
> +
> +/**
> +  Get Redfish value with the given Schema and Configure Language.
> +
> +  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> +  @param[in]   Schema              The Redfish schema to query.
> +  @param[in]   Version             The Redfish version to query.
> +  @param[in]   ConfigureLang       The target value which match this configure
> Language.
> +  @param[out]  Value               The returned value.
> +
> +  @retval EFI_SUCCESS              Value is returned successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE) (
> +  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> +  IN     CHAR8                                  *Schema,
> +  IN     CHAR8                                  *Version,
> +  IN     EFI_STRING                             ConfigureLang,
> +  OUT    EDKII_REDFISH_VALUE                    *Value
> +  );
> +
> +/**
> +  Set Redfish value with the given Schema and Configure Language.
> +
> +  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> +  @param[in]   Schema              The Redfish schema to query.
> +  @param[in]   Version             The Redfish version to query.
> +  @param[in]   ConfigureLang       The target value which match this configure
> Language.
> +  @param[in]   Value               The value to set.
> +
> +  @retval EFI_SUCCESS              Value is returned successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE) (
> +  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> +  IN     CHAR8                                  *Schema,
> +  IN     CHAR8                                  *Version,
> +  IN     EFI_STRING                             ConfigureLang,
> +  IN     EDKII_REDFISH_VALUE                    Value
> +  );
> +
> +/**
> +  Get the list of Configure Language from platform configuration by the
> given Schema and RegexPattern.
> +
> +  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> +  @param[in]   Schema              The Redfish schema to query.
> +  @param[in]   Version             The Redfish version to query.
> +  @param[in]   RegexPattern        The target Configure Language pattern.
> This is used for regular expression matching.
> +  @param[out]  ConfigureLangList   The list of Configure Language.
> +  @param[out]  Count               The number of Configure Language in
> ConfigureLangList.
> +
> +  @retval EFI_SUCCESS              ConfigureLangList is returned successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG) (
> +  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> +  IN     CHAR8                                  *Schema,
> +  IN     CHAR8                                  *Version,
> +  IN     EFI_STRING                             RegexPattern,
> +  OUT    EFI_STRING                             **ConfigureLangList,
> +  OUT    UINTN                                  *Count
> +  );
> +
> +
> +/**
> +  Get the list of supported Redfish schema from platform configuration on
> the give HII handle.
> +
> +  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> +  @param[in]   HiiHandle           The target handle to search. If handle is NULL,
> +                                   this function returns all schema from HII database.
> +  @param[out]  SupportedSchema     The supported schema list which is
> separated by ';'.
> +                                   For example: "x-uefi-redfish-Memory.v1_7_1;x-uefi-
> redfish-Boot.v1_0_1"
> +                                   The SupportedSchema is allocated by the callee. It's
> caller's
> +                                   responsibility to free this buffer using FreePool().
> +
> +  @retval EFI_SUCCESS              Schema is returned successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA)
> (
> +  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL    *This,
> +  IN     EFI_HII_HANDLE                            HiiHandle,       OPTIONAL
> +  OUT    CHAR8                                     **SupportedSchema
> +  );
> +
> +struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
> +  EDKII_REDFISH_PLATFORM_CONFIG_GET_VALUE             GetValue;
> +  EDKII_REDFISH_PLATFORM_CONFIG_SET_VALUE             SetValue;
> +  EDKII_REDFISH_PLATFORM_CONFIG_GET_CONFIG_LANG
> GetConfigureLang;
> +  EDKII_REDFISH_PLATFORM_CONFIG_GET_SUPPORTED_SCHEMA
> GetSupportedSchema;
> +};
> +
> +extern EFI_GUID gEdkIIRedfishPlatformConfigProtocolGuid;
> +
> +#endif
> diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> index 67818cccd2..971035f27d 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.c
> @@ -1,1304 +1,1783 @@
> -/** @file
> -
> -  The implementation of EDKII Redfidh Platform Config Protocol.
> -
> -  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> -
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include "RedfishPlatformConfigDxe.h"
> -#include "RedfishPlatformConfigImpl.h"
> -
> -REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
> NULL;
> -
> -/**
> -  Compare two value in HII statement format.
> -
> -  @param[in]  Value1        Firt value to compare.
> -  @param[in]  Value2        Second value to be compared.
> -
> -  @retval UINTN         0 is retuned when two values are equal.
> -                        1 is returned when first value is greater than second value.
> -                        -1 is returned when second value is greater than first value.
> -
> -**/
> -UINTN
> -CompareHiiStatementValue (
> -  IN HII_STATEMENT_VALUE  *Value1,
> -  IN HII_STATEMENT_VALUE  *Value2
> -  )
> -{
> -  INTN Result;
> -  UINT64 Data1;
> -  UINT64 Data2;
> -
> -  if (Value1 == NULL || Value2 == NULL) {
> -    return 0xFF;
> -  }
> -
> -  switch (Value1->Type) {
> -    case EFI_IFR_TYPE_NUM_SIZE_8:
> -      Data1 = Value1->Value.u8;
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_16:
> -      Data1 = Value1->Value.u16;
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_32:
> -      Data1 = Value1->Value.u32;
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_64:
> -      Data1 = Value1->Value.u64;
> -      break;
> -    case EFI_IFR_TYPE_BOOLEAN:
> -      Data1 = (Value1->Value.b ? 1 : 0);
> -      break;
> -    default:
> -      return 0xFF;
> -  }
> -
> -  switch (Value2->Type) {
> -    case EFI_IFR_TYPE_NUM_SIZE_8:
> -      Data2 = Value2->Value.u8;
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_16:
> -      Data2 = Value2->Value.u16;
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_32:
> -      Data2 = Value2->Value.u32;
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_64:
> -      Data2 = Value2->Value.u64;
> -      break;
> -    case EFI_IFR_TYPE_BOOLEAN:
> -      Data2 = (Value2->Value.b ? 1 : 0);
> -      break;
> -    default:
> -      return 0xFF;
> -  }
> -
> -  Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
> -
> -  return Result;
> -}
> -
> -/**
> -  Convert HII value to the string in HII one-of opcode.
> -
> -  @param[in]  Statement     Statement private instance
> -
> -  @retval EFI_STRING_ID     The string ID in HII database.
> -                            0 is returned when something goes wrong.
> -
> -**/
> -EFI_STRING_ID
> -HiiValueToOneOfOptionStringId (
> -  IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
> -  )
> -{
> -  LIST_ENTRY            *Link;
> -  HII_QUESTION_OPTION   *Option;
> -
> -  if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
> -    return 0;
> -  }
> -
> -  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> -    return 0;
> -  }
> -
> -  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> -  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> -    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> -
> -    if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
> &Option->Value) == 0) {
> -      return Option->Text;
> -    }
> -
> -    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
> -  }
> -
> -  return 0;
> -}
> -
> -/**
> -  Convert HII string to the value in HII one-of opcode.
> -
> -  @param[in]  Statement     Statement private instance
> -  @param[in]  Schema        Schema string
> -  @param[in]  HiiString     Input string
> -  @param[out] Value         Value returned
> -
> -  @retval EFI_SUCCESS       HII value is returned successfully.
> -  @retval Others            Errors occur
> -
> -**/
> -EFI_STATUS
> -HiiStringToOneOfOptionValue (
> -  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
> -  IN  CHAR8                           *Schema,
> -  IN  EFI_STRING                      HiiString,
> -  OUT HII_STATEMENT_VALUE             *Value
> -  )
> -{
> -  LIST_ENTRY            *Link;
> -  HII_QUESTION_OPTION   *Option;
> -  EFI_STRING            TmpString;
> -  BOOLEAN               Found;
> -
> -  if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
> -    return EFI_UNSUPPORTED;
> -  }
> -
> -  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  Found = FALSE;
> -  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> -  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> -    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> -
> -    TmpString = HiiGetRedfishString (Statement->ParentForm-
> >ParentFormset->HiiHandle, Schema, Option->Text);
> -    if (TmpString != NULL) {
> -      if (StrCmp (TmpString, HiiString) == 0) {
> -        CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
> -        Found = TRUE;
> -      }
> -      FreePool (TmpString);
> -    }
> -
> -    if (Found) {
> -      return EFI_SUCCESS;
> -    }
> -
> -    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
> -  }
> -
> -  return EFI_NOT_FOUND;
> -}
> -
> -/**
> -  Convert HII value to numeric value in Redfish format.
> -
> -  @param[in]  Value         Value to be converted.
> -  @param[out] RedfishValue  Value in Redfish format.
> -
> -  @retval EFI_SUCCESS       Redfish value is returned successfully.
> -  @retval Others            Errors occur
> -
> -**/
> -EFI_STATUS
> -HiiValueToRedfishNumeric (
> -  IN  HII_STATEMENT_VALUE  *Value,
> -  OUT EDKII_REDFISH_VALUE  *RedfishValue
> -  )
> -{
> -  if (Value == NULL || RedfishValue == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  switch (Value->Type) {
> -    case EFI_IFR_TYPE_NUM_SIZE_8:
> -      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> -      RedfishValue->Value.Integer = (INT64)Value->Value.u8;
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_16:
> -      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> -      RedfishValue->Value.Integer = (INT64)Value->Value.u16;
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_32:
> -      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> -      RedfishValue->Value.Integer = (INT64)Value->Value.u32;
> -      break;
> -    case EFI_IFR_TYPE_NUM_SIZE_64:
> -      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> -      RedfishValue->Value.Integer = (INT64)Value->Value.u64;
> -      break;
> -    case EFI_IFR_TYPE_BOOLEAN:
> -      RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
> -      RedfishValue->Value.Boolean = Value->Value.b;
> -      break;
> -    default:
> -      RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> -      break;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Convert numeric value in Redfish format to HII value.
> -
> -  @param[in]   RedfishValue  Value in Redfish format to be converted.
> -  @param[out]  Value         HII value returned.
> -
> -  @retval EFI_SUCCESS       HII value is returned successfully.
> -  @retval Others            Errors occur
> -
> -**/
> -EFI_STATUS
> -RedfishNumericToHiiValue (
> -  IN  EDKII_REDFISH_VALUE  *RedfishValue,
> -  OUT HII_STATEMENT_VALUE  *Value
> -  )
> -{
> -  if (Value == NULL || RedfishValue == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  switch (RedfishValue->Type) {
> -    case REDFISH_VALUE_TYPE_INTEGER:
> -      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
> -      Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
> -      break;
> -    case REDFISH_VALUE_TYPE_BOOLEAN:
> -      Value->Type = EFI_IFR_TYPE_BOOLEAN;
> -      Value->Value.b = RedfishValue->Value.Boolean;
> -      break;
> -    default:
> -      Value->Type = EFI_IFR_TYPE_UNDEFINED;
> -      break;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Return the full Redfish schema string from the given Schema and Version.
> -
> -  Returned schema string is: Schema + '.' + Version
> -
> -  @param[in]  Schema      Schema string
> -  @param[in]  Version     Schema version string
> -
> -  @retval CHAR8 *         Schema string. NULL when errors occur.
> -
> -**/
> -CHAR8 *
> -GetFullSchemaString (
> -  IN CHAR8   *Schema,
> -  IN CHAR8  *Version
> -  )
> -{
> -  UINTN Size;
> -  CHAR8 *FullName;
> -
> -  if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
> -    return NULL;
> -  }
> -
> -  Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize (Schema)
> + AsciiStrSize (Version);
> -
> -  FullName = AllocatePool (Size);
> -  if (FullName == NULL) {
> -    DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
> -    return NULL;
> -  }
> -
> -  AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
> Schema, Version);
> -
> -  return FullName;
> -}
> -
> -/**
> -  Common implementation to get statement private instance.
> -
> -  @param[in]   RedfishPlatformConfigPrivate   Private instance.
> -  @param[in]   Schema                         Redfish schema string.
> -  @param[in]   ConfigureLang                  Configure language that refers to this
> statement.
> -  @param[out]  Statement                      Statement instance
> -
> -  @retval EFI_SUCCESS       HII value is returned successfully.
> -  @retval Others            Errors occur
> -
> -**/
> -EFI_STATUS
> -RedfishPlatformConfigGetStatementCommon (
> -  IN     REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate,
> -  IN     CHAR8                                      *Schema,
> -  IN     EFI_STRING                                 ConfigureLang,
> -  OUT    REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  **Statement
> -  )
> -{
> -  EFI_STATUS                      Status;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
> -
> -  if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  *Statement = NULL;
> -
> -  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> -    return Status;
> -  }
> -
> -  TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> -  if (TargetStatement == NULL) {
> -    DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
> given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  //
> -  // Find current HII question value.
> -  //
> -  Status = GetQuestionValue (
> -             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
> -             TargetStatement->ParentForm->HiiForm,
> -             TargetStatement->HiiStatement,
> -             GetSetValueWithHiiDriver
> -             );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n",
> __FUNCTION__, Status));
> -    return Status;
> -  }
> -
> -
> -  if (TargetStatement->HiiStatement->Value.Type ==
> EFI_IFR_TYPE_UNDEFINED) {
> -    return EFI_DEVICE_ERROR;
> -  }
> -
> -  //
> -  // Return Value.
> -  //
> -  *Statement = TargetStatement;
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Get Redfish value with the given Schema and Configure Language.
> -
> -  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> -  @param[in]   Schema              The Redfish schema to query.
> -  @param[in]   Version             The Redfish version to query.
> -  @param[in]   ConfigureLang       The target value which match this configure
> Language.
> -  @param[out]  Value               The returned value.
> -
> -  @retval EFI_SUCCESS              Value is returned successfully.
> -  @retval Others                   Some error happened.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RedfishPlatformConfigProtocolGetValue (
> -  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> -  IN     CHAR8                                  *Schema,
> -  IN     CHAR8                                  *Version,
> -  IN     EFI_STRING                             ConfigureLang,
> -  OUT    EDKII_REDFISH_VALUE                    *Value
> -  )
> -{
> -  EFI_STATUS                                Status;
> -  REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
> -  EFI_STRING_ID                             StringId;
> -  CHAR8                                     *FullSchema;
> -  EFI_STRING                                HiiString;
> -  UINTN                                     Size;
> -
> -  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> -  Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> -  FullSchema = NULL;
> -  HiiString = NULL;
> -
> -  FullSchema = GetFullSchemaString (Schema, Version);
> -  if (FullSchema == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  Status = RedfishPlatformConfigGetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
> &TargetStatement);
> -  if (EFI_ERROR (Status)) {
> -    goto RELEASE_RESOURCE;
> -  }
> -
> -  switch (TargetStatement->HiiStatement->Operand) {
> -    case EFI_IFR_ONE_OF_OP:
> -      StringId = HiiValueToOneOfOptionStringId (TargetStatement);
> -      if (StringId == 0) {
> -        ASSERT (FALSE);
> -        Status = EFI_DEVICE_ERROR;
> -        goto RELEASE_RESOURCE;
> -      }
> -
> -      HiiString = HiiGetRedfishString (TargetStatement->ParentForm-
> >ParentFormset->HiiHandle, FullSchema, StringId);
> -      if (HiiString == NULL) {
> -        DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
> __FUNCTION__, StringId, FullSchema));
> -        Status = EFI_NOT_FOUND;
> -        goto RELEASE_RESOURCE;
> -      }
> -
> -      Size = StrLen (HiiString) + 1;
> -      Value->Value.Buffer = AllocatePool (Size);
> -      if (Value->Value.Buffer == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto RELEASE_RESOURCE;
> -      }
> -
> -      UnicodeStrToAsciiStrS (HiiString, Value->Value.Buffer, Size);
> -      Value->Type = REDFISH_VALUE_TYPE_STRING;
> -
> -      break;
> -    case EFI_IFR_STRING_OP:
> -      if (TargetStatement->HiiStatement->Value.Type !=
> EFI_IFR_TYPE_STRING) {
> -        ASSERT (FALSE);
> -        Status = EFI_DEVICE_ERROR;
> -        goto RELEASE_RESOURCE;
> -      }
> -
> -      Value->Type = REDFISH_VALUE_TYPE_STRING;
> -      Value->Value.Buffer = AllocateCopyPool (StrSize ((CHAR16
> *)TargetStatement->HiiStatement->Value.Buffer), TargetStatement-
> >HiiStatement->Value.Buffer);
> -      if (Value->Value.Buffer == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto RELEASE_RESOURCE;
> -      }
> -      break;
> -    case EFI_IFR_CHECKBOX_OP:
> -    case EFI_IFR_NUMERIC_OP:
> -      Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
> >Value, Value);
> -      if (EFI_ERROR (Status)) {
> -        DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
> value: %r\n", __FUNCTION__, Status));
> -        goto RELEASE_RESOURCE;
> -      }
> -      break;
> -    default:
> -      DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
> contact with author if we need to support this type.\n", __FUNCTION__,
> TargetStatement->HiiStatement->Operand));
> -      ASSERT (FALSE);
> -      Status = EFI_UNSUPPORTED;
> -      goto RELEASE_RESOURCE;
> -  }
> -
> -RELEASE_RESOURCE:
> -
> -  if (FullSchema != NULL) {
> -    FreePool (FullSchema);
> -  }
> -
> -  if (HiiString != NULL) {
> -    FreePool (HiiString);
> -  }
> -
> -  return Status;
> -}
> -
> -/**
> -  Function to save question value into HII database.
> -
> -  @param[in]   HiiFormset       HII form-set instance
> -  @param[in]   HiiForm          HII form instance
> -  @param[in]   HiiStatement     HII statement that keeps new value.
> -  @param[in]   Value            New value to applyu.
> -
> -  @retval EFI_SUCCESS       HII value is returned successfully.
> -  @retval Others            Errors occur
> -
> -**/
> -EFI_STATUS
> -RedfishPlatformConfigSaveQuestionValue (
> -  IN  HII_FORMSET         *HiiFormset,
> -  IN  HII_FORM            *HiiForm,
> -  IN  HII_STATEMENT       *HiiStatement,
> -  IN  HII_STATEMENT_VALUE *Value
> -  )
> -{
> -  EFI_STATUS  Status;
> -
> -  if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL ||
> Value == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  Status = SetQuestionValue (
> -             HiiFormset,
> -             HiiForm,
> -             HiiStatement,
> -             Value
> -             );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
> __FUNCTION__, Status));
> -    return Status;
> -  }
> -
> -  Status = SubmitForm (HiiFormset, HiiForm);
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n",
> __FUNCTION__, Status));
> -    return Status;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Common implementation to set statement private instance.
> -
> -  @param[in]   RedfishPlatformConfigPrivate   Private instance.
> -  @param[in]   Schema                         Redfish schema string.
> -  @param[in]   ConfigureLang                  Configure language that refers to this
> statement.
> -  @param[in]   Statement                      Statement instance
> -
> -  @retval EFI_SUCCESS       HII value is returned successfully.
> -  @retval Others            Errors occur
> -
> -**/
> -EFI_STATUS
> -RedfishPlatformConfigSetStatementCommon (
> -  IN     REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate,
> -  IN     CHAR8                            *Schema,
> -  IN     EFI_STRING                       ConfigureLang,
> -  IN     HII_STATEMENT_VALUE              *StatementValue
> -  )
> -{
> -  EFI_STATUS                                Status;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
> -  EFI_STRING                                TempBuffer;
> -
> -  if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  TempBuffer = NULL;
> -
> -  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> -    return Status;
> -  }
> -
> -  TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> -  if (TargetStatement == NULL) {
> -    DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
> given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  if (StatementValue->Type != TargetStatement->HiiStatement->Value.Type)
> {
> -    //
> -    // We treat one-of type as string in Redfish. But one-of statement is not
> -    // in string format from HII point of view. Do a patch here.
> -    //
> -    if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP
> && StatementValue->Type == EFI_IFR_TYPE_STRING) {
> -      TempBuffer = AllocatePool (StatementValue->BufferLen * sizeof
> (CHAR16));
> -      if (TempBuffer == NULL) {
> -        return EFI_OUT_OF_RESOURCES;
> -      }
> -
> -      AsciiStrToUnicodeStrS (StatementValue->Buffer, TempBuffer,
> StatementValue->BufferLen);
> -      FreePool (StatementValue->Buffer);
> -      StatementValue->Buffer = NULL;
> -      StatementValue->BufferLen = 0;
> -
> -      Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
> TempBuffer, StatementValue);
> -      if (EFI_ERROR (Status)) {
> -        DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given
> %s\n", __FUNCTION__, TempBuffer));
> -        FreePool (TempBuffer);
> -        return EFI_NOT_FOUND;
> -      }
> -
> -      FreePool (TempBuffer);
> -    } else if (TargetStatement->HiiStatement->Operand ==
> EFI_IFR_NUMERIC_OP && StatementValue->Type ==
> EFI_IFR_TYPE_NUM_SIZE_64) {
> -      //
> -      // Redfish only has numeric value type and it does not care about the
> value size.
> -      // Do a patch here so we have proper value size applied.
> -      //
> -      StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
> -    } else {
> -      DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type:
> 0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue-
> >Type, TargetStatement->HiiStatement->Value.Type));
> -      ASSERT (FALSE);
> -    }
> -  }
> -
> -  Status = RedfishPlatformConfigSaveQuestionValue (
> -             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
> -             TargetStatement->ParentForm->HiiForm,
> -             TargetStatement->HiiStatement,
> -             StatementValue
> -             );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n",
> __FUNCTION__, Status));
> -    return Status;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Set Redfish value with the given Schema and Configure Language.
> -
> -  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> -  @param[in]   Schema              The Redfish schema to query.
> -  @param[in]   Version             The Redfish version to query.
> -  @param[in]   ConfigureLang       The target value which match this configure
> Language.
> -  @param[in]   Value               The value to set.
> -
> -  @retval EFI_SUCCESS              Value is returned successfully.
> -  @retval Others                   Some error happened.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RedfishPlatformConfigProtocolSetValue (
> -  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> -  IN     CHAR8                                  *Schema,
> -  IN     CHAR8                                  *Version,
> -  IN     EFI_STRING                             ConfigureLang,
> -  IN     EDKII_REDFISH_VALUE                    Value
> -  )
> -{
> -  EFI_STATUS                                Status;
> -  REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate;
> -  CHAR8                                     *FullSchema;
> -  HII_STATEMENT_VALUE                       NewValue;
> -
> -  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang)) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
> REDFISH_VALUE_TYPE_MAX) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> -  FullSchema = NULL;
> -
> -  FullSchema = GetFullSchemaString (Schema, Version);
> -  if (FullSchema == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
> -
> -  switch (Value.Type) {
> -    case REDFISH_VALUE_TYPE_INTEGER:
> -    case REDFISH_VALUE_TYPE_BOOLEAN:
> -      Status = RedfishNumericToHiiValue (&Value, &NewValue);
> -      if (EFI_ERROR (Status)) {
> -        DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
> value: %r\n", __FUNCTION__, Status));
> -        goto RELEASE_RESOURCE;
> -      }
> -      break;
> -    case REDFISH_VALUE_TYPE_STRING:
> -      NewValue.Type = EFI_IFR_TYPE_STRING;
> -      NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
> -      NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
> Value.Value.Buffer);
> -      if (NewValue.Buffer == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto RELEASE_RESOURCE;
> -      }
> -      break;
> -    default:
> -      ASSERT (FALSE);
> -      break;
> -  }
> -
> -  Status = RedfishPlatformConfigSetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
> __FUNCTION__, Status));
> -  }
> -
> -RELEASE_RESOURCE:
> -
> -  if (FullSchema != NULL) {
> -    FreePool (FullSchema);
> -  }
> -
> -  return Status;
> -}
> -
> -/**
> -  Get the list of Configure Language from platform configuration by the given
> Schema and Pattern.
> -
> -  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> -  @param[in]   Schema              The Redfish schema to query.
> -  @param[in]   Version             The Redfish version to query.
> -  @param[in]   Pattern             The target Configure Language pattern.
> -  @param[out]  ConfigureLangList         The list of Configure Language.
> -  @param[out]  Count               The number of Configure Language in
> ConfigureLangList.
> -
> -  @retval EFI_SUCCESS              ConfigureLangList is returned successfully.
> -  @retval Others                   Some error happened.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RedfishPlatformConfigProtocolGetConfigureLang (
> -  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> -  IN     CHAR8                                  *Schema,
> -  IN     CHAR8                                  *Version,
> -  IN     EFI_STRING                             Pattern,
> -  OUT    EFI_STRING                             **ConfigureLangList,
> -  OUT    UINTN                                  *Count
> -  )
> -{
> -  REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate;
> -  EFI_STATUS                                      Status;
> -  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;
> -
> -  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || Count == NULL || ConfigureLangList == NULL ||
> IS_EMPTY_STRING (Pattern)) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  *Count = 0;
> -  *ConfigureLangList = NULL;
> -  FullSchema = NULL;
> -  RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> -
> -  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> -    return Status;
> -  }
> -
> -  FullSchema = GetFullSchemaString (Schema, Version);
> -  if (FullSchema == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  Status = GetStatementPrivateByConfigureLangRegex (
> -             RedfishPlatformConfigPrivate->RegularExpressionProtocol,
> -             &RedfishPlatformConfigPrivate->FormsetList,
> -             FullSchema,
> -             Pattern,
> -             &StatementList
> -             );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a,
> GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
> Status));
> -    goto RELEASE_RESOURCE;
> -  }
> -
> -  if (!IsListEmpty (&StatementList.StatementList)) {
> -
> -    TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
> StatementList.Count);
> -    if (TmpConfigureLangList == NULL) {
> -      Status = EFI_OUT_OF_RESOURCES;
> -      goto RELEASE_RESOURCE;
> -    }
> -
> -    Index = 0;
> -    NextLink = GetFirstNode (&StatementList.StatementList);
> -    while (!IsNull (&StatementList.StatementList, NextLink)) {
> -      StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> -      NextLink = GetNextNode (&StatementList.StatementList, NextLink);
> -
> -      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] = AllocateCopyPool (StrSize (TmpString),
> TmpString);
> -          ASSERT (TmpConfigureLangList[Index] != NULL);
> -          FreePool (TmpString);
> -          ++Index;
> -        }
> -      }
> -    }
> -  }
> -
> -  *Count = StatementList.Count;
> -  *ConfigureLangList = TmpConfigureLangList;
> -
> -RELEASE_RESOURCE:
> -
> -  if (FullSchema != NULL) {
> -    FreePool (FullSchema);
> -  }
> -
> -  ReleaseStatementList (&StatementList);
> -
> -  return Status;
> -}
> -
> -
> -/**
> -  Get the list of supported Redfish schema from paltform configuration on
> give HII handle.
> -
> -  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> -  @param[in]   HiiHandle           The target handle to search. If handle is NULL,
> -                                   this function return all schema from HII database.
> -  @param[out]  SupportedSchema     The supported schema list which is
> separated by ';'.
> -                                   The SupportedSchema is allocated by the callee. It's caller's
> -                                   responsibility to free this buffer using FreePool().
> -
> -  @retval EFI_SUCCESS              Schema is returned successfully.
> -  @retval Others                   Some error happened.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RedfishPlatformConfigProtocolGetSupportedSchema (
> -  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL   *This,
> -  IN     EFI_HII_HANDLE                           HiiHandle,       OPTIONAL
> -  OUT    CHAR8                                    **SupportedSchema
> -  )
> -{
> -  REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate;
> -  EFI_STATUS                                Status;
> -  LIST_ENTRY                                *HiiFormsetLink;
> -  LIST_ENTRY                                *HiiFormsetNextLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> -  UINTN                                     Index;
> -  UINTN                                     StringSize;
> -  CHAR8                                     *StringBuffer;
> -  UINTN                                     StringIndex;
> -
> -  if (This == NULL || SupportedSchema == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  *SupportedSchema = NULL;
> -
> -  RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> -
> -  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> -    return Status;
> -  }
> -
> -  if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  //
> -  // Calculate for string buffer size.
> -  //
> -  StringSize = 0;
> -  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> -  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> -    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> -    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> -    if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> -      HiiFormsetLink = HiiFormsetNextLink;
> -      continue;
> -    }
> -
> -    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> -      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> -        StringSize += AsciiStrSize (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> -      }
> -    }
> -
> -    HiiFormsetLink = HiiFormsetNextLink;
> -  }
> -
> -  if (StringSize == 0) {
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  StringBuffer = AllocatePool (StringSize);
> -  if (StringBuffer == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  StringIndex = 0;
> -  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> -  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> -    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> -    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> -    if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> -      HiiFormsetLink = HiiFormsetNextLink;
> -      continue;
> -    }
> -
> -    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> -      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> -        AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
> HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
> -        StringIndex += AsciiStrLen (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> -        StringBuffer[StringIndex] = ';';
> -        ++StringIndex;
> -      }
> -    }
> -
> -    HiiFormsetLink = HiiFormsetNextLink;
> -  }
> -
> -  StringBuffer[--StringIndex] = '\0';
> -
> -  *SupportedSchema = StringBuffer;
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Functions which are registered to receive notification of
> -  database events have this prototype. The actual event is encoded
> -  in NotifyType. The following table describes how PackageType,
> -  PackageGuid, Handle, and Package are used for each of the
> -  notification types.
> -
> -  @param[in] PackageType  Package type of the notification.
> -  @param[in] PackageGuid  If PackageType is
> -                          EFI_HII_PACKAGE_TYPE_GUID, then this is
> -                          the pointer to the GUID from the Guid
> -                          field of EFI_HII_PACKAGE_GUID_HEADER.
> -                          Otherwise, it must be NULL.
> -  @param[in] Package      Points to the package referred to by the
> -                          notification Handle The handle of the package
> -                          list which contains the specified package.
> -  @param[in] Handle       The HII handle.
> -  @param[in] NotifyType   The type of change concerning the
> -                          database. See
> -                          EFI_HII_DATABASE_NOTIFY_TYPE.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RedfishPlatformConfigFormUpdateNotify (
> -  IN UINT8                              PackageType,
> -  IN CONST EFI_GUID                     *PackageGuid,
> -  IN CONST EFI_HII_PACKAGE_HEADER       *Package,
> -  IN EFI_HII_HANDLE                     Handle,
> -  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType
> -  )
> -{
> -  EFI_STATUS  Status;
> -
> -  if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
> == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
> -    //
> -    // HII formset on this handle is updated by driver during run-time. The
> formset needs to be reloaded.
> -    //
> -    Status = NotifyFormsetUpdate (Handle, &mRedfishPlatformConfigPrivate-
> >PendingList);
> -    if (EFI_ERROR (Status)) {
> -      DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
> handle: 0x%x\n", __FUNCTION__, Handle));
> -      return Status;
> -    }
> -  } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
> -    //
> -    // HII resource is removed. The formset is no longer exist.
> -    //
> -    Status = NotifyFormsetDeleted (Handle,
> &mRedfishPlatformConfigPrivate->PendingList);
> -    if (EFI_ERROR (Status)) {
> -      DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
> handle: 0x%x\n", __FUNCTION__, Handle));
> -      return Status;
> -    }
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  This is a EFI_HII_STRING_PROTOCOL notification event handler.
> -
> -  Install HII package notification.
> -
> -  @param[in] Event    Event whose notification function is being invoked.
> -  @param[in] Context  Pointer to the notification function's context.
> -
> -**/
> -VOID
> -EFIAPI
> -HiiStringProtocolInstalled (
> -  IN  EFI_EVENT       Event,
> -  IN  VOID            *Context
> -  )
> -{
> -  EFI_STATUS  Status;
> -
> -  //
> -  // Locate HII database protocol.
> -  //
> -  Status = gBS->LocateProtocol (
> -                  &gEfiHiiStringProtocolGuid,
> -                  NULL,
> -                  (VOID **)&mRedfishPlatformConfigPrivate->HiiString
> -                  );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure:
> %r\n", __FUNCTION__, Status));
> -    return;
> -  }
> -
> -  gBS->CloseEvent (Event);
> -  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
> -}
> -
> -/**
> -  This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
> -
> -  Install HII package notification.
> -
> -  @param[in] Event    Event whose notification function is being invoked.
> -  @param[in] Context  Pointer to the notification function's context.
> -
> -**/
> -VOID
> -EFIAPI
> -HiiDatabaseProtocolInstalled (
> -  IN  EFI_EVENT       Event,
> -  IN  VOID            *Context
> -  )
> -{
> -  EFI_STATUS  Status;
> -
> -  //
> -  // Locate HII database protocol.
> -  //
> -  Status = gBS->LocateProtocol (
> -                  &gEfiHiiDatabaseProtocolGuid,
> -                  NULL,
> -                  (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
> -                  );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL
> failure: %r\n", __FUNCTION__, Status));
> -    return;
> -  }
> -
> -  //
> -  // Register package notification when new form package is installed.
> -  //
> -  Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> -                                             mRedfishPlatformConfigPrivate->HiiDatabase,
> -                                             EFI_HII_PACKAGE_FORMS,
> -                                             NULL,
> -                                             RedfishPlatformConfigFormUpdateNotify,
> -                                             EFI_HII_DATABASE_NOTIFY_NEW_PACK,
> -                                             &mRedfishPlatformConfigPrivate->NotifyHandle
> -                                             );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> -  }
> -
> -  //
> -  // Register package notification when new form package is updated.
> -  //
> -  Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> -                                             mRedfishPlatformConfigPrivate->HiiDatabase,
> -                                             EFI_HII_PACKAGE_FORMS,
> -                                             NULL,
> -                                             RedfishPlatformConfigFormUpdateNotify,
> -                                             EFI_HII_DATABASE_NOTIFY_ADD_PACK,
> -                                             &mRedfishPlatformConfigPrivate->NotifyHandle
> -                                             );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> -  }
> -
> -#if REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET
> -  //
> -  // Register package notification when new form package is removed.
> -  //
> -  Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> -                                             mRedfishPlatformConfigPrivate->HiiDatabase,
> -                                             EFI_HII_PACKAGE_FORMS,
> -                                             NULL,
> -                                             RedfishPlatformConfigFormUpdateNotify,
> -                                             EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
> -                                             &mRedfishPlatformConfigPrivate->NotifyHandle
> -                                             );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> -  }
> -#endif
> -
> -  gBS->CloseEvent (Event);
> -  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
> -
> -}
> -
> -/**
> -  This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
> -
> -  @param[in] Event    Event whose notification function is being invoked.
> -  @param[in] Context  Pointer to the notification function's context.
> -
> -**/
> -VOID
> -EFIAPI
> -RegexProtocolInstalled (
> -  IN  EFI_EVENT       Event,
> -  IN  VOID            *Context
> -  )
> -{
> -  EFI_STATUS  Status;
> -
> -  //
> -  // Locate regular expression protocol.
> -  //
> -  Status = gBS->LocateProtocol (
> -                  &gEfiRegularExpressionProtocolGuid,
> -                  NULL,
> -                  (VOID **)&mRedfishPlatformConfigPrivate-
> >RegularExpressionProtocol
> -                  );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, locate
> EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
> Status));
> -    return;
> -  }
> -
> -  gBS->CloseEvent (Event);
> -  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
> -
> -}
> -
> -/**
> -  Unloads an image.
> -
> -  @param  ImageHandle           Handle that identifies the image to be
> unloaded.
> -
> -  @retval EFI_SUCCESS           The image has been unloaded.
> -  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RedfishPlatformConfigDxeUnload (
> -  IN EFI_HANDLE  ImageHandle
> -  )
> -{
> -  EFI_STATUS Status;
> -
> -  if (mRedfishPlatformConfigPrivate != NULL) {
> -    Status = gBS->UninstallProtocolInterface (
> -                    mRedfishPlatformConfigPrivate->ImageHandle,
> -                    &gEdkIIRedfishPlatformConfigProtocolGuid,
> -                    (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> -                    );
> -    if (EFI_ERROR (Status)) {
> -      DEBUG ((DEBUG_ERROR, "%a, can not uninstall
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> -      ASSERT (FALSE);
> -    }
> -
> -    //
> -    // Close events
> -    //
> -    if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
> -      gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiDbNotify.ProtocolEvent);
> -    }
> -    if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent != NULL)
> {
> -      gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiStringNotify.ProtocolEvent);
> -    }
> -    if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL) {
> -      gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >RegexNotify.ProtocolEvent);
> -    }
> -
> -    //
> -    // Unregister package notification.
> -    //
> -    if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
> -      mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
> (
> -                                          mRedfishPlatformConfigPrivate->HiiDatabase,
> -                                          mRedfishPlatformConfigPrivate->NotifyHandle
> -                                          );
> -    }
> -
> -    ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
> -    FreePool (mRedfishPlatformConfigPrivate);
> -    mRedfishPlatformConfigPrivate = NULL;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -
> -/**
> -  This is the declaration of an EFI image entry point. This entry point is
> -  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> -  both device drivers and bus drivers.
> -
> -  @param  ImageHandle           The firmware allocated handle for the UEFI
> image.
> -  @param  SystemTable           A pointer to the EFI System Table.
> -
> -  @retval EFI_SUCCESS           The operation completed successfully.
> -  @retval Others                An unexpected error occurred.
> -**/
> -EFI_STATUS
> -EFIAPI
> -RedfishPlatformConfigDxeEntryPoint (
> -  IN EFI_HANDLE        ImageHandle,
> -  IN EFI_SYSTEM_TABLE  *SystemTable
> -  )
> -{
> -  EFI_STATUS  Status;
> -
> -  mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE
> *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
> -  if (mRedfishPlatformConfigPrivate == NULL) {
> -    DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
> REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
> -    ASSERT (FALSE);
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  //
> -  // Protocol initialization
> -  //
> -  mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
> -  mRedfishPlatformConfigPrivate->Protocol.GetValue =
> RedfishPlatformConfigProtocolGetValue;
> -  mRedfishPlatformConfigPrivate->Protocol.SetValue =
> RedfishPlatformConfigProtocolSetValue;
> -  mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
> RedfishPlatformConfigProtocolGetConfigureLang;
> -  mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
> RedfishPlatformConfigProtocolGetSupportedSchema;
> -
> -  InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
> -  InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
> -
> -  Status = gBS->InstallProtocolInterface (
> -                  &ImageHandle,
> -                  &gEdkIIRedfishPlatformConfigProtocolGuid,
> -                  EFI_NATIVE_INTERFACE,
> -                  (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> -                  );
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, can not install
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> -    ASSERT (FALSE);
> -  }
> -
> -  //
> -  // Install protocol notification if HII database protocol is installed.
> -  //
> -  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> -                                                              &gEfiHiiDatabaseProtocolGuid,
> -                                                              TPL_CALLBACK,
> -                                                              HiiDatabaseProtocolInstalled,
> -                                                              NULL,
> -                                                              &mRedfishPlatformConfigPrivate-
> >HiiDbNotify.Registration
> -                                                              );
> -  if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
> -    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
> -    ASSERT (FALSE);
> -  }
> -
> -  //
> -  // Install protocol notification if HII string protocol is installed.
> -  //
> -  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> -                                                                  &gEfiHiiStringProtocolGuid,
> -                                                                  TPL_CALLBACK,
> -                                                                  HiiStringProtocolInstalled,
> -                                                                  NULL,
> -                                                                  &mRedfishPlatformConfigPrivate-
> >HiiStringNotify.Registration
> -                                                                  );
> -  if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
> {
> -    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiStringProtocolGuid\n", __FUNCTION__));
> -    ASSERT (FALSE);
> -  }
> -
> -  //
> -  // Install protocol notification if regular expression protocol is installed.
> -  //
> -  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> -                                                              &gEfiRegularExpressionProtocolGuid,
> -                                                              TPL_CALLBACK,
> -                                                              RegexProtocolInstalled,
> -                                                              NULL,
> -                                                              &mRedfishPlatformConfigPrivate-
> >RegexNotify.Registration
> -                                                              );
> -  if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
> -    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
> -    ASSERT (FALSE);
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> +/** @file
> +
> +  The implementation of EDKII Redfidh Platform Config Protocol.
> +
> +  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "RedfishPlatformConfigDxe.h"
> +#include "RedfishPlatformConfigImpl.h"
> +
> +REDFISH_PLATFORM_CONFIG_PRIVATE *mRedfishPlatformConfigPrivate =
> NULL;
> +
> +
> +/**
> +  Zero extend integer/boolean to UINT64 for comparing.
> +
> +  @param  Value                  HII Value to be converted.
> +
> +**/
> +UINT64
> +ExtendHiiValueToU64 (
> +  IN HII_STATEMENT_VALUE    *Value
> +  )
> +{
> +  UINT64  Temp;
> +
> +  Temp = 0;
> +  switch (Value->Type) {
> +  case EFI_IFR_TYPE_NUM_SIZE_8:
> +    Temp = Value->Value.u8;
> +    break;
> +
> +  case EFI_IFR_TYPE_NUM_SIZE_16:
> +    Temp = Value->Value.u16;
> +    break;
> +
> +  case EFI_IFR_TYPE_NUM_SIZE_32:
> +    Temp = Value->Value.u32;
> +    break;
> +
> +  case EFI_IFR_TYPE_BOOLEAN:
> +    Temp = Value->Value.b;
> +    break;
> +
> +  case EFI_IFR_TYPE_TIME:
> +  case EFI_IFR_TYPE_DATE:
> +  default:
> +    break;
> +  }
> +
> +  return Temp;
> +}
> +
> +/**
> +  Set value of a data element in an Array by its Index in ordered list buffer.
> +
> +  @param  Array                  The data array.
> +  @param  Type                   Type of the data in this array.
> +  @param  Index                  Zero based index for data in this array.
> +  @param  Value                  The value to be set.
> +
> +**/
> +VOID
> +OrderedListSetArrayData (
> +  IN VOID                     *Array,
> +  IN UINT8                    Type,
> +  IN UINTN                    Index,
> +  IN UINT64                   Value
> +  )
> +{
> +
> +  ASSERT (Array != NULL);
> +
> +  switch (Type) {
> +  case EFI_IFR_TYPE_NUM_SIZE_8:
> +    *(((UINT8 *) Array) + Index) = (UINT8) Value;
> +    break;
> +
> +  case EFI_IFR_TYPE_NUM_SIZE_16:
> +    *(((UINT16 *) Array) + Index) = (UINT16) Value;
> +    break;
> +
> +  case EFI_IFR_TYPE_NUM_SIZE_32:
> +    *(((UINT32 *) Array) + Index) = (UINT32) Value;
> +    break;
> +
> +  case EFI_IFR_TYPE_NUM_SIZE_64:
> +    *(((UINT64 *) Array) + Index) = (UINT64) Value;
> +    break;
> +
> +  default:
> +    break;
> +  }
> +}
> +
> +/**
> +  Return data element in an Array by its Index in ordered list array buffer.
> +
> +  @param  Array                  The data array.
> +  @param  Type                   Type of the data in this array.
> +  @param  Index                  Zero based index for data in this array.
> +
> +  @retval Value                  The data to be returned
> +
> +**/
> +UINT64
> +OrderedListGetArrayData (
> +  IN VOID                     *Array,
> +  IN UINT8                    Type,
> +  IN UINTN                    Index
> +  )
> +{
> +  UINT64 Data;
> +
> +  ASSERT (Array != NULL);
> +
> +  Data = 0;
> +  switch (Type) {
> +  case EFI_IFR_TYPE_NUM_SIZE_8:
> +    Data = (UINT64) *(((UINT8 *) Array) + Index);
> +    break;
> +
> +  case EFI_IFR_TYPE_NUM_SIZE_16:
> +    Data = (UINT64) *(((UINT16 *) Array) + Index);
> +    break;
> +
> +  case EFI_IFR_TYPE_NUM_SIZE_32:
> +    Data = (UINT64) *(((UINT32 *) Array) + Index);
> +    break;
> +
> +  case EFI_IFR_TYPE_NUM_SIZE_64:
> +    Data = (UINT64) *(((UINT64 *) Array) + Index);
> +    break;
> +
> +  default:
> +    break;
> +  }
> +
> +  return Data;
> +}
> +
> +/**
> +  Find string ID of option if its value equals to given value.
> +
> +  @param[in]  HiiStatement  Statement to search.
> +  @param[in]  Value         Target value.
> +
> +  @retval EFI_SUCCESS       HII value is returned successfully.
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STRING_ID
> +OrderedListOptionValueToStringId (
> +  IN  HII_STATEMENT *HiiStatement,
> +  IN  UINT64        Value
> +  )
> +{
> +  LIST_ENTRY            *Link;
> +  HII_QUESTION_OPTION   *Option;
> +  BOOLEAN               Found;
> +  UINT64                CurrentValue;
> +
> +  if (HiiStatement == NULL) {
> +    return 0;
> +  }
> +
> +  if (HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
> +    return 0;
> +  }
> +
> +  if (IsListEmpty (&HiiStatement->OptionListHead)) {
> +    return 0;
> +  }
> +
> +  Found = FALSE;
> +  Link = GetFirstNode (&HiiStatement->OptionListHead);
> +  while (!IsNull (&HiiStatement->OptionListHead, Link)) {
> +    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> +    CurrentValue = ExtendHiiValueToU64 (&Option->Value);
> +    if (Value == CurrentValue) {
> +      return Option->Text;
> +    }
> +
> +    Link = GetNextNode (&HiiStatement->OptionListHead, Link);
> +  }
> +
> +  return 0;
> +}
> +
> +/**
> +  Compare two value in HII statement format.
> +
> +  @param[in]  Value1        Firt value to compare.
> +  @param[in]  Value2        Second value to be compared.
> +
> +  @retval INTN          0 is retuned when two values are equal.
> +                        1 is returned when first value is greater than second value.
> +                        -1 is returned when second value is greater than first value.
> +
> +**/
> +INTN
> +CompareHiiStatementValue (
> +  IN HII_STATEMENT_VALUE  *Value1,
> +  IN HII_STATEMENT_VALUE  *Value2
> +  )
> +{
> +  INTN Result;
> +  UINT64 Data1;
> +  UINT64 Data2;
> +
> +  if (Value1 == NULL || Value2 == NULL) {
> +    return -1;
> +  }
> +
> +  switch (Value1->Type) {
> +    case EFI_IFR_TYPE_NUM_SIZE_8:
> +      Data1 = Value1->Value.u8;
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_16:
> +      Data1 = Value1->Value.u16;
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_32:
> +      Data1 = Value1->Value.u32;
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_64:
> +      Data1 = Value1->Value.u64;
> +      break;
> +    case EFI_IFR_TYPE_BOOLEAN:
> +      Data1 = (Value1->Value.b ? 1 : 0);
> +      break;
> +    default:
> +      return -1;
> +  }
> +
> +  switch (Value2->Type) {
> +    case EFI_IFR_TYPE_NUM_SIZE_8:
> +      Data2 = Value2->Value.u8;
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_16:
> +      Data2 = Value2->Value.u16;
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_32:
> +      Data2 = Value2->Value.u32;
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_64:
> +      Data2 = Value2->Value.u64;
> +      break;
> +    case EFI_IFR_TYPE_BOOLEAN:
> +      Data2 = (Value2->Value.b ? 1 : 0);
> +      break;
> +    default:
> +      return -1;
> +  }
> +
> +  Result = (Data1 == Data2 ? 0 : (Data1 > Data2 ? 1 : -1));
> +
> +  return Result;
> +}
> +
> +/**
> +  Convert HII value to the string in HII one-of opcode.
> +
> +  @param[in]  Statement     Statement private instance
> +
> +  @retval EFI_STRING_ID     The string ID in HII database.
> +                            0 is returned when something goes wrong.
> +
> +**/
> +EFI_STRING_ID
> +HiiValueToOneOfOptionStringId (
> +  IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement
> +  )
> +{
> +  LIST_ENTRY            *Link;
> +  HII_QUESTION_OPTION   *Option;
> +
> +  if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
> +    return 0;
> +  }
> +
> +  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> +    return 0;
> +  }
> +
> +  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> +  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> +    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> +    if (CompareHiiStatementValue (&Statement->HiiStatement->Value,
> &Option->Value) == 0) {
> +      return Option->Text;
> +    }
> +
> +    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
> +  }
> +
> +  return 0;
> +}
> +
> +/**
> +  Convert HII string to the value in HII one-of opcode.
> +
> +  @param[in]  Statement     Statement private instance
> +  @param[in]  Schema        Schema string
> +  @param[in]  HiiString     Input string
> +  @param[out] Value         Value returned
> +
> +  @retval EFI_SUCCESS       HII value is returned successfully.
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +HiiStringToOneOfOptionValue (
> +  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
> +  IN  CHAR8                           *Schema,
> +  IN  EFI_STRING                      HiiString,
> +  OUT HII_STATEMENT_VALUE             *Value
> +  )
> +{
> +  LIST_ENTRY            *Link;
> +  HII_QUESTION_OPTION   *Option;
> +  EFI_STRING            TmpString;
> +  BOOLEAN               Found;
> +
> +  if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Statement->HiiStatement->Operand != EFI_IFR_ONE_OF_OP) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Found = FALSE;
> +  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> +  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> +    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> +    TmpString = HiiGetRedfishString (Statement->ParentForm-
> >ParentFormset->HiiHandle, Schema, Option->Text);
> +    if (TmpString != NULL) {
> +      if (StrCmp (TmpString, HiiString) == 0) {
> +        CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE));
> +        Found = TRUE;
> +      }
> +      FreePool (TmpString);
> +    }
> +
> +    if (Found) {
> +      return EFI_SUCCESS;
> +    }
> +
> +    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  Convert HII value to numeric value in Redfish format.
> +
> +  @param[in]  Value         Value to be converted.
> +  @param[out] RedfishValue  Value in Redfish format.
> +
> +  @retval EFI_SUCCESS       Redfish value is returned successfully.
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +HiiValueToRedfishNumeric (
> +  IN  HII_STATEMENT_VALUE  *Value,
> +  OUT EDKII_REDFISH_VALUE  *RedfishValue
> +  )
> +{
> +  if (Value == NULL || RedfishValue == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  switch (Value->Type) {
> +    case EFI_IFR_TYPE_NUM_SIZE_8:
> +      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> +      RedfishValue->Value.Integer = (INT64)Value->Value.u8;
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_16:
> +      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> +      RedfishValue->Value.Integer = (INT64)Value->Value.u16;
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_32:
> +      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> +      RedfishValue->Value.Integer = (INT64)Value->Value.u32;
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_64:
> +      RedfishValue->Type = REDFISH_VALUE_TYPE_INTEGER;
> +      RedfishValue->Value.Integer = (INT64)Value->Value.u64;
> +      break;
> +    case EFI_IFR_TYPE_BOOLEAN:
> +      RedfishValue->Type = REDFISH_VALUE_TYPE_BOOLEAN;
> +      RedfishValue->Value.Boolean = Value->Value.b;
> +      break;
> +    default:
> +      RedfishValue->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Convert numeric value in Redfish format to HII value.
> +
> +  @param[in]   RedfishValue  Value in Redfish format to be converted.
> +  @param[out]  Value         HII value returned.
> +
> +  @retval EFI_SUCCESS       HII value is returned successfully.
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +RedfishNumericToHiiValue (
> +  IN  EDKII_REDFISH_VALUE  *RedfishValue,
> +  OUT HII_STATEMENT_VALUE  *Value
> +  )
> +{
> +  if (Value == NULL || RedfishValue == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  switch (RedfishValue->Type) {
> +    case REDFISH_VALUE_TYPE_INTEGER:
> +      Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
> +      Value->Value.u64 = (UINT64)RedfishValue->Value.Integer;
> +      break;
> +    case REDFISH_VALUE_TYPE_BOOLEAN:
> +      Value->Type = EFI_IFR_TYPE_BOOLEAN;
> +      Value->Value.b = RedfishValue->Value.Boolean;
> +      break;
> +    default:
> +      Value->Type = EFI_IFR_TYPE_UNDEFINED;
> +      break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Dump the value in ordered list buffer.
> +
> +  @param[in]   OrderedListStatement Ordered list statement.
> +
> +**/
> +VOID
> +DumpOrderedListValue (
> +  IN  HII_STATEMENT *OrderedListStatement
> +  )
> +{
> +  UINT8 *Value8;
> +  UINT16 *Value16;
> +  UINT32 *Value32;
> +  UINT64 *Value64;
> +  UINTN  Count;
> +  UINTN  Index;
> +
> +  if (OrderedListStatement == NULL || OrderedListStatement->Operand !=
> EFI_IFR_ORDERED_LIST_OP) {
> +    return;
> +  }
> +
> +  DEBUG ((DEBUG_ERROR, "Value.Type= 0x%x\n", OrderedListStatement-
> >Value.Type));
> +  DEBUG ((DEBUG_ERROR, "Value.BufferValueType= 0x%x\n",
> OrderedListStatement->Value.BufferValueType));
> +  DEBUG ((DEBUG_ERROR, "Value.BufferLen= 0x%x\n",
> OrderedListStatement->Value.BufferLen));
> +  DEBUG ((DEBUG_ERROR, "Value.Buffer= 0x%x\n", OrderedListStatement-
> >Value.Buffer));
> +  DEBUG ((DEBUG_ERROR, "Value.MaxContainers= 0x%x\n",
> OrderedListStatement->ExtraData.OrderListData.MaxContainers));
> +  DEBUG ((DEBUG_ERROR, "StorageWidth= 0x%x\n",
> OrderedListStatement->StorageWidth));
> +
> +  if (OrderedListStatement->Value.Buffer == NULL) {
> +    return;
> +  }
> +
> +  Value8 = NULL;
> +  Value16 = NULL;
> +  Value32 = NULL;
> +  Value64 = NULL;
> +  Count = 0;
> +
> +  switch (OrderedListStatement->Value.BufferValueType) {
> +    case EFI_IFR_TYPE_NUM_SIZE_8:
> +      Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
> +      Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
> +      for (Index = 0; Index < Count; Index++) {
> +        DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
> +      }
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_16:
> +      Value16 = (UINT16 *)OrderedListStatement->Value.Buffer;
> +      Count = OrderedListStatement->StorageWidth / sizeof (UINT16);
> +      for (Index = 0; Index < Count; Index++) {
> +        DEBUG ((DEBUG_ERROR, "%d ", Value16[Index]));
> +      }
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_32:
> +      Value32 = (UINT32 *)OrderedListStatement->Value.Buffer;
> +      Count = OrderedListStatement->StorageWidth / sizeof (UINT32);
> +      for (Index = 0; Index < Count; Index++) {
> +        DEBUG ((DEBUG_ERROR, "%d ", Value32[Index]));
> +      }
> +      break;
> +    case EFI_IFR_TYPE_NUM_SIZE_64:
> +      Value64 = (UINT64 *)OrderedListStatement->Value.Buffer;
> +      Count = OrderedListStatement->StorageWidth / sizeof (UINT64);
> +      for (Index = 0; Index < Count; Index++) {
> +        DEBUG ((DEBUG_ERROR, "%d ", Value64[Index]));
> +      }
> +      break;
> +    default:
> +      Value8 = (UINT8 *)OrderedListStatement->Value.Buffer;
> +      Count = OrderedListStatement->StorageWidth / sizeof (UINT8);
> +      for (Index = 0; Index < Count; Index++) {
> +        DEBUG ((DEBUG_ERROR, "%d ", Value8[Index]));
> +      }
> +      break;
> +  }
> +
> +  DEBUG ((DEBUG_ERROR, "\n"));
> +}
> +
> +/**
> +  Convert HII value to the string in HII ordered list opcode. It's caller's
> +  responsibility to free returned buffer using FreePool().
> +
> +  @param[in]  Statement     Statement private instance
> +  @param[out] ReturnSize    The size of returned array
> +
> +  @retval EFI_STRING_ID     The string ID array for options in ordered list.
> +
> +**/
> +EFI_STRING_ID *
> +HiiValueToOrderedListOptionStringId (
> +  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
> +  OUT UINTN                                     *ReturnSize
> +  )
> +{
> +  LIST_ENTRY            *Link;
> +  HII_QUESTION_OPTION   *Option;
> +  UINTN                 OptionCount;
> +  EFI_STRING_ID         *ReturnedArray;
> +  UINTN                 Index;
> +  UINT64                Value;
> +
> +  if (Statement == NULL || ReturnSize == NULL) {
> +    return NULL;
> +  }
> +
> +  *ReturnSize = 0;
> +
> +  if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
> +    return NULL;
> +  }
> +
> +  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> +    return NULL;
> +  }
> +
> +  DEBUG_CODE (
> +    DumpOrderedListValue (Statement->HiiStatement);
> +  );
> +
> +  OptionCount = 0;
> +  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> +  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> +    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> +    ++OptionCount;
> +
> +    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
> +  }
> +
> +  *ReturnSize = OptionCount;
> +  ReturnedArray = AllocatePool (sizeof (EFI_STRING_ID) * OptionCount);
> +  if (ReturnedArray == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> +    *ReturnSize  = 0;
> +    return NULL;
> +  }
> +
> +  for (Index = 0; Index < OptionCount; Index++) {
> +    Value = OrderedListGetArrayData (Statement->HiiStatement-
> >Value.Buffer, Statement->HiiStatement->Value.BufferValueType, Index);
> +    ReturnedArray[Index] = OrderedListOptionValueToStringId (Statement-
> >HiiStatement, Value);
> +  }
> +
> +  return ReturnedArray;
> +}
> +
> +/**
> +  Convert HII string to the value in HII ordered list opcode.
> +
> +  @param[in]  Statement     Statement private instance
> +  @param[in]  Schema        Schema string
> +  @param[in]  HiiString     Input string
> +  @param[out] Value         Value returned
> +
> +  @retval EFI_SUCCESS       HII value is returned successfully.
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +HiiStringToOrderedListOptionValue (
> +  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement,
> +  IN  CHAR8                           *Schema,
> +  IN  EFI_STRING                      HiiString,
> +  OUT UINT64                          *Value
> +  )
> +{
> +  LIST_ENTRY            *Link;
> +  HII_QUESTION_OPTION   *Option;
> +  EFI_STRING            TmpString;
> +  BOOLEAN               Found;
> +
> +  if (Statement == NULL || IS_EMPTY_STRING (HiiString) || Value == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *Value = 0;
> +
> +  if (Statement->HiiStatement->Operand != EFI_IFR_ORDERED_LIST_OP) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  if (IsListEmpty (&Statement->HiiStatement->OptionListHead)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Found = FALSE;
> +  Link = GetFirstNode (&Statement->HiiStatement->OptionListHead);
> +  while (!IsNull (&Statement->HiiStatement->OptionListHead, Link)) {
> +    Option = HII_QUESTION_OPTION_FROM_LINK (Link);
> +
> +    TmpString = HiiGetRedfishString (Statement->ParentForm-
> >ParentFormset->HiiHandle, Schema, Option->Text);
> +    if (TmpString != NULL) {
> +      if (StrCmp (TmpString, HiiString) == 0) {
> +        *Value = ExtendHiiValueToU64 (&Option->Value);
> +        Found = TRUE;
> +      }
> +      FreePool (TmpString);
> +    }
> +
> +    if (Found) {
> +      return EFI_SUCCESS;
> +    }
> +
> +    Link = GetNextNode (&Statement->HiiStatement->OptionListHead, Link);
> +  }
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  Convert input ascii string to unicode string. It's caller's
> +  responsibility to free returned buffer using FreePool().
> +
> +  @param[in]  AsciiString     Ascii string to be converted.
> +
> +  @retval CHAR16 *            Unicode string on return.
> +
> +**/
> +EFI_STRING
> +StrToUnicodeStr (
> +  IN  CHAR8 *AsciiString
> + )
> +{
> +  UINTN       StringLen;
> +  EFI_STRING  Buffer;
> +  EFI_STATUS  Status;
> +
> +  if (AsciiString == NULL || AsciiString[0] == '\0') {
> +    return NULL;
> +  }
> +
> +  StringLen = AsciiStrLen (AsciiString) + 1;
> +  Buffer = AllocatePool (StringLen * sizeof (CHAR16));
> +  if (Buffer == NULL) {
> +    return NULL;
> +  }
> +
> +  Status = AsciiStrToUnicodeStrS (AsciiString, Buffer, StringLen);
> +  if (EFI_ERROR (Status)) {
> +    FreePool (Buffer);
> +    return NULL;
> +  }
> +
> +  return Buffer;
> +}
> +
> +/**
> +  Return the full Redfish schema string from the given Schema and Version.
> +
> +  Returned schema string is: Schema + '.' + Version
> +
> +  @param[in]  Schema      Schema string
> +  @param[in]  Version     Schema version string
> +
> +  @retval CHAR8 *         Schema string. NULL when errors occur.
> +
> +**/
> +CHAR8 *
> +GetFullSchemaString (
> +  IN CHAR8   *Schema,
> +  IN CHAR8  *Version
> +  )
> +{
> +  UINTN Size;
> +  CHAR8 *FullName;
> +
> +  if (IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING (Version)) {
> +    return NULL;
> +  }
> +
> +  Size = AsciiStrSize(CONFIGURE_LANGUAGE_PREFIX) + AsciiStrSize
> (Schema) + AsciiStrSize (Version);
> +
> +  FullName = AllocatePool (Size);
> +  if (FullName == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a, out-of-resource\n", __FUNCTION__));
> +    return NULL;
> +  }
> +
> +  AsciiSPrint (FullName, Size, "%a%a.%a", CONFIGURE_LANGUAGE_PREFIX,
> Schema, Version);
> +
> +  return FullName;
> +}
> +
> +/**
> +  Common implementation to get statement private instance.
> +
> +  @param[in]   RedfishPlatformConfigPrivate   Private instance.
> +  @param[in]   Schema                         Redfish schema string.
> +  @param[in]   ConfigureLang                  Configure language that refers to this
> statement.
> +  @param[out]  Statement                      Statement instance
> +
> +  @retval EFI_SUCCESS       HII value is returned successfully.
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +RedfishPlatformConfigGetStatementCommon (
> +  IN     REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate,
> +  IN     CHAR8                                      *Schema,
> +  IN     EFI_STRING                                 ConfigureLang,
> +  OUT    REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE  **Statement
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
> +
> +  if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || Statement == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *Statement = NULL;
> +
> +  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> +  if (TargetStatement == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
> given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Find current HII question value.
> +  //
> +  Status = GetQuestionValue (
> +             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
> +             TargetStatement->ParentForm->HiiForm,
> +             TargetStatement->HiiStatement,
> +             GetSetValueWithHiiDriver
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, failed to get question current value: %r\n",
> __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +
> +  if (TargetStatement->HiiStatement->Value.Type ==
> EFI_IFR_TYPE_UNDEFINED) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Return Value.
> +  //
> +  *Statement = TargetStatement;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Get Redfish value with the given Schema and Configure Language.
> +
> +  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> +  @param[in]   Schema              The Redfish schema to query.
> +  @param[in]   Version             The Redfish version to query.
> +  @param[in]   ConfigureLang       The target value which match this configure
> Language.
> +  @param[out]  Value               The returned value.
> +
> +  @retval EFI_SUCCESS              Value is returned successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPlatformConfigProtocolGetValue (
> +  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> +  IN     CHAR8                                  *Schema,
> +  IN     CHAR8                                  *Version,
> +  IN     EFI_STRING                             ConfigureLang,
> +  OUT    EDKII_REDFISH_VALUE                    *Value
> +  )
> +{
> +  EFI_STATUS                                Status;
> +  REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
> +  EFI_STRING_ID                             StringId;
> +  EFI_STRING_ID                             *StringIdArray;
> +  CHAR8                                     *FullSchema;
> +  EFI_STRING                                HiiString;
> +  UINTN                                     Count;
> +  UINTN                                     Index;
> +
> +  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang) || Value == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> +  Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> +  Value->ArrayCount = 0;
> +  Count = 0;
> +  FullSchema = NULL;
> +  HiiString = NULL;
> +  StringIdArray = NULL;
> +
> +  FullSchema = GetFullSchemaString (Schema, Version);
> +  if (FullSchema == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Status = RedfishPlatformConfigGetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang,
> &TargetStatement);
> +  if (EFI_ERROR (Status)) {
> +    goto RELEASE_RESOURCE;
> +  }
> +
> +  switch (TargetStatement->HiiStatement->Operand) {
> +    case EFI_IFR_ONE_OF_OP:
> +      StringId = HiiValueToOneOfOptionStringId (TargetStatement);
> +      if (StringId == 0) {
> +        ASSERT (FALSE);
> +        Status = EFI_DEVICE_ERROR;
> +        goto RELEASE_RESOURCE;
> +      }
> +
> +      Value->Value.Buffer = HiiGetRedfishAsciiString (TargetStatement-
> >ParentForm->ParentFormset->HiiHandle, FullSchema, StringId);
> +      if (Value->Value.Buffer == NULL) {
> +        Status = EFI_OUT_OF_RESOURCES;
> +        goto RELEASE_RESOURCE;
> +      }
> +
> +      Value->Type = REDFISH_VALUE_TYPE_STRING;
> +      break;
> +    case EFI_IFR_STRING_OP:
> +      if (TargetStatement->HiiStatement->Value.Type !=
> EFI_IFR_TYPE_STRING) {
> +        ASSERT (FALSE);
> +        Status = EFI_DEVICE_ERROR;
> +        goto RELEASE_RESOURCE;
> +      }
> +
> +      Value->Type = REDFISH_VALUE_TYPE_STRING;
> +      Value->Value.Buffer = AllocatePool (StrLen ((CHAR16
> *)TargetStatement->HiiStatement->Value.Buffer) + 1);
> +      UnicodeStrToAsciiStrS ((CHAR16 *)TargetStatement->HiiStatement-
> >Value.Buffer, Value->Value.Buffer, StrLen ((CHAR16 *)TargetStatement-
> >HiiStatement->Value.Buffer) + 1);
> +      break;
> +    case EFI_IFR_CHECKBOX_OP:
> +    case EFI_IFR_NUMERIC_OP:
> +      Status = HiiValueToRedfishNumeric (&TargetStatement->HiiStatement-
> >Value, Value);
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((DEBUG_ERROR, "%a, failed to convert HII value to Redfish
> value: %r\n", __FUNCTION__, Status));
> +        goto RELEASE_RESOURCE;
> +      }
> +      break;
> +    case EFI_IFR_ACTION_OP:
> +      if (TargetStatement->HiiStatement->Value.Type !=
> EFI_IFR_TYPE_ACTION) {
> +        ASSERT (FALSE);
> +        Status = EFI_DEVICE_ERROR;
> +        goto RELEASE_RESOURCE;
> +      }
> +
> +      //
> +      // Action has no value. Just return unknown type.
> +      //
> +      Value->Type = REDFISH_VALUE_TYPE_UNKNOWN;
> +      break;
> +    case EFI_IFR_ORDERED_LIST_OP:
> +      StringIdArray = HiiValueToOrderedListOptionStringId (TargetStatement,
> &Count);
> +      if (StringIdArray == NULL) {
> +        ASSERT (FALSE);
> +        Status = EFI_DEVICE_ERROR;
> +        goto RELEASE_RESOURCE;
> +      }
> +
> +      Value->Value.StringArray = AllocatePool (sizeof (CHAR8 *) * Count);
> +      if (Value->Value.StringArray == NULL) {
> +        ASSERT (FALSE);
> +        Status = EFI_OUT_OF_RESOURCES;
> +        goto RELEASE_RESOURCE;
> +      }
> +
> +      for (Index = 0; Index < Count; Index++) {
> +        ASSERT (StringIdArray[Index] != 0);
> +        Value->Value.StringArray[Index] = HiiGetRedfishAsciiString
> (TargetStatement->ParentForm->ParentFormset->HiiHandle, FullSchema,
> StringIdArray[Index]);
> +      }
> +
> +      Value->ArrayCount = Count;
> +      Value->Type = REDFISH_VALUE_TYPE_STRING_ARRAY;
> +      break;
> +    default:
> +      DEBUG ((DEBUG_ERROR, "%a, catch unsupported type: 0x%x! Please
> contact with author if we need to support this type.\n", __FUNCTION__,
> TargetStatement->HiiStatement->Operand));
> +      ASSERT (FALSE);
> +      Status = EFI_UNSUPPORTED;
> +      goto RELEASE_RESOURCE;
> +  }
> +
> +RELEASE_RESOURCE:
> +
> +  if (FullSchema != NULL) {
> +    FreePool (FullSchema);
> +  }
> +
> +  if (HiiString != NULL) {
> +    FreePool (HiiString);
> +  }
> +
> +  if (StringIdArray != NULL) {
> +    FreePool (StringIdArray);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Function to save question value into HII database.
> +
> +  @param[in]   HiiFormset       HII form-set instance
> +  @param[in]   HiiForm          HII form instance
> +  @param[in]   HiiStatement     HII statement that keeps new value.
> +  @param[in]   Value            New value to applyu.
> +
> +  @retval EFI_SUCCESS       HII value is returned successfully.
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +RedfishPlatformConfigSaveQuestionValue (
> +  IN  HII_FORMSET         *HiiFormset,
> +  IN  HII_FORM            *HiiForm,
> +  IN  HII_STATEMENT       *HiiStatement,
> +  IN  HII_STATEMENT_VALUE *Value
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  if (HiiFormset == NULL || HiiForm == NULL || HiiStatement == NULL ||
> Value == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = SetQuestionValue (
> +             HiiFormset,
> +             HiiForm,
> +             HiiStatement,
> +             Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, failed to set question value: %r\n",
> __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  Status = SubmitForm (HiiFormset, HiiForm);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, failed to submit form: %r\n",
> __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Common implementation to set statement private instance.
> +
> +  @param[in]   RedfishPlatformConfigPrivate   Private instance.
> +  @param[in]   Schema                         Redfish schema string.
> +  @param[in]   ConfigureLang                  Configure language that refers to this
> statement.
> +  @param[in]   Statement                      Statement instance
> +
> +  @retval EFI_SUCCESS       HII value is returned successfully.
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +RedfishPlatformConfigSetStatementCommon (
> +  IN     REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate,
> +  IN     CHAR8                            *Schema,
> +  IN     EFI_STRING                       ConfigureLang,
> +  IN     HII_STATEMENT_VALUE              *StatementValue
> +  )
> +{
> +  EFI_STATUS                                Status;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *TargetStatement;
> +  EFI_STRING                                TempBuffer;
> +  UINT8                                     *StringArray;
> +  UINTN                                     Index;
> +  UINT64                                    Value;
> +  CHAR8                                     **CharArray;
> +
> +  if (RedfishPlatformConfigPrivate == NULL || IS_EMPTY_STRING (Schema)
> || IS_EMPTY_STRING (ConfigureLang) || StatementValue == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TempBuffer = NULL;
> +  StringArray = NULL;
> +
> +  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  TargetStatement = GetStatementPrivateByConfigureLang
> (&RedfishPlatformConfigPrivate->FormsetList, Schema, ConfigureLang);
> +  if (TargetStatement == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a, No match HII statement is found by the
> given %s in schema %a\n", __FUNCTION__, ConfigureLang, Schema));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (StatementValue->Type != TargetStatement->HiiStatement-
> >Value.Type) {
> +    //
> +    // We treat one-of type as string in Redfish. But one-of statement is not
> +    // in string format from HII point of view. Do a patch here.
> +    //
> +    if (TargetStatement->HiiStatement->Operand == EFI_IFR_ONE_OF_OP
> && StatementValue->Type == EFI_IFR_TYPE_STRING) {
> +
> +      TempBuffer = StrToUnicodeStr ((CHAR8 *)StatementValue->Buffer);
> +      if (TempBuffer == NULL) {
> +        return EFI_OUT_OF_RESOURCES;
> +      }
> +      FreePool (StatementValue->Buffer);
> +      StatementValue->Buffer = NULL;
> +      StatementValue->BufferLen = 0;
> +
> +      Status = HiiStringToOneOfOptionValue (TargetStatement, Schema,
> TempBuffer, StatementValue);
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((DEBUG_ERROR, "%a, failed to find option value by the given
> %s\n", __FUNCTION__, TempBuffer));
> +        FreePool (TempBuffer);
> +        return EFI_NOT_FOUND;
> +      }
> +
> +      FreePool (TempBuffer);
> +    } else if (TargetStatement->HiiStatement->Operand ==
> EFI_IFR_ORDERED_LIST_OP && StatementValue->Type ==
> EFI_IFR_TYPE_STRING) {
> +      //
> +      // We treat ordered list type as string in Redfish. But ordered list
> statement is not
> +      // in string format from HII point of view. Do a patch here.
> +      //
> +      StringArray = AllocateZeroPool (TargetStatement->HiiStatement-
> >StorageWidth);
> +      if (StringArray == NULL) {
> +        return EFI_OUT_OF_RESOURCES;
> +      }
> +
> +      //
> +      // Arrage new option order from input string array
> +      //
> +      CharArray = (CHAR8 **)StatementValue->Buffer;
> +      for (Index = 0; Index < StatementValue->BufferLen; Index++) {
> +        TempBuffer = StrToUnicodeStr (CharArray[Index]);
> +        if (TempBuffer == NULL) {
> +          return EFI_OUT_OF_RESOURCES;
> +        }
> +
> +        Status = HiiStringToOrderedListOptionValue (TargetStatement, Schema,
> TempBuffer, &Value);
> +        if (EFI_ERROR (Status)) {
> +          ASSERT (FALSE);
> +          continue;
> +        }
> +        FreePool (TempBuffer);
> +        OrderedListSetArrayData (StringArray, TargetStatement->HiiStatement-
> >Value.BufferValueType, Index, Value);
> +      }
> +
> +      StatementValue->Type = EFI_IFR_TYPE_BUFFER;
> +      StatementValue->Buffer = StringArray;
> +      StatementValue->BufferLen = TargetStatement->HiiStatement-
> >StorageWidth;
> +      StatementValue->BufferValueType = TargetStatement->HiiStatement-
> >Value.BufferValueType;
> +    } else if (TargetStatement->HiiStatement->Operand ==
> EFI_IFR_NUMERIC_OP && StatementValue->Type ==
> EFI_IFR_TYPE_NUM_SIZE_64) {
> +      //
> +      // Redfish only has numeric value type and it does not care about the
> value size.
> +      // Do a patch here so we have proper value size applied.
> +      //
> +      StatementValue->Type = TargetStatement->HiiStatement->Value.Type;
> +    } else {
> +      DEBUG ((DEBUG_ERROR, "%a, catch value type mismatch! input type:
> 0x%x but target value type: 0x%x\n", __FUNCTION__, StatementValue-
> >Type, TargetStatement->HiiStatement->Value.Type));
> +      ASSERT (FALSE);
> +    }
> +  }
> +
> +  Status = RedfishPlatformConfigSaveQuestionValue (
> +             TargetStatement->ParentForm->ParentFormset->HiiFormSet,
> +             TargetStatement->ParentForm->HiiForm,
> +             TargetStatement->HiiStatement,
> +             StatementValue
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, failed to save question value: %r\n",
> __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Set Redfish value with the given Schema and Configure Language.
> +
> +  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> +  @param[in]   Schema              The Redfish schema to query.
> +  @param[in]   Version             The Redfish version to query.
> +  @param[in]   ConfigureLang       The target value which match this configure
> Language.
> +  @param[in]   Value               The value to set.
> +
> +  @retval EFI_SUCCESS              Value is returned successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPlatformConfigProtocolSetValue (
> +  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> +  IN     CHAR8                                  *Schema,
> +  IN     CHAR8                                  *Version,
> +  IN     EFI_STRING                             ConfigureLang,
> +  IN     EDKII_REDFISH_VALUE                    Value
> +  )
> +{
> +  EFI_STATUS                                Status;
> +  REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate;
> +  CHAR8                                     *FullSchema;
> +  HII_STATEMENT_VALUE                       NewValue;
> +
> +  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || IS_EMPTY_STRING (ConfigureLang)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Value.Type == REDFISH_VALUE_TYPE_UNKNOWN || Value.Type >=
> REDFISH_VALUE_TYPE_MAX) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> +  FullSchema = NULL;
> +
> +  FullSchema = GetFullSchemaString (Schema, Version);
> +  if (FullSchema == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  ZeroMem (&NewValue, sizeof (HII_STATEMENT_VALUE));
> +
> +  switch (Value.Type) {
> +    case REDFISH_VALUE_TYPE_INTEGER:
> +    case REDFISH_VALUE_TYPE_BOOLEAN:
> +      Status = RedfishNumericToHiiValue (&Value, &NewValue);
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((DEBUG_ERROR, "%a, failed to convert Redfish value to Hii
> value: %r\n", __FUNCTION__, Status));
> +        goto RELEASE_RESOURCE;
> +      }
> +      break;
> +    case REDFISH_VALUE_TYPE_STRING:
> +      NewValue.Type = EFI_IFR_TYPE_STRING;
> +      NewValue.BufferLen = (UINT16)AsciiStrSize (Value.Value.Buffer);
> +      NewValue.Buffer = AllocateCopyPool (NewValue.BufferLen,
> Value.Value.Buffer);
> +      if (NewValue.Buffer == NULL) {
> +        Status = EFI_OUT_OF_RESOURCES;
> +        goto RELEASE_RESOURCE;
> +      }
> +      break;
> +    case REDFISH_VALUE_TYPE_STRING_ARRAY:
> +      NewValue.Type = EFI_IFR_TYPE_STRING;
> +      NewValue.BufferLen = (UINT16)Value.ArrayCount;
> +      NewValue.Buffer = (UINT8 *)Value.Value.StringArray;
> +      break;
> +    default:
> +      ASSERT (FALSE);
> +      break;
> +  }
> +
> +  Status = RedfishPlatformConfigSetStatementCommon
> (RedfishPlatformConfigPrivate, FullSchema, ConfigureLang, &NewValue);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, failed to set value to statement: %r\n",
> __FUNCTION__, Status));
> +  }
> +
> +RELEASE_RESOURCE:
> +
> +  if (FullSchema != NULL) {
> +    FreePool (FullSchema);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Get the list of Configure Language from platform configuration by the
> given Schema and RegexPattern.
> +
> +  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> +  @param[in]   Schema              The Redfish schema to query.
> +  @param[in]   Version             The Redfish version to query.
> +  @param[in]   RegexPattern        The target Configure Language pattern.
> This is used for regular expression matching.
> +  @param[out]  ConfigureLangList   The list of Configure Language.
> +  @param[out]  Count               The number of Configure Language in
> ConfigureLangList.
> +
> +  @retval EFI_SUCCESS              ConfigureLangList is returned successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPlatformConfigProtocolGetConfigureLang (
> +  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL *This,
> +  IN     CHAR8                                  *Schema,
> +  IN     CHAR8                                  *Version,
> +  IN     EFI_STRING                             RegexPattern,
> +  OUT    EFI_STRING                             **ConfigureLangList,
> +  OUT    UINTN                                  *Count
> +  )
> +{
> +  REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate;
> +  EFI_STATUS                                      Status;
> +  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;
> +
> +  if (This == NULL || IS_EMPTY_STRING (Schema) || IS_EMPTY_STRING
> (Version) || Count == NULL || ConfigureLangList == NULL ||
> IS_EMPTY_STRING (RegexPattern)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *Count = 0;
> +  *ConfigureLangList = NULL;
> +  FullSchema = NULL;
> +  RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> +
> +  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  FullSchema = GetFullSchemaString (Schema, Version);
> +  if (FullSchema == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Status = GetStatementPrivateByConfigureLangRegex (
> +             RedfishPlatformConfigPrivate->RegularExpressionProtocol,
> +             &RedfishPlatformConfigPrivate->FormsetList,
> +             FullSchema,
> +             RegexPattern,
> +             &StatementList
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a,
> GetStatementPrivateByConfigureLangRegex failure: %r\n", __FUNCTION__,
> Status));
> +    goto RELEASE_RESOURCE;
> +  }
> +
> +  if (!IsListEmpty (&StatementList.StatementList)) {
> +
> +    TmpConfigureLangList = AllocateZeroPool (sizeof (CHAR16 *) *
> StatementList.Count);
> +    if (TmpConfigureLangList == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      goto RELEASE_RESOURCE;
> +    }
> +
> +    Index = 0;
> +    NextLink = GetFirstNode (&StatementList.StatementList);
> +    while (!IsNull (&StatementList.StatementList, NextLink)) {
> +      StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> +      NextLink = GetNextNode (&StatementList.StatementList, NextLink);
> +
> +      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] = AllocateCopyPool (StrSize (TmpString),
> TmpString);
> +          ASSERT (TmpConfigureLangList[Index] != NULL);
> +          FreePool (TmpString);
> +          ++Index;
> +        }
> +      }
> +    }
> +  }
> +
> +  *Count = StatementList.Count;
> +  *ConfigureLangList = TmpConfigureLangList;
> +
> +RELEASE_RESOURCE:
> +
> +  if (FullSchema != NULL) {
> +    FreePool (FullSchema);
> +  }
> +
> +  ReleaseStatementList (&StatementList);
> +
> +  return Status;
> +}
> +
> +/**
> +  Get the list of supported Redfish schema from paltform configuration on
> give HII handle.
> +
> +  @param[in]   This                Pointer to
> EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL instance.
> +  @param[in]   HiiHandle           The target handle to search. If handle is NULL,
> +                                   this function return all schema from HII database.
> +  @param[out]  SupportedSchema     The supported schema list which is
> separated by ';'.
> +                                   The SupportedSchema is allocated by the callee. It's
> caller's
> +                                   responsibility to free this buffer using FreePool().
> +
> +  @retval EFI_SUCCESS              Schema is returned successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPlatformConfigProtocolGetSupportedSchema (
> +  IN     EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL   *This,
> +  IN     EFI_HII_HANDLE                           HiiHandle,       OPTIONAL
> +  OUT    CHAR8                                    **SupportedSchema
> +  )
> +{
> +  REDFISH_PLATFORM_CONFIG_PRIVATE
> *RedfishPlatformConfigPrivate;
> +  EFI_STATUS                                Status;
> +  LIST_ENTRY                                *HiiFormsetLink;
> +  LIST_ENTRY                                *HiiFormsetNextLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> +  UINTN                                     Index;
> +  UINTN                                     StringSize;
> +  CHAR8                                     *StringBuffer;
> +  UINTN                                     StringIndex;
> +
> +  if (This == NULL || SupportedSchema == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *SupportedSchema = NULL;
> +
> +  RedfishPlatformConfigPrivate =
> REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS (This);
> +
> +  Status = ProcessPendingList (&RedfishPlatformConfigPrivate->FormsetList,
> &RedfishPlatformConfigPrivate->PendingList);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, ProcessPendingList failure: %r\n",
> __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  if (IsListEmpty (&RedfishPlatformConfigPrivate->FormsetList)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Calculate for string buffer size.
> +  //
> +  StringSize = 0;
> +  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> +  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> +    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> +    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> +    if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> +      HiiFormsetLink = HiiFormsetNextLink;
> +      continue;
> +    }
> +
> +    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> +      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> +        StringSize += AsciiStrSize (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> +      }
> +    }
> +
> +    HiiFormsetLink = HiiFormsetNextLink;
> +  }
> +
> +  if (StringSize == 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  StringBuffer = AllocatePool (StringSize);
> +  if (StringBuffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  StringIndex = 0;
> +  HiiFormsetLink = GetFirstNode (&RedfishPlatformConfigPrivate-
> >FormsetList);
> +  while (!IsNull (&RedfishPlatformConfigPrivate->FormsetList,
> HiiFormsetLink)) {
> +    HiiFormsetNextLink = GetNextNode (&RedfishPlatformConfigPrivate-
> >FormsetList, HiiFormsetLink);
> +    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> +    if (HiiHandle != NULL && HiiHandle != HiiFormsetPrivate->HiiHandle) {
> +      HiiFormsetLink = HiiFormsetNextLink;
> +      continue;
> +    }
> +
> +    if (HiiFormsetPrivate->SupportedSchema.Count > 0) {
> +      for (Index = 0; Index < HiiFormsetPrivate->SupportedSchema.Count;
> Index++) {
> +        AsciiStrCpyS (&StringBuffer[StringIndex], (StringSize - StringIndex),
> HiiFormsetPrivate->SupportedSchema.SchemaList[Index]);
> +        StringIndex += AsciiStrLen (HiiFormsetPrivate-
> >SupportedSchema.SchemaList[Index]);
> +        StringBuffer[StringIndex] = ';';
> +        ++StringIndex;
> +      }
> +    }
> +
> +    HiiFormsetLink = HiiFormsetNextLink;
> +  }
> +
> +  StringBuffer[--StringIndex] = '\0';
> +
> +  *SupportedSchema = StringBuffer;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Functions which are registered to receive notification of
> +  database events have this prototype. The actual event is encoded
> +  in NotifyType. The following table describes how PackageType,
> +  PackageGuid, Handle, and Package are used for each of the
> +  notification types.
> +
> +  @param[in] PackageType  Package type of the notification.
> +  @param[in] PackageGuid  If PackageType is
> +                          EFI_HII_PACKAGE_TYPE_GUID, then this is
> +                          the pointer to the GUID from the Guid
> +                          field of EFI_HII_PACKAGE_GUID_HEADER.
> +                          Otherwise, it must be NULL.
> +  @param[in] Package      Points to the package referred to by the
> +                          notification Handle The handle of the package
> +                          list which contains the specified package.
> +  @param[in] Handle       The HII handle.
> +  @param[in] NotifyType   The type of change concerning the
> +                          database. See
> +                          EFI_HII_DATABASE_NOTIFY_TYPE.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPlatformConfigFormUpdateNotify (
> +  IN UINT8                              PackageType,
> +  IN CONST EFI_GUID                     *PackageGuid,
> +  IN CONST EFI_HII_PACKAGE_HEADER       *Package,
> +  IN EFI_HII_HANDLE                     Handle,
> +  IN EFI_HII_DATABASE_NOTIFY_TYPE       NotifyType
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  if (NotifyType == EFI_HII_DATABASE_NOTIFY_NEW_PACK || NotifyType
> == EFI_HII_DATABASE_NOTIFY_ADD_PACK) {
> +    //
> +    // HII formset on this handle is updated by driver during run-time. The
> formset needs to be reloaded.
> +    //
> +    Status = NotifyFormsetUpdate (Handle,
> &mRedfishPlatformConfigPrivate->PendingList);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a, failed to notify updated formset of HII
> handle: 0x%x\n", __FUNCTION__, Handle));
> +      return Status;
> +    }
> +  } else if (NotifyType == EFI_HII_DATABASE_NOTIFY_REMOVE_PACK) {
> +    //
> +    // HII resource is removed. The formset is no longer exist.
> +    //
> +    Status = NotifyFormsetDeleted (Handle,
> &mRedfishPlatformConfigPrivate->PendingList);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a, failed to notify deleted formset of HII
> handle: 0x%x\n", __FUNCTION__, Handle));
> +      return Status;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This is a EFI_HII_STRING_PROTOCOL notification event handler.
> +
> +  Install HII package notification.
> +
> +  @param[in] Event    Event whose notification function is being invoked.
> +  @param[in] Context  Pointer to the notification function's context.
> +
> +**/
> +VOID
> +EFIAPI
> +HiiStringProtocolInstalled (
> +  IN  EFI_EVENT       Event,
> +  IN  VOID            *Context
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Locate HII database protocol.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiHiiStringProtocolGuid,
> +                  NULL,
> +                  (VOID **)&mRedfishPlatformConfigPrivate->HiiString
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_STRING_PROTOCOL failure:
> %r\n", __FUNCTION__, Status));
> +    return;
> +  }
> +
> +  gBS->CloseEvent (Event);
> +  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent = NULL;
> +}
> +
> +/**
> +  This is a EFI_HII_DATABASE_PROTOCOL notification event handler.
> +
> +  Install HII package notification.
> +
> +  @param[in] Event    Event whose notification function is being invoked.
> +  @param[in] Context  Pointer to the notification function's context.
> +
> +**/
> +VOID
> +EFIAPI
> +HiiDatabaseProtocolInstalled (
> +  IN  EFI_EVENT       Event,
> +  IN  VOID            *Context
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Locate HII database protocol.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiHiiDatabaseProtocolGuid,
> +                  NULL,
> +                  (VOID **)&mRedfishPlatformConfigPrivate->HiiDatabase
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, locate EFI_HII_DATABASE_PROTOCOL
> failure: %r\n", __FUNCTION__, Status));
> +    return;
> +  }
> +
> +  //
> +  // Register package notification when new form package is installed.
> +  //
> +  Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> +                                             mRedfishPlatformConfigPrivate->HiiDatabase,
> +                                             EFI_HII_PACKAGE_FORMS,
> +                                             NULL,
> +                                             RedfishPlatformConfigFormUpdateNotify,
> +                                             EFI_HII_DATABASE_NOTIFY_NEW_PACK,
> +                                             &mRedfishPlatformConfigPrivate->NotifyHandle
> +                                             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> +  }
> +
> +  //
> +  // Register package notification when new form package is updated.
> +  //
> +  Status = mRedfishPlatformConfigPrivate->HiiDatabase-
> >RegisterPackageNotify (
> +                                             mRedfishPlatformConfigPrivate->HiiDatabase,
> +                                             EFI_HII_PACKAGE_FORMS,
> +                                             NULL,
> +                                             RedfishPlatformConfigFormUpdateNotify,
> +                                             EFI_HII_DATABASE_NOTIFY_ADD_PACK,
> +                                             &mRedfishPlatformConfigPrivate->NotifyHandle
> +                                             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, RegisterPackageNotify for
> EFI_HII_DATABASE_NOTIFY_NEW_PACK failure: %r\n", __FUNCTION__,
> Status));
> +  }
> +
> +  gBS->CloseEvent (Event);
> +  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent = NULL;
> +
> +}
> +
> +/**
> +  This is a EFI_REGULAR_EXPRESSION_PROTOCOL notification event handler.
> +
> +  @param[in] Event    Event whose notification function is being invoked.
> +  @param[in] Context  Pointer to the notification function's context.
> +
> +**/
> +VOID
> +EFIAPI
> +RegexProtocolInstalled (
> +  IN  EFI_EVENT       Event,
> +  IN  VOID            *Context
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  //
> +  // Locate regular expression protocol.
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiRegularExpressionProtocolGuid,
> +                  NULL,
> +                  (VOID **)&mRedfishPlatformConfigPrivate-
> >RegularExpressionProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, locate
> EFI_REGULAR_EXPRESSION_PROTOCOL failure: %r\n", __FUNCTION__,
> Status));
> +    return;
> +  }
> +
> +  gBS->CloseEvent (Event);
> +  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent = NULL;
> +
> +}
> +
> +/**
> +  Unloads an image.
> +
> +  @param  ImageHandle           Handle that identifies the image to be
> unloaded.
> +
> +  @retval EFI_SUCCESS           The image has been unloaded.
> +  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPlatformConfigDxeUnload (
> +  IN EFI_HANDLE  ImageHandle
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (mRedfishPlatformConfigPrivate != NULL) {
> +    Status = gBS->UninstallProtocolInterface (
> +                    mRedfishPlatformConfigPrivate->ImageHandle,
> +                    &gEdkIIRedfishPlatformConfigProtocolGuid,
> +                    (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a, can not uninstall
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> +      ASSERT (FALSE);
> +    }
> +
> +    //
> +    // Close events
> +    //
> +    if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent != NULL) {
> +      gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiDbNotify.ProtocolEvent);
> +    }
> +    if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent !=
> NULL) {
> +      gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >HiiStringNotify.ProtocolEvent);
> +    }
> +    if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent != NULL)
> {
> +      gBS->CloseEvent (mRedfishPlatformConfigPrivate-
> >RegexNotify.ProtocolEvent);
> +    }
> +
> +    //
> +    // Unregister package notification.
> +    //
> +    if (mRedfishPlatformConfigPrivate->NotifyHandle != NULL) {
> +      mRedfishPlatformConfigPrivate->HiiDatabase->UnregisterPackageNotify
> (
> +                                          mRedfishPlatformConfigPrivate->HiiDatabase,
> +                                          mRedfishPlatformConfigPrivate->NotifyHandle
> +                                          );
> +    }
> +
> +    ReleaseFormsetList (&mRedfishPlatformConfigPrivate->FormsetList);
> +    FreePool (mRedfishPlatformConfigPrivate);
> +    mRedfishPlatformConfigPrivate = NULL;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This is the declaration of an EFI image entry point. This entry point is
> +  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> +  both device drivers and bus drivers.
> +
> +  @param  ImageHandle           The firmware allocated handle for the UEFI
> image.
> +  @param  SystemTable           A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS           The operation completed successfully.
> +  @retval Others                An unexpected error occurred.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPlatformConfigDxeEntryPoint (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  mRedfishPlatformConfigPrivate = (REDFISH_PLATFORM_CONFIG_PRIVATE
> *)AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_PRIVATE));
> +  if (mRedfishPlatformConfigPrivate == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a, can not allocate pool for
> REDFISH_PLATFORM_CONFIG_PRIVATE\n", __FUNCTION__));
> +    ASSERT (FALSE);
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Protocol initialization
> +  //
> +  mRedfishPlatformConfigPrivate->ImageHandle = ImageHandle;
> +  mRedfishPlatformConfigPrivate->Protocol.GetValue =
> RedfishPlatformConfigProtocolGetValue;
> +  mRedfishPlatformConfigPrivate->Protocol.SetValue =
> RedfishPlatformConfigProtocolSetValue;
> +  mRedfishPlatformConfigPrivate->Protocol.GetConfigureLang =
> RedfishPlatformConfigProtocolGetConfigureLang;
> +  mRedfishPlatformConfigPrivate->Protocol.GetSupportedSchema =
> RedfishPlatformConfigProtocolGetSupportedSchema;
> +
> +  InitializeListHead (&mRedfishPlatformConfigPrivate->FormsetList);
> +  InitializeListHead (&mRedfishPlatformConfigPrivate->PendingList);
> +
> +  Status = gBS->InstallProtocolInterface (
> +                  &ImageHandle,
> +                  &gEdkIIRedfishPlatformConfigProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  (VOID*)&mRedfishPlatformConfigPrivate->Protocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, can not install
> gEdkIIRedfishPlatformConfigProtocolGuid: %r\n", __FUNCTION__, Status));
> +    ASSERT (FALSE);
> +  }
> +
> +  //
> +  // Install protocol notification if HII database protocol is installed.
> +  //
> +  mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> +                                                              &gEfiHiiDatabaseProtocolGuid,
> +                                                              TPL_CALLBACK,
> +                                                              HiiDatabaseProtocolInstalled,
> +                                                              NULL,
> +                                                              &mRedfishPlatformConfigPrivate-
> >HiiDbNotify.Registration
> +                                                              );
> +  if (mRedfishPlatformConfigPrivate->HiiDbNotify.ProtocolEvent == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiDatabaseProtocolGuid\n", __FUNCTION__));
> +    ASSERT (FALSE);
> +  }
> +
> +  //
> +  // Install protocol notification if HII string protocol is installed.
> +  //
> +  mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> +                                                                  &gEfiHiiStringProtocolGuid,
> +                                                                  TPL_CALLBACK,
> +                                                                  HiiStringProtocolInstalled,
> +                                                                  NULL,
> +                                                                  &mRedfishPlatformConfigPrivate-
> >HiiStringNotify.Registration
> +                                                                  );
> +  if (mRedfishPlatformConfigPrivate->HiiStringNotify.ProtocolEvent == NULL)
> {
> +    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiHiiStringProtocolGuid\n", __FUNCTION__));
> +    ASSERT (FALSE);
> +  }
> +
> +  //
> +  // Install protocol notification if regular expression protocol is installed.
> +  //
> +  mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent =
> EfiCreateProtocolNotifyEvent (
> +                                                              &gEfiRegularExpressionProtocolGuid,
> +                                                              TPL_CALLBACK,
> +                                                              RegexProtocolInstalled,
> +                                                              NULL,
> +                                                              &mRedfishPlatformConfigPrivate-
> >RegexNotify.Registration
> +                                                              );
> +  if (mRedfishPlatformConfigPrivate->RegexNotify.ProtocolEvent == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a, failed to create protocol notification for
> gEfiRegularExpressionProtocolGuid\n", __FUNCTION__));
> +    ASSERT (FALSE);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> index 99a613d229..d3f7af55ad 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.h
> @@ -1,64 +1,64 @@
> -/** @file
> -  This file defines the EDKII Redfish Platform Config Protocol interface.
> -
> -  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> -
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> -#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> -
> -#include <Uefi.h>
> -
> -//
> -// Libraries
> -//
> -#include <Library/BaseLib.h>
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/MemoryAllocationLib.h>
> -#include <Library/PrintLib.h>
> -#include <Library/UefiLib.h>
> -#include <Library/UefiBootServicesTableLib.h>
> -#include <Library/UefiDriverEntryPoint.h>
> -
> -//
> -// Produced Protocols
> -//
> -#include <Protocol/EdkIIRedfishPlatformConfig.h>
> -#include <Protocol/HiiDatabase.h>
> -#include <Protocol/HiiString.h>
> -#include <Protocol/RegularExpressionProtocol.h>
> -
> -//
> -// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
> -//
> -typedef struct {
> -  EFI_EVENT                   ProtocolEvent;   // Protocol notification event.
> -  VOID                        *Registration;   // Protocol notification registration.
> -} REDFISH_PLATFORM_CONFIG_NOTIFY;
> -
> -//
> -// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
> -//
> -typedef struct {
> -  EFI_HANDLE                                ImageHandle;                // Driver image handle.
> -  EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL    Protocol;
> -  REDFISH_PLATFORM_CONFIG_NOTIFY            HiiDbNotify;
> -  EFI_HII_DATABASE_PROTOCOL                 *HiiDatabase;               // The HII
> database protocol.
> -  REDFISH_PLATFORM_CONFIG_NOTIFY            HiiStringNotify;
> -  EFI_HII_STRING_PROTOCOL                   *HiiString;                 // HII String
> Protocol.
> -  REDFISH_PLATFORM_CONFIG_NOTIFY            RegexNotify;
> -  EFI_REGULAR_EXPRESSION_PROTOCOL           *RegularExpressionProtocol;
> // Regular Expression Protocol.
> -  EFI_HANDLE                                NotifyHandle;               // The notify handle.
> -  LIST_ENTRY                                FormsetList;                // The list to keep cached
> HII formset.
> -  LIST_ENTRY                                PendingList;                // The list to keep updated
> HII handle.
> -} REDFISH_PLATFORM_CONFIG_PRIVATE;
> -
> -#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a)  BASE_CR
> (a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
> -#define REGULAR_EXPRESSION_INCLUDE_ALL                L".*"
> -#define CONFIGURE_LANGUAGE_PREFIX                     "x-uefi-redfish-"
> -
> -#endif
> +/** @file
> +  This file defines the EDKII Redfish Platform Config Protocol interface.
> +
> +  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> +#define EDKII_REDFISH_PLATFORM_CONFIG_DXE_H_
> +
> +#include <Uefi.h>
> +
> +//
> +// Libraries
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +
> +//
> +// Produced Protocols
> +//
> +#include <Protocol/EdkIIRedfishPlatformConfig.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/HiiString.h>
> +#include <Protocol/RegularExpressionProtocol.h>
> +
> +//
> +// Definition of EDKII_REDFISH_PLATFORM_CONFIG_NOTIFY.
> +//
> +typedef struct {
> +  EFI_EVENT                   ProtocolEvent;   // Protocol notification event.
> +  VOID                        *Registration;   // Protocol notification registration.
> +} REDFISH_PLATFORM_CONFIG_NOTIFY;
> +
> +//
> +// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
> +//
> +typedef struct {
> +  EFI_HANDLE                                ImageHandle;                // Driver image handle.
> +  EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL    Protocol;
> +  REDFISH_PLATFORM_CONFIG_NOTIFY            HiiDbNotify;
> +  EFI_HII_DATABASE_PROTOCOL                 *HiiDatabase;               // The HII
> database protocol.
> +  REDFISH_PLATFORM_CONFIG_NOTIFY            HiiStringNotify;
> +  EFI_HII_STRING_PROTOCOL                   *HiiString;                 // HII String
> Protocol.
> +  REDFISH_PLATFORM_CONFIG_NOTIFY            RegexNotify;
> +  EFI_REGULAR_EXPRESSION_PROTOCOL           *RegularExpressionProtocol;
> // Regular Expression Protocol.
> +  EFI_HANDLE                                NotifyHandle;               // The notify handle.
> +  LIST_ENTRY                                FormsetList;                // The list to keep cached
> HII formset.
> +  LIST_ENTRY                                PendingList;                // The list to keep updated
> HII handle.
> +} REDFISH_PLATFORM_CONFIG_PRIVATE;
> +
> +#define REDFISH_PLATFORM_CONFIG_PRIVATE_FROM_THIS(a)  BASE_CR
> (a, REDFISH_PLATFORM_CONFIG_PRIVATE, Protocol)
> +#define REGULAR_EXPRESSION_INCLUDE_ALL                L".*"
> +#define CONFIGURE_LANGUAGE_PREFIX                     "x-uefi-redfish-"
> +
> +#endif
> diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
> index 16739bef7a..81b22e03c3 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigDxe.inf
> @@ -1,53 +1,53 @@
> -## @file
> -#  Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
> interfaces.
> -#
> -#  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> -#  SPDX-License-Identifier: BSD-2-Clause-Patent
> -#
> -##
> -
> -[Defines]
> -  INF_VERSION               = 0x00010005
> -  BASE_NAME                 = RedfishPlatformConfigDxe
> -  FILE_GUID                 = BEAEFFE1-0633-41B5-913C-9389339C2927
> -  MODULE_TYPE               = DXE_DRIVER
> -  VERSION_STRING            = 1.0
> -  ENTRY_POINT               = RedfishPlatformConfigDxeEntryPoint
> -  UNLOAD_IMAGE              = RedfishPlatformConfigDxeUnload
> -
> -[Packages]
> -  MdePkg/MdePkg.dec
> -  MdeModulePkg/MdeModulePkg.dec
> -  RedfishPkg/RedfishPkg.dec
> -
> -[Sources]
> -  RedfishPlatformConfigDxe.h
> -  RedfishPlatformConfigDxe.c
> -  RedfishPlatformConfigImpl.h
> -  RedfishPlatformConfigImpl.c
> -
> -[LibraryClasses]
> -  BaseLib
> -  BaseMemoryLib
> -  DebugLib
> -  DevicePathLib
> -  HiiLib
> -  HiiUtilityLib
> -  MemoryAllocationLib
> -  PrintLib
> -  UefiLib
> -  UefiBootServicesTableLib
> -  UefiRuntimeServicesTableLib
> -  UefiDriverEntryPoint
> -
> -[Protocols]
> -  gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
> -  gEfiHiiDatabaseProtocolGuid             ## CONSUMED
> -  gEfiHiiStringProtocolGuid               ## CONSUMED
> -  gEfiRegularExpressionProtocolGuid       ## CONSUMED
> -
> -[Guids]
> -  gEfiRegexSyntaxTypePerlGuid             ## CONSUMED
> -
> -[Depex]
> +## @file
> +#  Implementation of EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL
> interfaces.
> +#
> +#  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION               = 0x00010005
> +  BASE_NAME                 = RedfishPlatformConfigDxe
> +  FILE_GUID                 = BEAEFFE1-0633-41B5-913C-9389339C2927
> +  MODULE_TYPE               = DXE_DRIVER
> +  VERSION_STRING            = 1.0
> +  ENTRY_POINT               = RedfishPlatformConfigDxeEntryPoint
> +  UNLOAD_IMAGE              = RedfishPlatformConfigDxeUnload
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  RedfishPkg/RedfishPkg.dec
> +
> +[Sources]
> +  RedfishPlatformConfigDxe.h
> +  RedfishPlatformConfigDxe.c
> +  RedfishPlatformConfigImpl.h
> +  RedfishPlatformConfigImpl.c
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  HiiLib
> +  HiiUtilityLib
> +  MemoryAllocationLib
> +  PrintLib
> +  UefiLib
> +  UefiBootServicesTableLib
> +  UefiRuntimeServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEdkIIRedfishPlatformConfigProtocolGuid ## PRODUCED
> +  gEfiHiiDatabaseProtocolGuid             ## CONSUMED
> +  gEfiHiiStringProtocolGuid               ## CONSUMED
> +  gEfiRegularExpressionProtocolGuid       ## CONSUMED
> +
> +[Guids]
> +  gEfiRegexSyntaxTypePerlGuid             ## CONSUMED
> +
> +[Depex]
>    TRUE
> \ No newline at end of file
> diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> index d9eab6c883..525e666b6c 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.c
> @@ -1,1240 +1,1288 @@
> -/** @file
> -
> -  The implementation of EDKII Redfidh Platform Config Protocol.
> -
> -  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> -
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -#include "RedfishPlatformConfigDxe.h"
> -#include "RedfishPlatformConfigImpl.h"
> -
> -extern REDFISH_PLATFORM_CONFIG_PRIVATE
> *mRedfishPlatformConfigPrivate;
> -
> -/**
> -  Debug dump HII string
> -
> -  @param[in]  HiiHandle   HII handle instance
> -  @param[in]  StringId    HII string to dump
> -
> -  @retval EFI_SUCCESS       Dump HII string successfully
> -  @retval Others            Errors occur
> -
> -**/
> -EFI_STATUS
> -DumpHiiString (
> -  IN EFI_HII_HANDLE HiiHandle,
> -  IN EFI_STRING_ID  StringId
> -  )
> -{
> -  EFI_STRING String;
> -
> -  if (HiiHandle == NULL || StringId == 0) {
> -    DEBUG ((DEBUG_INFO, "???"));
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  String = HiiGetString (HiiHandle, StringId, NULL);
> -  if (String == NULL) {
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  DEBUG ((DEBUG_INFO, "%s", String));
> -  FreePool (String);
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Debug dump HII form-set data
> -
> -  @param[in]  FormsetPrivate    HII form-set private instance.
> -
> -  @retval EFI_SUCCESS       Dump form-set successfully
> -  @retval Others            Errors occur
> -
> -**/
> -EFI_STATUS
> -DumpFormset (
> -  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
> -  )
> -{
> -  LIST_ENTRY                      *HiiFormLink;
> -  LIST_ENTRY                      *HiiNextFormLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> -  LIST_ENTRY                      *HiiStatementLink;
> -  LIST_ENTRY                      *HiiNextStatementLink;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> -  UINTN                           Index;
> -
> -  if (FormsetPrivate == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  Index = 0;
> -  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> -  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> -    HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> -    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> -
> -    DEBUG ((DEBUG_INFO, "  [%d] form: %d title: ", ++Index, HiiFormPrivate-
> >Id));
> -    DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
> -    DEBUG ((DEBUG_INFO, "\n"));
> -
> -    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> -    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> -      HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> -      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> -
> -      DEBUG ((DEBUG_INFO, "    QID: 0x%x Prompt: ", HiiStatementPrivate-
> >QuestionId));
> -      DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
> >Description);
> -      DEBUG ((DEBUG_INFO, "\n"));
> -
> -      HiiStatementLink = HiiNextStatementLink;
> -    }
> -
> -    HiiFormLink = HiiNextFormLink;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Debug dump HII form-set list
> -
> -  @param[in]  FormsetList   Form-set list instance
> -
> -  @retval EFI_SUCCESS       Dump list successfully
> -  @retval Others            Errors occur
> -
> -**/
> -EFI_STATUS
> -DumpFormsetList (
> -  IN  LIST_ENTRY      *FormsetList
> -  )
> -{
> -  LIST_ENTRY                      *HiiFormsetLink;
> -  LIST_ENTRY                      *HiiFormsetNextLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> -  UINTN                           Index;
> -
> -  if (FormsetList == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  if (IsListEmpty (FormsetList)) {
> -    DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
> -    return EFI_SUCCESS;
> -  }
> -
> -  Index = 0;
> -  HiiFormsetLink = GetFirstNode (FormsetList);
> -  while (!IsNull (FormsetList, HiiFormsetLink)) {
> -    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> -    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> -    DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
> ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
> HiiFormsetPrivate->DevicePathStr));
> -    DumpFormset (HiiFormsetPrivate);
> -
> -    HiiFormsetLink = HiiFormsetNextLink;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Retrieves a string from a string package in a English language. The
> -  returned string is allocated using AllocatePool().  The caller is responsible
> -  for freeing the allocated buffer using FreePool().
> -
> -  If HiiHandle is NULL, then ASSERT().
> -  If StringId is 0, then ASSET.
> -
> -  @param[in]  HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
> -  @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
> -HiiGetRedfishString (
> -  IN EFI_HII_HANDLE           HiiHandle,
> -  IN CHAR8                    *Language,
> -  IN EFI_STRING_ID            StringId
> -  )
> -{
> -  EFI_STATUS  Status;
> -  UINTN       StringSize;
> -  CHAR16      TempString;
> -  EFI_STRING  String;
> -
> -  if (mRedfishPlatformConfigPrivate->HiiString == NULL || HiiHandle == NULL
> || StringId == 0 || IS_EMPTY_STRING (Language)) {
> -    ASSERT (FALSE);
> -    return NULL;
> -  }
> -
> -  //
> -  // Retrieve the size of the string in the string package for the BestLanguage
> -  //
> -  StringSize = 0;
> -  Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
> -                                             mRedfishPlatformConfigPrivate->HiiString,
> -                                             Language,
> -                                             HiiHandle,
> -                                             StringId,
> -                                             &TempString,
> -                                             &StringSize,
> -                                             NULL
> -                                             );
> -  //
> -  // If GetString() returns EFI_SUCCESS for a zero size,
> -  // then there are no supported languages registered for HiiHandle.  If
> GetString()
> -  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
> not present
> -  // in the HII Database
> -  //
> -  if (Status != EFI_BUFFER_TOO_SMALL) {
> -    return NULL;
> -  }
> -
> -  //
> -  // Allocate a buffer for the return string
> -  //
> -  String = AllocateZeroPool (StringSize);
> -  if (String == NULL) {
> -    return NULL;
> -  }
> -
> -  //
> -  // Retrieve the string from the string package
> -  //
> -  Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
> -                                             mRedfishPlatformConfigPrivate->HiiString,
> -                                             Language,
> -                                             HiiHandle,
> -                                             StringId,
> -                                             String,
> -                                             &StringSize,
> -                                             NULL
> -                                             );
> -  if (EFI_ERROR (Status)) {
> -    //
> -    // Free the buffer and return NULL if the supported languages can not be
> retrieved.
> -    //
> -    FreePool (String);
> -    String = NULL;
> -  }
> -
> -  //
> -  // Return the Null-terminated Unicode string
> -  //
> -  return String;
> -}
> -
> -/**
> -  Get string from HII database in English language.
> -
> -  @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);
> -}
> -
> -/**
> -  Check and see if this is supported schema or not.
> -
> -  @param[in]  SupportedSchema   The list of supported schema.
> -  @param[in]  Schema            Schema string to be checked.
> -
> -  @retval BOOLEAN               TRUE if this is supported schema. FALSE
> otherwise.
> -
> -**/
> -BOOLEAN
> -CheckSupportedSchema (
> -  IN REDFISH_PLATFORM_CONFIG_SCHEMA   *SupportedSchema,
> -  IN CHAR8                            *Schema
> -  )
> -{
> -  UINTN Index;
> -
> -  if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
> -    return FALSE;
> -  }
> -
> -  if (SupportedSchema->Count == 0) {
> -    return FALSE;
> -  }
> -
> -  for (Index = 0; Index < SupportedSchema->Count; Index++) {
> -    if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
> -      return TRUE;
> -    }
> -  }
> -
> -  return FALSE;
> -}
> -
> -/**
> -  Get the list of supported schema from the given HII handle.
> -
> -  @param[in]  HiiHandle         HII handle instance.
> -  @param[out] SupportedSchema   Supported schema on this HII handle.
> -
> -  @retval EFI_SUCCESS           Schema list is returned.
> -  @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema
> is NULL.
> -  @retval EFI_NOT_FOUND         No supported schema found.
> -  @retval EFI_OUT_OF_RESOURCES  System is out of memory.
> -
> -**/
> -EFI_STATUS
> -GetSupportedSchema (
> -  IN  EFI_HII_HANDLE                  HiiHandle,
> -  OUT REDFISH_PLATFORM_CONFIG_SCHEMA  *SupportedSchema
> -  )
> -{
> -  CHAR8 *SupportedLanguages;
> -  UINTN Index;
> -  UINTN LangIndex;
> -  UINTN Count;
> -  UINTN StrSize;
> -  UINTN ListIndex;
> -
> -  if (HiiHandle == NULL || SupportedSchema == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  SupportedSchema->Count = 0;
> -
> -  SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
> -  if (SupportedLanguages == NULL) {
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  Index = 0;
> -  LangIndex = 0;
> -  Count = 0;
> -  while (TRUE) {
> -    if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> -      if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> -        ++Count;
> -      }
> -      LangIndex = Index + 1;
> -    }
> -
> -    if (SupportedLanguages[Index] == '\0') {
> -      break;
> -    }
> -
> -    ++Index;
> -  }
> -
> -  if (Count == 0) {
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  SupportedSchema->Count = Count;
> -  SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
> -  if (SupportedSchema->SchemaList == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  Index = 0;
> -  LangIndex = 0;
> -  ListIndex = 0;
> -  while (TRUE) {
> -
> -    if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> -      if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> -        StrSize = Index - LangIndex;
> -        SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
> + 1), &SupportedLanguages[LangIndex]);
> -        SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
> -        ++ListIndex;
> -      }
> -
> -      LangIndex = Index + 1;
> -    }
> -
> -    if (SupportedLanguages[Index] == '\0') {
> -      break;
> -    }
> -
> -    ++Index;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Search and find statement private instance by given regular expression
> patthern
> -  which describes the Configure Language.
> -
> -  @param[in]  RegularExpressionProtocol   Regular express protocol.
> -  @param[in]  FormsetList                 Form-set list to search.
> -  @param[in]  Schema                      Schema to be matched.
> -  @param[in]  Pattern                     Regular expression pattern.
> -  @param[out] StatementList               Statement list that match above
> pattern.
> -
> -  @retval EFI_SUCCESS             Statement list is returned.
> -  @retval EFI_INVALID_PARAMETER   Input parameter is NULL.
> -  @retval EFI_NOT_READY           Regular express protocol is NULL.
> -  @retval EFI_NOT_FOUND           No statement is found.
> -  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> -
> -**/
> -EFI_STATUS
> -GetStatementPrivateByConfigureLangRegex (
> -  IN  EFI_REGULAR_EXPRESSION_PROTOCOL
> *RegularExpressionProtocol,
> -  IN  LIST_ENTRY                                      *FormsetList,
> -  IN  CHAR8                                           *Schema,
> -  IN  EFI_STRING                                      Pattern,
> -  OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> *StatementList
> -  )
> -{
> -  LIST_ENTRY                      *HiiFormsetLink;
> -  LIST_ENTRY                      *HiiFormsetNextLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> -  LIST_ENTRY                      *HiiFormLink;
> -  LIST_ENTRY                      *HiiNextFormLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> -  LIST_ENTRY                      *HiiStatementLink;
> -  LIST_ENTRY                      *HiiNextStatementLink;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> -  EFI_STRING                      TmpString;
> -  UINTN                           CaptureCount;
> -  BOOLEAN                         IsMatch;
> -  EFI_STATUS                      Status;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
> -
> -  if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  if (RegularExpressionProtocol == NULL) {
> -    return EFI_NOT_READY;
> -  }
> -
> -  StatementList->Count = 0;
> -  InitializeListHead (&StatementList->StatementList);
> -
> -  if (IsListEmpty (FormsetList)) {
> -    return EFI_NOT_FOUND;
> -  }
> -
> -  HiiFormsetLink = GetFirstNode (FormsetList);
> -  while (!IsNull (FormsetList, HiiFormsetLink)) {
> -    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> -    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> -    //
> -    // Performance check.
> -    // If there is no desired Redfish schema found, skip this formset.
> -    //
> -    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> -      HiiFormsetLink = HiiFormsetNextLink;
> -      continue;
> -    }
> -
> -    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> -    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> -      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> -      HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> -
> -      HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> -      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> -        HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> -        HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> -
> -        if (HiiStatementPrivate->Description != 0) {
> -          TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> -          if (TmpString != NULL) {
> -            Status = RegularExpressionProtocol->MatchString (
> -                                                  RegularExpressionProtocol,
> -                                                  TmpString,
> -                                                  Pattern,
> -                                                  &gEfiRegexSyntaxTypePerlGuid,
> -                                                  &IsMatch,
> -                                                  NULL,
> -                                                  &CaptureCount
> -                                                  );
> -            if (EFI_ERROR (Status)) {
> -              DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n",
> __FUNCTION__, Pattern, Status));
> -              ASSERT (FALSE);
> -              return Status;
> -            }
> -
> -            //
> -            // Found
> -            //
> -            if (IsMatch) {
> -              StatementRef = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
> -              if (StatementRef == NULL) {
> -                return EFI_OUT_OF_RESOURCES;
> -              }
> -
> -              StatementRef->Statement = HiiStatementPrivate;
> -              InsertTailList (&StatementList->StatementList, &StatementRef->Link);
> -              ++StatementList->Count;
> -            }
> -
> -            FreePool (TmpString);
> -          }
> -        }
> -
> -        HiiStatementLink = HiiNextStatementLink;
> -      }
> -
> -      HiiFormLink = HiiNextFormLink;
> -    }
> -
> -    HiiFormsetLink = HiiFormsetNextLink;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Get statement private instance by the given configure language.
> -
> -  @param[in]  FormsetList                 Form-set list to search.
> -  @param[in]  Schema                      Schema to be matched.
> -  @param[in]  ConfigureLang               Configure language.
> -
> -  @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *   Pointer to
> statement private instance.
> -
> -**/
> -REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
> -GetStatementPrivateByConfigureLang (
> -  IN  LIST_ENTRY    *FormsetList,
> -  IN  CHAR8         *Schema,
> -  IN  EFI_STRING    ConfigureLang
> -  )
> -{
> -  LIST_ENTRY                      *HiiFormsetLink;
> -  LIST_ENTRY                      *HiiFormsetNextLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> -  LIST_ENTRY                      *HiiFormLink;
> -  LIST_ENTRY                      *HiiNextFormLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> -  LIST_ENTRY                      *HiiStatementLink;
> -  LIST_ENTRY                      *HiiNextStatementLink;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> -  EFI_STRING                      TmpString;
> -
> -  if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (ConfigureLang)) {
> -    return NULL;
> -  }
> -
> -  if (IsListEmpty (FormsetList)) {
> -    return NULL;
> -  }
> -
> -  HiiFormsetLink = GetFirstNode (FormsetList);
> -  while (!IsNull (FormsetList, HiiFormsetLink)) {
> -    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> -    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> -    //
> -    // Performance check.
> -    // If there is no desired Redfish schema found, skip this formset.
> -    //
> -    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> -      HiiFormsetLink = HiiFormsetNextLink;
> -      continue;
> -    }
> -
> -    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> -    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> -      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> -      HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> -
> -      HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> -      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> -        HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> -        HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> -
> -        DEBUG_CODE (
> -          STATIC UINTN Index = 0;
> -          DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x
> formset: %g\n", __FUNCTION__, ++Index, ConfigureLang,
> HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate-
> >Guid));
> -        );
> -
> -        if (HiiStatementPrivate->Description != 0) {
> -          TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> -          if (TmpString != NULL) {
> -            if (StrCmp (TmpString, ConfigureLang) == 0) {
> -              FreePool (TmpString);
> -              return HiiStatementPrivate;
> -            }
> -
> -            FreePool (TmpString);
> -          }
> -        }
> -
> -        HiiStatementLink = HiiNextStatementLink;
> -      }
> -
> -      HiiFormLink = HiiNextFormLink;
> -    }
> -
> -    HiiFormsetLink = HiiFormsetNextLink;
> -  }
> -
> -  return NULL;
> -}
> -
> -/**
> -  Get form-set private instance by the given HII handle.
> -
> -  @param[in]  HiiHandle       HII handle instance.
> -  @param[in]  FormsetList     Form-set list to search.
> -
> -  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to
> form-set private instance.
> -
> -**/
> -REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
> -GetFormsetPrivateByHiiHandle (
> -  IN  EFI_HII_HANDLE  HiiHandle,
> -  IN  LIST_ENTRY      *FormsetList
> -  )
> -{
> -  LIST_ENTRY                      *HiiFormsetLink;
> -  LIST_ENTRY                      *HiiFormsetNextLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> -
> -  if (HiiHandle == NULL || FormsetList == NULL) {
> -    return NULL;
> -  }
> -
> -  if (IsListEmpty (FormsetList)) {
> -    return NULL;
> -  }
> -
> -  HiiFormsetLink = GetFirstNode (FormsetList);
> -  while (!IsNull (FormsetList, HiiFormsetLink)) {
> -    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> -    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> -    if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
> -      return HiiFormsetPrivate;
> -    }
> -
> -    HiiFormsetLink = HiiFormsetNextLink;
> -  }
> -
> -  return NULL;
> -}
> -
> -/**
> -  Release formset and all the forms and statements that belong to this
> formset.
> -
> -  @param[in]      FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
> -
> -  @retval         EFI_STATUS
> -
> -**/
> -EFI_STATUS
> -ReleaseFormset (
> -  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
> -  )
> -{
> -  LIST_ENTRY                      *HiiFormLink;
> -  LIST_ENTRY                      *HiiNextFormLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> -  LIST_ENTRY                      *HiiStatementLink;
> -  LIST_ENTRY                      *HiiNextStatementLink;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> -  UINTN                           Index;
> -
> -  if (FormsetPrivate == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> -  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> -    HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> -    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> -
> -    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> -    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> -      HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> -      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> -
> -      //
> -      // HiiStatementPrivate->HiiStatement will be released in
> DestroyFormSet().
> -      //
> -
> -      if (HiiStatementPrivate->DesStringCache != NULL) {
> -        FreePool (HiiStatementPrivate->DesStringCache);
> -        HiiStatementPrivate->DesStringCache = NULL;
> -      }
> -
> -      RemoveEntryList (&HiiStatementPrivate->Link);
> -      FreePool (HiiStatementPrivate);
> -      HiiStatementLink = HiiNextStatementLink;
> -    }
> -
> -    //
> -    // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
> -    //
> -
> -    RemoveEntryList (&HiiFormPrivate->Link);
> -    FreePool (HiiFormPrivate);
> -    HiiFormLink = HiiNextFormLink;
> -  }
> -
> -  if (FormsetPrivate->HiiFormSet != NULL) {
> -    DestroyFormSet (FormsetPrivate->HiiFormSet);
> -    FormsetPrivate->HiiFormSet = NULL;
> -  }
> -
> -  FreePool (FormsetPrivate->DevicePathStr);
> -
> -  //
> -  // Release schema list
> -  //
> -  if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
> -    for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
> Index++) {
> -      FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
> -    }
> -
> -    FreePool (FormsetPrivate->SupportedSchema.SchemaList);
> -    FormsetPrivate->SupportedSchema.SchemaList = NULL;
> -    FormsetPrivate->SupportedSchema.Count = 0;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Create new form-set instance.
> -
> -  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to
> newly created form-set private instance.
> -
> -**/
> -REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *
> -NewFormsetPrivate (
> -  VOID
> -  )
> -{
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
> -
> -  NewFormsetPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
> -  if (NewFormsetPrivate == NULL) {
> -    return NULL;
> -  }
> -
> -  //
> -  // Initial newly created formset private data.
> -  //
> -  InitializeListHead (&NewFormsetPrivate->HiiFormList);
> -
> -  return NewFormsetPrivate;
> -}
> -
> -/**
> -  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
> -
> -**/
> -EFI_STATUS
> -LoadFormset (
> -  IN  EFI_HII_HANDLE                  HiiHandle,
> -  OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate
> -  )
> -{
> -  EFI_STATUS                      Status;
> -  HII_FORMSET                     *HiiFormSet;
> -  HII_FORM                        *HiiForm;
> -  LIST_ENTRY                      *HiiFormLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> -  HII_STATEMENT                   *HiiStatement;
> -  LIST_ENTRY                      *HiiStatementLink;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> -  EFI_GUID                        ZeroGuid;
> -
> -  if (HiiHandle == NULL || FormsetPrivate == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -
> -  HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
> -  if (HiiFormSet == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  //
> -  // Find HII formset by the given HII handle.
> -  //
> -  ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
> -  Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
> -  if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
> -    Status = EFI_NOT_FOUND;
> -    goto ErrorExit;
> -  }
> -
> -  //
> -  // Initialize formset
> -  //
> -  InitializeFormSet (HiiFormSet);
> -
> -  //
> -  // Initialize formset private data.
> -  //
> -  FormsetPrivate->HiiFormSet = HiiFormSet;
> -  FormsetPrivate->HiiHandle = HiiHandle;
> -  CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
> -  FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
> >DevicePath, FALSE, FALSE);
> -  Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
> &FormsetPrivate->SupportedSchema);
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
> %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
> -  }
> -
> -  HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
> -  while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
> -    HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
> -
> -    HiiFormPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
> -    if (HiiFormPrivate == NULL) {
> -      Status = EFI_OUT_OF_RESOURCES;
> -      goto ErrorExit;
> -    }
> -
> -    //
> -    // Initialize form private data.
> -    //
> -    HiiFormPrivate->HiiForm = HiiForm;
> -    HiiFormPrivate->Id = HiiForm->FormId;
> -    HiiFormPrivate->Title = HiiForm->FormTitle;
> -    HiiFormPrivate->ParentFormset = FormsetPrivate;
> -    InitializeListHead (&HiiFormPrivate->StatementList);
> -
> -    HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
> -    while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
> -      HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
> -
> -      HiiStatementPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
> -      if (HiiStatementPrivate == NULL) {
> -        Status = EFI_OUT_OF_RESOURCES;
> -        goto ErrorExit;
> -      }
> -      //
> -      // Initialize statement private data.
> -      //
> -      HiiStatementPrivate->HiiStatement = HiiStatement;
> -      HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
> -      HiiStatementPrivate->Description = HiiStatement->Prompt;
> -      HiiStatementPrivate->ParentForm = HiiFormPrivate;
> -
> -      //
> -      // Attach to statement list.
> -      //
> -      InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> >Link);
> -      HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> HiiStatementLink);
> -    }
> -    //
> -    // Attach to form list.
> -    //
> -    InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
> -    HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
> -  }
> -
> -  return EFI_SUCCESS;
> -
> -ErrorExit:
> -
> -  //
> -  // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
> -  //
> -  if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != HiiFormSet) {
> -    DestroyFormSet (HiiFormSet);
> -  }
> -
> -  //
> -  // Release resource when error happens.
> -  //
> -  ReleaseFormset (FormsetPrivate);
> -
> -  return Status;
> -}
> -
> -/**
> -  Release formset list and all the forms that belong to this formset.
> -
> -  @param[in]      FormsetList   Pointer to formst list that needs to be
> -                                released.
> -
> -  @retval         EFI_STATUS
> -
> -**/
> -EFI_STATUS
> -LoadFormsetList (
> -  IN   EFI_HII_HANDLE   *HiiHandle,
> -  OUT  LIST_ENTRY       *FormsetList
> -  )
> -{
> -  EFI_STATUS  Status;
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;
> -
> -  if (HiiHandle == NULL || FormsetList == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
> -  if (FormsetPrivate != NULL) {
> -    return EFI_ALREADY_STARTED;
> -  }
> -
> -  FormsetPrivate =  NewFormsetPrivate ();
> -  if (FormsetPrivate == NULL) {
> -    DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  //
> -  // Load formset on the given HII handle.
> -  //
> -  Status = LoadFormset (HiiHandle, FormsetPrivate);
> -  if (EFI_ERROR (Status)) {
> -    DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n",
> __FUNCTION__, Status));
> -    FreePool (FormsetPrivate);
> -    return Status;
> -  }
> -
> -  //
> -  // Attach to cache list.
> -  //
> -  InsertTailList (FormsetList, &FormsetPrivate->Link);
> -
> -  DEBUG_CODE (
> -    DumpFormsetList (FormsetList);
> -    );
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Release formset list and all the forms that belong to this formset.
> -
> -  @param[in]      FormsetList   Pointer to formst list that needs to be
> -                                released.
> -
> -  @retval         EFI_STATUS
> -
> -**/
> -EFI_STATUS
> -ReleaseFormsetList (
> -  IN  LIST_ENTRY      *FormsetList
> -  )
> -{
> -  LIST_ENTRY                      *HiiFormsetLink;
> -  LIST_ENTRY                      *HiiFormsetNextLink;
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> -
> -  if (FormsetList == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  if (IsListEmpty (FormsetList)) {
> -    return EFI_SUCCESS;
> -  }
> -
> -  HiiFormsetLink = GetFirstNode (FormsetList);
> -  while (!IsNull (FormsetList, HiiFormsetLink)) {
> -    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> -    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> -
> -    //
> -    // Detach from list.
> -    //
> -    RemoveEntryList (&HiiFormsetPrivate->Link);
> -    ReleaseFormset (HiiFormsetPrivate);
> -    FreePool (HiiFormsetPrivate);
> -    HiiFormsetLink = HiiFormsetNextLink;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Get all pending list.
> -
> -  @param[in]  HiiHandle   HII handle instance.
> -  @param[in]  PendingList Pending list to keep pending data.
> -
> -  @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST *   Pointer to
> pending list data.
> -
> -**/
> -REDFISH_PLATFORM_CONFIG_PENDING_LIST *
> -GetPendingList (
> -  IN  EFI_HII_HANDLE   *HiiHandle,
> -  IN  LIST_ENTRY       *PendingList
> -  )
> -{
> -  LIST_ENTRY                 *PendingListLink;
> -  REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
> -
> -  if (HiiHandle == NULL || PendingList == NULL) {
> -    return NULL;
> -  }
> -
> -  if (IsListEmpty (PendingList)) {
> -    return NULL;
> -  }
> -
> -  PendingListLink = GetFirstNode (PendingList);
> -  while (!IsNull (PendingList, PendingListLink)) {
> -    Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> -
> -    if (Target->HiiHandle == HiiHandle) {
> -      return Target;
> -    }
> -
> -    PendingListLink = GetNextNode (PendingList, PendingListLink);
> -  }
> -
> -  return NULL;
> -}
> -
> -/**
> -  When HII database is updated. Keep updated HII handle into pending list so
> -  we can process them later.
> -
> -  @param[in]  HiiHandle   HII handle instance.
> -  @param[in]  PendingList Pending list to keep HII handle which is recently
> updated.
> -
> -  @retval EFI_SUCCESS             HII handle is saved in pending list.
> -  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is
> NULL.
> -  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> -
> -**/
> -EFI_STATUS
> -NotifyFormsetUpdate (
> -  IN  EFI_HII_HANDLE   *HiiHandle,
> -  IN  LIST_ENTRY       *PendingList
> -  )
> -{
> -  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;
> -
> -  if (HiiHandle == NULL || PendingList == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Check and see if this HII handle is processed already.
> -  //
> -  TargetPendingList = GetPendingList (HiiHandle, PendingList);
> -  if (TargetPendingList != NULL) {
> -    TargetPendingList->IsDeleted = FALSE;
> -  DEBUG_CODE (
> -    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
> __FUNCTION__, HiiHandle));
> -    );
> -    return EFI_SUCCESS;
> -  }
> -
> -  TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> -  if (TargetPendingList == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  TargetPendingList->HiiHandle = HiiHandle;
> -  TargetPendingList->IsDeleted = FALSE;
> -
> -  InsertTailList (PendingList, &TargetPendingList->Link);
> -
> -  DEBUG_CODE (
> -    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n",
> __FUNCTION__, HiiHandle));
> -    );
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  When HII database is updated and form-set is deleted. Keep deleted HII
> handle into pending list so
> -  we can process them later.
> -
> -  @param[in]  HiiHandle   HII handle instance.
> -  @param[in]  PendingList Pending list to keep HII handle which is recently
> updated.
> -
> -  @retval EFI_SUCCESS             HII handle is saved in pending list.
> -  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is
> NULL.
> -  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> -
> -**/
> -EFI_STATUS
> -NotifyFormsetDeleted (
> -  IN  EFI_HII_HANDLE   *HiiHandle,
> -  IN  LIST_ENTRY       *PendingList
> -  )
> -{
> -  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;
> -
> -  if (HiiHandle == NULL || PendingList == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  //
> -  // Check and see if this HII handle is processed already.
> -  //
> -  TargetPendingList = GetPendingList (HiiHandle, PendingList);
> -  if (TargetPendingList != NULL) {
> -    TargetPendingList->IsDeleted = TRUE;
> -    DEBUG_CODE (
> -      DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
> __FUNCTION__, HiiHandle));
> -      );
> -    return EFI_SUCCESS;
> -  }
> -
> -  TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> -  if (TargetPendingList == NULL) {
> -    return EFI_OUT_OF_RESOURCES;
> -  }
> -
> -  TargetPendingList->HiiHandle = HiiHandle;
> -  TargetPendingList->IsDeleted = TRUE;
> -
> -  InsertTailList (PendingList, &TargetPendingList->Link);
> -
> -  DEBUG_CODE (
> -    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n",
> __FUNCTION__, HiiHandle));
> -    );
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  There are HII database update and we need to process them accordingly so
> that we
> -  won't use stale data. This function will parse updated HII handle again in
> order
> -  to get updated data-set.
> -
> -  @param[in]  FormsetList   List to keep HII form-set.
> -  @param[in]  PendingList   List to keep HII handle that is updated.
> -
> -  @retval EFI_SUCCESS             HII handle is saved in pending list.
> -  @retval EFI_INVALID_PARAMETER   FormsetList is NULL or PendingList is
> NULL.
> -
> -**/
> -EFI_STATUS
> -ProcessPendingList (
> -  IN  LIST_ENTRY       *FormsetList,
> -  IN  LIST_ENTRY       *PendingList
> -  )
> -{
> -  LIST_ENTRY                 *PendingListLink;
> -  LIST_ENTRY                 *PendingListNextLink;
> -  REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;
> -  EFI_STATUS                      Status;
> -
> -
> -  if (FormsetList == NULL || PendingList == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  if (IsListEmpty (PendingList)) {
> -    return EFI_SUCCESS;
> -  }
> -
> -  PendingListLink = GetFirstNode (PendingList);
> -  while (!IsNull (PendingList, PendingListLink)) {
> -    PendingListNextLink = GetNextNode (PendingList, PendingListLink);
> -    Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> -
> -    if (Target->IsDeleted) {
> -      //
> -      // The HII resource on this HII handle is removed. Release the formset.
> -      //
> -      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> -      if (FormsetPrivate != NULL) {
> -        DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
> release HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid));
> -        RemoveEntryList (&FormsetPrivate->Link);
> -        ReleaseFormset (FormsetPrivate);
> -        FreePool (FormsetPrivate);
> -      } else {
> -        DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was removed
> already\n", __FUNCTION__, Target->HiiHandle));
> -      }
> -    } else {
> -      //
> -      // The HII resource on this HII handle is updated/removed.
> -      //
> -      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> -      if (FormsetPrivate != NULL) {
> -        //
> -        // HII formset already exist, release it and query again.
> -        //
> -        DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
> formset\n", __FUNCTION__, &FormsetPrivate->Guid));
> -        RemoveEntryList (&FormsetPrivate->Link);
> -        ReleaseFormset (FormsetPrivate);
> -        FreePool (FormsetPrivate);
> -      }
> -
> -      Status = LoadFormsetList (Target->HiiHandle, FormsetList);
> -      if (EFI_ERROR (Status)) {
> -        DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x failed:
> %r\n", __FUNCTION__, Target->HiiHandle, Status));
> -      }
> -    }
> -
> -    //
> -    // Detach it from list first.
> -    //
> -    RemoveEntryList (&Target->Link);
> -    FreePool (Target);
> -
> -    PendingListLink = PendingListNextLink;
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> -
> -/**
> -  Release all resource in statement list.
> -
> -  @param[in]  StatementList   Statement list to be released.
> -
> -  @retval EFI_SUCCESS             All resource are released.
> -  @retval EFI_INVALID_PARAMETER   StatementList is NULL.
> -
> -**/
> -EFI_STATUS
> -ReleaseStatementList (
> -  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> *StatementList
> -  )
> -{
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
> -  LIST_ENTRY  *NextLink;
> -
> -  if (StatementList == NULL) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  if (IsListEmpty (&StatementList->StatementList)) {
> -    return EFI_SUCCESS;
> -  }
> -
> -  NextLink = GetFirstNode (&StatementList->StatementList);
> -  while (!IsNull (&StatementList->StatementList, NextLink)) {
> -    StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> -    NextLink = GetNextNode (&StatementList->StatementList, NextLink);
> -
> -    RemoveEntryList (&StatementRef->Link);
> -    FreePool (StatementRef);
> -  }
> -
> -  return EFI_SUCCESS;
> -}
> +/** @file
> +
> +  The implementation of EDKII Redfidh Platform Config Protocol.
> +
> +  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include "RedfishPlatformConfigDxe.h"
> +#include "RedfishPlatformConfigImpl.h"
> +
> +extern REDFISH_PLATFORM_CONFIG_PRIVATE
> *mRedfishPlatformConfigPrivate;
> +
> +/**
> +  Debug dump HII string
> +
> +  @param[in]  HiiHandle   HII handle instance
> +  @param[in]  StringId    HII string to dump
> +
> +  @retval EFI_SUCCESS       Dump HII string successfully
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +DumpHiiString (
> +  IN EFI_HII_HANDLE HiiHandle,
> +  IN EFI_STRING_ID  StringId
> +  )
> +{
> +  EFI_STRING String;
> +
> +  if (HiiHandle == NULL || StringId == 0) {
> +    DEBUG ((DEBUG_INFO, "???"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  String = HiiGetString (HiiHandle, StringId, NULL);
> +  if (String == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "%s", String));
> +  FreePool (String);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Debug dump HII form-set data
> +
> +  @param[in]  FormsetPrivate    HII form-set private instance.
> +
> +  @retval EFI_SUCCESS       Dump form-set successfully
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +DumpFormset (
> +  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
> +  )
> +{
> +  LIST_ENTRY                      *HiiFormLink;
> +  LIST_ENTRY                      *HiiNextFormLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> +  LIST_ENTRY                      *HiiStatementLink;
> +  LIST_ENTRY                      *HiiNextStatementLink;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> +  UINTN                           Index;
> +
> +  if (FormsetPrivate == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Index = 0;
> +  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> +  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> +    HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> +    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> +
> +    DEBUG ((DEBUG_INFO, "  [%d] form: %d title: ", ++Index, HiiFormPrivate-
> >Id));
> +    DumpHiiString (FormsetPrivate->HiiHandle, HiiFormPrivate->Title);
> +    DEBUG ((DEBUG_INFO, "\n"));
> +
> +    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> +    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> +      HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> +      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> +
> +      DEBUG ((DEBUG_INFO, "    QID: 0x%x Prompt: ", HiiStatementPrivate-
> >QuestionId));
> +      DumpHiiString (FormsetPrivate->HiiHandle, HiiStatementPrivate-
> >Description);
> +      DEBUG ((DEBUG_INFO, "\n"));
> +
> +      HiiStatementLink = HiiNextStatementLink;
> +    }
> +
> +    HiiFormLink = HiiNextFormLink;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Debug dump HII form-set list
> +
> +  @param[in]  FormsetList   Form-set list instance
> +
> +  @retval EFI_SUCCESS       Dump list successfully
> +  @retval Others            Errors occur
> +
> +**/
> +EFI_STATUS
> +DumpFormsetList (
> +  IN  LIST_ENTRY      *FormsetList
> +  )
> +{
> +  LIST_ENTRY                      *HiiFormsetLink;
> +  LIST_ENTRY                      *HiiFormsetNextLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> +  UINTN                           Index;
> +
> +  if (FormsetList == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (IsListEmpty (FormsetList)) {
> +    DEBUG ((DEBUG_INFO, "%a, Empty formset list\n", __FUNCTION__));
> +    return EFI_SUCCESS;
> +  }
> +
> +  Index = 0;
> +  HiiFormsetLink = GetFirstNode (FormsetList);
> +  while (!IsNull (FormsetList, HiiFormsetLink)) {
> +    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> +    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> +    DEBUG ((DEBUG_INFO, "[%d] HII Handle: 0x%x formset: %g at %s\n",
> ++Index, HiiFormsetPrivate->HiiHandle, &HiiFormsetPrivate->Guid,
> HiiFormsetPrivate->DevicePathStr));
> +    DumpFormset (HiiFormsetPrivate);
> +
> +    HiiFormsetLink = HiiFormsetNextLink;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Retrieves a unicode string from a string package in a given language. The
> +  returned string is allocated using AllocatePool().  The caller is responsible
> +  for freeing the allocated buffer using FreePool().
> +
> +  If HiiHandle is NULL, then ASSERT().
> +  If StringId is 0, then ASSET.
> +
> +  @param[in]  HiiHandle         A handle that was previously registered in the
> HII Database.
> +  @param[in]  Language          The specified configure language to get string.
> +  @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
> +HiiGetRedfishString (
> +  IN EFI_HII_HANDLE           HiiHandle,
> +  IN CHAR8                    *Language,
> +  IN EFI_STRING_ID            StringId
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINTN       StringSize;
> +  CHAR16      TempString;
> +  EFI_STRING  String;
> +
> +  if (mRedfishPlatformConfigPrivate->HiiString == NULL || HiiHandle ==
> NULL || StringId == 0 || IS_EMPTY_STRING (Language)) {
> +    ASSERT (FALSE);
> +    return NULL;
> +  }
> +
> +  //
> +  // Retrieve the size of the string in the string package for the BestLanguage
> +  //
> +  StringSize = 0;
> +  Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
> +                                             mRedfishPlatformConfigPrivate->HiiString,
> +                                             Language,
> +                                             HiiHandle,
> +                                             StringId,
> +                                             &TempString,
> +                                             &StringSize,
> +                                             NULL
> +                                             );
> +  //
> +  // If GetString() returns EFI_SUCCESS for a zero size,
> +  // then there are no supported languages registered for HiiHandle.  If
> GetString()
> +  // returns an error other than EFI_BUFFER_TOO_SMALL, then HiiHandle is
> not present
> +  // in the HII Database
> +  //
> +  if (Status != EFI_BUFFER_TOO_SMALL) {
> +    return NULL;
> +  }
> +
> +  //
> +  // Allocate a buffer for the return string
> +  //
> +  String = AllocateZeroPool (StringSize);
> +  if (String == NULL) {
> +    return NULL;
> +  }
> +
> +  //
> +  // Retrieve the string from the string package
> +  //
> +  Status = mRedfishPlatformConfigPrivate->HiiString->GetString (
> +                                             mRedfishPlatformConfigPrivate->HiiString,
> +                                             Language,
> +                                             HiiHandle,
> +                                             StringId,
> +                                             String,
> +                                             &StringSize,
> +                                             NULL
> +                                             );
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Free the buffer and return NULL if the supported languages can not be
> retrieved.
> +    //
> +    FreePool (String);
> +    String = NULL;
> +  }
> +
> +  //
> +  // Return the Null-terminated Unicode string
> +  //
> +  return String;
> +}
> +
> +/**
> +  Retrieves a ASCII string from a string package in a given language. The
> +  returned string is allocated using AllocatePool().  The caller is responsible
> +  for freeing the allocated buffer using FreePool().
> +
> +  If HiiHandle is NULL, then ASSERT().
> +  If StringId is 0, then ASSET.
> +
> +  @param[in]  HiiHandle         A handle that was previously registered in the
> HII Database.
> +  @param[in]  Language          The specified configure language to get string.
> +  @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.
> +
> +**/
> +CHAR8 *
> +HiiGetRedfishAsciiString (
> +  IN EFI_HII_HANDLE           HiiHandle,
> +  IN CHAR8                    *Language,
> +  IN EFI_STRING_ID            StringId
> +  )
> +{
> +  EFI_STRING  HiiString;
> +  UINTN       StringSize;
> +  CHAR8       *AsciiString;
> +
> +  HiiString = HiiGetRedfishString (HiiHandle, Language, StringId);
> +  if (HiiString == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a, Can not find string ID: 0x%x with %a\n",
> __FUNCTION__, StringId, Language));
> +    return NULL;
> +  }
> +
> +  StringSize = (StrLen (HiiString) + 1) * sizeof (CHAR8);
> +  AsciiString = AllocatePool (StringSize);
> +  if (AsciiString == NULL) {
> +    return NULL;
> +  }
> +
> +  UnicodeStrToAsciiStrS (HiiString, AsciiString, StringSize);
> +
> +  FreePool (HiiString);
> +  return AsciiString;
> +}
> +
> +/**
> +  Get string from HII database in English language.
> +
> +  @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);
> +}
> +
> +/**
> +  Check and see if this is supported schema or not.
> +
> +  @param[in]  SupportedSchema   The list of supported schema.
> +  @param[in]  Schema            Schema string to be checked.
> +
> +  @retval BOOLEAN               TRUE if this is supported schema. FALSE
> otherwise.
> +
> +**/
> +BOOLEAN
> +CheckSupportedSchema (
> +  IN REDFISH_PLATFORM_CONFIG_SCHEMA   *SupportedSchema,
> +  IN CHAR8                            *Schema
> +  )
> +{
> +  UINTN Index;
> +
> +  if (SupportedSchema == NULL || IS_EMPTY_STRING (Schema)) {
> +    return FALSE;
> +  }
> +
> +  if (SupportedSchema->Count == 0) {
> +    return FALSE;
> +  }
> +
> +  for (Index = 0; Index < SupportedSchema->Count; Index++) {
> +    if (AsciiStrCmp (SupportedSchema->SchemaList[Index], Schema) == 0) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Get the list of supported schema from the given HII handle.
> +
> +  @param[in]  HiiHandle         HII handle instance.
> +  @param[out] SupportedSchema   Supported schema on this HII handle.
> +
> +  @retval EFI_SUCCESS           Schema list is returned.
> +  @retval EFI_INVALID_PARAMETER HiiHandle is NULL or SupportedSchema
> is NULL.
> +  @retval EFI_NOT_FOUND         No supported schema found.
> +  @retval EFI_OUT_OF_RESOURCES  System is out of memory.
> +
> +**/
> +EFI_STATUS
> +GetSupportedSchema (
> +  IN  EFI_HII_HANDLE                  HiiHandle,
> +  OUT REDFISH_PLATFORM_CONFIG_SCHEMA  *SupportedSchema
> +  )
> +{
> +  CHAR8 *SupportedLanguages;
> +  UINTN Index;
> +  UINTN LangIndex;
> +  UINTN Count;
> +  UINTN StrSize;
> +  UINTN ListIndex;
> +
> +  if (HiiHandle == NULL || SupportedSchema == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  SupportedSchema->Count = 0;
> +
> +  SupportedLanguages = HiiGetSupportedLanguages (HiiHandle);
> +  if (SupportedLanguages == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  Index = 0;
> +  LangIndex = 0;
> +  Count = 0;
> +  while (TRUE) {
> +    if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> +      if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> +        ++Count;
> +      }
> +      LangIndex = Index + 1;
> +    }
> +
> +    if (SupportedLanguages[Index] == '\0') {
> +      break;
> +    }
> +
> +    ++Index;
> +  }
> +
> +  if (Count == 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  SupportedSchema->Count = Count;
> +  SupportedSchema->SchemaList = AllocatePool (sizeof (CHAR8 *) * Count);
> +  if (SupportedSchema->SchemaList == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Index = 0;
> +  LangIndex = 0;
> +  ListIndex = 0;
> +  while (TRUE) {
> +
> +    if (SupportedLanguages[Index] == ';' || SupportedLanguages[Index] ==
> '\0') {
> +      if (AsciiStrnCmp (&SupportedLanguages[LangIndex],
> X_UEFI_SCHEMA_PREFIX, AsciiStrLen (X_UEFI_SCHEMA_PREFIX)) == 0) {
> +        StrSize = Index - LangIndex;
> +        SupportedSchema->SchemaList[ListIndex] = AllocateCopyPool ((StrSize
> + 1), &SupportedLanguages[LangIndex]);
> +        SupportedSchema->SchemaList[ListIndex][StrSize] = '\0';
> +        ++ListIndex;
> +      }
> +
> +      LangIndex = Index + 1;
> +    }
> +
> +    if (SupportedLanguages[Index] == '\0') {
> +      break;
> +    }
> +
> +    ++Index;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Search and find statement private instance by given regular expression
> patthern
> +  which describes the Configure Language.
> +
> +  @param[in]  RegularExpressionProtocol   Regular express protocol.
> +  @param[in]  FormsetList                 Form-set list to search.
> +  @param[in]  Schema                      Schema to be matched.
> +  @param[in]  Pattern                     Regular expression pattern.
> +  @param[out] StatementList               Statement list that match above
> pattern.
> +
> +  @retval EFI_SUCCESS             Statement list is returned.
> +  @retval EFI_INVALID_PARAMETER   Input parameter is NULL.
> +  @retval EFI_NOT_READY           Regular express protocol is NULL.
> +  @retval EFI_NOT_FOUND           No statement is found.
> +  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> +
> +**/
> +EFI_STATUS
> +GetStatementPrivateByConfigureLangRegex (
> +  IN  EFI_REGULAR_EXPRESSION_PROTOCOL
> *RegularExpressionProtocol,
> +  IN  LIST_ENTRY                                      *FormsetList,
> +  IN  CHAR8                                           *Schema,
> +  IN  EFI_STRING                                      Pattern,
> +  OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> *StatementList
> +  )
> +{
> +  LIST_ENTRY                      *HiiFormsetLink;
> +  LIST_ENTRY                      *HiiFormsetNextLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> +  LIST_ENTRY                      *HiiFormLink;
> +  LIST_ENTRY                      *HiiNextFormLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> +  LIST_ENTRY                      *HiiStatementLink;
> +  LIST_ENTRY                      *HiiNextStatementLink;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> +  EFI_STRING                      TmpString;
> +  UINTN                           CaptureCount;
> +  BOOLEAN                         IsMatch;
> +  EFI_STATUS                      Status;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
> +
> +  if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (Pattern) || StatementList == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (RegularExpressionProtocol == NULL) {
> +    return EFI_NOT_READY;
> +  }
> +
> +  StatementList->Count = 0;
> +  InitializeListHead (&StatementList->StatementList);
> +
> +  if (IsListEmpty (FormsetList)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  HiiFormsetLink = GetFirstNode (FormsetList);
> +  while (!IsNull (FormsetList, HiiFormsetLink)) {
> +    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> +    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> +    //
> +    // Performance check.
> +    // If there is no desired Redfish schema found, skip this formset.
> +    //
> +    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> +      HiiFormsetLink = HiiFormsetNextLink;
> +      continue;
> +    }
> +
> +    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> +    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> +      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> +      HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> +
> +      HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> +      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> +        HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
> >StatementList, HiiStatementLink);
> +        HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> +
> +        if (HiiStatementPrivate->Description != 0) {
> +          TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> +          if (TmpString != NULL) {
> +            Status = RegularExpressionProtocol->MatchString (
> +                                                  RegularExpressionProtocol,
> +                                                  TmpString,
> +                                                  Pattern,
> +                                                  &gEfiRegexSyntaxTypePerlGuid,
> +                                                  &IsMatch,
> +                                                  NULL,
> +                                                  &CaptureCount
> +                                                  );
> +            if (EFI_ERROR (Status)) {
> +              DEBUG ((DEBUG_ERROR, "%a, MatchString \"%s\" failed: %r\n",
> __FUNCTION__, Pattern, Status));
> +              ASSERT (FALSE);
> +              return Status;
> +            }
> +
> +            //
> +            // Found
> +            //
> +            if (IsMatch) {
> +              StatementRef = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF));
> +              if (StatementRef == NULL) {
> +                return EFI_OUT_OF_RESOURCES;
> +              }
> +
> +              StatementRef->Statement = HiiStatementPrivate;
> +              InsertTailList (&StatementList->StatementList, &StatementRef-
> >Link);
> +              ++StatementList->Count;
> +            }
> +
> +            FreePool (TmpString);
> +          }
> +        }
> +
> +        HiiStatementLink = HiiNextStatementLink;
> +      }
> +
> +      HiiFormLink = HiiNextFormLink;
> +    }
> +
> +    HiiFormsetLink = HiiFormsetNextLink;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Get statement private instance by the given configure language.
> +
> +  @param[in]  FormsetList                 Form-set list to search.
> +  @param[in]  Schema                      Schema to be matched.
> +  @param[in]  ConfigureLang               Configure language.
> +
> +  @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *   Pointer
> to statement private instance.
> +
> +**/
> +REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
> +GetStatementPrivateByConfigureLang (
> +  IN  LIST_ENTRY    *FormsetList,
> +  IN  CHAR8         *Schema,
> +  IN  EFI_STRING    ConfigureLang
> +  )
> +{
> +  LIST_ENTRY                      *HiiFormsetLink;
> +  LIST_ENTRY                      *HiiFormsetNextLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> +  LIST_ENTRY                      *HiiFormLink;
> +  LIST_ENTRY                      *HiiNextFormLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> +  LIST_ENTRY                      *HiiStatementLink;
> +  LIST_ENTRY                      *HiiNextStatementLink;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> +  EFI_STRING                      TmpString;
> +
> +  if (FormsetList == NULL || IS_EMPTY_STRING (Schema) ||
> IS_EMPTY_STRING (ConfigureLang)) {
> +    return NULL;
> +  }
> +
> +  if (IsListEmpty (FormsetList)) {
> +    return NULL;
> +  }
> +
> +  HiiFormsetLink = GetFirstNode (FormsetList);
> +  while (!IsNull (FormsetList, HiiFormsetLink)) {
> +    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> +    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> +    //
> +    // Performance check.
> +    // If there is no desired Redfish schema found, skip this formset.
> +    //
> +    if (!CheckSupportedSchema (&HiiFormsetPrivate->SupportedSchema,
> Schema)) {
> +      HiiFormsetLink = HiiFormsetNextLink;
> +      continue;
> +    }
> +
> +    HiiFormLink = GetFirstNode (&HiiFormsetPrivate->HiiFormList);
> +    while (!IsNull (&HiiFormsetPrivate->HiiFormList, HiiFormLink)) {
> +      HiiNextFormLink = GetNextNode (&HiiFormsetPrivate->HiiFormList,
> HiiFormLink);
> +      HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> +
> +      HiiStatementLink =GetFirstNode (&HiiFormPrivate->StatementList);
> +      while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> +        HiiNextStatementLink = GetNextNode (&HiiFormPrivate-
> >StatementList, HiiStatementLink);
> +        HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> +
> +        DEBUG_CODE (
> +          STATIC UINTN Index = 0;
> +          DEBUG ((DEBUG_INFO, "%a, [%d] search %s in QID: 0x%x form: 0x%x
> formset: %g\n", __FUNCTION__, ++Index, ConfigureLang,
> HiiStatementPrivate->QuestionId, HiiFormPrivate->Id, &HiiFormsetPrivate-
> >Guid));
> +        );
> +
> +        if (HiiStatementPrivate->Description != 0) {
> +          TmpString = HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,
> Schema, HiiStatementPrivate->Description);
> +          if (TmpString != NULL) {
> +            if (StrCmp (TmpString, ConfigureLang) == 0) {
> +              FreePool (TmpString);
> +              return HiiStatementPrivate;
> +            }
> +
> +            FreePool (TmpString);
> +          }
> +        }
> +
> +        HiiStatementLink = HiiNextStatementLink;
> +      }
> +
> +      HiiFormLink = HiiNextFormLink;
> +    }
> +
> +    HiiFormsetLink = HiiFormsetNextLink;
> +  }
> +
> +  return NULL;
> +}
> +
> +/**
> +  Get form-set private instance by the given HII handle.
> +
> +  @param[in]  HiiHandle       HII handle instance.
> +  @param[in]  FormsetList     Form-set list to search.
> +
> +  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to
> form-set private instance.
> +
> +**/
> +REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *
> +GetFormsetPrivateByHiiHandle (
> +  IN  EFI_HII_HANDLE  HiiHandle,
> +  IN  LIST_ENTRY      *FormsetList
> +  )
> +{
> +  LIST_ENTRY                      *HiiFormsetLink;
> +  LIST_ENTRY                      *HiiFormsetNextLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> +
> +  if (HiiHandle == NULL || FormsetList == NULL) {
> +    return NULL;
> +  }
> +
> +  if (IsListEmpty (FormsetList)) {
> +    return NULL;
> +  }
> +
> +  HiiFormsetLink = GetFirstNode (FormsetList);
> +  while (!IsNull (FormsetList, HiiFormsetLink)) {
> +    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> +    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> +    if (HiiFormsetPrivate->HiiHandle == HiiHandle) {
> +      return HiiFormsetPrivate;
> +    }
> +
> +    HiiFormsetLink = HiiFormsetNextLink;
> +  }
> +
> +  return NULL;
> +}
> +
> +/**
> +  Release formset and all the forms and statements that belong to this
> formset.
> +
> +  @param[in]      FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE
> +
> +  @retval         EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +ReleaseFormset (
> +  IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate
> +  )
> +{
> +  LIST_ENTRY                      *HiiFormLink;
> +  LIST_ENTRY                      *HiiNextFormLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> +  LIST_ENTRY                      *HiiStatementLink;
> +  LIST_ENTRY                      *HiiNextStatementLink;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> +  UINTN                           Index;
> +
> +  if (FormsetPrivate == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  HiiFormLink = GetFirstNode (&FormsetPrivate->HiiFormList);
> +  while (!IsNull (&FormsetPrivate->HiiFormList, HiiFormLink)) {
> +    HiiFormPrivate = REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK
> (HiiFormLink);
> +    HiiNextFormLink = GetNextNode (&FormsetPrivate->HiiFormList,
> HiiFormLink);
> +
> +    HiiStatementLink = GetFirstNode (&HiiFormPrivate->StatementList);
> +    while (!IsNull (&HiiFormPrivate->StatementList, HiiStatementLink)) {
> +      HiiStatementPrivate =
> REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK (HiiStatementLink);
> +      HiiNextStatementLink = GetNextNode (&HiiFormPrivate->StatementList,
> HiiStatementLink);
> +
> +      //
> +      // HiiStatementPrivate->HiiStatement will be released in
> DestroyFormSet().
> +      //
> +
> +      if (HiiStatementPrivate->DesStringCache != NULL) {
> +        FreePool (HiiStatementPrivate->DesStringCache);
> +        HiiStatementPrivate->DesStringCache = NULL;
> +      }
> +
> +      RemoveEntryList (&HiiStatementPrivate->Link);
> +      FreePool (HiiStatementPrivate);
> +      HiiStatementLink = HiiNextStatementLink;
> +    }
> +
> +    //
> +    // HiiStatementPrivate->HiiForm will be released in DestroyFormSet().
> +    //
> +
> +    RemoveEntryList (&HiiFormPrivate->Link);
> +    FreePool (HiiFormPrivate);
> +    HiiFormLink = HiiNextFormLink;
> +  }
> +
> +  if (FormsetPrivate->HiiFormSet != NULL) {
> +    DestroyFormSet (FormsetPrivate->HiiFormSet);
> +    FormsetPrivate->HiiFormSet = NULL;
> +  }
> +
> +  if (FormsetPrivate->DevicePathStr != NULL) {
> +    FreePool(FormsetPrivate->DevicePathStr);
> +  }
> +
> +  //
> +  // Release schema list
> +  //
> +  if (FormsetPrivate->SupportedSchema.SchemaList != NULL) {
> +    for (Index = 0; Index < FormsetPrivate->SupportedSchema.Count;
> Index++) {
> +      FreePool (FormsetPrivate->SupportedSchema.SchemaList[Index]);
> +    }
> +
> +    FreePool (FormsetPrivate->SupportedSchema.SchemaList);
> +    FormsetPrivate->SupportedSchema.SchemaList = NULL;
> +    FormsetPrivate->SupportedSchema.Count = 0;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Create new form-set instance.
> +
> +  @retval REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *   Pointer to
> newly created form-set private instance.
> +
> +**/
> +REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *
> +NewFormsetPrivate (
> +  VOID
> +  )
> +{
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *NewFormsetPrivate;
> +
> +  NewFormsetPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE));
> +  if (NewFormsetPrivate == NULL) {
> +    return NULL;
> +  }
> +
> +  //
> +  // Initial newly created formset private data.
> +  //
> +  InitializeListHead (&NewFormsetPrivate->HiiFormList);
> +
> +  return NewFormsetPrivate;
> +}
> +
> +/**
> +  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
> +
> +**/
> +EFI_STATUS
> +LoadFormset (
> +  IN  EFI_HII_HANDLE                  HiiHandle,
> +  OUT REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE
> *FormsetPrivate
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  HII_FORMSET                     *HiiFormSet;
> +  HII_FORM                        *HiiForm;
> +  LIST_ENTRY                      *HiiFormLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_PRIVATE      *HiiFormPrivate;
> +  HII_STATEMENT                   *HiiStatement;
> +  LIST_ENTRY                      *HiiStatementLink;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> *HiiStatementPrivate;
> +  EFI_GUID                        ZeroGuid;
> +
> +  if (HiiHandle == NULL || FormsetPrivate == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +
> +  HiiFormSet = AllocateZeroPool (sizeof (HII_FORMSET));
> +  if (HiiFormSet == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Find HII formset by the given HII handle.
> +  //
> +  ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
> +  Status = CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet);
> +  if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) {
> +    Status = EFI_NOT_FOUND;
> +    goto ErrorExit;
> +  }
> +
> +  //
> +  // Initialize formset
> +  //
> +  InitializeFormSet (HiiFormSet);
> +
> +  //
> +  // Initialize formset private data.
> +  //
> +  FormsetPrivate->HiiFormSet = HiiFormSet;
> +  FormsetPrivate->HiiHandle = HiiHandle;
> +  CopyGuid (&FormsetPrivate->Guid, &HiiFormSet->Guid);
> +  FormsetPrivate->DevicePathStr = ConvertDevicePathToText (HiiFormSet-
> >DevicePath, FALSE, FALSE);
> +  Status = GetSupportedSchema (FormsetPrivate->HiiHandle,
> &FormsetPrivate->SupportedSchema);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_WARN, "%a, No schema from HII handle: 0x%x found:
> %r\n", __FUNCTION__, FormsetPrivate->HiiHandle, Status));
> +  }
> +
> +  HiiFormLink = GetFirstNode (&HiiFormSet->FormListHead);
> +  while (!IsNull (&HiiFormSet->FormListHead, HiiFormLink)) {
> +    HiiForm = HII_FORM_FROM_LINK (HiiFormLink);
> +
> +    HiiFormPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_FORM_PRIVATE));
> +    if (HiiFormPrivate == NULL) {
> +      Status = EFI_OUT_OF_RESOURCES;
> +      goto ErrorExit;
> +    }
> +
> +    //
> +    // Initialize form private data.
> +    //
> +    HiiFormPrivate->HiiForm = HiiForm;
> +    HiiFormPrivate->Id = HiiForm->FormId;
> +    HiiFormPrivate->Title = HiiForm->FormTitle;
> +    HiiFormPrivate->ParentFormset = FormsetPrivate;
> +    InitializeListHead (&HiiFormPrivate->StatementList);
> +
> +    HiiStatementLink = GetFirstNode (&HiiForm->StatementListHead);
> +    while (!IsNull (&HiiForm->StatementListHead, HiiStatementLink)) {
> +      HiiStatement = HII_STATEMENT_FROM_LINK (HiiStatementLink);
> +
> +      HiiStatementPrivate = AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE));
> +      if (HiiStatementPrivate == NULL) {
> +        Status = EFI_OUT_OF_RESOURCES;
> +        goto ErrorExit;
> +      }
> +      //
> +      // Initialize statement private data.
> +      //
> +      HiiStatementPrivate->HiiStatement = HiiStatement;
> +      HiiStatementPrivate->QuestionId = HiiStatement->QuestionId;
> +      HiiStatementPrivate->Description = HiiStatement->Prompt;
> +      HiiStatementPrivate->ParentForm = HiiFormPrivate;
> +
> +      //
> +      // Attach to statement list.
> +      //
> +      InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate-
> >Link);
> +      HiiStatementLink = GetNextNode (&HiiForm->StatementListHead,
> HiiStatementLink);
> +    }
> +    //
> +    // Attach to form list.
> +    //
> +    InsertTailList (&FormsetPrivate->HiiFormList, &HiiFormPrivate->Link);
> +    HiiFormLink = GetNextNode (&HiiFormSet->FormListHead, HiiFormLink);
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +ErrorExit:
> +
> +  //
> +  // Release HiiFormSet if HiiFormSet is not linked to FormsetPrivate yet.
> +  //
> +  if (HiiFormSet != NULL && FormsetPrivate->HiiFormSet != HiiFormSet) {
> +    DestroyFormSet (HiiFormSet);
> +  }
> +
> +  //
> +  // Release resource when error happens.
> +  //
> +  ReleaseFormset (FormsetPrivate);
> +
> +  return Status;
> +}
> +
> +/**
> +  Release formset list and all the forms that belong to this formset.
> +
> +  @param[in]      FormsetList   Pointer to formst list that needs to be
> +                                released.
> +
> +  @retval         EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +LoadFormsetList (
> +  IN   EFI_HII_HANDLE   *HiiHandle,
> +  OUT  LIST_ENTRY       *FormsetList
> +  )
> +{
> +  EFI_STATUS  Status;
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;
> +
> +  if (HiiHandle == NULL || FormsetList == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  FormsetPrivate = GetFormsetPrivateByHiiHandle (HiiHandle, FormsetList);
> +  if (FormsetPrivate != NULL) {
> +    return EFI_ALREADY_STARTED;
> +  }
> +
> +  FormsetPrivate =  NewFormsetPrivate ();
> +  if (FormsetPrivate == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a, out of resource\n", __FUNCTION__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Load formset on the given HII handle.
> +  //
> +  Status = LoadFormset (HiiHandle, FormsetPrivate);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a, failed to load formset: %r\n",
> __FUNCTION__, Status));
> +    FreePool (FormsetPrivate);
> +    return Status;
> +  }
> +
> +  //
> +  // Attach to cache list.
> +  //
> +  InsertTailList (FormsetList, &FormsetPrivate->Link);
> +
> +  DEBUG_CODE (
> +    DumpFormsetList (FormsetList);
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Release formset list and all the forms that belong to this formset.
> +
> +  @param[in]      FormsetList   Pointer to formst list that needs to be
> +                                released.
> +
> +  @retval         EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +ReleaseFormsetList (
> +  IN  LIST_ENTRY      *FormsetList
> +  )
> +{
> +  LIST_ENTRY                      *HiiFormsetLink;
> +  LIST_ENTRY                      *HiiFormsetNextLink;
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *HiiFormsetPrivate;
> +
> +  if (FormsetList == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (IsListEmpty (FormsetList)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  HiiFormsetLink = GetFirstNode (FormsetList);
> +  while (!IsNull (FormsetList, HiiFormsetLink)) {
> +    HiiFormsetNextLink = GetNextNode (FormsetList, HiiFormsetLink);
> +    HiiFormsetPrivate =
> REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK (HiiFormsetLink);
> +
> +    //
> +    // Detach from list.
> +    //
> +    RemoveEntryList (&HiiFormsetPrivate->Link);
> +    ReleaseFormset (HiiFormsetPrivate);
> +    FreePool (HiiFormsetPrivate);
> +    HiiFormsetLink = HiiFormsetNextLink;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Get all pending list.
> +
> +  @param[in]  HiiHandle   HII handle instance.
> +  @param[in]  PendingList Pending list to keep pending data.
> +
> +  @retval REDFISH_PLATFORM_CONFIG_PENDING_LIST *   Pointer to
> pending list data.
> +
> +**/
> +REDFISH_PLATFORM_CONFIG_PENDING_LIST *
> +GetPendingList (
> +  IN  EFI_HII_HANDLE   *HiiHandle,
> +  IN  LIST_ENTRY       *PendingList
> +  )
> +{
> +  LIST_ENTRY                 *PendingListLink;
> +  REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
> +
> +  if (HiiHandle == NULL || PendingList == NULL) {
> +    return NULL;
> +  }
> +
> +  if (IsListEmpty (PendingList)) {
> +    return NULL;
> +  }
> +
> +  PendingListLink = GetFirstNode (PendingList);
> +  while (!IsNull (PendingList, PendingListLink)) {
> +    Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> +
> +    if (Target->HiiHandle == HiiHandle) {
> +      return Target;
> +    }
> +
> +    PendingListLink = GetNextNode (PendingList, PendingListLink);
> +  }
> +
> +  return NULL;
> +}
> +
> +/**
> +  When HII database is updated. Keep updated HII handle into pending list
> so
> +  we can process them later.
> +
> +  @param[in]  HiiHandle   HII handle instance.
> +  @param[in]  PendingList Pending list to keep HII handle which is recently
> updated.
> +
> +  @retval EFI_SUCCESS             HII handle is saved in pending list.
> +  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is
> NULL.
> +  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> +
> +**/
> +EFI_STATUS
> +NotifyFormsetUpdate (
> +  IN  EFI_HII_HANDLE   *HiiHandle,
> +  IN  LIST_ENTRY       *PendingList
> +  )
> +{
> +  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;
> +
> +  if (HiiHandle == NULL || PendingList == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Check and see if this HII handle is processed already.
> +  //
> +  TargetPendingList = GetPendingList (HiiHandle, PendingList);
> +  if (TargetPendingList != NULL) {
> +    TargetPendingList->IsDeleted = FALSE;
> +  DEBUG_CODE (
> +    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated\n",
> __FUNCTION__, HiiHandle));
> +    );
> +    return EFI_SUCCESS;
> +  }
> +
> +  TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> +  if (TargetPendingList == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  TargetPendingList->HiiHandle = HiiHandle;
> +  TargetPendingList->IsDeleted = FALSE;
> +
> +  InsertTailList (PendingList, &TargetPendingList->Link);
> +
> +  DEBUG_CODE (
> +    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is created\n",
> __FUNCTION__, HiiHandle));
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  When HII database is updated and form-set is deleted. Keep deleted HII
> handle into pending list so
> +  we can process them later.
> +
> +  @param[in]  HiiHandle   HII handle instance.
> +  @param[in]  PendingList Pending list to keep HII handle which is recently
> updated.
> +
> +  @retval EFI_SUCCESS             HII handle is saved in pending list.
> +  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is
> NULL.
> +  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> +
> +**/
> +EFI_STATUS
> +NotifyFormsetDeleted (
> +  IN  EFI_HII_HANDLE   *HiiHandle,
> +  IN  LIST_ENTRY       *PendingList
> +  )
> +{
> +  REDFISH_PLATFORM_CONFIG_PENDING_LIST  *TargetPendingList;
> +
> +  if (HiiHandle == NULL || PendingList == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Check and see if this HII handle is processed already.
> +  //
> +  TargetPendingList = GetPendingList (HiiHandle, PendingList);
> +  if (TargetPendingList != NULL) {
> +    TargetPendingList->IsDeleted = TRUE;
> +    DEBUG_CODE (
> +      DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is updated and deleted\n",
> __FUNCTION__, HiiHandle));
> +      );
> +    return EFI_SUCCESS;
> +  }
> +
> +  TargetPendingList= AllocateZeroPool (sizeof
> (REDFISH_PLATFORM_CONFIG_PENDING_LIST));
> +  if (TargetPendingList == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  TargetPendingList->HiiHandle = HiiHandle;
> +  TargetPendingList->IsDeleted = TRUE;
> +
> +  InsertTailList (PendingList, &TargetPendingList->Link);
> +
> +  DEBUG_CODE (
> +    DEBUG ((DEBUG_INFO, "%a, HII handle: 0x%x is deleted\n",
> __FUNCTION__, HiiHandle));
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  There are HII database update and we need to process them accordingly
> so that we
> +  won't use stale data. This function will parse updated HII handle again in
> order
> +  to get updated data-set.
> +
> +  @param[in]  FormsetList   List to keep HII form-set.
> +  @param[in]  PendingList   List to keep HII handle that is updated.
> +
> +  @retval EFI_SUCCESS             HII handle is saved in pending list.
> +  @retval EFI_INVALID_PARAMETER   FormsetList is NULL or PendingList is
> NULL.
> +
> +**/
> +EFI_STATUS
> +ProcessPendingList (
> +  IN  LIST_ENTRY       *FormsetList,
> +  IN  LIST_ENTRY       *PendingList
> +  )
> +{
> +  LIST_ENTRY                 *PendingListLink;
> +  LIST_ENTRY                 *PendingListNextLink;
> +  REDFISH_PLATFORM_CONFIG_PENDING_LIST *Target;
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *FormsetPrivate;
> +  EFI_STATUS                      Status;
> +
> +
> +  if (FormsetList == NULL || PendingList == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (IsListEmpty (PendingList)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  PendingListLink = GetFirstNode (PendingList);
> +  while (!IsNull (PendingList, PendingListLink)) {
> +    PendingListNextLink = GetNextNode (PendingList, PendingListLink);
> +    Target = REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK
> (PendingListLink);
> +
> +    if (Target->IsDeleted) {
> +      //
> +      // The HII resource on this HII handle is removed. Release the formset.
> +      //
> +      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> +      if (FormsetPrivate != NULL) {
> +        DEBUG ((DEBUG_INFO, "%a, formset: %g is removed because driver
> release HII resource it already\n", __FUNCTION__, FormsetPrivate->Guid));
> +        RemoveEntryList (&FormsetPrivate->Link);
> +        ReleaseFormset (FormsetPrivate);
> +        FreePool (FormsetPrivate);
> +      } else {
> +        DEBUG ((DEBUG_WARN, "%a, formset on HII handle 0x%x was
> removed already\n", __FUNCTION__, Target->HiiHandle));
> +      }
> +    } else {
> +      //
> +      // The HII resource on this HII handle is updated/removed.
> +      //
> +      FormsetPrivate = GetFormsetPrivateByHiiHandle (Target->HiiHandle,
> FormsetList);
> +      if (FormsetPrivate != NULL) {
> +        //
> +        // HII formset already exist, release it and query again.
> +        //
> +        DEBUG ((DEBUG_INFO, "%a, formset: %g is updated. Release current
> formset\n", __FUNCTION__, &FormsetPrivate->Guid));
> +        RemoveEntryList (&FormsetPrivate->Link);
> +        ReleaseFormset (FormsetPrivate);
> +        FreePool (FormsetPrivate);
> +      }
> +
> +      Status = LoadFormsetList (Target->HiiHandle, FormsetList);
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((DEBUG_ERROR, "%a, load formset from HII handle: 0x%x
> failed: %r\n", __FUNCTION__, Target->HiiHandle, Status));
> +      }
> +    }
> +
> +    //
> +    // Detach it from list first.
> +    //
> +    RemoveEntryList (&Target->Link);
> +    FreePool (Target);
> +
> +    PendingListLink = PendingListNextLink;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Release all resource in statement list.
> +
> +  @param[in]  StatementList   Statement list to be released.
> +
> +  @retval EFI_SUCCESS             All resource are released.
> +  @retval EFI_INVALID_PARAMETER   StatementList is NULL.
> +
> +**/
> +EFI_STATUS
> +ReleaseStatementList (
> +  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> *StatementList
> +  )
> +{
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF *StatementRef;
> +  LIST_ENTRY  *NextLink;
> +
> +  if (StatementList == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (IsListEmpty (&StatementList->StatementList)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  NextLink = GetFirstNode (&StatementList->StatementList);
> +  while (!IsNull (&StatementList->StatementList, NextLink)) {
> +    StatementRef =
> REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK (NextLink);
> +    NextLink = GetNextNode (&StatementList->StatementList, NextLink);
> +
> +    RemoveEntryList (&StatementRef->Link);
> +    FreePool (StatementRef);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> index e0ba0fb2d3..cd7a52aef3 100644
> --- a/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> +++ b/RedfishPkg/RedfishPlatformConfigDxe/RedfishPlatformConfigImpl.h
> @@ -1,274 +1,297 @@
> -/** @file
> -  This file defines the EDKII Redfish Platform Config Protocol interface.
> -
> -  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> -
> -  SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> -#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> -
> -#include <Uefi.h>
> -
> -//
> -// Libraries
> -//
> -#include <Library/BaseLib.h>
> -#include <Library/BaseMemoryLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/DevicePathLib.h>
> -#include <Library/HiiUtilityLib.h>
> -#include <Library/HiiLib.h>
> -#include <Library/MemoryAllocationLib.h>
> -#include <Library/UefiBootServicesTableLib.h>
> -#include <Library/UefiLib.h>
> -
> -#define REDFISH_PLATFORM_CONFIG_DELETE_EXPIRED_FORMSET   0x00
> -#define IS_EMPTY_STRING(a)                               (a == NULL || a[0] == L'\0')
> -#define ENGLISH_LANGUAGE_CODE                            "en-US"
> -#define X_UEFI_SCHEMA_PREFIX                             "x-uefi-redfish-"
> -
> -//
> -// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
> -//
> -typedef struct {
> -  LIST_ENTRY                    Link;
> -  EFI_HII_HANDLE                HiiHandle;
> -  BOOLEAN                       IsDeleted;
> -} REDFISH_PLATFORM_CONFIG_PENDING_LIST;
> -
> -#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a)
> BASE_CR (a, REDFISH_PLATFORM_CONFIG_PENDING_LIST, Link)
> -
> -typedef struct {
> -  UINTN   Count;                                // Number of schema in list
> -  CHAR8   **SchemaList;                         // Schema list
> -} REDFISH_PLATFORM_CONFIG_SCHEMA;
> -
> -//
> -// 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.
> -} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
> -
> -#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a)  BASE_CR
> (a, REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE, Link)
> -
> -//
> -// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE
> -//
> -typedef struct {
> -  LIST_ENTRY                                Link;
> -  UINT16                                    Id;             // Form ID.
> -  EFI_STRING_ID                             Title;          // String token of form title.
> -  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *ParentFormset;
> -  HII_FORM                                  *HiiForm;       // Pointer to HII form data.
> -  LIST_ENTRY                                StatementList;  // Statement list that keep
> statement under this form.
> -} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
> -
> -#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a)  BASE_CR (a,
> REDFISH_PLATFORM_CONFIG_FORM_PRIVATE, Link)
> -
> -//
> -// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> -//
> -typedef struct {
> -  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                            DesStringCache; // The string cache for search
> function.
> -} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
> -
> -#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
> BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
> -
> -//
> -// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
> -//
> -typedef struct {
> -  LIST_ENTRY                                Link;
> -  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement;
> -} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF;
> -
> -#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a)
> BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
> -
> -//
> -// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> -//
> -typedef struct {
> -  LIST_ENTRY  StatementList;        // List of
> REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
> -  UINTN       Count;
> -} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST;
> -
> -/**
> -  Release formset list and all the forms that belong to this formset.
> -
> -  @param[in]      FormsetList   Pointer to formst list that needs to be
> -                                released.
> -
> -  @retval         EFI_STATUS
> -
> -**/
> -EFI_STATUS
> -ReleaseFormsetList (
> -  IN  LIST_ENTRY      *FormsetList
> -  );
> -
> -/**
> -  Release formset list and all the forms that belong to this formset.
> -
> -  @param[in]      FormsetList   Pointer to formst list that needs to be
> -                                released.
> -
> -  @retval         EFI_STATUS
> -
> -**/
> -EFI_STATUS
> -LoadFormsetList (
> -  IN   EFI_HII_HANDLE   *HiiHandle,
> -  OUT  LIST_ENTRY       *FormsetList
> -  );
> -
> -/**
> -  When HII database is updated. Keep updated HII handle into pending list so
> -  we can process them later.
> -
> -  @param[in]  HiiHandle   HII handle instance.
> -  @param[in]  PendingList Pending list to keep HII handle which is recently
> updated.
> -
> -  @retval EFI_SUCCESS             HII handle is saved in pending list.
> -  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is
> NULL.
> -  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> -
> -**/
> -EFI_STATUS
> -NotifyFormsetUpdate (
> -  IN  EFI_HII_HANDLE   *HiiHandle,
> -  IN  LIST_ENTRY       *PendingList
> -  );
> -
> -/**
> -  When HII database is updated and form-set is deleted. Keep deleted HII
> handle into pending list so
> -  we can process them later.
> -
> -  @param[in]  HiiHandle   HII handle instance.
> -  @param[in]  PendingList Pending list to keep HII handle which is recently
> updated.
> -
> -  @retval EFI_SUCCESS             HII handle is saved in pending list.
> -  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is
> NULL.
> -  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> -
> -**/
> -EFI_STATUS
> -NotifyFormsetDeleted (
> -  IN  EFI_HII_HANDLE   *HiiHandle,
> -  IN  LIST_ENTRY       *PendingList
> -  );
> -
> -/**
> -  Get statement private instance by the given configure language.
> -
> -  @param[in]  FormsetList                 Form-set list to search.
> -  @param[in]  Schema                      Schema to be matched.
> -  @param[in]  ConfigureLang               Configure language.
> -
> -  @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *   Pointer to
> statement private instance.
> -
> -**/
> -REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
> -GetStatementPrivateByConfigureLang (
> -  IN  LIST_ENTRY    *FormsetList,
> -  IN  CHAR8         *Schema,
> -  IN  EFI_STRING    ConfigureLang
> -  );
> -
> -/**
> -  Search and find statement private instance by given regular expression
> patthern
> -  which describes the Configure Language.
> -
> -  @param[in]  RegularExpressionProtocol   Regular express protocol.
> -  @param[in]  FormsetList                 Form-set list to search.
> -  @param[in]  Schema                      Schema to be matched.
> -  @param[in]  Pattern                     Regular expression pattern.
> -  @param[out] StatementList               Statement list that match above
> pattern.
> -
> -  @retval EFI_SUCCESS             Statement list is returned.
> -  @retval EFI_INVALID_PARAMETER   Input parameter is NULL.
> -  @retval EFI_NOT_READY           Regular express protocol is NULL.
> -  @retval EFI_NOT_FOUND           No statement is found.
> -  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> -
> -**/
> -EFI_STATUS
> -GetStatementPrivateByConfigureLangRegex (
> -  IN  EFI_REGULAR_EXPRESSION_PROTOCOL
> *RegularExpressionProtocol,
> -  IN  LIST_ENTRY                                      *FormsetList,
> -  IN  CHAR8                                           *Schema,
> -  IN  EFI_STRING                                      Pattern,
> -  OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> *StatementList
> -  );
> -
> -/**
> -  There are HII database update and we need to process them accordingly so
> that we
> -  won't use stale data. This function will parse updated HII handle again in
> order
> -  to get updated data-set.
> -
> -  @param[in]  FormsetList   List to keep HII form-set.
> -  @param[in]  PendingList   List to keep HII handle that is updated.
> -
> -  @retval EFI_SUCCESS             HII handle is saved in pending list.
> -  @retval EFI_INVALID_PARAMETER   FormsetList is NULL or PendingList is
> NULL.
> -
> -**/
> -EFI_STATUS
> -ProcessPendingList (
> -  IN  LIST_ENTRY       *FormsetList,
> -  IN  LIST_ENTRY       *PendingList
> -  );
> -
> -/**
> -  Retrieves a string from a string package in a English language. The
> -  returned string is allocated using AllocatePool().  The caller is responsible
> -  for freeing the allocated buffer using FreePool().
> -
> -  If HiiHandle is NULL, then ASSERT().
> -  If StringId is 0, then ASSET.
> -
> -  @param[in]  HiiStringProtocol EFI_HII_STRING_PROTOCOL instance.
> -  @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
> -HiiGetRedfishString (
> -  IN EFI_HII_HANDLE           HiiHandle,
> -  IN CHAR8                    *Language,
> -  IN EFI_STRING_ID            StringId
> -  );
> -
> -/**
> -  Release all resource in statement list.
> -
> -  @param[in]  StatementList   Statement list to be released.
> -
> -  @retval EFI_SUCCESS             All resource are released.
> -  @retval EFI_INVALID_PARAMETER   StatementList is NULL.
> -
> -**/
> -EFI_STATUS
> -ReleaseStatementList (
> -  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> *StatementList
> -  );
> -
> -#endif
> +/** @file
> +  This file defines the EDKII Redfish Platform Config Protocol interface.
> +
> +  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> +#define EDKII_REDFISH_PLATFORM_CONFIG_IMPL_H_
> +
> +#include <Uefi.h>
> +
> +//
> +// Libraries
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiUtilityLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +#define IS_EMPTY_STRING(a)                               (a == NULL || a[0] == L'\0')
> +#define ENGLISH_LANGUAGE_CODE                            "en-US"
> +#define X_UEFI_SCHEMA_PREFIX                             "x-uefi-redfish-"
> +
> +//
> +// Definition of REDFISH_PLATFORM_CONFIG_PRIVATE.
> +//
> +typedef struct {
> +  LIST_ENTRY                    Link;
> +  EFI_HII_HANDLE                HiiHandle;
> +  BOOLEAN                       IsDeleted;
> +} REDFISH_PLATFORM_CONFIG_PENDING_LIST;
> +
> +#define REDFISH_PLATFORM_CONFIG_PENDING_LIST_FROM_LINK(a)
> BASE_CR (a, REDFISH_PLATFORM_CONFIG_PENDING_LIST, Link)
> +
> +typedef struct {
> +  UINTN   Count;                                // Number of schema in list
> +  CHAR8   **SchemaList;                         // Schema list
> +} REDFISH_PLATFORM_CONFIG_SCHEMA;
> +
> +//
> +// 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.
> +} REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE;
> +
> +#define REDFISH_PLATFORM_CONFIG_FORMSET_FROM_LINK(a)  BASE_CR
> (a, REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE, Link)
> +
> +//
> +// Definition of REDFISH_PLATFORM_CONFIG_FORM_PRIVATE
> +//
> +typedef struct {
> +  LIST_ENTRY                                Link;
> +  UINT16                                    Id;             // Form ID.
> +  EFI_STRING_ID                             Title;          // String token of form title.
> +  REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE  *ParentFormset;
> +  HII_FORM                                  *HiiForm;       // Pointer to HII form data.
> +  LIST_ENTRY                                StatementList;  // Statement list that keep
> statement under this form.
> +} REDFISH_PLATFORM_CONFIG_FORM_PRIVATE;
> +
> +#define REDFISH_PLATFORM_CONFIG_FORM_FROM_LINK(a)  BASE_CR (a,
> REDFISH_PLATFORM_CONFIG_FORM_PRIVATE, Link)
> +
> +//
> +// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE
> +//
> +typedef struct {
> +  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                            DesStringCache; // The string cache for search
> function.
> +} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE;
> +
> +#define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a)
> BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link)
> +
> +//
> +// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
> +//
> +typedef struct {
> +  LIST_ENTRY                                Link;
> +  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *Statement;
> +} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF;
> +
> +#define REDFISH_PLATFORM_CONFIG_STATEMENT_REF_FROM_LINK(a)
> BASE_CR (a, REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF, Link)
> +
> +//
> +// Definition of REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> +//
> +typedef struct {
> +  LIST_ENTRY  StatementList;        // List of
> REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_REF
> +  UINTN       Count;
> +} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST;
> +
> +/**
> +  Release formset list and all the forms that belong to this formset.
> +
> +  @param[in]      FormsetList   Pointer to formst list that needs to be
> +                                released.
> +
> +  @retval         EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +ReleaseFormsetList (
> +  IN  LIST_ENTRY      *FormsetList
> +  );
> +
> +/**
> +  Release formset list and all the forms that belong to this formset.
> +
> +  @param[in]      FormsetList   Pointer to formst list that needs to be
> +                                released.
> +
> +  @retval         EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +LoadFormsetList (
> +  IN   EFI_HII_HANDLE   *HiiHandle,
> +  OUT  LIST_ENTRY       *FormsetList
> +  );
> +
> +/**
> +  When HII database is updated. Keep updated HII handle into pending list
> so
> +  we can process them later.
> +
> +  @param[in]  HiiHandle   HII handle instance.
> +  @param[in]  PendingList Pending list to keep HII handle which is recently
> updated.
> +
> +  @retval EFI_SUCCESS             HII handle is saved in pending list.
> +  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is
> NULL.
> +  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> +
> +**/
> +EFI_STATUS
> +NotifyFormsetUpdate (
> +  IN  EFI_HII_HANDLE   *HiiHandle,
> +  IN  LIST_ENTRY       *PendingList
> +  );
> +
> +/**
> +  When HII database is updated and form-set is deleted. Keep deleted HII
> handle into pending list so
> +  we can process them later.
> +
> +  @param[in]  HiiHandle   HII handle instance.
> +  @param[in]  PendingList Pending list to keep HII handle which is recently
> updated.
> +
> +  @retval EFI_SUCCESS             HII handle is saved in pending list.
> +  @retval EFI_INVALID_PARAMETER   HiiHnalde is NULL or PendingList is
> NULL.
> +  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> +
> +**/
> +EFI_STATUS
> +NotifyFormsetDeleted (
> +  IN  EFI_HII_HANDLE   *HiiHandle,
> +  IN  LIST_ENTRY       *PendingList
> +  );
> +
> +/**
> +  Get statement private instance by the given configure language.
> +
> +  @param[in]  FormsetList                 Form-set list to search.
> +  @param[in]  Schema                      Schema to be matched.
> +  @param[in]  ConfigureLang               Configure language.
> +
> +  @retval REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *   Pointer
> to statement private instance.
> +
> +**/
> +REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *
> +GetStatementPrivateByConfigureLang (
> +  IN  LIST_ENTRY    *FormsetList,
> +  IN  CHAR8         *Schema,
> +  IN  EFI_STRING    ConfigureLang
> +  );
> +
> +/**
> +  Search and find statement private instance by given regular expression
> patthern
> +  which describes the Configure Language.
> +
> +  @param[in]  RegularExpressionProtocol   Regular express protocol.
> +  @param[in]  FormsetList                 Form-set list to search.
> +  @param[in]  Schema                      Schema to be matched.
> +  @param[in]  Pattern                     Regular expression pattern.
> +  @param[out] StatementList               Statement list that match above
> pattern.
> +
> +  @retval EFI_SUCCESS             Statement list is returned.
> +  @retval EFI_INVALID_PARAMETER   Input parameter is NULL.
> +  @retval EFI_NOT_READY           Regular express protocol is NULL.
> +  @retval EFI_NOT_FOUND           No statement is found.
> +  @retval EFI_OUT_OF_RESOURCES    System is out of memory.
> +
> +**/
> +EFI_STATUS
> +GetStatementPrivateByConfigureLangRegex (
> +  IN  EFI_REGULAR_EXPRESSION_PROTOCOL
> *RegularExpressionProtocol,
> +  IN  LIST_ENTRY                                      *FormsetList,
> +  IN  CHAR8                                           *Schema,
> +  IN  EFI_STRING                                      Pattern,
> +  OUT REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> *StatementList
> +  );
> +
> +/**
> +  There are HII database update and we need to process them accordingly
> so that we
> +  won't use stale data. This function will parse updated HII handle again in
> order
> +  to get updated data-set.
> +
> +  @param[in]  FormsetList   List to keep HII form-set.
> +  @param[in]  PendingList   List to keep HII handle that is updated.
> +
> +  @retval EFI_SUCCESS             HII handle is saved in pending list.
> +  @retval EFI_INVALID_PARAMETER   FormsetList is NULL or PendingList is
> NULL.
> +
> +**/
> +EFI_STATUS
> +ProcessPendingList (
> +  IN  LIST_ENTRY       *FormsetList,
> +  IN  LIST_ENTRY       *PendingList
> +  );
> +
> +/**
> +  Retrieves a unicode string from a string package in a given language. The
> +  returned string is allocated using AllocatePool().  The caller is responsible
> +  for freeing the allocated buffer using FreePool().
> +
> +  If HiiHandle is NULL, then ASSERT().
> +  If StringId is 0, then ASSET.
> +
> +  @param[in]  HiiHandle         A handle that was previously registered in the
> HII Database.
> +  @param[in]  Language          The specified configure language to get string.
> +  @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
> +HiiGetRedfishString (
> +  IN EFI_HII_HANDLE           HiiHandle,
> +  IN CHAR8                    *Language,
> +  IN EFI_STRING_ID            StringId
> +  );
> +
> +/**
> +  Retrieves a ASCII string from a string package in a given language. The
> +  returned string is allocated using AllocatePool().  The caller is responsible
> +  for freeing the allocated buffer using FreePool().
> +
> +  If HiiHandle is NULL, then ASSERT().
> +  If StringId is 0, then ASSET.
> +
> +  @param[in]  HiiHandle         A handle that was previously registered in the
> HII Database.
> +  @param[in]  Language          The specified configure language to get string.
> +  @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.
> +
> +**/
> +CHAR8 *
> +HiiGetRedfishAsciiString (
> +  IN EFI_HII_HANDLE           HiiHandle,
> +  IN CHAR8                    *Language,
> +  IN EFI_STRING_ID            StringId
> +  );
> +
> +/**
> +  Release all resource in statement list.
> +
> +  @param[in]  StatementList   Statement list to be released.
> +
> +  @retval EFI_SUCCESS             All resource are released.
> +  @retval EFI_INVALID_PARAMETER   StatementList is NULL.
> +
> +**/
> +EFI_STATUS
> +ReleaseStatementList (
> +  IN  REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST
> *StatementList
> +  );
> +
> +#endif
> --
> 2.32.0.windows.2


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#91797): https://edk2.groups.io/g/devel/message/91797
Mute This Topic: https://groups.io/mt/92598008/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-