From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (NAM12-DM6-obe.outbound.protection.outlook.com [40.107.243.61]) by mx.groups.io with SMTP id smtpd.web11.6038.1681366871818670237 for ; Wed, 12 Apr 2023 23:21:12 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@nvidia.com header.s=selector2 header.b=eLbSp/Jz; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: nvidia.com, ip: 40.107.243.61, mailfrom: nicklew@nvidia.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eQAD3pgJrNhepDVY8zPxZdmkXIsp2p8MIls9jO83s/t1oVkTH3Nj3LshZYrpYTTrPXJ00dL6iV44Pz169UcMUHrDQ4snB/G0CMivVUYj0tzwr2+1dpekYKM+gqHQLArFLdwaO9HLyH5eHxyHD2WjeADjYEFs0aOhiHcaK643JJxyVWwv4wbj8s8ufliGUuh79/Hs7grGCxTOEIeP1dA8E4wCMF15UG9YPYOakYPhGyswlBKRNMJfjd+TmGMwuhUedorWxaTl5rl0auil2u355YKguvCzD40RXZLxy+F4MoDU4mMuhxbSbuu1EKAC2aNxsR9kcSrj+lqGv6rtLoSC6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=EfXms/vVNYXG0YJ76ZWeSwDbdVbX4IEUTnnxMyFDtLs=; b=hKHWwoIP01T5UVklb1hsHLArxIQRMK5ZCzlZt3NmNRW1GrzjDuu9mYdFXq0LkYLD3bHm1MO2GAds3aSCbxaI2bmNPwVsfA12A41DMkM4kcRY7evrcYvbjE0RtoWH+ICOonqYa+AhElpbN9x4gn9xOURXbSxYZFedAsBs8ODYYtoLK68Q1FPg6Zea6W9FHjf9H5FN0+xiqR8vIHUMmkTKDAyeOT4r8OKUtNNcyPbhZjozEemZe5KtHvTElhraU6SzRgde4d3HCqQ/oNIMbNOznh/Y5y1NysBAeYjc6NR8cym5mzJOxkhfRl6Ms3lHNdtY4mpjp77Iy5gdU4nnyRCLeA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.160) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=EfXms/vVNYXG0YJ76ZWeSwDbdVbX4IEUTnnxMyFDtLs=; b=eLbSp/JzoSadW3mrid2qAEBMcSN5Z4StyXvnRwduJ1JAOJNfSPWDA533Vxb0eoJhupMBhd8AKucJtm5Frv8cO9kgqONOjVlqSKAiUoIIWAoP7fw7psnTs0HHiM/hHiPhjBiAZgfvukS3/+lOX6vFnpQjokvuVJhj4eEE8WIX22q2vTBUKQz9BJcznc2SAYkUizFqX5dkXvlcBqqLMOLDzuB6T8A4fT1dn4XtX53dlB5NTsGPSoysW94zwaJ2iBxFVjtQdrn/w/z5lzyO0Mt8AIjLye4xAEpHCVc9b1K41NxYLYyFoI/lSCwUP/Nq8nlYhsgh5U3E79aKyaqWg7Vj6Q== Received: from DM6PR13CA0030.namprd13.prod.outlook.com (2603:10b6:5:bc::43) by SJ0PR12MB5422.namprd12.prod.outlook.com (2603:10b6:a03:3ac::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.30; Thu, 13 Apr 2023 06:21:00 +0000 Received: from DM6NAM11FT022.eop-nam11.prod.protection.outlook.com (2603:10b6:5:bc:cafe::35) by DM6PR13CA0030.outlook.office365.com (2603:10b6:5:bc::43) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.6 via Frontend Transport; Thu, 13 Apr 2023 06:21:00 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.160) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.160 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.160) by DM6NAM11FT022.mail.protection.outlook.com (10.13.172.210) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.31 via Frontend Transport; Thu, 13 Apr 2023 06:21:00 +0000 Received: from rnnvmail202.nvidia.com (10.129.68.7) by mail.nvidia.com (10.129.200.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Wed, 12 Apr 2023 23:20:50 -0700 Received: from rnnvmail205.nvidia.com (10.129.68.10) by rnnvmail202.nvidia.com (10.129.68.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Wed, 12 Apr 2023 23:20:46 -0700 Received: from NV-CL38DL3.nvidia.com (10.127.8.11) by mail.nvidia.com (10.129.68.10) with Microsoft SMTP Server id 15.2.986.37 via Frontend Transport; Wed, 12 Apr 2023 23:20:45 -0700 From: "Nickle Wang" To: CC: Abner Chang , Igor Kulchytskyy , "Nick Ramirez" Subject: [PATCH 2/5] RedfishPkg: introduce HII utility helper library Date: Thu, 13 Apr 2023 14:20:44 +0800 Message-ID: <20230413062044.1654-1-nicklew@nvidia.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 Return-Path: nicklew@nvidia.com X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM6NAM11FT022:EE_|SJ0PR12MB5422:EE_ X-MS-Office365-Filtering-Correlation-Id: b3e53ad5-ffdf-4e44-32a2-08db3be7404e X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +pf7A2AaSoMSkMx5vyyOSefSSPtrbXkUuGe4o8Mnr5ekqVojt5zEGp8AfMFy582dt5pnQ0IoEKM3r9Lb6eGD2eB/RpGGFft0+iPvMxgfAwPSBmBAEX/62P/NJyPTKrNBc2pZWlyzuV578UsRga/5xihGl3aX5HGfhM6bygiwArYHKYS3s5lrGlTbpwshFQd29TyNgaGeG2eGfiDa3J+wMW52v2TptgZksFdMCgfc/2ce5frhx/bz8MUynYJDXINYFaV3FOxcq6XxsPUuixC7hpAHt+hYejuly2mA7vIFJvEcb8toRaIrvPYjrItud53rS5D6f+1BdCCetSYgeOpwyWEjGaRBCDPrVfG8CQ2vVa3kW6xyp+zC9rkuks6/V/mBA+xCLiG6N6dfkYpie182Tt5znianT7DVxMv+9kVdFW4fx/lADFXTcavJsD60ticNH6JdVhRPy5mRTr/y6Nd8YSsoW5VjspDEhzPtsQmMgMN+XLZAhZNDfcC+Zl5fF3DTpq+jCkYIJ4oAdv77jyMKaP4KKYk62vFck9BoR/E56xwQ6KTGSnd9Ck/9SwIIygivniZTPMwQxtH3MaT/0+0EId3v1LFghfT3xQVnQdA+89u/leKOXVIVOkAIDRbacpdhopmE7gt4P/+UmO4U+658fCH52UcleXDBvjHSfXH3Hi5y2V9L4/4Hhl1JpOAEgl6+p6XLwhjubydN9xXgLHN8LAeE18Ohb54ym1hjVXk7vvUBu3LDyo1YA6ubp6+0FtaIxFx3yLV/9dLcTNY0k+93Z7WlfR6nTi3/ImHt9OgqmCo= X-Forefront-Antispam-Report: CIP:216.228.117.160;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge1.nvidia.com;CAT:NONE;SFS:(13230028)(4636009)(376002)(39860400002)(136003)(346002)(396003)(451199021)(40470700004)(36840700001)(46966006)(40460700003)(316002)(41300700001)(1076003)(7696005)(26005)(186003)(86362001)(66574015)(47076005)(34020700004)(356005)(36860700001)(107886003)(7636003)(2616005)(82310400005)(426003)(336012)(83380400001)(82740400003)(6916009)(4326008)(54906003)(36756003)(40480700001)(19627235002)(70206006)(70586007)(8676002)(8936002)(5660300002)(2906002)(30864003)(478600001)(579004)(559001);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Apr 2023 06:21:00.4001 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b3e53ad5-ffdf-4e44-32a2-08db3be7404e X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.160];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT022.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR12MB5422 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain HiiUtilityLib is a helper library that provides the functions to manipulate HII options. Signed-off-by: Nickle Wang Cc: Abner Chang Cc: Igor Kulchytskyy Cc: Nick Ramirez --- RedfishPkg/RedfishPkg.dec | 4 + .../Library/HiiUtilityLib/HiiUtilityLib.inf | 61 + RedfishPkg/Include/Library/HiiUtilityLib.h | 1205 ++++ .../Library/HiiUtilityLib/HiiExpression.h | 214 + .../Library/HiiUtilityLib/HiiInternal.h | 369 ++ .../Library/HiiUtilityLib/HiiExpression.c | 1442 ++++ .../Library/HiiUtilityLib/HiiIfrParse.c | 2717 ++++++++ .../HiiUtilityLib/HiiUtilityInternal.c | 5770 +++++++++++++++++ .../Library/HiiUtilityLib/HiiUtilityLib.c | 810 +++ 9 files changed, 12592 insertions(+) create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.inf create mode 100644 RedfishPkg/Include/Library/HiiUtilityLib.h create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiExpression.h create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiInternal.h create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiExpression.c create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiIfrParse.c create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiUtilityInternal.c create mode 100644 RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.c diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec index 904630ae4be6..e2892ce9cec1 100644 --- a/RedfishPkg/RedfishPkg.dec +++ b/RedfishPkg/RedfishPkg.dec @@ -60,6 +60,10 @@ # Library provides Redfish debug functions. RedfishDebugLib|Include/Library/RedfishDebugLib.h =20 + ## @libraryclass Provides the library functions to parse IFR binary da= ta. + # + HiiUtilityLib|Include/Library/HiiUtilityLib.h + [LibraryClasses.Common.Private] ## @libraryclass Provides the private C runtime library functions. # CRT library is currently used by edk2 JsonLib (open source diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.inf b/RedfishPk= g/Library/HiiUtilityLib/HiiUtilityLib.inf new file mode 100644 index 000000000000..58306aa73227 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.inf @@ -0,0 +1,61 @@ +## @file +# Library to handle HII IFR data. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D HiiUtilityLib + FILE_GUID =3D D00DA028-F19A-47AF-B22A-6EE9E8BD7335 + MODULE_TYPE =3D UEFI_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D HiiUtilityLib|DXE_DRIVER UEFI_DRIVER = UEFI_APPLICATION + +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + HiiUtilityLib.c + HiiExpression.c + HiiUtilityInternal.c + HiiIfrParse.c + HiiInternal.h + HiiExpression.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + PrintLib + DebugLib + BaseMemoryLib + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + MemoryAllocationLib + HiiLib + +[Guids] + gZeroGuid + gEdkiiIfrBitVarstoreGuid + gEfiHiiPlatformSetupFormsetGuid + gEfiHiiStandardFormGuid + +[Protocols] + gEfiHiiDatabaseProtocolGuid + gEfiHiiConfigRoutingProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiDevicePathFromTextProtocolGuid + gEfiUnicodeCollation2ProtocolGuid + gEfiRegularExpressionProtocolGuid + gEfiUserManagerProtocolGuid + +[Depex] + TRUE diff --git a/RedfishPkg/Include/Library/HiiUtilityLib.h b/RedfishPkg/Includ= e/Library/HiiUtilityLib.h new file mode 100644 index 000000000000..e2355b2f2898 --- /dev/null +++ b/RedfishPkg/Include/Library/HiiUtilityLib.h @@ -0,0 +1,1205 @@ +/** @file + Definitions of RedfishPlatformConfigLib. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef HII_UTILITY_LIB_ +#define HII_UTILITY_LIB_ + +#include +#include + +// +// IFR relative definition +// +#define EFI_HII_EXPRESSION_INCONSISTENT_IF 0 +#define EFI_HII_EXPRESSION_NO_SUBMIT_IF 1 +#define EFI_HII_EXPRESSION_GRAY_OUT_IF 2 +#define EFI_HII_EXPRESSION_SUPPRESS_IF 3 +#define EFI_HII_EXPRESSION_DISABLE_IF 4 +#define EFI_HII_EXPRESSION_VALUE 5 +#define EFI_HII_EXPRESSION_RULE 6 +#define EFI_HII_EXPRESSION_READ 7 +#define EFI_HII_EXPRESSION_WRITE 8 +#define EFI_HII_EXPRESSION_WARNING_IF 9 + +#define EFI_HII_VARSTORE_BUFFER 0 +#define EFI_HII_VARSTORE_NAME_VALUE 1 +#define EFI_HII_VARSTORE_EFI_VARIABLE 2 // EFI Varstore type fol= low UEFI spec before 2.3.1. +#define EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER 3 // EFI varstore type fol= low UEFI spec 2.3.1 and later. + +// +// HII_NAME_VALUE_NODE for name/value storage +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + CHAR16 *Name; + CHAR16 *Value; +} HII_NAME_VALUE_NODE; + +#define HII_NAME_VALUE_NODE_SIGNATURE SIGNATURE_32 ('N', 'V', 'S', 'T') +#define HII_NAME_VALUE_NODE_FROM_LINK(a) CR (a, HII_NAME_VALUE_NODE, Link= , HII_NAME_VALUE_NODE_SIGNATURE) + +// +// Storage info +// +typedef union { + EFI_STRING_ID VarName; + UINT16 VarOffset; +} HII_VAR_STORE_INFO; + +// +// FormSet storage +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + UINT8 Type; // Storage type + EFI_HII_HANDLE HiiHandle; // HiiHandle for this varstore. + + // + // For all type of storages. + // + UINT16 VarStoreId; // VarStore ID. + EFI_GUID Guid; // VarStore Guid. + + // + // For EFI_IFR_VARSTORE, EFI_IFR_VARSTORE_EFI + // + CHAR16 *Name; // VarStore name + UINT16 Size; // VarStore size. + UINT8 *Buffer; // Buffer storage. + UINT8 *EditBuffer; // Edit copy for Buffer Storage + + // + // For EFI_IFR_VARSTORE_EFI: EFI Variable. + // + UINT32 Attributes; + + // + // For EFI_IFR_VARSTORE_NAME_VALUE. + // + LIST_ENTRY NameValueList; // List of NAME_VALUE_NODE + + CHAR16 *ConfigHdr; // + CHAR16 *ConfigRequest; // =3D + <= RequestElement> + UINTN ElementCount; // Number of in the <= ConfigRequest> + UINTN SpareStrLen; // Spare length of ConfigRequest strin= g buffer +} HII_FORMSET_STORAGE; + +#define HII_STORAGE_SIGNATURE SIGNATURE_32 ('B', 'S', 'T', 'G') +#define HII_STORAGE_FROM_LINK(a) CR (a, HII_FORMSET_STORAGE, Link, HII_ST= ORAGE_SIGNATURE) + +// +// Definition of EXPRESS_RESULT +// +typedef enum { + ExpressFalse =3D 0, + ExpressGrayOut, + ExpressSuppress, + ExpressDisable +} EXPRESS_RESULT; + +// +// Definition of EXPRESS_LEVEL +// +typedef enum { + ExpressNone =3D 0, + ExpressForm, + ExpressStatement, + ExpressOption +} EXPRESS_LEVEL; + +// +// Definition of HII_EXPRESSION_OPCODE_EXTRA +// +typedef union { + EFI_HII_VALUE Value; // EFI_IFR_UINT64, EFI_IFR_UINT32, EFI_I= FR_UINT16, EFI_IFR_UINT8, EFI_IFR_STRING_REF1 + UINT8 Format; // For EFI_IFR_TO_STRING, EFI_IFR_FIND + UINT8 Flags; // For EFI_IFR_SPAN + UINT8 RuleId; // For EFI_IFR_RULE_REF + EFI_GUID Guid; // For EFI_IFR_SECURITY, EFI_IFR_MATCH2 + + struct { + EFI_QUESTION_ID QuestionId; + EFI_HII_VALUE Value; + } EqIdValData; + + struct { + EFI_QUESTION_ID QuestionId1; + EFI_QUESTION_ID QuestionId2; + } EqIdIdData; + + struct { + EFI_QUESTION_ID QuestionId; // For EFI_IFR_EQ_ID_VAL_LIST + UINT16 ListLength; + UINT16 *ValueList; + } EqIdListData; + + struct { + EFI_QUESTION_ID QuestionId; + } QuestionRef1Data; + + struct { + EFI_STRING_ID DevicePath; // For EFI_IFR_QUESTION_REF3_3 + EFI_GUID Guid; + } QuestionRef3Data; + + struct { + HII_FORMSET_STORAGE *VarStorage; + HII_VAR_STORE_INFO VarStoreInfo; + UINT8 ValueType; + UINT8 ValueWidth; + CHAR16 *ValueName; + } GetSetData; +} HII_EXPRESSION_OPCODE_EXTRA; + +typedef union _HII_DEPENDENCY_EXPRESSION HII_DEPENDENCY_EXPRESSION; + +// +// Definition of HII_EXPRESSION_CONSTANT +// +// Operand: +// +// EFI_IFR_TRUE +// EFI_IFR_FALSE +// EFI_IFR_ONE +// EFI_IFR_ONES +// EFI_IFR_ZERO +// EFI_IFR_UNDEFINED +// EFI_IFR_VERSION +// EFI_IFR_UINT8 +// EFI_IFR_UINT16 +// EFI_IFR_UINT32 +// EFI_IFR_UINT64 +// +typedef struct { + UINT8 Operand; + EFI_HII_VALUE Value; +} HII_EXPRESSION_CONSTANT; + +// +// Definition of HII_DEPENDENCY_DUP +// +typedef struct { + UINT8 Operand; +} HII_DEPENDENCY_DUP; + +// +// Definition of HII_DEPENDENCY_EQ_ID_VAL +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId; + EFI_HII_VALUE Value; +} HII_DEPENDENCY_EQ_ID_VAL; + +// +// Definition of HII_DEPENDENCY_EQ_ID_VAL +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId1; + EFI_QUESTION_ID QuestionId2; +} HII_DEPENDENCY_EQ_ID_ID; + +// +// Definition of HII_DEPENDENCY_EQ_ID_VAL_LIST +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId; + UINT16 ListLength; + UINT16 *ValueList; +} HII_DEPENDENCY_EQ_ID_VAL_LIST; + +// +// Definition of HII_DEPENDENCY_QUESTION_REF1 +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId; +} HII_DEPENDENCY_QUESTION_REF1; + +// +// Definition of HII_DEPENDENCY_RULE_REF +// +typedef struct { + UINT8 Operand; + UINT8 RuleId; +} HII_DEPENDENCY_RULE_REF; + +// +// Definition of HII_DEPENDENCY_STRING_REF1 +// +typedef struct { + UINT8 Operand; + EFI_HII_VALUE Value; +} HII_DEPENDENCY_STRING_REF1; + +// +// Definition of HII_DEPENDENCY_THIS +// +typedef struct { + UINT8 Operand; + EFI_QUESTION_ID QuestionId; +} HII_DEPENDENCY_THIS; + +// +// Definition of HII_DEPENDENCY_SECURITY +// +typedef struct { + UINT8 Operand; + EFI_GUID Permissions; +} HII_DEPENDENCY_SECURITY; + +// +// Definition of HII_DEPENDENCY_GET +// +typedef struct { + UINT8 Operand; + HII_FORMSET_STORAGE *VarStorage; + HII_VAR_STORE_INFO VarStoreInfo; + UINT8 ValueType; + UINT8 ValueWidth; + CHAR16 *ValueName; +} HII_DEPENDENCY_GET; + +// +// Definition of HII_DEPENDENCY_LENGTH +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_LENGTH; + +// +// Definition of HII_DEPENDENCY_BITWISE_NOT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_BITWISE_NOT; + +// +// Definition of HII_DEPENDENCY_STRING_REF2 +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_STRING_REF2; + +// +// Definition of HII_DEPENDENCY_QUESTION_REF2 +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_QUESTION_REF2; + +// +// Definition of HII_DEPENDENCY_QUESTION_REF3 +// +typedef struct { + UINT8 Operand; + EFI_STRING_ID DevicePath; + EFI_GUID Guid; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_QUESTION_REF3; + +// +// Definition of HII_DEPENDENCY_TO_BOOLEAN +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_BOOLEAN; + +// +// Definition of HII_DEPENDENCY_TO_STRING +// +typedef struct { + UINT8 Operand; + UINT8 Format; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_STRING; + +// +// Definition of HII_DEPENDENCY_TO_UINT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_UINT; + +// +// Definition of HII_DEPENDENCY_TO_UPPER +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_UPPER; + +// +// Definition of HII_DEPENDENCY_TO_LOWER +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_TO_LOWER; + +// +// Definition of HII_DEPENDENCY_SET +// +typedef struct { + UINT8 Operand; + HII_FORMSET_STORAGE *VarStorage; + HII_VAR_STORE_INFO VarStoreInfo; + UINT8 ValueType; + UINT8 ValueWidth; + CHAR16 *ValueName; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_SET; + +// +// Definition of HII_DEPENDENCY_NOT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression; +} HII_DEPENDENCY_NOT; + +// +// Definition of HII_DEPENDENCY_CATENATE +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *LeftStringExp; + HII_DEPENDENCY_EXPRESSION *RightStringExp; +} HII_DEPENDENCY_CATENATE; + +// +// Definition of HII_DEPENDENCY_MATCH +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *StringExp; + HII_DEPENDENCY_EXPRESSION *PatternExp; +} HII_DEPENDENCY_MATCH; + +// +// Definition of HII_DEPENDENCY_MATCH2 +// +typedef struct { + UINT8 Operand; + EFI_GUID SyntaxType; + HII_DEPENDENCY_EXPRESSION *StringExp; + HII_DEPENDENCY_EXPRESSION *PatternExp; +} HII_DEPENDENCY_MATCH2; + +// +// Definition of HII_DEPENDENCY_MULT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_MULT; + +// +// Definition of HII_DEPENDENCY_DIV +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; // right value + HII_DEPENDENCY_EXPRESSION *LeftHandExp; // left value +} HII_DEPENDENCY_DIV; + +// +// Definition of HII_DEPENDENCY_MOD +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; // right value + HII_DEPENDENCY_EXPRESSION *LeftHandExp; // left value +} HII_DEPENDENCY_MOD; + +// +// Definition of HII_DEPENDENCY_ADD +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; // right value + HII_DEPENDENCY_EXPRESSION *LeftHandExp; // left value +} HII_DEPENDENCY_ADD; + +// +// Definition of HII_DEPENDENCY_SUBTRACT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; // right value + HII_DEPENDENCY_EXPRESSION *LeftHandExp; // left value +} HII_DEPENDENCY_SUBTRACT; + +// +// Definition of HII_DEPENDENCY_SHIFT_LEFT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_SHIFT_LEFT; + +// +// Definition of HII_DEPENDENCY_SHIFT_RIGHT +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_SHIFT_RIGHT; + +// +// Definition of HII_DEPENDENCY_GREATER_THAN +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_GREATER_THAN; + +// +// Definition of HII_DEPENDENCY_GREATER_EQUAL +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_GREATER_EQUAL; + +// +// Definition of HII_DEPENDENCY_LESS_THAN +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_LESS_THAN; + +// +// Definition of HII_DEPENDENCY_LESS_EQUAL +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *RightHandExp; + HII_DEPENDENCY_EXPRESSION *LeftHandExp; +} HII_DEPENDENCY_LESS_EQUAL; + +// +// Definition of HII_DEPENDENCY_EQUAL +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_EQUAL; + +// +// Definition of HII_DEPENDENCY_NOT_EQUAL +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_NOT_EQUAL; + +// +// Definition of HII_DEPENDENCY_BITWISE_AND +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_BITWISE_AND; + +// +// Definition of HII_DEPENDENCY_BITWISE_OR +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_BITWISE_OR; + +// +// Definition of HII_DEPENDENCY_AND +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_AND; + +// +// Definition of HII_DEPENDENCY_OR +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExpression1; + HII_DEPENDENCY_EXPRESSION *SubExpression2; +} HII_DEPENDENCY_OR; + +// +// Definition of HII_DEPENDENCY_CONDITIONAL +// +// Ternary expression +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *CondTrueValExp; // right value + HII_DEPENDENCY_EXPRESSION *CondFalseValExp; // middle value + HII_DEPENDENCY_EXPRESSION *ConditionExp; // left value +} HII_DEPENDENCY_CONDITIONAL; + +// +// Definition of HII_DEPENDENCY_FIND +// +typedef struct { + UINT8 Operand; + UINT8 Format; + HII_DEPENDENCY_EXPRESSION *IndexExp; // right value + HII_DEPENDENCY_EXPRESSION *StringToCompWithExp; // middle value + HII_DEPENDENCY_EXPRESSION *StringToSearchExp; // left value +} HII_DEPENDENCY_FIND; + +// +// Definition of HII_DEPENDENCY_MID +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *LengthExp; // right value + HII_DEPENDENCY_EXPRESSION *IndexExp; // middle value + HII_DEPENDENCY_EXPRESSION *StringOrBufferExp; // left value +} HII_DEPENDENCY_MID; + +// +// Definition of HII_DEPENDENCY_TOKEN +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *IndexExp; // right value + HII_DEPENDENCY_EXPRESSION *DelimiterExp; // middle value + HII_DEPENDENCY_EXPRESSION *StringToSearchExp; // left value +} HII_DEPENDENCY_TOKEN; + +// +// Definition of HII_DEPENDENCY_SPAN +// +typedef struct { + UINT8 Operand; + UINT8 Flags; + HII_DEPENDENCY_EXPRESSION *IndexExp; // right value + HII_DEPENDENCY_EXPRESSION *CharsetExp; // middle value + HII_DEPENDENCY_EXPRESSION *StringToSearchExp; // left value +} HII_DEPENDENCY_SPAN; + +// +// Map expression +// +typedef struct { + HII_DEPENDENCY_EXPRESSION *MatchExp; + HII_DEPENDENCY_EXPRESSION *ReturnExp; +} HII_DEPENDENCY_EXPRESSION_PAIR; + +// +// Definition of HII_DEPENDENCY_MAP +// +typedef struct { + UINT8 Operand; + HII_DEPENDENCY_EXPRESSION *SubExp; + HII_DEPENDENCY_EXPRESSION_PAIR *ExpPair; + UINT8 ExpPairNo; +} HII_DEPENDENCY_MAP; + +// +// Definition of HII_DEPENDENCY_EXPRESSION +// +union _HII_DEPENDENCY_EXPRESSION { + // + // Constant + // + HII_EXPRESSION_CONSTANT ConstantExp; + // + // build-in expression + // + HII_DEPENDENCY_DUP DupExp; + HII_DEPENDENCY_EQ_ID_VAL EqIdValExp; + HII_DEPENDENCY_EQ_ID_ID EqIdIdExp; + HII_DEPENDENCY_EQ_ID_VAL_LIST EqIdListExp; + HII_DEPENDENCY_QUESTION_REF1 QuestionRef1Exp; + HII_DEPENDENCY_RULE_REF RuleRefExp; + HII_DEPENDENCY_STRING_REF1 StringRef1Exp; + HII_DEPENDENCY_THIS ThisExp; + HII_DEPENDENCY_SECURITY SecurityExp; + HII_DEPENDENCY_GET GetExp; + + // + // unary expression + // + HII_DEPENDENCY_LENGTH LengthExp; + HII_DEPENDENCY_BITWISE_NOT BitWiseNotExp; + HII_DEPENDENCY_STRING_REF2 StringRef2Exp; + HII_DEPENDENCY_QUESTION_REF2 QuestionRef2Exp; + HII_DEPENDENCY_QUESTION_REF3 QuestionRef3Exp; + HII_DEPENDENCY_TO_BOOLEAN ToBooleanExp; + HII_DEPENDENCY_TO_STRING ToStringExp; + HII_DEPENDENCY_TO_UINT ToUintExp; + HII_DEPENDENCY_TO_UPPER ToUpperExp; + HII_DEPENDENCY_TO_LOWER ToLowerExp; + HII_DEPENDENCY_SET SetExp; + HII_DEPENDENCY_NOT NotExp; + + // + // Binary expression + // + HII_DEPENDENCY_CATENATE CatenateExp; + HII_DEPENDENCY_MATCH MatchExp; + HII_DEPENDENCY_MATCH2 Match2Exp; + HII_DEPENDENCY_MULT MultExp; + HII_DEPENDENCY_DIV DivExp; + HII_DEPENDENCY_MOD ModExp; + HII_DEPENDENCY_ADD AddExp; + HII_DEPENDENCY_SUBTRACT SubtractExp; + HII_DEPENDENCY_SHIFT_LEFT ShiftLeftExp; + HII_DEPENDENCY_SHIFT_RIGHT ShiftRightExp; + HII_DEPENDENCY_GREATER_THAN GreaterThanExp; + HII_DEPENDENCY_GREATER_EQUAL GreaterEqualExp; + HII_DEPENDENCY_LESS_THAN LessThanExp; + HII_DEPENDENCY_LESS_EQUAL LessEqualExp; + HII_DEPENDENCY_EQUAL EqualExp; + HII_DEPENDENCY_NOT_EQUAL NotEqualExp; + HII_DEPENDENCY_BITWISE_AND BitwiseAndExp; + HII_DEPENDENCY_BITWISE_OR BitwiseOrExp; + HII_DEPENDENCY_AND AndExp; + HII_DEPENDENCY_OR OrExp; + + // + // ternary expression + // + HII_DEPENDENCY_CONDITIONAL ConditionalExp; + HII_DEPENDENCY_FIND FindExp; + HII_DEPENDENCY_MID MidExp; + HII_DEPENDENCY_TOKEN TokenExp; + HII_DEPENDENCY_SPAN SpanExp; + HII_DEPENDENCY_MAP MapExp; +}; + +// +// Definition of HII_EXPRESSION_OPCODE +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + UINT8 Operand; + HII_EXPRESSION_OPCODE_EXTRA ExtraData; + LIST_ENTRY MapExpressionList; // nested expressions = inside of Map opcode. +} HII_EXPRESSION_OPCODE; + +#define HII_EXPRESSION_OPCODE_SIGNATURE SIGNATURE_32 ('E', 'X', 'O', 'P') +#define HII_EXPRESSION_OPCODE_FROM_LINK(a) CR (a, HII_EXPRESSION_OPCODE, = Link, HII_EXPRESSION_OPCODE_SIGNATURE) + +// +// Definition of HII_WARNING_IF_DATA +// +typedef struct { + EFI_STRING_ID WarningIfError; + UINT8 TimeOut; +} HII_WARNING_IF_DATA; + +// +// Definition of HII_EXTRA_DATA +// +typedef union { + UINT8 RuleId; // For EFI_IFR_RULE only + EFI_STRING_ID Error; // For EFI_IFR_NO_SUBMIT_IF, EFI_IFR= _INCONSISTENT_IF only + HII_WARNING_IF_DATA WarningIfData; +} HII_EXTRA_DATA; + +// +// Definition of HII_EXPRESSION +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + UINT8 Type; // Type for this expres= sion + EFI_IFR_OP_HEADER *OpCode; // Save the opcode buff= er. + LIST_ENTRY OpCodeListHead; // OpCodes consist of t= his expression (HII_EXPRESSION_OPCODE) + HII_DEPENDENCY_EXPRESSION *RootDependencyExp; // Expression OpCodes t= ree layout to describe dependency of this expression. + HII_EXTRA_DATA ExtraData; + EFI_HII_VALUE Result; // Expression evaluation result +} HII_EXPRESSION; + +#define HII_EXPRESSION_SIGNATURE SIGNATURE_32 ('F', 'E', 'X', 'P') +#define HII_EXPRESSION_FROM_LINK(a) CR (a, HII_EXPRESSION, Link, HII_EXPR= ESSION_SIGNATURE) + +// +// Definition of HII_EXPRESSION_LIST +// +typedef struct { + UINTN Signature; + UINTN Count; + HII_EXPRESSION *Expression[1]; // Array[Count] of expressions +} HII_EXPRESSION_LIST; + +#define HII_EXPRESSION_LIST_SIGNATURE SIGNATURE_32 ('F', 'E', 'X', 'R') + +// +// Definition of HII_STATEMENT_VALUE +// +typedef struct { + // + // HII Data Type + // + UINT8 Type; + EFI_IFR_TYPE_VALUE Value; + // + // Buffer Data and Length if Type is EFI_IFR_TYPE_BUFFER or EFI_IFR_TYPE= _STRING + // + UINT8 *Buffer; + UINT16 BufferLen; + UINT8 BufferValueType; // Data type for buffer internal = data, currently only for orderedlist +} HII_STATEMENT_VALUE; + +// +// Default value +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + UINT16 DefaultId; + HII_STATEMENT_VALUE Value; // Default value + + HII_EXPRESSION *ValueExpression; // Not-NULL indicates default v= alue is provided by EFI_IFR_VALUE +} HII_QUESTION_DEFAULT; + +#define HII_QUESTION_DEFAULT_SIGNATURE SIGNATURE_32 ('Q', 'D', 'F', 'T') +#define HII_QUESTION_DEFAULT_FROM_LINK(a) CR (a, HII_QUESTION_DEFAULT, Li= nk, HII_QUESTION_DEFAULT_SIGNATURE) + +#define HII_QUESTION_OPTION_SIGNATURE SIGNATURE_32 ('Q', 'O', 'P', 'T') + +// +// Option value +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + EFI_IFR_ONE_OF_OPTION *OpCode; // OneOfOption Data + + EFI_STRING_ID Text; + UINT8 Flags; + HII_STATEMENT_VALUE Value; + EFI_IMAGE_ID ImageId; + + HII_EXPRESSION_LIST *SuppressExpression; // Non-NULL indicates nest= ed inside of SuppressIf +} HII_QUESTION_OPTION; + +#define HII_QUESTION_OPTION_FROM_LINK(a) CR (a, HII_QUESTION_OPTION, Link= , HII_QUESTION_OPTION_SIGNATURE) + +// +// class of default +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + UINT16 DefaultId; + EFI_STRING_ID DefaultName; +} HII_FORMSET_DEFAULTSTORE; + +#define HII_FORMSET_DEFAULTSTORE_SIGNATURE SIGNATURE_32 ('F', 'D', 'F', '= S') +#define HII_FORMSET_DEFAULTSTORE_FROM_LINK(a) CR (a, HII_FORMSET_DEFAULTS= TORE, Link, HII_FORMSET_DEFAULTSTORE_SIGNATURE) + +// +// Definition of HII_STATEMENT_EXTRA +// +typedef union { + UINT8 Flags; + EFI_STRING_ID TextTwo; + EFI_DEFAULT_ID DefaultId; + EFI_STRING_ID QuestionConfig; + EFI_GUID Guid; + + struct { + UINT8 Flags; + UINT64 Minimum; // for EFI_IFR_ONE_OF/EFI_IFR_NUMERIC,= it's Min/Max value + UINT64 Maximum; // for EFI_IFR_STRING/EFI_IFR_PASSWORD= , it's Min/Max length + UINT64 Step; + EFI_GUID Guid; + } NumData; + + struct { + UINT8 Flags; + UINT8 MaxContainers; // for EFI_IFR_ORDERED_LIST + } OrderListData; + + struct { + UINT8 Flags; + UINT8 MinSize; + UINT8 MaxSize; + } StrData; + + struct { + UINT16 MinSize; + UINT16 MaxSize; + } PwdData; +} HII_STATEMENT_EXTRA; + +// +// Statement (Question) +// +typedef struct _HII_STATEMENT HII_STATEMENT; +struct _HII_STATEMENT { + UINTN Signature; + LIST_ENTRY Link; + + UINT8 Operand; // The operand (first byte) of t= his Statement or Question + EFI_IFR_OP_HEADER *OpCode; + + // + // Statement Header + // + EFI_STRING_ID Prompt; + EFI_STRING_ID Help; + + // + // Question Header + // + EFI_QUESTION_ID QuestionId; // Question id, the value of zer= o is reserved + EFI_VARSTORE_ID VarStoreId; // VarStore id, a value of zero = indicates no variable storage + HII_VAR_STORE_INFO VarStoreInfo; // VarStoreInfoIf VarStoreId ref= ers to Buffer Storage (EFI_IFR_VARSTORE or EFI_IFR_VARSTORE_EFI), then VarS= toreInfo contains a 16-bit Buffer Storage offset (VarOffset). + // If VarStoreId refers to Name/= Value Storage (EFI_IFR_VARSTORE_NAME_VALUE), then VarStoreInfo contains the= String ID of the name (VarName) for this name/value pair. + UINT8 QuestionFlags; // The flag of this Question.(Re= adonly, reset required, callback attribute....) + + BOOLEAN QuestionReferToBitField; // Whether the questio= n is stored in a bit field. + UINT16 StorageWidth; // The storage width o= f this Question. + UINT16 BitStorageWidth; // The Storage width o= f this Question in bit level. + UINT16 BitVarOffset; // The storage offset = of this Question in bit level. + CHAR16 *VariableName; // Name/Value or EFI V= ariable name + CHAR16 *BlockName; // Buffer storage bloc= k name: "OFFSET=3D...WIDTH=3D..." + + HII_FORMSET_STORAGE *Storage; // Point to the storag= e that store this question. + HII_STATEMENT_EXTRA ExtraData; + + BOOLEAN Locked; // Whether this statement is = locked. + + HII_STATEMENT_VALUE Value; + + // + // Get from IFR parsing + // + + HII_STATEMENT *ParentStatement; // Parent Statement of curren= t statement. + HII_EXPRESSION_LIST *ExpressionList; // nesting inside of GrayedOu= tIf/DisableIf/SuppressIf + HII_EXPRESSION *ValueExpression; // nested EFI_IFR_VALUE, prov= ide Question value and indicate Question is ReadOnly + + EFI_IMAGE_ID ImageId; // nested EFI_IFR_IMAGE + UINT8 RefreshInterval; // nested EFI_IFR_REFRESH, = refresh interval(in seconds) for Question value, 0 means no refresh + + LIST_ENTRY DefaultListHead; // nested EFI_IFR_DEFAULT l= ist (HII_QUESTION_DEFAULT), provide default values + LIST_ENTRY OptionListHead; // nested EFI_IFR_ONE_OF_OP= TION list (HII_QUESTION_OPTION) + LIST_ENTRY InconsistentListHead; // nested inconsistent expr= ession list (HII_EXPRESSION) + LIST_ENTRY NoSubmitListHead; // nested nosubmit expressi= on list (HII_EXPRESSION) + LIST_ENTRY WarningListHead; // nested warning expressio= n list (HII_EXPRESSION) + + HII_EXPRESSION *ReadExpression; // nested EFI_IFR_READ, pr= ovide this question value by read expression. + HII_EXPRESSION *WriteExpression; // nested EFI_IFR_WRITE, e= valuate write expression after this question value is set. +}; + +#define HII_STATEMENT_SIGNATURE SIGNATURE_32 ('H', 'S', 'T', 'A') +#define HII_STATEMENT_FROM_LINK(a) CR (a, HII_STATEMENT, Link, HII_STATEM= ENT_SIGNATURE) + +// +// Form +// +#define STANDARD_MAP_FORM_TYPE 0x01 + +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + UINT16 FormId; // FormId of normal form or f= ormmap form. + EFI_STRING_ID FormTitle; // FormTile of normal form, o= r FormMapMethod title of formmap form. + UINT16 FormType; // Specific form type for the= different form. + + EFI_IMAGE_ID ImageId; // The image id. + + BOOLEAN ModalForm; // Whether this is a modal fo= rm. + BOOLEAN Locked; // Whether this form is locke= d. + EFI_GUID RefreshGuid; // Form refresh event guid. + + LIST_ENTRY StatementListHead; // List of Statements and Qu= estions (HII_STATEMENT) + LIST_ENTRY ConfigRequestHead; // List of configrequest for= all storage. + LIST_ENTRY RuleListHead; // nested EFI_IFR_RULE list,= pre-defined expressions attached to the form. + HII_EXPRESSION_LIST *SuppressExpression; // nesting inside of Suppres= sIf +} HII_FORM; + +#define HII_FORM_SIGNATURE SIGNATURE_32 ('F', 'F', 'R', 'M') +#define HII_FORM_FROM_LINK(a) CR (a, HII_FORM, Link, HII_FORM_SIGNATURE) + +// +// FormSet +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + EFI_HII_HANDLE HiiHandle; // Unique id fo= r formset, HII Handle of this FormSet package. + EFI_HANDLE DriverHandle; // EFI_HANDLE w= hich was registered with the package list in NewPackageList(). + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; // ConfigAccess= Protocol associated with this HiiPackageList + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + UINTN IfrBinaryLength; // Ifr binary d= ata length of this formset. + UINT8 *IfrBinaryData; // Point to the= Ifr binary data. + + EFI_GUID Guid; // Formset Guid= . + EFI_STRING_ID FormSetTitle; // String Id of= Formset title. + EFI_STRING_ID Help; // String Id of= Formset title. + + UINT8 NumberOfClassGuid; // Class Guid n= ame + EFI_GUID ClassGuid[3]; // Up to three = ClassGuid + + EFI_IMAGE_ID ImageId; // The image id= . + + LIST_ENTRY StatementListOSF; // Statement li= st out side of the form. + LIST_ENTRY StorageListHead; // Storage list= (HII_FORMSET_STORAGE) + LIST_ENTRY DefaultStoreListHead; // DefaultStore= list (HII_FORMSET_DEFAULTSTORE) + LIST_ENTRY FormListHead; // Form list (H= II_FORM_BROWSER_FORM) +} HII_FORMSET; + +#define HII_FORMSET_SIGNATURE SIGNATURE_32 ('H', 'I', 'F', 'S') +#define HII_FORMSET_FROM_LINK(a) CR (a, HII_FORMSET, Link, HII_FORMSET_SI= GNATURE) + +// +// Get/set question value from/to. +// +typedef enum { + GetSetValueWithBuffer =3D 0, // Get/Set question value from/to buf= fer in the storage. + GetSetValueWithHiiDriver, // Get/Set question value from/to hii d= river. + GetSetValueWithBoth, // Compare the editbuffer with buffer f= or this question, not use the question value. + GetSetValueWithMax // Invalid value. +} GET_SET_QUESTION_VALUE_WITH; + +/** + Initialize the internal data structure of a FormSet. + + @param Handle PackageList Handle + @param FormSetGuid On input, GUID or class GUID of a formset= . If not + specified (NULL or zero GUID), take the f= irst + FormSet with class GUID EFI_HII_PLATFORM_= SETUP_FORMSET_GUID + found in package list. + On output, GUID of the formset found(if n= ot NULL). + @param FormSet FormSet data structure. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_FOUND The specified FormSet could not be found. + +**/ +EFI_STATUS +CreateFormSetFromHiiHandle ( + IN EFI_HII_HANDLE Handle, + IN OUT EFI_GUID *FormSetGuid, + OUT HII_FORMSET *FormSet + ); + +/** + Initialize a Formset and get current setting for Questions. + + @param FormSet FormSet data structure. + +**/ +VOID +InitializeFormSet ( + IN OUT HII_FORMSET *FormSet + ); + +/** + Free resources allocated for a FormSet. + + @param FormSet Pointer of the FormSet + +**/ +VOID +DestroyFormSet ( + IN OUT HII_FORMSET *FormSet + ); + +/** + Save Question Value to the memory, but not to storage. + + @param FormSet FormSet data structure. + @param Form Form data structure. + @param Question Pointer to the Question. + @param QuestionValue New Question Value to be set. + + @retval EFI_SUCCESS The question value has been set successfu= lly. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +EFI_STATUS +SetQuestionValue ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN OUT HII_STATEMENT *Question, + IN HII_STATEMENT_VALUE *QuestionValue + ); + +/** + Get Question's current Value from storage. + + @param FormSet FormSet data structure. + @param Form Form data structure. + @param Question Question to be initialized. + + @return the current Question Value in storage if success. + @return NULL if Question is not found or any error occurs. + +**/ +HII_STATEMENT_VALUE * +RetrieveQuestion ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN OUT HII_STATEMENT *Question + ); + +/** + Get Question's current Value. + + @param[in] FormSet FormSet data structure. + @param[in] Form Form data structure. + @param[out] Question Question to be initialized. + @param[in] GetValueFrom Where to get value, may from editbuf= fer, buffer or hii driver. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_INVALID_PARAMETER Formset, Form or Question is NULL. + +**/ +EFI_STATUS +GetQuestionValue ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN OUT HII_STATEMENT *Question, + IN GET_SET_QUESTION_VALUE_WITH GetValueFrom + ); + +/** + Submit data for a form. + + @param FormSet FormSet which contains the Form. + @param Form Form to submit. + + @retval EFI_SUCCESS The function completed successfully. + @retval Others Other errors occur. + +**/ +EFI_STATUS +SubmitForm ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form + ); + +/** + Evaluate the result of a HII expression. + + If Expression is NULL, then ASSERT. + + @param FormSet FormSet associated with this expression. + @param Form Form associated with this expression. + @param Expression Expression to be evaluated. + + @retval EFI_SUCCESS The expression evaluated successfully + @retval EFI_NOT_FOUND The Question which referenced by a Questi= onId + could not be found. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + @retval EFI_ACCESS_DENIED The pop operation underflowed the stack + @retval EFI_INVALID_PARAMETER Syntax error with the Expression + +**/ +EFI_STATUS +EvaluateHiiExpression ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN OUT HII_EXPRESSION *Expression + ); + +/** + Retrieve dependencies within an expression. These dependencies can expre= ss how + this expression will be evaluated. + + @param Expression Expression to retrieve dependencies. + + @retval EFI_SUCCESS The dependencies were successfully retrie= ved. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory. + +**/ +EFI_STATUS +GetHiiExpressionDependency ( + IN HII_EXPRESSION *Expression + ); + +/** + Get default value of question. + + @param[in] FormSet The form set. + @param[in] Form The form. + @param[in] Question The question. + @param[in] DefaultId The Class of the default. + @param[out] DefaultValue The default value of given question. + + @retval EFI_SUCCESS Question is reset to default value. + +**/ +EFI_STATUS +GetQuestionDefault ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN HII_STATEMENT *Question, + IN UINT16 DefaultId, + OUT HII_STATEMENT_VALUE *DefaultValue + ); + +/** + Return the result of the expression list. Check the expression list and + return the highest priority express result. + Priority: DisableIf > SuppressIf > GrayOutIf > FALSE + + @param[in] ExpList The input expression list. + @param[in] Evaluate Whether need to evaluate the expression firs= t. + @param[in] FormSet FormSet associated with this expression. + @param[in] Form Form associated with this expression. + + @retval EXPRESS_RESULT Return the higher priority express result. + DisableIf > SuppressIf > GrayOutIf > FALSE + +**/ +EXPRESS_RESULT +EvaluateExpressionList ( + IN HII_EXPRESSION_LIST *ExpList, + IN BOOLEAN Evaluate, + IN HII_FORMSET *FormSet, + OPTIONAL + IN HII_FORM *Form OPTIONAL + ); + +#endif // _HII_UTILITY_LIB_ diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h b/RedfishPkg/= Library/HiiUtilityLib/HiiExpression.h new file mode 100644 index 000000000000..1005e67220fb --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.h @@ -0,0 +1,214 @@ +/** @file + Definitions of Hii Expression. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef HII_EXPRESSION_H_ +#define HII_EXPRESSION_H_ + +#include + +/** + Get the expression list count. + + @param[in] Level Which type this expression belong to. For= m, + statement or option? + + @retval >=3D0 The expression count + @retval -1 Input parameter error. + +**/ +INTN +GetConditionalExpressionCount ( + IN EXPRESS_LEVEL Level + ); + +/** + Get the expression Buffer pointer. + + @param[in] Level Which type this expression belong to. For= m, + statement or option? + + @retval The start pointer of the expression buffer or NULL. + +**/ +HII_EXPRESSION ** +GetConditionalExpressionList ( + IN EXPRESS_LEVEL Level + ); + +/** + Push the expression options onto the Stack. + + @param[in] Pointer Pointer to the current expression. + @param[in] Level Which type this expression belong to. For= m, + statement or option? + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushConditionalExpression ( + IN HII_EXPRESSION *Pointer, + IN EXPRESS_LEVEL Level + ); + +/** + Pop the expression options from the Stack + + @param[in] Level Which type this expression belong to. For= m, + statement or option? + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopConditionalExpression ( + IN EXPRESS_LEVEL Level + ); + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetCurrentExpressionStack ( + VOID + ); + +/** + Push current expression onto the Stack + + @param[in] Pointer Pointer to current expression. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushCurrentExpression ( + IN VOID *Pointer + ); + +/** + Pop current expression from the Stack + + @param[in] Pointer Pointer to current expression to be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopCurrentExpression ( + OUT VOID **Pointer + ); + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetMapExpressionListStack ( + VOID + ); + +/** + Push the list of map expression onto the Stack + + @param[in] Pointer Pointer to the list of map expression to = be pushed. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushMapExpressionList ( + IN VOID *Pointer + ); + +/** + Pop the list of map expression from the Stack + + @param[in] Pointer Pointer to the list of map expression to = be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopMapExpressionList ( + OUT VOID **Pointer + ); + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetScopeStack ( + VOID + ); + +/** + Push an Operand onto the Stack + + @param[in] Operand Operand to push. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + +**/ +EFI_STATUS +PushScope ( + IN UINT8 Operand + ); + +/** + Pop an Operand from the Stack + + @param[out] Operand Operand to pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + +**/ +EFI_STATUS +PopScope ( + OUT UINT8 *Operand + ); + +/** + Return the result of the expression list. Check the expression list and + return the highest priority express result. + Priority: DisableIf > SuppressIf > GrayOutIf > FALSE + + @param[in] ExpList The input expression list. + @param[in] Evaluate Whether need to evaluate the expression firs= t. + @param[in] FormSet FormSet associated with this expression. + @param[in] Form Form associated with this expression. + + @retval EXPRESS_RESULT Return the higher priority express result. + DisableIf > SuppressIf > GrayOutIf > FALSE + +**/ +EXPRESS_RESULT +EvaluateExpressionList ( + IN HII_EXPRESSION_LIST *ExpList, + IN BOOLEAN Evaluate, + IN HII_FORMSET *FormSet, + OPTIONAL + IN HII_FORM *Form OPTIONAL + ); + +#endif diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiInternal.h b/RedfishPkg/Li= brary/HiiUtilityLib/HiiInternal.h new file mode 100644 index 000000000000..b001502b34fa --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiInternal.h @@ -0,0 +1,369 @@ +/** @file + HII internal header file. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved= . + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef HII_INTERNAL_H_ +#define HII_INTERNAL_H_ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "HiiExpression.h" +#include + +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + CHAR16 *ConfigRequest; // =3D + + CHAR16 *ConfigAltResp; // Alt config response string for= this ConfigRequest. + UINTN ElementCount; // Number of in = the + UINTN SpareStrLen; + CHAR16 *RestoreConfigRequest; // When submit form fail, = the element need to be restored + CHAR16 *SyncConfigRequest; // When submit form fail, = the element need to be synced + + HII_FORMSET_STORAGE *Storage; +} HII_FORM_CONFIG_REQUEST; + +#define HII_FORM_CONFIG_REQUEST_SIGNATURE SIGNATURE_32 ('F', 'C', 'R', 'S= ') +#define HII_FORM_CONFIG_REQUEST_FROM_LINK(a) CR (a, HII_FORM_CONFIG_REQUE= ST, Link, HII_FORM_CONFIG_REQUEST_SIGNATURE) + +// Incremental string length of ConfigRequest +// +#define CONFIG_REQUEST_STRING_INCREMENTAL 1024 + +/** + Allocate new memory and then copy the Unicode string Source to Destinati= on. + + @param Dest Location to copy string + @param Src String to copy + +**/ +VOID +NewStringCpy ( + IN OUT CHAR16 **Dest, + IN CHAR16 *Src + ); + +/** + Set Value of given Name in a NameValue Storage. + + @param Storage The NameValue Storage. + @param Name The Name. + @param Value The Value to set. + @param ReturnNode The node use the input name. + + @retval EFI_SUCCESS Value found for given Name. + @retval EFI_NOT_FOUND No such Name found in NameValue storage. + +**/ +EFI_STATUS +SetValueByName ( + IN HII_FORMSET_STORAGE *Storage, + IN CHAR16 *Name, + IN CHAR16 *Value, + OUT HII_NAME_VALUE_NODE **ReturnNode + ); + +/** + Get bit field value from the buffer and then set the value for the quest= ion. + Note: Data type UINT32 can cover all the bit field value. + + @param Question The question refer to bit field. + @param Buffer Point to the buffer which the question value get= from. + @param QuestionValue The Question Value retrieved from Bits. + +**/ +VOID +GetBitsQuestionValue ( + IN HII_STATEMENT *Question, + IN UINT8 *Buffer, + OUT HII_STATEMENT_VALUE *QuestionValue + ); + +/** + Set bit field value to the buffer. + Note: Data type UINT32 can cover all the bit field value. + + @param Question The question refer to bit field. + @param Buffer Point to the buffer which the question value set= to. + @param Value The bit field value need to set. + +**/ +VOID +SetBitsQuestionValue ( + IN HII_STATEMENT *Question, + IN OUT UINT8 *Buffer, + IN UINT32 Value + ); + +/** + Convert the buffer value to HiiValue. + + @param Question The question. + @param Value Unicode buffer save the question value. + @param QuestionValue The Question Value retrieved from Buffer. + + @retval Status whether convert the value success. + +**/ +EFI_STATUS +BufferToValue ( + IN HII_STATEMENT *Question, + IN CHAR16 *Value, + OUT HII_STATEMENT_VALUE *QuestionValue + ); + +/** + Get the string based on the StringId and HII Package List Handle. + + @param Token The String's ID. + @param HiiHandle The package list in the HII database to s= earch for + the specified string. + + @return The output string. + +**/ +CHAR16 * +GetToken ( + IN EFI_STRING_ID Token, + IN EFI_HII_HANDLE HiiHandle + ); + +/** + 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 + ); + +/** + Evaluate if the result is a non-zero value. + + @param Result The result to be evaluated. + + @retval TRUE It is a non-zero value. + @retval FALSE It is a zero value. + +**/ +BOOLEAN +IsTrue ( + IN EFI_HII_VALUE *Result + ); + +/** + Set a new string to string package. + + @param[in] String A pointer to the Null-terminated Unicode= string + to add or update in the String Package a= ssociated + with HiiHandle. + @param[in] HiiHandle A handle that was previously registered = in the + HII Database. + + @return the Id for this new string. + +**/ +EFI_STRING_ID +NewString ( + IN CHAR16 *String, + IN EFI_HII_HANDLE HiiHandle + ); + +/** + Perform nosubmitif check for a Form. + + @param FormSet FormSet data structure. + @param Form Form data structure. + @param Question The Question to be validated. + + @retval EFI_SUCCESS Form validation pass. + @retval other Form validation failed. + +**/ +EFI_STATUS +ValidateNoSubmit ( + IN HII_FORMSET *FormSet, + IN HII_FORM *Form, + IN HII_STATEMENT *Question + ); + +/** + Perform NoSubmit check for each Form in FormSet. + + @param FormSet FormSet data structure. + @param CurrentForm Current input form data structure. + @param Statement The statement for this check. + + @retval EFI_SUCCESS Form validation pass. + @retval other Form validation failed. + +**/ +EFI_STATUS +NoSubmitCheck ( + IN HII_FORMSET *FormSet, + IN OUT HII_FORM **CurrentForm, + OUT HII_STATEMENT **Statement + ); + +/** + Convert setting of Buffer Storage or NameValue Storage to . + + @param Storage The Storage to be converted. + @param ConfigResp The returned . + @param ConfigRequest The ConfigRequest string. + + @retval EFI_SUCCESS Convert success. + @retval EFI_INVALID_PARAMETER Incorrect storage type. + +**/ +EFI_STATUS +StorageToConfigResp ( + IN HII_FORMSET_STORAGE *Storage, + IN CHAR16 **ConfigResp, + IN CHAR16 *ConfigRequest + ); + +/** + Convert to settings in Buffer Storage or NameValue Storage. + + @param Storage The Storage to receive the settings. + @param ConfigResp The to be converted. + + @retval EFI_SUCCESS Convert success. + @retval EFI_INVALID_PARAMETER Incorrect storage type. + +**/ +EFI_STATUS +ConfigRespToStorage ( + IN HII_FORMSET_STORAGE *Storage, + IN CHAR16 *ConfigResp + ); + +/** + Fetch the Ifr binary data of a FormSet. + + @param Handle PackageList Handle + @param FormSetGuid On input, GUID or class GUID of a formset= . If not + specified (NULL or zero GUID), take the f= irst + FormSet with class GUID EFI_HII_PLATFORM_= SETUP_FORMSET_GUID + found in package list. + On output, GUID of the formset found(if n= ot NULL). + @param BinaryLength The length of the FormSet IFR binary. + @param BinaryData The buffer designed to receive the FormSe= t. + + @retval EFI_SUCCESS Buffer filled with the requested FormSet. + BufferLength was updated. + @retval EFI_INVALID_PARAMETER The handle is unknown. + @retval EFI_NOT_FOUND A form or FormSet on the requested handle= cannot + be found with the requested FormId. + +**/ +EFI_STATUS +GetIfrBinaryData ( + IN EFI_HII_HANDLE Handle, + IN OUT EFI_GUID *FormSetGuid, + OUT UINTN *BinaryLength, + OUT UINT8 **BinaryData + ); + +/** + Fill storage with settings requested from Configuration Driver. + + @param FormSet FormSet data structure. + @param Storage Buffer Storage. + +**/ +VOID +LoadStorage ( + IN HII_FORMSET *FormSet, + IN HII_FORMSET_STORAGE *Storage + ); + +/** + Free resources of a Form. + + @param FormSet Pointer of the FormSet + @param Form Pointer of the Form. + +**/ +VOID +DestroyForm ( + IN HII_FORMSET *FormSet, + IN OUT HII_FORM *Form + ); + +/** + Get formset storage based on the input varstoreid info. + + @param FormSet Pointer of the current FormSet. + @param VarStoreId Varstore ID info. + + @return Pointer to a HII_FORMSET_STORAGE data structure. + +**/ +HII_FORMSET_STORAGE * +GetFstStgFromVarId ( + IN HII_FORMSET *FormSet, + IN EFI_VARSTORE_ID VarStoreId + ); + +/** + Zero extend integer/boolean/date/time to UINT64 for comparing. + + @param Value HII Value to be converted. + +**/ +VOID +ExtendValueToU64 ( + IN HII_STATEMENT_VALUE *Value + ); + +/** + Parse opcodes in the formset IFR binary. + + @param FormSet Pointer of the FormSet data structure. + + @retval EFI_SUCCESS Opcode parse success. + @retval Other Opcode parse fail. + +**/ +EFI_STATUS +ParseOpCodes ( + IN HII_FORMSET *FormSet + ); + +#endif // _HII_INTERNAL_H_ diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c b/RedfishPkg/= Library/HiiUtilityLib/HiiExpression.c new file mode 100644 index 000000000000..759ef3bb1836 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c @@ -0,0 +1,1442 @@ +/** @file + The implementation of HII expression. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights res= erved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "HiiInternal.h" + +// +// Global stack used to evaluate boolean expressions +// +EFI_HII_VALUE *mOpCodeScopeStack =3D NULL; +EFI_HII_VALUE *mOpCodeScopeStackEnd =3D NULL; +EFI_HII_VALUE *mOpCodeScopeStackPointer =3D NULL; + +// +// Stack used for Suppressif/grayoutif/disableif expression list. +// +HII_EXPRESSION **mFormExpressionStack =3D NULL; +HII_EXPRESSION **mFormExpressionEnd =3D NULL; +HII_EXPRESSION **mFormExpressionPointer =3D NULL; + +HII_EXPRESSION **mStatementExpressionStack =3D NULL; +HII_EXPRESSION **mStatementExpressionEnd =3D NULL; +HII_EXPRESSION **mStatementExpressionPointer =3D NULL; + +HII_EXPRESSION **mOptionExpressionStack =3D NULL; +HII_EXPRESSION **mOptionExpressionEnd =3D NULL; +HII_EXPRESSION **mOptionExpressionPointer =3D NULL; + +// +// Stack used for the sub expresion in map expression. +// +EFI_HII_VALUE *mCurrentExpressionStack =3D NULL; +EFI_HII_VALUE *mCurrentExpressionEnd =3D NULL; +EFI_HII_VALUE *mCurrentExpressionPointer =3D NULL; + +// +// Stack used for the map expression list. +// +EFI_HII_VALUE *mMapExpressionListStack =3D NULL; +EFI_HII_VALUE *mMapExpressionListEnd =3D NULL; +EFI_HII_VALUE *mMapExpressionListPointer =3D NULL; + +// +// Stack used for dependency expression. +// +HII_DEPENDENCY_EXPRESSION **mExpressionDependencyStack =3D NULL; +HII_DEPENDENCY_EXPRESSION **mExpressionDependencyEnd =3D NULL; +HII_DEPENDENCY_EXPRESSION **mExpressionDependencyPointer =3D NULL; + +#define EXPRESSION_STACK_SIZE_INCREMENT 0x100 + +/** + Grow size of the stack. + + This is an internal function. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + + @retval EFI_SUCCESS Grow stack success. + @retval EFI_OUT_OF_RESOURCES No enough memory for stack space. + +**/ +EFI_STATUS +GrowStack ( + IN OUT EFI_HII_VALUE **Stack, + IN OUT EFI_HII_VALUE **StackPtr, + IN OUT EFI_HII_VALUE **StackEnd + ) +{ + UINTN Size; + EFI_HII_VALUE *NewStack; + + Size =3D EXPRESSION_STACK_SIZE_INCREMENT; + if (*StackPtr !=3D NULL) { + Size =3D Size + (*StackEnd - *Stack); + } + + NewStack =3D AllocatePool (Size * sizeof (EFI_HII_VALUE)); + if (NewStack =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (*StackPtr !=3D NULL) { + // + // Copy from Old Stack to the New Stack + // + CopyMem ( + NewStack, + *Stack, + (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE) + ); + + // + // Free The Old Stack + // + FreePool (*Stack); + } + + // + // Make the Stack pointer point to the old data in the new stack + // + *StackPtr =3D NewStack + (*StackPtr - *Stack); + *Stack =3D NewStack; + *StackEnd =3D NewStack + Size; + + return EFI_SUCCESS; +} + +/** + Push an element onto the Boolean Stack. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + @param Data Data to push. + + @retval EFI_SUCCESS Push stack success. + +**/ +EFI_STATUS +PushStack ( + IN OUT EFI_HII_VALUE **Stack, + IN OUT EFI_HII_VALUE **StackPtr, + IN OUT EFI_HII_VALUE **StackEnd, + IN EFI_HII_VALUE *Data + ) +{ + EFI_STATUS Status; + + // + // Check for a stack overflow condition + // + if (*StackPtr >=3D *StackEnd) { + // + // Grow the stack + // + Status =3D GrowStack (Stack, StackPtr, StackEnd); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Push the item onto the stack + // + CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE)); + if (Data->Type =3D=3D EFI_IFR_TYPE_BUFFER) { + (*StackPtr)->Buffer =3D AllocateCopyPool (Data->BufferLen, Data->Buffe= r); + if ((*StackPtr)->Buffer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + *StackPtr =3D *StackPtr + 1; + + return EFI_SUCCESS; +} + +/** + Pop an element from the stack. + + @param Stack On input: old stack + @param StackPtr On input: old stack pointer; On output: n= ew stack pointer + @param Data Data to pop. + + @retval EFI_SUCCESS The value was popped onto the stack. + @retval EFI_ACCESS_DENIED The pop operation underflowed the stack + +**/ +EFI_STATUS +PopStack ( + IN EFI_HII_VALUE *Stack, + IN OUT EFI_HII_VALUE **StackPtr, + OUT EFI_HII_VALUE *Data + ) +{ + // + // Check for a stack underflow condition + // + if (*StackPtr =3D=3D Stack) { + return EFI_ACCESS_DENIED; + } + + // + // Pop the item off the stack + // + *StackPtr =3D *StackPtr - 1; + CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE)); + return EFI_SUCCESS; +} + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetCurrentExpressionStack ( + VOID + ) +{ + mCurrentExpressionPointer =3D mCurrentExpressionStack; + mFormExpressionPointer =3D mFormExpressionStack; + mStatementExpressionPointer =3D mStatementExpressionStack; + mOptionExpressionPointer =3D mOptionExpressionStack; +} + +/** + Push current expression onto the Stack + + @param Pointer Pointer to current expression. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushCurrentExpression ( + IN VOID *Pointer + ) +{ + EFI_HII_VALUE Data; + + Data.Type =3D EFI_IFR_TYPE_NUM_SIZE_64; + Data.Value.u64 =3D (UINT64)(UINTN)Pointer; + + return PushStack ( + &mCurrentExpressionStack, + &mCurrentExpressionPointer, + &mCurrentExpressionEnd, + &Data + ); +} + +/** + Pop current expression from the Stack + + @param Pointer Pointer to current expression to be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopCurrentExpression ( + OUT VOID **Pointer + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Data; + + Status =3D PopStack ( + mCurrentExpressionStack, + &mCurrentExpressionPointer, + &Data + ); + + *Pointer =3D (VOID *)(UINTN)Data.Value.u64; + + return Status; +} + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetMapExpressionListStack ( + VOID + ) +{ + mMapExpressionListPointer =3D mMapExpressionListStack; +} + +/** + Grow size of the stack. + + This is an internal function. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + @param MemberSize The stack member size. + + @retval EFI_SUCCESS Grow stack success. + @retval EFI_OUT_OF_RESOURCES No enough memory for stack space. + +**/ +EFI_STATUS +GrowConditionalStack ( + IN OUT HII_EXPRESSION ***Stack, + IN OUT HII_EXPRESSION ***StackPtr, + IN OUT HII_EXPRESSION ***StackEnd, + IN UINTN MemberSize + ) +{ + UINTN Size; + HII_EXPRESSION **NewStack; + + Size =3D EXPRESSION_STACK_SIZE_INCREMENT; + if (*StackPtr !=3D NULL) { + Size =3D Size + (*StackEnd - *Stack); + } + + NewStack =3D AllocatePool (Size * MemberSize); + if (NewStack =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (*StackPtr !=3D NULL) { + // + // Copy from Old Stack to the New Stack + // + CopyMem ( + NewStack, + *Stack, + (*StackEnd - *Stack) * MemberSize + ); + + // + // Free The Old Stack + // + FreePool (*Stack); + } + + // + // Make the Stack pointer point to the old data in the new stack + // + *StackPtr =3D NewStack + (*StackPtr - *Stack); + *Stack =3D NewStack; + *StackEnd =3D NewStack + Size; + + return EFI_SUCCESS; +} + +/** + Push an element onto the Stack. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + @param Data Data to push. + + @retval EFI_SUCCESS Push stack success. + +**/ +EFI_STATUS +PushConditionalStack ( + IN OUT HII_EXPRESSION ***Stack, + IN OUT HII_EXPRESSION ***StackPtr, + IN OUT HII_EXPRESSION ***StackEnd, + IN HII_EXPRESSION **Data + ) +{ + EFI_STATUS Status; + + // + // Check for a stack overflow condition + // + if (*StackPtr >=3D *StackEnd) { + // + // Grow the stack + // + Status =3D GrowConditionalStack (Stack, StackPtr, StackEnd, sizeof (HI= I_EXPRESSION *)); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Push the item onto the stack + // + CopyMem (*StackPtr, Data, sizeof (HII_EXPRESSION *)); + *StackPtr =3D *StackPtr + 1; + + return EFI_SUCCESS; +} + +/** + Pop an element from the stack. + + @param Stack On input: old stack + @param StackPtr On input: old stack pointer; On output: n= ew stack pointer + @param Data Data to pop. + + @retval EFI_SUCCESS The value was popped onto the stack. + @retval EFI_ACCESS_DENIED The pop operation underflowed the stack + +**/ +EFI_STATUS +PopConditionalStack ( + IN HII_EXPRESSION **Stack, + IN OUT HII_EXPRESSION ***StackPtr, + OUT HII_EXPRESSION **Data + ) +{ + // + // Check for a stack underflow condition + // + if (*StackPtr =3D=3D Stack) { + return EFI_ACCESS_DENIED; + } + + // + // Pop the item off the stack + // + *StackPtr =3D *StackPtr - 1; + CopyMem (Data, *StackPtr, sizeof (HII_EXPRESSION *)); + return EFI_SUCCESS; +} + +/** + Get the expression list count. + + @param Level Which type this expression belong to. For= m, + statement or option? + + @retval >=3D0 The expression count + @retval -1 Input parameter error. + +**/ +INTN +GetConditionalExpressionCount ( + IN EXPRESS_LEVEL Level + ) +{ + switch (Level) { + case ExpressForm: + return mFormExpressionPointer - mFormExpressionStack; + case ExpressStatement: + return mStatementExpressionPointer - mStatementExpressionStack; + case ExpressOption: + return mOptionExpressionPointer - mOptionExpressionStack; + default: + ASSERT (FALSE); + return -1; + } +} + +/** + Get the expression Buffer pointer. + + @param Level Which type this expression belong to. For= m, + statement or option? + + @retval The start pointer of the expression buffer or NULL. + +**/ +HII_EXPRESSION ** +GetConditionalExpressionList ( + IN EXPRESS_LEVEL Level + ) +{ + switch (Level) { + case ExpressForm: + return mFormExpressionStack; + case ExpressStatement: + return mStatementExpressionStack; + case ExpressOption: + return mOptionExpressionStack; + default: + ASSERT (FALSE); + return NULL; + } +} + +/** + Push the expression options onto the Stack. + + @param Pointer Pointer to the current expression. + @param Level Which type this expression belong to. For= m, + statement or option? + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushConditionalExpression ( + IN HII_EXPRESSION *Pointer, + IN EXPRESS_LEVEL Level + ) +{ + switch (Level) { + case ExpressForm: + return PushConditionalStack ( + &mFormExpressionStack, + &mFormExpressionPointer, + &mFormExpressionEnd, + &Pointer + ); + case ExpressStatement: + return PushConditionalStack ( + &mStatementExpressionStack, + &mStatementExpressionPointer, + &mStatementExpressionEnd, + &Pointer + ); + case ExpressOption: + return PushConditionalStack ( + &mOptionExpressionStack, + &mOptionExpressionPointer, + &mOptionExpressionEnd, + &Pointer + ); + default: + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } +} + +/** + Pop the expression options from the Stack + + @param Level Which type this expression belong to. For= m, + statement or option? + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopConditionalExpression ( + IN EXPRESS_LEVEL Level + ) +{ + HII_EXPRESSION *Pointer; + + switch (Level) { + case ExpressForm: + return PopConditionalStack ( + mFormExpressionStack, + &mFormExpressionPointer, + &Pointer + ); + + case ExpressStatement: + return PopConditionalStack ( + mStatementExpressionStack, + &mStatementExpressionPointer, + &Pointer + ); + + case ExpressOption: + return PopConditionalStack ( + mOptionExpressionStack, + &mOptionExpressionPointer, + &Pointer + ); + + default: + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } +} + +/** + Push the list of map expression onto the Stack + + @param Pointer Pointer to the list of map expression to = be pushed. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushMapExpressionList ( + IN VOID *Pointer + ) +{ + EFI_HII_VALUE Data; + + Data.Type =3D EFI_IFR_TYPE_NUM_SIZE_64; + Data.Value.u64 =3D (UINT64)(UINTN)Pointer; + + return PushStack ( + &mMapExpressionListStack, + &mMapExpressionListPointer, + &mMapExpressionListEnd, + &Data + ); +} + +/** + Pop the list of map expression from the Stack + + @param Pointer Pointer to the list of map expression to = be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopMapExpressionList ( + OUT VOID **Pointer + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Data; + + Status =3D PopStack ( + mMapExpressionListStack, + &mMapExpressionListPointer, + &Data + ); + + *Pointer =3D (VOID *)(UINTN)Data.Value.u64; + + return Status; +} + +/** + Reset stack pointer to begin of the stack. + +**/ +VOID +ResetScopeStack ( + VOID + ) +{ + mOpCodeScopeStackPointer =3D mOpCodeScopeStack; +} + +/** + Push an Operand onto the Stack + + @param Operand Operand to push. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + +**/ +EFI_STATUS +PushScope ( + IN UINT8 Operand + ) +{ + EFI_HII_VALUE Data; + + Data.Type =3D EFI_IFR_TYPE_NUM_SIZE_8; + Data.Value.u8 =3D Operand; + + return PushStack ( + &mOpCodeScopeStack, + &mOpCodeScopeStackPointer, + &mOpCodeScopeStackEnd, + &Data + ); +} + +/** + Pop an Operand from the Stack + + @param Operand Operand to pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the + stack. + +**/ +EFI_STATUS +PopScope ( + OUT UINT8 *Operand + ) +{ + EFI_STATUS Status; + EFI_HII_VALUE Data; + + Status =3D PopStack ( + mOpCodeScopeStack, + &mOpCodeScopeStackPointer, + &Data + ); + + *Operand =3D Data.Value.u8; + + return Status; +} + +/** + Grow size of the stack for Expression Dependencies. + + This is an internal function. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + + @retval EFI_SUCCESS Grow Dependency stack success. + @retval EFI_OUT_OF_RESOURCES No enough memory for stack space. + +**/ +EFI_STATUS +GrowDependencyStack ( + IN OUT HII_DEPENDENCY_EXPRESSION ***Stack, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackEnd + ) +{ + UINTN Size; + HII_DEPENDENCY_EXPRESSION **NewStack; + + Size =3D EXPRESSION_STACK_SIZE_INCREMENT; + if (*StackPtr !=3D NULL) { + Size =3D Size + (*StackEnd - *Stack); + } + + NewStack =3D AllocatePool (Size * sizeof (HII_DEPENDENCY_EXPRESSION *)); + if (NewStack =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (*StackPtr !=3D NULL) { + // + // Copy from Old Stack to the New Stack + // + CopyMem ( + NewStack, + *Stack, + (*StackEnd - *Stack) * sizeof (HII_DEPENDENCY_EXPRESSION *) + ); + + // + // Free The Old Stack + // + FreePool (*Stack); + } + + // + // Make the Stack pointer point to the old data in the new stack + // + *StackPtr =3D NewStack + (*StackPtr - *Stack); + *Stack =3D NewStack; + *StackEnd =3D NewStack + Size; + + return EFI_SUCCESS; +} + +/** + Push an element onto the Stack for Expression Dependencies. + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param StackEnd On input: old stack end; On output: new s= tack end + @param Data Data to push. + + @retval EFI_SUCCESS Push stack success. + +**/ +EFI_STATUS +PushDependencyStack ( + IN OUT HII_DEPENDENCY_EXPRESSION ***Stack, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackEnd, + IN HII_DEPENDENCY_EXPRESSION **Data + ) +{ + EFI_STATUS Status; + + // + // Check for a stack overflow condition + // + if (*StackPtr >=3D *StackEnd) { + // + // Grow the stack + // + Status =3D GrowDependencyStack (Stack, StackPtr, StackEnd); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Push the item onto the stack + // + CopyMem (*StackPtr, Data, sizeof (HII_DEPENDENCY_EXPRESSION *)); + *StackPtr =3D *StackPtr + 1; + + return EFI_SUCCESS; +} + +/** + Pop the Expression Dependency options from the Stack + + @param Stack On input: old stack; On output: new stack + @param StackPtr On input: old stack pointer; On output: n= ew stack + pointer + @param Data Data to push. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopDependencyStack ( + IN HII_DEPENDENCY_EXPRESSION **Stack, + IN OUT HII_DEPENDENCY_EXPRESSION ***StackPtr, + OUT HII_DEPENDENCY_EXPRESSION **Data + ) +{ + // + // Check for a stack underflow condition + // + if (*StackPtr =3D=3D Stack) { + return EFI_ACCESS_DENIED; + } + + // + // Pop the item off the stack + // + *StackPtr =3D *StackPtr - 1; + CopyMem (Data, *StackPtr, sizeof (HII_DEPENDENCY_EXPRESSION *)); + return EFI_SUCCESS; +} + +/** + Push the list of Expression Dependencies onto the Stack + + @param Pointer Pointer to the list of map expression to = be pushed. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PushDependencyExpDes ( + IN HII_DEPENDENCY_EXPRESSION **Pointer + ) +{ + return PushDependencyStack ( + &mExpressionDependencyStack, + &mExpressionDependencyPointer, + &mExpressionDependencyEnd, + Pointer + ); +} + +/** + Pop the list of Expression Dependencies from the Stack + + @param Pointer Pointer to the list of map expression to = be pop. + + @retval EFI_SUCCESS The value was pushed onto the stack. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow= the stack. + +**/ +EFI_STATUS +PopDependencyExpDes ( + OUT HII_DEPENDENCY_EXPRESSION **Pointer + ) +{ + return PopDependencyStack ( + mExpressionDependencyStack, + &mExpressionDependencyPointer, + Pointer + ); +} + +/** + Retrieve dependencies within an expression. These dependencies can expre= ss how + this expression will be evaluated. + + @param Expression Expression to retrieve dependencies. + + @retval EFI_SUCCESS The dependencies were successfully retrie= ved. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory. + +**/ +EFI_STATUS +GetHiiExpressionDependency ( + IN OUT HII_EXPRESSION *Expression + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Link; + HII_EXPRESSION_OPCODE *ExpressionOpCode; + HII_DEPENDENCY_EXPRESSION *DepExpressionOpCode; + LIST_ENTRY *SubExpressionLink; + HII_EXPRESSION *SubExpression; + UINT8 MapPairCount; + + Link =3D GetFirstNode (&Expression->OpCodeListHead); + while (!IsNull (&Expression->OpCodeListHead, Link)) { + ExpressionOpCode =3D HII_EXPRESSION_OPCODE_FROM_LINK (Link); + Link =3D GetNextNode (&Expression->OpCodeListHead, Link); + Status =3D EFI_SUCCESS; + + DepExpressionOpCode =3D (HII_DEPENDENCY_EXPRESSION *)AllocateZeroPool = (sizeof (HII_DEPENDENCY_EXPRESSION)); + if (DepExpressionOpCode =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + switch (ExpressionOpCode->Operand) { + // + // Constant + // + case EFI_IFR_FALSE_OP: + case EFI_IFR_ONE_OP: + case EFI_IFR_ONES_OP: + case EFI_IFR_TRUE_OP: + case EFI_IFR_UINT8_OP: + case EFI_IFR_UINT16_OP: + case EFI_IFR_UINT32_OP: + case EFI_IFR_UINT64_OP: + case EFI_IFR_UNDEFINED_OP: + case EFI_IFR_VERSION_OP: + case EFI_IFR_ZERO_OP: + DepExpressionOpCode->ConstantExp.Operand =3D ExpressionOpCode->Ope= rand; + CopyMem (&DepExpressionOpCode->ConstantExp.Value, &ExpressionOpCod= e->ExtraData.Value, sizeof (EFI_HII_VALUE)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // Built-in functions + // + case EFI_IFR_DUP_OP: + DepExpressionOpCode->DupExp.Operand =3D ExpressionOpCode->Operand; + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_EQ_ID_VAL_OP: + DepExpressionOpCode->EqIdValExp.Operand =3D ExpressionOpCode->Oper= and; + CopyMem (&DepExpressionOpCode->EqIdValExp.QuestionId, &ExpressionO= pCode->ExtraData.EqIdValData.QuestionId, sizeof (EFI_QUESTION_ID)); + CopyMem (&DepExpressionOpCode->EqIdValExp.Value, &ExpressionOpCode= ->ExtraData.EqIdValData.Value, sizeof (EFI_HII_VALUE)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_EQ_ID_ID_OP: + DepExpressionOpCode->EqIdIdExp.Operand =3D ExpressionOpCode->Opera= nd; + CopyMem (&DepExpressionOpCode->EqIdIdExp.QuestionId1, &ExpressionO= pCode->ExtraData.EqIdIdData.QuestionId1, sizeof (EFI_QUESTION_ID)); + CopyMem (&DepExpressionOpCode->EqIdIdExp.QuestionId2, &ExpressionO= pCode->ExtraData.EqIdIdData.QuestionId2, sizeof (EFI_QUESTION_ID)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_EQ_ID_VAL_LIST_OP: + DepExpressionOpCode->EqIdListExp.Operand =3D ExpressionOpCode->= Operand; + DepExpressionOpCode->EqIdListExp.ListLength =3D ExpressionOpCode->= ExtraData.EqIdListData.ListLength; + CopyMem (&DepExpressionOpCode->EqIdListExp.QuestionId, &Expression= OpCode->ExtraData.EqIdListData.QuestionId, sizeof (EFI_QUESTION_ID)); + PushDependencyExpDes (&DepExpressionOpCode); + DepExpressionOpCode->EqIdListExp.ValueList =3D AllocateCopyPool ( + DepExpressionOpCode= ->EqIdListExp.ListLength * sizeof (UINT16), + ExpressionOpCode->E= xtraData.EqIdListData.ValueList + ); + if (DepExpressionOpCode->EqIdListExp.ValueList =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_GET_OP: + DepExpressionOpCode->GetExp.Operand =3D ExpressionOpCode->Opera= nd; + DepExpressionOpCode->GetExp.VarStorage =3D ExpressionOpCode->Extra= Data.GetSetData.VarStorage; + CopyMem (&DepExpressionOpCode->GetExp.VarStoreInfo.VarName, &Expre= ssionOpCode->ExtraData.GetSetData.VarStoreInfo.VarName, sizeof (EFI_STRING_= ID)); + CopyMem (&DepExpressionOpCode->GetExp.VarStoreInfo.VarOffset, &Exp= ressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, sizeof (UINT16)= ); + DepExpressionOpCode->GetExp.VarStoreInfo =3D ExpressionOpCode->Ext= raData.GetSetData.VarStoreInfo; + if (ExpressionOpCode->ExtraData.GetSetData.ValueName !=3D NULL) { + DepExpressionOpCode->GetExp.ValueName =3D (CHAR16 *)AllocateCopy= Pool (sizeof (ExpressionOpCode->ExtraData.GetSetData.ValueName), Expression= OpCode->ExtraData.GetSetData.ValueName); + if (DepExpressionOpCode->GetExp.ValueName =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + DepExpressionOpCode->GetExp.ValueType =3D ExpressionOpCode->Extra= Data.GetSetData.ValueType; + DepExpressionOpCode->GetExp.ValueWidth =3D ExpressionOpCode->Extra= Data.GetSetData.ValueWidth; + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_QUESTION_REF1_OP: + DepExpressionOpCode->QuestionRef1Exp.Operand =3D ExpressionOpCode-= >Operand; + CopyMem (&DepExpressionOpCode->QuestionRef1Exp.QuestionId, &Expres= sionOpCode->ExtraData.QuestionRef1Data.QuestionId, sizeof (EFI_QUESTION_ID)= ); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_RULE_REF_OP: + DepExpressionOpCode->RuleRefExp.Operand =3D ExpressionOpCode->Oper= and; + DepExpressionOpCode->RuleRefExp.RuleId =3D ExpressionOpCode->Extr= aData.RuleId; + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_STRING_REF1_OP: + DepExpressionOpCode->StringRef1Exp.Operand =3D ExpressionOpCode->O= perand; + CopyMem (&DepExpressionOpCode->StringRef1Exp.Value.Value.string, &= ExpressionOpCode->ExtraData.Value.Value.string, sizeof (EFI_STRING_ID)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_THIS_OP: + DepExpressionOpCode->ThisExp.Operand =3D ExpressionOpCode->Operand= ; + CopyMem (&DepExpressionOpCode->ThisExp.QuestionId, &ExpressionOpCo= de->ExtraData.QuestionRef1Data.QuestionId, sizeof (EFI_QUESTION_ID)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SECURITY_OP: + DepExpressionOpCode->SecurityExp.Operand =3D ExpressionOpCode->Ope= rand; + CopyMem (&DepExpressionOpCode->SecurityExp.Permissions, &Expressio= nOpCode->ExtraData.Guid, sizeof (EFI_GUID)); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // unary-op + // + case EFI_IFR_LENGTH_OP: + DepExpressionOpCode->LengthExp.Operand =3D ExpressionOpCode->Opera= nd; + PopDependencyExpDes (&DepExpressionOpCode->LengthExp.SubExpression= ); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_NOT_OP: + DepExpressionOpCode->NotExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->NotExp.SubExpression); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_BITWISE_NOT_OP: + DepExpressionOpCode->BitWiseNotExp.Operand =3D ExpressionOpCode->O= perand; + PopDependencyExpDes (&DepExpressionOpCode->BitWiseNotExp.SubExpres= sion); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_QUESTION_REF2_OP: + DepExpressionOpCode->QuestionRef2Exp.Operand =3D ExpressionOpCode-= >Operand; + PopDependencyExpDes (&DepExpressionOpCode->QuestionRef2Exp.SubExpr= ession); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_QUESTION_REF3_OP: + DepExpressionOpCode->QuestionRef3Exp.Operand =3D ExpressionOpCode-= >Operand; + CopyMem (&DepExpressionOpCode->QuestionRef3Exp.DevicePath, &Expres= sionOpCode->ExtraData.QuestionRef3Data.DevicePath, sizeof (EFI_DEVICE_PATH)= ); + CopyMem (&DepExpressionOpCode->QuestionRef3Exp.Guid, &ExpressionOp= Code->ExtraData.QuestionRef3Data.Guid, sizeof (EFI_GUID)); + PopDependencyExpDes (&DepExpressionOpCode->QuestionRef3Exp.SubExpr= ession); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SET_OP: + DepExpressionOpCode->SetExp.Operand =3D ExpressionOpCode->Opera= nd; + DepExpressionOpCode->SetExp.VarStorage =3D ExpressionOpCode->Extra= Data.GetSetData.VarStorage; + CopyMem (&DepExpressionOpCode->SetExp.VarStoreInfo.VarName, &Expre= ssionOpCode->ExtraData.GetSetData.VarStoreInfo.VarName, sizeof (EFI_STRING_= ID)); + CopyMem (&DepExpressionOpCode->SetExp.VarStoreInfo.VarOffset, &Exp= ressionOpCode->ExtraData.GetSetData.VarStoreInfo.VarOffset, sizeof (UINT16)= ); + DepExpressionOpCode->SetExp.VarStoreInfo =3D ExpressionOpCode->Ext= raData.GetSetData.VarStoreInfo; + if (ExpressionOpCode->ExtraData.GetSetData.ValueName !=3D NULL) { + DepExpressionOpCode->SetExp.ValueName =3D (CHAR16 *)AllocateCopy= Pool (sizeof (ExpressionOpCode->ExtraData.GetSetData.ValueName), Expression= OpCode->ExtraData.GetSetData.ValueName); + if (DepExpressionOpCode->SetExp.ValueName =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + + DepExpressionOpCode->SetExp.ValueType =3D ExpressionOpCode->Extra= Data.GetSetData.ValueType; + DepExpressionOpCode->SetExp.ValueWidth =3D ExpressionOpCode->Extra= Data.GetSetData.ValueWidth; + PopDependencyExpDes (&DepExpressionOpCode->SetExp.SubExpression); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_STRING_REF2_OP: + DepExpressionOpCode->StringRef2Exp.Operand =3D ExpressionOpCode->O= perand; + PopDependencyExpDes (&DepExpressionOpCode->StringRef2Exp.SubExpres= sion); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_BOOLEAN_OP: + DepExpressionOpCode->ToBooleanExp.Operand =3D ExpressionOpCode->Op= erand; + PopDependencyExpDes (&DepExpressionOpCode->ToBooleanExp.SubExpress= ion); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_STRING_OP: + DepExpressionOpCode->ToStringExp.Operand =3D ExpressionOpCode->Ope= rand; + DepExpressionOpCode->ToStringExp.Format =3D ExpressionOpCode->Ext= raData.Format; + PopDependencyExpDes (&DepExpressionOpCode->ToStringExp.SubExpressi= on); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_UINT_OP: + DepExpressionOpCode->ToUintExp.Operand =3D ExpressionOpCode->Opera= nd; + PopDependencyExpDes (&DepExpressionOpCode->ToUintExp.SubExpression= ); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_LOWER_OP: + DepExpressionOpCode->ToLowerExp.Operand =3D ExpressionOpCode->Oper= and; + PopDependencyExpDes (&DepExpressionOpCode->ToLowerExp.SubExpressio= n); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TO_UPPER_OP: + DepExpressionOpCode->ToUpperExp.Operand =3D ExpressionOpCode->Oper= and; + PopDependencyExpDes (&DepExpressionOpCode->ToUpperExp.SubExpressio= n); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // binary-op + // + case EFI_IFR_ADD_OP: + DepExpressionOpCode->AddExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->AddExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->AddExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_AND_OP: + DepExpressionOpCode->AndExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->AndExp.SubExpression1); + PopDependencyExpDes (&DepExpressionOpCode->AndExp.SubExpression2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_BITWISE_AND_OP: + DepExpressionOpCode->BitwiseAndExp.Operand =3D ExpressionOpCode->O= perand; + PopDependencyExpDes (&DepExpressionOpCode->BitwiseAndExp.SubExpres= sion1); + PopDependencyExpDes (&DepExpressionOpCode->BitwiseAndExp.SubExpres= sion2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_BITWISE_OR_OP: + DepExpressionOpCode->BitwiseOrExp.Operand =3D ExpressionOpCode->Op= erand; + PopDependencyExpDes (&DepExpressionOpCode->BitwiseOrExp.SubExpress= ion1); + PopDependencyExpDes (&DepExpressionOpCode->BitwiseOrExp.SubExpress= ion2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_CATENATE_OP: + DepExpressionOpCode->CatenateExp.Operand =3D ExpressionOpCode->Ope= rand; + PopDependencyExpDes (&DepExpressionOpCode->CatenateExp.LeftStringE= xp); + PopDependencyExpDes (&DepExpressionOpCode->CatenateExp.RightString= Exp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_DIVIDE_OP: + DepExpressionOpCode->DivExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->DivExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->DivExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_EQUAL_OP: + DepExpressionOpCode->EqualExp.Operand =3D ExpressionOpCode->Operan= d; + PopDependencyExpDes (&DepExpressionOpCode->EqualExp.SubExpression1= ); + PopDependencyExpDes (&DepExpressionOpCode->EqualExp.SubExpression2= ); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_GREATER_EQUAL_OP: + DepExpressionOpCode->GreaterEqualExp.Operand =3D ExpressionOpCode-= >Operand; + PopDependencyExpDes (&DepExpressionOpCode->GreaterEqualExp.LeftHan= dExp); + PopDependencyExpDes (&DepExpressionOpCode->GreaterEqualExp.RightHa= ndExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_GREATER_THAN_OP: + DepExpressionOpCode->GreaterThanExp.Operand =3D ExpressionOpCode->= Operand; + PopDependencyExpDes (&DepExpressionOpCode->GreaterThanExp.LeftHand= Exp); + PopDependencyExpDes (&DepExpressionOpCode->GreaterThanExp.RightHan= dExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_LESS_EQUAL_OP: + DepExpressionOpCode->LessEqualExp.Operand =3D ExpressionOpCode->Op= erand; + PopDependencyExpDes (&DepExpressionOpCode->LessEqualExp.LeftHandEx= p); + PopDependencyExpDes (&DepExpressionOpCode->LessEqualExp.RightHandE= xp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_LESS_THAN_OP: + DepExpressionOpCode->LessThanExp.Operand =3D ExpressionOpCode->Ope= rand; + PopDependencyExpDes (&DepExpressionOpCode->LessThanExp.LeftHandExp= ); + PopDependencyExpDes (&DepExpressionOpCode->LessThanExp.RightHandEx= p); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MATCH_OP: + DepExpressionOpCode->MatchExp.Operand =3D ExpressionOpCode->Operan= d; + PopDependencyExpDes (&DepExpressionOpCode->MatchExp.PatternExp); + PopDependencyExpDes (&DepExpressionOpCode->MatchExp.StringExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MATCH2_OP: + DepExpressionOpCode->Match2Exp.Operand =3D ExpressionOpCode->Opera= nd; + CopyMem (&DepExpressionOpCode->Match2Exp.SyntaxType, &ExpressionOp= Code->ExtraData.Guid, sizeof (EFI_GUID)); + PopDependencyExpDes (&DepExpressionOpCode->Match2Exp.PatternExp); + PopDependencyExpDes (&DepExpressionOpCode->Match2Exp.StringExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MODULO_OP: + DepExpressionOpCode->ModExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->ModExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->ModExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MULTIPLY_OP: + DepExpressionOpCode->MultExp.Operand =3D ExpressionOpCode->Operand= ; + PopDependencyExpDes (&DepExpressionOpCode->MultExp.LeftHandExp); + PopDependencyExpDes (&DepExpressionOpCode->MultExp.RightHandExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_NOT_EQUAL_OP: + DepExpressionOpCode->NotEqualExp.Operand =3D ExpressionOpCode->Ope= rand; + PopDependencyExpDes (&DepExpressionOpCode->NotEqualExp.SubExpressi= on1); + PopDependencyExpDes (&DepExpressionOpCode->NotEqualExp.SubExpressi= on2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_OR_OP: + DepExpressionOpCode->OrExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->OrExp.SubExpression1); + PopDependencyExpDes (&DepExpressionOpCode->OrExp.SubExpression2); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SHIFT_LEFT_OP: + DepExpressionOpCode->ShiftLeftExp.Operand =3D ExpressionOpCode->Op= erand; + PopDependencyExpDes (&DepExpressionOpCode->ShiftLeftExp.LeftHandEx= p); + PopDependencyExpDes (&DepExpressionOpCode->ShiftLeftExp.RightHandE= xp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SHIFT_RIGHT_OP: + DepExpressionOpCode->ShiftRightExp.Operand =3D ExpressionOpCode->O= perand; + PopDependencyExpDes (&DepExpressionOpCode->ShiftRightExp.LeftHandE= xp); + PopDependencyExpDes (&DepExpressionOpCode->ShiftRightExp.RightHand= Exp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SUBTRACT_OP: + DepExpressionOpCode->SubtractExp.Operand =3D ExpressionOpCode->Ope= rand; + PopDependencyExpDes (&DepExpressionOpCode->SubtractExp.LeftHandExp= ); + PopDependencyExpDes (&DepExpressionOpCode->SubtractExp.RightHandEx= p); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // ternary-op + // + case EFI_IFR_CONDITIONAL_OP: + DepExpressionOpCode->ConditionalExp.Operand =3D ExpressionOpCode->= Operand; + PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.CondTrue= ValExp); + PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.CondFals= eValExp); + PopDependencyExpDes (&DepExpressionOpCode->ConditionalExp.Conditio= nExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_FIND_OP: + DepExpressionOpCode->FindExp.Operand =3D ExpressionOpCode->Operand= ; + PopDependencyExpDes (&DepExpressionOpCode->FindExp.StringToSearchE= xp); + PopDependencyExpDes (&DepExpressionOpCode->FindExp.StringToCompWit= hExp); + PopDependencyExpDes (&DepExpressionOpCode->FindExp.IndexExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_MID_OP: + DepExpressionOpCode->MidExp.Operand =3D ExpressionOpCode->Operand; + PopDependencyExpDes (&DepExpressionOpCode->MidExp.StringOrBufferEx= p); + PopDependencyExpDes (&DepExpressionOpCode->MidExp.IndexExp); + PopDependencyExpDes (&DepExpressionOpCode->MidExp.LengthExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_TOKEN_OP: + DepExpressionOpCode->TokenExp.Operand =3D ExpressionOpCode->Operan= d; + PopDependencyExpDes (&DepExpressionOpCode->TokenExp.StringToSearch= Exp); + PopDependencyExpDes (&DepExpressionOpCode->TokenExp.DelimiterExp); + PopDependencyExpDes (&DepExpressionOpCode->TokenExp.IndexExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + case EFI_IFR_SPAN_OP: + DepExpressionOpCode->SpanExp.Operand =3D ExpressionOpCode->Operand= ; + PopDependencyExpDes (&DepExpressionOpCode->SpanExp.StringToSearchE= xp); + PopDependencyExpDes (&DepExpressionOpCode->SpanExp.CharsetExp); + PopDependencyExpDes (&DepExpressionOpCode->SpanExp.IndexExp); + PushDependencyExpDes (&DepExpressionOpCode); + break; + + // + // Map + // + case EFI_IFR_MAP_OP: + // + // Go through map expression list. + // + DepExpressionOpCode->MapExp.Operand =3D ExpressionOpCode->Operand; + MapPairCount =3D 0; + SubExpressionLink =3D GetFirstNode (&ExpressionO= pCode->MapExpressionList); + while (!IsNull (&ExpressionOpCode->MapExpressionList, SubExpressio= nLink)) { + MapPairCount++; + SubExpressionLink =3D GetNextNode (&ExpressionOpCode->MapExpress= ionList, SubExpressionLink); + if (IsNull (&ExpressionOpCode->MapExpressionList, SubExpressionL= ink)) { + Status =3D EFI_INVALID_PARAMETER; + goto Done; + } + + // + // Goto the first expression on next pair. + // + SubExpressionLink =3D GetNextNode (&ExpressionOpCode->MapExpress= ionList, SubExpressionLink); + } + + DepExpressionOpCode->MapExp.ExpPair =3D (HII_DEPENDENCY_EXPRESSION= _PAIR *)AllocateZeroPool ( + = MapPairCount * sizeof (HII_DEPENDENCY_EXPRESSION_PAIR) + = ); + if (DepExpressionOpCode->MapExp.ExpPair =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto Done; + } + + DepExpressionOpCode->MapExp.ExpPairNo =3D MapPairCount; + MapPairCount =3D 0; + PopDependencyExpDes (&DepExpressionOpCode->MapExp.SubExp); + + // + // Go through map expression list. + // + SubExpressionLink =3D GetFirstNode (&ExpressionOpCode->MapExpressi= onList); + while (!IsNull (&ExpressionOpCode->MapExpressionList, SubExpressio= nLink)) { + SubExpression =3D HII_EXPRESSION_FROM_LINK (SubExpressionLink); + // + // Get the first expression description in this pair. + // + GetHiiExpressionDependency (SubExpression); + DepExpressionOpCode->MapExp.ExpPair[MapPairCount].MatchExp =3D S= ubExpression->RootDependencyExp; + + // + // Get the second expression description in this pair. + // + SubExpressionLink =3D GetNextNode (&ExpressionOpCode->MapExpress= ionList, SubExpressionLink); + SubExpression =3D HII_EXPRESSION_FROM_LINK (SubExpressionLin= k); + GetHiiExpressionDependency (SubExpression); + DepExpressionOpCode->MapExp.ExpPair[MapPairCount].ReturnExp =3D = SubExpression->RootDependencyExp; + // + // Goto the first expression on next pair. + // + SubExpressionLink =3D GetNextNode (&ExpressionOpCode->MapExpress= ionList, SubExpressionLink); + MapPairCount++; + } + + PushDependencyExpDes (&DepExpressionOpCode); + break; + + default: + break; + } + } + + PopDependencyExpDes (&Expression->RootDependencyExp); + +Done: + return Status; +} + +/** + Return the result of the expression list. Check the expression list and + return the highest priority express result. + Priority: DisableIf > SuppressIf > GrayOutIf > FALSE + + @param[in] ExpList The input expression list. + @param[in] Evaluate Whether need to evaluate the expression firs= t. + @param[in] FormSet FormSet associated with this expression. + @param[in] Form Form associated with this expression. + + @retval EXPRESS_RESULT Return the higher priority express result. + DisableIf > SuppressIf > GrayOutIf > FALSE + +**/ +EXPRESS_RESULT +EvaluateExpressionList ( + IN HII_EXPRESSION_LIST *ExpList, + IN BOOLEAN Evaluate, + IN HII_FORMSET *FormSet, + OPTIONAL + IN HII_FORM *Form OPTIONAL + ) +{ + UINTN Index; + EXPRESS_RESULT ReturnVal; + EXPRESS_RESULT CompareOne; + EFI_STATUS Status; + + if (ExpList =3D=3D NULL) { + return ExpressFalse; + } + + ASSERT (ExpList->Signature =3D=3D HII_EXPRESSION_LIST_SIGNATURE); + Index =3D 0; + + // + // Check whether need to evaluate the expression first. + // + if (Evaluate) { + while (ExpList->Count > Index) { + Status =3D EvaluateHiiExpression (FormSet, Form, ExpList->Expression= [Index++]); + if (EFI_ERROR (Status)) { + return ExpressFalse; + } + } + } + + // + // Run the list of expressions. + // + ReturnVal =3D ExpressFalse; + for (Index =3D 0; Index < ExpList->Count; Index++) { + if (IsTrue (&ExpList->Expression[Index]->Result)) { + switch (ExpList->Expression[Index]->Type) { + case EFI_HII_EXPRESSION_SUPPRESS_IF: + CompareOne =3D ExpressSuppress; + break; + + case EFI_HII_EXPRESSION_GRAY_OUT_IF: + CompareOne =3D ExpressGrayOut; + break; + + case EFI_HII_EXPRESSION_DISABLE_IF: + CompareOne =3D ExpressDisable; + break; + + default: + return ExpressFalse; + } + + ReturnVal =3D ReturnVal < CompareOne ? CompareOne : ReturnVal; + } + } + + return ReturnVal; +} diff --git a/RedfishPkg/Library/HiiUtilityLib/HiiIfrParse.c b/RedfishPkg/Li= brary/HiiUtilityLib/HiiIfrParse.c new file mode 100644 index 000000000000..8459ad0822c9 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiIfrParse.c @@ -0,0 +1,2717 @@ +/** @file + The implementation of HII IFR parser. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved= . + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "HiiInternal.h" + +#define EFI_IFR_SPECIFICATION_VERSION (UINT16) (((EFI_SYSTEM_TABLE_REVISI= ON >> 16) << 8) | (((EFI_SYSTEM_TABLE_REVISION & 0xFFFF) / 10) << 4) | ((EF= I_SYSTEM_TABLE_REVISION & 0xFFFF) % 10)) + +/** + Initialize Statement header members. + + @param[in] OpCodeData Pointer of the raw OpCode data. + @param[in,out] FormSet Pointer of the current FormSet. + @param[in,out] Form Pointer of the current Form. + + @return The Statement. + +**/ +HII_STATEMENT * +CreateStatement ( + IN UINT8 *OpCodeData, + IN OUT HII_FORMSET *FormSet, + IN OUT HII_FORM *Form + ) +{ + HII_STATEMENT *Statement; + EFI_IFR_STATEMENT_HEADER *StatementHdr; + INTN ConditionalExprCount; + + if (Form =3D=3D NULL) { + // + // Only guid op may out side the form level. + // + if (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode !=3D EFI_IFR_GUID_OP) { + return NULL; + } + } + + Statement =3D (HII_STATEMENT *)AllocateZeroPool (sizeof (HII_STATEMENT))= ; + if (Statement =3D=3D NULL) { + return NULL; + } + + InitializeListHead (&Statement->DefaultListHead); + InitializeListHead (&Statement->OptionListHead); + InitializeListHead (&Statement->InconsistentListHead); + InitializeListHead (&Statement->NoSubmitListHead); + InitializeListHead (&Statement->WarningListHead); + + Statement->Signature =3D HII_STATEMENT_SIGNATURE; + Statement->Operand =3D ((EFI_IFR_OP_HEADER *)OpCodeData)= ->OpCode; + Statement->OpCode =3D (EFI_IFR_OP_HEADER *)OpCodeData; + Statement->QuestionReferToBitField =3D FALSE; + + StatementHdr =3D (EFI_IFR_STATEMENT_HEADER *)(OpCodeData + sizeof (EFI_I= FR_OP_HEADER)); + CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_I= D)); + CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID)); + + ConditionalExprCount =3D GetConditionalExpressionCount (ExpressStatement= ); + if (ConditionalExprCount > 0) { + // + // Form is inside of suppressif + // + Statement->ExpressionList =3D (HII_EXPRESSION_LIST *)AllocatePool ( + (UINTN)(sizeof (H= II_EXPRESSION_LIST) + ((ConditionalExprCount - 1) * sizeof (HII_EXPRESSION = *))) + ); + if (Statement->ExpressionList =3D=3D NULL) { + return NULL; + } + + Statement->ExpressionList->Count =3D (UINTN)ConditionalExprCount; + Statement->ExpressionList->Signature =3D HII_EXPRESSION_LIST_SIGNATURE= ; + CopyMem ( + Statement->ExpressionList->Expression, + GetConditionalExpressionList (ExpressStatement), + (UINTN)(sizeof (HII_EXPRESSION *) * ConditionalExprCount) + ); + } + + // + // Insert this Statement into current Form + // + if (Form =3D=3D NULL) { + InsertTailList (&FormSet->StatementListOSF, &Statement->Link); + } else { + InsertTailList (&Form->StatementListHead, &Statement->Link); + } + + return Statement; +} + +/** + Initialize Question's members. + + @param[in] OpCodeData Pointer of the raw OpCode data. + @param[in,out] FormSet Pointer of the current FormSet. + @param[in,out] Form Pointer of the current Form. + + @return The Question. + +**/ +HII_STATEMENT * +CreateQuestion ( + IN UINT8 *OpCodeData, + IN OUT HII_FORMSET *FormSet, + IN OUT HII_FORM *Form + ) +{ + HII_STATEMENT *Statement; + EFI_IFR_QUESTION_HEADER *QuestionHdr; + LIST_ENTRY *Link; + HII_FORMSET_STORAGE *Storage; + HII_NAME_VALUE_NODE *NameValueNode; + BOOLEAN Find; + + Statement =3D CreateStatement (OpCodeData, FormSet, Form); + if (Statement =3D=3D NULL) { + return NULL; + } + + QuestionHdr =3D (EFI_IFR_QUESTION_HEADER *)(OpCodeData + sizeof (EFI_IFR= _OP_HEADER)); + CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_Q= UESTION_ID)); + CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_V= ARSTORE_ID)); + CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.= VarOffset, sizeof (UINT16)); + + Statement->QuestionFlags =3D QuestionHdr->Flags; + + if (Statement->VarStoreId =3D=3D 0) { + // + // VarStoreId of zero indicates no variable storage + // + return Statement; + } + + // + // Find Storage for this Question + // + Link =3D GetFirstNode (&FormSet->StorageListHead); + while (!IsNull (&FormSet->StorageListHead, Link)) { + Storage =3D HII_STORAGE_FROM_LINK (Link); + + if (Statement->VarStoreId =3D=3D Storage->VarStoreId) { + Statement->Storage =3D Storage; + break; + } + + Link =3D GetNextNode (&FormSet->StorageListHead, Link); + } + + if (Statement->Storage =3D=3D NULL) { + return NULL; + } + + // + // Initialize varname for Name/Value or EFI Variable + // + if ((Statement->Storage->Type =3D=3D EFI_HII_VARSTORE_NAME_VALUE) || + (Statement->Storage->Type =3D=3D EFI_HII_VARSTORE_EFI_VARIABLE)) + { + Statement->VariableName =3D GetToken (Statement->VarStoreInfo.VarName,= FormSet->HiiHandle); + if (Statement->VariableName =3D=3D NULL) { + return NULL; + } + + if (Statement->Storage->Type =3D=3D EFI_HII_VARSTORE_NAME_VALUE) { + // + // Check whether old string node already exist. + // + Find =3D FALSE; + if (!IsListEmpty (&Statement->Storage->NameValueList)) { + Link =3D GetFirstNode (&Statement->Storage->NameValueList); + while (!IsNull (&Statement->Storage->NameValueList, Link)) { + NameValueNode =3D HII_NAME_VALUE_NODE_FROM_LINK (Link); + + if (StrCmp (Statement->VariableName, NameValueNode->Name) =3D=3D= 0) { + Find =3D TRUE; + break; + } + + Link =3D GetNextNode (&Statement->Storage->NameValueList, Link); + } + } + + if (!Find) { + // + // Insert to Name/Value varstore list + // + NameValueNode =3D AllocateZeroPool (sizeof (HII_NAME_VALUE_NODE)); + if (NameValueNode =3D=3D NULL) { + return NULL; + } + + NameValueNode->Signature =3D HII_NAME_VALUE_NODE_SIGNATURE; + NameValueNode->Name =3D AllocateCopyPool (StrSize (Statement-= >VariableName), Statement->VariableName); + if (NameValueNode->Name =3D=3D NULL) { + FreePool (NameValueNode); + return NULL; + } + + NameValueNode->Value =3D AllocateZeroPool (0x10); + if (NameValueNode->Value =3D=3D NULL) { + FreePool (NameValueNode->Name); + FreePool (NameValueNode); + return NULL; + } + + InsertTailList (&Statement->Storage->NameValueList, &NameValueNode= ->Link); + } + } + } + + return Statement; +} + +/** + Allocate a HII_EXPRESSION node. + + @param[in,out] Form The Form associated with this Exp= ression + @param[in] OpCode The binary opcode data. + + @return Pointer to a HII_EXPRESSION data structure. + +**/ +HII_EXPRESSION * +CreateExpression ( + IN OUT HII_FORM *Form, + IN UINT8 *OpCode + ) +{ + HII_EXPRESSION *Expression; + + Expression =3D AllocateZeroPool (sizeof (HII_EXPRESSION)); + if (Expression =3D=3D NULL) { + return NULL; + } + + Expression->Signature =3D HII_EXPRESSION_SIGNATURE; + InitializeListHead (&Expression->OpCodeListHead); + Expression->OpCode =3D (EFI_IFR_OP_HEADER *)OpCode; + + return Expression; +} + +/** + Create ConfigHdr string for a storage. + + @param[in] FormSet Pointer of the current FormSet + @param[in,out] Storage Pointer of the storage + + @retval EFI_SUCCESS Initialize ConfigHdr success + +**/ +EFI_STATUS +InitializeConfigHdr ( + IN HII_FORMSET *FormSet, + IN OUT HII_FORMSET_STORAGE *Storage + ) +{ + CHAR16 *Name; + + if ((Storage->Type =3D=3D EFI_HII_VARSTORE_BUFFER) || + (Storage->Type =3D=3D EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) + { + Name =3D Storage->Name; + } else { + Name =3D NULL; + } + + Storage->ConfigHdr =3D HiiConstructConfigHdr ( + &Storage->Guid, + Name, + FormSet->DriverHandle + ); + + if (Storage->ConfigHdr =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** + Convert Ascii string to Unicode. + + This is an internal function. + + @param[in] AsciiString The Ascii string to be converted. + @param[out] UnicodeString The Unicode string retrieved. + +**/ +VOID +AsciiToUnicode ( + IN CHAR8 *AsciiString, + OUT CHAR16 *UnicodeString + ) +{ + UINT8 Index; + + Index =3D 0; + while (AsciiString[Index] !=3D 0) { + UnicodeString[Index] =3D (CHAR16)AsciiString[Index]; + Index++; + } + + UnicodeString[Index] =3D L'\0'; +} + +/** + Allocate a HII_FORMSET_STORAGE data structure and insert to FormSet Stor= age List. + + @param[in] FormSet Pointer of the current FormSet + @param[in] StorageType Storage type. + @param[in] OpCodeData Binary data for this opcode. + + @return Pointer to a HII_FORMSET_STORAGE data structure. + +**/ +HII_FORMSET_STORAGE * +CreateStorage ( + IN HII_FORMSET *FormSet, + IN UINT8 StorageType, + IN UINT8 *OpCodeData + ) +{ + HII_FORMSET_STORAGE *Storage; + CHAR8 *AsciiStorageName; + + AsciiStorageName =3D NULL; + + Storage =3D AllocateZeroPool (sizeof (HII_FORMSET_STORAGE)); + if (Storage =3D=3D NULL) { + return NULL; + } + + Storage->Signature =3D HII_STORAGE_SIGNATURE; + Storage->Type =3D StorageType; + + switch (StorageType) { + case EFI_HII_VARSTORE_BUFFER: + + CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *)OpCodeData)->Guid, si= zeof (EFI_GUID)); + CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *)OpCodeData)->Size, si= zeof (UINT16)); + + Storage->Buffer =3D AllocateZeroPool (Storage->Size); + if (Storage->Buffer =3D=3D NULL) { + FreePool (Storage); + return NULL; + } + + AsciiStorageName =3D (CHAR8 *)((EFI_IFR_VARSTORE *)OpCodeData)->Name= ; + Storage->Name =3D AllocatePool (sizeof (CHAR16) * (AsciiStrLen (A= sciiStorageName) + 1)); + if (Storage->Name =3D=3D NULL) { + FreePool (Storage); + return NULL; + } + + AsciiToUnicode (AsciiStorageName, Storage->Name); + + break; + + case EFI_HII_VARSTORE_EFI_VARIABLE: + case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER: + CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *)OpCodeData)->Guid= , sizeof (EFI_GUID)); + CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *)OpCodeData)= ->Attributes, sizeof (UINT32)); + CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE_EFI *)OpCodeData)->Size= , sizeof (UINT16)); + + if (StorageType =3D=3D EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) { + Storage->Buffer =3D AllocateZeroPool (Storage->Size); + if (Storage->Buffer =3D=3D NULL) { + FreePool (Storage); + return NULL; + } + } + + AsciiStorageName =3D (CHAR8 *)((EFI_IFR_VARSTORE_EFI *)OpCodeData)->= Name; + Storage->Name =3D AllocatePool (sizeof (CHAR16) * (AsciiStrLen (A= sciiStorageName) + 1)); + if (Storage->Name =3D=3D NULL) { + FreePool (Storage); + return NULL; + } + + AsciiToUnicode (AsciiStorageName, Storage->Name); + + break; + + case EFI_HII_VARSTORE_NAME_VALUE: + CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *)OpCodeData= )->Guid, sizeof (EFI_GUID)); + InitializeListHead (&Storage->NameValueList); + + break; + + default: + break; + } + + InitializeConfigHdr (FormSet, Storage); + InsertTailList (&FormSet->StorageListHead, &Storage->Link); + + return Storage; +} + +/** + Get formset storage based on the input varstoreid info. + + @param[in] FormSet Pointer of the current FormSet. + @param[in] VarStoreId Varstore ID info. + + @return Pointer to a HII_FORMSET_STORAGE data structure. + +**/ +HII_FORMSET_STORAGE * +GetFstStgFromVarId ( + IN HII_FORMSET *FormSet, + IN EFI_VARSTORE_ID VarStoreId + ) +{ + HII_FORMSET_STORAGE *Storage; + LIST_ENTRY *Link; + BOOLEAN Found; + + Found =3D FALSE; + Storage =3D NULL; + // + // Find Formset Storage for this Question + // + Link =3D GetFirstNode (&FormSet->StorageListHead); + while (!IsNull (&FormSet->StorageListHead, Link)) { + Storage =3D HII_STORAGE_FROM_LINK (Link); + + if (Storage->VarStoreId =3D=3D VarStoreId) { + Found =3D TRUE; + break; + } + + Link =3D GetNextNode (&FormSet->StorageListHead, Link); + } + + return Found ? Storage : NULL; +} + +/** + Initialize Request Element of a Question. ::=3D '&' | '&'