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