2 Initialize TPM device and measure FVs before handing off control to DXE.
\r
4 Copyright (c) 2005 - 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/Tpm12.h>
\r
18 #include <IndustryStandard/UefiTcgPlatform.h>
\r
19 #include <Ppi/FirmwareVolumeInfo.h>
\r
20 #include <Ppi/FirmwareVolumeInfo2.h>
\r
21 #include <Ppi/LockPhysicalPresence.h>
\r
22 #include <Ppi/TpmInitialized.h>
\r
23 #include <Ppi/FirmwareVolume.h>
\r
24 #include <Ppi/EndOfPeiPhase.h>
\r
25 #include <Ppi/FirmwareVolumeInfoMeasurementExcluded.h>
\r
27 #include <Guid/TcgEventHob.h>
\r
28 #include <Guid/MeasuredFvHob.h>
\r
29 #include <Guid/TpmInstance.h>
\r
31 #include <Library/DebugLib.h>
\r
32 #include <Library/BaseMemoryLib.h>
\r
33 #include <Library/PeiServicesLib.h>
\r
34 #include <Library/PeimEntryPoint.h>
\r
35 #include <Library/TpmCommLib.h>
\r
36 #include <Library/HobLib.h>
\r
37 #include <Library/PcdLib.h>
\r
38 #include <Library/PeiServicesTablePointerLib.h>
\r
39 #include <Library/BaseLib.h>
\r
40 #include <Library/MemoryAllocationLib.h>
\r
41 #include <Library/ReportStatusCodeLib.h>
\r
43 #include "TpmComm.h"
\r
45 BOOLEAN mImageInMemory = FALSE;
\r
47 EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {
\r
48 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
\r
49 &gPeiTpmInitializedPpiGuid,
\r
53 EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = {
\r
54 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
\r
55 &gPeiTpmInitializationDonePpiGuid,
\r
59 EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredBaseFvInfo;
\r
60 UINT32 mMeasuredBaseFvIndex = 0;
\r
62 EFI_PLATFORM_FIRMWARE_BLOB *mMeasuredChildFvInfo;
\r
63 UINT32 mMeasuredChildFvIndex = 0;
\r
65 EFI_PEI_FIRMWARE_VOLUME_INFO_MEASUREMENT_EXCLUDED_PPI *mMeasurementExcludedFvPpi;
\r
68 Lock physical presence if needed.
\r
70 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
\r
71 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
72 @param[in] Ppi Address of the PPI that was installed.
\r
74 @retval EFI_SUCCESS Operation completed successfully.
\r
79 PhysicalPresencePpiNotifyCallback (
\r
80 IN EFI_PEI_SERVICES **PeiServices,
\r
81 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
86 Measure and record the Firmware Volum Information once FvInfoPPI install.
\r
88 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
\r
89 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
90 @param[in] Ppi Address of the PPI that was installed.
\r
92 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
\r
93 @return Others Fail to measure FV.
\r
98 FirmwareVolmeInfoPpiNotifyCallback (
\r
99 IN EFI_PEI_SERVICES **PeiServices,
\r
100 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
105 Record all measured Firmware Volum Information into a Guid Hob
\r
107 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
\r
108 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
109 @param[in] Ppi Address of the PPI that was installed.
\r
111 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
\r
112 @return Others Fail to measure FV.
\r
117 EndofPeiSignalNotifyCallBack (
\r
118 IN EFI_PEI_SERVICES **PeiServices,
\r
119 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
123 EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
\r
125 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
\r
126 &gPeiLockPhysicalPresencePpiGuid,
\r
127 PhysicalPresencePpiNotifyCallback
\r
130 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
\r
131 &gEfiPeiFirmwareVolumeInfoPpiGuid,
\r
132 FirmwareVolmeInfoPpiNotifyCallback
\r
135 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
\r
136 &gEfiPeiFirmwareVolumeInfo2PpiGuid,
\r
137 FirmwareVolmeInfoPpiNotifyCallback
\r
140 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
\r
141 &gEfiEndOfPeiSignalPpiGuid,
\r
142 EndofPeiSignalNotifyCallBack
\r
147 Record all measured Firmware Volum Information into a Guid Hob
\r
148 Guid Hob payload layout is
\r
150 UINT32 *************************** FIRMWARE_BLOB number
\r
151 EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array
\r
153 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
\r
154 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
155 @param[in] Ppi Address of the PPI that was installed.
\r
157 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
\r
158 @return Others Fail to measure FV.
\r
163 EndofPeiSignalNotifyCallBack (
\r
164 IN EFI_PEI_SERVICES **PeiServices,
\r
165 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
169 MEASURED_HOB_DATA *MeasuredHobData;
\r
171 MeasuredHobData = NULL;
\r
174 // Create a Guid hob to save all measured Fv
\r
176 MeasuredHobData = BuildGuidHob(
\r
177 &gMeasuredFvHobGuid,
\r
178 sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex)
\r
181 if (MeasuredHobData != NULL){
\r
183 // Save measured FV info enty number
\r
185 MeasuredHobData->Num = mMeasuredBaseFvIndex + mMeasuredChildFvIndex;
\r
188 // Save measured base Fv info
\r
190 CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex));
\r
193 // Save measured child Fv info
\r
195 CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex));
\r
198 return EFI_SUCCESS;
\r
202 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,
\r
203 and build a GUIDed HOB recording the event which will be passed to the DXE phase and
\r
204 added into the Event Log.
\r
206 @param[in] PeiServices Describes the list of possible PEI Services.
\r
207 @param[in] HashData Physical address of the start of the data buffer
\r
208 to be hashed, extended, and logged.
\r
209 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.
\r
210 @param[in] TpmHandle TPM handle.
\r
211 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure.
\r
212 @param[in] NewEventData Pointer to the new event data.
\r
214 @retval EFI_SUCCESS Operation completed successfully.
\r
215 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
216 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
220 HashLogExtendEvent (
\r
221 IN EFI_PEI_SERVICES **PeiServices,
\r
222 IN UINT8 *HashData,
\r
223 IN UINTN HashDataLen,
\r
224 IN TIS_TPM_HANDLE TpmHandle,
\r
225 IN TCG_PCR_EVENT_HDR *NewEventHdr,
\r
226 IN UINT8 *NewEventData
\r
232 if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) {
\r
233 return EFI_DEVICE_ERROR;
\r
237 if (HashDataLen != 0) {
\r
238 Status = TpmCommHashAll (
\r
241 &NewEventHdr->Digest
\r
243 if (EFI_ERROR (Status)) {
\r
248 Status = TpmCommExtend (
\r
251 &NewEventHdr->Digest,
\r
252 NewEventHdr->PCRIndex,
\r
255 if (EFI_ERROR (Status)) {
\r
259 HobData = BuildGuidHob (
\r
260 &gTcgEventEntryHobGuid,
\r
261 sizeof (*NewEventHdr) + NewEventHdr->EventSize
\r
263 if (HobData == NULL) {
\r
264 Status = EFI_OUT_OF_RESOURCES;
\r
268 CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));
\r
269 HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));
\r
270 CopyMem (HobData, NewEventData, NewEventHdr->EventSize);
\r
273 if ((Status == EFI_DEVICE_ERROR) || (Status == EFI_TIMEOUT)) {
\r
274 DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status));
\r
275 BuildGuidHob (&gTpmErrorHobGuid,0);
\r
276 REPORT_STATUS_CODE (
\r
277 EFI_ERROR_CODE | EFI_ERROR_MINOR,
\r
278 (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR)
\r
280 Status = EFI_DEVICE_ERROR;
\r
286 Measure CRTM version.
\r
288 @param[in] PeiServices Describes the list of possible PEI Services.
\r
289 @param[in] TpmHandle TPM handle.
\r
291 @retval EFI_SUCCESS Operation completed successfully.
\r
292 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
293 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
298 MeasureCRTMVersion (
\r
299 IN EFI_PEI_SERVICES **PeiServices,
\r
300 IN TIS_TPM_HANDLE TpmHandle
\r
303 TCG_PCR_EVENT_HDR TcgEventHdr;
\r
306 // Use FirmwareVersion string to represent CRTM version.
\r
307 // OEMs should get real CRTM version string and measure it.
\r
310 TcgEventHdr.PCRIndex = 0;
\r
311 TcgEventHdr.EventType = EV_S_CRTM_VERSION;
\r
312 TcgEventHdr.EventSize = (UINT32) StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));
\r
314 return HashLogExtendEvent (
\r
316 (UINT8*)PcdGetPtr (PcdFirmwareVersionString),
\r
317 TcgEventHdr.EventSize,
\r
320 (UINT8*)PcdGetPtr (PcdFirmwareVersionString)
\r
326 Add it into the measured FV list after the FV is measured successfully.
\r
328 @param[in] FvBase Base address of FV image.
\r
329 @param[in] FvLength Length of FV image.
\r
331 @retval EFI_SUCCESS Fv image is measured successfully
\r
332 or it has been already measured.
\r
333 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
334 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
340 IN EFI_PHYSICAL_ADDRESS FvBase,
\r
346 EFI_PLATFORM_FIRMWARE_BLOB FvBlob;
\r
347 TCG_PCR_EVENT_HDR TcgEventHdr;
\r
348 TIS_TPM_HANDLE TpmHandle;
\r
350 TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;
\r
353 // Check if it is in Excluded FV list
\r
355 if (mMeasurementExcludedFvPpi != NULL) {
\r
356 for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) {
\r
357 if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) {
\r
358 DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei starts at: 0x%x\n", FvBase));
\r
359 DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei has the size: 0x%x\n", FvLength));
\r
360 return EFI_SUCCESS;
\r
366 // Check whether FV is in the measured FV list.
\r
368 for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) {
\r
369 if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) {
\r
370 return EFI_SUCCESS;
\r
375 // Measure and record the FV to the TPM
\r
377 FvBlob.BlobBase = FvBase;
\r
378 FvBlob.BlobLength = FvLength;
\r
380 DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob.BlobBase));
\r
381 DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob.BlobLength));
\r
383 TcgEventHdr.PCRIndex = 0;
\r
384 TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;
\r
385 TcgEventHdr.EventSize = sizeof (FvBlob);
\r
387 Status = HashLogExtendEvent (
\r
388 (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),
\r
389 (UINT8*) (UINTN) FvBlob.BlobBase,
\r
390 (UINTN) FvBlob.BlobLength,
\r
397 // Add new FV into the measured FV list.
\r
399 ASSERT (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));
\r
400 if (mMeasuredBaseFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {
\r
401 mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase;
\r
402 mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength;
\r
403 mMeasuredBaseFvIndex++;
\r
412 @param[in] PeiServices Describes the list of possible PEI Services.
\r
413 @param[in] TpmHandle TPM handle.
\r
415 @retval EFI_SUCCESS Operation completed successfully.
\r
416 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
417 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
423 IN EFI_PEI_SERVICES **PeiServices,
\r
424 IN TIS_TPM_HANDLE TpmHandle
\r
428 UINT32 FvInstances;
\r
429 EFI_PEI_FV_HANDLE VolumeHandle;
\r
430 EFI_FV_INFO VolumeInfo;
\r
431 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
\r
436 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement
\r
437 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special
\r
438 // platform for special CRTM TPM measuring.
\r
440 Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);
\r
441 if (EFI_ERROR (Status)) {
\r
446 // Measure and record the firmware volume that is dispatched by PeiCore
\r
448 Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
\r
449 ASSERT_EFI_ERROR (Status);
\r
451 // Locate the corresponding FV_PPI according to founded FV's format guid
\r
453 Status = PeiServicesLocatePpi (
\r
454 &VolumeInfo.FvFormat,
\r
459 if (!EFI_ERROR (Status)) {
\r
460 MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);
\r
466 return EFI_SUCCESS;
\r
470 Measure and record the Firmware Volum Information once FvInfoPPI install.
\r
472 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
\r
473 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
474 @param[in] Ppi Address of the PPI that was installed.
\r
476 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.
\r
477 @return Others Fail to measure FV.
\r
482 FirmwareVolmeInfoPpiNotifyCallback (
\r
483 IN EFI_PEI_SERVICES **PeiServices,
\r
484 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
488 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
\r
490 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
\r
493 Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;
\r
496 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.
\r
498 Status = PeiServicesLocatePpi (
\r
504 if (EFI_ERROR (Status)) {
\r
505 return EFI_SUCCESS;
\r
509 // This is an FV from an FFS file, and the parent FV must have already been measured,
\r
510 // No need to measure twice, so just record the FV and return
\r
512 if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {
\r
514 ASSERT (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported));
\r
515 if (mMeasuredChildFvIndex < PcdGet32 (PcdPeiCoreMaxFvSupported)) {
\r
517 // Check whether FV is in the measured child FV list.
\r
519 for (Index = 0; Index < mMeasuredChildFvIndex; Index++) {
\r
520 if (mMeasuredChildFvInfo[Index].BlobBase == (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo) {
\r
521 return EFI_SUCCESS;
\r
524 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobBase = (EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo;
\r
525 mMeasuredChildFvInfo[mMeasuredChildFvIndex].BlobLength = Fv->FvInfoSize;
\r
526 mMeasuredChildFvIndex++;
\r
528 return EFI_SUCCESS;
\r
531 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);
\r
535 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.
\r
536 And lock physical presence if needed.
\r
538 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
\r
539 @param[in] NotifyDescriptor Address of the notification descriptor data structure.
\r
540 @param[in] Ppi Address of the PPI that was installed.
\r
542 @retval EFI_SUCCESS Operation completed successfully.
\r
543 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.
\r
544 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
549 PhysicalPresencePpiNotifyCallback (
\r
550 IN EFI_PEI_SERVICES **PeiServices,
\r
551 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
\r
556 PEI_LOCK_PHYSICAL_PRESENCE_PPI *LockPhysicalPresencePpi;
\r
557 BOOLEAN LifetimeLock;
\r
559 TIS_TPM_HANDLE TpmHandle;
\r
560 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue;
\r
562 TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;
\r
564 Status = TpmCommGetCapability (PeiServices, TpmHandle, NULL, &LifetimeLock, &CmdEnable);
\r
565 if (EFI_ERROR (Status)) {
\r
570 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.
\r
572 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !LifetimeLock) {
\r
574 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet.
\r
576 PhysicalPresenceValue = TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK;
\r
578 if (PcdGetBool (PcdPhysicalPresenceCmdEnable)) {
\r
579 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_ENABLE;
\r
582 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_DISABLE;
\r
586 if (PcdGetBool (PcdPhysicalPresenceHwEnable)) {
\r
587 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_ENABLE;
\r
589 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_DISABLE;
\r
592 Status = TpmCommPhysicalPresence (
\r
595 PhysicalPresenceValue
\r
597 if (EFI_ERROR (Status)) {
\r
603 // 2. Lock physical presence if it is required.
\r
605 LockPhysicalPresencePpi = (PEI_LOCK_PHYSICAL_PRESENCE_PPI *) Ppi;
\r
606 if (!LockPhysicalPresencePpi->LockPhysicalPresence ((CONST EFI_PEI_SERVICES**) PeiServices)) {
\r
607 return EFI_SUCCESS;
\r
611 if (LifetimeLock) {
\r
613 // physicalPresenceCMDEnable is locked, can't change.
\r
615 return EFI_ABORTED;
\r
619 // Enable physical presence command
\r
620 // It is necessary in order to lock physical presence
\r
622 Status = TpmCommPhysicalPresence (
\r
625 TPM_PHYSICAL_PRESENCE_CMD_ENABLE
\r
627 if (EFI_ERROR (Status)) {
\r
633 // Lock physical presence
\r
635 Status = TpmCommPhysicalPresence (
\r
638 TPM_PHYSICAL_PRESENCE_LOCK
\r
644 Check if TPM chip is activeated or not.
\r
646 @param[in] PeiServices Describes the list of possible PEI Services.
\r
647 @param[in] TpmHandle TPM handle.
\r
649 @retval TRUE TPM is activated.
\r
650 @retval FALSE TPM is deactivated.
\r
656 IN EFI_PEI_SERVICES **PeiServices,
\r
657 IN TIS_TPM_HANDLE TpmHandle
\r
661 BOOLEAN Deactivated;
\r
663 Status = TpmCommGetCapability (PeiServices, TpmHandle, &Deactivated, NULL, NULL);
\r
664 if (EFI_ERROR (Status)) {
\r
667 return (BOOLEAN)(!Deactivated);
\r
671 Do measurement after memory is ready.
\r
673 @param[in] PeiServices Describes the list of possible PEI Services.
\r
675 @retval EFI_SUCCESS Operation completed successfully.
\r
676 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.
\r
677 @retval EFI_DEVICE_ERROR The command was unsuccessful.
\r
683 IN EFI_PEI_SERVICES **PeiServices
\r
687 TIS_TPM_HANDLE TpmHandle;
\r
689 Status = PeiServicesLocatePpi (
\r
690 &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid,
\r
693 (VOID**)&mMeasurementExcludedFvPpi
\r
695 // Do not check status, because it is optional
\r
697 mMeasuredBaseFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));
\r
698 ASSERT (mMeasuredBaseFvInfo != NULL);
\r
699 mMeasuredChildFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported));
\r
700 ASSERT (mMeasuredChildFvInfo != NULL);
\r
702 TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
\r
703 Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
\r
704 if (EFI_ERROR (Status)) {
\r
708 if (IsTpmUsable (PeiServices, TpmHandle)) {
\r
709 if (PcdGet8 (PcdTpmScrtmPolicy) == 1) {
\r
710 Status = MeasureCRTMVersion (PeiServices, TpmHandle);
\r
713 Status = MeasureMainBios (PeiServices, TpmHandle);
\r
718 // 1). for the FvInfoPpi services to measure and record
\r
719 // the additional Fvs to TPM
\r
720 // 2). for the OperatorPresencePpi service to determine whether to
\r
723 Status = PeiServicesNotifyPpi (&mNotifyList[0]);
\r
724 ASSERT_EFI_ERROR (Status);
\r
730 Entry point of this module.
\r
732 @param[in] FileHandle Handle of the file being invoked.
\r
733 @param[in] PeiServices Describes the list of possible PEI Services.
\r
741 IN EFI_PEI_FILE_HANDLE FileHandle,
\r
742 IN CONST EFI_PEI_SERVICES **PeiServices
\r
746 EFI_STATUS Status2;
\r
747 EFI_BOOT_MODE BootMode;
\r
748 TIS_TPM_HANDLE TpmHandle;
\r
750 if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){
\r
751 DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n"));
\r
752 return EFI_UNSUPPORTED;
\r
756 // Initialize TPM device
\r
758 Status = PeiServicesGetBootMode (&BootMode);
\r
759 ASSERT_EFI_ERROR (Status);
\r
762 // In S3 path, skip shadow logic. no measurement is required
\r
764 if (BootMode != BOOT_ON_S3_RESUME) {
\r
765 Status = (**PeiServices).RegisterForShadow(FileHandle);
\r
766 if (Status == EFI_ALREADY_STARTED) {
\r
767 mImageInMemory = TRUE;
\r
768 } else if (Status == EFI_NOT_FOUND) {
\r
769 ASSERT_EFI_ERROR (Status);
\r
773 if (!mImageInMemory) {
\r
774 TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;
\r
775 Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);
\r
776 if (EFI_ERROR (Status)) {
\r
777 DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));
\r
781 if (PcdGet8 (PcdTpmInitializationPolicy) == 1) {
\r
782 Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);
\r
783 if (EFI_ERROR (Status) ) {
\r
789 // TpmSelfTest is optional on S3 path, skip it to save S3 time
\r
791 if (BootMode != BOOT_ON_S3_RESUME) {
\r
792 Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);
\r
793 if (EFI_ERROR (Status)) {
\r
799 // Only intall TpmInitializedPpi on success
\r
801 Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);
\r
802 ASSERT_EFI_ERROR (Status);
\r
805 if (mImageInMemory) {
\r
806 Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);
\r
812 // Always intall TpmInitializationDonePpi no matter success or fail.
\r
813 // Other driver can know TPM initialization state by TpmInitializedPpi.
\r
815 Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
\r
816 ASSERT_EFI_ERROR (Status2);
\r