From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (NAM10-MW2-obe.outbound.protection.outlook.com [40.107.94.79]) by mx.groups.io with SMTP id smtpd.web10.28503.1681870348238048591 for ; Tue, 18 Apr 2023 19:12:28 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@nvidia.com header.s=selector2 header.b=Xzx2duPU; 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.94.79, mailfrom: nicklew@nvidia.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Dfd5BM0aGwbVq0LCM7To73sw0bTszmHImZw5Hx+4r9u2rL6pSZnb5erupgt13DXQEI2KGagXJT309lXKbArAlpse+NV0LfTz7wRNZkX6il9X/ufBK/cpbGAPjjak70aQphV3z+/zmeFl6nUU2Bcs9saDskS74m9eSrgLU29LoV98M7RKp5lCPDWXJKtfTy5UiCmEnH89caLK+LinD67/Et9VZ3H/7r2ELcbl5cBzScz7ZcDroov7PYmgWLZoorT/9jfQga7IcPR7H4sN1jjOY87VKoA4pzizKjAdw1j3c7iK51JWtl+VS6aNxCozKs7HeVFzlIdiPyQXr2PBeK094A== 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=mf+UKr2awb5MDnBkfrx3xwMGwPIo0sAHstEBIrnumyU=; b=eKdoo3Nf220/hr6CbLtsVxdrjTFRKWI98TF3jCyOco3zu6SVBllo8oxUhjeQbEMKa6oxcxg60yKEnqBN7poZXObgQXBSlxYOXlAvMQ7p63KoMZBwC67F9+IhA/3Uo5DUJMDGlWEttAcFfcCGLtGuxw+d2buExA75dNMW6nfSfQqyPY0FGp29xxi4/kH+n3YStDoB4c8QSzNn/PT5HZToDdvky/wY3dWq+LCmKZbqctzj8ctzi9NCW41l9inyu2xqbxbwuKiclXIdVniC+CN8+ntmkeSok96zrH7iHdSbccmVnd819qBmR6+jL2YKKig0pxDRYteT77V1Q64pAHgADA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.161) 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=mf+UKr2awb5MDnBkfrx3xwMGwPIo0sAHstEBIrnumyU=; b=Xzx2duPUb9hNinOxi0zCx7KzYDg4tmDdnThUWIqyoY9Nh5M9kRoQfzJu7TzCJwDJfICuNSK5QDSNVV4fpkzgRppqhC+NWVvp/aya0qHgw467xUqecpUxdLgvmGAOd2HFSjbYe4ZXeM7+GFtMI9EKjAYVhLqseFK94uBKSnf03QnI1YfX9lLJTcj8Mb3DUAWmoOStSBJg09Bxkq65hU7I7PA2buOlH9Q6cTJ51ATyYktTDL72GCsh13UU6iAXhV1jN60N/Xcxsc3ilDiH6b76BnD49VHBKQUYJxpVgkDiRtpzxOJocYKE5XozgrO2U4xHLxIHMOU21uvwG8Qn9hevWA== Received: from BN8PR03CA0009.namprd03.prod.outlook.com (2603:10b6:408:94::22) by MW3PR12MB4475.namprd12.prod.outlook.com (2603:10b6:303:55::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6298.45; Wed, 19 Apr 2023 02:12:16 +0000 Received: from BN8NAM11FT103.eop-nam11.prod.protection.outlook.com (2603:10b6:408:94:cafe::f0) by BN8PR03CA0009.outlook.office365.com (2603:10b6:408:94::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.20 via Frontend Transport; Wed, 19 Apr 2023 02:12:16 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.161) 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.161 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.161; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (216.228.117.161) by BN8NAM11FT103.mail.protection.outlook.com (10.13.176.181) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6319.20 via Frontend Transport; Wed, 19 Apr 2023 02:12:16 +0000 Received: from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com (10.129.200.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Tue, 18 Apr 2023 19:12:02 -0700 Received: from rnnvmail201.nvidia.com (10.129.68.8) by rnnvmail201.nvidia.com (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Tue, 18 Apr 2023 19:11:58 -0700 Received: from NV-CL38DL3.nvidia.com (10.127.8.14) by mail.nvidia.com (10.129.68.8) with Microsoft SMTP Server id 15.2.986.37 via Frontend Transport; Tue, 18 Apr 2023 19:11:57 -0700 From: "Nickle Wang" To: CC: Abner Chang , Igor Kulchytskyy , "Nick Ramirez" Subject: [PATCH v2 2/5] RedfishPkg: introduce HII utility helper library Date: Wed, 19 Apr 2023 10:11:56 +0800 Message-ID: <20230419021156.5920-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: BN8NAM11FT103:EE_|MW3PR12MB4475:EE_ X-MS-Office365-Filtering-Correlation-Id: 2e431e2b-d872-47b9-7be7-08db407b7f44 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 7IIXI+66/kPiUEXU1lKmroIDWFhv2NzyM28SX/igIu32b5Jig+Kf8Wx2NEczhcudeZmvaTuopDyiosdFahlRJfmeW1GuWMphgEJZY7+3oa/U8PNf9QPs/Jz177wQT1IsdFsEBjUIQrZiYZ2aTZrAzIAV/epBBLyY1dIG+zABugq21Lcq2QIXH+cwC6M5nEQF8sp3Ya4o+A6ZTiVllj+3wh62Qj4BvSMmm6cJNKtEpjrhEXy7Gd8VQnOTPocIR5FSlryvBB8bzA74J4EiQ2kW5Ay4H6Q3N78yK2vOo3qPi4ODl2xKPjAmFLT8EXqPbSS3DL/4F9mJ+fA/hezSuiUvdNKfPJ1tvtYBXNkpQeEibPhMaBBGxPhKSKFDmhe0LyV0X3btz9FXaH5ejJhPHEbTmEHR7n37b6HkwNeGSZdk63axWg+9NRR+7Cr7T0QiBseHLxtMrSwGv6lpqpt9fP41zQAq0kuFGnjYpvuxGIk6WkYbPojsbEc1OAjjyEb4cRMJdghm6tJSetK6i9EbRQMS3l/RFE5vODUsOvG5gBXW9MvbVip4wmnUDwc2MKtmQzLLwjcxerWM8CnVe9uUArOPPcfmAUZVDUn7hyxd19rYWimimDhnnqXuWf9ha6VgBlnjKRJbmIgJH+2MoRpL5vgOcXh0kzSfN1TdpdkUWa0Dxuwi4gTES1F2fOnoijdMlBg41MdYhrD5xZ8MAL5F1EVhqErcHOXsUj9ac2d3NW8k8SfT2nR0/PUDs84SiNjG4xz0cGE5cUsSSoj/1B2BxhNwVOM79fd8TCoxAxxRT/fqreY= X-Forefront-Antispam-Report: CIP:216.228.117.161;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:dc6edge2.nvidia.com;CAT:NONE;SFS:(13230028)(4636009)(346002)(39860400002)(136003)(376002)(396003)(451199021)(36840700001)(40470700004)(46966006)(36756003)(8676002)(5660300002)(8936002)(6916009)(41300700001)(70586007)(316002)(30864003)(7636003)(70206006)(356005)(4326008)(2906002)(54906003)(82310400005)(19627235002)(86362001)(478600001)(7696005)(336012)(82740400003)(186003)(40460700003)(1076003)(26005)(40480700001)(107886003)(83380400001)(2616005)(426003)(36860700001)(66574015)(34070700002)(47076005)(579004)(559001);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Apr 2023 02:12:16.1375 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2e431e2b-d872-47b9-7be7-08db407b7f44 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.161];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: BN8NAM11FT103.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW3PR12MB4475 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 | 62 + RedfishPkg/Include/Library/HiiUtilityLib.h | 1205 ++++ .../Library/HiiUtilityLib/HiiExpression.h | 214 + .../Library/HiiUtilityLib/HiiInternal.h | 376 ++ .../Library/HiiUtilityLib/HiiExpression.c | 1440 ++++ .../Library/HiiUtilityLib/HiiIfrParse.c | 2715 ++++++++ .../HiiUtilityLib/HiiUtilityInternal.c | 5770 +++++++++++++++++ .../Library/HiiUtilityLib/HiiUtilityLib.c | 810 +++ 9 files changed, 12596 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..cab3f8a0ee68 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.inf @@ -0,0 +1,62 @@ +## @file +# Library to handle HII IFR data. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserve= d. +# +# 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..d4d4843e7e5c --- /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 += + UINTN ElementCount; ///< Number of in the= + UINTN SpareStrLen; ///< Spare length of ConfigRequest str= ing 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= _IFR_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_MATCH= 2 + + 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 expression= s 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_I= FR_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 expr= ession + EFI_IFR_OP_HEADER *OpCode; ///< Save the opcode bu= ffer. + LIST_ENTRY OpCodeListHead; ///< OpCodes consist of= this expression (HII_EXPRESSION_OPCODE) + HII_DEPENDENCY_EXPRESSION *RootDependencyExp; ///< Expression OpCodes= tree layout to describe dependency of this expression. + HII_EXTRA_DATA ExtraData; + EFI_HII_VALUE Result; ///< Expression evaluat= ion 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_TYP= E_STRING + /// + UINT8 *Buffer; + UINT16 BufferLen; + UINT8 BufferValueType; ///< Data type for buffer interna= l 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= value 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 ne= sted 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_NUMERI= C, it's Min/Max value + UINT64 Maximum; ///< for EFI_IFR_STRING/EFI_IFR_PASSWO= RD, 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= this 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 z= ero is reserved + EFI_VARSTORE_ID VarStoreId; ///< VarStore id, a value of zer= o indicates no variable storage + HII_VAR_STORE_INFO VarStoreInfo; ///< VarStoreInfoIf VarStoreId r= efers to Buffer Storage (EFI_IFR_VARSTORE or EFI_IFR_VARSTORE_EFI), then Va= rStoreInfo contains a 16-bit Buffer Storage offset (VarOffset). + ///< If VarStoreId refers to Nam= e/Value Storage (EFI_IFR_VARSTORE_NAME_VALUE), then VarStoreInfo contains t= he String ID of the name (VarName) for this name/value pair. + UINT8 QuestionFlags; ///< The flag of this Question.(= Readonly, reset required, callback attribute....) + + BOOLEAN QuestionReferToBitField; ///< Whether the quest= ion is stored in a bit field. + UINT16 StorageWidth; ///< The storage width= of this Question. + UINT16 BitStorageWidth; ///< The Storage width= of this Question in bit level. + UINT16 BitVarOffset; ///< The storage offse= t of this Question in bit level. + CHAR16 *VariableName; ///< Name/Value or EFI= Variable name + CHAR16 *BlockName; ///< Buffer storage bl= ock name: "OFFSET=3D...WIDTH=3D..." + + HII_FORMSET_STORAGE *Storage; ///< Point to the stor= age that store this question. + HII_STATEMENT_EXTRA ExtraData; + + BOOLEAN Locked; ///< Whether this stat= ement is locked. + + HII_STATEMENT_VALUE Value; + + /// + /// Get from IFR parsing + /// + + HII_STATEMENT *ParentStatement; ///< Parent Statement of cu= rrent statement. + HII_EXPRESSION_LIST *ExpressionList; ///< nesting inside of Gray= edOutIf/DisableIf/SuppressIf + HII_EXPRESSION *ValueExpression; ///< nested EFI_IFR_VALUE, = provide 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= list (HII_QUESTION_DEFAULT), provide default values + LIST_ENTRY OptionListHead; ///< nested EFI_IFR_ONE_OF_= OPTION list (HII_QUESTION_OPTION) + LIST_ENTRY InconsistentListHead; ///< nested inconsistent ex= pression list (HII_EXPRESSION) + LIST_ENTRY NoSubmitListHead; ///< nested nosubmit expres= sion list (HII_EXPRESSION) + LIST_ENTRY WarningListHead; ///< nested warning express= ion list (HII_EXPRESSION) + + HII_EXPRESSION *ReadExpression; ///< nested EFI_IFR_READ, = provide this question value by read expression. + HII_EXPRESSION *WriteExpression; ///< nested EFI_IFR_WRITE,= evaluate 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 o= r formmap form. + EFI_STRING_ID FormTitle; ///< FormTile of normal form= , or 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= form. + BOOLEAN Locked; ///< Whether this form is lo= cked. + EFI_GUID RefreshGuid; ///< Form refresh event guid= . + + LIST_ENTRY StatementListHead; ///< List of Statements and = Questions (HII_STATEMENT) + LIST_ENTRY ConfigRequestHead; ///< List of configrequest f= or all storage. + LIST_ENTRY RuleListHead; ///< nested EFI_IFR_RULE lis= t, pre-defined expressions attached to the form. + HII_EXPRESSION_LIST *SuppressExpression; ///< nesting inside of Suppr= essIf +} 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 = for formset, HII Handle of this FormSet package. + EFI_HANDLE DriverHandle; ///< EFI_HANDLE= which was registered with the package list in NewPackageList(). + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; ///< ConfigAcce= ss Protocol associated with this HiiPackageList + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + UINTN IfrBinaryLength; ///< Ifr binary= data length of this formset. + UINT8 *IfrBinaryData; ///< Point to t= he Ifr binary data. + + EFI_GUID Guid; ///< Formset Gu= id. + EFI_STRING_ID FormSetTitle; ///< String Id = of Formset title. + EFI_STRING_ID Help; ///< String Id = of Formset title. + + UINT8 NumberOfClassGuid; ///< Class Guid= name + EFI_GUID ClassGuid[3]; ///< Up to thre= e ClassGuid + + EFI_IMAGE_ID ImageId; ///< The image = id. + + LIST_ENTRY StatementListOSF; ///< Statement = list out side of the form. + LIST_ENTRY StorageListHead; ///< Storage li= st (HII_FORMSET_STORAGE) + LIST_ENTRY DefaultStoreListHead; ///< DefaultSto= re list (HII_FORMSET_DEFAULTSTORE) + LIST_ENTRY FormListHead; ///< Form list = (HII_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 b= uffer in the storage. + GetSetValueWithHiiDriver, ///< Get/Set question value from/to hii= driver. + GetSetValueWithBoth, ///< Compare the editbuffer with buffer= for this question, not use the question value. + GetSetValueWithMax ///< Invalid value. +} GET_SET_QUESTION_VALUE_WITH; + +/** + Initialize the internal data structure of a FormSet. + + @param[in] Handle PackageList Handle + @param[in,out] 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[out] 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[in,out] FormSet FormSet data structure. + +**/ +VOID +InitializeFormSet ( + IN OUT HII_FORMSET *FormSet + ); + +/** + Free resources allocated for a FormSet. + + @param[in,out] FormSet Pointer of the FormSet + +**/ +VOID +DestroyFormSet ( + IN OUT HII_FORMSET *FormSet + ); + +/** + Save Question Value to the memory, but not to storage. + + @param[in] FormSet FormSet data structure. + @param[in] Form Form data structure. + @param[in,out] Question Pointer to the Question. + @param[in] 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[in] FormSet FormSet data structure. + @param[in] Form Form data structure. + @param[in,out] 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[in] FormSet FormSet which contains the Form. + @param[in] 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[in] FormSet FormSet associated with this expre= ssion. + @param[in] Form Form associated with this expressi= on. + @param[in,out] 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[in] 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..e68a61f8b27d --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiInternal.h @@ -0,0 +1,376 @@ +/** @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 + +#define EXPRESSION_STACK_SIZE_INCREMENT 0x100 +#define EFI_IFR_SPECIFICATION_VERSION (UINT16) (((EFI_SYSTEM_TABLE_REVI= SION >> 16) << 8) | (((EFI_SYSTEM_TABLE_REVISION & 0xFFFF) / 10) << 4) | ((= EFI_SYSTEM_TABLE_REVISION & 0xFFFF) % 10)) + +/// +/// Definition of HII_FORM_CONFIG_REQUEST +// +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + CHAR16 *ConfigRequest; ///< =3D + + CHAR16 *ConfigAltResp; ///< Alt config response string f= or this ConfigRequest. + UINTN ElementCount; ///< Number of i= n 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[in,out] Dest Location to copy string + @param[in] Src String to copy + +**/ +VOID +NewStringCopy ( + IN OUT CHAR16 **Dest, + IN CHAR16 *Src + ); + +/** + Set Value of given Name in a NameValue Storage. + + @param[in] Storage The NameValue Storage. + @param[in] Name The Name. + @param[in] Value The Value to set. + @param[out] 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[in] Question The question refer to bit field. + @param[in] Buffer Point to the buffer which the question value= get from. + @param[out] 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[in] Question The question refer to bit field. + @param[in,out] Buffer Point to the buffer which the question va= lue set to. + @param[in] 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[in] Question The question. + @param[in] Value Unicode buffer save the question value= . + @param[out] QuestionValue The Question Value retrieved from Buff= er. + + @retval Status whether convert the value success. + +**/ +EFI_STATUS +BufferToQuestionValue ( + 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[in] Token The String's ID. + @param[in] HiiHandle The package list in the HII database = to search for + the specified string. + + @return The output string. + +**/ +CHAR16 * +GetTokenString ( + 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[in] ConfigString String to be converted + +**/ +VOID +EFIAPI +HiiStringToLowercase ( + IN EFI_STRING ConfigString + ); + +/** + Evaluate if the result is a non-zero value. + + @param[in] Result The result to be evaluated. + + @retval TRUE It is a non-zero value. + @retval FALSE It is a zero value. + +**/ +BOOLEAN +IsHiiValueTrue ( + 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 +NewHiiString ( + IN CHAR16 *String, + IN EFI_HII_HANDLE HiiHandle + ); + +/** + Perform nosubmitif check for a Form. + + @param[in] FormSet FormSet data structure. + @param[in] Form Form data structure. + @param[in] 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[in] FormSet FormSet data structure. + @param[in,out] CurrentForm Current input form data structure. + @param[out] 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[in] Storage The Storage to be converted. + @param[in] ConfigResp The returned . + @param[in] 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[in] Storage The Storage to receive the settings. + @param[in] 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[in] Handle PackageList Handle + @param[in,out] 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[out] BinaryLength The length of the FormSet IFR binary. + @param[out] 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[in] FormSet FormSet data structure. + @param[in] Storage Buffer Storage. + +**/ +VOID +LoadFormSetStorage ( + IN HII_FORMSET *FormSet, + IN HII_FORMSET_STORAGE *Storage + ); + +/** + Free resources of a Form. + + @param[in] FormSet Pointer of the FormSet + @param[in,out] 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[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 + ); + +/** + Zero extend integer/boolean/date/time to UINT64 for comparing. + + @param[in] Value HII Value to be converted. + +**/ +VOID +ExtendValueToU64 ( + IN HII_STATEMENT_VALUE *Value + ); + +/** + Parse opcodes in the formset IFR binary. + + @param[in] 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..0317a3765a46 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiExpression.c @@ -0,0 +1,1440 @@ +/** @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; + +/** + 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[in,out] 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 (IsHiiValueTrue (&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..a51d7b9c6d24 --- /dev/null +++ b/RedfishPkg/Library/HiiUtilityLib/HiiIfrParse.c @@ -0,0 +1,2715 @@ +/** @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" + +/** + 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 GetTokenString (Statement->VarStoreInfo.Va= rName, 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 '&' | '&'