X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=UefiCpuPkg%2FLibrary%2FMpInitLib%2FDxeMpLib.c;h=b399f1c24d301158ee79c8245a38ba818c1b6b05;hb=438f17665c949ccd8b2fec7646fa894f31b54df8;hp=42d320ff8a6efc59256aef03e38ec4613f312ef5;hpb=4d3314f694881f4a4a53636515da144230f1d913;p=mirror_edk2.git diff --git a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c index 42d320ff8a..b399f1c24d 100644 --- a/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/DxeMpLib.c @@ -23,7 +23,7 @@ CPU_MP_DATA *mCpuMpData = NULL; EFI_EVENT mCheckAllApsEvent = NULL; EFI_EVENT mMpInitExitBootServicesEvent = NULL; volatile BOOLEAN mStopCheckAllApsStatus = TRUE; - +VOID *mReservedApLoopFunc = NULL; /** Get the pointer to CPU MP Data structure. @@ -66,29 +66,33 @@ AllocateResetVector ( UINTN ApResetVectorSize; EFI_PHYSICAL_ADDRESS StartAddress; - ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + - sizeof (MP_CPU_EXCHANGE_INFO); - - StartAddress = BASE_1MB; - Status = gBS->AllocatePages ( - AllocateMaxAddress, - EfiACPIMemoryNVS, - EFI_SIZE_TO_PAGES (ApResetVectorSize), - &StartAddress - ); - ASSERT_EFI_ERROR (Status); - - CpuMpData->WakeupBuffer = (UINTN) StartAddress; - CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) + if (CpuMpData->SaveRestoreFlag) { + BackupAndPrepareWakeupBuffer (CpuMpData); + } else { + ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + + sizeof (MP_CPU_EXCHANGE_INFO); + + StartAddress = BASE_1MB; + Status = gBS->AllocatePages ( + AllocateMaxAddress, + EfiACPIMemoryNVS, + EFI_SIZE_TO_PAGES (ApResetVectorSize), + &StartAddress + ); + ASSERT_EFI_ERROR (Status); + + CpuMpData->WakeupBuffer = (UINTN) StartAddress; + CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize); - // - // copy AP reset code in it - // - CopyMem ( - (VOID *) CpuMpData->WakeupBuffer, - (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress, - CpuMpData->AddressMap.RendezvousFunnelSize - ); + // + // copy AP reset code in it + // + CopyMem ( + (VOID *) CpuMpData->WakeupBuffer, + (VOID *) CpuMpData->AddressMap.RendezvousFunnelAddress, + CpuMpData->AddressMap.RendezvousFunnelSize + ); + } } /** @@ -103,13 +107,18 @@ FreeResetVector ( { EFI_STATUS Status; UINTN ApResetVectorSize; - ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + - sizeof (MP_CPU_EXCHANGE_INFO); - Status = gBS->FreePages( - (EFI_PHYSICAL_ADDRESS)CpuMpData->WakeupBuffer, - EFI_SIZE_TO_PAGES (ApResetVectorSize) - ); - ASSERT_EFI_ERROR (Status); + + if (CpuMpData->SaveRestoreFlag) { + RestoreWakeupBuffer (CpuMpData); + } else { + ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize + + sizeof (MP_CPU_EXCHANGE_INFO); + Status = gBS->FreePages( + (EFI_PHYSICAL_ADDRESS)CpuMpData->WakeupBuffer, + EFI_SIZE_TO_PAGES (ApResetVectorSize) + ); + ASSERT_EFI_ERROR (Status); + } } /** @@ -163,7 +172,7 @@ CheckAndUpdateApsStatus ( /** Checks APs' status periodically. - This function is triggerred by timer perodically to check the + This function is triggered by timer periodically to check the state of APs for StartupAllAPs() and StartupThisAP() executed in non-blocking mode. @@ -189,7 +198,7 @@ CheckApsStatus ( /** Get Protected mode code segment from current GDT table. - @returen Protected mode code segment value. + @return Protected mode code segment value. **/ UINT16 GetProtectedModeCS ( @@ -258,19 +267,12 @@ MpInitExitBootServicesCallback ( ) { CPU_MP_DATA *CpuMpData; - VOID *ReservedApLoopFunc; - // - // Avoid APs access invalid buff data which allocated by BootServices, - // so we will allocate reserved data for AP loop code. - // + CpuMpData = GetCpuMpData (); + CpuMpData->SaveRestoreFlag = TRUE; CpuMpData->PmCodeSegment = GetProtectedModeCS (); CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode); - ReservedApLoopFunc = AllocateReservedCopyPool ( - CpuMpData->AddressMap.RelocateApLoopFuncSize, - CpuMpData->AddressMap.RelocateApLoopFuncAddress - ); - WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, ReservedApLoopFunc); + WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, mReservedApLoopFunc); DEBUG ((DEBUG_INFO, "MpInitExitBootServicesCallback() done!\n")); } @@ -288,6 +290,18 @@ InitMpGlobalData ( SaveCpuMpData (CpuMpData); + // + // Avoid APs access invalid buff data which allocated by BootServices, + // so we will allocate reserved data for AP loop code. + // Allocating it in advance since memory services are not available in + // Exit Boot Services callback function. + // + mReservedApLoopFunc = AllocateReservedCopyPool ( + CpuMpData->AddressMap.RelocateApLoopFuncSize, + CpuMpData->AddressMap.RelocateApLoopFuncAddress + ); + ASSERT (mReservedApLoopFunc != NULL); + Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY,