From nobody Fri Apr 26 04:16:08 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+53125+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53125+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1578634515; cv=none; d=zohomail.com; s=zohoarc; b=miykIVQC9aP5wTnQeq2o7RleGiYOrDIt4UDTeGdeUXGNysqluzZZYu0SjGNVLgf34iWYEZHB5Ti7NGvy2DpXi3FjAOtib/chg66QZZ9EW1LAwTxjWVCWsEIp8TFlOB80rsONJv4ju9zHKpKjjVl1Tf41iSrXBMS9646ChhfVOoU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1578634515; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=5bo1jiWbWVJD2eHE9SmQrz/CXV+gbvad5/IFwJ3Wjbo=; b=UnpG0MKBvlrPB/wS6zlt7QE3jmBNCcyg4znhA8RSyKsaCFUcome0cH9ENNWWAkr+F6DALtRZeZ5bO0NMHQHd9xOCzGllueqOx6nbUsoELsX84YX9eXItkG5cGNVEop/EyJvM5zkWkSaeOAgovZb9ccjIn/qSv6VgsI92v7XuitU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53125+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1578634515080989.2615308468236; Thu, 9 Jan 2020 21:35:15 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id cF8CYY1788612x1uBxa4xRL2; Thu, 09 Jan 2020 21:35:14 -0800 X-Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web11.6216.1578634514007423001 for ; Thu, 09 Jan 2020 21:35:14 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Jan 2020 21:35:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,415,1571727600"; d="scan'208";a="371507841" X-Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.39]) by orsmga004.jf.intel.com with ESMTP; 09 Jan 2020 21:35:12 -0800 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Michael D Kinney , Liming Gao Subject: [edk2-devel][PATCH 1/3] MdePkg: Add definition for Fmp Capsule Dependency. Date: Fri, 10 Jan 2020 13:34:52 +0800 Message-Id: <20200110053454.15376-2-wei6.xu@intel.com> In-Reply-To: <20200110053454.15376-1-wei6.xu@intel.com> References: <20200110053454.15376-1-wei6.xu@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wei6.xu@intel.com X-Gm-Message-State: 2SuSfBr26MEb2aDQcPg5E4p4x1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1578634514; bh=POMdEDLY1+ecRhPPOGk1dee/FEZX8Ai3g5teJ02u7G4=; h=Cc:Content-Type:Date:From:Reply-To:Subject:To; b=n9BkCP3wDBOVMZ4n0P1nWk682J1Nz7a/ibWwnNomrpyR9kwjAEkxBPY69qyIl9pklIb NJeAiLidUuZ/A3Vad/I9t1fzmrufb+aCCEY0iXNwvtUTDVzYeP3ncLR6liY42iF/6ZEDu kQIHt60bqOBBOj1UqWFm7ypNx/uYuHi3cos= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2421 Add new definitions for Fmp Capsule dependency in UEFI Spec 2.8. 1. Extend the Last Attempt Status with a value to indicate the firmware update fails with unsatisfied dependencies. 2. Add the definition of dependency expression op-codes. 3. Add the definition of EFI_FIRMWARE_IMAGE_DEP which is an array of FMP dependency expression op-codes. 4. Extend the EFI_FIRMWARE_IMAGE_DESCRIPTOR with a pointer to the array of FMP dependency expression op-codes. 5. Extend the Image Attribute Definitions with IMAGE_ATTRIBUTE_DEPENDENCY to indicate that there is and EFI_FIRMWARE_IMAGE_DEP section associated with the image. 6. Update EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION to 4. Cc: Michael D Kinney Cc: Liming Gao Signed-off-by: Wei6 Xu --- MdePkg/Include/Guid/SystemResourceTable.h | 19 ++++++++------- MdePkg/Include/Protocol/FirmwareManagement.h | 35 ++++++++++++++++++++++++= ++-- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/MdePkg/Include/Guid/SystemResourceTable.h b/MdePkg/Include/Gui= d/SystemResourceTable.h index 57c42bf9f3..418b8c8d05 100644 --- a/MdePkg/Include/Guid/SystemResourceTable.h +++ b/MdePkg/Include/Guid/SystemResourceTable.h @@ -1,9 +1,9 @@ /** @file Guid & data structure used for EFI System Resource Table (ESRT) =20 - Copyright (c) 2015, Intel Corporation. All rights reserved.
+ Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 @par Revision Reference: GUIDs defined in UEFI 2.5 spec. =20 @@ -32,18 +32,19 @@ #define ESRT_FW_TYPE_UEFIDRIVER 0x00000003 =20 /// /// Last Attempt Status Values /// -#define LAST_ATTEMPT_STATUS_SUCCESS 0x00000000 -#define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL 0x00000001 -#define LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES 0x00000002 -#define LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION 0x00000003 -#define LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT 0x00000004 -#define LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR 0x00000005 -#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_AC 0x00000006 -#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT 0x00000007 +#define LAST_ATTEMPT_STATUS_SUCCESS 0x00000000 +#define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL 0x00000001 +#define LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES 0x00000002 +#define LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION 0x00000003 +#define LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT 0x00000004 +#define LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR 0x00000005 +#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_AC 0x00000006 +#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT 0x00000007 +#define LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES 0x00000008 =20 typedef struct { /// /// The firmware class field contains a GUID that identifies a firmware = component /// that can be updated via UpdateCapsule(). This GUID must be unique wi= thin all diff --git a/MdePkg/Include/Protocol/FirmwareManagement.h b/MdePkg/Include/= Protocol/FirmwareManagement.h index 0a0bf4c84a..297bb5ff03 100644 --- a/MdePkg/Include/Protocol/FirmwareManagement.h +++ b/MdePkg/Include/Protocol/FirmwareManagement.h @@ -6,11 +6,11 @@ =20 GetImageInfo() is the only required function. GetImage(), SetImage(), CheckImage(), GetPackageInfo(), and SetPackageInfo() shall return EFI_UNSUPPORTED if not supported by the driver. =20 - Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.
Copyright (c) 2013 - 2014, Hewlett-Packard Development Company, L.P.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 @par Revision Reference: This Protocol is introduced in UEFI Specification 2.3 @@ -26,10 +26,35 @@ 0x86c77a67, 0xb97, 0x4633, {0xa1, 0x87, 0x49, 0x10, 0x4d, 0x6, 0x85, 0= xc7 } \ } =20 typedef struct _EFI_FIRMWARE_MANAGEMENT_PROTOCOL EFI_FIRMWARE_MANAGEMENT_P= ROTOCOL; =20 +/// +/// Dependency Expression Opcode +/// +#define EFI_FMP_DEP_PUSH_GUID 0x00 +#define EFI_FMP_DEP_PUSH_VERSION 0x01 +#define EFI_FMP_DEP_VERSION_STR 0x02 +#define EFI_FMP_DEP_AND 0x03 +#define EFI_FMP_DEP_OR 0x04 +#define EFI_FMP_DEP_NOT 0x05 +#define EFI_FMP_DEP_TRUE 0x06 +#define EFI_FMP_DEP_FALSE 0x07 +#define EFI_FMP_DEP_EQ 0x08 +#define EFI_FMP_DEP_GT 0x09 +#define EFI_FMP_DEP_GTE 0x0A +#define EFI_FMP_DEP_LT 0x0B +#define EFI_FMP_DEP_LTE 0x0C +#define EFI_FMP_DEP_END 0x0D + +/// +/// Image Attribute - Dependency +/// +typedef struct { + UINT8 Dependencies[1]; +} EFI_FIRMWARE_IMAGE_DEP; + /// /// EFI_FIRMWARE_IMAGE_DESCRIPTOR /// typedef struct { /// @@ -109,10 +134,11 @@ typedef struct { /// instance a zero can be used. A zero means the FMP provider is not ab= le to determine a /// unique hardware instance number or a hardware instance number is not= needed. Only /// present in version 3 or higher. /// UINT64 HardwareInstance; + EFI_FIRMWARE_IMAGE_DEP *Dependencies; } EFI_FIRMWARE_IMAGE_DESCRIPTOR; =20 =20 // // Image Attribute Definitions @@ -141,10 +167,15 @@ typedef struct { #define IMAGE_ATTRIBUTE_IN_USE 0x0000000000000008 /// /// The attribute IMAGE_ATTRIBUTE_UEFI_IMAGE indicates that this image is = an EFI compatible image. /// #define IMAGE_ATTRIBUTE_UEFI_IMAGE 0x0000000000000010 +/// +/// The attribute IMAGE_ATTRIBUTE_DEPENDENCY indicates that there is an EF= I_FIRMWARE_IMAGE_DEP +/// section associated with the image. +/// +#define IMAGE_ATTRIBUTE_DEPENDENCY 0x0000000000000020 =20 =20 // // Image Compatibility Definitions // @@ -156,11 +187,11 @@ typedef struct { #define IMAGE_COMPATIBILITY_CHECK_SUPPORTED 0x0000000000000001 =20 /// /// Descriptor Version exposed by GetImageInfo() function /// -#define EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION 3 +#define EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION 4 =20 =20 /// /// Image Attribute - Authentication Required /// --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53125): https://edk2.groups.io/g/devel/message/53125 Mute This Topic: https://groups.io/mt/69595649/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri Apr 26 04:16:08 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+53126+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53126+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1578634518; cv=none; d=zohomail.com; s=zohoarc; b=RL/mtIIKgdFEWpWV2YZu676ccxza18bEzyEKnIxeWqUMK9593lt9GdgqWF9Fce6Wemn0oYS7vYCX2lqSIfb7xE/Z4o2FqPdK2+qXipfB+qEmuorFDn2mbmnQrfYEYOh0d+aAmG91zybqQ1f124rTLImUrBGDnUvkbQvCgKq6JSk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1578634518; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=H3i272zFwIe6l0aM7RouY/UquHClVGNoC0jB0WfYiEs=; b=inE2+x0MIoAoWEiJ+wVZxL0A+VHc7ALppOLAa40B+WRNpJJP6gCa091DHCrcY70NQaTL9jpDp1tf3E8+QB1hcn5yYOqQ/ZpQUW7+Ohuw0TWvkNVzBZU0uz+9Tz6+obQAU4kN5/NEHfmhb2FxfCzMiTeeaTOo0u8YJbvDqCPglEw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53126+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1578634518094857.4833435854599; Thu, 9 Jan 2020 21:35:18 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id U7htYY1788612xBTlOxl4WTz; Thu, 09 Jan 2020 21:35:17 -0800 X-Received: from mga03.intel.com (mga03.intel.com []) by mx.groups.io with SMTP id smtpd.web11.6216.1578634514007423001 for ; Thu, 09 Jan 2020 21:35:17 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Jan 2020 21:35:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,415,1571727600"; d="scan'208";a="371507847" X-Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.39]) by orsmga004.jf.intel.com with ESMTP; 09 Jan 2020 21:35:15 -0800 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Michael D Kinney , Liming Gao Subject: [edk2-devel][PATCH 2/3] MdeModulePkg/CapsuleApp: Enhance CapsuleApp for Fmp Capsule Dependency Date: Fri, 10 Jan 2020 13:34:53 +0800 Message-Id: <20200110053454.15376-3-wei6.xu@intel.com> In-Reply-To: <20200110053454.15376-1-wei6.xu@intel.com> References: <20200110053454.15376-1-wei6.xu@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wei6.xu@intel.com X-Gm-Message-State: KZvSdtfnBCW4iTouCMB2G2P5x1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1578634517; bh=JpNVete1o2leEV6P3JxvT1KKNq0AXDk3fJ8RkSYp1DA=; h=Cc:Date:From:Reply-To:Subject:To; b=wqBWb90lVFmVaIzE88pEKiRqKBgW/uKjGgk/VRYpSluysmdIMwviemzhRCgEFxKntAL 4UU0i/8xmwYW19HbBU+VDBqG4pQ7t2BScXlCb5wwOAZs1DFOXFL3Ci3e4tuPHXpJhvh8X z5eSwKG4ftnshkrVKFh1XPsukz0XB3vuRBs= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2421 1. Enhance "CapsuleApp -P" to output the depex expression op-codes in the EFI_FIRMWARE_IMAGE_DESCRIPTOR. 2. Enhance Last Attempt Status String with a new string to describe the error LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES. Cc: Michael D Kinney Cc: Liming Gao Signed-off-by: Wei6 Xu --- MdeModulePkg/Application/CapsuleApp/CapsuleDump.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c b/MdeModuleP= kg/Application/CapsuleApp/CapsuleDump.c index 58a93568d0..d65197b256 100644 --- a/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c +++ b/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c @@ -1,9 +1,9 @@ /** @file Dump Capsule image information. =20 - Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ =20 #include "CapsuleApp.h" @@ -336,10 +336,11 @@ CHAR8 *mLastAttemptStatusString[] =3D { "Error: Incorrect Version", "Error: Invalid Format", "Error: Auth Error", "Error: Power Event AC", "Error: Power Event Battery", + "Error: Unsatisfied Dependencies", }; =20 /** Convert FwType to a string. =20 @@ -1005,10 +1006,11 @@ DumpFmpImageInfo ( IN CHAR16 *PackageVersionName ) { EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo; UINTN Index; + UINTN Index2; =20 Print(L" DescriptorVersion - 0x%x\n", DescriptorVersion); Print(L" DescriptorCount - 0x%x\n", DescriptorCount); Print(L" DescriptorSize - 0x%x\n", DescriptorSize); Print(L" PackageVersion - 0x%x\n", PackageVersion); @@ -1041,10 +1043,22 @@ DumpFmpImageInfo ( Print(L" LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo-= >LowestSupportedImageVersion); if (DescriptorVersion > 2) { Print(L" LastAttemptVersion - 0x%x\n", CurrentImageInf= o->LastAttemptVersion); Print(L" LastAttemptStatus - 0x%x (%a)\n", CurrentIma= geInfo->LastAttemptStatus, LastAttemptStatusToString(CurrentImageInfo->Last= AttemptStatus)); Print(L" HardwareInstance - 0x%lx\n", CurrentImageIn= fo->HardwareInstance); + if (DescriptorVersion > 3) { + Print(L" Dependencies - "); + if (CurrentImageInfo->Dependencies =3D=3D NULL) { + Print(L"NULL\n"); + } else { + Index2 =3D 0; + do { + Print(L"%02x ", CurrentImageInfo->Dependencies->Dependencies= [Index2]); + } while (CurrentImageInfo->Dependencies->Dependencies[Index2 += +] !=3D EFI_FMP_DEP_END); + Print(L"\n"); + } + } } } // // Use DescriptorSize to move ImageInfo Pointer to stay compatible wit= h different ImageInfo version // --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53126): https://edk2.groups.io/g/devel/message/53126 Mute This Topic: https://groups.io/mt/69595651/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Fri Apr 26 04:16:08 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) client-ip=66.175.222.12; envelope-from=bounce+27952+53127+1787277+3901457@groups.io; helo=web01.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53127+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1578634522; cv=none; d=zohomail.com; s=zohoarc; b=TLYCokpbW62VCeilcx/1KFzGHEhK1++piA/k7IwOrOQfrmtVdK8WWLuMWBespv1cLPbr9ZI7TayckTqBLmTgGzFxZzaanDqoMinR2Ozs/Fo8pxPeQQIoTKCBhFXwipS6TzDJsUwk1hYqCuZTfgXfKdBL7RDn1YM4ja8vY0QJFDQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1578634522; h=Cc:Date:From:In-Reply-To:List-Id:List-Unsubscribe:Message-ID:Reply-To:References:Sender:Subject:To; bh=Zky4CdblJwdMPb7WBfBsvgoFgjuwWb3fCzdAMpgQjGg=; b=iRpas1zK/5RvALAiMkp1YtAHYqBOE9kKSjfgSRlxrL8CGjJm+YJ/SQi4HAscXXGkvCDcAbYYkfiiN+Q5Hi17PfGpgSxh7Ji2MCWoyMyAKtzE4l3E9qrh+PIuQjs3wfuXCxZT78AdFowDbOlf4nD1fAdaozmwP0kZIPl2b5qSnqw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.12 as permitted sender) smtp.mailfrom=bounce+27952+53127+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) header.from= Received: from web01.groups.io (web01.groups.io [66.175.222.12]) by mx.zohomail.com with SMTPS id 1578634522030618.8953520369234; Thu, 9 Jan 2020 21:35:22 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id xrODYY1788612xqhb8n50FD6; Thu, 09 Jan 2020 21:35:21 -0800 X-Received: from mga03.intel.com (mga03.intel.com []) by mx.groups.io with SMTP id smtpd.web11.6216.1578634514007423001 for ; Thu, 09 Jan 2020 21:35:21 -0800 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Jan 2020 21:35:20 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,415,1571727600"; d="scan'208";a="371507857" X-Received: from shwdeopenpsi174.ccr.corp.intel.com ([10.239.157.39]) by orsmga004.jf.intel.com with ESMTP; 09 Jan 2020 21:35:19 -0800 From: "Xu, Wei6" To: devel@edk2.groups.io Cc: Michael D Kinney , Liming Gao Subject: [edk2-devel][PATCH 3/3] FmdDevicePkg/FmpDxe: Support Fmp Capsule Dependency. Date: Fri, 10 Jan 2020 13:34:54 +0800 Message-Id: <20200110053454.15376-4-wei6.xu@intel.com> In-Reply-To: <20200110053454.15376-1-wei6.xu@intel.com> References: <20200110053454.15376-1-wei6.xu@intel.com> Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wei6.xu@intel.com X-Gm-Message-State: qxNTtDsAzlkD4P8TKRfdckcRx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1578634521; bh=3t4w/STabSA5xzIbE0DGnRwcNkXS1rVpR6gGZtabcEQ=; h=Cc:Date:From:Reply-To:Subject:To; b=d7sOwpsm9GrDOTK2ckvU6ZLEM87I1AyZj6O8dAc/QZgq6dHs//+nhk99l1ymdddYZu0 vfKil28hPg6b4P9kjpLDEbT/ukYQWBXSJHGbiqKRBTd8gUHK3iI8K8MR9isqPXJbLrYnr 5t5IMc26viqn11oO8fNYTUBleqmJ7q2o0sk= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2421 Capsule Dependency is an incremental change of Fmp Capsule Update. The capsule format is extended to include a set of binary encoded dependency expression. The dependency expression is signed together with the Fmp payload and evaluated before update is applied. This feature is defined in UEFI Spec 2.8. The dependency evaluation has two steps: 1. Validate platform existing Fmp images' version satisfy the dependency expression in capsule image. 2. Validate the capsule image version satisfy all the platform existing Fmp image's dependency expression. If the dependency expression evaluates to FALSE, then the capsule update fails and last attempt status is set to LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES. The dependency saving and getting is FmpDeviceLib implementation scope. The parameter "Image" of FmpDeviceSetImage and FmpDeviceGetImage function is extended to contain the dependency. The layout: +--------------------------+ | Dependency Op-codes | +--------------------------+ | Fmp Payload Image | +--------------------------+ 1. FmpDeviceSetImage is responsible for retrieving the dependency from the parameter "Image" and saving it to a protected storage. 2. FmpDeviceGetImage is responsible for retrieving the dependency from the storage where FmpDeviceSetImage saves dependency and combining it with the Fmp Payload Image into one buffer which is returned to the caller. This dependency will be populated into EFI_FIRMWARE_IMAGE_DESCRIPTOR and used for dependency evaluation. 3. FmpDeviceGetAttributes must set the bit IMAGE_ATTRIBUTE_DEPENDENCY to indicate the Fmp device supports Fmp Capsule Dependency feature. Cc: Michael D Kinney Cc: Liming Gao Signed-off-by: Wei6 Xu --- FmpDevicePkg/FmpDxe/Dependency.c | 679 ++++++++++++++++++++++++++++++++++= ++++ FmpDevicePkg/FmpDxe/Dependency.h | 63 ++++ FmpDevicePkg/FmpDxe/FmpDxe.c | 238 ++++++++++++- FmpDevicePkg/FmpDxe/FmpDxe.inf | 4 +- FmpDevicePkg/FmpDxe/FmpDxeLib.inf | 4 +- 5 files changed, 972 insertions(+), 16 deletions(-) create mode 100644 FmpDevicePkg/FmpDxe/Dependency.c create mode 100644 FmpDevicePkg/FmpDxe/Dependency.h diff --git a/FmpDevicePkg/FmpDxe/Dependency.c b/FmpDevicePkg/FmpDxe/Depende= ncy.c new file mode 100644 index 0000000000..b63a36b989 --- /dev/null +++ b/FmpDevicePkg/FmpDxe/Dependency.c @@ -0,0 +1,679 @@ +/** @file + Supports Capsule Dependency Expression. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include "FmpDxe.h" +#include "Dependency.h" + +// +// Define the initial size of the dependency expression evaluation stack +// +#define DEPEX_STACK_SIZE_INCREMENT 0x1000 + +// +// Type of stack element +// +typedef enum { + BooleanType, + VersionType +} ELEMENT_TYPE; + +// +// Value of stack element +// +typedef union { + BOOLEAN Boolean; + UINT32 Version; +} ELEMENT_VALUE; + +// +// Stack element used to evaluate dependency expressions +// +typedef struct { + ELEMENT_VALUE Value; + ELEMENT_TYPE Type; +} DEPEX_ELEMENT; + +// +// Global variable used to support dependency evaluation +// +UINTN mNumberOfFmpInstance =3D 0; +EFI_FIRMWARE_IMAGE_DESCRIPTOR **mFmpImageInfoBuf =3D NULL; + +// +// Indicates the status of dependency check, default value is DEPENDENCIES= _SATISFIED. +// +UINT8 mDependenciesCheckStatus =3D DEPENDENCIES_SATISFIED; + +// +// Global stack used to evaluate dependency expressions +// +DEPEX_ELEMENT *mDepexEvaluationStack =3D NULL; +DEPEX_ELEMENT *mDepexEvaluationStackEnd =3D NULL; +DEPEX_ELEMENT *mDepexEvaluationStackPointer =3D NULL; + +/** + Grow size of the Depex stack + + @retval EFI_SUCCESS Stack successfully growed. + @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow = the stack. + +**/ +EFI_STATUS +GrowDepexStack ( + VOID + ) +{ + DEPEX_ELEMENT *NewStack; + UINTN Size; + + Size =3D DEPEX_STACK_SIZE_INCREMENT; + if (mDepexEvaluationStack !=3D NULL) { + Size =3D Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack); + } + + NewStack =3D AllocatePool (Size * sizeof (DEPEX_ELEMENT)); + if (NewStack =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (mDepexEvaluationStack !=3D NULL) { + // + // Copy to Old Stack to the New Stack + // + CopyMem ( + NewStack, + mDepexEvaluationStack, + (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (DEPEX_E= LEMENT) + ); + + // + // Free The Old Stack + // + FreePool (mDepexEvaluationStack); + } + + // + // Make the Stack pointer point to the old data in the new stack + // + mDepexEvaluationStackPointer =3D NewStack + (mDepexEvaluationStackPointe= r - mDepexEvaluationStack); + mDepexEvaluationStack =3D NewStack; + mDepexEvaluationStackEnd =3D NewStack + Size; + + return EFI_SUCCESS; +} + +/** + Push an element onto the Stack. + + @param[in] Value Value to push. + @param[in] Type Element Type + + @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. + @retval EFI_INVALID_PARAMETER Wrong stack element type. + +**/ +EFI_STATUS +Push ( + IN UINT32 Value, + IN UINTN Type + ) +{ + EFI_STATUS Status; + DEPEX_ELEMENT Element; + + // + // Check Type + // + if (Type !=3D BooleanType && Type !=3D VersionType) { + return EFI_INVALID_PARAMETER; + } + + // + // Check for a stack overflow condition + // + if (mDepexEvaluationStackPointer =3D=3D mDepexEvaluationStackEnd) { + // + // Grow the stack + // + Status =3D GrowDepexStack (); + if (EFI_ERROR (Status)) { + return Status; + } + } + + Element.Value.Version =3D Value; + Element.Type =3D Type; + + // + // Push the item onto the stack + // + *mDepexEvaluationStackPointer =3D Element; + mDepexEvaluationStackPointer++; + + return EFI_SUCCESS; +} + + +/** + Pop an element from the stack. + + @param[in] Value Element to pop. + @param[in] Type Type of element. + + @retval EFI_SUCCESS The value was popped onto the stack. + @retval EFI_ACCESS_DENIED The pop operation underflowed the stack. + @retval EFI_INVALID_PARAMETER Type is mismatched. + +**/ +EFI_STATUS +Pop ( + OUT DEPEX_ELEMENT *Element, + IN ELEMENT_TYPE Type + ) +{ + // + // Check for a stack underflow condition + // + if (mDepexEvaluationStackPointer =3D=3D mDepexEvaluationStack) { + return EFI_ACCESS_DENIED; + } + + // + // Pop the item off the stack + // + mDepexEvaluationStackPointer--; + *Element =3D *mDepexEvaluationStackPointer; + if ((*Element).Type !=3D Type) { + return EFI_INVALID_PARAMETER; + } + return EFI_SUCCESS; +} + +/** + Evaluate the dependencies. + + @param[in] Dependencies Dependency expressions. + @param[in] DependenciesSize Size of Dependency expressions. + + @retval TRUE Dependency expressions evaluate to TRUE. + @retval FALSE Dependency expressions evaluate to FALSE. + +**/ +BOOLEAN +EvaluateDependencies ( + IN CONST EFI_FIRMWARE_IMAGE_DEP * Dependencies, + IN CONST UINTN DependenciesSize + ) +{ + EFI_STATUS Status; + UINT8 *Iterator; + UINT8 Index; + DEPEX_ELEMENT Element1; + DEPEX_ELEMENT Element2; + GUID ImageTypeId; + UINT32 Version; + + if (Dependencies =3D=3D NULL || DependenciesSize =3D=3D 0) { + return FALSE; + } + + // + // Clean out memory leaks in Depex Boolean stack. Leaks are only caused = by + // incorrectly formed DEPEX expressions + // + mDepexEvaluationStackPointer =3D mDepexEvaluationStack; + + Iterator =3D (UINT8 *) Dependencies->Dependencies; + while (Iterator < (UINT8 *) Dependencies->Dependencies + DependenciesSiz= e) { + switch (*Iterator) + { + case EFI_FMP_DEP_PUSH_GUID: + if (Iterator + sizeof (EFI_GUID) >=3D (UINT8 *) Dependencies->Depend= encies + DependenciesSize) { + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + + CopyGuid (&ImageTypeId, (EFI_GUID *) (Iterator + 1)); + Iterator =3D Iterator + sizeof (EFI_GUID); + + for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++){ + if (mFmpImageInfoBuf[Index] =3D=3D NULL) { + continue; + } + if(CompareGuid (&mFmpImageInfoBuf[Index]->ImageTypeId, &ImageTypeI= d)){ + Status =3D Push (mFmpImageInfoBuf[Index]->Version, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + } + } + if (Index =3D=3D mNumberOfFmpInstance) { + Status =3D EFI_NOT_FOUND; + goto Error; + } + break; + case EFI_FMP_DEP_PUSH_VERSION: + if (Iterator + sizeof (UINT32) >=3D (UINT8 *) Dependencies->Dependen= cies + DependenciesSize ) { + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + + Version =3D *(UINT32 *) (Iterator + 1); + Status =3D Push (Version, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Iterator =3D Iterator + sizeof (UINT32); + break; + case EFI_FMP_DEP_VERSION_STR: + Iterator +=3D AsciiStrnLenS ((CHAR8 *) Iterator, DependenciesSize - = (Iterator - Dependencies->Dependencies)); + break; + case EFI_FMP_DEP_AND: + Status =3D Pop (&Element1, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Push (Element1.Value.Boolean & Element2.Value.Boolean, Bo= oleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_OR: + Status =3D Pop (&Element1, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop(&Element2, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Push (Element1.Value.Boolean | Element2.Value.Boolean, Bo= oleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_NOT: + Status =3D Pop (&Element1, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Push (!(Element1.Value.Boolean), BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_TRUE: + Status =3D Push (TRUE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_FALSE: + Status =3D Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_EQ: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version =3D=3D Element2.Value.Version) ? = Push (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_GT: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version > Element2.Value.Version) ? Push= (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_GTE: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version >=3D Element2.Value.Version) ? Pu= sh (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_LT: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version < Element2.Value.Version) ? Push= (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_LTE: + Status =3D Pop (&Element1, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D Pop (&Element2, VersionType); + if (EFI_ERROR (Status)) { + goto Error; + } + Status =3D (Element1.Value.Version <=3D Element2.Value.Version) ? Pu= sh (TRUE, BooleanType) : Push (FALSE, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + break; + case EFI_FMP_DEP_END: + Status =3D Pop (&Element1, BooleanType); + if (EFI_ERROR (Status)) { + goto Error; + } + return Element1.Value.Boolean; + default: + Status =3D EFI_INVALID_PARAMETER; + goto Error; + } + Iterator++; + } + +Error: + + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): EvaluateDependencies() - RESULT =3D FA= LSE (Status =3D %r)\n", mImageIdName, Status)); + return FALSE; +} + +/** + Validate the dependency expression and output its size. + + @param[in] ImageDepex Pointer to the EFI_FIRMWARE_IMAGE_DEP. + @param[in] MaxDepexSize Max size of the dependency. + @param[out] DepexSize Size of dependency. + + @retval TRUE The capsule is valid. + @retval FALSE The capsule is invalid. + +**/ +BOOLEAN +ValidateImageDepex ( + IN EFI_FIRMWARE_IMAGE_DEP *ImageDepex, + IN CONST UINTN MaxDepexSize, + OUT UINT32 *DepexSize + ) +{ + UINT8 *Depex; + + *DepexSize =3D 0; + Depex =3D ImageDepex->Dependencies; + while (Depex < ImageDepex->Dependencies + MaxDepexSize) { + switch (*Depex) + { + case EFI_FMP_DEP_PUSH_GUID: + Depex +=3D sizeof (EFI_GUID) + 1; + break; + case EFI_FMP_DEP_PUSH_VERSION: + Depex +=3D sizeof (UINT32) + 1; + break; + case EFI_FMP_DEP_VERSION_STR: + Depex +=3D AsciiStrnLenS ((CHAR8 *) Depex, ImageDepex->Dependencies = + MaxDepexSize - Depex) + 1; + break; + case EFI_FMP_DEP_AND: + case EFI_FMP_DEP_OR: + case EFI_FMP_DEP_NOT: + case EFI_FMP_DEP_TRUE: + case EFI_FMP_DEP_FALSE: + case EFI_FMP_DEP_EQ: + case EFI_FMP_DEP_GT: + case EFI_FMP_DEP_GTE: + case EFI_FMP_DEP_LT: + case EFI_FMP_DEP_LTE: + Depex +=3D 1; + break; + case EFI_FMP_DEP_END: + Depex +=3D 1; + *DepexSize =3D (UINT32)(Depex - ImageDepex->Dependencies); + return TRUE; + default: + return FALSE; + } + } + + return FALSE; +} + + +/** + Get the size of dependencies. Assume the dependencies is validated before + calling this function. + + @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP. + + @retval The size of dependencies. + +**/ +UINTN +GetDepexSize ( + IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies + ) +{ + UINTN Index; + + if (Dependencies =3D=3D NULL) { + return 0; + } + + Index =3D 0; + while (Dependencies->Dependencies[Index] !=3D EFI_FMP_DEP_END) { + Index ++; + } + + return Index + 1; +} + +/** + Check dependency for firmware update. + + @param[in] ImageTypeId Image Type Id. + @param[in] Version New version. + @param[in] Dependencies The dependencies. + @param[in] DependenciesSize Size of the dependencies + @param[out] IsSatisfied Indicate the dependencies is satisfied = or not. + + @retval EFI_SUCCESS Dependency Evaluation is successful. + @retval Others Dependency Evaluation fails with unexpe= cted error. + +**/ +EFI_STATUS +EvaluateImageDependencies ( + IN CONST EFI_GUID ImageTypeId, + IN CONST UINT32 Version, + IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies, + IN CONST UINT32 DependenciesSize, + OUT BOOLEAN *IsSatisfied + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN Index; + EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp; + UINTN ImageInfoSize; + UINT32 FmpImageInfoDescriptorVer; + UINT8 FmpImageInfoCount; + UINTN DescriptorSize; + UINT32 PackageVersion; + CHAR16 *PackageVersionName; + UINTN DepexSize; + + *IsSatisfied =3D TRUE; + PackageVersionName =3D NULL; + + // + // Get ImageDescriptors of all FMP instances, and archive them for depex= evaluation. + // + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareManagementProtocolGuid, + NULL, + &mNumberOfFmpInstance, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + mFmpImageInfoBuf =3D AllocatePool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR = *) * mNumberOfFmpInstance); + if (mFmpImageInfoBuf =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++) { + Status =3D gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiFirmwareManagementProtocolGuid, + (VOID **) &Fmp + ); + if (EFI_ERROR(Status)) { + continue; + } + + ImageInfoSize =3D 0; + Status =3D Fmp->GetImageInfo ( + Fmp, + &ImageInfoSize, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + ); + if (Status !=3D EFI_BUFFER_TOO_SMALL) { + continue; + } + + mFmpImageInfoBuf[Index] =3D AllocateZeroPool (ImageInfoSize); + if (mFmpImageInfoBuf[Index] =3D=3D NULL) { + continue; + } + + Status =3D Fmp->GetImageInfo ( + Fmp, + &ImageInfoSize, // ImageInfoSize + mFmpImageInfoBuf[Index], // ImageInfo + &FmpImageInfoDescriptorVer, // DescriptorVersion + &FmpImageInfoCount, // DescriptorCount + &DescriptorSize, // DescriptorSize + &PackageVersion, // PackageVersion + &PackageVersionName // PackageVersionName + ); + if (EFI_ERROR(Status)) { + FreePool (mFmpImageInfoBuf[Index]); + mFmpImageInfoBuf[Index] =3D NULL; + continue; + } + + if (PackageVersionName !=3D NULL) { + FreePool (PackageVersionName); + PackageVersionName =3D NULL; + } + } + + // + // Step 1 - Evaluate firmware image's depex, against the version of othe= r Fmp instances. + // + if (Dependencies !=3D NULL) { + *IsSatisfied =3D EvaluateDependencies (Dependencies, DependenciesSize); + } + + if (!*IsSatisfied) { + goto cleanup; + } + + // + // Step 2 - Evaluate the depex of all other Fmp instances, against the n= ew version in + // the firmware image. + // + + // + // Update the new version to mFmpImageInfoBuf. + // + for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++) { + if (mFmpImageInfoBuf[Index] !=3D NULL) { + if (CompareGuid (&ImageTypeId, &mFmpImageInfoBuf[Index]->ImageTypeId= )) { + mFmpImageInfoBuf[Index]->Version =3D Version; + break; + } + } + } + + // + // Evaluate the Dependencies one by one. + // + for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++) { + if (mFmpImageInfoBuf[Index] !=3D NULL) { + // + // Skip the Fmp instance to be "SetImage". + // + if (CompareGuid (&ImageTypeId, &mFmpImageInfoBuf[Index]->ImageTypeId= )) { + continue; + } + if ((mFmpImageInfoBuf[Index]->AttributesSupported & IMAGE_ATTRIBUTE_= DEPENDENCY) && + mFmpImageInfoBuf[Index]->Dependencies !=3D NULL) { + // + // Get the size of depex. + // Assume that the dependencies in EFI_FIRMWARE_IMAGE_DESCRIPTOR i= s validated when PopulateDescriptor(). + // + DepexSize =3D GetDepexSize (mFmpImageInfoBuf[Index]->Dependencies); + if (DepexSize > 0) { + *IsSatisfied =3D EvaluateDependencies (mFmpImageInfoBuf[Index]->= Dependencies, DepexSize); + if (!*IsSatisfied) { + break; + } + } + } + } + } + +cleanup: + if (mFmpImageInfoBuf !=3D NULL) { + for (Index =3D 0; Index < mNumberOfFmpInstance; Index ++) { + if (mFmpImageInfoBuf[Index] !=3D NULL) { + FreePool (mFmpImageInfoBuf[Index]); + } + } + FreePool (mFmpImageInfoBuf); + } + + return EFI_SUCCESS; +} diff --git a/FmpDevicePkg/FmpDxe/Dependency.h b/FmpDevicePkg/FmpDxe/Depende= ncy.h new file mode 100644 index 0000000000..a2aaaceeae --- /dev/null +++ b/FmpDevicePkg/FmpDxe/Dependency.h @@ -0,0 +1,63 @@ +/** @file + Fmp Capsule Dependency support functions for Firmware Management Protoco= l based + firmware updates. + + Copyright (c) 2020, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __DEPENDENCY_H__ +#define __DEPENDENCY_H__ + +#include +#include + +#define DEPENDENCIES_SATISFIED 0 +#define DEPENDENCIES_UNSATISFIED 1 +#define DEPENDENCIES_INVALID 2 + +extern UINT8 mDependenciesCheckStatus; + +/** + Validate the dependency expression and output its size. + + @param[in] ImageDepex Pointer to the EFI_FIRMWARE_IMAGE_DEP. + @param[in] MaxDepexSize Max size of the dependency. + @param[out] DepexSize Size of dependency. + + @retval TRUE The capsule is valid. + @retval FALSE The capsule is invalid. + +**/ +BOOLEAN +ValidateImageDepex ( + IN EFI_FIRMWARE_IMAGE_DEP *ImageDepex, + IN CONST UINTN MaxDepexSize, + OUT UINT32 *DepexSize + ); + +/** + Check dependency for firmware update. + + @param[in] ImageTypeId Image Type Id. + @param[in] Version New version. + @param[in] Dependencies The dependencies. + @param[in] DepexSize Size of the dependencies + @param[out] IsSatisfied Indicate the dependencies is satisfied = or not. + + @retval EFI_SUCCESS Dependency Evaluation is successful. + @retval Others Dependency Evaluation fails with unexpe= cted error. + +**/ +EFI_STATUS +EvaluateImageDependencies ( + IN CONST EFI_GUID ImageTypeId, + IN CONST UINT32 Version, + IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies, + IN CONST UINT32 DependenciesSize, + OUT BOOLEAN *IsSatisfied + ); + +#endif diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c index fe465af11e..aa92331966 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.c +++ b/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -2,18 +2,19 @@ Produces a Firmware Management Protocol that supports updates to a firmw= are image stored in a firmware device with platform and firmware device spec= ific information provided through PCDs and libraries. =20 Copyright (c) 2016, Microsoft Corporation. All rights reserved.
- Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
+ Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 **/ =20 #include "FmpDxe.h" #include "VariableSupport.h" +#include "Dependency.h" =20 /// /// FILE_GUID from FmpDxe.inf. When FmpDxe.inf is used in a platform, the /// FILE_GUID must always be overridden in the section to provide /// the ESRT GUID value associated with the updatable firmware image. A @@ -273,10 +274,17 @@ VOID PopulateDescriptor ( FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private ) { EFI_STATUS Status; + VOID *Image; + UINTN ImageSize; + BOOLEAN IsDepexValid; + UINT32 DepexSize; + + Image =3D NULL; + ImageSize =3D 0; =20 if (Private->DescriptorPopulated) { return; } =20 @@ -376,11 +384,51 @@ PopulateDescriptor ( } =20 Private->Descriptor.LastAttemptVersion =3D GetLastAttemptVersionFromVari= able (Private); Private->Descriptor.LastAttemptStatus =3D GetLastAttemptStatusFromVaria= ble (Private); =20 + // + // Get the dependency from the FmpDeviceLib and populate it to the descr= iptor. + // + Private->Descriptor.Dependencies =3D NULL; + + // + // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY + // + if (Private->Descriptor.AttributesSupported & IMAGE_ATTRIBUTE_DEPENDENCY= ) { + // + // The parameter "Image" of FmpDeviceGetImage() is extended to contain= the dependency. + // Get the dependency from the Image. + // + ImageSize =3D Private->Descriptor.Size; + Image =3D AllocatePool (ImageSize); + if (Image !=3D NULL) { + Status =3D FmpDeviceGetImage (Image, &ImageSize); + if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { + FreePool (Image); + Image =3D AllocatePool (ImageSize); + if (Image !=3D NULL) { + Status =3D FmpDeviceGetImage (Image, &ImageSize); + } + } + } + if (!EFI_ERROR (Status) && Image !=3D NULL) { + IsDepexValid =3D ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP *) Imag= e, ImageSize, &DepexSize); + if (IsDepexValid =3D=3D TRUE) { + Private->Descriptor.Dependencies =3D AllocatePool (DepexSize); + if (Private->Descriptor.Dependencies !=3D NULL) { + CopyMem (Private->Descriptor.Dependencies->Dependencies, Image, = DepexSize); + } + } + } + } + Private->DescriptorPopulated =3D TRUE; + + if (Image !=3D NULL) { + FreePool (Image); + } } =20 /** Returns information about the current firmware image(s) of the device. =20 @@ -538,16 +586,21 @@ GetTheImage ( ) { EFI_STATUS Status; FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private; UINTN Size; + UINT8 *ImageBuffer; + UINTN ImageBufferSize; + UINT32 DepexSize; =20 if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) { return EFI_UNSUPPORTED; } =20 - Status =3D EFI_SUCCESS; + Status =3D EFI_SUCCESS; + ImageBuffer =3D NULL; + DepexSize =3D 0; =20 // // Retrieve the private context structure // Private =3D FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This); @@ -573,12 +626,49 @@ GetTheImage ( // Status =3D FmpDeviceGetSize (&Size); if (EFI_ERROR (Status)) { Size =3D 0; } - if (*ImageSize < Size) { - *ImageSize =3D Size; + + // + // The parameter "Image" of FmpDeviceGetImage() is extended to contain t= he dependency. + // Get the Fmp Payload from the Image. + // + ImageBufferSize =3D Size; + ImageBuffer =3D AllocatePool (ImageBufferSize); + if (ImageBuffer =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - AllocatePool fails.\n",= mImageIdName)); + Status =3D EFI_NOT_FOUND; + goto cleanup; + } + Status =3D FmpDeviceGetImage (ImageBuffer, &ImageBufferSize); + if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { + FreePool (ImageBuffer); + ImageBuffer =3D AllocatePool (ImageBufferSize); + if (ImageBuffer =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - AllocatePool fails.\n= ", mImageIdName)); + Status =3D EFI_NOT_FOUND; + goto cleanup; + } + Status =3D FmpDeviceGetImage (ImageBuffer, &ImageBufferSize); + } + if (EFI_ERROR (Status)) { + goto cleanup; + } + + // + // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY + // + if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { + // + // Validate the dependency to get its size. + // + ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP *) ImageBuffer, ImageBuffe= rSize, &DepexSize); + } + + if (*ImageSize < ImageBufferSize - DepexSize) { + *ImageSize =3D ImageBufferSize - DepexSize; DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): GetImage() - ImageSize is to small= .\n", mImageIdName)); Status =3D EFI_BUFFER_TOO_SMALL; goto cleanup; } =20 @@ -586,12 +676,21 @@ GetTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - Image Pointer Parameter= is NULL.\n", mImageIdName)); Status =3D EFI_INVALID_PARAMETER; goto cleanup; } =20 - Status =3D FmpDeviceGetImage (Image, ImageSize); + // + // Image is after the dependency expression. + // + *ImageSize =3D ImageBufferSize - DepexSize; + CopyMem (Image, ImageBuffer + DepexSize, *ImageSize); + Status =3D EFI_SUCCESS; + cleanup: + if (ImageBuffer !=3D NULL) { + FreePool (ImageBuffer); + } =20 return Status; } =20 /** @@ -708,18 +807,24 @@ CheckTheImage ( UINT32 Index; VOID *PublicKeyData; UINTN PublicKeyDataLength; UINT8 *PublicKeyDataXdr; UINT8 *PublicKeyDataXdrEnd; + EFI_FIRMWARE_IMAGE_DEP *Dependencies; + UINT32 DependenciesSize; + BOOLEAN IsDepexValid; + BOOLEAN IsDepexSatisfied; =20 Status =3D EFI_SUCCESS; RawSize =3D 0; FmpPayloadHeader =3D NULL; FmpPayloadSize =3D 0; Version =3D 0; FmpHeaderSize =3D 0; AllHeaderSize =3D 0; + Dependencies =3D NULL; + DependenciesSize =3D 0; =20 if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) { return EFI_UNSUPPORTED; } =20 @@ -840,14 +945,37 @@ CheckTheImage ( Status =3D EFI_ABORTED; goto cleanup; } Status =3D GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadSize,= &Version); if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadHeade= rVersion failed %r.\n", mImageIdName, Status)); - *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; - Status =3D EFI_SUCCESS; - goto cleanup; + // + // Check if there is dependency expression + // + IsDepexValid =3D ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP*) FmpPayl= oadHeader, FmpPayloadSize, &DependenciesSize); + if (IsDepexValid && (DependenciesSize < FmpPayloadSize)) { + // + // Fmp payload is after dependency expression + // + Dependencies =3D (EFI_FIRMWARE_IMAGE_DEP*) FmpPayloadHeader; + FmpPayloadHeader =3D (UINT8 *) Dependencies + DependenciesSize; + FmpPayloadSize =3D FmpPayloadSize - DependenciesSize; + Status =3D GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadS= ize, &Version); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadH= eaderVersion failed %r.\n", mImageIdName, Status)); + *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; + Status =3D EFI_SUCCESS; + goto cleanup; + } + } else { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency is in= valid.\n", mImageIdName)); + mDependenciesCheckStatus =3D DEPENDENCIES_INVALID; + *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; + Status =3D EFI_SUCCESS; + goto cleanup; + } + } else { + DEBUG ((DEBUG_WARN, "FmpDxe(%s): CheckTheImage() - No dependency assoc= iated in image.\n", mImageIdName)); } =20 // // Check the lowest supported version // @@ -860,10 +988,26 @@ CheckTheImage ( *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID_OLD; Status =3D EFI_SUCCESS; goto cleanup; } =20 + // + // Evaluate dependency expression + // + Status =3D EvaluateImageDependencies (Private->Descriptor.ImageTypeId, V= ersion, Dependencies, DependenciesSize, &IsDepexSatisfied); + if (!IsDepexSatisfied || EFI_ERROR (Status)) { + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check= failed %r.\n", mImageIdName, Status)); + } else { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency is no= t satisfied.\n", mImageIdName)); + } + mDependenciesCheckStatus =3D DEPENDENCIES_UNSATISFIED; + *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; + Status =3D EFI_SUCCESS; + goto cleanup; + } + // // Get the FmpHeaderSize so we can determine the real payload size // Status =3D GetFmpPayloadHeaderSize (FmpPayloadHeader, FmpPayloadSize, &F= mpHeaderSize); if (EFI_ERROR (Status)) { @@ -875,11 +1019,11 @@ CheckTheImage ( =20 // // Call FmpDevice Lib Check Image on the // Raw payload. So all headers need stripped off // - AllHeaderSize =3D GetAllHeaderSize ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION = *)Image, FmpHeaderSize ); + AllHeaderSize =3D GetAllHeaderSize ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION = *)Image, FmpHeaderSize + DependenciesSize); if (AllHeaderSize =3D=3D 0) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetAllHeaderSize f= ailed.\n", mImageIdName)); Status =3D EFI_ABORTED; goto cleanup; } @@ -965,20 +1109,29 @@ SetTheImage ( UINT32 AllHeaderSize; UINT32 IncomingFwVersion; UINT32 LastAttemptStatus; UINT32 Version; UINT32 LowestSupportedVersion; + EFI_FIRMWARE_IMAGE_DEP *Dependencies; + UINT32 DependenciesSize; + BOOLEAN IsDepexValid; + UINT8 *ImageBuffer; + UINTN ImageBufferSize; =20 Status =3D EFI_SUCCESS; Updateable =3D 0; BooleanValue =3D FALSE; FmpHeaderSize =3D 0; FmpHeader =3D NULL; FmpPayloadSize =3D 0; AllHeaderSize =3D 0; - IncomingFwVersion =3D 0; + IncomingFwVersion =3D 0; LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; + Dependencies =3D NULL; + DependenciesSize =3D 0; + ImageBuffer =3D NULL; + ImageBufferSize =3D 0; =20 if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) { return EFI_UNSUPPORTED; } =20 @@ -1006,10 +1159,15 @@ SetTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Device is already lo= cked. Can't update.\n", mImageIdName)); Status =3D EFI_UNSUPPORTED; goto cleanup; } =20 + // + // Set check status to satisfied before CheckTheImage() + // + mDependenciesCheckStatus =3D DEPENDENCIES_SATISFIED; + // // Call check image to verify the image // Status =3D CheckTheImage (This, ImageIndex, Image, ImageSize, &Updateabl= e); if (EFI_ERROR (Status)) { @@ -1029,10 +1187,25 @@ SetTheImage ( DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetFmpHeader failed.= \n", mImageIdName)); Status =3D EFI_ABORTED; goto cleanup; } Status =3D GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &Incom= ingFwVersion); + if (EFI_ERROR (Status)) { + // + // Check if there is dependency expression + // + IsDepexValid =3D ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP*) FmpHead= er, FmpPayloadSize, &DependenciesSize); + if (IsDepexValid && (DependenciesSize < FmpPayloadSize)) { + // + // Fmp payload is after dependency expression + // + Dependencies =3D (EFI_FIRMWARE_IMAGE_DEP*) FmpHeader; + FmpHeader =3D (UINT8 *) FmpHeader + DependenciesSize; + FmpPayloadSize =3D FmpPayloadSize - DependenciesSize; + Status =3D GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &I= ncomingFwVersion); + } + } if (!EFI_ERROR (Status)) { // // Set to actual value // SetLastAttemptVersionInVariable (Private, IncomingFwVersion); @@ -1043,10 +1216,15 @@ SetTheImage ( DEBUG ( (DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Check The Image returned that the Image= was not valid for update. Updatable value =3D 0x%X.\n", mImageIdName, Updateable) ); + if (mDependenciesCheckStatus =3D=3D DEPENDENCIES_UNSATISFIED) { + LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDEN= CIES; + } else if (mDependenciesCheckStatus =3D=3D DEPENDENCIES_INVALID) { + LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT; + } Status =3D EFI_ABORTED; goto cleanup; } =20 if (Progress =3D=3D NULL) { @@ -1136,28 +1314,56 @@ SetTheImage ( if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetFmpPayloadHeaderS= ize failed %r.\n", mImageIdName, Status)); goto cleanup; } =20 - AllHeaderSize =3D GetAllHeaderSize ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION = *)Image, FmpHeaderSize ); + AllHeaderSize =3D GetAllHeaderSize ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *= )Image, FmpHeaderSize + DependenciesSize); if (AllHeaderSize =3D=3D 0) { DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetAllHeaderSize fai= led.\n", mImageIdName)); Status =3D EFI_ABORTED; goto cleanup; } =20 + // + // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY + // + if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) { + // + // To support saving dependency, extend param "Image" of FmpDeviceSetI= mage() to + // contain the dependency inside. FmpDeviceSetImage() is responsible f= or saving + // the dependency which can be used for future dependency check. + // + ImageBufferSize =3D DependenciesSize + ImageSize - AllHeaderSize; + ImageBuffer =3D AllocatePool (ImageBufferSize); + if (ImageBuffer =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - AllocatePool faile= d.\n", mImageIdName)); + Status =3D EFI_ABORTED; + goto cleanup; + } + CopyMem (ImageBuffer, Dependencies->Dependencies, DependenciesSize); + CopyMem (ImageBuffer + DependenciesSize, (UINT8 *)Image + AllHeaderSiz= e, ImageBufferSize - DependenciesSize); + } else { + ImageBufferSize =3D ImageSize - AllHeaderSize; + ImageBuffer =3D AllocateCopyPool(ImageBufferSize, (UINT8 *)Image + All= HeaderSize); + if (ImageBuffer =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - AllocatePool faile= d.\n", mImageIdName)); + Status =3D EFI_ABORTED; + goto cleanup; + } + } + // // Indicate that control is handed off to FmpDeviceLib // Progress (5); =20 // //Copy the requested image to the firmware using the FmpDeviceLib // Status =3D FmpDeviceSetImage ( - (((UINT8 *)Image) + AllHeaderSize), - ImageSize - AllHeaderSize, + ImageBuffer, + ImageBufferSize, VendorCode, FmpDxeProgress, IncomingFwVersion, AbortReason ); @@ -1190,10 +1396,14 @@ SetTheImage ( SetLowestSupportedVersionInVariable (Private, LowestSupportedVersion); =20 LastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; =20 cleanup: + if (ImageBuffer !=3D NULL) { + FreePool (ImageBuffer); + } + mProgressFunc =3D NULL; SetLastAttemptStatusInVariable (Private, LastAttemptStatus); =20 if (Progress !=3D NULL) { // diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.inf b/FmpDevicePkg/FmpDxe/FmpDxe.inf index bec73aa8fb..97b6518fa1 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxe.inf +++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf @@ -2,11 +2,11 @@ # Produces a Firmware Management Protocol that supports updates to a firm= ware # image stored in a firmware device with platform and firmware device spe= cific # information provided through PCDs and libraries. # # Copyright (c) 2016, Microsoft Corporation. All rights reserved.
-# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent ## =20 [Defines] @@ -26,10 +26,12 @@ # =20 [Sources] FmpDxe.c FmpDxe.h + Dependency.c + Dependency.h DetectTestKey.c VariableSupport.h VariableSupport.c =20 [Packages] diff --git a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf b/FmpDevicePkg/FmpDxe/FmpDxe= Lib.inf index edc0cd66c1..de005b6892 100644 --- a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf +++ b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf @@ -2,11 +2,11 @@ # Produces a Firmware Management Protocol that supports updates to a firm= ware # image stored in a firmware device with platform and firmware device spe= cific # information provided through PCDs and libraries. # # Copyright (c) 2016, Microsoft Corporation. All rights reserved.
-# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent ## =20 [Defines] @@ -27,10 +27,12 @@ # =20 [Sources] FmpDxe.c FmpDxe.h + Dependency.c + Dependency.h DetectTestKey.c VariableSupport.h VariableSupport.c =20 [Packages] --=20 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#53127): https://edk2.groups.io/g/devel/message/53127 Mute This Topic: https://groups.io/mt/69595653/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-