/** @file Get SEC platform information(2) PPI and reinstall it. Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "SecMain.h" EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformation = { SecPlatformInformationBist }; EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation = { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiSecPlatformInformationPpiGuid, &mSecPlatformInformation }; EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2 = { SecPlatformInformation2Bist }; EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2 = { (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), &gEfiSecPlatformInformation2PpiGuid, &mSecPlatformInformation2 }; /** Worker function to parse CPU BIST information from Guided HOB. @param[in, out] StructureSize Pointer to the variable describing size of the input buffer. @param[in, out] StructureBuffer Pointer to the buffer save CPU BIST information. @retval EFI_SUCCESS The data was successfully returned. @retval EFI_BUFFER_TOO_SMALL The buffer was too small. **/ EFI_STATUS GetBistFromHob ( IN OUT UINT64 *StructureSize, IN OUT VOID *StructureBuffer ) { EFI_HOB_GUID_TYPE *GuidHob; VOID *DataInHob; UINTN DataSize; GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); if (GuidHob == NULL) { *StructureSize = 0; return EFI_SUCCESS; } DataInHob = GET_GUID_HOB_DATA (GuidHob); DataSize = GET_GUID_HOB_DATA_SIZE (GuidHob); // // return the information from BistHob // if ((*StructureSize) < (UINT64)DataSize) { *StructureSize = (UINT64)DataSize; return EFI_BUFFER_TOO_SMALL; } *StructureSize = (UINT64)DataSize; CopyMem (StructureBuffer, DataInHob, DataSize); return EFI_SUCCESS; } /** Implementation of the PlatformInformation service in EFI_SEC_PLATFORM_INFORMATION_PPI. @param[in] PeiServices Pointer to the PEI Services Table. @param[in, out] StructureSize Pointer to the variable describing size of the input buffer. @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. @retval EFI_SUCCESS The data was successfully returned. @retval EFI_BUFFER_TOO_SMALL The buffer was too small. **/ EFI_STATUS EFIAPI SecPlatformInformationBist ( IN CONST EFI_PEI_SERVICES **PeiServices, IN OUT UINT64 *StructureSize, OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord ) { return GetBistFromHob (StructureSize, PlatformInformationRecord); } /** Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI. @param[in] PeiServices The pointer to the PEI Services Table. @param[in, out] StructureSize The pointer to the variable describing size of the input buffer. @param[out] PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2. @retval EFI_SUCCESS The data was successfully returned. @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to hold the record is returned in StructureSize. **/ EFI_STATUS EFIAPI SecPlatformInformation2Bist ( IN CONST EFI_PEI_SERVICES **PeiServices, IN OUT UINT64 *StructureSize, OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2 ) { return GetBistFromHob (StructureSize, PlatformInformationRecord2); } /** Worker function to get CPUs' BIST by calling SecPlatformInformationPpi or SecPlatformInformation2Ppi. @param[in] PeiServices Pointer to PEI Services Table @param[in] Guid PPI Guid @param[out] PpiDescriptor Return a pointer to instance of the EFI_PEI_PPI_DESCRIPTOR @param[out] BistInformationData Pointer to BIST information data @param[out] BistInformationSize Return the size in bytes of BIST information @retval EFI_SUCCESS Retrieve of the BIST data successfully @retval EFI_NOT_FOUND No sec platform information(2) ppi export @retval EFI_DEVICE_ERROR Failed to get CPU Information **/ EFI_STATUS GetBistInfoFromPpi ( IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_GUID *Guid, OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, OUT VOID **BistInformationData, OUT UINT64 *BistInformationSize OPTIONAL ) { EFI_STATUS Status; EFI_SEC_PLATFORM_INFORMATION2_PPI *SecPlatformInformation2Ppi; EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2; UINT64 InformationSize; Status = PeiServicesLocatePpi ( Guid, // GUID 0, // INSTANCE PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR (VOID **)&SecPlatformInformation2Ppi // PPI ); if (Status == EFI_NOT_FOUND) { return EFI_NOT_FOUND; } if (Status == EFI_SUCCESS) { // // Get the size of the sec platform information2(BSP/APs' BIST data) // InformationSize = 0; SecPlatformInformation2 = NULL; Status = SecPlatformInformation2Ppi->PlatformInformation2 ( PeiServices, &InformationSize, SecPlatformInformation2 ); if (Status == EFI_BUFFER_TOO_SMALL) { Status = PeiServicesAllocatePool ( (UINTN)InformationSize, (VOID **)&SecPlatformInformation2 ); if (Status == EFI_SUCCESS) { // // Retrieve BIST data // Status = SecPlatformInformation2Ppi->PlatformInformation2 ( PeiServices, &InformationSize, SecPlatformInformation2 ); if (Status == EFI_SUCCESS) { *BistInformationData = SecPlatformInformation2; if (BistInformationSize != NULL) { *BistInformationSize = InformationSize; } return EFI_SUCCESS; } } } } return EFI_DEVICE_ERROR; } /** Get CPUs' BIST by calling SecPlatformInformationPpi/SecPlatformInformation2Ppi. **/ VOID RepublishSecPlatformInformationPpi ( VOID ) { EFI_STATUS Status; CONST EFI_PEI_SERVICES **PeiServices; UINT64 BistInformationSize; VOID *BistInformationData; EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor; PeiServices = GetPeiServicesTablePointer (); Status = GetBistInfoFromPpi ( PeiServices, &gEfiSecPlatformInformation2PpiGuid, &SecInformationDescriptor, &BistInformationData, &BistInformationSize ); if (Status == EFI_SUCCESS) { BuildGuidDataHob ( &gEfiCallerIdGuid, BistInformationData, (UINTN)BistInformationSize ); // // The old SecPlatformInformation2 data is on temporary memory. // After memory discovered, we should never get it from temporary memory, // or the data will be crashed. So, we reinstall SecPlatformInformation2 PPI here. // Status = PeiServicesReInstallPpi ( SecInformationDescriptor, &mPeiSecPlatformInformation2 ); } if (Status == EFI_NOT_FOUND) { Status = GetBistInfoFromPpi ( PeiServices, &gEfiSecPlatformInformationPpiGuid, &SecInformationDescriptor, &BistInformationData, &BistInformationSize ); if (Status == EFI_SUCCESS) { BuildGuidDataHob ( &gEfiCallerIdGuid, BistInformationData, (UINTN)BistInformationSize ); // // The old SecPlatformInformation data is on temporary memory. // After memory discovered, we should never get it from temporary memory, // or the data will be crashed. So, we reinstall SecPlatformInformation PPI here. // Status = PeiServicesReInstallPpi ( SecInformationDescriptor, &mPeiSecPlatformInformation ); } else if (Status == EFI_NOT_FOUND) { return; } } ASSERT_EFI_ERROR (Status); }