REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1525

* Add Capsule Update Policy Protocol to FmpDevicePkg
* Add CapsuleUpdatePolicyLib instance that uses the services
  of the Capsule Update Policy Protocol
* Add module that produces the Capsule Update Policy
  Protocol using the services of the CapsuleUpdatePolicyLib
  class.
* Update FmpDevicePkg DSC to build the new library instance
  and the new module and update builds of FmpDxe modules
  to demonstrate the use of the different CapsuleUpdatePolicyLib
  instances.

Cc: Sean Brogan <sean.bro...@microsoft.com>
Cc: Bret Barkelew <bret.barke...@microsoft.com>
Cc: Liming Gao <liming....@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kin...@intel.com>
Signed-off-by: Wang Fan <fan.w...@intel.com>
Reviewed-by: Eric Jin <eric....@intel.com>
---
 .../CapsuleUpdatePolicyDxe.c                  | 173 ++++++++++++++++++
 .../CapsuleUpdatePolicyDxe.h                  | 140 ++++++++++++++
 .../CapsuleUpdatePolicyDxe.inf                |  48 +++++
 .../CapsuleUpdatePolicyDxe.uni                |  14 ++
 .../CapsuleUpdatePolicyDxeExtra.uni           |  14 ++
 FmpDevicePkg/FmpDevicePkg.dec                 |  26 ++-
 FmpDevicePkg/FmpDevicePkg.dsc                 |  21 ++-
 .../CapsuleUpdatePolicyLibOnProtocol.c        | 171 +++++++++++++++++
 .../CapsuleUpdatePolicyLibOnProtocol.inf      |  40 ++++
 .../CapsuleUpdatePolicyLibOnProtocol.uni      |  15 ++
 .../Library/FmpPayloadHeaderLib.h             |   0
 .../Protocol/CapsuleUpdatePolicy.h            | 132 +++++++++++++
 12 files changed, 784 insertions(+), 10 deletions(-)
 create mode 100644 FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.c
 create mode 100644 FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.h
 create mode 100644 
FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.inf
 create mode 100644 
FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.uni
 create mode 100644 
FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxeExtra.uni
 create mode 100644 
FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.c
 create mode 100644 
FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf
 create mode 100644 
FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.uni
 rename FmpDevicePkg/{Include => PrivateInclude}/Library/FmpPayloadHeaderLib.h 
(100%)
 create mode 100644 FmpDevicePkg/PrivateInclude/Protocol/CapsuleUpdatePolicy.h

