123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- /** @file
- Update and publish processors' BIST information.
- Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "CpuMpPei.h"
- EFI_SEC_PLATFORM_INFORMATION2_PPI mSecPlatformInformation2Ppi = {
- SecPlatformInformation2
- };
- EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformInformation2Ppi = {
- (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
- &gEfiSecPlatformInformation2PpiGuid,
- &mSecPlatformInformation2Ppi
- };
- /**
- Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI.
- @param PeiServices The pointer to the PEI Services Table.
- @param StructureSize The pointer to the variable describing size of the input buffer.
- @param 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
- SecPlatformInformation2 (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN OUT UINT64 *StructureSize,
- OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2
- )
- {
- EFI_HOB_GUID_TYPE *GuidHob;
- VOID *DataInHob;
- UINTN DataSize;
- GuidHob = GetFirstGuidHob (&gEfiSecPlatformInformation2PpiGuid);
- 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 (PlatformInformationRecord2, DataInHob, DataSize);
- return EFI_SUCCESS;
- }
- /**
- Worker function to get CPUs' BIST by calling SecPlatformInformationPpi
- or SecPlatformInformation2Ppi.
- @param PeiServices Pointer to PEI Services Table
- @param Guid PPI Guid
- @param PpiDescriptor Return a pointer to instance of the
- EFI_PEI_PPI_DESCRIPTOR
- @param BistInformationData Pointer to BIST information data
- @param 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;
- }
- /**
- Collects BIST data from PPI.
- This function collects BIST data from Sec Platform Information2 PPI
- or SEC Platform Information PPI.
- @param PeiServices Pointer to PEI Services Table
- **/
- VOID
- CollectBistDataFromPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
- {
- EFI_STATUS Status;
- EFI_PEI_PPI_DESCRIPTOR *SecInformationDescriptor;
- EFI_SEC_PLATFORM_INFORMATION_RECORD2 *SecPlatformInformation2;
- EFI_SEC_PLATFORM_INFORMATION_RECORD *SecPlatformInformation;
- UINTN NumberOfData;
- EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance;
- EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance;
- UINTN ProcessorNumber;
- UINTN CpuIndex;
- EFI_PROCESSOR_INFORMATION ProcessorInfo;
- EFI_HEALTH_FLAGS BistData;
- UINTN NumberOfProcessors;
- UINTN NumberOfEnabledProcessors;
- UINTN BistInformationSize;
- EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2;
- EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstanceInHob;
- MpInitLibGetNumberOfProcessors (&NumberOfProcessors, &NumberOfEnabledProcessors);
- BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) +
- sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * NumberOfProcessors;
- Status = PeiServicesAllocatePool (
- (UINTN)BistInformationSize,
- (VOID **)&PlatformInformationRecord2
- );
- ASSERT_EFI_ERROR (Status);
- PlatformInformationRecord2->NumberOfCpus = (UINT32)NumberOfProcessors;
- SecPlatformInformation2 = NULL;
- SecPlatformInformation = NULL;
- NumberOfData = 0;
- CpuInstance = NULL;
- //
- // Get BIST information from Sec Platform Information2 Ppi firstly
- //
- Status = GetBistInfoFromPpi (
- PeiServices,
- &gEfiSecPlatformInformation2PpiGuid,
- &SecInformationDescriptor,
- (VOID *)&SecPlatformInformation2,
- NULL
- );
- if (Status == EFI_SUCCESS) {
- //
- // Sec Platform Information2 PPI includes BSP/APs' BIST information
- //
- NumberOfData = SecPlatformInformation2->NumberOfCpus;
- CpuInstance = SecPlatformInformation2->CpuInstance;
- } else {
- //
- // Otherwise, get BIST information from Sec Platform Information Ppi
- //
- Status = GetBistInfoFromPpi (
- PeiServices,
- &gEfiSecPlatformInformationPpiGuid,
- &SecInformationDescriptor,
- (VOID *)&SecPlatformInformation,
- NULL
- );
- if (Status == EFI_SUCCESS) {
- NumberOfData = 1;
- //
- // SEC Platform Information only includes BSP's BIST information
- // and does not have BSP's APIC ID
- //
- BspCpuInstance.CpuLocation = GetInitialApicId ();
- BspCpuInstance.InfoRecord.IA32HealthFlags.Uint32 = SecPlatformInformation->IA32HealthFlags.Uint32;
- CpuInstance = &BspCpuInstance;
- } else {
- DEBUG ((DEBUG_INFO, "Does not find any stored CPU BIST information from PPI!\n"));
- }
- }
- for (ProcessorNumber = 0; ProcessorNumber < NumberOfProcessors; ProcessorNumber++) {
- MpInitLibGetProcessorInfo (ProcessorNumber, &ProcessorInfo, &BistData);
- for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex++) {
- ASSERT (CpuInstance != NULL);
- if (ProcessorInfo.ProcessorId == CpuInstance[CpuIndex].CpuLocation) {
- //
- // Update processor's BIST data if it is already stored before
- //
- BistData = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags;
- }
- }
- if (BistData.Uint32 != 0) {
- //
- // Report Status Code that self test is failed
- //
- REPORT_STATUS_CODE (
- EFI_ERROR_CODE | EFI_ERROR_MAJOR,
- (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST)
- );
- }
- DEBUG ((
- DEBUG_INFO,
- " APICID - 0x%08x, BIST - 0x%08x\n",
- (UINT32)ProcessorInfo.ProcessorId,
- BistData
- ));
- CpuInstanceInHob = PlatformInformationRecord2->CpuInstance;
- CpuInstanceInHob[ProcessorNumber].CpuLocation = (UINT32)ProcessorInfo.ProcessorId;
- CpuInstanceInHob[ProcessorNumber].InfoRecord.IA32HealthFlags = BistData;
- }
- //
- // Build SecPlatformInformation2 PPI GUIDed HOB that also could be consumed
- // by CPU MP driver to get CPU BIST data
- //
- BuildGuidDataHob (
- &gEfiSecPlatformInformation2PpiGuid,
- PlatformInformationRecord2,
- (UINTN)BistInformationSize
- );
- if (SecPlatformInformation2 != NULL) {
- if (NumberOfData < NumberOfProcessors) {
- //
- // Reinstall SecPlatformInformation2 PPI to include new BIST information
- //
- Status = PeiServicesReInstallPpi (
- SecInformationDescriptor,
- &mPeiSecPlatformInformation2Ppi
- );
- ASSERT_EFI_ERROR (Status);
- }
- } else {
- //
- // Install SecPlatformInformation2 PPI
- //
- Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi);
- ASSERT_EFI_ERROR (Status);
- }
- }
|