UefiCpuPkg MpInitLib: Save/restore original WakeupBuffer for DxeMpLib

Current code always allocates/frees < 1MB WakeupBuffer for DxeMpLib
until ExitBootService, but the allocation may be failed at late
phase of the boot.

This patch is to always save/restore original WakeupBuffer for
DxeMpLib, it is aligned with the solution for PeiMpLib at
9293d6e42e, then AllocateResetVector()
and FreeResetVector() will be common and moved to MpLib.c.
Only difference is GetWakeupBuffer() that will be in PeiMpLib or
DxeMpLib respectively.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Jeff Fan <jeff.fan@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Star Zeng
2017-08-04 10:05:20 +08:00
parent 4ad5f59715
commit a6b3d753f9
4 changed files with 109 additions and 168 deletions

View File

@ -75,72 +75,41 @@ SaveCpuMpData (
}
/**
Allocate reset vector buffer.
Get available system memory below 1MB by specified size.
@param[in, out] CpuMpData The pointer to CPU MP Data structure.
@param[in] WakeupBufferSize Wakeup buffer size required
@retval other Return wakeup buffer address below 1MB.
@retval -1 Cannot find free memory below 1MB.
**/
VOID
AllocateResetVector (
IN OUT CPU_MP_DATA *CpuMpData
UINTN
GetWakeupBuffer (
IN UINTN WakeupBufferSize
)
{
EFI_STATUS Status;
UINTN ApResetVectorSize;
EFI_PHYSICAL_ADDRESS StartAddress;
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS StartAddress;
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
);
}
}
/**
Free AP reset vector buffer.
@param[in] CpuMpData The pointer to CPU MP Data structure.
**/
VOID
FreeResetVector (
IN CPU_MP_DATA *CpuMpData
)
{
EFI_STATUS Status;
UINTN ApResetVectorSize;
if (CpuMpData->SaveRestoreFlag) {
RestoreWakeupBuffer (CpuMpData);
} else {
ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +
sizeof (MP_CPU_EXCHANGE_INFO);
StartAddress = BASE_1MB;
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiBootServicesData,
EFI_SIZE_TO_PAGES (WakeupBufferSize),
&StartAddress
);
ASSERT_EFI_ERROR (Status);
if (!EFI_ERROR (Status)) {
Status = gBS->FreePages(
(EFI_PHYSICAL_ADDRESS)CpuMpData->WakeupBuffer,
EFI_SIZE_TO_PAGES (ApResetVectorSize)
StartAddress,
EFI_SIZE_TO_PAGES (WakeupBufferSize)
);
ASSERT_EFI_ERROR (Status);
DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n",
(UINTN) StartAddress, WakeupBufferSize));
} else {
StartAddress = (EFI_PHYSICAL_ADDRESS) -1;
}
return (UINTN) StartAddress;
}
/**
@ -299,7 +268,6 @@ MpInitChangeApLoopCallback (
CPU_MP_DATA *CpuMpData;
CpuMpData = GetCpuMpData ();
CpuMpData->SaveRestoreFlag = TRUE;
CpuMpData->PmCodeSegment = GetProtectedModeCS ();
CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
mNumberToFinish = CpuMpData->CpuCount - 1;