2 Initialize TPM2 device and measure FVs before handing off control to DXE.
\r
4 Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>
\r
5 This program and the accompanying materials
\r
6 are licensed and made available under the terms and conditions of the BSD License
\r
7 which accompanies this distribution. The full text of the license may be found at
\r
8 http://opensource.org/licenses/bsd-license.php
\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
\r
17 #include <IndustryStandard/UefiTcgPlatform.h>
\r
18 #include <Ppi/FirmwareVolumeInfo.h>
\r
19 #include <Ppi/FirmwareVolumeInfo2.h>
\r
20 #include <Ppi/LockPhysicalPresence.h>
\r
21 #include <Ppi/TpmInitialized.h>
\r
22 #include <Ppi/FirmwareVolume.h>
\r
23 #include <Ppi/EndOfPeiPhase.h>
\r
24 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
\r
26 #include <Guid/TcgEventHob.h>
\r
27 #include <Guid/MeasuredFvHob.h>
\r
28 #include <Guid/TpmInstance.h>
\r
30 #include <Library/DebugLib.h>
\r
31 #include <Library/BaseMemoryLib.h>
\r
32 #include <Library/PeiServicesLib.h>
\r
33 #include <Library/PeimEntryPoint.h>
\r
34 #include <Library/Tpm2CommandLib.h>
\r
35 #include <Library/Tpm2DeviceLib.h>
\r
36 #include <Library/HashLib.h>
\r
37 #include <Library/HobLib.h>
\r
38 #include <Library/PcdLib.h>
\r
39 #include <Library/PeiServicesTablePointerLib.h>
\r
40 #include <Protocol/TrEEProtocol.h>
\r
41 #include <Library/PerformanceLib.h>
\r
42 #include <Library/MemoryAllocationLib.h>
\r
43 #include <Library/ReportStatusCodeLib.h>
\r
45 #define PERF_ID_TREE_PEI 0x3080
\r
48 EFI_GUID *EventGuid;
\r
49 TREE_EVENT_LOG_FORMAT LogFormat;
\r
50 } TREE_EVENT_INFO_STRUCT;
\r
52 TREE_EVENT_INFO_STRUCT mTreeEventInfo[] = {
\r
53 {&gTcgEventEntryHobGuid, TREE_EVENT_LOG_FORMAT_TCG_1_2},
\r
56 BOOLEAN mImageInMemory = FALSE;
\r
57 EFI_PEI_FILE_HANDLE mFileHandle;
\r
59 EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {
\r
60 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
\r
61 &gPeiTpmInitializedPpiGuid,
\r
65 EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredBaseFvInfo;
\r
66 UINT32 mMeasuredBaseFvIndex = 0;
\r
68 EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo;
\r
69 UINT32 mMeasuredChildFvIndex = 0;
\r
72 Measure and record the Firmware Volum Information once FvInfoPPI install.
\r
74 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
\r
75 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
76 @param[in] Ppi Address of the PPI that was installed.
\r
78 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
\r
79 @return Others Fail to measure FV.
\r
84 FirmwareVolmeInfoPpiNotifyCallback (
\r
85 IN EFI_PEI_SERVICES **PeiServices,
\r
86 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
91 Record all measured Firmware Volum Information into a Guid Hob
\r
93 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
\r
94 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
95 @param[in] Ppi Address of the PPI that was installed.
\r
97 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
\r
98 @return Others Fail to measure FV.
\r
103 EndofPeiSignalNotifyCallBack (
\r
104 IN EFI_PEI_SERVICES **PeiServices,
\r
105 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
109 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
\r
111 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
\r
112 &gEfiPeiFirmwareVolumeInfoPpiGuid,
\r
113 FirmwareVolmeInfoPpiNotifyCallback
\r
116 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
\r
117 &gEfiPeiFirmwareVolumeInfo2PpiGuid,
\r
118 FirmwareVolmeInfoPpiNotifyCallback
\r
121 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
\r
122 &gEfiEndOfPeiSignalPpiGuid,
\r
123 EndofPeiSignalNotifyCallBack
\r
127 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;
\r
130 This function get digest from digest list.
\r
132 @param HashAlg digest algorithm
\r
133 @param DigestList digest list
\r
134 @param Digest digest
\r
136 @retval EFI_SUCCESS Sha1Digest is found and returned.
\r
137 @retval EFI_NOT_FOUND Sha1Digest is not found.
\r
140 Tpm2GetDigestFromDigestList (
\r
141 IN TPMI_ALG_HASH HashAlg,
\r
142 IN TPML_DIGEST_VALUES *DigestList,
\r
149 DigestSize = GetHashSizeFromAlgo (HashAlg);
\r
150 for (Index = 0; Index < DigestList->count; Index++) {
\r
151 if (DigestList->digests[Index].hashAlg == HashAlg) {
\r
154 &DigestList->digests[Index].digest,
\r
157 return EFI_SUCCESS;
\r
161 return EFI_NOT_FOUND;
\r
165 Record all measured Firmware Volum Information into a Guid Hob
\r
166 Guid Hob payload layout is
\r
168 UINT32 *************************** FIRMWARE_BLOB number
\r
169 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
\r
171 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
\r
172 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
173 @param[in] Ppi Address of the PPI that was installed.
\r
175 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
\r
176 @return Others Fail to measure FV.
\r
181 EndofPeiSignalNotifyCallBack (
\r
182 IN EFI_PEI_SERVICES **PeiServices,
\r
183 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
187 MEASURED_HOB_DATA *MeasuredHobData;
\r
189 MeasuredHobData = NULL;
\r
192 // Create a Guid hob to save all measured Fv
\r
194 MeasuredHobData = BuildGuidHob(
\r
195 &gMeasuredFvHobGuid,
\r
196 sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)
\r
199 if (MeasuredHobData != NULL){
\r
201 // Save measured FV info enty number
\r
203 MeasuredHobData->Num = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;
\r
206 // Save measured base Fv info
\r
208 CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));
\r
211 // Save measured child Fv info
\r
213 CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));
\r
216 return EFI_SUCCESS;
\r
220 Add a new entry to the Event Log.
\r
222 @param[in] DigestList A list of digest.
\r
223 @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
\r
224 @param[in] NewEventData Pointer to the new event data.
\r
226 @retval EFI_SUCCESS The new event log entry was added.
\r
227 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
231 IN TPML_DIGEST_VALUES *DigestList,
\r
232 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
\r
233 IN UINT8 *NewEventData
\r
239 EFI_STATUS RetStatus;
\r
241 RetStatus = EFI_SUCCESS;
\r
242 for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) {
\r
243 DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTreeEventInfo[Index].LogFormat));
\r
244 switch (mTreeEventInfo[Index].LogFormat) {
\r
245 case TREE_EVENT_LOG_FORMAT_TCG_1_2:
\r
246 Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest);
\r
247 if (!EFI_ERROR (Status)) {
\r
248 HobData = BuildGuidHob (
\r
249 &gTcgEventEntryHobGuid,
\r
250 sizeof (*NewEventHdr) + NewEventHdr->EventSize
\r
252 if (HobData == NULL) {
\r
253 RetStatus = EFI_OUT_OF_RESOURCES;
\r
257 CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));
\r
258 HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));
\r
259 CopyMem (HobData, NewEventData, NewEventHdr->EventSize);
\r
269 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
\r
270 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
\r
271 added into the Event Log.
\r
273 @param[in] Flags Bitmap providing additional information.
\r
274 @param[in] HashData Physical address of the start of the data buffer
\r
275 to be hashed, extended, and logged.
\r
276 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
\r
277 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
\r
278 @param[in] NewEventData Pointer to the new event data.
\r
280 @retval EFI_SUCCESS Operation completed successfully.
\r
281 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
282 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
286 HashLogExtendEvent (
\r
288 IN UINT8 *HashData,
\r
289 IN UINTN HashDataLen,
\r
290 IN TCG_PCR_EVENT_HDR *NewEventHdr,
\r
291 IN UINT8 *NewEventData
\r
295 TPML_DIGEST_VALUES DigestList;
\r
297 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
\r
298 return EFI_DEVICE_ERROR;
\r
301 Status = HashAndExtend (
\r
302 NewEventHdr->PCRIndex,
\r
307 if (!EFI_ERROR (Status)) {
\r
308 if ((Flags & TREE_EXTEND_ONLY) == 0) {
\r
309 Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData);
\r
313 if (Status == EFI_DEVICE_ERROR) {
\r
314 DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
\r
315 BuildGuidHob (&gTpmErrorHobGuid,0);
\r
316 REPORT_STATUS_CODE (
\r
317 EFI_ERROR_CODE | EFI_ERROR_MINOR,
\r
318 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
\r
326 Measure CRTM version.
\r
328 @retval EFI_SUCCESS Operation completed successfully.
\r
329 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
330 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
334 MeasureCRTMVersion (
\r
338 TCG_PCR_EVENT_HDR TcgEventHdr;
\r
341 // Use FirmwareVersion string to represent CRTM version.
\r
342 // OEMs should get real CRTM version string and measure it.
\r
345 TcgEventHdr.PCRIndex = 0;
\r
346 TcgEventHdr.EventType = EV_S_CRTM_VERSION;
\r
347 TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));
\r
349 return HashLogExtendEvent (
\r
351 (UINT8*)PcdGetPtr (PcdFirmwareVersionString),
\r
352 TcgEventHdr.EventSize,
\r
354 (UINT8*)PcdGetPtr (PcdFirmwareVersionString)
\r
360 Add it into the measured FV list after the FV is measured successfully.
\r
362 @param[in] FvBase Base address of FV image.
\r
363 @param[in] FvLength Length of FV image.
\r
365 @retval EFI_SUCCESS Fv image is measured successfully
\r
366 or it has been already measured.
\r
367 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
368 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
373 IN EFI_PHYSICAL_ADDRESS FvBase,
\r
379 EFI_PLATFORM_FIRMWARE_BLOB FvBlob;
\r
380 TCG_PCR_EVENT_HDR TcgEventHdr;
\r
383 // Check if it is in Excluded FV list
\r
385 if (mMeasurementExcludedFvPpi != NULL) {
\r
386 for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) {
\r
387 if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) {
\r
388 DEBUG ((DEBUG_INFO, "The FV which is excluded by TrEEPei starts at: 0x%x\n", FvBase));
\r
389 DEBUG ((DEBUG_INFO, "The FV which is excluded by TrEEPei has the size: 0x%x\n", FvLength));
\r
390 return EFI_SUCCESS;
\r
396 // Check whether FV is in the measured FV list.
\r
398 for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {
\r
399 if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {
\r
400 return EFI_SUCCESS;
\r
405 // Measure and record the FV to the TPM
\r
407 FvBlob.BlobBase = FvBase;
\r
408 FvBlob.BlobLength = FvLength;
\r
410 DEBUG ((DEBUG_INFO, "The FV which is measured by TrEEPei starts at: 0x%x\n", FvBlob.BlobBase));
\r
411 DEBUG ((DEBUG_INFO, "The FV which is measured by TrEEPei has the size: 0x%x\n", FvBlob.BlobLength));
\r
413 TcgEventHdr.PCRIndex = 0;
\r
414 TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
\r
415 TcgEventHdr.EventSize = sizeof (FvBlob);
\r
417 Status = HashLogExtendEvent (
\r
419 (UINT8*) (UINTN) FvBlob.BlobBase,
\r
420 (UINTN) FvBlob.BlobLength,
\r
426 // Add new FV into the measured FV list.
\r
428 ASSERT (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
\r
429 if (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
\r
430 mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase;
\r
431 mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;
\r
432 mMeasuredBaseFvIndex++;
\r
441 @retval EFI_SUCCESS Operation completed successfully.
\r
442 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
443 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
452 UINT32 FvInstances;
\r
453 EFI_PEI_FV_HANDLE VolumeHandle;
\r
454 EFI_FV_INFO VolumeInfo;
\r
455 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
\r
457 PERF_START_EX (mFileHandle, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI);
\r
461 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
\r
462 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
\r
463 // platform for special CRTM TPM measuring.
\r
465 Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);
\r
466 if (EFI_ERROR (Status)) {
\r
471 // Measure and record the firmware volume that is dispatched by PeiCore
\r
473 Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
\r
474 ASSERT_EFI_ERROR (Status);
\r
476 // Locate the corresponding FV_PPI according to founded FV's format guid
\r
478 Status = PeiServicesLocatePpi (
\r
479 &VolumeInfo.FvFormat,
\r
484 if (!EFI_ERROR (Status)) {
\r
485 MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);
\r
490 PERF_END_EX (mFileHandle, "EventRec", "TrEEPei", 0, PERF_ID_TREE_PEI + 1);
\r
492 return EFI_SUCCESS;
\r
496 Measure and record the Firmware Volum Information once FvInfoPPI install.
\r
498 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
\r
499 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
500 @param[in] Ppi Address of the PPI that was installed.
\r
502 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
\r
503 @return Others Fail to measure FV.
\r
508 FirmwareVolmeInfoPpiNotifyCallback (
\r
509 IN EFI_PEI_SERVICES **PeiServices,
\r
510 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
514 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
\r
516 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
\r
519 Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;
\r
522 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
\r
524 Status = PeiServicesLocatePpi (
\r
530 if (EFI_ERROR (Status)) {
\r
531 return EFI_SUCCESS;
\r
535 // This is an FV from an FFS file, and the parent FV must have already been measured,
\r
536 // No need to measure twice, so just record the FV and return
\r
538 if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {
\r
540 ASSERT (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));
\r
541 if (mMeasuredChildFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {
\r
543 // Check whether FV is in the measured child FV list.
\r
545 for (Index = 0; Index < mMeasuredChildFvIndex; Index++) {
\r
546 if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo) {
\r
547 return EFI_SUCCESS;
\r
550 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;
\r
551 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;
\r
552 mMeasuredChildFvIndex++;
\r
554 return EFI_SUCCESS;
\r
557 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);
\r
561 Do measurement after memory is ready.
\r
563 @param[in] PeiServices Describes the list of possible PEI Services.
\r
565 @retval EFI_SUCCESS Operation completed successfully.
\r
566 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
567 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
572 IN EFI_PEI_SERVICES **PeiServices
\r
577 Status = PeiServicesLocatePpi (
\r
578 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid,
\r
581 (VOID**)&mMeasurementExcludedFvPpi
\r
583 // Do not check status, because it is optional
\r
585 mMeasuredBaseFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));
\r
586 ASSERT (mMeasuredBaseFvInfo != NULL);
\r
587 mMeasuredChildFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));
\r
588 ASSERT (mMeasuredChildFvInfo != NULL);
\r
590 if (PcdGet8 (PcdTpm2ScrtmPolicy) == 1) {
\r
591 Status = MeasureCRTMVersion ();
\r
594 Status = MeasureMainBios ();
\r
598 // for the FvInfoPpi services to measure and record
\r
599 // the additional Fvs to TPM
\r
601 Status = PeiServicesNotifyPpi (&mNotifyList[0]);
\r
602 ASSERT_EFI_ERROR (Status);
\r
608 Entry point of this module.
\r
610 @param[in] FileHandle Handle of the file being invoked.
\r
611 @param[in] PeiServices Describes the list of possible PEI Services.
\r
619 IN EFI_PEI_FILE_HANDLE FileHandle,
\r
620 IN CONST EFI_PEI_SERVICES **PeiServices
\r
624 EFI_BOOT_MODE BootMode;
\r
626 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) ||
\r
627 CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
\r
628 DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n"));
\r
629 return EFI_UNSUPPORTED;
\r
633 // Update for Performance optimization
\r
635 Status = Tpm2RequestUseTpm ();
\r
636 if (EFI_ERROR (Status)) {
\r
637 DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
\r
641 Status = PeiServicesGetBootMode (&BootMode);
\r
642 ASSERT_EFI_ERROR (Status);
\r
645 // In S3 path, skip shadow logic. no measurement is required
\r
647 if (BootMode != BOOT_ON_S3_RESUME) {
\r
648 Status = (**PeiServices).RegisterForShadow(FileHandle);
\r
649 if (Status == EFI_ALREADY_STARTED) {
\r
650 mImageInMemory = TRUE;
\r
651 mFileHandle = FileHandle;
\r
652 } else if (Status == EFI_NOT_FOUND) {
\r
653 ASSERT_EFI_ERROR (Status);
\r
657 if (!mImageInMemory) {
\r
659 // Initialize TPM device
\r
661 if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) {
\r
662 if (BootMode == BOOT_ON_S3_RESUME) {
\r
663 Status = Tpm2Startup (TPM_SU_STATE);
\r
664 if (EFI_ERROR (Status) ) {
\r
665 Status = Tpm2Startup (TPM_SU_CLEAR);
\r
668 Status = Tpm2Startup (TPM_SU_CLEAR);
\r
670 if (EFI_ERROR (Status) ) {
\r
676 // TpmSelfTest is optional on S3 path, skip it to save S3 time
\r
678 if (BootMode != BOOT_ON_S3_RESUME) {
\r
679 if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) {
\r
680 Status = Tpm2SelfTest (NO);
\r
681 if (EFI_ERROR (Status)) {
\r
687 Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
\r
688 ASSERT_EFI_ERROR (Status);
\r
691 if (mImageInMemory) {
\r
692 Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
\r
693 if (EFI_ERROR (Status)) {
\r