2 Initialize TPM device and measure FVs before handing off control to DXE.
4 Copyright (c) 2005 - 2014, 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/Tpm12.h>
18 #include <IndustryStandard/UefiTcgPlatform.h>
19 #include <Ppi/FirmwareVolumeInfo.h>
20 #include <Ppi/FirmwareVolumeInfo2.h>
21 #include <Ppi/LockPhysicalPresence.h>
22 #include <Ppi/TpmInitialized.h>
23 #include <Ppi/FirmwareVolume.h>
24 #include <Ppi/EndOfPeiPhase.h>
25 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
27 #include <Guid/TcgEventHob.h>
28 #include <Guid/MeasuredFvHob.h>
29 #include <Guid/TpmInstance.h>
31 #include <Library/DebugLib.h>
32 #include <Library/BaseMemoryLib.h>
33 #include <Library/PeiServicesLib.h>
34 #include <Library/PeimEntryPoint.h>
35 #include <Library/TpmCommLib.h>
36 #include <Library/HobLib.h>
37 #include <Library/PcdLib.h>
38 #include <Library/PeiServicesTablePointerLib.h>
39 #include <Library/BaseLib.h>
43 BOOLEAN mImageInMemory
= FALSE
;
45 EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList
= {
46 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
47 &gPeiTpmInitializedPpiGuid
,
51 EFI_PLATFORM_FIRMWARE_BLOB mMeasuredBaseFvInfo
[FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)];
52 UINT32 mMeasuredBaseFvIndex
= 0;
54 EFI_PLATFORM_FIRMWARE_BLOB mMeasuredChildFvInfo
[FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)];
55 UINT32 mMeasuredChildFvIndex
= 0;
57 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI
*mMeasurementExcludedFvPpi
;
60 Lock physical presence if needed.
62 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
63 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
64 @param[in] Ppi Address of the PPI that was installed.
66 @retval EFI_SUCCESS Operation completed successfully.
71 PhysicalPresencePpiNotifyCallback (
72 IN EFI_PEI_SERVICES
**PeiServices
,
73 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
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 &gPeiLockPhysicalPresencePpiGuid
,
119 PhysicalPresencePpiNotifyCallback
122 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
123 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
124 FirmwareVolmeInfoPpiNotifyCallback
127 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
128 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
129 FirmwareVolmeInfoPpiNotifyCallback
132 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
133 &gEfiEndOfPeiSignalPpiGuid
,
134 EndofPeiSignalNotifyCallBack
139 Record all measured Firmware Volum Information into a Guid Hob
140 Guid Hob payload layout is
142 UINT32 *************************** FIRMWARE_BLOB number
143 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
145 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
146 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
147 @param[in] Ppi Address of the PPI that was installed.
149 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
150 @return Others Fail to measure FV.
155 EndofPeiSignalNotifyCallBack (
156 IN EFI_PEI_SERVICES
**PeiServices
,
157 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
161 MEASURED_HOB_DATA
*MeasuredHobData
;
163 MeasuredHobData
= NULL
;
166 // Create a Guid hob to save all measured Fv
168 MeasuredHobData
= BuildGuidHob(
170 sizeof(UINTN
) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
)
173 if (MeasuredHobData
!= NULL
){
175 // Save measured FV info enty number
177 MeasuredHobData
->Num
= mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
;
180 // Save measured base Fv info
182 CopyMem (MeasuredHobData
->MeasuredFvBuf
, mMeasuredBaseFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
));
185 // Save measured child Fv info
187 CopyMem (&MeasuredHobData
->MeasuredFvBuf
[mMeasuredBaseFvIndex
] , mMeasuredChildFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredChildFvIndex
));
194 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
195 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
196 added into the Event Log.
198 @param[in] PeiServices Describes the list of possible PEI Services.
199 @param[in] HashData Physical address of the start of the data buffer
200 to be hashed, extended, and logged.
201 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
202 @param[in] TpmHandle TPM handle.
203 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
204 @param[in] NewEventData Pointer to the new event data.
206 @retval EFI_SUCCESS Operation completed successfully.
207 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
208 @retval EFI_DEVICE_ERROR The command was unsuccessful.
213 IN EFI_PEI_SERVICES
**PeiServices
,
215 IN UINTN HashDataLen
,
216 IN TIS_TPM_HANDLE TpmHandle
,
217 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
218 IN UINT8
*NewEventData
225 if (HashDataLen
!= 0) {
226 Status
= TpmCommHashAll (
231 ASSERT_EFI_ERROR (Status
);
234 Status
= TpmCommExtend (
237 &NewEventHdr
->Digest
,
238 NewEventHdr
->PCRIndex
,
241 ASSERT_EFI_ERROR (Status
);
243 HobData
= BuildGuidHob (
244 &gTcgEventEntryHobGuid
,
245 sizeof (*NewEventHdr
) + NewEventHdr
->EventSize
247 if (HobData
== NULL
) {
248 return EFI_OUT_OF_RESOURCES
;
251 CopyMem (HobData
, NewEventHdr
, sizeof (*NewEventHdr
));
252 HobData
= (VOID
*) ((UINT8
*)HobData
+ sizeof (*NewEventHdr
));
253 CopyMem (HobData
, NewEventData
, NewEventHdr
->EventSize
);
258 Measure CRTM version.
260 @param[in] PeiServices Describes the list of possible PEI Services.
261 @param[in] TpmHandle TPM handle.
263 @retval EFI_SUCCESS Operation completed successfully.
264 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
265 @retval EFI_DEVICE_ERROR The command was unsuccessful.
271 IN EFI_PEI_SERVICES
**PeiServices
,
272 IN TIS_TPM_HANDLE TpmHandle
275 TCG_PCR_EVENT_HDR TcgEventHdr
;
278 // Use FirmwareVersion string to represent CRTM version.
279 // OEMs should get real CRTM version string and measure it.
282 TcgEventHdr
.PCRIndex
= 0;
283 TcgEventHdr
.EventType
= EV_S_CRTM_VERSION
;
284 TcgEventHdr
.EventSize
= (UINT32
) StrSize((CHAR16
*)PcdGetPtr (PcdFirmwareVersionString
));
286 return HashLogExtendEvent (
288 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
),
289 TcgEventHdr
.EventSize
,
292 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
)
298 Add it into the measured FV list after the FV is measured successfully.
300 @param[in] FvBase Base address of FV image.
301 @param[in] FvLength Length of FV image.
303 @retval EFI_SUCCESS Fv image is measured successfully
304 or it has been already measured.
305 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
306 @retval EFI_DEVICE_ERROR The command was unsuccessful.
312 IN EFI_PHYSICAL_ADDRESS FvBase
,
318 EFI_PLATFORM_FIRMWARE_BLOB FvBlob
;
319 TCG_PCR_EVENT_HDR TcgEventHdr
;
320 TIS_TPM_HANDLE TpmHandle
;
322 TpmHandle
= (TIS_TPM_HANDLE
) (UINTN
) TPM_BASE_ADDRESS
;
325 // Check if it is in Excluded FV list
327 if (mMeasurementExcludedFvPpi
!= NULL
) {
328 for (Index
= 0; Index
< mMeasurementExcludedFvPpi
->Count
; Index
++) {
329 if (mMeasurementExcludedFvPpi
->Fv
[Index
].FvBase
== FvBase
) {
330 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase
));
331 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength
));
338 // Check whether FV is in the measured FV list.
340 for (Index
= 0; Index
< mMeasuredBaseFvIndex
; Index
++) {
341 if (mMeasuredBaseFvInfo
[Index
].BlobBase
== FvBase
) {
347 // Measure and record the FV to the TPM
349 FvBlob
.BlobBase
= FvBase
;
350 FvBlob
.BlobLength
= FvLength
;
352 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob
.BlobBase
));
353 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob
.BlobLength
));
355 TcgEventHdr
.PCRIndex
= 0;
356 TcgEventHdr
.EventType
= EV_EFI_PLATFORM_FIRMWARE_BLOB
;
357 TcgEventHdr
.EventSize
= sizeof (FvBlob
);
359 Status
= HashLogExtendEvent (
360 (EFI_PEI_SERVICES
**) GetPeiServicesTablePointer(),
361 (UINT8
*) (UINTN
) FvBlob
.BlobBase
,
362 (UINTN
) FvBlob
.BlobLength
,
367 ASSERT_EFI_ERROR (Status
);
370 // Add new FV into the measured FV list.
372 ASSERT (mMeasuredBaseFvIndex
< FixedPcdGet32 (PcdPeiCoreMaxFvSupported
));
373 if (mMeasuredBaseFvIndex
< FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)) {
374 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobBase
= FvBase
;
375 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobLength
= FvLength
;
376 mMeasuredBaseFvIndex
++;
385 @param[in] PeiServices Describes the list of possible PEI Services.
386 @param[in] TpmHandle TPM handle.
388 @retval EFI_SUCCESS Operation completed successfully.
389 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
390 @retval EFI_DEVICE_ERROR The command was unsuccessful.
396 IN EFI_PEI_SERVICES
**PeiServices
,
397 IN TIS_TPM_HANDLE TpmHandle
402 EFI_PEI_FV_HANDLE VolumeHandle
;
403 EFI_FV_INFO VolumeInfo
;
404 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
409 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
410 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
411 // platform for special CRTM TPM measuring.
413 Status
= PeiServicesFfsFindNextVolume (FvInstances
, &VolumeHandle
);
414 if (EFI_ERROR (Status
)) {
419 // Measure and record the firmware volume that is dispatched by PeiCore
421 Status
= PeiServicesFfsGetVolumeInfo (VolumeHandle
, &VolumeInfo
);
422 ASSERT_EFI_ERROR (Status
);
424 // Locate the corresponding FV_PPI according to founded FV's format guid
426 Status
= PeiServicesLocatePpi (
427 &VolumeInfo
.FvFormat
,
432 if (!EFI_ERROR (Status
)) {
433 MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) VolumeInfo
.FvStart
, VolumeInfo
.FvSize
);
443 Measure and record the Firmware Volum Information once FvInfoPPI install.
445 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
446 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
447 @param[in] Ppi Address of the PPI that was installed.
449 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
450 @return Others Fail to measure FV.
455 FirmwareVolmeInfoPpiNotifyCallback (
456 IN EFI_PEI_SERVICES
**PeiServices
,
457 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
461 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
463 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
466 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*) Ppi
;
469 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
471 Status
= PeiServicesLocatePpi (
477 if (EFI_ERROR (Status
)) {
482 // This is an FV from an FFS file, and the parent FV must have already been measured,
483 // No need to measure twice, so just record the FV and return
485 if (Fv
->ParentFvName
!= NULL
|| Fv
->ParentFileName
!= NULL
) {
487 ASSERT (mMeasuredChildFvIndex
< FixedPcdGet32 (PcdPeiCoreMaxFvSupported
));
488 if (mMeasuredChildFvIndex
< FixedPcdGet32 (PcdPeiCoreMaxFvSupported
)) {
490 // Check whether FV is in the measured child FV list.
492 for (Index
= 0; Index
< mMeasuredChildFvIndex
; Index
++) {
493 if (mMeasuredChildFvInfo
[Index
].BlobBase
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
) {
497 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
;
498 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobLength
= Fv
->FvInfoSize
;
499 mMeasuredChildFvIndex
++;
504 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
, Fv
->FvInfoSize
);
508 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.
509 And lock physical presence if needed.
511 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
512 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
513 @param[in] Ppi Address of the PPI that was installed.
515 @retval EFI_SUCCESS Operation completed successfully.
516 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.
517 @retval EFI_DEVICE_ERROR The command was unsuccessful.
522 PhysicalPresencePpiNotifyCallback (
523 IN EFI_PEI_SERVICES
**PeiServices
,
524 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
529 PEI_LOCK_PHYSICAL_PRESENCE_PPI
*LockPhysicalPresencePpi
;
530 BOOLEAN LifetimeLock
;
532 TIS_TPM_HANDLE TpmHandle
;
533 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue
;
535 TpmHandle
= (TIS_TPM_HANDLE
) (UINTN
) TPM_BASE_ADDRESS
;
537 Status
= TpmCommGetCapability (PeiServices
, TpmHandle
, NULL
, &LifetimeLock
, &CmdEnable
);
538 if (EFI_ERROR (Status
)) {
543 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.
545 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock
) && !LifetimeLock
) {
547 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
549 PhysicalPresenceValue
= TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK
;
551 if (PcdGetBool (PcdPhysicalPresenceCmdEnable
)) {
552 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_ENABLE
;
555 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_DISABLE
;
559 if (PcdGetBool (PcdPhysicalPresenceHwEnable
)) {
560 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_ENABLE
;
562 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_DISABLE
;
565 Status
= TpmCommPhysicalPresence (
568 PhysicalPresenceValue
570 if (EFI_ERROR (Status
)) {
576 // 2. Lock physical presence if it is required.
578 LockPhysicalPresencePpi
= (PEI_LOCK_PHYSICAL_PRESENCE_PPI
*) Ppi
;
579 if (!LockPhysicalPresencePpi
->LockPhysicalPresence ((CONST EFI_PEI_SERVICES
**) PeiServices
)) {
586 // physicalPresenceCMDEnable is locked, can't change.
592 // Enable physical presence command
593 // It is necessary in order to lock physical presence
595 Status
= TpmCommPhysicalPresence (
598 TPM_PHYSICAL_PRESENCE_CMD_ENABLE
600 if (EFI_ERROR (Status
)) {
606 // Lock physical presence
608 Status
= TpmCommPhysicalPresence (
611 TPM_PHYSICAL_PRESENCE_LOCK
617 Check if TPM chip is activeated or not.
619 @param[in] PeiServices Describes the list of possible PEI Services.
620 @param[in] TpmHandle TPM handle.
622 @retval TRUE TPM is activated.
623 @retval FALSE TPM is deactivated.
629 IN EFI_PEI_SERVICES
**PeiServices
,
630 IN TIS_TPM_HANDLE TpmHandle
636 Status
= TpmCommGetCapability (PeiServices
, TpmHandle
, &Deactivated
, NULL
, NULL
);
637 if (EFI_ERROR (Status
)) {
640 return (BOOLEAN
)(!Deactivated
);
644 Do measurement after memory is ready.
646 @param[in] PeiServices Describes the list of possible PEI Services.
648 @retval EFI_SUCCESS Operation completed successfully.
649 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
650 @retval EFI_DEVICE_ERROR The command was unsuccessful.
656 IN EFI_PEI_SERVICES
**PeiServices
660 TIS_TPM_HANDLE TpmHandle
;
662 Status
= PeiServicesLocatePpi (
663 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid
,
666 (VOID
**)&mMeasurementExcludedFvPpi
668 // Do not check status, because it is optional
670 TpmHandle
= (TIS_TPM_HANDLE
)(UINTN
)TPM_BASE_ADDRESS
;
671 Status
= TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR
)TpmHandle
);
672 if (EFI_ERROR (Status
)) {
676 if (IsTpmUsable (PeiServices
, TpmHandle
)) {
677 if (PcdGet8 (PcdTpmScrtmPolicy
) == 1) {
678 Status
= MeasureCRTMVersion (PeiServices
, TpmHandle
);
679 ASSERT_EFI_ERROR (Status
);
682 Status
= MeasureMainBios (PeiServices
, TpmHandle
);
687 // 1). for the FvInfoPpi services to measure and record
688 // the additional Fvs to TPM
689 // 2). for the OperatorPresencePpi service to determine whether to
692 Status
= PeiServicesNotifyPpi (&mNotifyList
[0]);
693 ASSERT_EFI_ERROR (Status
);
699 Entry point of this module.
701 @param[in] FileHandle Handle of the file being invoked.
702 @param[in] PeiServices Describes the list of possible PEI Services.
710 IN EFI_PEI_FILE_HANDLE FileHandle
,
711 IN CONST EFI_PEI_SERVICES
**PeiServices
715 EFI_BOOT_MODE BootMode
;
716 TIS_TPM_HANDLE TpmHandle
;
718 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
719 DEBUG ((EFI_D_ERROR
, "No TPM12 instance required!\n"));
720 return EFI_UNSUPPORTED
;
724 // Initialize TPM device
726 Status
= PeiServicesGetBootMode (&BootMode
);
727 ASSERT_EFI_ERROR (Status
);
730 // In S3 path, skip shadow logic. no measurement is required
732 if (BootMode
!= BOOT_ON_S3_RESUME
) {
733 Status
= (**PeiServices
).RegisterForShadow(FileHandle
);
734 if (Status
== EFI_ALREADY_STARTED
) {
735 mImageInMemory
= TRUE
;
736 } else if (Status
== EFI_NOT_FOUND
) {
737 ASSERT_EFI_ERROR (Status
);
741 if (!mImageInMemory
) {
742 TpmHandle
= (TIS_TPM_HANDLE
)(UINTN
)TPM_BASE_ADDRESS
;
743 Status
= TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR
)TpmHandle
);
744 if (EFI_ERROR (Status
)) {
745 DEBUG ((DEBUG_ERROR
, "TPM not detected!\n"));
749 if (PcdGet8 (PcdTpmInitializationPolicy
) == 1) {
750 Status
= TpmCommStartup ((EFI_PEI_SERVICES
**)PeiServices
, TpmHandle
, BootMode
);
751 if (EFI_ERROR (Status
) ) {
757 // TpmSelfTest is optional on S3 path, skip it to save S3 time
759 if (BootMode
!= BOOT_ON_S3_RESUME
) {
760 Status
= TpmCommContinueSelfTest ((EFI_PEI_SERVICES
**)PeiServices
, TpmHandle
);
761 if (EFI_ERROR (Status
)) {
766 Status
= PeiServicesInstallPpi (&mTpmInitializedPpiList
);
767 ASSERT_EFI_ERROR (Status
);
770 if (mImageInMemory
) {
771 Status
= PeimEntryMP ((EFI_PEI_SERVICES
**)PeiServices
);
772 if (EFI_ERROR (Status
)) {