| /** @file | |
| The module entry point for Tcg2 configuration module. | |
| Copyright (c) 2015, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include <PiPei.h> | |
| #include <Guid/TpmInstance.h> | |
| #include <Library/BaseLib.h> | |
| #include <Library/BaseMemoryLib.h> | |
| #include <Library/DebugLib.h> | |
| #include <Library/MemoryAllocationLib.h> | |
| #include <Library/PeiServicesLib.h> | |
| #include <Library/PcdLib.h> | |
| #include <Ppi/ReadOnlyVariable2.h> | |
| #include <Ppi/TpmInitialized.h> | |
| #include <Protocol/Tcg2Protocol.h> | |
| #include "Tcg2ConfigNvData.h" | |
| TPM_INSTANCE_ID mTpmInstanceId[] = TPM_INSTANCE_ID_LIST; | |
| CONST EFI_PEI_PPI_DESCRIPTOR gTpmSelectedPpi = { | |
| (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), | |
| &gEfiTpmDeviceSelectedGuid, | |
| NULL | |
| }; | |
| EFI_PEI_PPI_DESCRIPTOR mTpmInitializationDonePpiList = { | |
| EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, | |
| &gPeiTpmInitializationDonePpiGuid, | |
| NULL | |
| }; | |
| /** | |
| This routine check both SetupVariable and real TPM device, and return final TpmDevice configuration. | |
| @param SetupTpmDevice TpmDevice configuration in setup driver | |
| @return TpmDevice configuration | |
| **/ | |
| UINT8 | |
| DetectTpmDevice ( | |
| IN UINT8 SetupTpmDevice | |
| ); | |
| /** | |
| The entry point for Tcg2 configuration driver. | |
| @param FileHandle Handle of the file being invoked. | |
| @param PeiServices Describes the list of possible PEI Services. | |
| @retval EFI_SUCCES Convert variable to PCD successfully. | |
| @retval Others Fail to convert variable to PCD. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| Tcg2ConfigPeimEntryPoint ( | |
| IN EFI_PEI_FILE_HANDLE FileHandle, | |
| IN CONST EFI_PEI_SERVICES **PeiServices | |
| ) | |
| { | |
| UINTN Size; | |
| EFI_STATUS Status; | |
| EFI_STATUS Status2; | |
| EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariablePpi; | |
| TCG2_CONFIGURATION Tcg2Configuration; | |
| UINTN Index; | |
| UINT8 TpmDevice; | |
| Status = PeiServicesLocatePpi (&gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **) &VariablePpi); | |
| ASSERT_EFI_ERROR (Status); | |
| Size = sizeof(Tcg2Configuration); | |
| Status = VariablePpi->GetVariable ( | |
| VariablePpi, | |
| TCG2_STORAGE_NAME, | |
| &gTcg2ConfigFormSetGuid, | |
| NULL, | |
| &Size, | |
| &Tcg2Configuration | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| // | |
| // Variable not ready, set default value | |
| // | |
| Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT; | |
| } | |
| // | |
| // Validation | |
| // | |
| if ((Tcg2Configuration.TpmDevice > TPM_DEVICE_MAX) || (Tcg2Configuration.TpmDevice < TPM_DEVICE_MIN)) { | |
| Tcg2Configuration.TpmDevice = TPM_DEVICE_DEFAULT; | |
| } | |
| // | |
| // Although we have SetupVariable info, we still need detect TPM device manually. | |
| // | |
| DEBUG ((EFI_D_INFO, "Tcg2Configuration.TpmDevice from Setup: %x\n", Tcg2Configuration.TpmDevice)); | |
| if (PcdGetBool (PcdTpmAutoDetection)) { | |
| TpmDevice = DetectTpmDevice (Tcg2Configuration.TpmDevice); | |
| DEBUG ((EFI_D_INFO, "TpmDevice final: %x\n", TpmDevice)); | |
| if (TpmDevice != TPM_DEVICE_NULL) { | |
| Tcg2Configuration.TpmDevice = TpmDevice; | |
| } | |
| } else { | |
| TpmDevice = Tcg2Configuration.TpmDevice; | |
| } | |
| // | |
| // Convert variable to PCD. | |
| // This is work-around because there is no gurantee DynamicHiiPcd can return correct value in DXE phase. | |
| // Using DynamicPcd instead. | |
| // | |
| // NOTE: Tcg2Configuration variable contains the desired TpmDevice type, | |
| // while PcdTpmInstanceGuid PCD contains the real detected TpmDevice type | |
| // | |
| for (Index = 0; Index < sizeof(mTpmInstanceId)/sizeof(mTpmInstanceId[0]); Index++) { | |
| if (TpmDevice == mTpmInstanceId[Index].TpmDevice) { | |
| Size = sizeof(mTpmInstanceId[Index].TpmInstanceGuid); | |
| Status = PcdSetPtrS (PcdTpmInstanceGuid, &Size, &mTpmInstanceId[Index].TpmInstanceGuid); | |
| ASSERT_EFI_ERROR (Status); | |
| DEBUG ((EFI_D_INFO, "TpmDevice PCD: %g\n", &mTpmInstanceId[Index].TpmInstanceGuid)); | |
| break; | |
| } | |
| } | |
| // | |
| // Selection done | |
| // | |
| Status = PeiServicesInstallPpi (&gTpmSelectedPpi); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Even if no TPM is selected or detected, we still need intall TpmInitializationDonePpi. | |
| // Because TcgPei or Tcg2Pei will not run, but we still need a way to notify other driver. | |
| // Other driver can know TPM initialization state by TpmInitializedPpi. | |
| // | |
| if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid)) { | |
| Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList); | |
| ASSERT_EFI_ERROR (Status2); | |
| } | |
| return Status; | |
| } |