From: "Xu, Wei6" <wei6.xu@intel.com>
To: devel@edk2.groups.io
Cc: Michael D Kinney <michael.d.kinney@intel.com>,
Liming Gao <liming.gao@intel.com>,
Sean Brogan <sean.brogan@microsoft.com>
Subject: [edk2-devel] [PATCH V4 3/5] FmpDevicePkg: Add FmpDependencyCheck library class and instances
Date: Fri, 15 May 2020 09:51:21 +0800 [thread overview]
Message-ID: <20200515015123.11484-4-wei6.xu@intel.com> (raw)
In-Reply-To: <20200515015123.11484-1-wei6.xu@intel.com>
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2696
* This library class provides platform specific services to support
dependency check during updating firmware image. Platform can perform
dependency check in platform specific manner by implementing its own
FmpDependencyCheckLib.
* Add FmpDependencyCheck instance to provide a sample of dependency
check. The sample instance only checks the dependency from capsule
image. The dependency from other FMP instances isn't checked here.
* Add NULL instance as an option to skip the dependency check.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
---
FmpDevicePkg/FmpDevicePkg.dec | 4 +
FmpDevicePkg/FmpDevicePkg.dsc | 3 +
.../Include/Library/FmpDependencyCheckLib.h | 38 ++++
.../FmpDependencyCheckLib/FmpDependencyCheckLib.c | 196 +++++++++++++++++++++
.../FmpDependencyCheckLib.inf | 43 +++++
.../FmpDependencyCheckLib.uni | 13 ++
.../FmpDependencyCheckLibNull.c | 34 ++++
.../FmpDependencyCheckLibNull.inf | 30 ++++
.../FmpDependencyCheckLibNull.uni | 13 ++
9 files changed, 374 insertions(+)
create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni
diff --git a/FmpDevicePkg/FmpDevicePkg.dec b/FmpDevicePkg/FmpDevicePkg.dec
index 4947008346..871d5ce890 100644
--- a/FmpDevicePkg/FmpDevicePkg.dec
+++ b/FmpDevicePkg/FmpDevicePkg.dec
@@ -37,10 +37,14 @@
## @libraryclass Provides generic services to support capsule dependency
# expression evaluation.
FmpDependencyLib|Include/Library/FmpDependencyLib.h
+ ## @libraryclass Provides platform specific services to support dependency
+ # check during update of firmware image.
+ FmpDependencyCheckLib|Include/Library/FmpDependencyCheckLib.h
+
[LibraryClasses.Common.Private]
## @libraryclass Provides services to retrieve values from a capsule's FMP
# Payload Header. The structure is not included in the
# library class. Instead, services are provided to retrieve
# information from the FMP Payload Header. If information is
diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index 49c6ff3a30..7e80806171 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -61,10 +61,11 @@
FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
FmpDeviceLib|FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf
FmpDependencyLib|FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf
+ FmpDependencyCheckLib|FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
# It is not possible to prevent the ARM compiler for generic intrinsic functions.
@@ -90,10 +91,12 @@
FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf
FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf
FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf
+ FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf
+ FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
FmpDevicePkg/FmpDxe/FmpDxeLib.inf
#
# Modules
#
diff --git a/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h b/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h
new file mode 100644
index 0000000000..ec380c4947
--- /dev/null
+++ b/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h
@@ -0,0 +1,38 @@
+/** @file
+ Fmp Capsule Dependency check functions for Firmware Management Protocol based
+ firmware updates.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FMP_DEPENDENCY_CHECK_LIB__
+#define __FMP_DEPENDENCY_CHECK_LIB__
+
+#include <PiDxe.h>
+#include <Protocol/FirmwareManagement.h>
+
+/**
+ Check dependency for firmware update.
+
+ @param[in] ImageTypeId Image Type Id.
+ @param[in] Version New version.
+ @param[in] Dependencies Fmp dependency.
+ @param[in] DependenciesSize Size, in bytes, of the Fmp dependency.
+
+ @retval TRUE Dependencies are satisfied.
+ @retval FALSE Dependencies are unsatisfied or dependency check fails.
+
+**/
+BOOLEAN
+EFIAPI
+CheckFmpDependency (
+ IN EFI_GUID ImageTypeId,
+ IN UINT32 Version,
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
+ IN UINT32 DependenciesSize
+ );
+
+#endif
diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c
new file mode 100644
index 0000000000..5e0241b259
--- /dev/null
+++ b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c
@@ -0,0 +1,196 @@
+/** @file
+ Provides FMP capsule dependency check services when updating the firmware
+ image of a FMP device.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FmpDependencyLib.h>
+#include <Library/FmpDependencyCheckLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Check dependency for firmware update.
+
+ @param[in] ImageTypeId Image Type Id.
+ @param[in] Version New version.
+ @param[in] Dependencies Fmp dependency.
+ @param[in] DependenciesSize Size, in bytes, of the Fmp dependency.
+
+ @retval TRUE Dependencies are satisfied.
+ @retval FALSE Dependencies are unsatisfied or dependency check fails.
+
+**/
+BOOLEAN
+EFIAPI
+CheckFmpDependency (
+ IN EFI_GUID ImageTypeId,
+ IN UINT32 Version,
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
+ IN UINT32 DependenciesSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
+ UINTN ImageInfoSize;
+ UINT32 *DescriptorVer;
+ UINT8 FmpImageInfoCount;
+ UINTN *DescriptorSize;
+ UINT32 PackageVersion;
+ CHAR16 *PackageVersionName;
+ UINTN NumberOfFmpInstance;
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR **FmpImageInfoBuf;
+ FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions;
+ UINTN FmpVersionsCount;
+ BOOLEAN IsSatisfied;
+
+ FmpImageInfoBuf = NULL;
+ DescriptorVer = NULL;
+ DescriptorSize = NULL;
+ NumberOfFmpInstance = 0;
+ FmpVersions = NULL;
+ FmpVersionsCount = 0;
+ IsSatisfied = TRUE;
+ PackageVersionName = NULL;
+
+ //
+ // Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareManagementProtocolGuid,
+ NULL,
+ &NumberOfFmpInstance,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status));
+ goto cleanup;
+ }
+
+ FmpImageInfoBuf = AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfFmpInstance);
+ if (FmpImageInfoBuf == NULL) {
+ IsSatisfied = FALSE;
+ goto cleanup;
+ }
+
+ DescriptorVer = AllocateZeroPool (sizeof(UINT32) * NumberOfFmpInstance);
+ if (DescriptorVer == NULL ) {
+ IsSatisfied = FALSE;
+ goto cleanup;
+ }
+
+ DescriptorSize = AllocateZeroPool (sizeof(UINTN) * NumberOfFmpInstance);
+ if (DescriptorSize == NULL ) {
+ IsSatisfied = FALSE;
+ goto cleanup;
+ }
+
+ FmpVersions = AllocateZeroPool (sizeof(FMP_DEPEX_CHECK_VERSION_DATA) * NumberOfFmpInstance);
+ if (FmpVersions == NULL) {
+ IsSatisfied = FALSE;
+ goto cleanup;
+ }
+
+ for (Index = 0; Index < NumberOfFmpInstance; Index ++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareManagementProtocolGuid,
+ (VOID **) &Fmp
+ );
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ ImageInfoSize = 0;
+ Status = Fmp->GetImageInfo (
+ Fmp,
+ &ImageInfoSize,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ );
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ continue;
+ }
+
+ FmpImageInfoBuf[Index] = AllocateZeroPool (ImageInfoSize);
+ if (FmpImageInfoBuf[Index] == NULL) {
+ continue;
+ }
+
+ Status = Fmp->GetImageInfo (
+ Fmp,
+ &ImageInfoSize, // ImageInfoSize
+ FmpImageInfoBuf[Index], // ImageInfo
+ &DescriptorVer[Index], // DescriptorVersion
+ &FmpImageInfoCount, // DescriptorCount
+ &DescriptorSize[Index], // DescriptorSize
+ &PackageVersion, // PackageVersion
+ &PackageVersionName // PackageVersionName
+ );
+ if (EFI_ERROR(Status)) {
+ FreePool (FmpImageInfoBuf[Index]);
+ FmpImageInfoBuf[Index] = NULL;
+ continue;
+ }
+
+ if (PackageVersionName != NULL) {
+ FreePool (PackageVersionName);
+ PackageVersionName = NULL;
+ }
+
+ CopyGuid (&FmpVersions[FmpVersionsCount].ImageTypeId, &FmpImageInfoBuf[Index]->ImageTypeId);
+ FmpVersions[FmpVersionsCount].Version = FmpImageInfoBuf[Index]->Version;
+ FmpVersionsCount ++;
+ }
+
+ //
+ // Evaluate firmware image's depex, against the version of other Fmp instances.
+ //
+ if (Dependencies != NULL) {
+ IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount);
+ }
+
+ if (!IsSatisfied) {
+ DEBUG ((DEBUG_ERROR, "CheckFmpDependency: %g\'s dependency is not satisfied!\n", ImageTypeId));
+ goto cleanup;
+ }
+
+cleanup:
+ if (FmpImageInfoBuf != NULL) {
+ for (Index = 0; Index < NumberOfFmpInstance; Index ++) {
+ if (FmpImageInfoBuf[Index] != NULL) {
+ FreePool (FmpImageInfoBuf[Index]);
+ }
+ }
+ FreePool (FmpImageInfoBuf);
+ }
+
+ if (DescriptorVer != NULL) {
+ FreePool (DescriptorVer);
+ }
+
+ if (DescriptorSize != NULL) {
+ FreePool (DescriptorSize);
+ }
+
+ if (FmpVersions != NULL) {
+ FreePool (FmpVersions);
+ }
+
+ return IsSatisfied;
+}
diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf
new file mode 100644
index 0000000000..2050cc6490
--- /dev/null
+++ b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Provides FMP capsule dependency check services when updating the firmware
+# image of a FMP device.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDependencyCheckLib
+ MODULE_UNI_FILE = FmpDependencyCheckLib.uni
+ FILE_GUID = 8296D425-3095-4CFE-88D8-B0A44DB174A8
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmpDependencyCheckLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDependencyCheckLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ FmpDependencyLib
+ MemoryAllocationLib
+ UefiLib
+ UefiBootServicesTableLib
+
+[Protocols]
+ gEfiFirmwareManagementProtocolGuid ## CONSUMES
diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni
new file mode 100644
index 0000000000..c6369e2277
--- /dev/null
+++ b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni
@@ -0,0 +1,13 @@
+// /** @file
+// Provides FMP capsule dependency check services when updating the firmware
+// image of a FMP device.
+//
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "FMP Dependency Check Lib"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides FMP capsule dependency check services when updating the firmware image of a FMP device."
diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c
new file mode 100644
index 0000000000..55e9af2290
--- /dev/null
+++ b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c
@@ -0,0 +1,34 @@
+/** @file
+ Null instance of FmpDependencyCheckLib.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiDxe.h>
+#include <Library/FmpDependencyCheckLib.h>
+
+/**
+ Check dependency for firmware update.
+
+ @param[in] ImageTypeId Image Type Id.
+ @param[in] Version New version.
+ @param[in] Dependencies Fmp dependency.
+ @param[in] DependenciesSize Size, in bytes, of the Fmp dependency.
+
+ @retval TRUE Dependencies are satisfied.
+ @retval FALSE Dependencies are unsatisfied or dependency check fails.
+
+**/
+BOOLEAN
+EFIAPI
+CheckFmpDependency (
+ IN EFI_GUID ImageTypeId,
+ IN UINT32 Version,
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
+ IN UINT32 DependenciesSize
+ )
+{
+ return TRUE;
+}
diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
new file mode 100644
index 0000000000..5794d89191
--- /dev/null
+++ b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
@@ -0,0 +1,30 @@
+## @file
+# Null instance of FmpDependencyCheckLib as an option to skip the dependency
+# check when updating the firmware image of a FMP device.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDependencyCheckLibNull
+ MODULE_UNI_FILE = FmpDependencyCheckLibNull.uni
+ FILE_GUID = D63F3166-9CBC-4AC2-8F23-8818E42EA2BD
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmpDependencyCheckLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDependencyCheckLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
diff --git a/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni
new file mode 100644
index 0000000000..7942d08f76
--- /dev/null
+++ b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni
@@ -0,0 +1,13 @@
+// /** @file
+// Null instance of FmpDependencyCheckLib as an option to skip the dependency
+// check when updating the firmware image of a FMP device.
+//
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "FMP Dependency Check Library NULL instance"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Null instance of FmpDependencyCheckLib as an option to skip the dependency check when updating the firmware image of a FMP device."
--
2.16.2.windows.1
next prev parent reply other threads:[~2020-05-15 1:51 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-15 1:51 [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 1/5] FmpDevicePkg: Add FmpDependency library class and BASE instance Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 2/5] FmpDevicePkg/Test: Add FmpDependencyLib unit test Xu, Wei6
2020-05-15 1:51 ` Xu, Wei6 [this message]
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 4/5] FmpDevicePkg: Add FmpDependencyDevice library class and NULL instance Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 5/5] FmpDevicePkg/FmpDxe: Use new Fmp dependency libraries Xu, Wei6
2020-05-15 3:01 ` [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Liming Gao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200515015123.11484-4-wei6.xu@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox