2 Initialize TPM2 device and measure FVs before handing off control to DXE.
4 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <IndustryStandard/UefiTcgPlatform.h>
18 #include <Ppi/FirmwareVolumeInfo.h>
19 #include <Ppi/FirmwareVolumeInfo2.h>
20 #include <Ppi/LockPhysicalPresence.h>
21 #include <Ppi/TpmInitialized.h>
22 #include <Ppi/FirmwareVolume.h>
23 #include <Ppi/EndOfPeiPhase.h>
24 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
26 #include <Guid/TcgEventHob.h>
27 #include <Guid/MeasuredFvHob.h>
28 #include <Guid/TpmInstance.h>
30 #include <Library/DebugLib.h>
31 #include <Library/BaseMemoryLib.h>
32 #include <Library/PeiServicesLib.h>
33 #include <Library/PeimEntryPoint.h>
34 #include <Library/Tpm2CommandLib.h>
35 #include <Library/Tpm2DeviceLib.h>
36 #include <Library/HashLib.h>
37 #include <Library/HobLib.h>
38 #include <Library/PcdLib.h>
39 #include <Library/PeiServicesTablePointerLib.h>
40 #include <Protocol/TrEEProtocol.h>
41 #include <Library/PerformanceLib.h>
42 #include <Library/MemoryAllocationLib.h>
43 #include <Library/ReportStatusCodeLib.h>
45 #define PERF_ID_TREE_PEI 0x3080
49 TREE_EVENT_LOG_FORMAT LogFormat
;
50 } TREE_EVENT_INFO_STRUCT
;
52 TREE_EVENT_INFO_STRUCT mTreeEventInfo
[] = {
53 {&gTcgEventEntryHobGuid
, TREE_EVENT_LOG_FORMAT_TCG_1_2
},
56 BOOLEAN mImageInMemory
= FALSE
;
57 EFI_PEI_FILE_HANDLE mFileHandle
;
59 EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList
= {
60 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
61 &gPeiTpmInitializedPpiGuid
,
65 EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList
= {
66 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
67 &gPeiTpmInitializationDonePpiGuid
,
71 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredBaseFvInfo
;
72 UINT32 mMeasuredBaseFvIndex
= 0;
74 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredChildFvInfo
;
75 UINT32 mMeasuredChildFvIndex
= 0;
78 Measure and record the Firmware Volum Information once FvInfoPPI install.
80 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
81 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
82 @param[in] Ppi Address of the PPI that was installed.
84 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
85 @return Others Fail to measure FV.
90 FirmwareVolmeInfoPpiNotifyCallback (
91 IN EFI_PEI_SERVICES
**PeiServices
,
92 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
97 Record all measured Firmware Volum Information into a Guid Hob
99 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
100 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
101 @param[in] Ppi Address of the PPI that was installed.
103 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
104 @return Others Fail to measure FV.
109 EndofPeiSignalNotifyCallBack (
110 IN EFI_PEI_SERVICES
**PeiServices
,
111 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
115 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList
[] = {
117 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
118 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
119 FirmwareVolmeInfoPpiNotifyCallback
122 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
123 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
124 FirmwareVolmeInfoPpiNotifyCallback
127 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
128 &gEfiEndOfPeiSignalPpiGuid
,
129 EndofPeiSignalNotifyCallBack
133 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI
*mMeasurementExcludedFvPpi
;
136 Record all measured Firmware Volum Information into a Guid Hob
137 Guid Hob payload layout is
139 UINT32 *************************** FIRMWARE_BLOB number
140 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
142 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
143 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
144 @param[in] Ppi Address of the PPI that was installed.
146 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
147 @return Others Fail to measure FV.
152 EndofPeiSignalNotifyCallBack (
153 IN EFI_PEI_SERVICES
**PeiServices
,
154 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
158 MEASURED_HOB_DATA
*MeasuredHobData
;
160 MeasuredHobData
= NULL
;
163 // Create a Guid hob to save all measured Fv
165 MeasuredHobData
= BuildGuidHob(
167 sizeof(UINTN
) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
)
170 if (MeasuredHobData
!= NULL
){
172 // Save measured FV info enty number
174 MeasuredHobData
->Num
= mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
;
177 // Save measured base Fv info
179 CopyMem (MeasuredHobData
->MeasuredFvBuf
, mMeasuredBaseFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
));
182 // Save measured child Fv info
184 CopyMem (&MeasuredHobData
->MeasuredFvBuf
[mMeasuredBaseFvIndex
] , mMeasuredChildFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredChildFvIndex
));
191 Add a new entry to the Event Log.
193 @param[in] DigestList A list of digest.
194 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
195 @param[in] NewEventData Pointer to the new event data.
197 @retval EFI_SUCCESS The new event log entry was added.
198 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
202 IN TPML_DIGEST_VALUES
*DigestList
,
203 IN OUT TCG_PCR_EVENT_HDR
*NewEventHdr
,
204 IN UINT8
*NewEventData
210 EFI_STATUS RetStatus
;
212 RetStatus
= EFI_SUCCESS
;
213 for (Index
= 0; Index
< sizeof(mTreeEventInfo
)/sizeof(mTreeEventInfo
[0]); Index
++) {
214 DEBUG ((EFI_D_INFO
, " LogFormat - 0x%08x\n", mTreeEventInfo
[Index
].LogFormat
));
215 switch (mTreeEventInfo
[Index
].LogFormat
) {
216 case TREE_EVENT_LOG_FORMAT_TCG_1_2
:
217 Status
= GetDigestFromDigestList (TPM_ALG_SHA1
, DigestList
, &NewEventHdr
->Digest
);
218 if (!EFI_ERROR (Status
)) {
219 HobData
= BuildGuidHob (
220 &gTcgEventEntryHobGuid
,
221 sizeof (*NewEventHdr
) + NewEventHdr
->EventSize
223 if (HobData
== NULL
) {
224 RetStatus
= EFI_OUT_OF_RESOURCES
;
228 CopyMem (HobData
, NewEventHdr
, sizeof (*NewEventHdr
));
229 HobData
= (VOID
*) ((UINT8
*)HobData
+ sizeof (*NewEventHdr
));
230 CopyMem (HobData
, NewEventData
, NewEventHdr
->EventSize
);
240 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
241 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
242 added into the Event Log.
244 @param[in] Flags Bitmap providing additional information.
245 @param[in] HashData Physical address of the start of the data buffer
246 to be hashed, extended, and logged.
247 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
248 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
249 @param[in] NewEventData Pointer to the new event data.
251 @retval EFI_SUCCESS Operation completed successfully.
252 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
253 @retval EFI_DEVICE_ERROR The command was unsuccessful.
260 IN UINTN HashDataLen
,
261 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
262 IN UINT8
*NewEventData
266 TPML_DIGEST_VALUES DigestList
;
268 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
269 return EFI_DEVICE_ERROR
;
272 Status
= HashAndExtend (
273 NewEventHdr
->PCRIndex
,
278 if (!EFI_ERROR (Status
)) {
279 if ((Flags
& TREE_EXTEND_ONLY
) == 0) {
280 Status
= LogHashEvent (&DigestList
, NewEventHdr
, NewEventData
);
284 if (Status
== EFI_DEVICE_ERROR
) {
285 DEBUG ((EFI_D_ERROR
, "HashLogExtendEvent - %r. Disable TPM.\n", Status
));
286 BuildGuidHob (&gTpmErrorHobGuid
,0);
288 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
289 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
297 Measure CRTM version.
299 @retval EFI_SUCCESS Operation completed successfully.
300 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
301 @retval EFI_DEVICE_ERROR The command was unsuccessful.
309 TCG_PCR_EVENT_HDR TcgEventHdr
;
312 // Use FirmwareVersion string to represent CRTM version.
313 // OEMs should get real CRTM version string and measure it.
316 TcgEventHdr
.PCRIndex
= 0;
317 TcgEventHdr
.EventType
= EV_S_CRTM_VERSION
;
318 TcgEventHdr
.EventSize
= (UINT32
) StrSize((CHAR16
*)PcdGetPtr (PcdFirmwareVersionString
));
320 return HashLogExtendEvent (
322 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
),
323 TcgEventHdr
.EventSize
,
325 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
)
331 Add it into the measured FV list after the FV is measured successfully.
333 @param[in] FvBase Base address of FV image.
334 @param[in] FvLength Length of FV image.
336 @retval EFI_SUCCESS Fv image is measured successfully
337 or it has been already measured.
338 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
339 @retval EFI_DEVICE_ERROR The command was unsuccessful.
344 IN EFI_PHYSICAL_ADDRESS FvBase
,
350 EFI_PLATFORM_FIRMWARE_BLOB FvBlob
;
351 TCG_PCR_EVENT_HDR TcgEventHdr
;
354 // Check if it is in Excluded FV list
356 if (mMeasurementExcludedFvPpi
!= NULL
) {
357 for (Index
= 0; Index
< mMeasurementExcludedFvPpi
->Count
; Index
++) {
358 if (mMeasurementExcludedFvPpi
->Fv
[Index
].FvBase
== FvBase
) {
359 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TrEEPei starts at: 0x%x\n", FvBase
));
360 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TrEEPei has the size: 0x%x\n", FvLength
));
367 // Check whether FV is in the measured FV list.
369 for (Index
= 0; Index
< mMeasuredBaseFvIndex
; Index
++) {
370 if (mMeasuredBaseFvInfo
[Index
].BlobBase
== FvBase
) {
376 // Measure and record the FV to the TPM
378 FvBlob
.BlobBase
= FvBase
;
379 FvBlob
.BlobLength
= FvLength
;
381 DEBUG ((DEBUG_INFO
, "The FV which is measured by TrEEPei starts at: 0x%x\n", FvBlob
.BlobBase
));
382 DEBUG ((DEBUG_INFO
, "The FV which is measured by TrEEPei has the size: 0x%x\n", FvBlob
.BlobLength
));
384 TcgEventHdr
.PCRIndex
= 0;
385 TcgEventHdr
.EventType
= EV_EFI_PLATFORM_FIRMWARE_BLOB
;
386 TcgEventHdr
.EventSize
= sizeof (FvBlob
);
388 Status
= HashLogExtendEvent (
390 (UINT8
*) (UINTN
) FvBlob
.BlobBase
,
391 (UINTN
) FvBlob
.BlobLength
,
397 // Add new FV into the measured FV list.
399 ASSERT (mMeasuredBaseFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
));
400 if (mMeasuredBaseFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
401 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobBase
= FvBase
;
402 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobLength
= FvLength
;
403 mMeasuredBaseFvIndex
++;
412 @retval EFI_SUCCESS Operation completed successfully.
413 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
414 @retval EFI_DEVICE_ERROR The command was unsuccessful.
424 EFI_PEI_FV_HANDLE VolumeHandle
;
425 EFI_FV_INFO VolumeInfo
;
426 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
428 PERF_START_EX (mFileHandle
, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI
);
432 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
433 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
434 // platform for special CRTM TPM measuring.
436 Status
= PeiServicesFfsFindNextVolume (FvInstances
, &VolumeHandle
);
437 if (EFI_ERROR (Status
)) {
442 // Measure and record the firmware volume that is dispatched by PeiCore
444 Status
= PeiServicesFfsGetVolumeInfo (VolumeHandle
, &VolumeInfo
);
445 ASSERT_EFI_ERROR (Status
);
447 // Locate the corresponding FV_PPI according to founded FV's format guid
449 Status
= PeiServicesLocatePpi (
450 &VolumeInfo
.FvFormat
,
455 if (!EFI_ERROR (Status
)) {
456 MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) VolumeInfo
.FvStart
, VolumeInfo
.FvSize
);
461 PERF_END_EX (mFileHandle
, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI
+ 1);
467 Measure and record the Firmware Volum Information once FvInfoPPI install.
469 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
470 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
471 @param[in] Ppi Address of the PPI that was installed.
473 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
474 @return Others Fail to measure FV.
479 FirmwareVolmeInfoPpiNotifyCallback (
480 IN EFI_PEI_SERVICES
**PeiServices
,
481 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
485 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
487 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
490 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*) Ppi
;
493 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
495 Status
= PeiServicesLocatePpi (
501 if (EFI_ERROR (Status
)) {
506 // This is an FV from an FFS file, and the parent FV must have already been measured,
507 // No need to measure twice, so just record the FV and return
509 if (Fv
->ParentFvName
!= NULL
|| Fv
->ParentFileName
!= NULL
) {
511 ASSERT (mMeasuredChildFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
));
512 if (mMeasuredChildFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
514 // Check whether FV is in the measured child FV list.
516 for (Index
= 0; Index
< mMeasuredChildFvIndex
; Index
++) {
517 if (mMeasuredChildFvInfo
[Index
].BlobBase
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
) {
521 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
;
522 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobLength
= Fv
->FvInfoSize
;
523 mMeasuredChildFvIndex
++;
528 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
, Fv
->FvInfoSize
);
532 Do measurement after memory is ready.
534 @param[in] PeiServices Describes the list of possible PEI Services.
536 @retval EFI_SUCCESS Operation completed successfully.
537 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
538 @retval EFI_DEVICE_ERROR The command was unsuccessful.
543 IN EFI_PEI_SERVICES
**PeiServices
548 Status
= PeiServicesLocatePpi (
549 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid
,
552 (VOID
**)&mMeasurementExcludedFvPpi
554 // Do not check status, because it is optional
556 mMeasuredBaseFvInfo
= (EFI_PLATFORM_FIRMWARE_BLOB
*) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * PcdGet32 (PcdPeiCoreMaxFvSupported
));
557 ASSERT (mMeasuredBaseFvInfo
!= NULL
);
558 mMeasuredChildFvInfo
= (EFI_PLATFORM_FIRMWARE_BLOB
*) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * PcdGet32 (PcdPeiCoreMaxFvSupported
));
559 ASSERT (mMeasuredChildFvInfo
!= NULL
);
561 if (PcdGet8 (PcdTpm2ScrtmPolicy
) == 1) {
562 Status
= MeasureCRTMVersion ();
565 Status
= MeasureMainBios ();
569 // for the FvInfoPpi services to measure and record
570 // the additional Fvs to TPM
572 Status
= PeiServicesNotifyPpi (&mNotifyList
[0]);
573 ASSERT_EFI_ERROR (Status
);
579 Entry point of this module.
581 @param[in] FileHandle Handle of the file being invoked.
582 @param[in] PeiServices Describes the list of possible PEI Services.
590 IN EFI_PEI_FILE_HANDLE FileHandle
,
591 IN CONST EFI_PEI_SERVICES
**PeiServices
596 EFI_BOOT_MODE BootMode
;
598 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceNoneGuid
) ||
599 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
600 DEBUG ((EFI_D_ERROR
, "No TPM2 instance required!\n"));
601 return EFI_UNSUPPORTED
;
604 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
605 DEBUG ((EFI_D_ERROR
, "TPM2 error!\n"));
606 return EFI_DEVICE_ERROR
;
609 Status
= PeiServicesGetBootMode (&BootMode
);
610 ASSERT_EFI_ERROR (Status
);
613 // In S3 path, skip shadow logic. no measurement is required
615 if (BootMode
!= BOOT_ON_S3_RESUME
) {
616 Status
= (**PeiServices
).RegisterForShadow(FileHandle
);
617 if (Status
== EFI_ALREADY_STARTED
) {
618 mImageInMemory
= TRUE
;
619 mFileHandle
= FileHandle
;
620 } else if (Status
== EFI_NOT_FOUND
) {
621 ASSERT_EFI_ERROR (Status
);
625 if (!mImageInMemory
) {
627 // Initialize TPM device
629 Status
= Tpm2RequestUseTpm ();
630 if (EFI_ERROR (Status
)) {
631 DEBUG ((DEBUG_ERROR
, "TPM2 not detected!\n"));
635 if (PcdGet8 (PcdTpm2InitializationPolicy
) == 1) {
636 if (BootMode
== BOOT_ON_S3_RESUME
) {
637 Status
= Tpm2Startup (TPM_SU_STATE
);
638 if (EFI_ERROR (Status
) ) {
639 Status
= Tpm2Startup (TPM_SU_CLEAR
);
642 Status
= Tpm2Startup (TPM_SU_CLEAR
);
644 if (EFI_ERROR (Status
) ) {
650 // TpmSelfTest is optional on S3 path, skip it to save S3 time
652 if (BootMode
!= BOOT_ON_S3_RESUME
) {
653 if (PcdGet8 (PcdTpm2SelfTestPolicy
) == 1) {
654 Status
= Tpm2SelfTest (NO
);
655 if (EFI_ERROR (Status
)) {
662 // Only intall TpmInitializedPpi on success
664 Status
= PeiServicesInstallPpi (&mTpmInitializedPpiList
);
665 ASSERT_EFI_ERROR (Status
);
668 if (mImageInMemory
) {
669 Status
= PeimEntryMP ((EFI_PEI_SERVICES
**)PeiServices
);
674 if (EFI_ERROR (Status
)) {
675 DEBUG ((EFI_D_ERROR
, "TPM2 error! Build Hob\n"));
676 BuildGuidHob (&gTpmErrorHobGuid
,0);
678 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
679 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
683 // Always intall TpmInitializationDonePpi no matter success or fail.
684 // Other driver can know TPM initialization state by TpmInitializedPpi.
686 Status2
= PeiServicesInstallPpi (&mTpmInitializationDonePpiList
);
687 ASSERT_EFI_ERROR (Status2
);