X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FCpuMpPei%2FCpuBist.c;h=bf18ca4556c01e64bbae24b71948cf4e803023e0;hp=579b6b0b2493bbf5623d8d4a82ac5ee1689bf13f;hb=e3ae7f52738667c7540486d91eff47efd0906fee;hpb=a21fe4285ec30d80d1e2925aead5521cf9239a41 diff --git a/UefiCpuPkg/CpuMpPei/CpuBist.c b/UefiCpuPkg/CpuMpPei/CpuBist.c index 579b6b0b24..bf18ca4556 100644 --- a/UefiCpuPkg/CpuMpPei/CpuBist.c +++ b/UefiCpuPkg/CpuMpPei/CpuBist.c @@ -1,260 +1,295 @@ -/** @file - Update and publish processors' BIST information. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#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 - ) -{ - PEI_CPU_MP_DATA *PeiCpuMpData; - UINTN BistInformationSize; - UINTN CpuIndex; - EFI_SEC_PLATFORM_INFORMATION_CPU *CpuInstance; - - PeiCpuMpData = GetMpHobData (); - - BistInformationSize = sizeof (EFI_SEC_PLATFORM_INFORMATION_RECORD2) + - sizeof (EFI_SEC_PLATFORM_INFORMATION_CPU) * PeiCpuMpData->CpuCount; - // - // return the information size if input buffer size is too small - // - if ((*StructureSize) < (UINT64) BistInformationSize) { - *StructureSize = (UINT64) BistInformationSize; - return EFI_BUFFER_TOO_SMALL; - } - - PlatformInformationRecord2->NumberOfCpus = PeiCpuMpData->CpuCount; - CpuInstance = PlatformInformationRecord2->CpuInstance; - for (CpuIndex = 0; CpuIndex < PeiCpuMpData->CpuCount; CpuIndex ++) { - CpuInstance[CpuIndex].CpuLocation = PeiCpuMpData->CpuData[CpuIndex].ApicId; - CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags = PeiCpuMpData->CpuData[CpuIndex].Health; - } - - 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 - - @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 - ) -{ - 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; - 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 - @param PeiCpuMpData Pointer to PEI CPU MP Data - -**/ -VOID -CollectBistDataFromPpi ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN PEI_CPU_MP_DATA *PeiCpuMpData - ) -{ - 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; - PEI_CPU_DATA *CpuData; - - SecPlatformInformation2 = NULL; - SecPlatformInformation = NULL; - NumberOfData = 0; - CpuInstance = NULL; - - // - // Get BIST information from Sec Platform Information2 Ppi firstly - // - Status = GetBistInfoFromPpi ( - PeiServices, - &gEfiSecPlatformInformation2PpiGuid, - &SecInformationDescriptor, - (VOID *) &SecPlatformInformation2 - ); - 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 - ); - 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 ((EFI_D_INFO, "Does not find any stored CPU BIST information from PPI!\n")); - } - } - for (ProcessorNumber = 0; ProcessorNumber < PeiCpuMpData->CpuCount; ProcessorNumber ++) { - CpuData = &PeiCpuMpData->CpuData[ProcessorNumber]; - for (CpuIndex = 0; CpuIndex < NumberOfData; CpuIndex ++) { - ASSERT (CpuInstance != NULL); - if (CpuData->ApicId == CpuInstance[CpuIndex].CpuLocation) { - // - // Update processor's BIST data if it is already stored before - // - CpuData->Health = CpuInstance[CpuIndex].InfoRecord.IA32HealthFlags; - } - } - if (CpuData->Health.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 ((EFI_D_INFO, " APICID - 0x%08x, BIST - 0x%08x\n", - PeiCpuMpData->CpuData[ProcessorNumber].ApicId, - PeiCpuMpData->CpuData[ProcessorNumber].Health.Uint32 - )); - } - - if (SecPlatformInformation2 != NULL && NumberOfData < PeiCpuMpData->CpuCount) { - // - // Reinstall SecPlatformInformation2 PPI to include new BIST inforamtion - // - Status = PeiServicesReInstallPpi ( - SecInformationDescriptor, - &mPeiSecPlatformInformation2Ppi - ); - ASSERT_EFI_ERROR (Status); - } else { - // - // Install SecPlatformInformation2 PPI to include new BIST inforamtion - // - Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi); - ASSERT_EFI_ERROR(Status); - } -} +/** @file + Update and publish processors' BIST information. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#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 ((EFI_D_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 ((EFI_D_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 && NumberOfData < NumberOfProcessors) { + // + // Reinstall SecPlatformInformation2 PPI to include new BIST information + // + Status = PeiServicesReInstallPpi ( + SecInformationDescriptor, + &mPeiSecPlatformInformation2Ppi + ); + ASSERT_EFI_ERROR (Status); + } else { + // + // Install SecPlatformInformation2 PPI to include new BIST information + // + Status = PeiServicesInstallPpi (&mPeiSecPlatformInformation2Ppi); + ASSERT_EFI_ERROR(Status); + } +} +