1 /** @file 2 The module entry point for TrEE configuration module. 3 4 Copyright (c) 2013, 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 #include "TrEEConfigImpl.h" 16 17 extern TPM_INSTANCE_ID mTpmInstanceId[TPM_DEVICE_MAX + 1]; 18 19 /** 20 The entry point for TrEE configuration driver. 21 22 @param[in] ImageHandle The image handle of the driver. 23 @param[in] SystemTable The system table. 24 25 @retval EFI_ALREADY_STARTED The driver already exists in system. 26 @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of resources. 27 @retval EFI_SUCCES All the related protocols are installed on the driver. 28 @retval Others Fail to install protocols as indicated. 29 30 **/ 31 EFI_STATUS 32 EFIAPI 33 TrEEConfigDriverEntryPoint ( 34 IN EFI_HANDLE ImageHandle, 35 IN EFI_SYSTEM_TABLE *SystemTable 36 ) 37 { 38 EFI_STATUS Status; 39 TREE_CONFIG_PRIVATE_DATA *PrivateData; 40 TREE_CONFIGURATION TrEEConfiguration; 41 TREE_DEVICE_DETECTION TrEEDeviceDetection; 42 UINTN Index; 43 UINTN DataSize; 44 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol; 45 46 Status = gBS->OpenProtocol ( 47 ImageHandle, 48 &gEfiCallerIdGuid, 49 NULL, 50 ImageHandle, 51 ImageHandle, 52 EFI_OPEN_PROTOCOL_TEST_PROTOCOL 53 ); 54 if (!EFI_ERROR (Status)) { 55 return EFI_ALREADY_STARTED; 56 } 57 58 // 59 // Create a private data structure. 60 // 61 PrivateData = AllocateCopyPool (sizeof (TREE_CONFIG_PRIVATE_DATA), &mTrEEConfigPrivateDateTemplate); 62 ASSERT (PrivateData != NULL); 63 64 // 65 // Install private GUID. 66 // 67 Status = gBS->InstallMultipleProtocolInterfaces ( 68 &ImageHandle, 69 &gEfiCallerIdGuid, 70 PrivateData, 71 NULL 72 ); 73 ASSERT_EFI_ERROR (Status); 74 75 DataSize = sizeof(TrEEConfiguration); 76 Status = gRT->GetVariable ( 77 TREE_STORAGE_NAME, 78 &gTrEEConfigFormSetGuid, 79 NULL, 80 &DataSize, 81 &TrEEConfiguration 82 ); 83 if (EFI_ERROR (Status)) { 84 // 85 // Variable not ready, set default value 86 // 87 TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT; 88 } 89 90 // 91 // Validation 92 // 93 if ((TrEEConfiguration.TpmDevice > TPM_DEVICE_MAX) || (TrEEConfiguration.TpmDevice < TPM_DEVICE_MIN)) { 94 TrEEConfiguration.TpmDevice = TPM_DEVICE_DEFAULT; 95 } 96 97 // 98 // Save to variable so platform driver can get it. 99 // 100 Status = gRT->SetVariable ( 101 TREE_STORAGE_NAME, 102 &gTrEEConfigFormSetGuid, 103 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 104 sizeof(TrEEConfiguration), 105 &TrEEConfiguration 106 ); 107 if (EFI_ERROR (Status)) { 108 DEBUG ((EFI_D_ERROR, "TrEEConfigDriver: Fail to set TREE_STORAGE_NAME\n")); 109 } 110 111 // 112 // Sync data from PCD to variable, so that we do not need detect again in S3 phase. 113 // 114 TrEEDeviceDetection.TpmDeviceDetected = TPM_DEVICE_NULL; 115 for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) { 116 if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &mTpmInstanceId[Index].TpmInstanceGuid)) { 117 TrEEDeviceDetection.TpmDeviceDetected = mTpmInstanceId[Index].TpmDevice; 118 break; 119 } 120 } 121 122 PrivateData->TpmDeviceDetected = TrEEDeviceDetection.TpmDeviceDetected; 123 124 // 125 // Save to variable so platform driver can get it. 126 // 127 Status = gRT->SetVariable ( 128 TREE_DEVICE_DETECTION_NAME, 129 &gTrEEConfigFormSetGuid, 130 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 131 sizeof(TrEEDeviceDetection), 132 &TrEEDeviceDetection 133 ); 134 if (EFI_ERROR (Status)) { 135 DEBUG ((EFI_D_ERROR, "TrEEConfigDriver: Fail to set TREE_DEVICE_DETECTION_NAME\n")); 136 Status = gRT->SetVariable ( 137 TREE_DEVICE_DETECTION_NAME, 138 &gTrEEConfigFormSetGuid, 139 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, 140 0, 141 NULL 142 ); 143 ASSERT_EFI_ERROR (Status); 144 } 145 146 // 147 // We should lock TrEEDeviceDetection, because it contains information needed at S3. 148 // 149 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol); 150 if (!EFI_ERROR (Status)) { 151 Status = VariableLockProtocol->RequestToLock ( 152 VariableLockProtocol, 153 TREE_DEVICE_DETECTION_NAME, 154 &gTrEEConfigFormSetGuid 155 ); 156 ASSERT_EFI_ERROR (Status); 157 } 158 159 // 160 // Install TrEE configuration form 161 // 162 Status = InstallTrEEConfigForm (PrivateData); 163 if (EFI_ERROR (Status)) { 164 goto ErrorExit; 165 } 166 167 return EFI_SUCCESS; 168 169 ErrorExit: 170 if (PrivateData != NULL) { 171 UninstallTrEEConfigForm (PrivateData); 172 } 173 174 return Status; 175 } 176 177 /** 178 Unload the TrEE configuration form. 179 180 @param[in] ImageHandle The driver's image handle. 181 182 @retval EFI_SUCCESS The TrEE configuration form is unloaded. 183 @retval Others Failed to unload the form. 184 185 **/ 186 EFI_STATUS 187 EFIAPI 188 TrEEConfigDriverUnload ( 189 IN EFI_HANDLE ImageHandle 190 ) 191 { 192 EFI_STATUS Status; 193 TREE_CONFIG_PRIVATE_DATA *PrivateData; 194 195 Status = gBS->HandleProtocol ( 196 ImageHandle, 197 &gEfiCallerIdGuid, 198 (VOID **) &PrivateData 199 ); 200 if (EFI_ERROR (Status)) { 201 return Status; 202 } 203 204 ASSERT (PrivateData->Signature == TREE_CONFIG_PRIVATE_DATA_SIGNATURE); 205 206 gBS->UninstallMultipleProtocolInterfaces ( 207 &ImageHandle, 208 &gEfiCallerIdGuid, 209 PrivateData, 210 NULL 211 ); 212 213 UninstallTrEEConfigForm (PrivateData); 214 215 return EFI_SUCCESS; 216 } 217