Home | History | Annotate | Download | only in TrEEConfig
      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