mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-07 19:45:07 +02:00
FmpDevicePkg/FmpDxe: Use new FmpDeviceLib APIs
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1525 Update FmpDxe to support multiple controllers and use new FmpDeviceLib APIs to support Stop/Unload and to set the context for the worker functions in the FmpDeviceLib. Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Cc: Liming Gao <liming.gao@intel.com> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Eric Jin <eric.jin@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
parent
a6ee24fbdd
commit
4f0544b144
@ -4,46 +4,13 @@
|
||||
information provided through PCDs and libraries.
|
||||
|
||||
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
|
||||
|
||||
**/
|
||||
|
||||
#include <PiDxe.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/FmpAuthenticationLib.h>
|
||||
#include <Library/FmpDeviceLib.h>
|
||||
#include <Library/FmpPayloadHeaderLib.h>
|
||||
#include <Library/CapsuleUpdatePolicyLib.h>
|
||||
#include <Protocol/FirmwareManagement.h>
|
||||
#include <Protocol/FirmwareManagementProgress.h>
|
||||
#include <Guid/SystemResourceTable.h>
|
||||
#include <Guid/EventGroup.h>
|
||||
#include "VariableSupport.h"
|
||||
|
||||
#define VERSION_STRING_NOT_SUPPORTED L"VERSION STRING NOT SUPPORTED"
|
||||
#define VERSION_STRING_NOT_AVAILABLE L"VERSION STRING NOT AVAILABLE"
|
||||
|
||||
/**
|
||||
Check to see if any of the keys in PcdFmpDevicePkcs7CertBufferXdr matches
|
||||
the test key. PcdFmpDeviceTestKeySha256Digest contains the SHA256 hash of
|
||||
the test key. For each key in PcdFmpDevicePkcs7CertBufferXdr, compute the
|
||||
SHA256 hash and compare it to PcdFmpDeviceTestKeySha256Digest. If the
|
||||
SHA256 hash matches or there is then error computing the SHA256 hash, then
|
||||
set PcdTestKeyUsed to TRUE. Skip this check if PcdTestKeyUsed is already
|
||||
TRUE or PcdFmpDeviceTestKeySha256Digest is not exactly SHA256_DIGEST_SIZE
|
||||
bytes.
|
||||
**/
|
||||
VOID
|
||||
DetectTestKey (
|
||||
VOID
|
||||
);
|
||||
#include "FmpDxe.h"
|
||||
|
||||
///
|
||||
/// FILE_GUID from FmpDxe.inf. When FmpDxe.inf is used in a platform, the
|
||||
@ -56,30 +23,73 @@ const EFI_GUID mDefaultModuleFileGuid = {
|
||||
0x78ef0a56, 0x1cf0, 0x4535, { 0xb5, 0xda, 0xf6, 0xfd, 0x2f, 0x40, 0x5a, 0x11 }
|
||||
};
|
||||
|
||||
EFI_FIRMWARE_IMAGE_DESCRIPTOR mDesc;
|
||||
BOOLEAN mDescriptorPopulated = FALSE;
|
||||
BOOLEAN mRuntimeVersionSupported = TRUE;
|
||||
BOOLEAN mFmpInstalled = FALSE;
|
||||
///
|
||||
/// TRUE if FmpDeviceLib manages a single firmware storage device.
|
||||
///
|
||||
BOOLEAN mFmpSingleInstance = FALSE;
|
||||
|
||||
///
|
||||
/// Function pointer to progress function
|
||||
/// Firmware Management Protocol instance that is initialized in the entry
|
||||
/// point from PCD settings.
|
||||
///
|
||||
EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS mProgressFunc = NULL;
|
||||
BOOLEAN mProgressSupported = FALSE;
|
||||
EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL mFmpProgress;
|
||||
|
||||
//
|
||||
// Template of the private context structure for the Firmware Management
|
||||
// Protocol instance
|
||||
//
|
||||
const FIRMWARE_MANAGEMENT_PRIVATE_DATA mFirmwareManagementPrivateDataTemplate = {
|
||||
FIRMWARE_MANAGEMENT_PRIVATE_DATA_SIGNATURE, // Signature
|
||||
NULL, // Handle
|
||||
{ // Fmp
|
||||
GetTheImageInfo,
|
||||
GetTheImage,
|
||||
SetTheImage,
|
||||
CheckTheImage,
|
||||
GetPackageInfo,
|
||||
SetPackageInfo
|
||||
},
|
||||
FALSE, // DescriptorPopulated
|
||||
{ // Desc
|
||||
1, // ImageIndex
|
||||
//
|
||||
// ImageTypeId
|
||||
//
|
||||
{ 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
|
||||
1, // ImageId
|
||||
NULL, // ImageIdName
|
||||
0, // Version
|
||||
NULL, // VersionName
|
||||
0, // Size
|
||||
0, // AttributesSupported
|
||||
0, // AttributesSetting
|
||||
0, // Compatibilities
|
||||
0, // LowestSupportedImageVersion
|
||||
0, // LastAttemptVersion
|
||||
0, // LastAttemptStatus
|
||||
0 // HardwareInstance
|
||||
},
|
||||
NULL, // ImageIdName
|
||||
NULL, // VersionName
|
||||
TRUE, // RuntimeVersionSupported
|
||||
NULL, // FmpDeviceLockEvent
|
||||
FALSE // FmpDeviceLocked
|
||||
};
|
||||
|
||||
///
|
||||
/// GUID that is used to create event used to lock the firmware storage device.
|
||||
///
|
||||
EFI_GUID *mLockGuid = NULL;
|
||||
|
||||
///
|
||||
/// Progress() function pointer passed into SetTheImage()
|
||||
///
|
||||
EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS mProgressFunc = NULL;
|
||||
|
||||
///
|
||||
/// Null-terminated Unicode string retrieved from PcdFmpDeviceImageIdName.
|
||||
///
|
||||
CHAR16 *mImageIdName = NULL;
|
||||
UINT64 mImageId = 0x1;
|
||||
CHAR16 *mVersionName = NULL;
|
||||
|
||||
EFI_EVENT mFmpDeviceLockEvent;
|
||||
//
|
||||
// Indicates if an attempt has been made to lock a
|
||||
// FLASH storage device by calling FmpDeviceLock().
|
||||
// A FLASH storage device may not support being locked,
|
||||
// so this variable is set to TRUE even if FmpDeviceLock()
|
||||
// returns an error.
|
||||
//
|
||||
BOOLEAN mFmpDeviceLocked = FALSE;
|
||||
|
||||
/**
|
||||
Callback function to report the process of the firmware updating.
|
||||
@ -111,10 +121,6 @@ FmpDxeProgress (
|
||||
|
||||
Status = EFI_UNSUPPORTED;
|
||||
|
||||
if (!mProgressSupported) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
if (mProgressFunc == NULL) {
|
||||
return Status;
|
||||
}
|
||||
@ -125,7 +131,6 @@ FmpDxeProgress (
|
||||
Status = mProgressFunc (((Completion * 92) / 100) + 6);
|
||||
|
||||
if (Status == EFI_UNSUPPORTED) {
|
||||
mProgressSupported = FALSE;
|
||||
mProgressFunc = NULL;
|
||||
}
|
||||
|
||||
@ -183,7 +188,7 @@ GetImageTypeNameString (
|
||||
2. Check if we have a variable for lowest supported version (this will be updated with each capsule applied)
|
||||
3. Check Fixed at build PCD
|
||||
|
||||
Take the largest value
|
||||
@return The largest value
|
||||
|
||||
**/
|
||||
UINT32
|
||||
@ -237,101 +242,117 @@ GetLowestSupportedVersion (
|
||||
}
|
||||
|
||||
/**
|
||||
Populates the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure in the module global
|
||||
variable mDesc.
|
||||
Populates the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure in the private
|
||||
context structure.
|
||||
|
||||
@param[in] Private Pointer to the private context structure for the
|
||||
Firmware Management Protocol instance.
|
||||
|
||||
**/
|
||||
VOID
|
||||
PopulateDescriptor (
|
||||
VOID
|
||||
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
mDesc.ImageIndex = 1;
|
||||
CopyGuid (&mDesc.ImageTypeId, GetImageTypeIdGuid());
|
||||
mDesc.ImageId = mImageId;
|
||||
mDesc.ImageIdName = GetImageTypeNameString();
|
||||
if (Private->DescriptorPopulated) {
|
||||
return;
|
||||
}
|
||||
|
||||
Private->Descriptor.ImageIndex = 1;
|
||||
CopyGuid (&Private->Descriptor.ImageTypeId, GetImageTypeIdGuid());
|
||||
Private->Descriptor.ImageId = Private->Descriptor.ImageIndex;
|
||||
Private->Descriptor.ImageIdName = GetImageTypeNameString();
|
||||
|
||||
//
|
||||
// Get the version. Some devices don't support getting the firmware version
|
||||
// at runtime. If FmpDeviceLib does not support returning a version, then
|
||||
// it is stored in a UEFI variable.
|
||||
//
|
||||
Status = FmpDeviceGetVersion (&mDesc.Version);
|
||||
Status = FmpDeviceGetVersion (&Private->Descriptor.Version);
|
||||
if (Status == EFI_UNSUPPORTED) {
|
||||
mRuntimeVersionSupported = FALSE;
|
||||
mDesc.Version = GetVersionFromVariable();
|
||||
Private->RuntimeVersionSupported = FALSE;
|
||||
Private->Descriptor.Version = GetVersionFromVariable();
|
||||
} else if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Unexpected error. Use default version.
|
||||
//
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: GetVersion() from FmpDeviceLib (%s) returned %r\n", GetImageTypeNameString(), Status));
|
||||
mDesc.Version = DEFAULT_VERSION;
|
||||
Private->Descriptor.Version = DEFAULT_VERSION;
|
||||
}
|
||||
|
||||
//
|
||||
// Free the current version name. Shouldn't really happen but this populate
|
||||
// function could be called multiple times (to refresh).
|
||||
//
|
||||
if (mVersionName != NULL) {
|
||||
FreePool (mVersionName);
|
||||
mVersionName = NULL;
|
||||
if (Private->Descriptor.VersionName != NULL) {
|
||||
FreePool (Private->Descriptor.VersionName);
|
||||
Private->Descriptor.VersionName = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Attempt to get the version string from the FmpDeviceLib
|
||||
//
|
||||
Status = FmpDeviceGetVersionString (&mVersionName);
|
||||
Status = FmpDeviceGetVersionString (&Private->Descriptor.VersionName);
|
||||
if (Status == EFI_UNSUPPORTED) {
|
||||
DEBUG ((DEBUG_INFO, "FmpDxe: GetVersionString() unsupported in FmpDeviceLib.\n"));
|
||||
mVersionName = AllocateCopyPool (
|
||||
sizeof (VERSION_STRING_NOT_SUPPORTED),
|
||||
VERSION_STRING_NOT_SUPPORTED
|
||||
);
|
||||
Private->Descriptor.VersionName = AllocateCopyPool (
|
||||
sizeof (VERSION_STRING_NOT_SUPPORTED),
|
||||
VERSION_STRING_NOT_SUPPORTED
|
||||
);
|
||||
} else if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_INFO, "FmpDxe: GetVersionString() not available in FmpDeviceLib.\n"));
|
||||
mVersionName = AllocateCopyPool (
|
||||
sizeof (VERSION_STRING_NOT_AVAILABLE),
|
||||
VERSION_STRING_NOT_AVAILABLE
|
||||
);
|
||||
Private->Descriptor.VersionName = AllocateCopyPool (
|
||||
sizeof (VERSION_STRING_NOT_AVAILABLE),
|
||||
VERSION_STRING_NOT_AVAILABLE
|
||||
);
|
||||
}
|
||||
|
||||
mDesc.VersionName = mVersionName;
|
||||
|
||||
mDesc.LowestSupportedImageVersion = GetLowestSupportedVersion();
|
||||
Private->Descriptor.LowestSupportedImageVersion = GetLowestSupportedVersion();
|
||||
|
||||
//
|
||||
// Get attributes from the FmpDeviceLib
|
||||
//
|
||||
FmpDeviceGetAttributes (&mDesc.AttributesSupported, &mDesc.AttributesSetting);
|
||||
FmpDeviceGetAttributes (
|
||||
&Private->Descriptor.AttributesSupported,
|
||||
&Private->Descriptor.AttributesSetting
|
||||
);
|
||||
|
||||
//
|
||||
// Force set the updatable bits in the attributes;
|
||||
//
|
||||
mDesc.AttributesSupported |= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
|
||||
mDesc.AttributesSetting |= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
|
||||
Private->Descriptor.AttributesSupported |= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
|
||||
Private->Descriptor.AttributesSetting |= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
|
||||
|
||||
//
|
||||
// Force set the authentication bits in the attributes;
|
||||
//
|
||||
mDesc.AttributesSupported |= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
|
||||
mDesc.AttributesSetting |= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
|
||||
Private->Descriptor.AttributesSupported |= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
|
||||
Private->Descriptor.AttributesSetting |= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
|
||||
|
||||
mDesc.Compatibilities = 0;
|
||||
Private->Descriptor.Compatibilities = 0;
|
||||
|
||||
//
|
||||
// Get the size of the firmware image from the FmpDeviceLib
|
||||
//
|
||||
Status = FmpDeviceGetSize (&mDesc.Size);
|
||||
Status = FmpDeviceGetSize (&Private->Descriptor.Size);
|
||||
if (EFI_ERROR (Status)) {
|
||||
mDesc.Size = 0;
|
||||
Private->Descriptor.Size = 0;
|
||||
}
|
||||
|
||||
mDesc.LastAttemptVersion = GetLastAttemptVersionFromVariable ();
|
||||
mDesc.LastAttemptStatus = GetLastAttemptStatusFromVariable ();
|
||||
Private->Descriptor.LastAttemptVersion = GetLastAttemptVersionFromVariable ();
|
||||
Private->Descriptor.LastAttemptStatus = GetLastAttemptStatusFromVariable ();
|
||||
|
||||
mDescriptorPopulated = TRUE;
|
||||
//
|
||||
// Get the hardware instance from FmpDeviceLib
|
||||
//
|
||||
Status = FmpDeviceGetHardwareInstance (&Private->Descriptor.HardwareInstance);
|
||||
if (Status == EFI_UNSUPPORTED) {
|
||||
Private->Descriptor.HardwareInstance = 0;
|
||||
}
|
||||
|
||||
Private->DescriptorPopulated = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -385,10 +406,17 @@ GetTheImageInfo (
|
||||
OUT CHAR16 **PackageVersionName
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
//
|
||||
// Retrieve the private context structure
|
||||
//
|
||||
Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
|
||||
FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
|
||||
|
||||
//
|
||||
// Check for valid pointer
|
||||
//
|
||||
@ -424,15 +452,15 @@ GetTheImageInfo (
|
||||
//
|
||||
*ImageInfoSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR);
|
||||
|
||||
|
||||
if (!mDescriptorPopulated) {
|
||||
PopulateDescriptor();
|
||||
}
|
||||
//
|
||||
// make sure the descriptor has already been loaded
|
||||
//
|
||||
PopulateDescriptor (Private);
|
||||
|
||||
//
|
||||
// Copy the image descriptor
|
||||
//
|
||||
CopyMem (ImageInfo, &mDesc, sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR));
|
||||
CopyMem (ImageInfo, &Private->Descriptor, sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR));
|
||||
|
||||
*DescriptorVersion = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
|
||||
*DescriptorCount = 1;
|
||||
@ -483,11 +511,18 @@ GetTheImage (
|
||||
IN OUT UINTN *ImageSize
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN Size;
|
||||
EFI_STATUS Status;
|
||||
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
|
||||
UINTN Size;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
|
||||
//
|
||||
// Retrieve the private context structure
|
||||
//
|
||||
Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
|
||||
FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
|
||||
|
||||
//
|
||||
// Check to make sure index is 1 (only 1 image for this device)
|
||||
//
|
||||
@ -632,18 +667,19 @@ CheckTheImage (
|
||||
OUT UINT32 *ImageUpdatable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINTN RawSize;
|
||||
VOID *FmpPayloadHeader;
|
||||
UINTN FmpPayloadSize;
|
||||
UINT32 Version;
|
||||
UINT32 FmpHeaderSize;
|
||||
UINTN AllHeaderSize;
|
||||
UINT32 Index;
|
||||
VOID *PublicKeyData;
|
||||
UINTN PublicKeyDataLength;
|
||||
UINT8 *PublicKeyDataXdr;
|
||||
UINT8 *PublicKeyDataXdrEnd;
|
||||
EFI_STATUS Status;
|
||||
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
|
||||
UINTN RawSize;
|
||||
VOID *FmpPayloadHeader;
|
||||
UINTN FmpPayloadSize;
|
||||
UINT32 Version;
|
||||
UINT32 FmpHeaderSize;
|
||||
UINTN AllHeaderSize;
|
||||
UINT32 Index;
|
||||
VOID *PublicKeyData;
|
||||
UINTN PublicKeyDataLength;
|
||||
UINT8 *PublicKeyDataXdr;
|
||||
UINT8 *PublicKeyDataXdrEnd;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
RawSize = 0;
|
||||
@ -653,12 +689,16 @@ CheckTheImage (
|
||||
FmpHeaderSize = 0;
|
||||
AllHeaderSize = 0;
|
||||
|
||||
//
|
||||
// Retrieve the private context structure
|
||||
//
|
||||
Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
|
||||
FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
|
||||
|
||||
//
|
||||
// make sure the descriptor has already been loaded
|
||||
//
|
||||
if (!mDescriptorPopulated) {
|
||||
PopulateDescriptor();
|
||||
}
|
||||
PopulateDescriptor (Private);
|
||||
|
||||
if (ImageUpdatable == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: CheckImage() - ImageUpdatable Pointer Parameter is NULL.\n"));
|
||||
@ -776,11 +816,11 @@ CheckTheImage (
|
||||
//
|
||||
// Check the lowest supported version
|
||||
//
|
||||
if (Version < mDesc.LowestSupportedImageVersion) {
|
||||
if (Version < Private->Descriptor.LowestSupportedImageVersion) {
|
||||
DEBUG (
|
||||
(DEBUG_ERROR,
|
||||
"FmpDxe: CheckTheImage() - Version Lower than lowest supported version. 0x%08X < 0x%08X\n",
|
||||
Version, mDesc.LowestSupportedImageVersion)
|
||||
Version, Private->Descriptor.LowestSupportedImageVersion)
|
||||
);
|
||||
*ImageUpdatable = IMAGE_UPDATABLE_INVALID_OLD;
|
||||
Status = EFI_SUCCESS;
|
||||
@ -880,17 +920,18 @@ SetTheImage (
|
||||
OUT CHAR16 **AbortReason
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 Updateable;
|
||||
BOOLEAN BooleanValue;
|
||||
UINT32 FmpHeaderSize;
|
||||
VOID *FmpHeader;
|
||||
UINTN FmpPayloadSize;
|
||||
UINT32 AllHeaderSize;
|
||||
UINT32 IncommingFwVersion;
|
||||
UINT32 LastAttemptStatus;
|
||||
UINT32 Version;
|
||||
UINT32 LowestSupportedVersion;
|
||||
EFI_STATUS Status;
|
||||
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
|
||||
UINT32 Updateable;
|
||||
BOOLEAN BooleanValue;
|
||||
UINT32 FmpHeaderSize;
|
||||
VOID *FmpHeader;
|
||||
UINTN FmpPayloadSize;
|
||||
UINT32 AllHeaderSize;
|
||||
UINT32 IncommingFwVersion;
|
||||
UINT32 LastAttemptStatus;
|
||||
UINT32 Version;
|
||||
UINT32 LowestSupportedVersion;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
Updateable = 0;
|
||||
@ -902,6 +943,11 @@ SetTheImage (
|
||||
IncommingFwVersion = 0;
|
||||
LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
|
||||
|
||||
//
|
||||
// Retrieve the private context structure
|
||||
//
|
||||
Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
|
||||
FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
|
||||
|
||||
SetLastAttemptVersionInVariable (IncommingFwVersion); //set to 0 to clear any previous results.
|
||||
|
||||
@ -909,7 +955,7 @@ SetTheImage (
|
||||
// if we have locked the device, then skip the set operation.
|
||||
// it should be blocked by hardware too but we can catch here even faster
|
||||
//
|
||||
if (mFmpDeviceLocked) {
|
||||
if (Private->FmpDeviceLocked) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: SetTheImage() - Device is already locked. Can't update.\n"));
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto cleanup;
|
||||
@ -963,7 +1009,6 @@ SetTheImage (
|
||||
}
|
||||
|
||||
mProgressFunc = Progress;
|
||||
mProgressSupported = TRUE;
|
||||
|
||||
//
|
||||
// Checking the image is at least 1%
|
||||
@ -1084,7 +1129,7 @@ SetTheImage (
|
||||
//
|
||||
// Update the version stored in variable
|
||||
//
|
||||
if (!mRuntimeVersionSupported) {
|
||||
if (!Private->RuntimeVersionSupported) {
|
||||
Version = DEFAULT_VERSION;
|
||||
GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &Version);
|
||||
SetVersionInVariable (Version);
|
||||
@ -1103,7 +1148,6 @@ SetTheImage (
|
||||
|
||||
cleanup:
|
||||
mProgressFunc = NULL;
|
||||
mProgressSupported = FALSE;
|
||||
SetLastAttemptStatusInVariable (LastAttemptStatus);
|
||||
|
||||
if (Progress != NULL) {
|
||||
@ -1117,7 +1161,7 @@ cleanup:
|
||||
// Need repopulate after SetImage is called to
|
||||
// update LastAttemptVersion and LastAttemptStatus.
|
||||
//
|
||||
mDescriptorPopulated = FALSE;
|
||||
Private->DescriptorPopulated = FALSE;
|
||||
|
||||
return Status;
|
||||
}
|
||||
@ -1228,12 +1272,16 @@ FmpDxeLockEventNotify (
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_STATUS Status;
|
||||
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
|
||||
|
||||
if (!mFmpDeviceLocked) {
|
||||
Private = (FIRMWARE_MANAGEMENT_PRIVATE_DATA *)Context;
|
||||
|
||||
if (!Private->FmpDeviceLocked) {
|
||||
//
|
||||
// Lock the firmware device
|
||||
//
|
||||
FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
|
||||
Status = FmpDeviceLock();
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Status != EFI_UNSUPPORTED) {
|
||||
@ -1242,7 +1290,7 @@ FmpDxeLockEventNotify (
|
||||
DEBUG ((DEBUG_WARN, "FmpDxe: FmpDeviceLock() returned error. Status = %r\n", Status));
|
||||
}
|
||||
}
|
||||
mFmpDeviceLocked = TRUE;
|
||||
Private->FmpDeviceLocked = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1262,85 +1310,198 @@ InstallFmpInstance (
|
||||
IN EFI_HANDLE Handle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
|
||||
EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL *FmpProgress;
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
|
||||
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
Fmp = NULL;
|
||||
FmpProgress = NULL;
|
||||
DEBUG ((DEBUG_ERROR, "InstallFmpInstance: Entry\n"));
|
||||
|
||||
//
|
||||
// Only allow a single FMP Protocol instance to be installed
|
||||
//
|
||||
if (mFmpInstalled) {
|
||||
Status = gBS->OpenProtocol (
|
||||
Handle,
|
||||
&gEfiFirmwareManagementProtocolGuid,
|
||||
(VOID **)&Fmp,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate FMP Protocol instance
|
||||
//
|
||||
Fmp = AllocateZeroPool (sizeof (EFI_FIRMWARE_MANAGEMENT_PROTOCOL));
|
||||
if (Fmp == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to allocate memory for FMP Protocol instance.\n"));
|
||||
Private = AllocateCopyPool (
|
||||
sizeof (mFirmwareManagementPrivateDataTemplate),
|
||||
&mFirmwareManagementPrivateDataTemplate
|
||||
);
|
||||
if (Private == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to allocate memory for private structure.\n"));
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
// Allocate FMP Progress Protocol instance
|
||||
// Initialize private context data structure
|
||||
//
|
||||
FmpProgress = AllocateZeroPool (sizeof (EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL));
|
||||
if (FmpProgress == NULL) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to allocate memory for FMP Progress Protocol instance.\n"));
|
||||
Status = EFI_OUT_OF_RESOURCES;
|
||||
FreePool (Fmp);
|
||||
DEBUG ((DEBUG_ERROR, "InstallFmpInstance: Initialize private context data structure\n"));
|
||||
|
||||
Private->Handle = Handle;
|
||||
|
||||
Private->FmpDeviceContext = NULL;
|
||||
Status = FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
|
||||
if (Status == EFI_UNSUPPORTED) {
|
||||
Private->FmpDeviceContext = NULL;
|
||||
} else if (EFI_ERROR (Status)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
// Set up FMP Protocol function pointers
|
||||
//
|
||||
Fmp->GetImageInfo = GetTheImageInfo;
|
||||
Fmp->GetImage = GetTheImage;
|
||||
Fmp->SetImage = SetTheImage;
|
||||
Fmp->CheckImage = CheckTheImage;
|
||||
Fmp->GetPackageInfo = GetPackageInfo;
|
||||
Fmp->SetPackageInfo = SetPackageInfo;
|
||||
DEBUG ((DEBUG_ERROR, "InstallFmpInstance: Lock events\n"));
|
||||
|
||||
//
|
||||
// Fill in FMP Progress Protocol fields for Version 1
|
||||
//
|
||||
FmpProgress->Version = 1;
|
||||
FmpProgress->ProgressBarForegroundColor.Raw = PcdGet32 (PcdFmpDeviceProgressColor);
|
||||
FmpProgress->WatchdogSeconds = PcdGet8 (PcdFmpDeviceProgressWatchdogTimeInSeconds);
|
||||
if (IsLockFmpDeviceAtLockEventGuidRequired ()) {
|
||||
//
|
||||
// Lock all UEFI Variables used by this module.
|
||||
//
|
||||
Status = LockAllFmpVariables ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to lock variables. Status = %r.\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "FmpDxe: All variables locked\n"));
|
||||
}
|
||||
|
||||
//
|
||||
// Create and register notify function to lock the FMP device.
|
||||
//
|
||||
Status = gBS->CreateEventEx (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
FmpDxeLockEventNotify,
|
||||
Private,
|
||||
mLockGuid,
|
||||
&Private->FmpDeviceLockEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to register notification. Status = %r\n", Status));
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
} else {
|
||||
DEBUG ((DEBUG_VERBOSE, "FmpDxe: Not registering notification to call FmpDeviceLock() because mfg mode\n"));
|
||||
}
|
||||
|
||||
//
|
||||
// Install FMP Protocol and FMP Progress Protocol
|
||||
//
|
||||
DEBUG ((DEBUG_ERROR, "InstallFmpInstance: Install FMP Protocol and FMP Progress Protocol\n"));
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&Handle,
|
||||
&gEfiFirmwareManagementProtocolGuid,
|
||||
Fmp,
|
||||
&gEdkiiFirmwareManagementProgressProtocolGuid,
|
||||
FmpProgress,
|
||||
&Private->Handle,
|
||||
&gEfiFirmwareManagementProtocolGuid, &Private->Fmp,
|
||||
&gEdkiiFirmwareManagementProgressProtocolGuid, &mFmpProgress,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: FMP Protocol install error. Status = %r.\n", Status));
|
||||
FreePool (Fmp);
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: Protocol install error. Status = %r.\n", Status));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO, "FmpDxe: FMP Protocol Installed!\n"));
|
||||
mFmpInstalled = TRUE;
|
||||
DEBUG ((DEBUG_INFO, "FmpDxe: Protocols Installed!\n"));
|
||||
|
||||
cleanup:
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
if (Private != NULL) {
|
||||
if (Private->FmpDeviceLockEvent != NULL) {
|
||||
gBS->CloseEvent (Private->FmpDeviceLockEvent);
|
||||
}
|
||||
FreePool (Private);
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Function to uninstall FMP instance.
|
||||
|
||||
@param[in] Handle The device handle to install a FMP instance on.
|
||||
|
||||
@retval EFI_SUCCESS FMP Installed
|
||||
@retval EFI_INVALID_PARAMETER Handle was invalid
|
||||
@retval other Error installing FMP
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
UninstallFmpInstance (
|
||||
IN EFI_HANDLE Handle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
|
||||
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
|
||||
|
||||
Status = gBS->OpenProtocol (
|
||||
Handle,
|
||||
&gEfiFirmwareManagementProtocolGuid,
|
||||
(VOID **)&Fmp,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (Fmp);
|
||||
FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
|
||||
|
||||
if (Private->FmpDeviceLockEvent != NULL) {
|
||||
gBS->CloseEvent (Private->FmpDeviceLockEvent);
|
||||
}
|
||||
|
||||
Status = gBS->UninstallMultipleProtocolInterfaces (
|
||||
Private->Handle,
|
||||
&gEfiFirmwareManagementProtocolGuid, &Private->Fmp,
|
||||
&gEdkiiFirmwareManagementProgressProtocolGuid, &mFmpProgress,
|
||||
NULL
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
FmpDeviceSetContext (NULL, &Private->FmpDeviceContext);
|
||||
|
||||
FreePool (Private);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Unloads the application and its installed protocol.
|
||||
|
||||
@param ImageHandle Handle that identifies the image to be unloaded.
|
||||
@param SystemTable The system table.
|
||||
|
||||
@retval EFI_SUCCESS The image has been unloaded.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FmpDxeLibDestructor (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
if (mFmpSingleInstance) {
|
||||
return UninstallFmpInstance (ImageHandle);
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Main entry for this driver/library.
|
||||
|
||||
@ -1356,7 +1517,6 @@ FmpDxeEntryPoint (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_GUID *LockGuid;
|
||||
|
||||
//
|
||||
// Verify that a new FILE_GUID value has been provided in the <Defines>
|
||||
@ -1381,49 +1541,28 @@ FmpDxeEntryPoint (
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Detects if PcdFmpDevicePkcs7CertBufferXdr contains a test key.
|
||||
//
|
||||
DetectTestKey ();
|
||||
|
||||
if (IsLockFmpDeviceAtLockEventGuidRequired ()) {
|
||||
//
|
||||
// Lock all UEFI Variables used by this module.
|
||||
//
|
||||
Status = LockAllFmpVariables ();
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to lock variables. Status = %r.\n", Status));
|
||||
} else {
|
||||
DEBUG ((DEBUG_INFO, "FmpDxe: All variables locked\n"));
|
||||
}
|
||||
//
|
||||
// Fill in FMP Progress Protocol fields for Version 1
|
||||
//
|
||||
mFmpProgress.Version = 1;
|
||||
mFmpProgress.ProgressBarForegroundColor.Raw = PcdGet32 (PcdFmpDeviceProgressColor);
|
||||
mFmpProgress.WatchdogSeconds = PcdGet8 (PcdFmpDeviceProgressWatchdogTimeInSeconds);
|
||||
|
||||
//
|
||||
// Register notify function to lock the FMP device.
|
||||
// The lock event GUID is retrieved from PcdFmpDeviceLockEventGuid.
|
||||
// If PcdFmpDeviceLockEventGuid is not the size of an EFI_GUID, then
|
||||
// gEfiEndOfDxeEventGroupGuid is used.
|
||||
//
|
||||
LockGuid = &gEfiEndOfDxeEventGroupGuid;
|
||||
if (PcdGetSize (PcdFmpDeviceLockEventGuid) == sizeof (EFI_GUID)) {
|
||||
LockGuid = (EFI_GUID *)PcdGetPtr (PcdFmpDeviceLockEventGuid);
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "FmpDxe: Lock GUID: %g\n", LockGuid));
|
||||
|
||||
Status = gBS->CreateEventEx (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
FmpDxeLockEventNotify,
|
||||
NULL,
|
||||
LockGuid,
|
||||
&mFmpDeviceLockEvent
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: Failed to register notification. Status = %r\n", Status));
|
||||
}
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
} else {
|
||||
DEBUG ((DEBUG_VERBOSE, "FmpDxe: Not registering notification to call FmpDeviceLock() because mfg mode\n"));
|
||||
// The lock event GUID is retrieved from PcdFmpDeviceLockEventGuid.
|
||||
// If PcdFmpDeviceLockEventGuid is not the size of an EFI_GUID, then
|
||||
// gEfiEndOfDxeEventGroupGuid is used.
|
||||
//
|
||||
mLockGuid = &gEfiEndOfDxeEventGroupGuid;
|
||||
if (PcdGetSize (PcdFmpDeviceLockEventGuid) == sizeof (EFI_GUID)) {
|
||||
mLockGuid = (EFI_GUID *)PcdGetPtr (PcdFmpDeviceLockEventGuid);
|
||||
}
|
||||
DEBUG ((DEBUG_INFO, "FmpDxe: Lock GUID: %g\n", mLockGuid));
|
||||
|
||||
//
|
||||
// Register with library the install function so if the library uses
|
||||
@ -1433,8 +1572,15 @@ FmpDxeEntryPoint (
|
||||
//
|
||||
Status = RegisterFmpInstaller (InstallFmpInstance);
|
||||
if (Status == EFI_UNSUPPORTED) {
|
||||
mFmpSingleInstance = TRUE;
|
||||
DEBUG ((DEBUG_INFO, "FmpDxe: FmpDeviceLib registration returned EFI_UNSUPPORTED. Installing single FMP instance.\n"));
|
||||
Status = InstallFmpInstance (ImageHandle);
|
||||
Status = RegisterFmpUninstaller (UninstallFmpInstance);
|
||||
if (Status == EFI_UNSUPPORTED) {
|
||||
Status = InstallFmpInstance (ImageHandle);
|
||||
} else {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: FmpDeviceLib RegisterFmpInstaller and RegisterFmpUninstaller do not match.\n"));
|
||||
Status = EFI_UNSUPPORTED;
|
||||
}
|
||||
} else if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: FmpDeviceLib registration returned %r. No FMP installed.\n", Status));
|
||||
} else {
|
||||
@ -1442,6 +1588,10 @@ FmpDxeEntryPoint (
|
||||
DEBUG_INFO,
|
||||
"FmpDxe: FmpDeviceLib registration returned EFI_SUCCESS. Expect FMP to be installed during the BDS/Device connection phase.\n"
|
||||
));
|
||||
Status = RegisterFmpUninstaller (UninstallFmpInstance);
|
||||
if (EFI_ERROR (Status)) {
|
||||
DEBUG ((DEBUG_ERROR, "FmpDxe: FmpDeviceLib RegisterFmpInstaller and RegisterFmpUninstaller do not match.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
|
341
FmpDevicePkg/FmpDxe/FmpDxe.h
Normal file
341
FmpDevicePkg/FmpDxe/FmpDxe.h
Normal file
@ -0,0 +1,341 @@
|
||||
/** @file
|
||||
Produces a Firmware Management Protocol that supports updates to a firmware
|
||||
image stored in a firmware device with platform and firmware device specific
|
||||
information provided through PCDs and libraries.
|
||||
|
||||
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
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _FMP_DXE_H_
|
||||
#define _FMP_DXE_H_
|
||||
|
||||
#include <PiDxe.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/FmpAuthenticationLib.h>
|
||||
#include <Library/FmpDeviceLib.h>
|
||||
#include <Library/FmpPayloadHeaderLib.h>
|
||||
#include <Library/CapsuleUpdatePolicyLib.h>
|
||||
#include <Protocol/FirmwareManagement.h>
|
||||
#include <Protocol/FirmwareManagementProgress.h>
|
||||
#include <Guid/SystemResourceTable.h>
|
||||
#include <Guid/EventGroup.h>
|
||||
#include "VariableSupport.h"
|
||||
|
||||
#define VERSION_STRING_NOT_SUPPORTED L"VERSION STRING NOT SUPPORTED"
|
||||
#define VERSION_STRING_NOT_AVAILABLE L"VERSION STRING NOT AVAILABLE"
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
#define FIRMWARE_MANAGEMENT_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('f','m','p','p')
|
||||
|
||||
typedef struct {
|
||||
UINTN Signature;
|
||||
EFI_HANDLE Handle;
|
||||
EFI_FIRMWARE_MANAGEMENT_PROTOCOL Fmp;
|
||||
BOOLEAN DescriptorPopulated;
|
||||
EFI_FIRMWARE_IMAGE_DESCRIPTOR Descriptor;
|
||||
CHAR16 *ImageIdName;
|
||||
CHAR16 *VersionName;
|
||||
BOOLEAN RuntimeVersionSupported;
|
||||
EFI_EVENT FmpDeviceLockEvent;
|
||||
//
|
||||
// Indicates if an attempt has been made to lock a
|
||||
// FLASH storage device by calling FmpDeviceLock().
|
||||
// A FLASH storage device may not support being locked,
|
||||
// so this variable is set to TRUE even if FmpDeviceLock()
|
||||
// returns an error.
|
||||
//
|
||||
BOOLEAN FmpDeviceLocked;
|
||||
VOID *FmpDeviceContext;
|
||||
} FIRMWARE_MANAGEMENT_PRIVATE_DATA;
|
||||
|
||||
///
|
||||
///
|
||||
///
|
||||
#define FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS(a) \
|
||||
CR (a, FIRMWARE_MANAGEMENT_PRIVATE_DATA, Fmp, FIRMWARE_MANAGEMENT_PRIVATE_DATA_SIGNATURE)
|
||||
|
||||
/**
|
||||
Check to see if any of the keys in PcdFmpDevicePkcs7CertBufferXdr matches
|
||||
the test key. PcdFmpDeviceTestKeySha256Digest contains the SHA256 hash of
|
||||
the test key. For each key in PcdFmpDevicePkcs7CertBufferXdr, compute the
|
||||
SHA256 hash and compare it to PcdFmpDeviceTestKeySha256Digest. If the
|
||||
SHA256 hash matches or there is then error computing the SHA256 hash, then
|
||||
set PcdTestKeyUsed to TRUE. Skip this check if PcdTestKeyUsed is already
|
||||
TRUE or PcdFmpDeviceTestKeySha256Digest is not exactly SHA256_DIGEST_SIZE
|
||||
bytes.
|
||||
**/
|
||||
VOID
|
||||
DetectTestKey (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Returns information about the current firmware image(s) of the device.
|
||||
|
||||
This function allows a copy of the current firmware image to be created and saved.
|
||||
The saved copy could later been used, for example, in firmware image recovery or rollback.
|
||||
|
||||
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
|
||||
@param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer.
|
||||
On input, this is the size of the buffer allocated by the caller.
|
||||
On output, it is the size of the buffer returned by the firmware
|
||||
if the buffer was large enough, or the size of the buffer needed
|
||||
to contain the image(s) information if the buffer was too small.
|
||||
@param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s)
|
||||
information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
|
||||
@param[out] DescriptorVersion A pointer to the location in which firmware returns the version number
|
||||
associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
|
||||
@param[out] DescriptorCount A pointer to the location in which firmware returns the number of
|
||||
descriptors or firmware images within this device.
|
||||
@param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes,
|
||||
of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR.
|
||||
@param[out] PackageVersion A version number that represents all the firmware images in the device.
|
||||
The format is vendor specific and new version must have a greater value
|
||||
than the old version. If PackageVersion is not supported, the value is
|
||||
0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison
|
||||
is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates
|
||||
that package version update is in progress.
|
||||
@param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the
|
||||
package version name. The buffer is allocated by this function with
|
||||
AllocatePool(), and it is the caller's responsibility to free it with a call
|
||||
to FreePool().
|
||||
|
||||
@retval EFI_SUCCESS The device was successfully updated with the new image.
|
||||
@retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size
|
||||
needed to hold the image(s) information is returned in ImageInfoSize.
|
||||
@retval EFI_INVALID_PARAMETER ImageInfoSize is NULL.
|
||||
@retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetTheImageInfo (
|
||||
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
|
||||
IN OUT UINTN *ImageInfoSize,
|
||||
IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,
|
||||
OUT UINT32 *DescriptorVersion,
|
||||
OUT UINT8 *DescriptorCount,
|
||||
OUT UINTN *DescriptorSize,
|
||||
OUT UINT32 *PackageVersion,
|
||||
OUT CHAR16 **PackageVersionName
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieves a copy of the current firmware image of the device.
|
||||
|
||||
This function allows a copy of the current firmware image to be created and saved.
|
||||
The saved copy could later been used, for example, in firmware image recovery or rollback.
|
||||
|
||||
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
|
||||
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
|
||||
The number is between 1 and DescriptorCount.
|
||||
@param[in, out] Image Points to the buffer where the current image is copied to.
|
||||
@param[in, out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes.
|
||||
On return, points to the length of the image, in bytes.
|
||||
|
||||
@retval EFI_SUCCESS The device was successfully updated with the new image.
|
||||
@retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the
|
||||
image. The current buffer size needed to hold the image is returned
|
||||
in ImageSize.
|
||||
@retval EFI_INVALID_PARAMETER The Image was NULL.
|
||||
@retval EFI_NOT_FOUND The current image is not copied to the buffer.
|
||||
@retval EFI_UNSUPPORTED The operation is not supported.
|
||||
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetTheImage (
|
||||
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
|
||||
IN UINT8 ImageIndex,
|
||||
IN OUT VOID *Image,
|
||||
IN OUT UINTN *ImageSize
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
Checks if the firmware image is valid for the device.
|
||||
|
||||
This function allows firmware update application to validate the firmware image without
|
||||
invoking the SetImage() first.
|
||||
|
||||
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
|
||||
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
|
||||
The number is between 1 and DescriptorCount.
|
||||
@param[in] Image Points to the new image.
|
||||
@param[in] ImageSize Size of the new image in bytes.
|
||||
@param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides,
|
||||
if available, additional information if the image is invalid.
|
||||
|
||||
@retval EFI_SUCCESS The image was successfully checked.
|
||||
@retval EFI_ABORTED The operation is aborted.
|
||||
@retval EFI_INVALID_PARAMETER The Image was NULL.
|
||||
@retval EFI_UNSUPPORTED The operation is not supported.
|
||||
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
CheckTheImage (
|
||||
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
|
||||
IN UINT8 ImageIndex,
|
||||
IN CONST VOID *Image,
|
||||
IN UINTN ImageSize,
|
||||
OUT UINT32 *ImageUpdatable
|
||||
);
|
||||
|
||||
/**
|
||||
Updates the firmware image of the device.
|
||||
|
||||
This function updates the hardware with the new firmware image.
|
||||
This function returns EFI_UNSUPPORTED if the firmware image is not updatable.
|
||||
If the firmware image is updatable, the function should perform the following minimal validations
|
||||
before proceeding to do the firmware image update.
|
||||
- Validate the image authentication if image has attribute
|
||||
IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns
|
||||
EFI_SECURITY_VIOLATION if the validation fails.
|
||||
- Validate the image is a supported image for this device. The function returns EFI_ABORTED if
|
||||
the image is unsupported. The function can optionally provide more detailed information on
|
||||
why the image is not a supported image.
|
||||
- Validate the data from VendorCode if not null. Image validation must be performed before
|
||||
VendorCode data validation. VendorCode data is ignored or considered invalid if image
|
||||
validation failed. The function returns EFI_ABORTED if the data is invalid.
|
||||
|
||||
VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if
|
||||
the caller did not specify the policy or use the default policy. As an example, vendor can implement
|
||||
a policy to allow an option to force a firmware image update when the abort reason is due to the new
|
||||
firmware image version is older than the current firmware image version or bad image checksum.
|
||||
Sensitive operations such as those wiping the entire firmware image and render the device to be
|
||||
non-functional should be encoded in the image itself rather than passed with the VendorCode.
|
||||
AbortReason enables vendor to have the option to provide a more detailed description of the abort
|
||||
reason to the caller.
|
||||
|
||||
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
|
||||
@param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
|
||||
The number is between 1 and DescriptorCount.
|
||||
@param[in] Image Points to the new image.
|
||||
@param[in] ImageSize Size of the new image in bytes.
|
||||
@param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy.
|
||||
Null indicates the caller did not specify the policy or use the default policy.
|
||||
@param[in] Progress A function used by the driver to report the progress of the firmware update.
|
||||
@param[out] AbortReason A pointer to a pointer to a null-terminated string providing more
|
||||
details for the aborted operation. The buffer is allocated by this function
|
||||
with AllocatePool(), and it is the caller's responsibility to free it with a
|
||||
call to FreePool().
|
||||
|
||||
@retval EFI_SUCCESS The device was successfully updated with the new image.
|
||||
@retval EFI_ABORTED The operation is aborted.
|
||||
@retval EFI_INVALID_PARAMETER The Image was NULL.
|
||||
@retval EFI_UNSUPPORTED The operation is not supported.
|
||||
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetTheImage (
|
||||
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
|
||||
IN UINT8 ImageIndex,
|
||||
IN CONST VOID *Image,
|
||||
IN UINTN ImageSize,
|
||||
IN CONST VOID *VendorCode,
|
||||
IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,
|
||||
OUT CHAR16 **AbortReason
|
||||
);
|
||||
|
||||
/**
|
||||
Returns information about the firmware package.
|
||||
|
||||
This function returns package information.
|
||||
|
||||
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
|
||||
@param[out] PackageVersion A version number that represents all the firmware images in the device.
|
||||
The format is vendor specific and new version must have a greater value
|
||||
than the old version. If PackageVersion is not supported, the value is
|
||||
0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version
|
||||
comparison is to be performed using PackageVersionName. A value of
|
||||
0xFFFFFFFD indicates that package version update is in progress.
|
||||
@param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing
|
||||
the package version name. The buffer is allocated by this function with
|
||||
AllocatePool(), and it is the caller's responsibility to free it with a
|
||||
call to FreePool().
|
||||
@param[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of
|
||||
package version name. A value of 0 indicates the device does not support
|
||||
update of package version name. Length is the number of Unicode characters,
|
||||
including the terminating null character.
|
||||
@param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute
|
||||
Definitions' for possible returned values of this parameter. A value of 1
|
||||
indicates the attribute is supported and the current setting value is
|
||||
indicated in AttributesSetting. A value of 0 indicates the attribute is not
|
||||
supported and the current setting value in AttributesSetting is meaningless.
|
||||
@param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned
|
||||
values of this parameter
|
||||
|
||||
@retval EFI_SUCCESS The package information was successfully returned.
|
||||
@retval EFI_UNSUPPORTED The operation is not supported.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetPackageInfo (
|
||||
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
|
||||
OUT UINT32 *PackageVersion,
|
||||
OUT CHAR16 **PackageVersionName,
|
||||
OUT UINT32 *PackageVersionNameMaxLen,
|
||||
OUT UINT64 *AttributesSupported,
|
||||
OUT UINT64 *AttributesSetting
|
||||
);
|
||||
|
||||
/**
|
||||
Updates information about the firmware package.
|
||||
|
||||
This function updates package information.
|
||||
This function returns EFI_UNSUPPORTED if the package information is not updatable.
|
||||
VendorCode enables vendor to implement vendor-specific package information update policy.
|
||||
Null if the caller did not specify this policy or use the default policy.
|
||||
|
||||
@param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
|
||||
@param[in] Image Points to the authentication image.
|
||||
Null if authentication is not required.
|
||||
@param[in] ImageSize Size of the authentication image in bytes.
|
||||
0 if authentication is not required.
|
||||
@param[in] VendorCode This enables vendor to implement vendor-specific firmware
|
||||
image update policy.
|
||||
Null indicates the caller did not specify this policy or use
|
||||
the default policy.
|
||||
@param[in] PackageVersion The new package version.
|
||||
@param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing
|
||||
the package version name.
|
||||
The string length is equal to or less than the value returned in
|
||||
PackageVersionNameMaxLen.
|
||||
|
||||
@retval EFI_SUCCESS The device was successfully updated with the new package
|
||||
information.
|
||||
@retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value
|
||||
returned in PackageVersionNameMaxLen.
|
||||
@retval EFI_UNSUPPORTED The operation is not supported.
|
||||
@retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SetPackageInfo (
|
||||
IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
|
||||
IN CONST VOID *Image,
|
||||
IN UINTN ImageSize,
|
||||
IN CONST VOID *VendorCode,
|
||||
IN UINT32 PackageVersion,
|
||||
IN CONST CHAR16 *PackageVersionName
|
||||
);
|
||||
|
||||
#endif
|
@ -4,7 +4,7 @@
|
||||
# information provided through PCDs and libraries.
|
||||
#
|
||||
# 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
|
||||
##
|
||||
@ -17,6 +17,7 @@
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = FmpDxeEntryPoint
|
||||
UNLOAD_IMAGE = UninstallFmpInstance
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
@ -26,6 +27,7 @@
|
||||
|
||||
[Sources]
|
||||
FmpDxe.c
|
||||
FmpDxe.h
|
||||
DetectTestKey.c
|
||||
VariableSupport.h
|
||||
VariableSupport.c
|
||||
|
@ -4,7 +4,7 @@
|
||||
# information provided through PCDs and libraries.
|
||||
#
|
||||
# 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
|
||||
##
|
||||
@ -18,6 +18,7 @@
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = NULL
|
||||
CONSTRUCTOR = FmpDxeEntryPoint
|
||||
DESTRUCTOR = FmpDxeLibDestructor
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
@ -27,6 +28,7 @@
|
||||
|
||||
[Sources]
|
||||
FmpDxe.c
|
||||
FmpDxe.h
|
||||
DetectTestKey.c
|
||||
VariableSupport.h
|
||||
VariableSupport.c
|
||||
|
Loading…
x
Reference in New Issue
Block a user