X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=UefiCpuPkg%2FCpuMpPei%2FCpuMpPei.c;h=97b7e99c9a0419182a5e40bf1b4405432b9fd2d2;hb=3fd56a2672ede208e44d5bc495339bfb9ba6cd5d;hp=d63b1ff23111ac9d49fb5a87f3e482072aaa8906;hpb=d1cf93333f3a9394c2f746db4deb374b6ba374fd;p=mirror_edk2.git diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c index d63b1ff231..97b7e99c9a 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c @@ -38,6 +38,12 @@ GLOBAL_REMOVE_IF_UNREFERENCED IA32_DESCRIPTOR mGdt = { (UINTN) mGdtEntries }; +GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + CpuMpEndOfPeiCallback +}; + /** Sort the APIC ID of all processors. @@ -94,6 +100,31 @@ SortApicId ( } } } + +/** + Get CPU MP Data pointer from the Guided HOB. + + @return Pointer to Pointer to PEI CPU MP Data +**/ +PEI_CPU_MP_DATA * +GetMpHobData ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + VOID *DataInHob; + PEI_CPU_MP_DATA *CpuMpData; + + CpuMpData = NULL; + GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); + if (GuidHob != NULL) { + DataInHob = GET_GUID_HOB_DATA (GuidHob); + CpuMpData = (PEI_CPU_MP_DATA *)(*(UINTN *)DataInHob); + } + ASSERT (CpuMpData != NULL); + return CpuMpData; +} + /** This function will be called from AP reset code if BSP uses WakeUpAP. @@ -108,6 +139,8 @@ ApCFunction ( ) { PEI_CPU_MP_DATA *PeiCpuMpData; + UINTN ProcessorNumber; + EFI_AP_PROCEDURE Procedure; UINTN BistData; PeiCpuMpData = ExchangeInfo->PeiCpuMpData; @@ -123,6 +156,18 @@ ApCFunction ( // MtrrSetAllMtrrs (&PeiCpuMpData->MtrrTable); MicrocodeDetect (); + } else { + // + // Execute AP function if AP is not disabled + // + GetProcessorNumber (PeiCpuMpData, &ProcessorNumber); + if ((PeiCpuMpData->CpuData[ProcessorNumber].State != CpuStateDisabled) && + (PeiCpuMpData->ApFunction != 0)) { + PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateBusy; + Procedure = (EFI_AP_PROCEDURE)(UINTN)PeiCpuMpData->ApFunction; + Procedure ((VOID *)(UINTN)PeiCpuMpData->ApFunctionArgument); + PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle; + } } // @@ -130,6 +175,7 @@ ApCFunction ( // InterlockedIncrement ((UINT32 *)&PeiCpuMpData->FinishedCount); + AsmCliHltLoop (); } /** @@ -277,6 +323,20 @@ BackupAndPrepareWakeupBuffer( PeiCpuMpData->AddressMap.RendezvousFunnelSize ); } + +/** + Restore wakeup buffer data. + + @param PeiCpuMpData Pointer to PEI CPU MP Data +**/ +VOID +RestoreWakeupBuffer( + IN PEI_CPU_MP_DATA *PeiCpuMpData + ) +{ + CopyMem ((VOID *) PeiCpuMpData->WakeupBuffer, (VOID *) PeiCpuMpData->BackupBuffer, PeiCpuMpData->BackupBufferSize); +} + /** This function will get CPU count in the system. @@ -341,6 +401,7 @@ PrepareAPStartupVector ( AsmGetAddressMap (&AddressMap); WakeupBufferSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO); WakeupBuffer = GetWakeupBuffer ((WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1)); + ASSERT (WakeupBuffer != (UINTN) -1); DEBUG ((EFI_D_INFO, "CpuMpPei: WakeupBuffer = 0x%x\n", WakeupBuffer)); // @@ -369,6 +430,7 @@ PrepareAPStartupVector ( PeiCpuMpData->CpuData = (PEI_CPU_DATA *) (PeiCpuMpData->MpCpuExchangeInfo + 1); PeiCpuMpData->CpuData[0].ApicId = GetInitialApicId (); PeiCpuMpData->CpuData[0].Health.Uint32 = 0; + PeiCpuMpData->EndOfPeiFlag = FALSE; CopyMem (&PeiCpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP)); // @@ -378,6 +440,70 @@ PrepareAPStartupVector ( return PeiCpuMpData; } + +/** + Notify function on End Of Pei PPI. + + On S3 boot, this function will restore wakeup buffer data. + On normal boot, this function will flag wakeup buffer to be un-used type. + + @param PeiServices The pointer to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS When everything is OK. + +**/ +EFI_STATUS +EFIAPI +CpuMpEndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + PEI_CPU_MP_DATA *PeiCpuMpData; + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_MEMORY_ALLOCATION *MemoryHob; + + DEBUG ((EFI_D_INFO, "CpuMpPei: CpuMpEndOfPeiCallback () invokded\n")); + + Status = PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + PeiCpuMpData = GetMpHobData (); + ASSERT (PeiCpuMpData != NULL); + + if (BootMode != BOOT_ON_S3_RESUME) { + // + // Get the HOB list for processing + // + Hob.Raw = GetHobList (); + // + // Collect memory ranges + // + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) { + MemoryHob = Hob.MemoryAllocation; + if(MemoryHob->AllocDescriptor.MemoryBaseAddress == PeiCpuMpData->WakeupBuffer) { + // + // Flag this HOB type to un-used + // + GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED; + break; + } + } + Hob.Raw = GET_NEXT_HOB (Hob); + } + } else { + RestoreWakeupBuffer (PeiCpuMpData); + PeiCpuMpData->EndOfPeiFlag = TRUE; + } + return EFI_SUCCESS; +} + /** The Entry point of the MP CPU PEIM. @@ -397,7 +523,7 @@ CpuMpPeimInit ( IN CONST EFI_PEI_SERVICES **PeiServices ) { - + EFI_STATUS Status; PEI_CPU_MP_DATA *PeiCpuMpData; UINT32 ProcessorCount; @@ -413,6 +539,28 @@ CpuMpPeimInit ( // Count processor number and collect processor information // ProcessorCount = CountProcessorNumber (PeiCpuMpData); + // + // Build location of PEI CPU MP DATA buffer in HOB + // + BuildGuidDataHob ( + &gEfiCallerIdGuid, + (VOID *)&PeiCpuMpData, + sizeof(UINT64) + ); + // + // Update and publish CPU BIST information + // + CollectBistDataFromPpi (PeiServices, PeiCpuMpData); + // + // register an event for EndOfPei + // + Status = PeiServicesNotifyPpi (&mNotifyList); + ASSERT_EFI_ERROR (Status); + // + // Install CPU MP PPI + // + Status = PeiServicesInstallPpi(&mPeiCpuMpPpiDesc); + ASSERT_EFI_ERROR (Status); - return EFI_SUCCESS; + return Status; }