2 Initialize TPM device and measure FVs before handing off control to DXE.
4 Copyright (c) 2005 - 2017, 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/HobLib.h>
36 #include <Library/PcdLib.h>
37 #include <Library/PeiServicesTablePointerLib.h>
38 #include <Library/BaseLib.h>
39 #include <Library/MemoryAllocationLib.h>
40 #include <Library/ReportStatusCodeLib.h>
41 #include <Library/Tpm12DeviceLib.h>
42 #include <Library/Tpm12CommandLib.h>
43 #include <Library/BaseCryptLib.h>
45 BOOLEAN mImageInMemory
= FALSE
;
47 EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList
= {
48 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
49 &gPeiTpmInitializedPpiGuid
,
53 EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList
= {
54 EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
,
55 &gPeiTpmInitializationDonePpiGuid
,
59 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredBaseFvInfo
;
60 UINT32 mMeasuredBaseFvIndex
= 0;
62 EFI_PLATFORM_FIRMWARE_BLOB
*mMeasuredChildFvInfo
;
63 UINT32 mMeasuredChildFvIndex
= 0;
65 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI
*mMeasurementExcludedFvPpi
;
68 Lock physical presence if needed.
70 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
71 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
72 @param[in] Ppi Address of the PPI that was installed.
74 @retval EFI_SUCCESS Operation completed successfully.
79 PhysicalPresencePpiNotifyCallback (
80 IN EFI_PEI_SERVICES
**PeiServices
,
81 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
86 Measure and record the Firmware Volum Information once FvInfoPPI install.
88 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
89 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
90 @param[in] Ppi Address of the PPI that was installed.
92 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
93 @return Others Fail to measure FV.
98 FirmwareVolmeInfoPpiNotifyCallback (
99 IN EFI_PEI_SERVICES
**PeiServices
,
100 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
105 Record all measured Firmware Volum Information into a Guid Hob
107 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
108 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
109 @param[in] Ppi Address of the PPI that was installed.
111 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
112 @return Others Fail to measure FV.
117 EndofPeiSignalNotifyCallBack (
118 IN EFI_PEI_SERVICES
**PeiServices
,
119 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
123 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList
[] = {
125 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
126 &gPeiLockPhysicalPresencePpiGuid
,
127 PhysicalPresencePpiNotifyCallback
130 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
131 &gEfiPeiFirmwareVolumeInfoPpiGuid
,
132 FirmwareVolmeInfoPpiNotifyCallback
135 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
,
136 &gEfiPeiFirmwareVolumeInfo2PpiGuid
,
137 FirmwareVolmeInfoPpiNotifyCallback
140 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
141 &gEfiEndOfPeiSignalPpiGuid
,
142 EndofPeiSignalNotifyCallBack
147 Record all measured Firmware Volum Information into a Guid Hob
148 Guid Hob payload layout is
150 UINT32 *************************** FIRMWARE_BLOB number
151 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
153 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
154 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
155 @param[in] Ppi Address of the PPI that was installed.
157 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
158 @return Others Fail to measure FV.
163 EndofPeiSignalNotifyCallBack (
164 IN EFI_PEI_SERVICES
**PeiServices
,
165 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
169 MEASURED_HOB_DATA
*MeasuredHobData
;
171 MeasuredHobData
= NULL
;
174 // Create a Guid hob to save all measured Fv
176 MeasuredHobData
= BuildGuidHob(
178 sizeof(UINTN
) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
)
181 if (MeasuredHobData
!= NULL
){
183 // Save measured FV info enty number
185 MeasuredHobData
->Num
= mMeasuredBaseFvIndex
+ mMeasuredChildFvIndex
;
188 // Save measured base Fv info
190 CopyMem (MeasuredHobData
->MeasuredFvBuf
, mMeasuredBaseFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredBaseFvIndex
));
193 // Save measured child Fv info
195 CopyMem (&MeasuredHobData
->MeasuredFvBuf
[mMeasuredBaseFvIndex
] , mMeasuredChildFvInfo
, sizeof(EFI_PLATFORM_FIRMWARE_BLOB
) * (mMeasuredChildFvIndex
));
202 Single function calculates SHA1 digest value for all raw data. It
203 combines Sha1Init(), Sha1Update() and Sha1Final().
205 @param[in] Data Raw data to be digested.
206 @param[in] DataLen Size of the raw data.
207 @param[out] Digest Pointer to a buffer that stores the final digest.
209 @retval EFI_SUCCESS Always successfully calculate the final digest.
214 IN CONST UINT8
*Data
,
216 OUT TPM_DIGEST
*Digest
222 CtxSize
= Sha1GetContextSize ();
223 Sha1Ctx
= AllocatePool (CtxSize
);
224 ASSERT (Sha1Ctx
!= NULL
);
227 Sha1Update (Sha1Ctx
, Data
, DataLen
);
228 Sha1Final (Sha1Ctx
, (UINT8
*)Digest
);
236 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
237 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
238 added into the Event Log.
240 @param[in] PeiServices Describes the list of possible PEI Services.
241 @param[in] HashData Physical address of the start of the data buffer
242 to be hashed, extended, and logged.
243 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
244 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
245 @param[in] NewEventData Pointer to the new event data.
247 @retval EFI_SUCCESS Operation completed successfully.
248 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
249 @retval EFI_DEVICE_ERROR The command was unsuccessful.
254 IN EFI_PEI_SERVICES
**PeiServices
,
256 IN UINTN HashDataLen
,
257 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
258 IN UINT8
*NewEventData
264 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
265 return EFI_DEVICE_ERROR
;
269 if (HashDataLen
!= 0) {
270 Status
= TpmCommHashAll (
275 if (EFI_ERROR (Status
)) {
280 Status
= Tpm12Extend (
281 &NewEventHdr
->Digest
,
282 NewEventHdr
->PCRIndex
,
285 if (EFI_ERROR (Status
)) {
289 HobData
= BuildGuidHob (
290 &gTcgEventEntryHobGuid
,
291 sizeof (*NewEventHdr
) + NewEventHdr
->EventSize
293 if (HobData
== NULL
) {
294 Status
= EFI_OUT_OF_RESOURCES
;
298 CopyMem (HobData
, NewEventHdr
, sizeof (*NewEventHdr
));
299 HobData
= (VOID
*) ((UINT8
*)HobData
+ sizeof (*NewEventHdr
));
300 CopyMem (HobData
, NewEventData
, NewEventHdr
->EventSize
);
303 if ((Status
== EFI_DEVICE_ERROR
) || (Status
== EFI_TIMEOUT
)) {
304 DEBUG ((EFI_D_ERROR
, "HashLogExtendEvent - %r. Disable TPM.\n", Status
));
305 BuildGuidHob (&gTpmErrorHobGuid
,0);
307 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
308 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
310 Status
= EFI_DEVICE_ERROR
;
316 Measure CRTM version.
318 @param[in] PeiServices Describes the list of possible PEI Services.
320 @retval EFI_SUCCESS Operation completed successfully.
321 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
322 @retval EFI_DEVICE_ERROR The command was unsuccessful.
328 IN EFI_PEI_SERVICES
**PeiServices
331 TCG_PCR_EVENT_HDR TcgEventHdr
;
334 // Use FirmwareVersion string to represent CRTM version.
335 // OEMs should get real CRTM version string and measure it.
338 TcgEventHdr
.PCRIndex
= 0;
339 TcgEventHdr
.EventType
= EV_S_CRTM_VERSION
;
340 TcgEventHdr
.EventSize
= (UINT32
) StrSize((CHAR16
*)PcdGetPtr (PcdFirmwareVersionString
));
342 return HashLogExtendEvent (
344 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
),
345 TcgEventHdr
.EventSize
,
347 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
)
353 Add it into the measured FV list after the FV is measured successfully.
355 @param[in] FvBase Base address of FV image.
356 @param[in] FvLength Length of FV image.
358 @retval EFI_SUCCESS Fv image is measured successfully
359 or it has been already measured.
360 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
361 @retval EFI_DEVICE_ERROR The command was unsuccessful.
367 IN EFI_PHYSICAL_ADDRESS FvBase
,
373 EFI_PLATFORM_FIRMWARE_BLOB FvBlob
;
374 TCG_PCR_EVENT_HDR TcgEventHdr
;
377 // Check if it is in Excluded FV list
379 if (mMeasurementExcludedFvPpi
!= NULL
) {
380 for (Index
= 0; Index
< mMeasurementExcludedFvPpi
->Count
; Index
++) {
381 if (mMeasurementExcludedFvPpi
->Fv
[Index
].FvBase
== FvBase
) {
382 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase
));
383 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength
));
390 // Check whether FV is in the measured FV list.
392 for (Index
= 0; Index
< mMeasuredBaseFvIndex
; Index
++) {
393 if (mMeasuredBaseFvInfo
[Index
].BlobBase
== FvBase
) {
399 // Measure and record the FV to the TPM
401 FvBlob
.BlobBase
= FvBase
;
402 FvBlob
.BlobLength
= FvLength
;
404 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob
.BlobBase
));
405 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob
.BlobLength
));
407 TcgEventHdr
.PCRIndex
= 0;
408 TcgEventHdr
.EventType
= EV_EFI_PLATFORM_FIRMWARE_BLOB
;
409 TcgEventHdr
.EventSize
= sizeof (FvBlob
);
411 Status
= HashLogExtendEvent (
412 (EFI_PEI_SERVICES
**) GetPeiServicesTablePointer(),
413 (UINT8
*) (UINTN
) FvBlob
.BlobBase
,
414 (UINTN
) FvBlob
.BlobLength
,
420 // Add new FV into the measured FV list.
422 ASSERT (mMeasuredBaseFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
));
423 if (mMeasuredBaseFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
424 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobBase
= FvBase
;
425 mMeasuredBaseFvInfo
[mMeasuredBaseFvIndex
].BlobLength
= FvLength
;
426 mMeasuredBaseFvIndex
++;
435 @param[in] PeiServices Describes the list of possible PEI Services.
437 @retval EFI_SUCCESS Operation completed successfully.
438 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
439 @retval EFI_DEVICE_ERROR The command was unsuccessful.
445 IN EFI_PEI_SERVICES
**PeiServices
450 EFI_PEI_FV_HANDLE VolumeHandle
;
451 EFI_FV_INFO VolumeInfo
;
452 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
457 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
458 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
459 // platform for special CRTM TPM measuring.
461 Status
= PeiServicesFfsFindNextVolume (FvInstances
, &VolumeHandle
);
462 if (EFI_ERROR (Status
)) {
467 // Measure and record the firmware volume that is dispatched by PeiCore
469 Status
= PeiServicesFfsGetVolumeInfo (VolumeHandle
, &VolumeInfo
);
470 ASSERT_EFI_ERROR (Status
);
472 // Locate the corresponding FV_PPI according to founded FV's format guid
474 Status
= PeiServicesLocatePpi (
475 &VolumeInfo
.FvFormat
,
480 if (!EFI_ERROR (Status
)) {
481 MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) VolumeInfo
.FvStart
, VolumeInfo
.FvSize
);
491 Measure and record the Firmware Volum Information once FvInfoPPI install.
493 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
494 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
495 @param[in] Ppi Address of the PPI that was installed.
497 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
498 @return Others Fail to measure FV.
503 FirmwareVolmeInfoPpiNotifyCallback (
504 IN EFI_PEI_SERVICES
**PeiServices
,
505 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
509 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
511 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
514 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*) Ppi
;
517 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
519 Status
= PeiServicesLocatePpi (
525 if (EFI_ERROR (Status
)) {
530 // This is an FV from an FFS file, and the parent FV must have already been measured,
531 // No need to measure twice, so just record the FV and return
533 if (Fv
->ParentFvName
!= NULL
|| Fv
->ParentFileName
!= NULL
) {
535 ASSERT (mMeasuredChildFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
));
536 if (mMeasuredChildFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
538 // Check whether FV is in the measured child FV list.
540 for (Index
= 0; Index
< mMeasuredChildFvIndex
; Index
++) {
541 if (mMeasuredChildFvInfo
[Index
].BlobBase
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
) {
545 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
;
546 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobLength
= Fv
->FvInfoSize
;
547 mMeasuredChildFvIndex
++;
552 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
, Fv
->FvInfoSize
);
556 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.
557 And lock physical presence if needed.
559 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
560 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
561 @param[in] Ppi Address of the PPI that was installed.
563 @retval EFI_SUCCESS Operation completed successfully.
564 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.
565 @retval EFI_DEVICE_ERROR The command was unsuccessful.
570 PhysicalPresencePpiNotifyCallback (
571 IN EFI_PEI_SERVICES
**PeiServices
,
572 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
577 TPM_PERMANENT_FLAGS TpmPermanentFlags
;
578 PEI_LOCK_PHYSICAL_PRESENCE_PPI
*LockPhysicalPresencePpi
;
579 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue
;
581 Status
= Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags
);
582 if (EFI_ERROR (Status
)) {
587 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.
589 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock
) && !TpmPermanentFlags
.physicalPresenceLifetimeLock
) {
591 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
593 PhysicalPresenceValue
= TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK
;
594 TpmPermanentFlags
.physicalPresenceLifetimeLock
= TRUE
;
596 if (PcdGetBool (PcdPhysicalPresenceCmdEnable
)) {
597 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_ENABLE
;
598 TpmPermanentFlags
.physicalPresenceCMDEnable
= TRUE
;
600 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_DISABLE
;
601 TpmPermanentFlags
.physicalPresenceCMDEnable
= FALSE
;
604 if (PcdGetBool (PcdPhysicalPresenceHwEnable
)) {
605 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_ENABLE
;
607 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_DISABLE
;
610 Status
= Tpm12PhysicalPresence (
611 PhysicalPresenceValue
613 if (EFI_ERROR (Status
)) {
619 // 2. Lock physical presence if it is required.
621 LockPhysicalPresencePpi
= (PEI_LOCK_PHYSICAL_PRESENCE_PPI
*) Ppi
;
622 if (!LockPhysicalPresencePpi
->LockPhysicalPresence ((CONST EFI_PEI_SERVICES
**) PeiServices
)) {
626 if (!TpmPermanentFlags
.physicalPresenceCMDEnable
) {
627 if (TpmPermanentFlags
.physicalPresenceLifetimeLock
) {
629 // physicalPresenceCMDEnable is locked, can't change.
635 // Enable physical presence command
636 // It is necessary in order to lock physical presence
638 Status
= Tpm12PhysicalPresence (
639 TPM_PHYSICAL_PRESENCE_CMD_ENABLE
641 if (EFI_ERROR (Status
)) {
647 // Lock physical presence
649 Status
= Tpm12PhysicalPresence (
650 TPM_PHYSICAL_PRESENCE_LOCK
656 Check if TPM chip is activeated or not.
658 @param[in] PeiServices Describes the list of possible PEI Services.
660 @retval TRUE TPM is activated.
661 @retval FALSE TPM is deactivated.
670 TPM_PERMANENT_FLAGS TpmPermanentFlags
;
672 Status
= Tpm12GetCapabilityFlagPermanent (&TpmPermanentFlags
);
673 if (EFI_ERROR (Status
)) {
676 return (BOOLEAN
)(!TpmPermanentFlags
.deactivated
);
680 Do measurement after memory is ready.
682 @param[in] PeiServices Describes the list of possible PEI Services.
684 @retval EFI_SUCCESS Operation completed successfully.
685 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
686 @retval EFI_DEVICE_ERROR The command was unsuccessful.
692 IN EFI_PEI_SERVICES
**PeiServices
697 Status
= PeiServicesLocatePpi (
698 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid
,
701 (VOID
**)&mMeasurementExcludedFvPpi
703 // Do not check status, because it is optional
705 mMeasuredBaseFvInfo
= (EFI_PLATFORM_FIRMWARE_BLOB
*) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * PcdGet32 (PcdPeiCoreMaxFvSupported
));
706 ASSERT (mMeasuredBaseFvInfo
!= NULL
);
707 mMeasuredChildFvInfo
= (EFI_PLATFORM_FIRMWARE_BLOB
*) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * PcdGet32 (PcdPeiCoreMaxFvSupported
));
708 ASSERT (mMeasuredChildFvInfo
!= NULL
);
710 Status
= Tpm12RequestUseTpm ();
711 if (EFI_ERROR (Status
)) {
715 if (IsTpmUsable ()) {
716 if (PcdGet8 (PcdTpmScrtmPolicy
) == 1) {
717 Status
= MeasureCRTMVersion (PeiServices
);
720 Status
= MeasureMainBios (PeiServices
);
725 // 1). for the FvInfoPpi services to measure and record
726 // the additional Fvs to TPM
727 // 2). for the OperatorPresencePpi service to determine whether to
730 Status
= PeiServicesNotifyPpi (&mNotifyList
[0]);
731 ASSERT_EFI_ERROR (Status
);
737 Entry point of this module.
739 @param[in] FileHandle Handle of the file being invoked.
740 @param[in] PeiServices Describes the list of possible PEI Services.
748 IN EFI_PEI_FILE_HANDLE FileHandle
,
749 IN CONST EFI_PEI_SERVICES
**PeiServices
754 EFI_BOOT_MODE BootMode
;
756 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
757 DEBUG ((EFI_D_ERROR
, "No TPM12 instance required!\n"));
758 return EFI_UNSUPPORTED
;
761 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
762 DEBUG ((EFI_D_ERROR
, "TPM error!\n"));
763 return EFI_DEVICE_ERROR
;
767 // Initialize TPM device
769 Status
= PeiServicesGetBootMode (&BootMode
);
770 ASSERT_EFI_ERROR (Status
);
773 // In S3 path, skip shadow logic. no measurement is required
775 if (BootMode
!= BOOT_ON_S3_RESUME
) {
776 Status
= (**PeiServices
).RegisterForShadow(FileHandle
);
777 if (Status
== EFI_ALREADY_STARTED
) {
778 mImageInMemory
= TRUE
;
779 } else if (Status
== EFI_NOT_FOUND
) {
780 ASSERT_EFI_ERROR (Status
);
784 if (!mImageInMemory
) {
785 Status
= Tpm12RequestUseTpm ();
786 if (EFI_ERROR (Status
)) {
787 DEBUG ((DEBUG_ERROR
, "TPM not detected!\n"));
791 if (PcdGet8 (PcdTpmInitializationPolicy
) == 1) {
792 if (BootMode
== BOOT_ON_S3_RESUME
) {
793 Status
= Tpm12Startup (TPM_ST_STATE
);
795 Status
= Tpm12Startup (TPM_ST_CLEAR
);
797 if (EFI_ERROR (Status
) ) {
803 // TpmSelfTest is optional on S3 path, skip it to save S3 time
805 if (BootMode
!= BOOT_ON_S3_RESUME
) {
806 Status
= Tpm12ContinueSelfTest ();
807 if (EFI_ERROR (Status
)) {
813 // Only intall TpmInitializedPpi on success
815 Status
= PeiServicesInstallPpi (&mTpmInitializedPpiList
);
816 ASSERT_EFI_ERROR (Status
);
819 if (mImageInMemory
) {
820 Status
= PeimEntryMP ((EFI_PEI_SERVICES
**)PeiServices
);
825 if (EFI_ERROR (Status
)) {
826 DEBUG ((EFI_D_ERROR
, "TPM error! Build Hob\n"));
827 BuildGuidHob (&gTpmErrorHobGuid
,0);
829 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
830 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
834 // Always intall TpmInitializationDonePpi no matter success or fail.
835 // Other driver can know TPM initialization state by TpmInitializedPpi.
837 Status2
= PeiServicesInstallPpi (&mTpmInitializationDonePpiList
);
838 ASSERT_EFI_ERROR (Status2
);