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