X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=UefiCpuPkg%2FLibrary%2FMpInitLib%2FPeiMpLib.c;h=65400b95a237de7944c8edf3451c51a4591151c9;hb=HEAD;hp=90015c650c68127096ee338b37ac8429ac53d482;hpb=dbc22a178546edb6373a4a1f331b0f16f04e2e3d;p=mirror_edk2.git diff --git a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c index 90015c650c..e732371ddd 100644 --- a/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/PeiMpLib.c @@ -11,7 +11,7 @@ #include #include -STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB; +STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB; /** S3 SMM Init Done notification function. @@ -26,16 +26,15 @@ STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB; EFI_STATUS EFIAPI NotifyOnS3SmmInitDonePpi ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, - IN VOID *InvokePpi + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *InvokePpi ); - // // Global function // -EFI_PEI_NOTIFY_DESCRIPTOR mS3SmmInitDoneNotifyDesc = { +EFI_PEI_NOTIFY_DESCRIPTOR mS3SmmInitDoneNotifyDesc = { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, &gEdkiiS3SmmInitDoneGuid, NotifyOnS3SmmInitDonePpi @@ -54,12 +53,12 @@ EFI_PEI_NOTIFY_DESCRIPTOR mS3SmmInitDoneNotifyDesc = { EFI_STATUS EFIAPI NotifyOnS3SmmInitDonePpi ( - IN EFI_PEI_SERVICES **PeiServices, - IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, - IN VOID *InvokePpi + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, + IN VOID *InvokePpi ) { - CPU_MP_DATA *CpuMpData; + CPU_MP_DATA *CpuMpData; CpuMpData = GetCpuMpData (); @@ -76,7 +75,6 @@ NotifyOnS3SmmInitDonePpi ( return EFI_SUCCESS; } - /** Enable Debug Agent to support source debugging on AP function. @@ -91,7 +89,7 @@ EnableDebugAgent ( /** Get pointer to CPU MP Data structure. For BSP, the pointer is retrieved from HOB. - For AP, the structure is just after IDT. + For AP, the structure is stored in the top of each AP's stack. @return The pointer to CPU MP Data structure. **/ @@ -102,16 +100,19 @@ GetCpuMpData ( { CPU_MP_DATA *CpuMpData; MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr; - IA32_DESCRIPTOR Idtr; + UINTN ApTopOfStack; + AP_STACK_DATA *ApStackData; ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE); if (ApicBaseMsr.Bits.BSP == 1) { CpuMpData = GetCpuMpDataFromGuidedHob (); ASSERT (CpuMpData != NULL); } else { - AsmReadIdtr (&Idtr); - CpuMpData = (CPU_MP_DATA *) (Idtr.Base + Idtr.Limit + 1); + ApTopOfStack = ALIGN_VALUE ((UINTN)&ApTopOfStack, (UINTN)PcdGet32 (PcdCpuApStackSize)); + ApStackData = (AP_STACK_DATA *)((UINTN)ApTopOfStack- sizeof (AP_STACK_DATA)); + CpuMpData = (CPU_MP_DATA *)ApStackData->MpData; } + return CpuMpData; } @@ -122,17 +123,18 @@ GetCpuMpData ( **/ VOID SaveCpuMpData ( - IN CPU_MP_DATA *CpuMpData + IN CPU_MP_DATA *CpuMpData ) { - UINT64 Data64; + UINT64 Data64; + // // Build location of CPU MP DATA buffer in HOB // - Data64 = (UINT64) (UINTN) CpuMpData; + Data64 = (UINT64)(UINTN)CpuMpData; BuildGuidDataHob ( &mCpuInitMpLibHobGuid, - (VOID *) &Data64, + (VOID *)&Data64, sizeof (UINT64) ); } @@ -148,15 +150,15 @@ SaveCpuMpData ( **/ BOOLEAN CheckOverlapWithAllocatedBuffer ( - IN UINT64 WakeupBufferStart, - IN UINT64 WakeupBufferEnd + IN UINT64 WakeupBufferStart, + IN UINT64 WakeupBufferEnd ) { - EFI_PEI_HOB_POINTERS Hob; - EFI_HOB_MEMORY_ALLOCATION *MemoryHob; - BOOLEAN Overlapped; - UINT64 MemoryStart; - UINT64 MemoryEnd; + EFI_PEI_HOB_POINTERS Hob; + EFI_HOB_MEMORY_ALLOCATION *MemoryHob; + BOOLEAN Overlapped; + UINT64 MemoryStart; + UINT64 MemoryEnd; Overlapped = FALSE; // @@ -176,8 +178,10 @@ CheckOverlapWithAllocatedBuffer ( break; } } + Hob.Raw = GET_NEXT_HOB (Hob); } + return Overlapped; } @@ -191,12 +195,12 @@ CheckOverlapWithAllocatedBuffer ( **/ UINTN GetWakeupBuffer ( - IN UINTN WakeupBufferSize + IN UINTN WakeupBufferSize ) { - EFI_PEI_HOB_POINTERS Hob; - UINT64 WakeupBufferStart; - UINT64 WakeupBufferEnd; + EFI_PEI_HOB_POINTERS Hob; + UINT64 WakeupBufferStart; + UINT64 WakeupBufferEnd; WakeupBufferSize = (WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1); @@ -216,14 +220,16 @@ GetWakeupBuffer ( (EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED - )) == 0) - ) { + )) == 0) + ) + { // // Need memory under 1MB to be collected here // WakeupBufferEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength; - if (PcdGetBool (PcdSevEsIsEnabled) && - WakeupBufferEnd > mSevEsPeiWakeupBuffer) { + if (ConfidentialComputingGuestHas (CCAttrAmdSevEs) && + (WakeupBufferEnd > mSevEsPeiWakeupBuffer)) + { // // SEV-ES Wakeup buffer should be under 1MB and under any previous one // @@ -234,6 +240,7 @@ GetWakeupBuffer ( // WakeupBufferEnd = BASE_1MB; } + while (WakeupBufferEnd > WakeupBufferSize) { // // Wakeup buffer should be aligned on 4KB @@ -242,6 +249,7 @@ GetWakeupBuffer ( if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) { break; } + if (CheckOverlapWithAllocatedBuffer (WakeupBufferStart, WakeupBufferEnd)) { // // If this range is overlapped with existing allocated buffer, skip it @@ -250,10 +258,15 @@ GetWakeupBuffer ( WakeupBufferEnd -= WakeupBufferSize; continue; } - DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n", - WakeupBufferStart, WakeupBufferSize)); - if (PcdGetBool (PcdSevEsIsEnabled)) { + DEBUG (( + DEBUG_INFO, + "WakeupBufferStart = %x, WakeupBufferSize = %x\n", + WakeupBufferStart, + WakeupBufferSize + )); + + if (ConfidentialComputingGuestHas (CCAttrAmdSevEs)) { // // Next SEV-ES wakeup buffer allocation must be below this // allocation @@ -265,13 +278,14 @@ GetWakeupBuffer ( } } } + // // Find the next HOB // Hob.Raw = GET_NEXT_HOB (Hob); } - return (UINTN) -1; + return (UINTN)-1; } /** @@ -287,14 +301,19 @@ GetWakeupBuffer ( @retval 0 Cannot find free memory below 4GB. **/ UINTN -GetModeTransitionBuffer ( - IN UINTN BufferSize +AllocateCodeBuffer ( + IN UINTN BufferSize ) { - // - // PEI phase doesn't need to do such transition. So simply return 0. - // - return 0; + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Address; + + Status = PeiServicesAllocatePages (EfiBootServicesCode, EFI_SIZE_TO_PAGES (BufferSize), &Address); + if (EFI_ERROR (Status)) { + Address = 0; + } + + return (UINTN)Address; } /** @@ -336,17 +355,17 @@ CheckAndUpdateApsStatus ( **/ VOID BuildMicrocodeCacheHob ( - IN CPU_MP_DATA *CpuMpData + IN CPU_MP_DATA *CpuMpData ) { - EDKII_MICROCODE_PATCH_HOB *MicrocodeHob; - UINTN HobDataLength; - UINT32 Index; + EDKII_MICROCODE_PATCH_HOB *MicrocodeHob; + UINTN HobDataLength; + UINT32 Index; HobDataLength = sizeof (EDKII_MICROCODE_PATCH_HOB) + sizeof (UINT64) * CpuMpData->CpuCount; - MicrocodeHob = AllocatePool (HobDataLength); + MicrocodeHob = AllocatePool (HobDataLength); if (MicrocodeHob == NULL) { ASSERT (FALSE); return; @@ -387,7 +406,7 @@ BuildMicrocodeCacheHob ( **/ VOID InitMpGlobalData ( - IN CPU_MP_DATA *CpuMpData + IN CPU_MP_DATA *CpuMpData ) { EFI_STATUS Status; @@ -480,12 +499,12 @@ InitMpGlobalData ( EFI_STATUS EFIAPI MpInitLibStartupAllAPs ( - IN EFI_AP_PROCEDURE Procedure, - IN BOOLEAN SingleThread, - IN EFI_EVENT WaitEvent OPTIONAL, - IN UINTN TimeoutInMicroseconds, - IN VOID *ProcedureArgument OPTIONAL, - OUT UINTN **FailedCpuList OPTIONAL + IN EFI_AP_PROCEDURE Procedure, + IN BOOLEAN SingleThread, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT UINTN **FailedCpuList OPTIONAL ) { if (WaitEvent != NULL) { @@ -577,12 +596,12 @@ MpInitLibStartupAllAPs ( EFI_STATUS EFIAPI MpInitLibStartupThisAP ( - IN EFI_AP_PROCEDURE Procedure, - IN UINTN ProcessorNumber, - IN EFI_EVENT WaitEvent OPTIONAL, - IN UINTN TimeoutInMicroseconds, - IN VOID *ProcedureArgument OPTIONAL, - OUT BOOLEAN *Finished OPTIONAL + IN EFI_AP_PROCEDURE Procedure, + IN UINTN ProcessorNumber, + IN EFI_EVENT WaitEvent OPTIONAL, + IN UINTN TimeoutInMicroseconds, + IN VOID *ProcedureArgument OPTIONAL, + OUT BOOLEAN *Finished OPTIONAL ) { if (WaitEvent != NULL) { @@ -628,8 +647,8 @@ MpInitLibStartupThisAP ( EFI_STATUS EFIAPI MpInitLibSwitchBSP ( - IN UINTN ProcessorNumber, - IN BOOLEAN EnableOldBSP + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSP ) { return SwitchBSPWorker (ProcessorNumber, EnableOldBSP); @@ -668,9 +687,9 @@ MpInitLibSwitchBSP ( EFI_STATUS EFIAPI MpInitLibEnableDisableAP ( - IN UINTN ProcessorNumber, - IN BOOLEAN EnableAP, - IN UINT32 *HealthFlag OPTIONAL + IN UINTN ProcessorNumber, + IN BOOLEAN EnableAP, + IN UINT32 *HealthFlag OPTIONAL ) { return EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag); @@ -689,29 +708,29 @@ MpInitLibEnableDisableAP ( **/ EFI_STATUS PlatformShadowMicrocode ( - IN OUT CPU_MP_DATA *CpuMpData + IN OUT CPU_MP_DATA *CpuMpData ) { - EFI_STATUS Status; - EDKII_PEI_SHADOW_MICROCODE_PPI *ShadowMicrocodePpi; - UINTN CpuCount; - EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId; - UINTN Index; - UINTN BufferSize; - VOID *Buffer; + EFI_STATUS Status; + EDKII_PEI_SHADOW_MICROCODE_PPI *ShadowMicrocodePpi; + UINTN CpuCount; + EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId; + UINTN Index; + UINTN BufferSize; + VOID *Buffer; Status = PeiServicesLocatePpi ( &gEdkiiPeiShadowMicrocodePpiGuid, 0, NULL, - (VOID **) &ShadowMicrocodePpi + (VOID **)&ShadowMicrocodePpi ); if (EFI_ERROR (Status)) { return EFI_UNSUPPORTED; } - CpuCount = CpuMpData->CpuCount; - MicrocodeCpuId = (EDKII_PEI_MICROCODE_CPU_ID *) AllocateZeroPool (sizeof (EDKII_PEI_MICROCODE_CPU_ID) * CpuCount); + CpuCount = CpuMpData->CpuCount; + MicrocodeCpuId = (EDKII_PEI_MICROCODE_CPU_ID *)AllocateZeroPool (sizeof (EDKII_PEI_MICROCODE_CPU_ID) * CpuCount); if (MicrocodeCpuId == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -722,24 +741,26 @@ PlatformShadowMicrocode ( } Status = ShadowMicrocodePpi->ShadowMicrocode ( - ShadowMicrocodePpi, - CpuCount, - MicrocodeCpuId, - &BufferSize, - &Buffer - ); + ShadowMicrocodePpi, + CpuCount, + MicrocodeCpuId, + &BufferSize, + &Buffer + ); FreePool (MicrocodeCpuId); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } - CpuMpData->MicrocodePatchAddress = (UINTN) Buffer; + CpuMpData->MicrocodePatchAddress = (UINTN)Buffer; CpuMpData->MicrocodePatchRegionSize = BufferSize; DEBUG (( DEBUG_INFO, "%a: Required microcode patches have been loaded at 0x%lx, with size 0x%lx.\n", - __FUNCTION__, CpuMpData->MicrocodePatchAddress, CpuMpData->MicrocodePatchRegionSize + __FUNCTION__, + CpuMpData->MicrocodePatchAddress, + CpuMpData->MicrocodePatchRegionSize )); return EFI_SUCCESS;