/** Do measurement after memory is ready. @param[in] PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI PeimEntryMP ( IN EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; Status = PeiServicesLocatePpi ( &gEfiPeiFirmwareVolumeInfoMeasurementExcludedPpiGuid, 0, NULL, (VOID**)&mMeasurementExcludedFvPpi ); // Do not check status, because it is optional mMeasuredBaseFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported)); ASSERT (mMeasuredBaseFvInfo != NULL); mMeasuredChildFvInfo = (EFI_PLATFORM_FIRMWARE_BLOB *) AllocateZeroPool (sizeof (EFI_PLATFORM_FIRMWARE_BLOB) * PcdGet32 (PcdPeiCoreMaxFvSupported)); ASSERT (mMeasuredChildFvInfo != NULL); Status = Tpm12RequestUseTpm (); if (EFI_ERROR (Status)) { return Status; } if (IsTpmUsable ()) { if (PcdGet8 (PcdTpmScrtmPolicy) == 1) { Status = MeasureCRTMVersion (PeiServices); } Status = MeasureMainBios (PeiServices); } // // Post callbacks: // 1). for the FvInfoPpi services to measure and record // the additional Fvs to TPM // 2). for the OperatorPresencePpi service to determine whether to // lock the TPM // Status = PeiServicesNotifyPpi (&mNotifyList[0]); ASSERT_EFI_ERROR (Status); return Status; }
/** The driver's entry point. It publishes EFI TCG Protocol. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI DriverEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_EVENT Event; VOID *Registration; if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n")); return EFI_UNSUPPORTED; } if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { DEBUG ((EFI_D_ERROR, "TPM error!\n")); return EFI_DEVICE_ERROR; } Status = Tpm12RequestUseTpm (); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TPM not detected!\n")); return Status; } Status = GetTpmStatus (&mTcgDxeData.BsCap.TPMDeactivatedFlag); if (EFI_ERROR (Status)) { DEBUG (( EFI_D_ERROR, "Line %d in file " __FILE__ ":\n " "DriverEntry: TPM not working properly\n", __LINE__ )); return Status; } Status = gBS->InstallProtocolInterface ( &ImageHandle, &gEfiTcgProtocolGuid, EFI_NATIVE_INTERFACE, &mTcgDxeData.TcgProtocol ); if (!EFI_ERROR (Status) && (!mTcgDxeData.BsCap.TPMDeactivatedFlag) && mTcgDxeData.BsCap.TPMPresentFlag) { // // Setup the log area and copy event log from hob list to it // Status = SetupEventLog (); ASSERT_EFI_ERROR (Status); // // Measure handoff tables, Boot#### variables etc. // Status = EfiCreateEventReadyToBootEx ( TPL_CALLBACK, OnReadyToBoot, NULL, &Event ); Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, OnExitBootServices, NULL, &gEfiEventExitBootServicesGuid, &Event ); // // Measure Exit Boot Service failed // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, OnExitBootServicesFailed, NULL, &gEventExitBootServicesFailedGuid, &Event ); } // // Install ACPI Table // EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration); return Status; }
/** Entry point of this module. @param[in] FileHandle Handle of the file being invoked. @param[in] PeiServices Describes the list of possible PEI Services. @return Status. **/ EFI_STATUS EFIAPI PeimEntryMA ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_STATUS Status2; EFI_BOOT_MODE BootMode; if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n")); return EFI_UNSUPPORTED; } if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { DEBUG ((EFI_D_ERROR, "TPM error!\n")); return EFI_DEVICE_ERROR; } // // Initialize TPM device // Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); // // In S3 path, skip shadow logic. no measurement is required // if (BootMode != BOOT_ON_S3_RESUME) { Status = (**PeiServices).RegisterForShadow(FileHandle); if (Status == EFI_ALREADY_STARTED) { mImageInMemory = TRUE; } else if (Status == EFI_NOT_FOUND) { ASSERT_EFI_ERROR (Status); } } if (!mImageInMemory) { Status = Tpm12RequestUseTpm (); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "TPM not detected!\n")); goto Done; } if (PcdGet8 (PcdTpmInitializationPolicy) == 1) { if (BootMode == BOOT_ON_S3_RESUME) { Status = Tpm12Startup (TPM_ST_STATE); } else { Status = Tpm12Startup (TPM_ST_CLEAR); } if (EFI_ERROR (Status) ) { goto Done; } } // // TpmSelfTest is optional on S3 path, skip it to save S3 time // if (BootMode != BOOT_ON_S3_RESUME) { Status = Tpm12ContinueSelfTest (); if (EFI_ERROR (Status)) { goto Done; } } // // Only intall TpmInitializedPpi on success // Status = PeiServicesInstallPpi (&mTpmInitializedPpiList); ASSERT_EFI_ERROR (Status); } if (mImageInMemory) { Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices); return Status; } Done: if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TPM error! Build Hob\n")); BuildGuidHob (&gTpmErrorHobGuid,0); REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) ); } // // Always intall TpmInitializationDonePpi no matter success or fail. // Other driver can know TPM initialization state by TpmInitializedPpi. // Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList); ASSERT_EFI_ERROR (Status2); return Status; }
/** This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration. @param SetupTpmDevice TpmDevice configuration in setup driver @return TpmDevice configuration **/ UINT8 DetectTpmDevice ( IN UINT8 SetupTpmDevice ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; TCG2_DEVICE_DETECTION Tcg2DeviceDetection; EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; UINTN Size; Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); // // In S3, we rely on normal boot Detection, because we save to ReadOnly Variable in normal boot. // if (BootMode == BOOT_ON_S3_RESUME) { DEBUG ((EFI_D_INFO, "DetectTpmDevice: S3 mode\n")); Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi); ASSERT_EFI_ERROR (Status); Size = sizeof(TCG2_DEVICE_DETECTION); ZeroMem (&Tcg2DeviceDetection, sizeof(Tcg2DeviceDetection)); Status = VariablePpi->GetVariable ( VariablePpi, TCG2_DEVICE_DETECTION_NAME, &gTcg2ConfigFormSetGuid, NULL, &Size, &Tcg2DeviceDetection ); if (!EFI_ERROR (Status) && (Tcg2DeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) && (Tcg2DeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX)) { DEBUG ((EFI_D_ERROR, "TpmDevice from DeviceDetection: %x\n", Tcg2DeviceDetection.TpmDeviceDetected)); return Tcg2DeviceDetection.TpmDeviceDetected; } } DEBUG ((EFI_D_INFO, "DetectTpmDevice:\n")); // dTPM available and not disabled by setup // We need check if it is TPM1.2 or TPM2.0 // So try TPM1.2 command at first Status = Tpm12RequestUseTpm (); if (EFI_ERROR (Status)) { // // dTPM not available // return TPM_DEVICE_NULL; } if (BootMode == BOOT_ON_S3_RESUME) { Status = Tpm12Startup (TPM_ST_STATE); } else { Status = Tpm12Startup (TPM_ST_CLEAR); } if (EFI_ERROR (Status)) { return TPM_DEVICE_2_0_DTPM; } // NO initialization needed again. Status = PcdSet8S (PcdTpmInitializationPolicy, 0); ASSERT_EFI_ERROR (Status); return TPM_DEVICE_1_2; }