1 /** @file
2 The module entry point for Tcg2 configuration module.
3
4 Copyright (c) 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
18 #include <Guid/TpmInstance.h>
19
20 #include <Library/BaseLib.h>
21 #include <Library/BaseMemoryLib.h>
22 #include <Library/DebugLib.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/PeiServicesLib.h>
25 #include <Library/PcdLib.h>
26
27 #include <Ppi/ReadOnlyVariable2.h>
28 #include <Ppi/TpmInitialized.h>
29 #include <Protocol/Tcg2Protocol.h>
30
31 #include "Tcg2ConfigNvData.h"
32
33 TPM_INSTANCE_ID mTpmInstanceId[] = TPM_INSTANCE_ID_LIST;
34
35 CONST EFI_PEI_PPI_DESCRIPTOR gTpmSelectedPpi = {
36 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
37 &gEfiTpmDeviceSelectedGuid,
38 NULL
39 };
40
41 EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = {
42 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
43 &gPeiTpmInitializationDonePpiGuid,
44 NULL
45 };
46
47 /**
48 This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration.
49
50 @param SetupTpmDevice TpmDevice configuration in setup driver
51
52 @return TpmDevice configuration
53 **/
54 UINT8
55 DetectTpmDevice (
56 IN UINT8 SetupTpmDevice
57 );
58
59 /**
60 The entry point for Tcg2 configuration driver.
61
62 @param FileHandle Handle of the file being invoked.
63 @param PeiServices Describes the list of possible PEI Services.
64
65 @retval EFI_SUCCES Convert variable to PCD successfully.
66 @retval Others Fail to convert variable to PCD.
67 **/
68 EFI_STATUS
69 EFIAPI
Tcg2ConfigPeimEntryPoint(IN EFI_PEI_FILE_HANDLE FileHandle,IN CONST EFI_PEI_SERVICES ** PeiServices)70 Tcg2ConfigPeimEntryPoint (
71 IN EFI_PEI_FILE_HANDLE FileHandle,
72 IN CONST EFI_PEI_SERVICES **PeiServices
73 )
74 {
75 UINTN Size;
76 EFI_STATUS Status;
77 EFI_STATUS Status2;
78 EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi;
79 TCG2_CONFIGURATION Tcg2Configuration;
80 UINTN Index;
81 UINT8 TpmDevice;
82
83 Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi);
84 ASSERT_EFI_ERROR (Status);
85
86 Size = sizeof(Tcg2Configuration);
87 Status = VariablePpi->GetVariable (
88 VariablePpi,
89 TCG2_STORAGE_NAME,
90 &gTcg2ConfigFormSetGuid,
91 NULL,
92 &Size,
93 &Tcg2Configuration
94 );
95 if (EFI_ERROR (Status)) {
96 //
97 // Variable not ready, set default value
98 //
99 Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;
100 }
101
102 //
103 // Validation
104 //
105 if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) {
106 Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT;
107 }
108
109 //
110 // Although we have SetupVariable info, we still need detect TPM device manually.
111 //
112 DEBUG ((EFI_D_INFO, "Tcg2Configuration.TpmDevice from Setup: %x\n", Tcg2Configuration.TpmDevice));
113
114 if (PcdGetBool (PcdTpmAutoDetection)) {
115 TpmDevice = DetectTpmDevice (Tcg2Configuration.TpmDevice);
116 DEBUG ((EFI_D_INFO, "TpmDevice final: %x\n", TpmDevice));
117 if (TpmDevice != TPM_DEVICE_NULL) {
118 Tcg2Configuration.TpmDevice = TpmDevice;
119 }
120 } else {
121 TpmDevice = Tcg2Configuration.TpmDevice;
122 }
123
124 //
125 // Convert variable to PCD.
126 // This is work-around because there is no gurantee DynamicHiiPcd can return correct value in DXE phase.
127 // Using DynamicPcd instead.
128 //
129 // NOTE: Tcg2Configuration variable contains the desired TpmDevice type,
130 // while PcdTpmInstanceGuid PCD contains the real detected TpmDevice type
131 //
132 for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) {
133 if (TpmDevice == mTpmInstanceId[Index].TpmDevice) {
134 Size = sizeof(mTpmInstanceId[Index].TpmInstanceGuid);
135 Status = PcdSetPtrS (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[Index].TpmInstanceGuid);
136 ASSERT_EFI_ERROR (Status);
137 DEBUG ((EFI_D_INFO, "TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid));
138 break;
139 }
140 }
141
142 //
143 // Selection done
144 //
145 Status = PeiServicesInstallPpi (&gTpmSelectedPpi);
146 ASSERT_EFI_ERROR (Status);
147
148 //
149 // Even if no TPM is selected or detected, we still need intall TpmInitializationDonePpi.
150 // Because TcgPei or Tcg2Pei will not run, but we still need a way to notify other driver.
151 // Other driver can know TPM initialization state by TpmInitializedPpi.
152 //
153 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid)) {
154 Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList);
155 ASSERT_EFI_ERROR (Status2);
156 }
157
158 return Status;
159 }
160