2 Initialize TPM device and measure FVs before handing off control to DXE.
4 Copyright (c) 2005 - 2015, 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>
40 #include <Library/MemoryAllocationLib.h>
41 #include <Library/ReportStatusCodeLib.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 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
203 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
204 added into the Event Log.
206 @param[in] PeiServices Describes the list of possible PEI Services.
207 @param[in] HashData Physical address of the start of the data buffer
208 to be hashed, extended, and logged.
209 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
210 @param[in] TpmHandle TPM handle.
211 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
212 @param[in] NewEventData Pointer to the new event data.
214 @retval EFI_SUCCESS Operation completed successfully.
215 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
216 @retval EFI_DEVICE_ERROR The command was unsuccessful.
221 IN EFI_PEI_SERVICES
**PeiServices
,
223 IN UINTN HashDataLen
,
224 IN TIS_TPM_HANDLE TpmHandle
,
225 IN TCG_PCR_EVENT_HDR
*NewEventHdr
,
226 IN UINT8
*NewEventData
232 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
233 return EFI_DEVICE_ERROR
;
237 if (HashDataLen
!= 0) {
238 Status
= TpmCommHashAll (
243 if (EFI_ERROR (Status
)) {
248 Status
= TpmCommExtend (
251 &NewEventHdr
->Digest
,
252 NewEventHdr
->PCRIndex
,
255 if (EFI_ERROR (Status
)) {
259 HobData
= BuildGuidHob (
260 &gTcgEventEntryHobGuid
,
261 sizeof (*NewEventHdr
) + NewEventHdr
->EventSize
263 if (HobData
== NULL
) {
264 Status
= EFI_OUT_OF_RESOURCES
;
268 CopyMem (HobData
, NewEventHdr
, sizeof (*NewEventHdr
));
269 HobData
= (VOID
*) ((UINT8
*)HobData
+ sizeof (*NewEventHdr
));
270 CopyMem (HobData
, NewEventData
, NewEventHdr
->EventSize
);
273 if ((Status
== EFI_DEVICE_ERROR
) || (Status
== EFI_TIMEOUT
)) {
274 DEBUG ((EFI_D_ERROR
, "HashLogExtendEvent - %r. Disable TPM.\n", Status
));
275 BuildGuidHob (&gTpmErrorHobGuid
,0);
277 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
278 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
280 Status
= EFI_DEVICE_ERROR
;
286 Measure CRTM version.
288 @param[in] PeiServices Describes the list of possible PEI Services.
289 @param[in] TpmHandle TPM handle.
291 @retval EFI_SUCCESS Operation completed successfully.
292 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
293 @retval EFI_DEVICE_ERROR The command was unsuccessful.
299 IN EFI_PEI_SERVICES
**PeiServices
,
300 IN TIS_TPM_HANDLE TpmHandle
303 TCG_PCR_EVENT_HDR TcgEventHdr
;
306 // Use FirmwareVersion string to represent CRTM version.
307 // OEMs should get real CRTM version string and measure it.
310 TcgEventHdr
.PCRIndex
= 0;
311 TcgEventHdr
.EventType
= EV_S_CRTM_VERSION
;
312 TcgEventHdr
.EventSize
= (UINT32
) StrSize((CHAR16
*)PcdGetPtr (PcdFirmwareVersionString
));
314 return HashLogExtendEvent (
316 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
),
317 TcgEventHdr
.EventSize
,
320 (UINT8
*)PcdGetPtr (PcdFirmwareVersionString
)
326 Add it into the measured FV list after the FV is measured successfully.
328 @param[in] FvBase Base address of FV image.
329 @param[in] FvLength Length of FV image.
331 @retval EFI_SUCCESS Fv image is measured successfully
332 or it has been already measured.
333 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
334 @retval EFI_DEVICE_ERROR The command was unsuccessful.
340 IN EFI_PHYSICAL_ADDRESS FvBase
,
346 EFI_PLATFORM_FIRMWARE_BLOB FvBlob
;
347 TCG_PCR_EVENT_HDR TcgEventHdr
;
348 TIS_TPM_HANDLE TpmHandle
;
350 TpmHandle
= (TIS_TPM_HANDLE
) (UINTN
) TPM_BASE_ADDRESS
;
353 // Check if it is in Excluded FV list
355 if (mMeasurementExcludedFvPpi
!= NULL
) {
356 for (Index
= 0; Index
< mMeasurementExcludedFvPpi
->Count
; Index
++) {
357 if (mMeasurementExcludedFvPpi
->Fv
[Index
].FvBase
== FvBase
) {
358 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase
));
359 DEBUG ((DEBUG_INFO
, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength
));
366 // Check whether FV is in the measured FV list.
368 for (Index
= 0; Index
< mMeasuredBaseFvIndex
; Index
++) {
369 if (mMeasuredBaseFvInfo
[Index
].BlobBase
== FvBase
) {
375 // Measure and record the FV to the TPM
377 FvBlob
.BlobBase
= FvBase
;
378 FvBlob
.BlobLength
= FvLength
;
380 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob
.BlobBase
));
381 DEBUG ((DEBUG_INFO
, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob
.BlobLength
));
383 TcgEventHdr
.PCRIndex
= 0;
384 TcgEventHdr
.EventType
= EV_EFI_PLATFORM_FIRMWARE_BLOB
;
385 TcgEventHdr
.EventSize
= sizeof (FvBlob
);
387 Status
= HashLogExtendEvent (
388 (EFI_PEI_SERVICES
**) GetPeiServicesTablePointer(),
389 (UINT8
*) (UINTN
) FvBlob
.BlobBase
,
390 (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 @param[in] PeiServices Describes the list of possible PEI Services.
413 @param[in] TpmHandle TPM handle.
415 @retval EFI_SUCCESS Operation completed successfully.
416 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
417 @retval EFI_DEVICE_ERROR The command was unsuccessful.
423 IN EFI_PEI_SERVICES
**PeiServices
,
424 IN TIS_TPM_HANDLE TpmHandle
429 EFI_PEI_FV_HANDLE VolumeHandle
;
430 EFI_FV_INFO VolumeInfo
;
431 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
436 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
437 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
438 // platform for special CRTM TPM measuring.
440 Status
= PeiServicesFfsFindNextVolume (FvInstances
, &VolumeHandle
);
441 if (EFI_ERROR (Status
)) {
446 // Measure and record the firmware volume that is dispatched by PeiCore
448 Status
= PeiServicesFfsGetVolumeInfo (VolumeHandle
, &VolumeInfo
);
449 ASSERT_EFI_ERROR (Status
);
451 // Locate the corresponding FV_PPI according to founded FV's format guid
453 Status
= PeiServicesLocatePpi (
454 &VolumeInfo
.FvFormat
,
459 if (!EFI_ERROR (Status
)) {
460 MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) VolumeInfo
.FvStart
, VolumeInfo
.FvSize
);
470 Measure and record the Firmware Volum Information once FvInfoPPI install.
472 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
473 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
474 @param[in] Ppi Address of the PPI that was installed.
476 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
477 @return Others Fail to measure FV.
482 FirmwareVolmeInfoPpiNotifyCallback (
483 IN EFI_PEI_SERVICES
**PeiServices
,
484 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
488 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*Fv
;
490 EFI_PEI_FIRMWARE_VOLUME_PPI
*FvPpi
;
493 Fv
= (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI
*) Ppi
;
496 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
498 Status
= PeiServicesLocatePpi (
504 if (EFI_ERROR (Status
)) {
509 // This is an FV from an FFS file, and the parent FV must have already been measured,
510 // No need to measure twice, so just record the FV and return
512 if (Fv
->ParentFvName
!= NULL
|| Fv
->ParentFileName
!= NULL
) {
514 ASSERT (mMeasuredChildFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
));
515 if (mMeasuredChildFvIndex
< PcdGet32 (PcdPeiCoreMaxFvSupported
)) {
517 // Check whether FV is in the measured child FV list.
519 for (Index
= 0; Index
< mMeasuredChildFvIndex
; Index
++) {
520 if (mMeasuredChildFvInfo
[Index
].BlobBase
== (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
) {
524 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
;
525 mMeasuredChildFvInfo
[mMeasuredChildFvIndex
].BlobLength
= Fv
->FvInfoSize
;
526 mMeasuredChildFvIndex
++;
531 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS
) (UINTN
) Fv
->FvInfo
, Fv
->FvInfoSize
);
535 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.
536 And lock physical presence if needed.
538 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
539 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
540 @param[in] Ppi Address of the PPI that was installed.
542 @retval EFI_SUCCESS Operation completed successfully.
543 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.
544 @retval EFI_DEVICE_ERROR The command was unsuccessful.
549 PhysicalPresencePpiNotifyCallback (
550 IN EFI_PEI_SERVICES
**PeiServices
,
551 IN EFI_PEI_NOTIFY_DESCRIPTOR
*NotifyDescriptor
,
556 PEI_LOCK_PHYSICAL_PRESENCE_PPI
*LockPhysicalPresencePpi
;
557 BOOLEAN LifetimeLock
;
559 TIS_TPM_HANDLE TpmHandle
;
560 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue
;
562 TpmHandle
= (TIS_TPM_HANDLE
) (UINTN
) TPM_BASE_ADDRESS
;
564 Status
= TpmCommGetCapability (PeiServices
, TpmHandle
, NULL
, &LifetimeLock
, &CmdEnable
);
565 if (EFI_ERROR (Status
)) {
570 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.
572 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock
) && !LifetimeLock
) {
574 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
576 PhysicalPresenceValue
= TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK
;
578 if (PcdGetBool (PcdPhysicalPresenceCmdEnable
)) {
579 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_ENABLE
;
582 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_CMD_DISABLE
;
586 if (PcdGetBool (PcdPhysicalPresenceHwEnable
)) {
587 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_ENABLE
;
589 PhysicalPresenceValue
|= TPM_PHYSICAL_PRESENCE_HW_DISABLE
;
592 Status
= TpmCommPhysicalPresence (
595 PhysicalPresenceValue
597 if (EFI_ERROR (Status
)) {
603 // 2. Lock physical presence if it is required.
605 LockPhysicalPresencePpi
= (PEI_LOCK_PHYSICAL_PRESENCE_PPI
*) Ppi
;
606 if (!LockPhysicalPresencePpi
->LockPhysicalPresence ((CONST EFI_PEI_SERVICES
**) PeiServices
)) {
613 // physicalPresenceCMDEnable is locked, can't change.
619 // Enable physical presence command
620 // It is necessary in order to lock physical presence
622 Status
= TpmCommPhysicalPresence (
625 TPM_PHYSICAL_PRESENCE_CMD_ENABLE
627 if (EFI_ERROR (Status
)) {
633 // Lock physical presence
635 Status
= TpmCommPhysicalPresence (
638 TPM_PHYSICAL_PRESENCE_LOCK
644 Check if TPM chip is activeated or not.
646 @param[in] PeiServices Describes the list of possible PEI Services.
647 @param[in] TpmHandle TPM handle.
649 @retval TRUE TPM is activated.
650 @retval FALSE TPM is deactivated.
656 IN EFI_PEI_SERVICES
**PeiServices
,
657 IN TIS_TPM_HANDLE TpmHandle
663 Status
= TpmCommGetCapability (PeiServices
, TpmHandle
, &Deactivated
, NULL
, NULL
);
664 if (EFI_ERROR (Status
)) {
667 return (BOOLEAN
)(!Deactivated
);
671 Do measurement after memory is ready.
673 @param[in] PeiServices Describes the list of possible PEI Services.
675 @retval EFI_SUCCESS Operation completed successfully.
676 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
677 @retval EFI_DEVICE_ERROR The command was unsuccessful.
683 IN EFI_PEI_SERVICES
**PeiServices
687 TIS_TPM_HANDLE TpmHandle
;
689 Status
= PeiServicesLocatePpi (
690 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid
,
693 (VOID
**)&mMeasurementExcludedFvPpi
695 // Do not check status, because it is optional
697 mMeasuredBaseFvInfo
= (EFI_PLATFORM_FIRMWARE_BLOB
*) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * PcdGet32 (PcdPeiCoreMaxFvSupported
));
698 ASSERT (mMeasuredBaseFvInfo
!= NULL
);
699 mMeasuredChildFvInfo
= (EFI_PLATFORM_FIRMWARE_BLOB
*) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB
) * PcdGet32 (PcdPeiCoreMaxFvSupported
));
700 ASSERT (mMeasuredChildFvInfo
!= NULL
);
702 TpmHandle
= (TIS_TPM_HANDLE
)(UINTN
)TPM_BASE_ADDRESS
;
703 Status
= TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR
)TpmHandle
);
704 if (EFI_ERROR (Status
)) {
708 if (IsTpmUsable (PeiServices
, TpmHandle
)) {
709 if (PcdGet8 (PcdTpmScrtmPolicy
) == 1) {
710 Status
= MeasureCRTMVersion (PeiServices
, TpmHandle
);
713 Status
= MeasureMainBios (PeiServices
, TpmHandle
);
718 // 1). for the FvInfoPpi services to measure and record
719 // the additional Fvs to TPM
720 // 2). for the OperatorPresencePpi service to determine whether to
723 Status
= PeiServicesNotifyPpi (&mNotifyList
[0]);
724 ASSERT_EFI_ERROR (Status
);
730 Entry point of this module.
732 @param[in] FileHandle Handle of the file being invoked.
733 @param[in] PeiServices Describes the list of possible PEI Services.
741 IN EFI_PEI_FILE_HANDLE FileHandle
,
742 IN CONST EFI_PEI_SERVICES
**PeiServices
747 EFI_BOOT_MODE BootMode
;
748 TIS_TPM_HANDLE TpmHandle
;
750 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid
), &gEfiTpmDeviceInstanceTpm12Guid
)){
751 DEBUG ((EFI_D_ERROR
, "No TPM12 instance required!\n"));
752 return EFI_UNSUPPORTED
;
755 if (GetFirstGuidHob (&gTpmErrorHobGuid
) != NULL
) {
756 DEBUG ((EFI_D_ERROR
, "TPM error!\n"));
757 return EFI_DEVICE_ERROR
;
761 // Initialize TPM device
763 Status
= PeiServicesGetBootMode (&BootMode
);
764 ASSERT_EFI_ERROR (Status
);
767 // In S3 path, skip shadow logic. no measurement is required
769 if (BootMode
!= BOOT_ON_S3_RESUME
) {
770 Status
= (**PeiServices
).RegisterForShadow(FileHandle
);
771 if (Status
== EFI_ALREADY_STARTED
) {
772 mImageInMemory
= TRUE
;
773 } else if (Status
== EFI_NOT_FOUND
) {
774 ASSERT_EFI_ERROR (Status
);
778 if (!mImageInMemory
) {
779 TpmHandle
= (TIS_TPM_HANDLE
)(UINTN
)TPM_BASE_ADDRESS
;
780 Status
= TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR
)TpmHandle
);
781 if (EFI_ERROR (Status
)) {
782 DEBUG ((DEBUG_ERROR
, "TPM not detected!\n"));
786 if (PcdGet8 (PcdTpmInitializationPolicy
) == 1) {
787 Status
= TpmCommStartup ((EFI_PEI_SERVICES
**)PeiServices
, TpmHandle
, BootMode
);
788 if (EFI_ERROR (Status
) ) {
794 // TpmSelfTest is optional on S3 path, skip it to save S3 time
796 if (BootMode
!= BOOT_ON_S3_RESUME
) {
797 Status
= TpmCommContinueSelfTest ((EFI_PEI_SERVICES
**)PeiServices
, TpmHandle
);
798 if (EFI_ERROR (Status
)) {
804 // Only intall TpmInitializedPpi on success
806 Status
= PeiServicesInstallPpi (&mTpmInitializedPpiList
);
807 ASSERT_EFI_ERROR (Status
);
810 if (mImageInMemory
) {
811 Status
= PeimEntryMP ((EFI_PEI_SERVICES
**)PeiServices
);
816 if (EFI_ERROR (Status
)) {
817 DEBUG ((EFI_D_ERROR
, "TPM error! Build Hob\n"));
818 BuildGuidHob (&gTpmErrorHobGuid
,0);
820 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
821 (PcdGet32 (PcdStatusCodeSubClassTpmDevice
) | EFI_P_EC_INTERFACE_ERROR
)
825 // Always intall TpmInitializationDonePpi no matter success or fail.
826 // Other driver can know TPM initialization state by TpmInitializedPpi.
828 Status2
= PeiServicesInstallPpi (&mTpmInitializationDonePpiList
);
829 ASSERT_EFI_ERROR (Status2
);