• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
IsDtpmPresent(VOID)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
DetectTpmDevice(IN UINT8 SetupTpmDevice)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