diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/UefiCpuPkg/SecCore/SecBist.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/UefiCpuPkg/SecCore/SecBist.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/SecCore/SecBist.c b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/SecCore/SecBist.c new file mode 100644 index 00000000..ce85b565 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/UefiCpuPkg/SecCore/SecBist.c @@ -0,0 +1,264 @@ +/** @file + Get SEC platform information(2) PPI and reinstall it. + + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> + 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); +} |