/** 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; }