From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 968D374004C for ; Tue, 26 Mar 2024 15:15:40 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=R1usTBn39qnpBuTPLZ8Z4v7kR4bIug/vOu+WtJzF8JU=; c=relaxed/simple; d=groups.io; h=Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20240206; t=1711466139; v=1; b=Gnef+IDBulR36VIl8uIbkN869QpJ+FxSH+np6iXGOWiWAYos/Io6OG/RHomKmlG7wzRE9hGT LT5X7VT65+OLBAPMlxjf02JR6yxqWCOIcXqjYC27/W/rC6CyFuxhIvvwiVOVtzoe6ubKxVnUSPN 1QzlPGyJFzLE70DAATq59S7HQZutCv5e4KFKEJ6NAirPVkiQLEnYlenzNJvF7vL+i5skL4Q2wgk LlBUH6rZqQJetCvuj5pH3WO1s+VJHMinNvQQQkmIkhPjRrWwTFOr5HYwgaRfQOjyp9x8H6BoKZr daueGzrYXckkSVuLUXiW2lU+35BDraCwftfSrRvlbuyNw== X-Received: by 127.0.0.2 with SMTP id DPnvYY7687511xXqRm0M6pbr; Tue, 26 Mar 2024 08:15:39 -0700 X-Received: from NAM11-DM6-obe.outbound.protection.outlook.com (NAM11-DM6-obe.outbound.protection.outlook.com [40.107.223.59]) by mx.groups.io with SMTP id smtpd.web10.11959.1711466138293840839 for ; Tue, 26 Mar 2024 08:15:38 -0700 X-Received: from PH7P221CA0028.NAMP221.PROD.OUTLOOK.COM (2603:10b6:510:32a::16) by MN2PR12MB4373.namprd12.prod.outlook.com (2603:10b6:208:261::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7409.33; Tue, 26 Mar 2024 15:15:35 +0000 X-Received: from CY4PEPF0000E9D9.namprd05.prod.outlook.com (2603:10b6:510:32a:cafe::bf) by PH7P221CA0028.outlook.office365.com (2603:10b6:510:32a::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7409.13 via Frontend Transport; Tue, 26 Mar 2024 15:15:34 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by CY4PEPF0000E9D9.mail.protection.outlook.com (10.167.241.77) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7409.10 via Frontend Transport; Tue, 26 Mar 2024 15:15:34 +0000 X-Received: from TPE-L1-ABNCHANG.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Tue, 26 Mar 2024 10:15:32 -0500 From: "Chang, Abner via groups.io" To: CC: Nickle Wang , Igor Kulchytskyy Subject: [edk2-devel] [PATCH V2 1/6] RedfishPkg/RedfishPlatformConfigDxe: Config language searching optimization Date: Tue, 26 Mar 2024 23:14:57 +0800 Message-ID: <20240326151503.106-2-abner.chang@amd.com> In-Reply-To: <20240326151503.106-1-abner.chang@amd.com> References: <20240326151503.106-1-abner.chang@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CY4PEPF0000E9D9:EE_|MN2PR12MB4373:EE_ X-MS-Office365-Filtering-Correlation-Id: b2588c3e-300d-495b-2969-08dc4da795c2 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: arIT3p1euGbVPJg/G9sHvfkqLV+kSZ8N4MpaX9jxUxYaCHLuWAXoYKhACssWitrYeVCtAZb+kLtuIoQaavjf3c73hlG6xTx+V3VP2Rp/0cUL5u4sFS7keRAYhFUOrv03po3SAoSEZZGH8ZvaeIDGGAHCdefdoJCytRjQOXcdQCn11R+cc7XAf5mayHaV/9TvN9s+6mk4Qy725D7h6D89iW6SdwzCf/TfrUZxXggIsHXJHOK2nHh634r/5PH7YBjqtK6wHpXQkWsfNyAdl3lGaRPSxf9PcBHh+3qPJ6XaLeVTSwmOD01+jWF30alZFRmJ/Srf02dWYWdsfokII7arkmo9iRj2Xwr+Vx3WBTXoPUrOOCKuc19f3An63YlsUWltomTOgooSaUR7+/u8eFVvfxU9y+J4FwVFVbd9RoOaVbxtb8octbgd5OmCpqRwyDNAzKqzuQNLyEG9OZfjHknuF+57syBf/ykEWUw6JQsBAag3SMAQBHkmgCPBWANcI59WndR2XuG5KjbtwKLmn/lF2+efAMWwWAafW3oEefj+mA1qwvx8mLVdSFK+P1XJMCSNTBBXAZkgU/GKfp5c2acdqL5YvSR/q5EfQyTSV3dtoZUvYOj7B/SsU0F+vclPdg+iQwTo/tOS+zV1Su0R9SSdVYPj55wIHfU7zSXxnzRhIJf+zBA1tIqrYuOUIFsEi4UwAIZvJYuuqFJUVZ6RWy+z/i28oOhxrQXQtzND6Y6SYk1vUzKLL9zWFg7WHL+1f36P X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Mar 2024 15:15:34.6237 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b2588c3e-300d-495b-2969-08dc4da795c2 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: CY4PEPF0000E9D9.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4373 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Tue, 26 Mar 2024 08:15:38 -0700 Reply-To: devel@edk2.groups.io,abner.chang@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: E0cH5cGmvQDdch2ZD7wdpqjLx7686176AA= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=Gnef+IDB; dmarc=pass (policy=none) header.from=groups.io; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io From: abnchang 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 Co-authored-by: Nickle Wang Cc: Igor Kulchytskyy --- .../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 str= ucture. =20 (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
- Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -30,6 +31,10 @@ #define ENGLISH_LANGUAGE_CODE "en-US" #define X_UEFI_SCHEMA_PREFIX "x-uefi-redfish-" =20 +#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; =20 +// 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_NUMB= ER 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_AR= RAY_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 for= mset data. - EFI_GUID Guid; // Formset GUID. - EFI_HII_HANDLE HiiHandle; // Hii Handle of this= formset. - LIST_ENTRY HiiFormList; // Form list that kee= p form data under this formset. - CHAR16 *DevicePathStr; // Device path of thi= s formset. - REDFISH_PLATFORM_CONFIG_SCHEMA SupportedSchema; // Schema that is sup= ported in this formset. + HII_FORMSET *HiiFormSet; // Pointer= to HII formset data. + EFI_GUID Guid; // Formset= GUID. + EFI_HII_HANDLE HiiHandle; // Hii Han= dle of this formset. + EFI_HII_PACKAGE_LIST_HEADER *HiiPackageListHeader; // Hii Pac= kage list header. + LIST_ENTRY HiiFormList; // Form li= st 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; =20 #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 toke= n of this question. - EFI_STRING_ID Help; // String toke= n of help message. - EFI_STRING DesStringCache; // The string = cache for search function. - UINT8 Flags; // The stateme= nt flag. - REDFISH_PLATFORM_CONFIG_STATEMENT_DATA StatementData; // The max/min= for statement value. - BOOLEAN Suppressed; // Statement i= s suppressed. - BOOLEAN GrayedOut; // Statement i= s GrayedOut. -} REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE; + HII_STATEMENT *HiiStatement; // Pointer t= o HII statement data. + EFI_QUESTION_ID QuestionId; // Question = ID of this statement. + EFI_STRING_ID Description; // String to= ken of this question. + CHAR16 *DescriptionStr; // String of= this question. + EFI_STRING_ID Help; // String to= ken of help message. + UINT8 Flags; // The state= ment flag. + REDFISH_PLATFORM_CONFIG_STATEMENT_DATA StatementData; // The max/m= in for statement value. + BOOLEAN Suppressed; // Statement= is suppressed. + BOOLEAN GrayedOut; // Statement= is GrayedOut. +}; =20 #define REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LINK(a) BASE_CR (a, REDFIS= H_PLATFORM_CONFIG_STATEMENT_PRIVATE, Link) =20 @@ -347,4 +384,38 @@ ReleaseStatementList ( IN REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE_LIST *StatementList ); =20 +/** + 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. =20 (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
- Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -928,6 +929,10 @@ HiiStringToOneOfOptionValue ( Option =3D HII_QUESTION_OPTION_FROM_LINK (Link); =20 TmpString =3D HiiGetRedfishString (Statement->ParentForm->ParentFormse= t->HiiHandle, Schema, Option->Text); + if (TmpString =3D=3D NULL) { + TmpString =3D HiiGetRedfishString (Statement->ParentForm->ParentForm= set->HiiHandle, ENGLISH_LANGUAGE_CODE, Option->Text); + } + if (TmpString !=3D NULL) { if (StrCmp (TmpString, HiiString) =3D=3D 0) { CopyMem (Value, &Option->Value, sizeof (HII_STATEMENT_VALUE)); @@ -1227,6 +1232,10 @@ HiiStringToOrderedListOptionValue ( Option =3D HII_QUESTION_OPTION_FROM_LINK (Link); =20 TmpString =3D HiiGetRedfishString (Statement->ParentForm->ParentFormse= t->HiiHandle, Schema, Option->Text); + if (TmpString =3D=3D NULL) { + TmpString =3D HiiGetRedfishString (Statement->ParentForm->ParentForm= set->HiiHandle, ENGLISH_LANGUAGE_CODE, Option->Text); + } + if (TmpString !=3D NULL) { if (StrCmp (TmpString, HiiString) =3D=3D 0) { *Value =3D ExtendHiiValueToU64 (&Option->Value); @@ -1491,7 +1500,7 @@ StrToAsciiStr ( return NULL; } =20 - StringLen =3D StrLen (UnicodeString) + 1; + StringLen =3D HiiStrLen (UnicodeString) + 1; Buffer =3D AllocatePool (StringLen * sizeof (CHAR8)); if (Buffer =3D=3D 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 ( =20 ASSERT (StatementRef->Statement->Description !=3D 0); if (StatementRef->Statement->Description !=3D 0) { - TmpString =3D HiiGetRedfishString (StatementRef->Statement->Parent= Form->ParentFormset->HiiHandle, FullSchema, StatementRef->Statement->Descri= ption); - ASSERT (TmpString !=3D NULL); - if (TmpString !=3D NULL) { - TmpConfigureLangList[Index] =3D TmpString; - ++Index; - } + ASSERT (StatementRef->Statement->DescriptionStr !=3D NULL); + TmpConfigureLangList[Index] =3D AllocateCopyPool (HiiStrSize (Stat= ementRef->Statement->DescriptionStr), (VOID *)StatementRef->Statement->Desc= riptionStr); + ++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 @@ =20 (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP
Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -143,6 +144,88 @@ DumpFormsetList ( return EFI_SUCCESS; } =20 +/** + 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 !=3D NULL); + + for (Length =3D 0; *String !=3D 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) !=3D 0); + ASSERT (HiiStrSize (SecondString) !=3D 0); + + while ((*FirstString !=3D L'\0') && (*FirstString =3D=3D *SecondString))= { + FirstString++; + SecondString++; + } + + return *FirstString - *SecondString; +} + /** Delete a string from HII Package List by given HiiHandle. =20 @@ -301,28 +384,6 @@ HiiGetRedfishAsciiString ( return AsciiString; } =20 -/** - Get string from HII database in English language. The returned string is= allocated - using AllocatePool(). The caller is responsible for freeing the allocate= d 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 st= ring 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 str= ing is allocated using AllocatePool(). The caller is responsible for freeing the allocate= d buffer using @@ -562,7 +623,7 @@ GetStatementPrivateByConfigureLangRegex ( HiiStatementPrivate =3D REDFISH_PLATFORM_CONFIG_STATEMENT_FROM_LI= NK (HiiStatementLink); =20 if ((HiiStatementPrivate->Description !=3D 0) && !HiiStatementPriv= ate->Suppressed) { - TmpString =3D HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,= Schema, HiiStatementPrivate->Description); + TmpString =3D HiiStatementPrivate->DescriptionStr; if (TmpString !=3D NULL) { Status =3D RegularExpressionProtocol->MatchString ( RegularExpressionProtoco= l, @@ -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); } } =20 @@ -676,14 +738,11 @@ GetStatementPrivateByConfigureLang ( ); =20 if (HiiStatementPrivate->Description !=3D 0) { - TmpString =3D HiiGetRedfishString (HiiFormsetPrivate->HiiHandle,= Schema, HiiStatementPrivate->Description); + TmpString =3D HiiStatementPrivate->DescriptionStr; if (TmpString !=3D NULL) { - if (StrCmp (TmpString, ConfigureLang) =3D=3D 0) { - FreePool (TmpString); + if (HiiStrCmp (TmpString, ConfigureLang) =3D=3D 0) { return HiiStatementPrivate; } - - FreePool (TmpString); } } =20 @@ -741,10 +800,74 @@ GetFormsetPrivateByHiiHandle ( return NULL; } =20 +/** + 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 !=3D NULL) { + FreePool (FormsetPrivate->HiiPackageListHeader); + } + + // Walk through x-uefi-redfish string database. + if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) { + EndDatabase =3D FALSE; + ThisDatabase =3D (REDFISH_X_UEFI_STRING_DATABASE *)GetFirstNode (&Form= setPrivate->XuefiRedfishStringDatabase); + while (!EndDatabase) { + // Walk through string arrays. + if (!IsListEmpty (&ThisDatabase->XuefiRedfishStringArrays)) { + EndArray =3D FALSE; + ThisStringArray =3D (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (= &ThisDatabase->XuefiRedfishStringArrays); + while (!EndArray) { + // Remove this array + FreePool (ThisStringArray->ArrayEntryAddress); + EndArray =3D IsNodeAtEnd (&ThisDatabase->XuefiRedfishStrin= gArrays, &ThisStringArray->NextArray); + PreStringArray =3D ThisStringArray; + if (!EndArray) { + ThisStringArray =3D (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNod= e (&ThisDatabase->XuefiRedfishStringArrays, &ThisStringArray->NextArray); + } + + RemoveEntryList (&PreStringArray->NextArray); + FreePool (PreStringArray); + } + } + + // + // Remove this database + // + EndDatabase =3D IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringData= base, &ThisDatabase->NextXuefiRedfishLanguage); + PreDatabase =3D ThisDatabase; + if (!EndDatabase) { + ThisDatabase =3D (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&F= ormsetPrivate->XuefiRedfishStringDatabase, &ThisDatabase->NextXuefiRedfishL= anguage); + } + + RemoveEntryList (&PreDatabase->NextXuefiRedfishLanguage); + FreePool (PreDatabase); + } + } + + return EFI_SUCCESS; +} + /** Release formset and all the forms and statements that belong to this for= mset. =20 - @param[in] FormsetPrivate Pointer to HP_HII_FORM_SET_PRIVATE + @param[in] FormsetPrivate Pointer to HII form-set private instance. =20 @retval EFI_STATUS =20 @@ -779,12 +902,6 @@ ReleaseFormset ( // // HiiStatementPrivate->HiiStatement will be released in DestroyForm= Set(). // - - if (HiiStatementPrivate->DesStringCache !=3D NULL) { - FreePool (HiiStatementPrivate->DesStringCache); - HiiStatementPrivate->DesStringCache =3D NULL; - } - RemoveEntryList (&HiiStatementPrivate->Link); FreePool (HiiStatementPrivate); HiiStatementLink =3D HiiNextStatementLink; @@ -821,6 +938,8 @@ ReleaseFormset ( FormsetPrivate->SupportedSchema.Count =3D 0; } =20 + ReleaseXuefiStringDatabase (FormsetPrivate); + return EFI_SUCCESS; } =20 @@ -846,17 +965,607 @@ NewFormsetPrivate ( // Initial newly created formset private data. // InitializeListHead (&NewFormsetPrivate->HiiFormList); + InitializeListHead (&NewFormsetPrivate->XuefiRedfishStringDatabase); =20 return NewFormsetPrivate; } =20 +/** + Create new x-uefi-redfish string array. + + @param[in] FormsetPrivate Pointer to HII form-set priv= ate instance. + @param[in] XuefiRedfishStringDatabase The x-uefi-redfish string da= tabase. + + @retval EFI_OUT_OF_RESOURCES Not enough memory for creating a n= ew 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 *XuefiRedfishStringDatabas= e + ) +{ + REDFISH_X_UEFI_STRINGS_ARRAY *ArrayAddress; + + // Initial first REDFISH_X_UEFI_STRINGS_ARRAY memory. + ArrayAddress =3D (REDFISH_X_UEFI_STRINGS_ARRAY *)AllocateZeroPool (sizeo= f (REDFISH_X_UEFI_STRINGS_ARRAY)); + if (ArrayAddress =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Failed to allocate REDFISH_X_UEFI_STRINGS_AR= RAY.\n", __func__)); + return EFI_OUT_OF_RESOURCES; + } + + InitializeListHead (&ArrayAddress->NextArray); + + // Allocate memory buffer for REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT eleme= nts. + ArrayAddress->ArrayEntryAddress =3D \ + (REDFISH_X_UEFI_STRINGS_ARRAY_ELEMENT *)AllocateZeroPool (sizeof (REDF= ISH_X_UEFI_STRINGS_ARRAY_ELEMENT) * X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBE= R); + if (ArrayAddress->ArrayEntryAddress =3D=3D 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 =3D TRUE; + XuefiRedfishStringDatabase =3D NULL; + if (!IsListEmpty (&FormsetPrivate->XuefiRedfishStringDatabase)) { + XuefiRedfishStringDatabase =3D (REDFISH_X_UEFI_STRING_DATABASE *)GetFi= rstNode (&FormsetPrivate->XuefiRedfishStringDatabase); + + while (TRUE) { + if (AsciiStriCmp (XuefiRedfishStringDatabase->XuefiRedfishLanguage, = HiiStringPackageHeader->Language) =3D=3D 0) { + CreateNewOne =3D FALSE; + break; + } + + if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &Xuefi= RedfishStringDatabase->NextXuefiRedfishLanguage)) { + break; + } + + XuefiRedfishStringDatabase =3D \ + (REDFISH_X_UEFI_STRING_DATABASE *)GetNextNode (&FormsetPrivate->Xu= efiRedfishStringDatabase, &XuefiRedfishStringDatabase->NextXuefiRedfishLang= uage); + } + } + + if (CreateNewOne) { + DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, " Creating x-uefi-redfish (%a)= string database...\n", HiiStringPackageHeader->Language)); + XuefiRedfishStringDatabase =3D (REDFISH_X_UEFI_STRING_DATABASE *)Alloc= ateZeroPool (sizeof (REDFISH_X_UEFI_STRING_DATABASE)); + if (XuefiRedfishStringDatabase =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, " Failed to allocate REDFISH_X_UEFI_STRING_DAT= ABASE.\n")); + return NULL; + } + + InitializeListHead (&XuefiRedfishStringDatabase->NextXuefiRedfishLangu= age); + InitializeListHead (&XuefiRedfishStringDatabase->XuefiRedfishStringArr= ays); + XuefiRedfishStringDatabase->StringsArrayBlocks =3D 0; + XuefiRedfishStringDatabase->XuefiRedfishLanguage =3D HiiStringPackageH= eader->Language; + + Status =3D NewRedfishXuefiStringArray (FormsetPrivate, XuefiRedfishStr= ingDatabase); + if (EFI_ERROR (Status)) { + FreePool (XuefiRedfishStringDatabase); + return NULL; + } + + DEBUG (( + REDFISH_PLATFORM_CONFIG_DEBUG, + " x-uefi-redfish (%a):\n String array is added to XuefiRedfishSt= ringDatabase, total %d arrays now.\n", + XuefiRedfishStringDatabase->XuefiRedfishLanguage, + XuefiRedfishStringDatabase->StringsArrayBlocks + )); + + // Link string database to FormsetPrivate. + InsertTailList (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRed= fishStringDatabase->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 priv= ate instance. + @param[in] XuefiRedfishStringDatabase Pointer to the x-uefi-redfis= h database. + @param[in] StringId String ID added to database. + + @retval EFI_SUCCESS The size of x-uefi-string ar= ray is adjusted or + is not required to be adjust= ed. + Otherwise, refer to the error code returned from NewRedf= ishXuefiStringArray(). + +**/ +EFI_STATUS +RedfishXuefiStringAdjustArrays ( + IN REDFISH_PLATFORM_CONFIG_FORM_SET_PRIVATE *FormsetPrivate, + IN REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabas= e, + IN EFI_STRING_ID StringId + ) +{ + EFI_STATUS Status; + + while (((StringId + X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) / X_UEFI_R= EDFISH_STRING_ARRAY_ENTRY_NUMBER) > (UINT16)XuefiRedfishStringDatabase->Str= ingsArrayBlocks) { + Status =3D NewRedfishXuefiStringArray (FormsetPrivate, XuefiRedfishStr= ingDatabase); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to adjust x-uefi-string array", __f= unc__)); + 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 datab= ase. + EFI_LOAD_ERROR Something wrong when insert an H= II 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 =3D GetExitOrCreateXuefiStringDatabase (Forms= etPrivate, HiiStringPackageHeader); + if (XuefiRedfishStringDatabase =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: Failed to get REDFISH_X_UEFI_STRING_DATABASE= of x-uefi-redfish language %a.\n", __func__, HiiStringPackageHeader->Langu= age)); + ReleaseXuefiStringDatabase (FormsetPrivate); + return EFI_LOAD_ERROR; + } + + Status =3D RedfishXuefiStringAdjustArrays (FormsetPrivate, XuefiRedfishS= tringDatabase, 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 =3D (UINTN)StringId; + ThisArray =3D (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiR= edfishStringDatabase->XuefiRedfishStringArrays); + while (StringIdOffset >=3D X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) { + ThisArray =3D (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&Xuef= iRedfishStringDatabase->XuefiRedfishStringArrays, &ThisArray->NextArray); + StringIdOffset -=3D X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER; + } + + // Insert string + (ThisArray->ArrayEntryAddress + StringIdOffset)->StringId =3D StringId; + (ThisArray->ArrayEntryAddress + StringIdOffset)->UcsString =3D StringTex= tPtr; + + 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 =3D (UINT8 *)((UINTN)HiiStringPackageHeader + HiiStringP= ackageHeader->StringInfoOffset); + BlockHdr =3D StringBlockInfo; + BlockSize =3D 0; + Offset =3D 0; + CurrentStringId =3D 1; + while (*BlockHdr !=3D EFI_HII_SIBT_END) { + switch (*BlockHdr) { + case EFI_HII_SIBT_STRING_SCSU: + Offset =3D sizeof (EFI_HII_STRING_BLOCK); + StringTextPtr =3D BlockHdr + Offset; + BlockSize +=3D Offset + AsciiStrSize ((CHAR8 *)StringTextPtr); + CurrentStringId++; + break; + + case EFI_HII_SIBT_STRING_SCSU_FONT: + Offset =3D sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - s= izeof (UINT8); + StringTextPtr =3D BlockHdr + Offset; + BlockSize +=3D Offset + AsciiStrSize ((CHAR8 *)StringTextPtr); + CurrentStringId++; + break; + + case EFI_HII_SIBT_STRINGS_SCSU: + CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), s= izeof (UINT16)); + StringTextPtr =3D (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT= _STRINGS_SCSU_BLOCK) - sizeof (UINT8)); + BlockSize +=3D StringTextPtr - BlockHdr; + + for (Index =3D 0; Index < StringCount; Index++) { + BlockSize +=3D AsciiStrSize ((CHAR8 *)StringTextPtr); + StringTextPtr =3D StringTextPtr + AsciiStrSize ((CHAR8 *)StringT= extPtr); + CurrentStringId++; + } + + break; + + case EFI_HII_SIBT_STRINGS_SCSU_FONT: + CopyMem ( + &StringCount, + (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + size= of (UINT8)), + sizeof (UINT16) + ); + StringTextPtr =3D (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_SIBT= _STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8)); + BlockSize +=3D StringTextPtr - BlockHdr; + + for (Index =3D 0; Index < StringCount; Index++) { + BlockSize +=3D AsciiStrSize ((CHAR8 *)StringTextPtr); + StringTextPtr =3D StringTextPtr + AsciiStrSize ((CHAR8 *)StringT= extPtr); + CurrentStringId++; + } + + break; + + case EFI_HII_SIBT_STRING_UCS2: + Offset =3D sizeof (EFI_HII_STRING_BLOCK); + StringTextPtr =3D BlockHdr + Offset; + + // x-uefi-redfish string is always encoded as UCS and started with= '/'. + if (*StringTextPtr =3D=3D (UINT16)'/') { + Status =3D RedfishXuefiStringInsertDatabase ( + FormsetPrivate, + HiiStringPackageHeader, + CurrentStringId, + (CHAR16 *)StringTextPtr + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to insert x-uefi-redfish stri= ng %s.\n", __func__, StringTextPtr)); + return FALSE; + } + } + + BlockSize +=3D (Offset + HiiStrSize ((CHAR16 *)StringTextPtr)); + CurrentStringId++; + break; + + case EFI_HII_SIBT_STRING_UCS2_FONT: + Offset =3D sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - = sizeof (CHAR16); + StringTextPtr =3D BlockHdr + Offset; + BlockSize +=3D (Offset + HiiStrSize ((CHAR16 *)StringTextPtr)); + CurrentStringId++; + break; + + case EFI_HII_SIBT_STRINGS_UCS2: + Offset =3D sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeo= f (CHAR16); + StringTextPtr =3D BlockHdr + Offset; + BlockSize +=3D Offset; + CopyMem (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), s= izeof (UINT16)); + for (Index =3D 0; Index < StringCount; Index++) { + BlockSize +=3D HiiStrSize ((CHAR16 *)StringTextPtr); + StringTextPtr =3D StringTextPtr + HiiStrSize ((CHAR16 *)StringTe= xtPtr); + CurrentStringId++; + } + + break; + + case EFI_HII_SIBT_STRINGS_UCS2_FONT: + Offset =3D sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - = sizeof (CHAR16); + StringTextPtr =3D BlockHdr + Offset; + BlockSize +=3D Offset; + CopyMem ( + &StringCount, + (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + size= of (UINT8)), + sizeof (UINT16) + ); + for (Index =3D 0; Index < StringCount; Index++) { + BlockSize +=3D HiiStrSize ((CHAR16 *)StringTextPtr); + StringTextPtr =3D StringTextPtr + HiiStrSize ((CHAR16 *)StringTe= xtPtr); + CurrentStringId++; + } + + break; + + case EFI_HII_SIBT_DUPLICATE: + BlockSize +=3D sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK); + CurrentStringId++; + break; + + case EFI_HII_SIBT_SKIP1: + SkipCount =3D (UINT16)(*(UINT8 *)((UINTN)BlockHdr + sizeof (= EFI_HII_STRING_BLOCK))); + CurrentStringId =3D (UINT16)(CurrentStringId + SkipCount); + BlockSize +=3D sizeof (EFI_HII_SIBT_SKIP1_BLOCK); + break; + + case EFI_HII_SIBT_SKIP2: + CopyMem (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), siz= eof (UINT16)); + CurrentStringId =3D (UINT16)(CurrentStringId + SkipCount); + BlockSize +=3D sizeof (EFI_HII_SIBT_SKIP2_BLOCK); + break; + + case EFI_HII_SIBT_EXT1: + CopyMem ( + &Length8, + (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + size= of (UINT8)), + sizeof (UINT8) + ); + BlockSize +=3D Length8; + break; + + case EFI_HII_SIBT_EXT2: + CopyMem (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK)); + BlockSize +=3D Ext2.Length; + break; + + case EFI_HII_SIBT_EXT4: + CopyMem ( + &Length32, + (UINT8 *)((UINTN)BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + size= of (UINT8)), + sizeof (UINT32) + ); + + BlockSize +=3D Length32; + break; + + default: + break; + } + + BlockHdr =3D (UINT8 *)(StringBlockInfo + BlockSize); + } + + return TRUE; +} + +/** + Get x-uefi-redfish string and language by string ID. + + @param[in] FormsetPrivate Pointer to HII form-set private ins= tance. + @param[in] StringId The HII string ID. + @param[out] String Optionally return USC string. + @param[out] Language Optionally return x-uefi-redfish la= nguage. + @param[out] XuefiStringDatabase Optionally return x-uefi-redfish da= tabase. + + @retval EFI_SUCCESS String information is returned. + EFI_INVALID_PARAMETER One of the given parameters to this func= tion 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 OPT= IONAL + ) +{ + REDFISH_X_UEFI_STRING_DATABASE *XuefiRedfishStringDatabase; + REDFISH_X_UEFI_STRINGS_ARRAY *StringArray; + UINT16 StringIndex; + + if ((String =3D=3D NULL) && (Language =3D=3D NULL) && (XuefiStringDataba= se =3D=3D 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 =3D (REDFISH_X_UEFI_STRING_DATABASE *)GetFirs= tNode (&FormsetPrivate->XuefiRedfishStringDatabase); + while (TRUE) { + if (Language !=3D NULL) { + *Language =3D XuefiRedfishStringDatabase->XuefiRedfishLanguage; + } + + StringArray =3D (REDFISH_X_UEFI_STRINGS_ARRAY *)GetFirstNode (&XuefiRe= dfishStringDatabase->XuefiRedfishStringArrays); + + // Loop to the correct string array. + StringIndex =3D StringId; + while (StringIndex >=3D X_UEFI_REDFISH_STRING_ARRAY_ENTRY_NUMBER) { + if (IsNodeAtEnd (&XuefiRedfishStringDatabase->XuefiRedfishStringArra= ys, &StringArray->NextArray)) { + goto ErrorEixt; + } + + StringArray =3D (REDFISH_X_UEFI_STRINGS_ARRAY *)GetNextNode (&Xuefi= RedfishStringDatabase->XuefiRedfishStringArrays, &StringArray->NextArray); + StringIndex -=3D 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 I= D + // should be in another x-uefi-redfish database. + // + if ((StringArray->ArrayEntryAddress + StringIndex)->UcsString !=3D NUL= L) { + // + // String ID is belong to this x-uef-redfish language database. + // + if (String !=3D NULL) { + *String =3D (StringArray->ArrayEntryAddress + StringIndex)->UcsStr= ing; + } + + if (XuefiStringDatabase !=3D NULL) { + *XuefiStringDatabase =3D XuefiRedfishStringDatabase; + } + + return EFI_SUCCESS; + } + + if (IsNodeAtEnd (&FormsetPrivate->XuefiRedfishStringDatabase, &XuefiRe= dfishStringDatabase->NextXuefiRedfishLanguage)) { + return EFI_NOT_FOUND; + } + + XuefiRedfishStringDatabase =3D (REDFISH_X_UEFI_STRING_DATABASE *)GetNe= xtNode ( + &Form= setPrivate->XuefiRedfishStringDatabase, + &Xuef= iRedfishStringDatabase->NextXuefiRedfishLanguage + ); + } + +ErrorEixt:; + DEBUG ((DEBUG_ERROR, "%a: String ID (%d) is not in any x-uef-redfish str= ing databases.\n", __func__, StringId)); + return EFI_NOT_FOUND; +} + +/** + Build a x-uefi-redfish database for the newly added x-uefi-redfish langu= age. + + @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 Fo= rmset GUID - %g.\n", __func__, FormsetPrivate->Guid)); + + BufferSize =3D 0; + Status =3D mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackage= Lists ( + mRedfishPlatf= ormConfigPrivate->HiiDatabase, + FormsetPrivat= e->HiiHandle, + &BufferSize, + FormsetPrivat= e->HiiPackageListHeader + ); + if (Status !=3D EFI_BUFFER_TOO_SMALL) { + DEBUG ((DEBUG_ERROR, " Failed to export package list.\n")); + return; + } + + FormsetPrivate->HiiPackageListHeader =3D (EFI_HII_PACKAGE_LIST_HEADER *)= AllocateZeroPool (BufferSize); + if (FormsetPrivate->HiiPackageListHeader =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, " Failed to allocate memory for the exported pac= kage list.\n")); + return; + } + + Status =3D mRedfishPlatformConfigPrivate->HiiDatabase->ExportPackageList= s ( + mRedfishPlatformC= onfigPrivate->HiiDatabase, + FormsetPrivate->H= iiHandle, + &BufferSize, + FormsetPrivate->H= iiPackageListHeader + ); + if (EFI_ERROR (Status)) { + return; + } + + // + // Finding the string package. + // + EndingPackageAddress =3D (UINTN)FormsetPrivate->HiiPackageListHeader + F= ormsetPrivate->HiiPackageListHeader->PackageLength; + PackageHeader =3D (EFI_HII_PACKAGE_HEADER *)(FormsetPrivate->HiiP= ackageListHeader + 1); + SupportedSchemaLang =3D FormsetPrivate->SupportedSchema.SchemaList; + while ((UINTN)PackageHeader < EndingPackageAddress) { + switch (PackageHeader->Type) { + case EFI_HII_PACKAGE_STRINGS: + StringIdMapIsBuilt =3D FALSE; + HiiStringPackageHeader =3D (EFI_HII_STRING_PACKAGE_HDR *)PackageHe= ader; + + // Check if this is the string package for x-uefi-redfish + for (SupportedSchemaLangCount =3D 0; + SupportedSchemaLangCount < FormsetPrivate->SupportedSchema.Co= unt; + SupportedSchemaLangCount++ + ) + { + if (AsciiStrnCmp ( + *(SupportedSchemaLang + SupportedSchemaLangCount), + HiiStringPackageHeader->Language, + AsciiStrLen (HiiStringPackageHeader->Language) + ) =3D=3D 0) + { + StringIdMapIsBuilt =3D CreateXuefiLanguageStringIdMap (Formset= Private, HiiStringPackageHeader); + break; + } + } + + if (StringIdMapIsBuilt =3D=3D FALSE) { + if (AsciiStrStr (HiiStringPackageHeader->Language, X_UEFI_SCHEMA= _PREFIX) =3D=3D NULL) { + DEBUG ((REDFISH_PLATFORM_CONFIG_DEBUG, " No need to build x-u= efi-redfish string ID map for HII language %a\n", HiiStringPackageHeader->L= anguage)); + } else { + DEBUG ((DEBUG_ERROR, " Failed to build x-uefi-redfish string = ID map of HII language %a\n", HiiStringPackageHeader->Language)); + } + } + + default: + PackageHeader =3D (EFI_HII_PACKAGE_HEADER *)((UINTN)PackageHeader = + PackageHeader->Length); + } + } +} + /** Load the HII formset from the given HII handle. =20 @param[in] HiiHandle Target HII handle to load. @param[out] FormsetPrivate The formset private data. =20 - @retval EFI_STATUS + @retval EFI_STATUS The formset is loaded successfully. + @retval EFI_UNSUPPORTED This formset doesn't have any x-uefi-redfish= configuration. =20 **/ EFI_STATUS @@ -875,6 +1584,7 @@ LoadFormset ( REDFISH_PLATFORM_CONFIG_STATEMENT_PRIVATE *HiiStatementPrivate; EFI_GUID ZeroGuid; EXPRESS_RESULT ExpressionResult; + CHAR16 *String; =20 if ((HiiHandle =3D=3D NULL) || (FormsetPrivate =3D=3D NULL)) { return EFI_INVALID_PARAMETER; @@ -882,6 +1592,7 @@ LoadFormset ( =20 HiiFormSet =3D AllocateZeroPool (sizeof (HII_FORMSET)); if (HiiFormSet =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: No memory resource for HII_FORMSET - %g\n", = __func__, FormsetPrivate->Guid)); return EFI_OUT_OF_RESOURCES; } =20 @@ -891,6 +1602,7 @@ LoadFormset ( ZeroMem (&ZeroGuid, sizeof (ZeroGuid)); Status =3D CreateFormSetFromHiiHandle (HiiHandle, &ZeroGuid, HiiFormSet)= ; if (EFI_ERROR (Status) || IsListEmpty (&HiiFormSet->FormListHead)) { + DEBUG ((DEBUG_ERROR, "%a: Formset not found by HII handle - %g\n", __f= unc__, FormsetPrivate->Guid)); Status =3D EFI_NOT_FOUND; goto ErrorExit; } @@ -909,7 +1621,11 @@ LoadFormset ( FormsetPrivate->DevicePathStr =3D ConvertDevicePathToText (HiiFormSet->D= evicePath, FALSE, FALSE); Status =3D GetSupportedSchema (FormsetPrivate->Hi= iHandle, &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 configur= ation found on the formset - %g\n", __func__, FormsetPrivate->Guid)); + return EFI_UNSUPPORTED; // Can't build AttributeRegistry Meni path wit= h returning EFI_UNSUPPORTED. + } else { + // Building x-uefi-redfish string database + BuildXUefiRedfishStringDatabase (FormsetPrivate); } =20 HiiFormLink =3D GetFirstNode (&HiiFormSet->FormListHead); @@ -919,6 +1635,7 @@ LoadFormset ( HiiFormPrivate =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_CONFIG_F= ORM_PRIVATE)); if (HiiFormPrivate =3D=3D NULL) { Status =3D EFI_OUT_OF_RESOURCES; + DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_CO= NFIG_FORM_PRIVATE.\n", __func__)); goto ErrorExit; } =20 @@ -944,6 +1661,7 @@ LoadFormset ( =20 HiiStatementPrivate =3D AllocateZeroPool (sizeof (REDFISH_PLATFORM_C= ONFIG_STATEMENT_PRIVATE)); if (HiiStatementPrivate =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "%a: No memory resource for REDFISH_PLATFORM_= CONFIG_STATEMENT_PRIVATE.\n", __func__)); Status =3D EFI_OUT_OF_RESOURCES; goto ErrorExit; } @@ -981,10 +1699,18 @@ LoadFormset ( } } =20 - // - // Attach to statement list. - // - InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPrivate= ->Link); + // Get x-uefi-redfish string using String ID. + Status =3D GetXuefiStringAndLangByStringId (FormsetPrivate, HiiState= mentPrivate->Description, &String, NULL, NULL); + if (!EFI_ERROR (Status)) { + HiiStatementPrivate->DescriptionStr =3D String; + // + // Attach to statement list. + // + InsertTailList (&HiiFormPrivate->StatementList, &HiiStatementPriva= te->Link); + } else { + FreePool (HiiStatementPrivate); + } + HiiStatementLink =3D GetNextNode (&HiiForm->StatementListHead, HiiSt= atementLink); } =20 @@ -1052,7 +1778,7 @@ LoadFormsetList ( // Status =3D LoadFormset (HiiHandle, FormsetPrivate); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: failed to load formset: %r\n", __func__, Sta= tus)); + DEBUG ((DEBUG_ERROR, "%a: Formset is not loaded for edk2 redfish: %r\n= ", __func__, Status)); FreePool (FormsetPrivate); return Status; } @@ -1325,7 +2051,11 @@ ProcessPendingList ( =20 Status =3D LoadFormsetList (Target->HiiHandle, FormsetList); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "%a: load formset from HII handle: 0x%x faile= d: %r\n", __func__, Target->HiiHandle, Status)); + if (Status =3D=3D EFI_UNSUPPORTED) { + DEBUG ((DEBUG_ERROR, " The formset has no x-uefi-redfish config= urations.\n")); + } else { + DEBUG ((DEBUG_ERROR, " load formset from HII handle: 0x%x faile= d: %r\n", Target->HiiHandle, Status)); + } } } =20 --=20 2.37.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#117123): https://edk2.groups.io/g/devel/message/117123 Mute This Topic: https://groups.io/mt/105159783/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-