1 /** @file 2 TPM1.2/dTPM2.0 auto detection. 3 4 Copyright (c) 2013 - 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 9 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. 12 13 **/ 14 15 16 #include <PiPei.h> 17 #include <Ppi/ReadOnlyVariable2.h> 18 19 #include <Library/BaseLib.h> 20 #include <Library/BaseMemoryLib.h> 21 #include <Library/IoLib.h> 22 #include <Library/DebugLib.h> 23 #include <Library/PeiServicesLib.h> 24 #include <Library/PcdLib.h> 25 #include <Library/Tpm12DeviceLib.h> 26 #include <Library/Tpm12CommandLib.h> 27 #include <IndustryStandard/Tpm12.h> 28 29 #include "TrEEConfigNvData.h" 30 31 /** 32 This routine return if dTPM (1.2 or 2.0) present. 33 34 @retval TRUE dTPM present 35 @retval FALSE dTPM not present 36 **/ 37 BOOLEAN 38 IsDtpmPresent ( 39 VOID 40 ) 41 { 42 UINT8 RegRead; 43 44 RegRead = MmioRead8 ((UINTN)PcdGet64 (PcdTpmBaseAddress)); 45 if (RegRead == 0xFF) { 46 DEBUG ((EFI_D_ERROR, "DetectTpmDevice: Dtpm not present\n")); 47 return FALSE; 48 } else { 49 DEBUG ((EFI_D_INFO, "DetectTpmDevice: Dtpm present\n")); 50 return TRUE; 51 } 52 } 53 54 /** 55 This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration. 56 57 @param SetupTpmDevice TpmDevice configuration in setup driver 58 59 @return TpmDevice configuration 60 **/ 61 UINT8 62 DetectTpmDevice ( 63 IN UINT8 SetupTpmDevice 64 ) 65 { 66 EFI_STATUS Status; 67 EFI_BOOT_MODE BootMode; 68 TREE_DEVICE_DETECTION TrEEDeviceDetection; 69 EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; 70 UINTN Size; 71 72 Status = PeiServicesGetBootMode (&BootMode); 73 ASSERT_EFI_ERROR (Status); 74 75 // 76 // In S3, we rely on normal boot Detection, because we save to ReadOnly Variable in normal boot. 77 // 78 if (BootMode == BOOT_ON_S3_RESUME) { 79 DEBUG ((EFI_D_INFO, "DetectTpmDevice: S3 mode\n")); 80 81 Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi); 82 ASSERT_EFI_ERROR (Status); 83 84 Size = sizeof(TREE_DEVICE_DETECTION); 85 ZeroMem (&TrEEDeviceDetection, sizeof(TrEEDeviceDetection)); 86 Status = VariablePpi->GetVariable ( 87 VariablePpi, 88 TREE_DEVICE_DETECTION_NAME, 89 &gTrEEConfigFormSetGuid, 90 NULL, 91 &Size, 92 &TrEEDeviceDetection 93 ); 94 if (!EFI_ERROR (Status) && 95 (TrEEDeviceDetection.TpmDeviceDetected >= TPM_DEVICE_MIN) && 96 (TrEEDeviceDetection.TpmDeviceDetected <= TPM_DEVICE_MAX)) { 97 DEBUG ((EFI_D_ERROR, "TpmDevice from DeviceDetection: %x\n", TrEEDeviceDetection.TpmDeviceDetected)); 98 return TrEEDeviceDetection.TpmDeviceDetected; 99 } 100 } 101 102 DEBUG ((EFI_D_INFO, "DetectTpmDevice:\n")); 103 if (!IsDtpmPresent ()) { 104 // dTPM not available 105 return TPM_DEVICE_NULL; 106 } 107 108 // dTPM available and not disabled by setup 109 // We need check if it is TPM1.2 or TPM2.0 110 // So try TPM1.2 command at first 111 112 Status = Tpm12RequestUseTpm (); 113 if (EFI_ERROR (Status)) { 114 return TPM_DEVICE_2_0_DTPM; 115 } 116 117 if (BootMode == BOOT_ON_S3_RESUME) { 118 Status = Tpm12Startup (TPM_ST_STATE); 119 } else { 120 Status = Tpm12Startup (TPM_ST_CLEAR); 121 } 122 if (EFI_ERROR (Status)) { 123 return TPM_DEVICE_2_0_DTPM; 124 } 125 126 // NO initialization needed again. 127 Status = PcdSet8S (PcdTpmInitializationPolicy, 0); 128 ASSERT_EFI_ERROR (Status); 129 return TPM_DEVICE_1_2; 130 } 131