diff --git a/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.c 
b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.c
new file mode 100644
index 0000000000..d2571fd0e6
--- /dev/null
+++ b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.c
@@ -0,0 +1,173 @@
+/** @file
+  Provides platform policy services used during a capsule update that uses the
+  services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CapsuleUpdatePolicyDxe.h"
+
+///
+/// Handle for the Capsule Update Policy Protocol
+///
+EFI_HANDLE  mHandle = NULL;
+
+///
+/// Capsule Update Policy Protocol instance
+///
+EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  mCapsuleUpdatePolicy = {
+  CapsuleUpdatePolicyCheckSystemPower,
+  CapsuleUpdatePolicyCheckSystemThermal,
+  CapsuleUpdatePolicyCheckSystemEnvironment,
+  CapsuleUpdatePolicyIsLowestSupportedVersionCheckRequired,
+  CapsuleUpdatePolicyIsLockFmpDeviceAtLockEventGuidRequired
+};
+
+/**
+  Determine if the system power state supports a capsule update.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+  @param[out] Good  Returns TRUE if system power state supports a capsule
+                    update.  Returns FALSE if system power state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System power state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemPower (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This,
+  OUT BOOLEAN                               *Good
+  )
+{
+  return CheckSystemPower (Good);
+}
+
+
+/**
+  Determines if the system thermal state supports a capsule update.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+  @param[out] Good  Returns TRUE if system thermal state supports a capsule
+                    update.  Returns FALSE if system thermal state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System thermal state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemThermal (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This,
+  OUT BOOLEAN                               *Good
+  )
+{
+  return CheckSystemThermal (Good);
+}
+
+/**
+  Determines if the system environment state supports a capsule update.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+  @param[out] Good  Returns TRUE if system environment state supports a capsule
+                    update.  Returns FALSE if system environment state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System environment state can not be 
determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemEnvironment (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This,
+  OUT BOOLEAN                               *Good
+  )
+{
+  return CheckSystemEnvironment (Good);
+}
+
+/**
+  Determines if the Lowest Supported Version checks should be performed.  The
+  expected result from this function is TRUE.  A platform can choose to return
+  FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+  version below the current Lowest Supported Version.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+
+  @retval TRUE   The lowest supported version check is required.
+  @retval FALSE  Do not perform lowest support version check.
+
+**/
+BOOLEAN
+EFIAPI
+CapsuleUpdatePolicyIsLowestSupportedVersionCheckRequired (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This
+  )
+{
+  return IsLowestSupportedVersionCheckRequired ();
+}
+
+/**
+  Determines if the FMP device should be locked when the event specified by
+  PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+  is TRUE so the FMP device is always locked.  A platform can choose to return
+  FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+
+  @retval TRUE   The FMP device lock action is required at lock event guid.
+  @retval FALSE  Do not perform FMP device lock at lock event guid.
+
+**/
+BOOLEAN
+EFIAPI
+CapsuleUpdatePolicyIsLockFmpDeviceAtLockEventGuidRequired (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This
+  )
+{
+  return IsLockFmpDeviceAtLockEventGuidRequired ();
+}
+
+/**
+  The user Entry Point for module CapsuleUpdatePolicyDxe. The user code starts
+  with this function.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, 
&gEdkiiCapuleUpdatePolicyProtocolGuid);
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mHandle,
+                  &gEdkiiCapuleUpdatePolicyProtocolGuid, &mCapsuleUpdatePolicy,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.h 
b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.h
new file mode 100644
index 0000000000..1be15a40db
--- /dev/null
+++ b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.h
@@ -0,0 +1,140 @@
+/** @file
+  Provides platform policy services used during a capsule update that uses the
+  services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __CAPSULE_UPDATE_POLICY_DXE_H__
+#define __CAPSULE_UPDATE_POLICY_DXE_H__
+
+#include <PiDxe.h>
+
+#include <Protocol/CapsuleUpdatePolicy.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/CapsuleUpdatePolicyLib.h>
+
+/**
+  Determine if the system power state supports a capsule update.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+  @param[out] Good  Returns TRUE if system power state supports a capsule
+                    update.  Returns FALSE if system power state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System power state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemPower (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This,
+  OUT BOOLEAN                               *Good
+  );
+
+/**
+  Determines if the system thermal state supports a capsule update.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+  @param[out] Good  Returns TRUE if system thermal state supports a capsule
+                    update.  Returns FALSE if system thermal state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System thermal state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemThermal (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This,
+  OUT BOOLEAN                               *Good
+  );
+
+/**
+  Determines if the system environment state supports a capsule update.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+  @param[out] Good  Returns TRUE if system environment state supports a capsule
+                    update.  Returns FALSE if system environment state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System environment state can not be 
determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemEnvironment (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This,
+  OUT BOOLEAN                               *Good
+  );
+
+/**
+  Determines if the Lowest Supported Version checks should be performed.  The
+  expected result from this function is TRUE.  A platform can choose to return
+  FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+  version below the current Lowest Supported Version.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+
+  @retval TRUE   The lowest supported version check is required.
+  @retval FALSE  Do not perform lowest support version check.
+
+**/
+BOOLEAN
+EFIAPI
+CapsuleUpdatePolicyIsLowestSupportedVersionCheckRequired (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This
+  );
+
+/**
+  Determines if the FMP device should be locked when the event specified by
+  PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+  is TRUE so the FMP device is always locked.  A platform can choose to return
+  FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+
+  @retval TRUE   The FMP device lock action is required at lock event guid.
+  @retval FALSE  Do not perform FMP device lock at lock event guid.
+
+**/
+BOOLEAN
+EFIAPI
+CapsuleUpdatePolicyIsLockFmpDeviceAtLockEventGuidRequired (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This
+  );
+
+/**
+  The user Entry Point for module CapsuleUpdatePolicyDxe. The user code starts
+  with this function.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  );
+
+#endif
diff --git a/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.inf 
b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.inf
new file mode 100644
index 0000000000..d168780eb9
--- /dev/null
+++ b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.inf
@@ -0,0 +1,48 @@
+## @file
+#  Produce the Capsule Update Policy Protocol using the services of the Capsule
+#  Update Policy Library.
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION     = 0x00010005
+  BASE_NAME       = CapsuleUpdatePolicyDxe
+  MODULE_UNI_FILE = CapsuleUpdatePolicyDxe.uni
+  FILE_GUID       = 86F67A12-2E32-44FC-8D6C-7901E2B5649A
+  MODULE_TYPE     = DXE_DRIVER
+  VERSION_STRING  = 1.0
+  ENTRY_POINT     = CapsuleUpdatePolicyInitialize
+
+#
+# The following information is for reference only and not required by the 
build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC
+#
+
+[Sources]
+  CapsuleUpdatePolicyDxe.c
+  CapsuleUpdatePolicyDxe.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  BaseLib
+  DebugLib
+  UefiBootServicesTableLib
+  CapsuleUpdatePolicyLib
+
+[Protocols]
+  gEdkiiCapuleUpdatePolicyProtocolGuid  ## PRODUCES
+
+[Depex]
+  TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  CapsuleUpdatePolicyDxeExtra.uni
diff --git a/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.uni 
b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.uni
new file mode 100644
index 0000000000..12f50c0f41
--- /dev/null
+++ b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Produce the Capsule Update Policy Protocol using the services of the Capsule
+// Update Policy Library.
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT             #language en-US "Produce the Capsule 
Update Policy Protocol using the services of the Capsule Update Policy Library"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Produce the Capsule 
Update Policy Protocol using the services of the Capsule Update Policy Library."
+
diff --git 
a/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxeExtra.uni 
b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxeExtra.uni
new file mode 100644
index 0000000000..46d8f34cff
--- /dev/null
+++ b/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxeExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// CapsuleUpdatePolicyDxe Localized Strings and Content
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Capsule Update Policy DXE Driver"
+
+
diff --git a/FmpDevicePkg/FmpDevicePkg.dec b/FmpDevicePkg/FmpDevicePkg.dec
index fb183cddff..c68dbb7153 100644
--- a/FmpDevicePkg/FmpDevicePkg.dec
+++ b/FmpDevicePkg/FmpDevicePkg.dec
@@ -7,7 +7,7 @@
 # customized using libraries and PCDs.
 #
 # Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
-# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
 #
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -23,15 +23,10 @@
 [Includes]
   Include
 
-[LibraryClasses]
-  ##  @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
-  #                  added to the FMP Payload Header, then new services may be
-  #                  added to this library class to retrieve the new 
information.
-  FmpPayloadHeaderLib|Include/Library/FmpPayloadHeaderLib.h
+[Includes.Common.Private]
+  PrivateInclude
 
+[LibraryClasses]
   ##  @libraryclass  Provides platform policy services used during a capsule
   #                  update.
   CapsuleUpdatePolicyLib|Include/Library/CapsuleUpdatePolicyLib.h
@@ -40,10 +35,23 @@
   #                  updates of a firmware image stored in a firmware device.
   FmpDeviceLib|Include/Library/FmpDeviceLib.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
+  #                  added to the FMP Payload Header, then new services may be
+  #                  added to this library class to retrieve the new 
information.
+  FmpPayloadHeaderLib|PrivateInclude/Library/FmpPayloadHeaderLib.h
+
 [Guids]
   ## Firmware Management Protocol Device Package Token Space GUID
   gFmpDevicePkgTokenSpaceGuid = { 0x40b2d964, 0xfe11, 0x40dc, { 0x82, 0x83, 
0x2e, 0xfb, 0xda, 0x29, 0x53, 0x56 } }
 
+[Protocols.Common.Private]
+  ## Capsule Update Policy Protocol
+  gEdkiiCapuleUpdatePolicyProtocolGuid = { 0x487784c5, 0x6299, 0x4ba6, { 0xb0, 
0x96, 0x5c, 0xc5, 0x27, 0x7c, 0xf7, 0x57 } }
+
 [PcdsFixedAtBuild]
   ## The SHA-256 hash of a PKCS7 test key that is used to detect if a test key
   #  is being used to authenticate capsules.  Test key detection is disabled by
diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index c9513135cb..3356571fff 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -7,7 +7,7 @@
 # customized using libraries and PCDs.
 #
 # Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
-# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
 #
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -71,6 +71,7 @@
   # Libraries
   #
   
FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+  
FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf
   FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
   FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf
   FmpDevicePkg/FmpDxe/FmpDxeLib.inf
@@ -78,12 +79,23 @@
   #
   # Modules
   #
+  FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.inf {
+    <LibraryClasses>
+      
CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+  }
   FmpDevicePkg/FmpDxe/FmpDxe.inf {
     <Defines>
       #
       # FILE_GUID is used as ESRT GUID
       #
       FILE_GUID = $(SYSTEM_FMP_ESRT_GUID)
+    <LibraryClasses>
+      #
+      # Use CapsuleUpdatePolicyLib that calls the Capsule Update Policy 
Protocol.
+      # Depends on the CapsuleUpdatePolicyDxe module to produce the protocol.
+      # Required for FmpDxe modules that are intended to be platform 
independent.
+      #
+      
CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf
   }
 
   FmpDevicePkg/FmpDxe/FmpDxe.inf {
@@ -92,6 +104,13 @@
       # FILE_GUID is used as ESRT GUID
       #
       FILE_GUID = $(DEVICE_FMP_ESRT_GUID)
+    <LibraryClasses>
+      #
+      # Directly use a platform specific CapsuleUpdatePolicyLib instance.
+      # Only works for FmpDxe modules that are build from sources and included
+      # in a system firmware image.
+      #
+      
CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
   }
 
 [BuildOptions]
diff --git 
a/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.c
 
b/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.c
new file mode 100644
index 0000000000..2c7c37fa92
--- /dev/null
+++ 
b/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.c
@@ -0,0 +1,171 @@
+/** @file
+  Provides platform policy services used during a capsule update that uses the
+  services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL. If the
+  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL is not available, then assume the
+  platform is in a state that supports a firmware update.
+
+  Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+  Copyright (c) 2018-2019, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/CapsuleUpdatePolicyLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/CapsuleUpdatePolicy.h>
+
+///
+/// Pointer to the EDK II Capsule Update Policy Protocol instances that is
+/// optionally installed by a platform.
+///
+EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *mCapsuleUpdatePolicy = NULL;
+
+/**
+  Lookup the EDK II Capsule Update Policy Protocol.
+**/
+BOOLEAN
+LookupCapsuleUpdatePolicyProtocol (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+
+  if (mCapsuleUpdatePolicy != NULL) {
+    return TRUE;
+  }
+  Status = gBS->LocateProtocol (
+                  &gEdkiiCapuleUpdatePolicyProtocolGuid,
+                  NULL,
+                  (VOID **)&mCapsuleUpdatePolicy
+                  );
+  if (EFI_ERROR (Status)) {
+    mCapsuleUpdatePolicy = NULL;
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Determine if the system power state supports a capsule update.
+
+  @param[out] Good  Returns TRUE if system power state supports a capsule
+                    update.  Returns FALSE if system power state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System power state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemPower (
+  OUT BOOLEAN  *Good
+  )
+{
+  if (LookupCapsuleUpdatePolicyProtocol ()) {
+    return mCapsuleUpdatePolicy->CheckSystemPower (mCapsuleUpdatePolicy, Good);
+  }
+  *Good = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  Determines if the system thermal state supports a capsule update.
+
+  @param[out] Good  Returns TRUE if system thermal state supports a capsule
+                    update.  Returns FALSE if system thermal state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System thermal state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemThermal (
+  OUT BOOLEAN   *Good
+  )
+{
+  if (LookupCapsuleUpdatePolicyProtocol ()) {
+    return mCapsuleUpdatePolicy->CheckSystemThermal (mCapsuleUpdatePolicy, 
Good);
+  }
+  *Good = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  Determines if the system environment state supports a capsule update.
+
+  @param[out] Good  Returns TRUE if system environment state supports a capsule
+                    update.  Returns FALSE if system environment state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System environment state can not be 
determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemEnvironment (
+  OUT BOOLEAN   *Good
+  )
+{
+  if (LookupCapsuleUpdatePolicyProtocol ()) {
+    return mCapsuleUpdatePolicy->CheckSystemEnvironment (mCapsuleUpdatePolicy, 
Good);
+  }
+  *Good = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  Determines if the Lowest Supported Version checks should be performed.  The
+  expected result from this function is TRUE.  A platform can choose to return
+  FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+  version below the current Lowest Supported Version.
+
+  @retval TRUE   The lowest supported version check is required.
+  @retval FALSE  Do not perform lowest support version check.
+
+**/
+BOOLEAN
+EFIAPI
+IsLowestSupportedVersionCheckRequired (
+  VOID
+  )
+{
+  if (LookupCapsuleUpdatePolicyProtocol ()) {
+    return mCapsuleUpdatePolicy->IsLowestSupportedVersionCheckRequired 
(mCapsuleUpdatePolicy);
+  }
+  return TRUE;
+}
+
+/**
+  Determines if the FMP device should be locked when the event specified by
+  PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+  is TRUE so the FMP device is always locked.  A platform can choose to return
+  FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+  @retval TRUE   The FMP device lock action is required at lock event guid.
+  @retval FALSE  Do not perform FMP device lock at lock event guid.
+
+**/
+BOOLEAN
+EFIAPI
+IsLockFmpDeviceAtLockEventGuidRequired (
+  VOID
+  )
+{
+  if (LookupCapsuleUpdatePolicyProtocol ()) {
+    return mCapsuleUpdatePolicy->IsLockFmpDeviceAtLockEventGuidRequired 
(mCapsuleUpdatePolicy);
+  }
+  return TRUE;
+}
diff --git 
a/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf
 
b/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf
new file mode 100644
index 0000000000..042daaabce
--- /dev/null
+++ 
b/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf
@@ -0,0 +1,40 @@
+## @file
+#  Provides platform policy services used during a capsule update that uses the
+#  services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL.  If the
+#  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL is not available, then assume the
+#  platform is in a state that supports a firmware update.
+#
+#  Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+#  Copyright (c) 2018-2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION     = 0x00010005
+  BASE_NAME       = CapsuleUpdatePolicyLibOnProtocol
+  MODULE_UNI_FILE = CapsuleUpdatePolicyLibOnProtocol.uni
+  FILE_GUID       = 0EA4C03F-D91B-4929-AAA5-B2FC8D69E2F4
+  MODULE_TYPE     = DXE_DRIVER
+  VERSION_STRING  = 1.0
+  LIBRARY_CLASS   = CapsuleUpdatePolicyLib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+  CapsuleUpdatePolicyLibOnProtocol.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  UefiBootServicesTableLib
+
+[Protocols]
+  gEdkiiCapuleUpdatePolicyProtocolGuid  ## CONSUMES
diff --git 
a/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.uni
 
b/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.uni
new file mode 100644
index 0000000000..58d0783126
--- /dev/null
+++ 
b/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.uni
@@ -0,0 +1,15 @@
+// /** @file
+// Provides platform policy services used during a capsule update that uses the
+// services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL.  If the
+// EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL is not available, then assume the
+// platform is in a state that supports a firmware update.
+//
+// Copyright (c) 2018-2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT     #language en-US  "Provides platform policy 
services used during a capsule update that uses the services of the 
EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL."
+
+#string STR_MODULE_DESCRIPTION  #language en-US  "Provides platform policy 
services used during a capsule update that uses the services of the 
EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL."
diff --git a/FmpDevicePkg/Include/Library/FmpPayloadHeaderLib.h 
b/FmpDevicePkg/PrivateInclude/Library/FmpPayloadHeaderLib.h
similarity index 100%
rename from FmpDevicePkg/Include/Library/FmpPayloadHeaderLib.h
rename to FmpDevicePkg/PrivateInclude/Library/FmpPayloadHeaderLib.h
diff --git a/FmpDevicePkg/PrivateInclude/Protocol/CapsuleUpdatePolicy.h 
b/FmpDevicePkg/PrivateInclude/Protocol/CapsuleUpdatePolicy.h
new file mode 100644
index 0000000000..871f0a1854
--- /dev/null
+++ b/FmpDevicePkg/PrivateInclude/Protocol/CapsuleUpdatePolicy.h
@@ -0,0 +1,132 @@
+/** @file
+  Provides platform policy services used during a capsule update.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __CAPSULE_UPDATE_POLICY_H__
+#define __CAPSULE_UPDATE_POLICY_H__
+
+#define EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL_GUID \
+  { \
+    0x487784c5, 0x6299, 0x4ba6, { 0xb0, 0x96, 0x5c, 0xc5, 0x27, 0x7c, 0xf7, 
0x57 } \
+  }
+
+typedef struct _EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  
EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL;
+
+/**
+  Determine if the system power state supports a capsule update.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+  @param[out] Good  Returns TRUE if system power state supports a capsule
+                    update.  Returns FALSE if system power state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System power state can not be determined.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_POWER) (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This,
+  OUT BOOLEAN                               *Good
+  );
+
+/**
+  Determines if the system thermal state supports a capsule update.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+  @param[out] Good  Returns TRUE if system thermal state supports a capsule
+                    update.  Returns FALSE if system thermal state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System thermal state can not be determined.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_THERMAL) (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This,
+  OUT BOOLEAN                               *Good
+  );
+
+/**
+  Determines if the system environment state supports a capsule update.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+  @param[out] Good  Returns TRUE if system environment state supports a capsule
+                    update.  Returns FALSE if system environment state does not
+                    support a capsule update.  Return value is only valid if
+                    return status is EFI_SUCCESS.
+
+  @retval EFI_SUCCESS            Good parameter has been updated with result.
+  @retval EFI_INVALID_PARAMETER  Good is NULL.
+  @retval EFI_DEVICE_ERROR       System environment state can not be 
determined.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_ENVIRONMENT) (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This,
+  OUT BOOLEAN                               *Good
+  );
+
+/**
+  Determines if the Lowest Supported Version checks should be performed.  The
+  expected result from this function is TRUE.  A platform can choose to return
+  FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+  version below the current Lowest Supported Version.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+
+  @retval TRUE   The lowest supported version check is required.
+  @retval FALSE  Do not perform lowest support version check.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI * 
EDKII_CAPSULE_UPDATE_POLICY_IS_LOWEST_SUPPORTED_VERSION_CHECK_REQUIRED) (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This
+  );
+
+/**
+  Determines if the FMP device should be locked when the event specified by
+  PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+  is TRUE so the FMP device is always locked.  A platform can choose to return
+  FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+  @param[in]  This  A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL 
instance.
+
+  @retval TRUE   The FMP device lock action is required at lock event guid.
+  @retval FALSE  Do not perform FMP device lock at lock event guid.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI * EDKII_CAPSULE_UPDATE_POLICY_IS_FMP_DEVICE_AT_LOCK_EVENT_REQUIRED) (
+  IN  EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL  *This
+  );
+
+///
+/// This protocol provides platform policy services used during a capsule 
update.
+///
+struct _EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL {
+  EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_POWER                          
CheckSystemPower;
+  EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_THERMAL                        
CheckSystemThermal;
+  EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_ENVIRONMENT                    
CheckSystemEnvironment;
+  EDKII_CAPSULE_UPDATE_POLICY_IS_LOWEST_SUPPORTED_VERSION_CHECK_REQUIRED  
IsLowestSupportedVersionCheckRequired;
+  EDKII_CAPSULE_UPDATE_POLICY_IS_FMP_DEVICE_AT_LOCK_EVENT_REQUIRED        
IsLockFmpDeviceAtLockEventGuidRequired;
+};
+
+extern EFI_GUID gEdkiiCapuleUpdatePolicyProtocolGuid;
+
+#endif
-- 
2.20.1.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#45337): https://edk2.groups.io/g/devel/message/45337
Mute This Topic: https://groups.io/mt/32836428/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to