/** @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); | |
} |