2 Produces a Firmware Management Protocol that supports updates to a firmware
3 image stored in a firmware device with platform and firmware device specific
4 information provided through PCDs and libraries.
6 Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
7 Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation
15 and/or other materials provided with the distribution.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <Library/DebugLib.h>
32 #include <Library/BaseLib.h>
33 #include <Library/BaseMemoryLib.h>
34 #include <Library/UefiBootServicesTableLib.h>
35 #include <Library/MemoryAllocationLib.h>
36 #include <Library/UefiLib.h>
37 #include <Library/FmpAuthenticationLib.h>
38 #include <Library/FmpDeviceLib.h>
39 #include <Library/FmpPayloadHeaderLib.h>
40 #include <Library/CapsuleUpdatePolicyLib.h>
41 #include <Protocol/FirmwareManagement.h>
42 #include <Protocol/FirmwareManagementProgress.h>
43 #include <Guid/SystemResourceTable.h>
44 #include <Guid/EventGroup.h>
45 #include "VariableSupport.h"
47 #define VERSION_STRING_NOT_SUPPORTED L"VERSION STRING NOT SUPPORTED"
48 #define VERSION_STRING_NOT_AVAILABLE L"VERSION STRING NOT AVAILABLE"
51 Check to see if any of the keys in PcdFmpDevicePkcs7CertBufferXdr matches
52 the test key. PcdFmpDeviceTestKeySha256Digest contains the SHA256 hash of
53 the test key. For each key in PcdFmpDevicePkcs7CertBufferXdr, compute the
54 SHA256 hash and compare it to PcdFmpDeviceTestKeySha256Digest. If the
55 SHA256 hash matches or there is then error computing the SHA256 hash, then
56 set PcdTestKeyUsed to TRUE. Skip this check if PcdTestKeyUsed is already
57 TRUE or PcdFmpDeviceTestKeySha256Digest is not exactly SHA256_DIGEST_SIZE
66 /// FILE_GUID from FmpDxe.inf. When FmpDxe.inf is used in a platform, the
67 /// FILE_GUID must always be overridden in the <Defines> section to provide
68 /// the ESRT GUID value associated with the updatable firmware image. A
69 /// check is made in this module's driver entry point to verify that a
70 /// new FILE_GUID value has been defined.
72 const EFI_GUID mDefaultModuleFileGuid
= {
73 0x78ef0a56, 0x1cf0, 0x4535, { 0xb5, 0xda, 0xf6, 0xfd, 0x2f, 0x40, 0x5a, 0x11 }
76 EFI_FIRMWARE_IMAGE_DESCRIPTOR mDesc
;
77 BOOLEAN mDescriptorPopulated
= FALSE
;
78 BOOLEAN mRuntimeVersionSupported
= TRUE
;
79 BOOLEAN mFmpInstalled
= FALSE
;
82 /// Function pointer to progress function
84 EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS mProgressFunc
= NULL
;
85 BOOLEAN mProgressSupported
= FALSE
;
87 CHAR16
*mImageIdName
= NULL
;
88 UINT64 mImageId
= 0x1;
89 CHAR16
*mVersionName
= NULL
;
91 EFI_EVENT mFmpDeviceLockEvent
;
92 BOOLEAN mFmpDeviceLocked
= FALSE
;
95 Callback function to report the process of the firmware updating.
97 Wrap the caller's version in this so that progress from the device lib is
98 within the expected range. Convert device lib 0% - 100% to 6% - 98%.
100 FmpDxe 1% - 5% for validation
101 FmpDeviceLib 6% - 98% for flashing/update
102 FmpDxe 99% - 100% finish
104 @param[in] Completion A value between 1 and 100 indicating the current
105 completion progress of the firmware update. Completion
106 progress is reported as from 1 to 100 percent. A value
107 of 0 is used by the driver to indicate that progress
108 reporting is not supported.
110 @retval EFI_SUCCESS The progress was updated.
111 @retval EFI_UNSUPPORTED Updating progress is not supported.
122 Status
= EFI_UNSUPPORTED
;
124 if (!mProgressSupported
) {
128 if (mProgressFunc
== NULL
) {
133 // Reserve 6% - 98% for the FmpDeviceLib. Call the real progress function.
135 Status
= mProgressFunc (((Completion
* 92) / 100) + 6);
137 if (Status
== EFI_UNSUPPORTED
) {
138 mProgressSupported
= FALSE
;
139 mProgressFunc
= NULL
;
146 Returns a pointer to the ImageTypeId GUID value. An attempt is made to get
147 the GUID value from the FmpDeviceLib. If the FmpDeviceLib does not provide
148 a GUID value, then gEfiCallerIdGuid is returned.
150 @return The ImageTypeId GUID
159 EFI_GUID
*FmpDeviceLibGuid
;
161 FmpDeviceLibGuid
= NULL
;
162 Status
= FmpDeviceGetImageTypeIdGuidPtr (&FmpDeviceLibGuid
);
163 if (EFI_ERROR (Status
)) {
164 if (Status
!= EFI_UNSUPPORTED
) {
165 DEBUG ((DEBUG_ERROR
, "FmpDxe: FmpDeviceLib GetImageTypeIdGuidPtr() returned invalid error %r\n", Status
));
167 return &gEfiCallerIdGuid
;
169 if (FmpDeviceLibGuid
== NULL
) {
170 DEBUG ((DEBUG_ERROR
, "FmpDxe: FmpDeviceLib GetImageTypeIdGuidPtr() returned invalid GUID\n"));
171 return &gEfiCallerIdGuid
;
173 return FmpDeviceLibGuid
;
177 Returns a pointer to the Null-terminated Unicode ImageIdName string.
179 @return Null-terminated Unicode ImageIdName string.
183 GetImageTypeNameString (
191 Lowest supported version is a combo of three parts.
192 1. Check if the device lib has a lowest supported version
193 2. Check if we have a variable for lowest supported version (this will be updated with each capsule applied)
194 3. Check Fixed at build PCD
196 Take the largest value
200 GetLowestSupportedVersion (
205 UINT32 DeviceLibLowestSupportedVersion
;
206 UINT32 VariableLowestSupportedVersion
;
210 // Get the LowestSupportedVersion.
213 if (!IsLowestSupportedVersionCheckRequired ()) {
215 // Any Version can pass the 0 LowestSupportedVersion check.
220 ReturnLsv
= PcdGet32 (PcdFmpDeviceBuildTimeLowestSupportedVersion
);
223 // Check the FmpDeviceLib
225 Status
= FmpDeviceGetLowestSupportedVersion (&DeviceLibLowestSupportedVersion
);
226 if (EFI_ERROR (Status
)) {
227 DeviceLibLowestSupportedVersion
= DEFAULT_LOWESTSUPPORTEDVERSION
;
230 if (DeviceLibLowestSupportedVersion
> ReturnLsv
) {
231 ReturnLsv
= DeviceLibLowestSupportedVersion
;
235 // Check the lowest supported version UEFI variable for this device
237 VariableLowestSupportedVersion
= GetLowestSupportedVersionFromVariable();
238 if (VariableLowestSupportedVersion
> ReturnLsv
) {
239 ReturnLsv
= VariableLowestSupportedVersion
;
243 // Return the largest value
249 Populates the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure in the module global
260 mDesc
.ImageIndex
= 1;
261 CopyGuid (&mDesc
.ImageTypeId
, GetImageTypeIdGuid());
262 mDesc
.ImageId
= mImageId
;
263 mDesc
.ImageIdName
= GetImageTypeNameString();
266 // Get the version. Some devices don't support getting the firmware version
267 // at runtime. If FmpDeviceLib does not support returning a version, then
268 // it is stored in a UEFI variable.
270 Status
= FmpDeviceGetVersion (&mDesc
.Version
);
271 if (Status
== EFI_UNSUPPORTED
) {
272 mRuntimeVersionSupported
= FALSE
;
273 mDesc
.Version
= GetVersionFromVariable();
274 } else if (EFI_ERROR (Status
)) {
276 // Unexpected error. Use default version.
278 DEBUG ((DEBUG_ERROR
, "FmpDxe: GetVersion() from FmpDeviceLib (%s) returned %r\n", GetImageTypeNameString(), Status
));
279 mDesc
.Version
= DEFAULT_VERSION
;
283 // Free the current version name. Shouldn't really happen but this populate
284 // function could be called multiple times (to refresh).
286 if (mVersionName
!= NULL
) {
287 FreePool (mVersionName
);
292 // Attempt to get the version string from the FmpDeviceLib
294 Status
= FmpDeviceGetVersionString (&mVersionName
);
295 if (Status
== EFI_UNSUPPORTED
) {
296 DEBUG ((DEBUG_INFO
, "FmpDxe: GetVersionString() unsupported in FmpDeviceLib.\n"));
297 mVersionName
= AllocateCopyPool (
298 sizeof (VERSION_STRING_NOT_SUPPORTED
),
299 VERSION_STRING_NOT_SUPPORTED
301 } else if (EFI_ERROR (Status
)) {
302 DEBUG ((DEBUG_INFO
, "FmpDxe: GetVersionString() not available in FmpDeviceLib.\n"));
303 mVersionName
= AllocateCopyPool (
304 sizeof (VERSION_STRING_NOT_AVAILABLE
),
305 VERSION_STRING_NOT_AVAILABLE
309 mDesc
.VersionName
= mVersionName
;
311 mDesc
.LowestSupportedImageVersion
= GetLowestSupportedVersion();
314 // Get attributes from the FmpDeviceLib
316 FmpDeviceGetAttributes (&mDesc
.AttributesSupported
, &mDesc
.AttributesSetting
);
319 // Force set the updatable bits in the attributes;
321 mDesc
.AttributesSupported
|= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
;
322 mDesc
.AttributesSetting
|= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
;
325 // Force set the authentication bits in the attributes;
327 mDesc
.AttributesSupported
|= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
);
328 mDesc
.AttributesSetting
|= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
);
330 mDesc
.Compatibilities
= 0;
333 // Get the size of the firmware image from the FmpDeviceLib
335 Status
= FmpDeviceGetSize (&mDesc
.Size
);
336 if (EFI_ERROR (Status
)) {
340 mDesc
.LastAttemptVersion
= GetLastAttemptVersionFromVariable ();
341 mDesc
.LastAttemptStatus
= GetLastAttemptStatusFromVariable ();
343 mDescriptorPopulated
= TRUE
;
347 Returns information about the current firmware image(s) of the device.
349 This function allows a copy of the current firmware image to be created and saved.
350 The saved copy could later been used, for example, in firmware image recovery or rollback.
352 @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
353 @param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer.
354 On input, this is the size of the buffer allocated by the caller.
355 On output, it is the size of the buffer returned by the firmware
356 if the buffer was large enough, or the size of the buffer needed
357 to contain the image(s) information if the buffer was too small.
358 @param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s)
359 information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
360 @param[out] DescriptorVersion A pointer to the location in which firmware returns the version number
361 associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
362 @param[out] DescriptorCount A pointer to the location in which firmware returns the number of
363 descriptors or firmware images within this device.
364 @param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes,
365 of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR.
366 @param[out] PackageVersion A version number that represents all the firmware images in the device.
367 The format is vendor specific and new version must have a greater value
368 than the old version. If PackageVersion is not supported, the value is
369 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison
370 is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates
371 that package version update is in progress.
372 @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the
373 package version name. The buffer is allocated by this function with
374 AllocatePool(), and it is the caller's responsibility to free it with a call
377 @retval EFI_SUCCESS The device was successfully updated with the new image.
378 @retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size
379 needed to hold the image(s) information is returned in ImageInfoSize.
380 @retval EFI_INVALID_PARAMETER ImageInfoSize is NULL.
381 @retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image.
387 IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*This
,
388 IN OUT UINTN
*ImageInfoSize
,
389 IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR
*ImageInfo
,
390 OUT UINT32
*DescriptorVersion
,
391 OUT UINT8
*DescriptorCount
,
392 OUT UINTN
*DescriptorSize
,
393 OUT UINT32
*PackageVersion
,
394 OUT CHAR16
**PackageVersionName
399 Status
= EFI_SUCCESS
;
402 // Check for valid pointer
404 if (ImageInfoSize
== NULL
) {
405 DEBUG ((DEBUG_ERROR
, "FmpDxe: GetImageInfo() - ImageInfoSize is NULL.\n"));
406 Status
= EFI_INVALID_PARAMETER
;
411 // Check the buffer size
412 // NOTE: Check this first so caller can get the necessary memory size it must allocate.
414 if (*ImageInfoSize
< (sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR
))) {
415 *ImageInfoSize
= sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR
);
416 DEBUG ((DEBUG_VERBOSE
, "FmpDxe: GetImageInfo() - ImageInfoSize is to small.\n"));
417 Status
= EFI_BUFFER_TOO_SMALL
;
422 // Confirm that buffer isn't null
424 if ( (ImageInfo
== NULL
) || (DescriptorVersion
== NULL
) || (DescriptorCount
== NULL
) || (DescriptorSize
== NULL
)
425 || (PackageVersion
== NULL
)) {
426 DEBUG ((DEBUG_ERROR
, "FmpDxe: GetImageInfo() - Pointer Parameter is NULL.\n"));
427 Status
= EFI_INVALID_PARAMETER
;
432 // Set the size to whatever we need
434 *ImageInfoSize
= sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR
);
437 if (!mDescriptorPopulated
) {
438 PopulateDescriptor();
442 // Copy the image descriptor
444 CopyMem (ImageInfo
, &mDesc
, sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR
));
446 *DescriptorVersion
= EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION
;
447 *DescriptorCount
= 1;
448 *DescriptorSize
= sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR
);
452 *PackageVersion
= 0xFFFFFFFF;
455 // Do not update PackageVersionName since it is not supported in this instance.
464 Retrieves a copy of the current firmware image of the device.
466 This function allows a copy of the current firmware image to be created and saved.
467 The saved copy could later been used, for example, in firmware image recovery or rollback.
469 @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
470 @param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
471 The number is between 1 and DescriptorCount.
472 @param[out] Image Points to the buffer where the current image is copied to.
473 @param[out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes.
474 On return, points to the length of the image, in bytes.
476 @retval EFI_SUCCESS The device was successfully updated with the new image.
477 @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the
478 image. The current buffer size needed to hold the image is returned
480 @retval EFI_INVALID_PARAMETER The Image was NULL.
481 @retval EFI_NOT_FOUND The current image is not copied to the buffer.
482 @retval EFI_UNSUPPORTED The operation is not supported.
483 @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure.
489 IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*This
,
492 IN OUT UINTN
*ImageSize
498 Status
= EFI_SUCCESS
;
500 if ((ImageSize
== NULL
)) {
501 DEBUG ((DEBUG_ERROR
, "FmpDxe: GetImage() - ImageSize Pointer Parameter is NULL.\n"));
502 Status
= EFI_INVALID_PARAMETER
;
507 // Check the buffer size
509 Status
= FmpDeviceGetSize (&Size
);
510 if (EFI_ERROR (Status
)) {
513 if (*ImageSize
< Size
) {
515 DEBUG ((DEBUG_VERBOSE
, "FmpDxe: GetImage() - ImageSize is to small.\n"));
516 Status
= EFI_BUFFER_TOO_SMALL
;
521 DEBUG ((DEBUG_ERROR
, "FmpDxe: GetImage() - Image Pointer Parameter is NULL.\n"));
522 Status
= EFI_INVALID_PARAMETER
;
527 // Check to make sure index is 1 (only 1 image for this device)
529 if (ImageIndex
!= 1) {
530 DEBUG ((DEBUG_ERROR
, "FmpDxe: GetImage() - Image Index Invalid.\n"));
531 Status
= EFI_INVALID_PARAMETER
;
536 Status
= FmpDeviceGetImage (Image
, ImageSize
);
543 Helper function to safely retrieve the FMP header from
544 within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure.
546 @param[in] Image Pointer to the image.
547 @param[in] ImageSize Size of the image.
548 @param[out] PayloadSize
550 @retval !NULL Valid pointer to the header.
551 @retval NULL Structure is bad and pointer cannot be found.
556 IN CONST EFI_FIRMWARE_IMAGE_AUTHENTICATION
*Image
,
557 IN CONST UINTN ImageSize
,
558 OUT UINTN
*PayloadSize
562 // Check to make sure that operation can be safely performed.
564 if (((UINTN
)Image
+ sizeof (Image
->MonotonicCount
) + Image
->AuthInfo
.Hdr
.dwLength
) < (UINTN
)Image
|| \
565 ((UINTN
)Image
+ sizeof (Image
->MonotonicCount
) + Image
->AuthInfo
.Hdr
.dwLength
) >= (UINTN
)Image
+ ImageSize
) {
567 // Pointer overflow. Invalid image.
572 *PayloadSize
= ImageSize
- (sizeof (Image
->MonotonicCount
) + Image
->AuthInfo
.Hdr
.dwLength
);
573 return (VOID
*)((UINT8
*)Image
+ sizeof (Image
->MonotonicCount
) + Image
->AuthInfo
.Hdr
.dwLength
);
577 Helper function to safely calculate the size of all headers
578 within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure.
580 @param[in] Image Pointer to the image.
581 @param[in] AdditionalHeaderSize Size of any headers that cannot be calculated by this function.
583 @retval UINT32>0 Valid size of all the headers.
584 @retval 0 Structure is bad and size cannot be found.
589 IN CONST EFI_FIRMWARE_IMAGE_AUTHENTICATION
*Image
,
590 IN UINT32 AdditionalHeaderSize
593 UINT32 CalculatedSize
;
595 CalculatedSize
= sizeof (Image
->MonotonicCount
) +
596 AdditionalHeaderSize
+
597 Image
->AuthInfo
.Hdr
.dwLength
;
600 // Check to make sure that operation can be safely performed.
602 if (CalculatedSize
< sizeof (Image
->MonotonicCount
) ||
603 CalculatedSize
< AdditionalHeaderSize
||
604 CalculatedSize
< Image
->AuthInfo
.Hdr
.dwLength
) {
606 // Integer overflow. Invalid image.
611 return CalculatedSize
;
615 Checks if the firmware image is valid for the device.
617 This function allows firmware update application to validate the firmware image without
618 invoking the SetImage() first.
620 @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
621 @param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
622 The number is between 1 and DescriptorCount.
623 @param[in] Image Points to the new image.
624 @param[in] ImageSize Size of the new image in bytes.
625 @param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides,
626 if available, additional information if the image is invalid.
628 @retval EFI_SUCCESS The image was successfully checked.
629 @retval EFI_ABORTED The operation is aborted.
630 @retval EFI_INVALID_PARAMETER The Image was NULL.
631 @retval EFI_UNSUPPORTED The operation is not supported.
632 @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure.
638 IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*This
,
640 IN CONST VOID
*Image
,
642 OUT UINT32
*ImageUpdateable
647 VOID
*FmpPayloadHeader
;
648 UINTN FmpPayloadSize
;
650 UINT32 FmpHeaderSize
;
654 UINTN PublicKeyDataLength
;
655 UINT8
*PublicKeyDataXdr
;
656 UINT8
*PublicKeyDataXdrEnd
;
658 Status
= EFI_SUCCESS
;
660 FmpPayloadHeader
= NULL
;
667 // make sure the descriptor has already been loaded
669 if (!mDescriptorPopulated
) {
670 PopulateDescriptor();
673 if (ImageUpdateable
== NULL
) {
674 DEBUG ((DEBUG_ERROR
, "FmpDxe: CheckImage() - ImageUpdateable Pointer Parameter is NULL.\n"));
675 Status
= EFI_INVALID_PARAMETER
;
680 //Set to valid and then if any tests fail it will update this flag.
682 *ImageUpdateable
= IMAGE_UPDATABLE_VALID
;
685 DEBUG ((DEBUG_ERROR
, "FmpDxe: CheckImage() - Image Pointer Parameter is NULL.\n"));
687 // not sure if this is needed
689 *ImageUpdateable
= IMAGE_UPDATABLE_INVALID
;
690 return EFI_INVALID_PARAMETER
;
693 PublicKeyDataXdr
= PcdGetPtr (PcdFmpDevicePkcs7CertBufferXdr
);
694 PublicKeyDataXdrEnd
= PublicKeyDataXdr
+ PcdGetSize (PcdFmpDevicePkcs7CertBufferXdr
);
696 if (PublicKeyDataXdr
== NULL
|| (PublicKeyDataXdr
== PublicKeyDataXdrEnd
)) {
697 DEBUG ((DEBUG_ERROR
, "FmpDxe: Invalid certificate, skipping it.\n"));
698 Status
= EFI_ABORTED
;
701 // Try each key from PcdFmpDevicePkcs7CertBufferXdr
703 for (Index
= 1; PublicKeyDataXdr
< PublicKeyDataXdrEnd
; Index
++) {
707 "FmpDxe: Certificate #%d [%p..%p].\n",
714 if ((PublicKeyDataXdr
+ sizeof (UINT32
)) > PublicKeyDataXdrEnd
) {
716 // Key data extends beyond end of PCD
718 DEBUG ((DEBUG_ERROR
, "FmpDxe: Certificate size extends beyond end of PCD, skipping it.\n"));
719 Status
= EFI_ABORTED
;
723 // Read key length stored in big-endian format
725 PublicKeyDataLength
= SwapBytes32 (*(UINT32
*)(PublicKeyDataXdr
));
727 // Point to the start of the key data
729 PublicKeyDataXdr
+= sizeof (UINT32
);
730 if (PublicKeyDataXdr
+ PublicKeyDataLength
> PublicKeyDataXdrEnd
) {
732 // Key data extends beyond end of PCD
734 DEBUG ((DEBUG_ERROR
, "FmpDxe: Certificate extends beyond end of PCD, skipping it.\n"));
735 Status
= EFI_ABORTED
;
738 PublicKeyData
= PublicKeyDataXdr
;
739 Status
= AuthenticateFmpImage (
740 (EFI_FIRMWARE_IMAGE_AUTHENTICATION
*)Image
,
745 if (!EFI_ERROR (Status
)) {
748 PublicKeyDataXdr
+= PublicKeyDataLength
;
749 PublicKeyDataXdr
= (UINT8
*)ALIGN_POINTER (PublicKeyDataXdr
, sizeof (UINT32
));
753 if (EFI_ERROR (Status
)) {
754 DEBUG ((DEBUG_ERROR
, "FmpDxe: CheckTheImage() - Authentication Failed %r.\n", Status
));
759 // Check to make sure index is 1
761 if (ImageIndex
!= 1) {
762 DEBUG ((DEBUG_ERROR
, "FmpDxe: CheckImage() - Image Index Invalid.\n"));
763 *ImageUpdateable
= IMAGE_UPDATABLE_INVALID_TYPE
;
764 Status
= EFI_SUCCESS
;
770 // Check the FmpPayloadHeader
772 FmpPayloadHeader
= GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION
*)Image
, ImageSize
, &FmpPayloadSize
);
773 if (FmpPayloadHeader
== NULL
) {
774 DEBUG ((DEBUG_ERROR
, "FmpDxe: CheckTheImage() - GetFmpHeader failed.\n"));
775 Status
= EFI_ABORTED
;
778 Status
= GetFmpPayloadHeaderVersion (FmpPayloadHeader
, FmpPayloadSize
, &Version
);
779 if (EFI_ERROR (Status
)) {
780 DEBUG ((DEBUG_ERROR
, "FmpDxe: CheckTheImage() - GetFmpPayloadHeaderVersion failed %r.\n", Status
));
781 *ImageUpdateable
= IMAGE_UPDATABLE_INVALID
;
782 Status
= EFI_SUCCESS
;
787 // Check the lowest supported version
789 if (Version
< mDesc
.LowestSupportedImageVersion
) {
792 "FmpDxe: CheckTheImage() - Version Lower than lowest supported version. 0x%08X < 0x%08X\n",
793 Version
, mDesc
.LowestSupportedImageVersion
)
795 *ImageUpdateable
= IMAGE_UPDATABLE_INVALID_OLD
;
796 Status
= EFI_SUCCESS
;
801 // Get the FmpHeaderSize so we can determine the real payload size
803 Status
= GetFmpPayloadHeaderSize (FmpPayloadHeader
, FmpPayloadSize
, &FmpHeaderSize
);
804 if (EFI_ERROR (Status
)) {
805 DEBUG ((DEBUG_ERROR
, "FmpDxe: CheckTheImage() - GetFmpPayloadHeaderSize failed %r.\n", Status
));
806 *ImageUpdateable
= IMAGE_UPDATABLE_INVALID
;
807 Status
= EFI_SUCCESS
;
812 // Call FmpDevice Lib Check Image on the
813 // Raw payload. So all headers need stripped off
815 AllHeaderSize
= GetAllHeaderSize ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION
*)Image
, FmpHeaderSize
);
816 if (AllHeaderSize
== 0) {
817 DEBUG ((DEBUG_ERROR
, "FmpDxe: CheckTheImage() - GetAllHeaderSize failed.\n"));
818 Status
= EFI_ABORTED
;
821 RawSize
= ImageSize
- AllHeaderSize
;
824 // FmpDeviceLib CheckImage function to do any specific checks
826 Status
= FmpDeviceCheckImage ((((UINT8
*)Image
) + AllHeaderSize
), RawSize
, ImageUpdateable
);
827 if (EFI_ERROR (Status
)) {
828 DEBUG ((DEBUG_ERROR
, "FmpDxe: CheckTheImage() - FmpDeviceLib CheckImage failed. Status = %r\n", Status
));
836 Updates the firmware image of the device.
838 This function updates the hardware with the new firmware image.
839 This function returns EFI_UNSUPPORTED if the firmware image is not updatable.
840 If the firmware image is updatable, the function should perform the following minimal validations
841 before proceeding to do the firmware image update.
842 - Validate the image authentication if image has attribute
843 IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns
844 EFI_SECURITY_VIOLATION if the validation fails.
845 - Validate the image is a supported image for this device. The function returns EFI_ABORTED if
846 the image is unsupported. The function can optionally provide more detailed information on
847 why the image is not a supported image.
848 - Validate the data from VendorCode if not null. Image validation must be performed before
849 VendorCode data validation. VendorCode data is ignored or considered invalid if image
850 validation failed. The function returns EFI_ABORTED if the data is invalid.
852 VendorCode enables vendor to implement vendor-specific firmware image update policy. Null if
853 the caller did not specify the policy or use the default policy. As an example, vendor can implement
854 a policy to allow an option to force a firmware image update when the abort reason is due to the new
855 firmware image version is older than the current firmware image version or bad image checksum.
856 Sensitive operations such as those wiping the entire firmware image and render the device to be
857 non-functional should be encoded in the image itself rather than passed with the VendorCode.
858 AbortReason enables vendor to have the option to provide a more detailed description of the abort
859 reason to the caller.
861 @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
862 @param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
863 The number is between 1 and DescriptorCount.
864 @param[in] Image Points to the new image.
865 @param[in] ImageSize Size of the new image in bytes.
866 @param[in] VendorCode This enables vendor to implement vendor-specific firmware image update policy.
867 Null indicates the caller did not specify the policy or use the default policy.
868 @param[in] Progress A function used by the driver to report the progress of the firmware update.
869 @param[out] AbortReason A pointer to a pointer to a null-terminated string providing more
870 details for the aborted operation. The buffer is allocated by this function
871 with AllocatePool(), and it is the caller's responsibility to free it with a
874 @retval EFI_SUCCESS The device was successfully updated with the new image.
875 @retval EFI_ABORTED The operation is aborted.
876 @retval EFI_INVALID_PARAMETER The Image was NULL.
877 @retval EFI_UNSUPPORTED The operation is not supported.
878 @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure.
884 IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*This
,
886 IN CONST VOID
*Image
,
888 IN CONST VOID
*VendorCode
,
889 IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress
,
890 OUT CHAR16
**AbortReason
895 BOOLEAN BooleanValue
;
896 UINT32 FmpHeaderSize
;
898 UINTN FmpPayloadSize
;
899 UINT32 AllHeaderSize
;
900 UINT32 IncommingFwVersion
;
901 UINT32 LastAttemptStatus
;
903 Status
= EFI_SUCCESS
;
905 BooleanValue
= FALSE
;
910 IncommingFwVersion
= 0;
911 LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL
;
914 SetLastAttemptVersionInVariable (IncommingFwVersion
); //set to 0 to clear any previous results.
917 // if we have locked the device, then skip the set operation.
918 // it should be blocked by hardware too but we can catch here even faster
920 if (mFmpDeviceLocked
) {
921 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - Device is already locked. Can't update.\n"));
922 Status
= EFI_ACCESS_DENIED
;
927 // Call check image to verify the image
929 Status
= CheckTheImage (This
, ImageIndex
, Image
, ImageSize
, &Updateable
);
930 if (EFI_ERROR (Status
)) {
931 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - Check The Image failed with %r.\n", Status
));
932 if (Status
== EFI_SECURITY_VIOLATION
) {
933 LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR
;
939 // No functional error in CheckTheImage. Attempt to get the Version to
940 // support better error reporting.
942 FmpHeader
= GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION
*)Image
, ImageSize
, &FmpPayloadSize
);
943 if (FmpHeader
== NULL
) {
944 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - GetFmpHeader failed.\n"));
945 Status
= EFI_ABORTED
;
948 Status
= GetFmpPayloadHeaderVersion (FmpHeader
, FmpPayloadSize
, &IncommingFwVersion
);
949 if (!EFI_ERROR (Status
)) {
951 // Set to actual value
953 SetLastAttemptVersionInVariable (IncommingFwVersion
);
957 if (Updateable
!= IMAGE_UPDATABLE_VALID
) {
960 "FmpDxed: SetTheImage() - Check The Image returned that the Image was not valid for update. Updatable value = 0x%X.\n",
963 Status
= EFI_ABORTED
;
967 if (Progress
== NULL
) {
968 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - Invalid progress callback\n"));
969 Status
= EFI_INVALID_PARAMETER
;
973 mProgressFunc
= Progress
;
974 mProgressSupported
= TRUE
;
977 // Checking the image is at least 1%
979 Status
= Progress (1);
980 if (EFI_ERROR (Status
)) {
981 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - Progress Callback failed with Status %r.\n", Status
));
987 Status
= CheckSystemPower (&BooleanValue
);
988 if (EFI_ERROR (Status
)) {
989 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - CheckSystemPower - API call failed %r.\n", Status
));
993 Status
= EFI_ABORTED
;
996 "FmpDxe: SetTheImage() - CheckSystemPower - returned False. Update not allowed due to System Power.\n")
998 LastAttemptStatus
= LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT
;
1005 //Check System Thermal
1007 Status
= CheckSystemThermal (&BooleanValue
);
1008 if (EFI_ERROR (Status
)) {
1009 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - CheckSystemThermal - API call failed %r.\n", Status
));
1012 if (!BooleanValue
) {
1013 Status
= EFI_ABORTED
;
1016 "FmpDxe: SetTheImage() - CheckSystemThermal - returned False. Update not allowed due to System Thermal.\n")
1024 //Check System Environment
1026 Status
= CheckSystemEnvironment (&BooleanValue
);
1027 if (EFI_ERROR (Status
)) {
1028 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - CheckSystemEnvironment - API call failed %r.\n", Status
));
1031 if (!BooleanValue
) {
1032 Status
= EFI_ABORTED
;
1035 "FmpDxe: SetTheImage() - CheckSystemEnvironment - returned False. Update not allowed due to System Environment.\n")
1043 // Save LastAttemptStatus as error so that if SetImage never returns the error
1044 // state is recorded.
1046 SetLastAttemptStatusInVariable (LastAttemptStatus
);
1049 // Strip off all the headers so the device can process its firmware
1051 Status
= GetFmpPayloadHeaderSize (FmpHeader
, FmpPayloadSize
, &FmpHeaderSize
);
1052 if (EFI_ERROR (Status
)) {
1053 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - GetFmpPayloadHeaderSize failed %r.\n", Status
));
1057 AllHeaderSize
= GetAllHeaderSize ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION
*)Image
, FmpHeaderSize
);
1058 if (AllHeaderSize
== 0) {
1059 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() - GetAllHeaderSize failed.\n"));
1060 Status
= EFI_ABORTED
;
1065 // Indicate that control is handed off to FmpDeviceLib
1070 //Copy the requested image to the firmware using the FmpDeviceLib
1072 Status
= FmpDeviceSetImage (
1073 (((UINT8
*)Image
) + AllHeaderSize
),
1074 ImageSize
- AllHeaderSize
,
1080 if (EFI_ERROR (Status
)) {
1081 DEBUG ((DEBUG_ERROR
, "FmpDxe: SetTheImage() SetImage from FmpDeviceLib failed. Status = %r.\n", Status
));
1087 // Finished the update without error
1088 // Indicate that control has been returned from FmpDeviceLib
1093 // Update the version stored in variable
1095 if (!mRuntimeVersionSupported
) {
1096 UINT32 Version
= DEFAULT_VERSION
;
1097 GetFmpPayloadHeaderVersion (FmpHeader
, FmpPayloadSize
, &Version
);
1098 SetVersionInVariable (Version
);
1102 // Update lowest supported variable
1105 UINT32 Version
= DEFAULT_LOWESTSUPPORTEDVERSION
;
1106 GetFmpPayloadHeaderLowestSupportedVersion (FmpHeader
, FmpPayloadSize
, &Version
);
1107 SetLowestSupportedVersionInVariable (Version
);
1110 LastAttemptStatus
= LAST_ATTEMPT_STATUS_SUCCESS
;
1113 // Set flag so the descriptor is repopulated
1114 // This only applied to devices that do not require system reboot
1116 if (!PcdGetBool (PcdFmpDeviceSystemResetRequired
)) {
1117 mDescriptorPopulated
= FALSE
;
1121 mProgressFunc
= NULL
;
1122 mProgressSupported
= FALSE
;
1123 SetLastAttemptStatusInVariable (LastAttemptStatus
);
1125 if (Progress
!= NULL
) {
1127 // Set progress to 100 after everything is done including recording Status.
1136 Returns information about the firmware package.
1138 This function returns package information.
1140 @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
1141 @param[out] PackageVersion A version number that represents all the firmware images in the device.
1142 The format is vendor specific and new version must have a greater value
1143 than the old version. If PackageVersion is not supported, the value is
1144 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version
1145 comparison is to be performed using PackageVersionName. A value of
1146 0xFFFFFFFD indicates that package version update is in progress.
1147 @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing
1148 the package version name. The buffer is allocated by this function with
1149 AllocatePool(), and it is the caller's responsibility to free it with a
1151 @param[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of
1152 package version name. A value of 0 indicates the device does not support
1153 update of package version name. Length is the number of Unicode characters,
1154 including the terminating null character.
1155 @param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute
1156 Definitions' for possible returned values of this parameter. A value of 1
1157 indicates the attribute is supported and the current setting value is
1158 indicated in AttributesSetting. A value of 0 indicates the attribute is not
1159 supported and the current setting value in AttributesSetting is meaningless.
1160 @param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned
1161 values of this parameter
1163 @retval EFI_SUCCESS The package information was successfully returned.
1164 @retval EFI_UNSUPPORTED The operation is not supported.
1170 IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*This
,
1171 OUT UINT32
*PackageVersion
,
1172 OUT CHAR16
**PackageVersionName
,
1173 OUT UINT32
*PackageVersionNameMaxLen
,
1174 OUT UINT64
*AttributesSupported
,
1175 OUT UINT64
*AttributesSetting
1178 return EFI_UNSUPPORTED
;
1182 Updates information about the firmware package.
1184 This function updates package information.
1185 This function returns EFI_UNSUPPORTED if the package information is not updatable.
1186 VendorCode enables vendor to implement vendor-specific package information update policy.
1187 Null if the caller did not specify this policy or use the default policy.
1189 @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
1190 @param[in] Image Points to the authentication image.
1191 Null if authentication is not required.
1192 @param[in] ImageSize Size of the authentication image in bytes.
1193 0 if authentication is not required.
1194 @param[in] VendorCode This enables vendor to implement vendor-specific firmware
1195 image update policy.
1196 Null indicates the caller did not specify this policy or use
1198 @param[in] PackageVersion The new package version.
1199 @param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing
1200 the package version name.
1201 The string length is equal to or less than the value returned in
1202 PackageVersionNameMaxLen.
1204 @retval EFI_SUCCESS The device was successfully updated with the new package
1206 @retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value
1207 returned in PackageVersionNameMaxLen.
1208 @retval EFI_UNSUPPORTED The operation is not supported.
1209 @retval EFI_SECURITY_VIOLATIO The operation could not be performed due to an authentication failure.
1215 IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*This
,
1216 IN CONST VOID
*Image
,
1218 IN CONST VOID
*VendorCode
,
1219 IN UINT32 PackageVersion
,
1220 IN CONST CHAR16
*PackageVersionName
1223 return EFI_UNSUPPORTED
;
1227 Event notification function that is invoked when the event GUID specified by
1228 PcdFmpDeviceLockEventGuid is signaled.
1230 @param[in] Event Event whose notification function is being invoked.
1231 @param[in] Context The pointer to the notification function's context,
1232 which is implementation-dependent.
1236 FmpDxeLockEventNotify (
1243 if (!mFmpDeviceLocked
) {
1244 if (IsLockFmpDeviceAtLockEventGuidRequired ()) {
1246 // Lock all UEFI Variables used by this module.
1248 Status
= LockAllFmpVariables ();
1249 if (EFI_ERROR (Status
)) {
1250 DEBUG ((DEBUG_ERROR
, "FmpDxe: Failed to lock variables. Status = %r.\n"));
1252 DEBUG ((DEBUG_INFO
, "FmpDxe: All variables locked\n"));
1256 // Lock the firmware device
1258 Status
= FmpDeviceLock();
1259 if (EFI_ERROR (Status
)) {
1260 if (Status
!= EFI_UNSUPPORTED
) {
1261 DEBUG ((DEBUG_ERROR
, "FmpDxe: FmpDeviceLock() returned error. Status = %r\n", Status
));
1263 DEBUG ((DEBUG_WARN
, "FmpDxe: FmpDeviceLock() returned error. Status = %r\n", Status
));
1266 mFmpDeviceLocked
= TRUE
;
1268 DEBUG ((DEBUG_VERBOSE
, "FmpDxe: Not calling FmpDeviceLock() because mfg mode\n"));
1274 Function to install FMP instance.
1276 @param[in] Handle The device handle to install a FMP instance on.
1278 @retval EFI_SUCCESS FMP Installed
1279 @retval EFI_INVALID_PARAMETER Handle was invalid
1280 @retval other Error installing FMP
1285 InstallFmpInstance (
1286 IN EFI_HANDLE Handle
1290 EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*Fmp
;
1291 EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL
*FmpProgress
;
1293 Status
= EFI_SUCCESS
;
1298 // Only allow a single FMP Protocol instance to be installed
1300 if (mFmpInstalled
) {
1301 return EFI_ALREADY_STARTED
;
1305 // Allocate FMP Protocol instance
1307 Fmp
= AllocateZeroPool (sizeof (EFI_FIRMWARE_MANAGEMENT_PROTOCOL
));
1309 DEBUG ((DEBUG_ERROR
, "FmpDxe: Failed to allocate memory for FMP Protocol instance.\n"));
1310 Status
= EFI_OUT_OF_RESOURCES
;
1315 // Allocate FMP Progress Protocol instance
1317 FmpProgress
= AllocateZeroPool (sizeof (EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL
));
1318 if (FmpProgress
== NULL
) {
1319 DEBUG ((DEBUG_ERROR
, "FmpDxe: Failed to allocate memory for FMP Progress Protocol instance.\n"));
1320 Status
= EFI_OUT_OF_RESOURCES
;
1326 // Set up FMP Protocol function pointers
1328 Fmp
->GetImageInfo
= GetTheImageInfo
;
1329 Fmp
->GetImage
= GetTheImage
;
1330 Fmp
->SetImage
= SetTheImage
;
1331 Fmp
->CheckImage
= CheckTheImage
;
1332 Fmp
->GetPackageInfo
= GetPackageInfo
;
1333 Fmp
->SetPackageInfo
= SetPackageInfo
;
1336 // Fill in FMP Progress Protocol fields for Version 1
1338 FmpProgress
->Version
= 1;
1339 FmpProgress
->ProgressBarForegroundColor
.Raw
= PcdGet32 (PcdFmpDeviceProgressColor
);
1340 FmpProgress
->WatchdogSeconds
= PcdGet8 (PcdFmpDeviceProgressWatchdogTimeInSeconds
);
1343 // Install FMP Protocol and FMP Progress Protocol
1345 Status
= gBS
->InstallMultipleProtocolInterfaces (
1347 &gEfiFirmwareManagementProtocolGuid
,
1349 &gEdkiiFirmwareManagementProgressProtocolGuid
,
1354 if (EFI_ERROR (Status
)) {
1355 DEBUG ((DEBUG_ERROR
, "FmpDxe: FMP Protocol install error. Status = %r.\n", Status
));
1360 DEBUG ((DEBUG_INFO
, "FmpDxe: FMP Protocol Installed!\n"));
1361 mFmpInstalled
= TRUE
;
1369 Main entry for this driver/library.
1371 @param[in] ImageHandle Image handle this driver.
1372 @param[in] SystemTable Pointer to SystemTable.
1378 IN EFI_HANDLE ImageHandle
,
1379 IN EFI_SYSTEM_TABLE
*SystemTable
1386 // Verify that a new FILE_GUID value has been provided in the <Defines>
1387 // section of this module. The FILE_GUID is the ESRT GUID that must be
1388 // unique for each updatable firmware image.
1390 if (CompareGuid (&mDefaultModuleFileGuid
, &gEfiCallerIdGuid
)) {
1391 DEBUG ((DEBUG_ERROR
, "FmpDxe: Use of default FILE_GUID detected. FILE_GUID must be set to a unique value.\n"));
1393 return EFI_UNSUPPORTED
;
1397 // Get the ImageIdName value for the EFI_FIRMWARE_IMAGE_DESCRIPTOR from a PCD.
1399 mImageIdName
= (CHAR16
*) PcdGetPtr (PcdFmpDeviceImageIdName
);
1400 if (PcdGetSize (PcdFmpDeviceImageIdName
) <= 2 || mImageIdName
[0] == 0) {
1402 // PcdFmpDeviceImageIdName must be set to a non-empty Unicode string
1404 DEBUG ((DEBUG_ERROR
, "FmpDxe: FmpDeviceLib PcdFmpDeviceImageIdName is an empty string.\n"));
1409 // Detects if PcdFmpDevicePkcs7CertBufferXdr contains a test key.
1414 // Register with library the install function so if the library uses
1415 // UEFI driver model/driver binding protocol it can install FMP on its device handle
1416 // If library is simple lib that does not use driver binding then it should return
1417 // unsupported and this will install the FMP instance on the ImageHandle
1419 Status
= RegisterFmpInstaller (InstallFmpInstance
);
1420 if (Status
== EFI_UNSUPPORTED
) {
1421 DEBUG ((DEBUG_INFO
, "FmpDxe: FmpDeviceLib registration returned EFI_UNSUPPORTED. Installing single FMP instance.\n"));
1422 Status
= InstallFmpInstance (ImageHandle
);
1423 } else if (EFI_ERROR (Status
)) {
1424 DEBUG ((DEBUG_ERROR
, "FmpDxe: FmpDeviceLib registration returned %r. No FMP installed.\n", Status
));
1428 "FmpDxe: FmpDeviceLib registration returned EFI_SUCCESS. Expect FMP to be installed during the BDS/Device connection phase.\n"
1433 // Register notify function to lock the FMP device.
1434 // The lock event GUID is retrieved from PcdFmpDeviceLockEventGuid.
1435 // If PcdFmpDeviceLockEventGuid is not the size of an EFI_GUID, then
1436 // gEfiEndOfDxeEventGroupGuid is used.
1438 LockGuid
= &gEfiEndOfDxeEventGroupGuid
;
1439 if (PcdGetSize (PcdFmpDeviceLockEventGuid
) == sizeof (EFI_GUID
)) {
1440 LockGuid
= (EFI_GUID
*)PcdGetPtr (PcdFmpDeviceLockEventGuid
);
1442 DEBUG ((DEBUG_INFO
, "FmpDxe: Lock GUID: %g\n", LockGuid
));
1444 Status
= gBS
->CreateEventEx (
1447 FmpDxeLockEventNotify
,
1450 &mFmpDeviceLockEvent
1452 if (EFI_ERROR (Status
)) {
1453 DEBUG ((DEBUG_ERROR
, "FmpDxe: Failed to register for ready to boot. Status = %r\n", Status
));
1455 ASSERT_EFI_ERROR (Status
);