2 Initialize TPM device and measure FVs before handing off control to DXE.
4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <IndustryStandard/Tpm12.h>
12 #include <IndustryStandard/UefiTcgPlatform.h>
13 #include <Ppi/FirmwareVolumeInfo.h>
14 #include <Ppi/FirmwareVolumeInfo2.h>
15 #include <Ppi/LockPhysicalPresence.h>
16 #include <Ppi/TpmInitialized.h>
17 #include <Ppi/FirmwareVolume.h>
18 #include <Ppi/EndOfPeiPhase.h>
19 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
21 #include <Guid/TcgEventHob.h>
22 #include <Guid/MeasuredFvHob.h>
23 #include <Guid/TpmInstance.h>
25 #include <Library/DebugLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/PeiServicesLib.h>
28 #include <Library/PeimEntryPoint.h>
29 #include <Library/HobLib.h>
30 #include <Library/PcdLib.h>
31 #include <Library/PeiServicesTablePointerLib.h>
32 #include <Library/BaseLib.h>
33 #include <Library/MemoryAllocationLib.h>
34 #include <Library/ReportStatusCodeLib.h>
35 #include <Library/Tpm12DeviceLib.h>
36 #include <Library/Tpm12CommandLib.h>
37 #include <Library/BaseCryptLib.h>
38 #include <Library/PerformanceLib.h>
40 BOOLEAN mImageInMemory
= FALSE
;
42 EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList
= {
43 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
44 &gPeiTpmInitializedPpiGuid
,
48 EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList
= {
49 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
50 &gPeiTpmInitializationDonePpiGuid
,
55 // Number of firmware blobs to grow by each time we run out of room
57 #define FIRMWARE_BLOB_GROWTH_STEP 4
59 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredBaseFvInfo
;
60 UINT32 mMeasuredMaxBaseFvIndex
= 0;
61 UINT32 mMeasuredBaseFvIndex
= 0;
63 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredChildFvInfo
;
64 UINT32 mMeasuredMaxChildFvIndex
= 0;
65 UINT32 mMeasuredChildFvIndex
= 0;
67 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI
*mMeasurementExcludedFvPpi
;
70 Lock physical presence if needed.
72 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
73 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
74 @param[in] Ppi Address of the PPI that was installed.
76 @retval EFI_SUCCESS Operation completed successfully.
81 PhysicalPresencePpiNotifyCallback (
82 IN EFI_PEI_SERVICES
**PeiServices
,
83 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
88 Measure and record the Firmware Volum Information once FvInfoPPI install.
90 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
91 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
92 @param[in] Ppi Address of the PPI that was installed.
94 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
95 @return Others Fail to measure FV.
100 FirmwareVolmeInfoPpiNotifyCallback (
101 IN EFI_PEI_SERVICES
**PeiServices
,
102 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
107 Record all measured Firmware Volum Information into a Guid Hob
109 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
110 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
111 @param[in] Ppi Address of the PPI that was installed.
113 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
114 @return Others Fail to measure FV.
119 EndofPeiSignalNotifyCallBack (
120 IN EFI_PEI_SERVICES
**PeiServices
,
121 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
125 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList
[] = {
127 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
128 &gPeiLockPhysicalPresencePpiGuid
,
129 PhysicalPresencePpiNotifyCallback
132 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
133 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
134 FirmwareVolmeInfoPpiNotifyCallback
137 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
138 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
139 FirmwareVolmeInfoPpiNotifyCallback
142 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
143 &gEfiEndOfPeiSignalPpiGuid
,
144 EndofPeiSignalNotifyCallBack
149 Record all measured Firmware Volum Information into a Guid Hob
150 Guid Hob payload layout is
152 UINT32 *************************** FIRMWARE_BLOB number
153 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
155 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
156 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
157 @param[in] Ppi Address of the PPI that was installed.
159 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
160 @return Others Fail to measure FV.
165 EndofPeiSignalNotifyCallBack (
166 IN EFI_PEI_SERVICES
**PeiServices
,
167 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
171 MEASURED_HOB_DATA
*MeasuredHobData
;
173 MeasuredHobData
= NULL
;
175 PERF_CALLBACK_BEGIN (&gEfiEndOfPeiSignalPpiGuid
);
178 // Create a Guid hob to save all measured Fv
180 MeasuredHobData
= BuildGuidHob(
182 sizeof(UINTN
) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
)
185 if (MeasuredHobData
!= NULL
){
187 // Save measured FV info enty number
189 MeasuredHobData
->Num
= mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
;
192 // Save measured base Fv info
194 CopyMem (MeasuredHobData
->MeasuredFvBuf
, mMeasuredBaseFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
));
197 // Save measured child Fv info
199 CopyMem (&MeasuredHobData
->MeasuredFvBuf
[mMeasuredBaseFvIndex
] , mMeasuredChildFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredChildFvIndex
));
202 PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid
);
208 Single function calculates SHA1 digest value for all raw data. It
209 combines Sha1Init(), Sha1Update() and Sha1Final().
211 @param[in] Data Raw data to be digested.
212 @param[in] DataLen Size of the raw data.
213 @param[out] Digest Pointer to a buffer that stores the final digest.
215 @retval EFI_SUCCESS Always successfully calculate the final digest.
220 IN CONST UINT8
*Data
,
222 OUT TPM_DIGEST
*Digest
228 CtxSize
= Sha1GetContextSize ();
229 Sha1Ctx
= AllocatePool (CtxSize
);
230 ASSERT (Sha1Ctx
!= NULL
);
233 Sha1Update (Sha1Ctx
, Data
, DataLen
);
234 Sha1Final (Sha1Ctx
, (UINT8
*)Digest
);
242 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
243 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
244 added into the Event Log.
246 @param[in] PeiServices Describes the list of possible PEI Services.
247 @param[in] HashData Physical address of the start of the data buffer
248 to be hashed, extended, and logged.
249 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
250 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
251 @param[in] NewEventData Pointer to the new event data.
253 @retval EFI_SUCCESS Operation completed successfully.
254 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
255 @retval EFI_DEVICE_ERROR The command was unsuccessful.
260 IN EFI_PEI_SERVICES
**PeiServices
,
262 IN UINTN HashDataLen
,
263 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
264 IN UINT8
*NewEventData
270 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
271 return EFI_DEVICE_ERROR
;
275 if (HashDataLen
!= 0) {
276 Status
= TpmCommHashAll (
281 if (EFI_ERROR (Status
)) {
286 Status
= Tpm12Extend (
287 &NewEventHdr
->Digest
,
288 NewEventHdr
->PCRIndex
,
291 if (EFI_ERROR (Status
)) {
295 HobData
= BuildGuidHob (
296 &gTcgEventEntryHobGuid
,
297 sizeof (*NewEventHdr
) + NewEventHdr
->EventSize
299 if (HobData
== NULL
) {
300 Status
= EFI_OUT_OF_RESOURCES
;
304 CopyMem (HobData
, NewEventHdr
, sizeof (*NewEventHdr
));
305 HobData
= (VOID
*) ((UINT8
*)HobData
+ sizeof (*NewEventHdr
));
306 CopyMem (HobData
, NewEventData
, NewEventHdr
->EventSize
);
309 if ((Status
== EFI_DEVICE_ERROR
) || (Status
== EFI_TIMEOUT
)) {
310 DEBUG ((EFI_D_ERROR
, "HashLogExtendEvent - %r. Disable TPM.\n", Status
));
311 BuildGuidHob (&gTpmErrorHobGuid
,0);
313 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
314 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
316 Status
= EFI_DEVICE_ERROR
;
322 Measure CRTM version.
324 @param[in] PeiServices Describes the list of possible PEI Services.
326 @retval EFI_SUCCESS Operation completed successfully.
327 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
328 @retval EFI_DEVICE_ERROR The command was unsuccessful.
334 IN EFI_PEI_SERVICES
**PeiServices
337 TCG_PCR_EVENT_HDR TcgEventHdr
;
340 // Use FirmwareVersion string to represent CRTM version.
341 // OEMs should get real CRTM version string and measure it.
344 TcgEventHdr
.PCRIndex
= 0;
345 TcgEventHdr
.EventType
= EV_S_CRTM_VERSION
;
346 TcgEventHdr
.EventSize
= (UINT32
) StrSize((CHAR16
*)PcdGetPtr (PcdFirmwareVersionString
));
348 return HashLogExtendEvent (
350 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
),
351 TcgEventHdr
.EventSize
,
353 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
)
359 Add it into the measured FV list after the FV is measured successfully.
361 @param[in] FvBase Base address of FV image.
362 @param[in] FvLength Length of FV image.
364 @retval EFI_SUCCESS Fv image is measured successfully
365 or it has been already measured.
366 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
367 @retval EFI_DEVICE_ERROR The command was unsuccessful.
373 IN EFI_PHYSICAL_ADDRESS FvBase
,
379 EFI_PLATFORM_FIRMWARE_BLOB FvBlob
;
380 TCG_PCR_EVENT_HDR TcgEventHdr
;
383 // Check if it is in Excluded FV list
385 if (mMeasurementExcludedFvPpi
!= NULL
) {
386 for (Index
= 0; Index
< mMeasurementExcludedFvPpi
->Count
; Index
++) {
387 if (mMeasurementExcludedFvPpi
->Fv
[Index
].FvBase
== FvBase
) {
388 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase
));
389 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength
));
396 // Check whether FV is in the measured FV list.
398 for (Index
= 0; Index
< mMeasuredBaseFvIndex
; Index
++) {
399 if (mMeasuredBaseFvInfo
[Index
].BlobBase
== FvBase
) {
405 // Measure and record the FV to the TPM
407 FvBlob
.BlobBase
= FvBase
;
408 FvBlob
.BlobLength
= FvLength
;
410 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob
.BlobBase
));
411 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob
.BlobLength
));
413 TcgEventHdr
.PCRIndex
= 0;
414 TcgEventHdr
.EventType
= EV_EFI_PLATFORM_FIRMWARE_BLOB
;
415 TcgEventHdr
.EventSize
= sizeof (FvBlob
);
417 Status
= HashLogExtendEvent (
418 (EFI_PEI_SERVICES
**) GetPeiServicesTablePointer(),
419 (UINT8
*) (UINTN
) FvBlob
.BlobBase
,
420 (UINTN
) FvBlob
.BlobLength
,
426 // Add new FV into the measured FV list.
428 if (mMeasuredBaseFvIndex
>= mMeasuredMaxBaseFvIndex
) {
429 mMeasuredBaseFvInfo
= ReallocatePool (
430 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * mMeasuredMaxBaseFvIndex
,
431 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredMaxBaseFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
),
434 ASSERT (mMeasuredBaseFvInfo
!= NULL
);
435 mMeasuredMaxBaseFvIndex
= mMeasuredMaxBaseFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
;
438 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobBase
= FvBase
;
439 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobLength
= FvLength
;
440 mMeasuredBaseFvIndex
++;
448 @param[in] PeiServices Describes the list of possible PEI Services.
450 @retval EFI_SUCCESS Operation completed successfully.
451 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
452 @retval EFI_DEVICE_ERROR The command was unsuccessful.
458 IN EFI_PEI_SERVICES
**PeiServices
463 EFI_PEI_FV_HANDLE VolumeHandle
;
464 EFI_FV_INFO VolumeInfo
;
465 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
470 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
471 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
472 // platform for special CRTM TPM measuring.
474 Status
= PeiServicesFfsFindNextVolume (FvInstances
, &VolumeHandle
);
475 if (EFI_ERROR (Status
)) {
480 // Measure and record the firmware volume that is dispatched by PeiCore
482 Status
= PeiServicesFfsGetVolumeInfo (VolumeHandle
, &VolumeInfo
);
483 ASSERT_EFI_ERROR (Status
);
485 // Locate the corresponding FV_PPI according to founded FV's format guid
487 Status
= PeiServicesLocatePpi (
488 &VolumeInfo
.FvFormat
,
493 if (!EFI_ERROR (Status
)) {
494 MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) VolumeInfo
.FvStart
, VolumeInfo
.FvSize
);
504 Measure and record the Firmware Volum Information once FvInfoPPI install.
506 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
507 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
508 @param[in] Ppi Address of the PPI that was installed.
510 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
511 @return Others Fail to measure FV.
516 FirmwareVolmeInfoPpiNotifyCallback (
517 IN EFI_PEI_SERVICES
**PeiServices
,
518 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
522 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
524 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
527 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*) Ppi
;
530 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
532 Status
= PeiServicesLocatePpi (
538 if (EFI_ERROR (Status
)) {
543 // This is an FV from an FFS file, and the parent FV must have already been measured,
544 // No need to measure twice, so just record the FV and return
546 if (Fv
->ParentFvName
!= NULL
|| Fv
->ParentFileName
!= NULL
) {
548 if (mMeasuredChildFvIndex
>= mMeasuredMaxChildFvIndex
) {
549 mMeasuredChildFvInfo
= ReallocatePool (
550 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * mMeasuredMaxChildFvIndex
,
551 sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredMaxChildFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
),
554 ASSERT (mMeasuredChildFvInfo
!= NULL
);
555 mMeasuredMaxChildFvIndex
= mMeasuredMaxChildFvIndex
+ FIRMWARE_BLOB_GROWTH_STEP
;
558 // Check whether FV is in the measured child FV list.
560 for (Index
= 0; Index
< mMeasuredChildFvIndex
; Index
++) {
561 if (mMeasuredChildFvInfo
[Index
].BlobBase
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
) {
565 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
;
566 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobLength
= Fv
->FvInfoSize
;
567 mMeasuredChildFvIndex
++;
571 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
, Fv
->FvInfoSize
);
575 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.
576 And lock physical presence if needed.
578 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
579 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
580 @param[in] Ppi Address of the PPI that was installed.
582 @retval EFI_SUCCESS Operation completed successfully.
583 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.
584 @retval EFI_DEVICE_ERROR The command was unsuccessful.
589 PhysicalPresencePpiNotifyCallback (
590 IN EFI_PEI_SERVICES
**PeiServices
,
591 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
596 TPM_PERMANENT_FLAGS TpmPermanentFlags
;
597 PEI_LOCK_PHYSICAL_PRESENCE_PPI
*LockPhysicalPresencePpi
;
598 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue
;
600 Status
= Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags
);
601 if (EFI_ERROR (Status
)) {
606 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.
608 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock
) && !TpmPermanentFlags
.physicalPresenceLifetimeLock
) {
610 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
612 PhysicalPresenceValue
= TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK
;
613 TpmPermanentFlags
.physicalPresenceLifetimeLock
= TRUE
;
615 if (PcdGetBool (PcdPhysicalPresenceCmdEnable
)) {
616 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_ENABLE
;
617 TpmPermanentFlags
.physicalPresenceCMDEnable
= TRUE
;
619 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_DISABLE
;
620 TpmPermanentFlags
.physicalPresenceCMDEnable
= FALSE
;
623 if (PcdGetBool (PcdPhysicalPresenceHwEnable
)) {
624 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_ENABLE
;
626 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_DISABLE
;
629 Status
= Tpm12PhysicalPresence (
630 PhysicalPresenceValue
632 if (EFI_ERROR (Status
)) {
638 // 2. Lock physical presence if it is required.
640 LockPhysicalPresencePpi
= (PEI_LOCK_PHYSICAL_PRESENCE_PPI
*) Ppi
;
641 if (!LockPhysicalPresencePpi
->LockPhysicalPresence ((CONST EFI_PEI_SERVICES
**) PeiServices
)) {
645 if (!TpmPermanentFlags
.physicalPresenceCMDEnable
) {
646 if (TpmPermanentFlags
.physicalPresenceLifetimeLock
) {
648 // physicalPresenceCMDEnable is locked, can't change.
654 // Enable physical presence command
655 // It is necessary in order to lock physical presence
657 Status
= Tpm12PhysicalPresence (
658 TPM_PHYSICAL_PRESENCE_CMD_ENABLE
660 if (EFI_ERROR (Status
)) {
666 // Lock physical presence
668 Status
= Tpm12PhysicalPresence (
669 TPM_PHYSICAL_PRESENCE_LOCK
675 Check if TPM chip is activeated or not.
677 @param[in] PeiServices Describes the list of possible PEI Services.
679 @retval TRUE TPM is activated.
680 @retval FALSE TPM is deactivated.
689 TPM_PERMANENT_FLAGS TpmPermanentFlags
;
691 Status
= Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags
);
692 if (EFI_ERROR (Status
)) {
695 return (BOOLEAN
)(!TpmPermanentFlags
.deactivated
);
699 Do measurement after memory is ready.
701 @param[in] PeiServices Describes the list of possible PEI Services.
703 @retval EFI_SUCCESS Operation completed successfully.
704 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
705 @retval EFI_DEVICE_ERROR The command was unsuccessful.
711 IN EFI_PEI_SERVICES
**PeiServices
716 Status
= PeiServicesLocatePpi (
717 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid
,
720 (VOID
**)&mMeasurementExcludedFvPpi
722 // Do not check status, because it is optional
724 Status
= Tpm12RequestUseTpm ();
725 if (EFI_ERROR (Status
)) {
729 if (IsTpmUsable ()) {
730 if (PcdGet8 (PcdTpmScrtmPolicy
) == 1) {
731 Status
= MeasureCRTMVersion (PeiServices
);
734 Status
= MeasureMainBios (PeiServices
);
739 // 1). for the FvInfoPpi services to measure and record
740 // the additional Fvs to TPM
741 // 2). for the OperatorPresencePpi service to determine whether to
744 Status
= PeiServicesNotifyPpi (&mNotifyList
[0]);
745 ASSERT_EFI_ERROR (Status
);
751 Entry point of this module.
753 @param[in] FileHandle Handle of the file being invoked.
754 @param[in] PeiServices Describes the list of possible PEI Services.
762 IN EFI_PEI_FILE_HANDLE FileHandle
,
763 IN CONST EFI_PEI_SERVICES
**PeiServices
768 EFI_BOOT_MODE BootMode
;
770 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
771 DEBUG ((EFI_D_ERROR
, "No TPM12 instance required!\n"));
772 return EFI_UNSUPPORTED
;
775 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
776 DEBUG ((EFI_D_ERROR
, "TPM error!\n"));
777 return EFI_DEVICE_ERROR
;
781 // Initialize TPM device
783 Status
= PeiServicesGetBootMode (&BootMode
);
784 ASSERT_EFI_ERROR (Status
);
787 // In S3 path, skip shadow logic. no measurement is required
789 if (BootMode
!= BOOT_ON_S3_RESUME
) {
790 Status
= (**PeiServices
).RegisterForShadow(FileHandle
);
791 if (Status
== EFI_ALREADY_STARTED
) {
792 mImageInMemory
= TRUE
;
793 } else if (Status
== EFI_NOT_FOUND
) {
794 ASSERT_EFI_ERROR (Status
);
798 if (!mImageInMemory
) {
799 Status
= Tpm12RequestUseTpm ();
800 if (EFI_ERROR (Status
)) {
801 DEBUG ((DEBUG_ERROR
, "TPM not detected!\n"));
805 if (PcdGet8 (PcdTpmInitializationPolicy
) == 1) {
806 if (BootMode
== BOOT_ON_S3_RESUME
) {
807 Status
= Tpm12Startup (TPM_ST_STATE
);
809 Status
= Tpm12Startup (TPM_ST_CLEAR
);
811 if (EFI_ERROR (Status
) ) {
817 // TpmSelfTest is optional on S3 path, skip it to save S3 time
819 if (BootMode
!= BOOT_ON_S3_RESUME
) {
820 Status
= Tpm12ContinueSelfTest ();
821 if (EFI_ERROR (Status
)) {
827 // Only intall TpmInitializedPpi on success
829 Status
= PeiServicesInstallPpi (&mTpmInitializedPpiList
);
830 ASSERT_EFI_ERROR (Status
);
833 if (mImageInMemory
) {
834 Status
= PeimEntryMP ((EFI_PEI_SERVICES
**)PeiServices
);
839 if (EFI_ERROR (Status
)) {
840 DEBUG ((EFI_D_ERROR
, "TPM error! Build Hob\n"));
841 BuildGuidHob (&gTpmErrorHobGuid
,0);
843 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
844 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
848 // Always intall TpmInitializationDonePpi no matter success or fail.
849 // Other driver can know TPM initialization state by TpmInitializedPpi.
851 Status2
= PeiServicesInstallPpi (&mTpmInitializationDonePpiList
);
852 ASSERT_EFI_ERROR (Status2
);