From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail05.groups.io (mail05.groups.io [45.79.224.7]) by spool.mail.gandi.net (Postfix) with ESMTPS id 0CA50D80078 for ; Wed, 15 May 2024 03:52:08 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=8iGXn1YB0YePWohiRj9yAA0Kx65ZQnsCvmtjCZaOfmM=; c=relaxed/simple; d=groups.io; h=Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Received-SPF:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Resent-From:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20240206; t=1715745127; v=1; b=AvplLiD7GwQdIQr44MtwoszTZfauZSPn2z6akAWmHlTZFv0dMe5J20u0P7DkZ3var0wlHjCt fPG4Wxct4Pq5lRH2wtWP6uZWuH/WbtT8WtCetTuGZm2l7N8BGMU+in45LIlpDSlGmr03N58y5yG 047TRvdy23v+illdk2q22UsuzyteeqR18tR/+Hk8/RWx+t1jkvY3ikNvzKxuLY2uZqKhYYcN8s6 KgZM7EP5CnSPHzZMhzu2av4ZUhBPS6ZaUlVoSMuUjPlv7+KqDGIPKlGWZPPy328koyhrfYqT1C+ ySI4JUhbQ56ZAUGGroYhWxtXkjjQ4DFLZPTlZa4qjK3Xw== X-Received: by 127.0.0.2 with SMTP id HUDtYY7687511xflGHBr3KoN; Tue, 14 May 2024 20:52:07 -0700 X-Received: from NAM10-BN7-obe.outbound.protection.outlook.com (NAM10-BN7-obe.outbound.protection.outlook.com [40.107.92.64]) by mx.groups.io with SMTP id smtpd.web10.6398.1715745125278228291 for ; Tue, 14 May 2024 20:52:05 -0700 X-Received: from DS7PR05CA0046.namprd05.prod.outlook.com (2603:10b6:8:2f::14) by MN0PR12MB5884.namprd12.prod.outlook.com (2603:10b6:208:37c::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7544.55; Wed, 15 May 2024 03:52:01 +0000 X-Received: from DS3PEPF0000C37C.namprd04.prod.outlook.com (2603:10b6:8:2f:cafe::44) by DS7PR05CA0046.outlook.office365.com (2603:10b6:8:2f::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7587.26 via Frontend Transport; Wed, 15 May 2024 03:52:01 +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=SATLEXMB03.amd.com; pr=C X-Received: from SATLEXMB03.amd.com (165.204.84.17) by DS3PEPF0000C37C.mail.protection.outlook.com (10.167.23.6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7587.21 via Frontend Transport; Wed, 15 May 2024 03:52:01 +0000 X-Received: from SATLEXMB04.amd.com (10.181.40.145) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Tue, 14 May 2024 22:51:59 -0500 X-Received: from BLR-LAB-SFW01.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 via Frontend Transport; Tue, 14 May 2024 22:51:58 -0500 From: "Abdul Lateef Attar via groups.io" To: CC: Abdul Lateef Attar , Abner Chang , Paul Grimes Subject: [edk2-devel] [RESEND 5/7] AmdPlatformPkg: Adds AmdConfigRouting driver Date: Wed, 15 May 2024 09:20:23 +0530 Message-ID: <4e601797964bb73cc045c910666c94940a8d40c0.1715744867.git.AbdulLateef.Attar@amd.com> In-Reply-To: References: MIME-Version: 1.0 Received-SPF: None (SATLEXMB03.amd.com: AbdulLateef.Attar@amd.com does not designate permitted sender hosts) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS3PEPF0000C37C:EE_|MN0PR12MB5884:EE_ X-MS-Office365-Filtering-Correlation-Id: 020c2c80-c2a7-4c81-6d6d-08dc74926077 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?7V0hqZldy0SR4wZNsPsLJdnNse7Z/MdTS0iMWshVFU0mkGQQShBrura+tGUG?= =?us-ascii?Q?bvycMP7cP/c0MolGtbj0aj/GJ94ro//ONUETh8wDbGqnFFKMD/qUjnBWxZBe?= =?us-ascii?Q?cpLZ6bR0npo5yf0+m8slHRaKWMw/jNMjJzEdzMiegcUuVq2zv/NnKMhiVPZ+?= =?us-ascii?Q?rYioy4N179tpDCo4DTsDZGVap02/alb3s6lNmPPyqf0GZ5vPjaUdqRZYzk+Q?= =?us-ascii?Q?ZpMSFEqBEI+naTJY04GUXDLUAkkh0memvLRgw3L+BJ2rsTyg7Xt+Mb7n/qKB?= =?us-ascii?Q?XCFODiiUt9HIDUOydvpb0sxCcowF7vfy0akAutFoXyTjHA5n9hPk1wFhC6wj?= =?us-ascii?Q?Iha763rxxoVll0AK6L53BjLDsj7doI3pOujJ5jbm9uuE2aIJ9jKx4DJFSYyU?= =?us-ascii?Q?6VKqyM+zmxUbZLrwGmVntNSDOiEEael+acJKht1csyPNxhBKHSMqbu7YQgOZ?= =?us-ascii?Q?io8PXDnvuAKBO0sxO0d2sD00HNPax+1N5ceBbk4znVzhT79yp0+OH/0REZCA?= =?us-ascii?Q?VRxv2LGuXcUHjOFn0tBhbamSuwEBwabrco392fzJLcjhdy6/dxTi5unt1DK6?= =?us-ascii?Q?AVGG7v9sxYhsrsUiraaG6XqJGWyFa5fKhuPTsOxTS1gXMXHClfqrT7lOVkUX?= =?us-ascii?Q?ODPFU3kt3rex2Ssw1dHQgveDaBkDLT0XgyptscAW8O4FtPlo9IW/ZnfeCBAR?= =?us-ascii?Q?0wszahYTuGFNObyIN6xOmm7PjBDUZm5GqzsOfQCdScawkXw2saCqMoBP3zq+?= =?us-ascii?Q?shBBB7+C4LTUbBxomJfQNRSAP2QmVbIqOITMu08221SYA94D0T/nyl2E1XDH?= =?us-ascii?Q?vxtqpT17wLu3i68thqNk6QPc0QVLOtBKkS8fWwCbojVRo4Vw1hawvJPeK+SG?= =?us-ascii?Q?pFEb1UgtlhVkcAAFscVk7eG98MnbmnPEo63zyVBPIhFZgU8OVtGolDaGdMVL?= =?us-ascii?Q?cjz/2weQ9JuiJULiSqMcZP1QG05HPaWMbVIyE1i+SfW4rb0iiwvOhb/dABJF?= =?us-ascii?Q?RJMcc8mZz0s5Y9If4Ncg1jHosR3A2IHtwqdMKVB9U+FCWfB+QqOR2FZxutH8?= =?us-ascii?Q?ozgc7M+MY1VXkqqGYlEHJ16ViZkc8gO6dW/hX/JwW0R106KRzLyxGvWK/Q+H?= =?us-ascii?Q?RPYrRbVdESyYPSP0KbkwTIR4/pMeVhZxz9t2pLlmoEEoauAdQxKvUeJARN2J?= =?us-ascii?Q?vOIM2JkhDr5UiUSQpa7SuokCvWap+/qdEwC5IRxYAtjy0qJFF8Zzo8zhNpoA?= =?us-ascii?Q?jZPQJiaHudWcx+yvsB0thKQo7R4jBOD04X+vXjznnNGYcsedu0sP7Wf3HDhc?= =?us-ascii?Q?MKiwFkpWB4ca+SVGCQvk/o0remAP8hQCLiwMQ3Q+zyNThM5ssIKNC9bhUoog?= =?us-ascii?Q?6alEXHppvJ883R0todNNTdvYOf+9?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 May 2024 03:52:01.1473 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 020c2c80-c2a7-4c81-6d6d-08dc74926077 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=[SATLEXMB03.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS3PEPF0000C37C.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN0PR12MB5884 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, 14 May 2024 20:52:05 -0700 Resent-From: AbdulLateef.Attar@amd.com Reply-To: devel@edk2.groups.io,AbdulLateef.Attar@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: FTMIgMBoZWXe6hP7I7gbsBOZx7686176AA= 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=AvplLiD7; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.7 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=pass (policy=none) header.from=groups.io Adds AmdConfigRouting driver to improve HII performance. Cc: Abner Chang Cc: Paul Grimes Signed-off-by: Abdul Lateef Attar --- .../AMD/AmdPlatformPkg/AmdPlatformPkg.dsc | 1 + .../HiiConfigRouting/AmdConfigRouting.inf | 45 + .../HiiConfigRouting/AmdConfigRoutingEntry.c | 57 + .../HiiConfigRouting/AmdHiiConfigRouting.c | 1101 +++++++++++++++++ .../HiiConfigRouting/AmdHiiConfigRouting.h | 189 +++ 5 files changed, 1393 insertions(+) create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/= AmdConfigRouting.inf create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/= AmdConfigRoutingEntry.c create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/= AmdHiiConfigRouting.c create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/= AmdHiiConfigRouting.h diff --git a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc b/Platform/AMD/= AmdPlatformPkg/AmdPlatformPkg.dsc index a717263c58..3d13c9e41d 100644 --- a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc +++ b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc @@ -51,6 +51,7 @@ AmdPlatformPkg/Library/BaseAlwaysFalseDepexLib/BaseAlwaysFalseDepexLib.i= nf AmdPlatformPkg/Library/DxePlatformSocLib/DxePlatformSocLibNull.inf AmdPlatformPkg/Library/SimulatorSerialPortLibPort80/SimulatorSerialPortL= ibPort80.inf + AmdPlatformPkg/Universal/HiiConfigRouting/AmdConfigRouting.inf AmdPlatformPkg/Universal/LogoDxe/JpegLogoDxe.inf = # Server platform JPEG logo driver AmdPlatformPkg/Universal/LogoDxe/LogoDxe.inf = # Server platfrom Bitmap logo driver AmdPlatformPkg/Universal/LogoDxe/S3LogoDxe.inf \ No newline at end of file diff --git a/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdConf= igRouting.inf b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdC= onfigRouting.inf new file mode 100644 index 0000000000..6cfb1dcceb --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdConfigRouti= ng.inf @@ -0,0 +1,45 @@ +## @file +# AMD HII Config routing driver INF file. +# This module provides better performance of BlockToConfig and ConfigToBl= ock +# functions. +# +# Copyright (C) 2021 - 2024 Advanced Micro Devices, Inc. All rights reser= ved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D AmdConfigRouting + FILE_GUID =3D 64302048-7006-49C4-AF0A-5ACE61257437 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D AmdConfigRoutingEntry + +[Sources] + AmdConfigRoutingEntry.c + AmdHiiConfigRouting.c + AmdHiiConfigRouting.h + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + +[Protocols] + gEfiHiiConfigRoutingProtocolGuid + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength + +[Depex] + gEfiHiiConfigRoutingProtocolGuid diff --git a/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdConf= igRoutingEntry.c b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/A= mdConfigRoutingEntry.c new file mode 100644 index 0000000000..29246ac1b2 --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdConfigRouti= ngEntry.c @@ -0,0 +1,57 @@ +/** @file + AMD implementation of interface functions for EFI_HII_CONFIG_ROUTING_PRO= TOCOL. + This module overrides BlockToConfig and ConfigToBlock for the better per= formance. + + Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserv= ed. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "AmdHiiConfigRouting.h" + +/** + Entry point for the AMD HII Config Routing driver. + + @param[in] ImageHandle The image handle. + @param[in] SystemTable The system table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Others Some error occurs when executing this entry point. +**/ +EFI_STATUS +EFIAPI +AmdConfigRoutingEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting; + + HiiConfigRouting =3D NULL; + + Status =3D gBS->LocateProtocol ( + &gEfiHiiConfigRoutingProtocolGuid, + NULL, + (VOID **)&HiiConfigRouting + ); + if (!EFI_ERROR (Status)) { + ASSERT (HiiConfigRouting !=3D NULL); + DEBUG (( + DEBUG_INFO, + "HiiConfigRouting->BlockToConfig: 0x%lX\n", + (UINTN)HiiBlockToConfig + )); + DEBUG (( + DEBUG_INFO, + "HiiConfigRouting->ConfigToBlock: 0x%lX\n", + (UINTN)HiiConfigToBlock + )); + + HiiConfigRouting->BlockToConfig =3D HiiBlockToConfig; + HiiConfigRouting->ConfigToBlock =3D HiiConfigToBlock; + } + + return Status; +} diff --git a/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdHiiC= onfigRouting.c b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/Amd= HiiConfigRouting.c new file mode 100644 index 0000000000..0a28d887e9 --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdHiiConfigRo= uting.c @@ -0,0 +1,1101 @@ +/** @file + AMD implementation of interfaces function for EFI_HII_CONFIG_ROUTING_PRO= TOCOL. + This file provides better performance of BlockToConfig and ConfigToBlock + functions. + + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+ Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserv= ed. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "AmdHiiConfigRouting.h" + +HII_ELEMENT gElementInfo[] =3D { + { L"GUID=3D", FIXED_STR_LEN (L"GUID=3D") }, + { L"NAME=3D", FIXED_STR_LEN (L"NAME=3D") }, + { L"PATH=3D", FIXED_STR_LEN (L"PATH=3D") }, + { L"OFFSET=3D", FIXED_STR_LEN (L"OFFSET=3D") }, + { L"WIDTH=3D", FIXED_STR_LEN (L"WIDTH=3D") }, + { L"VALUE=3D", FIXED_STR_LEN (L"VALUE=3D") } +}; + +/** + Converts the unicode character of the string from uppercase to lowercase= . + This is a internal function. + + @param ConfigString String to be converted + +**/ +VOID +EFIAPI +HiiToLower ( + IN EFI_STRING ConfigString + ) +{ + EFI_STRING String; + BOOLEAN Lower; + + ASSERT (ConfigString !=3D NULL); + + // + // Convert all hex digits in range [A-F] in the configuration header to = [a-f] + // + for (String =3D ConfigString, Lower =3D FALSE; *String !=3D L'\0'; Strin= g++) { + if (*String =3D=3D L'=3D') { + Lower =3D TRUE; + } else if (*String =3D=3D L'&') { + Lower =3D FALSE; + } else if (Lower && (*String >=3D L'A') && (*String <=3D L'F')) { + *String =3D (CHAR16)(*String - L'A' + L'a'); + } + } + + return; +} + +// +// Updated EDK2 functions to improve performance. +// + +/** + Returns the length of a Null-terminated Unicode string. + + This function returns the number of Unicode characters in the Null-termi= nated + Unicode string specified by String. + + @param String A pointer to a Null-terminated Unicode string. + + @retval The length of String. + +**/ +UINTN +EFIAPI +HiiStrLen ( + IN EFI_STRING String + ) +{ + UINTN Length; + + ASSERT (String !=3D NULL); + + for (Length =3D 0; String[Length] !=3D L'\0'; Length++) { + } + + // + // If PcdMaximumUnicodeStringLength is not zero, + // length should not more than PcdMaximumUnicodeStringLength + // + if (PcdGet32 (PcdMaximumUnicodeStringLength) !=3D 0) { + ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength)); + } + + return Length; +} + +/** + Compares up to a specified length the contents of two Null-terminated Un= icode + strings, and returns the difference between the first mismatched Unicode + characters. + + This function compares the Null-terminated Unicode string FirstString to= the + Null-terminated Unicode string SecondString. At most, Length Unicode + characters will be compared. If Length is 0, then 0 is returned. If + FirstString is identical to SecondString, then 0 is returned. Otherwise,= the + value returned is the first mismatched Unicode character in SecondString + subtracted from the first mismatched Unicode character in FirstString. + + @param[in] FirstString A pointer to a Null-terminated Unicode string. + @param[in] SecondString A pointer to a Null-terminated Unicode string. + @param[in] Length The maximum number of Unicode characters to co= mpare. + + @retval 0 FirstString is identical to SecondString. + @retval others FirstString is not identical to SecondString. + +**/ +INTN +EFIAPI +HiiStrnCmp ( + IN EFI_STRING FirstString, + IN EFI_STRING SecondString, + IN UINTN Length + ) +{ + if (Length =3D=3D 0) { + return 0; + } + + ASSERT (FirstString !=3D NULL); + ASSERT (SecondString !=3D NULL); + if (PcdGet32 (PcdMaximumUnicodeStringLength) !=3D 0) { + ASSERT (Length <=3D PcdGet32 (PcdMaximumUnicodeStringLength)); + } + + while ((*FirstString !=3D L'\0') && + (*SecondString !=3D L'\0') && + (*FirstString =3D=3D *SecondString) && + (Length > 1)) + { + FirstString++; + SecondString++; + Length--; + } + + return *FirstString - *SecondString; +} + +/** + Initializes HII_NUMBER instance to 0. + + @param[in, out] This Pointer to HII_NUMBER instances. + +**/ +VOID +HiiNumberInit ( + IN OUT HII_NUMBER *This + ) +{ + ASSERT (This !=3D NULL); + + This->NumberPtr =3D 0; + This->NumberPtrLength =3D 0; + This->Value =3D 0; + This->PrivateBufferSize =3D 0; +} + +/** + Frees buffer in HII_NUMBER instance. + + @param[in, out] This Pointer to HII_NUMBER instance. + +**/ +VOID +HiiNumberFree ( + IN OUT HII_NUMBER *This + ) +{ + ASSERT (This !=3D NULL); + + if (This->NumberPtr !=3D NULL) { + FreePool (This->NumberPtr); + This->NumberPtr =3D NULL; + This->PrivateBufferSize =3D 0; + } +} + +/** + If buffer doesn't exist, allocate it. If the existing buffer is less tha= n + requested, allocate a larger one. + + @param[in, out] This Pointer to HII_NUMBER instance. + @param[in] Size Requested buffer size. + + @retval EFI_SUCCESS Buffer allocated. + @retval EFI_OUT_OF_RESOURCES OUt of memory. + +**/ +EFI_STATUS +HiiNumberSetMinBufferSize ( + IN OUT HII_NUMBER *This, + IN UINTN Size + ) +{ + ASSERT (This !=3D NULL); + + if (This->PrivateBufferSize < Size) { + Size +=3D MAX_STRING_LENGTH; + This->NumberPtr =3D ReallocatePool (This->PrivateBufferSize, Size, Thi= s->NumberPtr); + if (This->NumberPtr =3D=3D NULL) { + This->PrivateBufferSize =3D 0; + return EFI_OUT_OF_RESOURCES; + } + + This->PrivateBufferSize =3D Size; + } + + return EFI_SUCCESS; +} + +/** + Get value of number from string and update HII_NUMBER instance. + + @param[in, out] This Pointer to HII_NUMBER instance. + @param[in] String String to get value from. String may end in \0 or &. + + @retval EFI_SUCCESS Buffer allocated. + @retval EFI_OUT_OF_RESOURCES OUt of memory. + +**/ +EFI_STATUS +GetValueOfNumber ( + IN OUT HII_NUMBER *This, + IN EFI_STRING String + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN StringLength; + UINTN NumLen; + CHAR16 Digit; + UINT8 DigitUint8; + EFI_STRING EndOfString; + + if ((This =3D=3D NULL) || (String =3D=3D NULL) || (*String =3D=3D L'\0')= ) { + return EFI_INVALID_PARAMETER; + } + + EndOfString =3D String; + StringLength =3D 0; + + while (*EndOfString !=3D L'\0' && *EndOfString !=3D L'&') { + EndOfString++; + StringLength++; + } + + This->StringLength =3D StringLength; + + NumLen =3D (StringLength + 1) / 2; + + Status =3D HiiNumberSetMinBufferSize (This, NumLen); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index =3D 0; Index < StringLength; Index++) { + Digit =3D String[StringLength - Index - 1]; + if (Digit < L'0') { + DigitUint8 =3D 0; + } else if (Digit <=3D L'9') { + DigitUint8 =3D (UINT8)(Digit - L'0'); + } else if (Digit < L'A') { + DigitUint8 =3D 0; + } else if (Digit <=3D L'F') { + DigitUint8 =3D (UINT8)(Digit - L'A' + 0xa); + } else if (Digit < L'a') { + DigitUint8 =3D 0; + } else if (Digit <=3D L'f') { + DigitUint8 =3D (UINT8)(Digit - L'a' + 0xa); + } else { + DigitUint8 =3D 0; + } + + if ((Index & 1) =3D=3D 0) { + This->NumberPtr[Index / 2] =3D DigitUint8; + } else { + This->NumberPtr[Index / 2] =3D (UINT8)((DigitUint8 << 4) + This->Num= berPtr[Index / 2]); + } + } + + This->NumberPtrLength =3D StringLength; + This->Value =3D 0; + + if (StringLength <=3D sizeof (UINTN) * sizeof (CHAR16)) { + CopyMem ( + &This->Value, + This->NumberPtr, + NumLen < sizeof (UINTN) ? NumLen : sizeof (UINTN) + ); + } + + return EFI_SUCCESS; +} + +/** + Initializes HII_STRING instance allocating buffer. + + @param[in, out] This Pointer to HII_STRING instance. + @param[in] Size Size of initial allocation. + + @retval EFI_SUCCESS Allocated buffer successfully. + @retval EFI_OUT_OF_RESOURCES Out of memory. +**/ +EFI_STATUS +HiiStringInit ( + IN OUT HII_STRING *This, + IN UINTN Size + ) +{ + ASSERT (This !=3D NULL); + + This->StringLength =3D 0; + + if (Size =3D=3D 0) { + This->String =3D NULL; + This->PrivateBufferSize =3D 0; + return EFI_SUCCESS; + } + + This->String =3D (EFI_STRING)AllocatePool (Size); + + if (This->String !=3D NULL) { + This->String[0] =3D L'\0'; + This->PrivateBufferSize =3D Size; + } else { + This->PrivateBufferSize =3D 0; + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Frees HiiString Buffer + + @param[in, out] This Pointer to HII_STRING instance. + +**/ +VOID +HiiStringFree ( + IN OUT HII_STRING *This + ) +{ + ASSERT (This !=3D NULL); + + if (This->String !=3D NULL) { + FreePool (This->String); + This->String =3D NULL; + This->PrivateBufferSize =3D 0; + } +} + +/** + If buffer doesn't exist, allocate it. If the existing buffer is less tha= n + requested, allocate a larger one. + + @param[in, out] This Pointer to HII_STRING instance. + @param[in] Size Requested buffer size. + + @retval EFI_SUCCESS Buffer allocated. + @retval EFI_OUT_OF_RESOURCES OUt of memory. + +**/ +EFI_STATUS +HiiStringSetMinBufferSize ( + IN OUT HII_STRING *This, + IN UINTN Size + ) +{ + UINTN ThisStringSize; + EFI_STRING NewAlloc; + + ThisStringSize =3D (This->StringLength + 1) * sizeof (CHAR16); + + if (Size > This->PrivateBufferSize) { + NewAlloc =3D (EFI_STRING)AllocatePool (Size); + if (NewAlloc =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (NewAlloc, This->String, ThisStringSize); + FreePool (This->String); + This->String =3D NewAlloc; + This->PrivateBufferSize =3D Size; + } + + return EFI_SUCCESS; +} + +/** + Append a string to the string in HII_STRING instance. + + @param[in, out] This Pointer to HII_STRING instance. + @param[in] String String to append. + + @retval EFI_SUCCESS String is appended. + @retval EFI_OUT_OF_RESOURCES OUt of memory. + +**/ +EFI_STATUS +HiiStringAppend ( + IN OUT HII_STRING *This, + IN EFI_STRING String + ) +{ + EFI_STATUS Status; + UINTN ThisStringSize; + UINTN StringSize; + UINTN MaxLen; + + if ((This =3D=3D NULL) || (String =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + ThisStringSize =3D (This->StringLength + 1) * sizeof (CHAR16); + StringSize =3D HII_STR_SIZE (String); + + if (ThisStringSize + StringSize > This->PrivateBufferSize) { + MaxLen =3D (ThisStringSize + StringSize) * 2; + Status =3D HiiStringSetMinBufferSize (This, MaxLen); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Append the incoming string + // + CopyMem (&This->String[This->StringLength], String, StringSize); + This->StringLength +=3D StringSize / sizeof (CHAR16) - 1; + + return EFI_SUCCESS; +} + +/** + Append a number to the string in HII_STRING instance. + + @param[in, out] This Pointer to HII_STRING instance. + @param[in] Number Number to append. + @param[in] Length Length of Number. + + @retval EFI_SUCCESS Number is appended. + @retval EFI_OUT_OF_RESOURCES OUt of memory. +**/ +EFI_STATUS +HiiStringAppendValue ( + IN OUT HII_STRING *This, + IN UINT8 *Number, + IN UINTN Length + ) +{ + EFI_STATUS Status; + UINTN ThisStringSize; + UINTN Index; + UINTN Index2; + UINT8 Nibble; + UINTN MaxLen; + + CHAR16 *String; + + if (Length =3D=3D 0) { + return EFI_INVALID_PARAMETER; + } + + ThisStringSize =3D (This->StringLength + 1) * sizeof (CHAR16); + + if (ThisStringSize + Length * 2 * sizeof (CHAR16) > This->PrivateBufferS= ize) { + MaxLen =3D (ThisStringSize + Length * 2 * sizeof (CHAR16)) * 2; // Dou= ble requested string length. + Status =3D HiiStringSetMinBufferSize (This, MaxLen); + if (EFI_ERROR (Status)) { + return Status; + } + } + + String =3D This->String + This->StringLength; + This->StringLength +=3D Length * 2; + + Index =3D Length; + + do { + Index--; + Nibble =3D Number[Index] >> 4; + + for (Index2 =3D 0; Index2 < 2; Index2++) { + if (Nibble < 0xa) { + *String =3D '0' + Nibble; + } else { + *String =3D 'a' + Nibble - 0xa; + } + + Nibble =3D Number[Index] & 0xf; + String++; + } + } while (Index > 0); + + *String =3D '\0'; + + return EFI_SUCCESS; +} + +/** + Find an element header in the input string, and return pointer it is val= ue. + + This is a internal function. + + @param[in] Hdr Element Header to search for. + @param[in] String Search for element header in this string. + + @retval Pointer to value in element header. + @retval NULL if element header not found or end of string. + +**/ +EFI_STRING +FindElmentValue ( + IN ELEMENT_HDR Hdr, + IN EFI_STRING String + ) +{ + ASSERT (String !=3D NULL); + + if (HiiStrnCmp (String, gElementInfo[Hdr].ElementString, gElementInfo[Hd= r].ElementLength) !=3D 0) { + return NULL; + } + + return String + gElementInfo[Hdr].ElementLength; +} + +/** + Find pointer after value for element header in string. + + This is a internal function. + + @param[in] String String to search. + + @retval Pointer after value in element header. + +**/ +EFI_STRING +SkipElementValue ( + IN EFI_STRING String + ) +{ + ASSERT (String !=3D NULL); + + while (*String !=3D 0 && *String !=3D L'&') { + String++; + } + + if (*String =3D=3D L'&') { + String++; // Skip '&' + } + + return String; +} + +/** + Return pointer after ConfigHdr. + + This is a internal function. + + @param[in] String String to search. + + @retval Pointer after ConfigHdr. + @retval NULL if Config header not formed correctly. + +**/ +EFI_STRING +GetEndOfConfigHdr ( + IN EFI_STRING String + ) +{ + ASSERT (String !=3D NULL); + + String =3D FindElmentValue (ElementGuidHdr, String); + if (String =3D=3D NULL) { + return NULL; + } + + String =3D SkipElementValue (String); + if (*String =3D=3D 0) { + return NULL; + } + + while (*String !=3D 0 && + HiiStrnCmp ( + String, + gElementInfo[ElementPathHdr].ElementString, + gElementInfo[ElementPathHdr].ElementLength + ) + !=3D 0) + { + String++; + } + + if (*String !=3D 0) { + String =3D String + gElementInfo[ElementPathHdr].ElementLength; + } + + String =3D SkipElementValue (String); + return String; +} + +/** + This helper function is to be called by drivers to map configuration dat= a + stored in byte array ("block") formats such as UEFI Variables into curre= nt + configuration strings. + + @param[in] This A pointer to the EFI_HII_CONFIG_ROUTI= NG_PROTOCOL + instance. + @param[in] ConfigRequest A null-terminated Unicode string in + format. + @param[in] Block Array of bytes defining the block's c= onfiguration. + @param[in] BlockSize Length in bytes of Block. + @param[out] Config Filled-in configuration string. Stri= ng allocated + by the function. Returned only if call is + successful. It is string for= mat. + @param[out] Progress A pointer to a string filled in with= the offset of + the most recent & before the first failin= g + name/value pair (or the beginning of the = string if + the failure is in the first name/value pa= ir) or + the terminating NULL if all was successfu= l. + + @retval EFI_SUCCESS The request succeeded. Progress points to= the null + terminator at the end of the ConfigReques= t + string. + @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate Config. Pro= gress + points to the first character of ConfigRe= quest. + @retval EFI_INVALID_PARAMETER Passing in a NULL for the ConfigRequest o= r + Block parameter would result in this type= of + error. Progress points to the first chara= cter of + ConfigRequest. + @retval EFI_DEVICE_ERROR Block not large enough. Progress undefine= d. + @retval EFI_INVALID_PARAMETER Encountered non formatted str= ing. + Block is left updated and Progress points= at + the "&" preceding the first non-. + +**/ +EFI_STATUS +EFIAPI +HiiBlockToConfig ( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + IN CONST EFI_STRING ConfigRequest, + IN CONST UINT8 *Block, + IN CONST UINTN BlockSize, + OUT EFI_STRING *Config, + OUT EFI_STRING *Progress + ) +{ + EFI_STATUS Status; + EFI_STRING StringPtr; + EFI_STRING OrigPtr; + CHAR16 CharBackup; + UINTN Offset; + UINTN Width; + UINT8 *Value; + HII_STRING HiiString; + HII_NUMBER HiiNumber; + + if ((This =3D=3D NULL) || (Progress =3D=3D NULL) || (Config =3D=3D NULL)= ) { + return EFI_INVALID_PARAMETER; + } + + if ((Block =3D=3D NULL) || (ConfigRequest =3D=3D NULL)) { + *Progress =3D ConfigRequest; + return EFI_INVALID_PARAMETER; + } + + StringPtr =3D ConfigRequest; + + Status =3D HiiStringInit (&HiiString, MAX_STRING_LENGTH); + if (EFI_ERROR (Status)) { + *Progress =3D ConfigRequest; + return Status; + } + + HiiNumberInit (&HiiNumber); + + // + // Jump + // + StringPtr =3D GetEndOfConfigHdr (StringPtr); + if (StringPtr =3D=3D NULL) { + // + // Invalid header. + // + *Progress =3D ConfigRequest; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + if (*StringPtr =3D=3D L'\0') { + *Progress =3D StringPtr; + HiiStringAppend (&HiiString, ConfigRequest); + HiiToLower (HiiString.String); + + // + // Do not free HiiString.String with HiiStringFree; + // + *Config =3D HiiString.String; + return EFI_SUCCESS; + } + + // + // Copy and an additional '&' to + // + CharBackup =3D StringPtr[0]; + StringPtr[0] =3D L'\0'; // Temporarily change & to L'\0' + Status =3D HiiStringAppend (&HiiString, ConfigRequest); + if (EFI_ERROR (Status)) { + *Progress =3D ConfigRequest; + goto Exit; + } + + StringPtr[0] =3D CharBackup; + + // + // Parse each if exists + // Only format is supported by this help function. + // ::=3D 'OFFSET=3D'&'WIDTH=3D' + // + + // + // while search for "OFFSET=3D" + // When "OFFSET=3D" is found, OrigPtr starts at "OFFSET=3D", and StringP= tr points to value. + // + while (*StringPtr !=3D 0 && + (OrigPtr =3D StringPtr, (StringPtr =3D FindElmentValue (ElementOf= fsetHdr, StringPtr)) !=3D NULL) + ) + { + // + // Get Offset + // + Status =3D GetValueOfNumber (&HiiNumber, StringPtr); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_OUT_OF_RESOURCES) { + *Progress =3D ConfigRequest; // Out of memory + } else { + *Progress =3D OrigPtr - 1; + } + + goto Exit; + } + + Offset =3D HiiNumber.Value; + StringPtr +=3D HiiNumber.StringLength + 1; + + // + // Get Width + // + StringPtr =3D FindElmentValue (ElementWidthHdr, StringPtr); + if (StringPtr =3D=3D NULL) { + *Progress =3D OrigPtr - 1; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + Status =3D GetValueOfNumber (&HiiNumber, StringPtr); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_OUT_OF_RESOURCES) { + *Progress =3D ConfigRequest; // Out of memory + } else { + *Progress =3D OrigPtr - 1; + } + + goto Exit; + } + + Width =3D HiiNumber.Value; + StringPtr +=3D HiiNumber.StringLength; + + if ((*StringPtr !=3D 0) && (*StringPtr !=3D L'&')) { + *Progress =3D OrigPtr - 1; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + // + // Calculate Value and convert it to hex string. + // + if (Offset + Width > BlockSize) { + *Progress =3D StringPtr; + Status =3D EFI_DEVICE_ERROR; + goto Exit; + } + + Value =3D (UINT8 *)Block + Offset; + + CharBackup =3D *StringPtr; + *StringPtr =3D L'\0'; + + Status =3D HiiStringAppend (&HiiString, OrigPtr); + if (EFI_ERROR (Status)) { + *Progress =3D ConfigRequest; // Out of memory + goto Exit; + } + + *StringPtr =3D CharBackup; // End of section of string OrigPtr + + Status =3D HiiStringAppend (&HiiString, L"&VALUE=3D"); + if (EFI_ERROR (Status)) { + *Progress =3D ConfigRequest; // Out of memory + goto Exit; + } + + Status =3D HiiStringAppendValue (&HiiString, Value, Width); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_OUT_OF_RESOURCES) { + *Progress =3D ConfigRequest; // Out of memory + } else { + *Progress =3D OrigPtr - 1; + } + + goto Exit; + } + + // + // If L'\0', parsing is finished. Otherwise skip L'&' to continue + // + if (*StringPtr =3D=3D L'\0') { + break; + } + + Status =3D HiiStringAppend (&HiiString, L"&"); + if (EFI_ERROR (Status)) { + *Progress =3D ConfigRequest; // Out of memory + goto Exit; + } + + StringPtr++; // Skip L'&' + } + + if (*StringPtr !=3D L'\0') { + *Progress =3D StringPtr - 1; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + HiiToLower (HiiString.String); + *Progress =3D StringPtr; + + HiiNumberFree (&HiiNumber); + + // + // Do not free HiiString.String with HiiStringFree. The caller will + // consume it when EFI_SUCCESS. + // + *Config =3D HiiString.String; + + return EFI_SUCCESS; + +Exit: + HiiStringFree (&HiiString); + HiiNumberFree (&HiiNumber); + + *Config =3D NULL; + + return Status; +} + +/** + This helper function is to be called by drivers to map configuration str= ings + to configurations stored in byte array ("block") formats such as UEFI Va= riables. + + @param[in] This A pointer to the EFI_HII_CONFIG_ROUTI= NG_PROTOCOL + instance. + @param[in] ConfigResp A null-terminated Unicode string in <= ConfigResp> + format. + @param[in, out] Block A possibly null array of bytes r= epresenting the + current block. Only bytes referenced in t= he + ConfigResp string in the block are modifi= ed. If + this parameter is null or if the *BlockSi= ze + parameter is (on input) shorter than requ= ired by + the Configuration string, only the BlockS= ize + parameter is updated and an appropriate s= tatus + (see below) is returned. + @param[in, out] BlockSize The length of the Block in units= of UINT8. On + input, this is the size of the Block. On = output, + if successful, contains the largest index= of the + modified byte in the Block, or the requir= ed buffer + size if the Block is not large enough. + @param[out] Progress On return, points to an element of t= he ConfigResp + string filled in with the offset of the m= ost + recent '&' before the first failing name = / value + pair (or the beginning of the string if t= he + failure is in the first name / value pair= ) or the + terminating NULL if all was successful. + + @retval EFI_SUCCESS The request succeeded. Progress points to= the null + terminator at the end of the ConfigResp s= tring. + @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate Config. Pro= gress + points to the first character of ConfigRe= sp. + @retval EFI_INVALID_PARAMETER Passing in a NULL for the ConfigResp or + Block parameter would result in this type= of + error. Progress points to the first chara= cter of + ConfigResp. + @retval EFI_INVALID_PARAMETER Encountered non formatted nam= e / + value pair. Block is left updated and + Progress points at the '&' preceding the = first + non-. + @retval EFI_BUFFER_TOO_SMALL Block not large enough. Progress undefine= d. + BlockSize is updated with the required bu= ffer size. + @retval EFI_NOT_FOUND Target for the specified routing data was= not found. + Progress points to the "G" in "GUID" of t= he errant + routing data. + +**/ +EFI_STATUS +EFIAPI +HiiConfigToBlock ( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + IN CONST EFI_STRING ConfigResp, + IN OUT UINT8 *Block, + IN OUT UINTN *BlockSize, + OUT EFI_STRING *Progress + ) +{ + EFI_STATUS Status; + EFI_STRING StringPtr; + EFI_STRING OrigPtr; + UINTN Offset; + UINTN Width; + UINTN BufferSize; + UINTN MaxBlockSize; + HII_NUMBER HiiNumber; + + if ((This =3D=3D NULL) || (BlockSize =3D=3D NULL) || (Progress =3D=3D NU= LL)) { + return EFI_INVALID_PARAMETER; + } + + *Progress =3D ConfigResp; + if (ConfigResp =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + StringPtr =3D ConfigResp; + BufferSize =3D *BlockSize; + MaxBlockSize =3D 0; + + HiiNumberInit (&HiiNumber); + // + // Jump + // + StringPtr =3D GetEndOfConfigHdr (StringPtr); + if (StringPtr =3D=3D NULL) { + // + // Invalid header. + // + *Progress =3D ConfigResp; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + if (*StringPtr =3D=3D L'\0') { + *Progress =3D StringPtr; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + // + // Parse each if exists + // Only '&' format is supported by this help function. + // ::=3D 'OFFSET=3D'&'WIDTH=3D'&'VALUE=3D'= + // + while (*StringPtr !=3D L'\0' && + (OrigPtr =3D StringPtr, (StringPtr =3D FindElmentValue (ElementOf= fsetHdr, StringPtr)) !=3D NULL) + ) + { + // + // Get Offset + // + Status =3D GetValueOfNumber (&HiiNumber, StringPtr); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_OUT_OF_RESOURCES) { + *Progress =3D ConfigResp; // Out of memory + } else { + *Progress =3D OrigPtr - 1; + } + + goto Exit; + } + + Offset =3D HiiNumber.Value; + StringPtr +=3D HiiNumber.StringLength + 1; + + // + // Get Width + // + StringPtr =3D FindElmentValue (ElementWidthHdr, StringPtr); + if (StringPtr =3D=3D NULL) { + *Progress =3D OrigPtr - 1; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + Status =3D GetValueOfNumber (&HiiNumber, StringPtr); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_OUT_OF_RESOURCES) { + *Progress =3D ConfigResp; // Out of memory + } else { + *Progress =3D OrigPtr - 1; + } + + goto Exit; + } + + Width =3D HiiNumber.Value; + StringPtr +=3D HiiNumber.StringLength + 1; + + // + // Get Value + // + StringPtr =3D FindElmentValue (ElementValueHdr, StringPtr); + if (StringPtr =3D=3D NULL) { + *Progress =3D OrigPtr - 1; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + Status =3D GetValueOfNumber (&HiiNumber, StringPtr); + if (EFI_ERROR (Status)) { + if (Status =3D=3D EFI_OUT_OF_RESOURCES) { + *Progress =3D ConfigResp; // Out of memory + } else { + *Progress =3D OrigPtr - 1; + } + + goto Exit; + } + + // + // Update the Block with configuration info + // + if ((Block !=3D NULL) && (Offset + Width <=3D BufferSize)) { + CopyMem (Block + Offset, HiiNumber.NumberPtr, Width); + } + + if (Offset + Width > MaxBlockSize) { + MaxBlockSize =3D Offset + Width; + } + + StringPtr +=3D HiiNumber.StringLength; + + if ((*StringPtr !=3D L'\0') && (*StringPtr !=3D L'&')) { + *Progress =3D OrigPtr - 1; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + // + // If L'\0', parsing is finished. + // + if (*StringPtr =3D=3D L'\0') { + break; + } + + StringPtr++; // Skip L'&' + } + + // + // The input string is not ConfigResp format, return error. + // + if (*StringPtr !=3D L'\0') { + *Progress =3D StringPtr; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + *Progress =3D StringPtr + HiiStrLen (StringPtr); + *BlockSize =3D MaxBlockSize - 1; + + if (MaxBlockSize > BufferSize) { + *BlockSize =3D MaxBlockSize; + if (Block !=3D NULL) { + Status =3D EFI_BUFFER_TOO_SMALL; + goto Exit; + } + } + + if (Block =3D=3D NULL) { + *Progress =3D ConfigResp; + Status =3D EFI_INVALID_PARAMETER; + goto Exit; + } + + Status =3D EFI_SUCCESS; + +Exit: + + HiiNumberFree (&HiiNumber); + + return Status; +} diff --git a/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdHiiC= onfigRouting.h b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/Amd= HiiConfigRouting.h new file mode 100644 index 0000000000..bce606f7dd --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/HiiConfigRouting/AmdHiiConfigRo= uting.h @@ -0,0 +1,189 @@ +/** @file + Provide optimized implementation of HII_CONFIG_ROUTING Protocol + functions HiiBlockToConfig and HiiConfigToBlock. + + Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserv= ed. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef AMD_HII_CONFIG_ROUTING_H_ +#define AMD_HII_CONFIG_ROUTING_H_ + +#include +#include +#include +#include +#include +#include + +#define MAX_STRING_LENGTH 1024 + +/// +/// Returns the size of a Null-terminated Unicode string in bytes, includi= ng the +/// Null terminator. +/// +#define HII_STR_SIZE(str) ((HiiStrLen (str) + 1) * sizeof (*str)) + +/// +/// HII_NUMBER definitions +/// +typedef struct { + // Public variables + UINT8 *NumberPtr; ///< Pointer to a number in array of bytes. + UINTN NumberPtrLength; ///< 2 * number of bytes. Note: changing thi= s to + ///< number of bytes will impact existing co= de and + ///< hard to test. + UINTN Value; ///< If Value is less than or equal to 64-bi= ts, + ///< store value here as an unsigned integer= . + UINTN StringLength; ///< Input string length. + + // Private variables + UINTN PrivateBufferSize; ///< Size of allocated NumberPtr. This reduc= es + ///< reallocations as this can be used for + ///< multiple numbers. +} HII_NUMBER; + +/// +/// HII_STRING definitions +/// +typedef struct { + // Public variables + EFI_STRING String; ///< String that is maintained here, and= futures + ///< calls will append to it. + UINTN StringLength; ///< Length of String. + + // Private variables + UINTN PrivateBufferSize; ///< Length of allocated String. This r= educes + ///< reallocations as strings are appen= ded. +} HII_STRING; + +#define FIXED_STR_LEN(String) (sizeof (String) / sizeof (CHAR16) - 1) + +typedef enum { + ElementGuidHdr =3D 0, + ElementNameHdr =3D 1, + ElementPathHdr =3D 2, + ElementOffsetHdr =3D 3, + ElementWidthHdr =3D 4, + ElementValueHdr =3D 5 +} ELEMENT_HDR; + +typedef struct { + EFI_STRING ElementString; + UINTN ElementLength; +} HII_ELEMENT; + +/** + This helper function is to be called by drivers to map configuration dat= a + stored in byte array ("block") formats such as UEFI Variables into curre= nt + configuration strings. + + @param This A pointer to the EFI_HII_CONFIG_ROUTING_= PROTOCOL + instance. + @param ConfigRequest A null-terminated Unicode string in + format. + @param Block Array of bytes defining the block's + configuration. + @param BlockSize Length in bytes of Block. + @param Config Filled-in configuration string. String a= llocated + by the function. Returned only if call = is + successful. + @param Progress A pointer to a string filled in with the= offset + of the most recent & before the first f= ailing + name/value pair (or the beginning of the= string + if the failure is in the first name / va= lue pair) + or the terminating NULL if all was succe= ssful. + + @retval EFI_SUCCESS The request succeeded. Progress points t= o the + null terminator at the end of the Config= Request + string. + @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate Config. + Progress points to the first character o= f + ConfigRequest. + @retval EFI_INVALID_PARAMETER Passing in a NULL for the ConfigRequest = or + Block parameter would result in this typ= e of + error. Progress points to the first char= acter + of ConfigRequest. + @retval EFI_NOT_FOUND Target for the specified routing data wa= s not + found. Progress points to the "G" in "GU= ID" of + the errant routing data. + @retval EFI_DEVICE_ERROR Block not large enough. Progress undefin= ed. + @retval EFI_INVALID_PARAMETER Encountered non formatted st= ring. + Block is left updated and Progress point= s at + the '&' preceding the first non-. + +**/ +EFI_STATUS +EFIAPI +HiiBlockToConfig ( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + IN CONST EFI_STRING ConfigRequest, + IN CONST UINT8 *Block, + IN CONST UINTN BlockSize, + OUT EFI_STRING *Config, + OUT EFI_STRING *Progress + ); + +/** + This helper function is to be called by drivers to map configuration str= ings + to configurations stored in byte array ("block") formats such as UEFI Va= riables. + + @param This A pointer to the EFI_HII_CONFIG_ROUTING_= PROTOCOL + instance. + @param ConfigResp A null-terminated Unicode string in + format. + @param Block A possibly null array of bytes represent= ing the + current block. Only bytes referenced in = the + ConfigResp string in the block are modif= ied. If + this parameter is null or if the *BlockS= ize + parameter is (on input) shorter than req= uired by + the Configuration string, only the Block= Size + parameter is updated and an appropriate = status + (see below) is returned. + @param BlockSize The length of the Block in units of UINT= 8. On + input, this is the size of the Block. On= output, + if successful, contains the largest inde= x of + the modified byte in the Block, or the r= equired + buffer. + size if the Block is not large enough. + @param Progress On return, points to an element of the C= onfigResp + string filled in with the offset of the = most + recent '&' before the first failing name= /value + pair (or the beginning of the string if = the + failure is in the first name/value pair)= or + the terminating NULL if all was successf= ul. + + @retval EFI_SUCCESS The request succeeded. Progress points t= o the + null terminator at the end of the Config= Resp + string. + @retval EFI_OUT_OF_RESOURCES Not enough memory to allocate Config. Pr= ogress + points to the first character of ConfigR= esp. + @retval EFI_INVALID_PARAMETER Passing in a NULL for the ConfigResp or = Block + parameter would result in this type of e= rror. + Progress points to the first character o= f + ConfigResp. + @retval EFI_NOT_FOUND Target for the specified routing data wa= s not + found. Progress points to the "G" in "GU= ID" of + the errant routing data. + @retval EFI_INVALID_PARAMETER Encountered non formatted na= me/ + value pair. Block is left updated and Pr= ogress + points at the '&' preceding the first + non-. + @retval EFI_BUFFER_TOO_SMALL Block not large enough. Progress undefin= ed. + BlockSize is updated with the required b= uffer + size. + +**/ +EFI_STATUS +EFIAPI +HiiConfigToBlock ( + IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This, + IN CONST EFI_STRING ConfigResp, + IN OUT UINT8 *Block, + IN OUT UINTN *BlockSize, + OUT EFI_STRING *Progress + ); + +#endif // AMD_HII_CONFIG_ROUTING_H_ --=20 2.34.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 (#118905): https://edk2.groups.io/g/devel/message/118905 Mute This Topic: https://groups.io/mt/106108334/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-