CloverBootloader/UefiCpuPkg/SecCore/SecBist.c

265 lines
9.0 KiB
C

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