**/\r
\r
#include "MpLib.h"\r
-#include <Ppi/EndOfPeiPhase.h>\r
-#include <Library/PeiServicesLib.h>\r
-\r
-//\r
-// Global PEI notify function descriptor on EndofPei event\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mMpInitLibNotifyList = {\r
- (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
- &gEfiEndOfPeiSignalPpiGuid,\r
- CpuMpEndOfPeiCallback\r
-};\r
-\r
\r
/**\r
Enable Debug Agent to support source debugging on AP function.\r
);\r
}\r
\r
-/**\r
- Notify function on End Of PEI PPI.\r
-\r
- On S3 boot, this function will restore wakeup buffer data.\r
- On normal boot, this function will flag wakeup buffer to be un-used type.\r
-\r
- @param[in] PeiServices The pointer to the PEI Services Table.\r
- @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
- @param[in] Ppi Address of the PPI that was installed.\r
-\r
- @retval EFI_SUCCESS When everything is OK.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CpuMpEndOfPeiCallback (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
- IN VOID *Ppi\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_BOOT_MODE BootMode;\r
- CPU_MP_DATA *CpuMpData;\r
- EFI_PEI_HOB_POINTERS Hob;\r
- EFI_HOB_MEMORY_ALLOCATION *MemoryHob;\r
-\r
- DEBUG ((DEBUG_INFO, "PeiMpInitLib: CpuMpEndOfPeiCallback () invoked\n"));\r
-\r
- Status = PeiServicesGetBootMode (&BootMode);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- CpuMpData = GetCpuMpData ();\r
- if (BootMode != BOOT_ON_S3_RESUME) {\r
- //\r
- // Get the HOB list for processing\r
- //\r
- Hob.Raw = GetHobList ();\r
- //\r
- // Collect memory ranges\r
- //\r
- while (!END_OF_HOB_LIST (Hob)) {\r
- if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {\r
- MemoryHob = Hob.MemoryAllocation;\r
- if (MemoryHob->AllocDescriptor.MemoryBaseAddress == CpuMpData->WakeupBuffer) {\r
- //\r
- // Flag this HOB type to un-used\r
- //\r
- GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED;\r
- break;\r
- }\r
- }\r
- Hob.Raw = GET_NEXT_HOB (Hob);\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
/**\r
Check if AP wakeup buffer is overlapped with existing allocated buffer.\r
\r
}\r
DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n",\r
WakeupBufferStart, WakeupBufferSize));\r
- //\r
- // Create a memory allocation HOB.\r
- //\r
- BuildMemoryAllocationHob (\r
- WakeupBufferStart,\r
- WakeupBufferSize,\r
- EfiBootServicesData\r
- );\r
return WakeupBufferStart;\r
}\r
}\r
return (UINTN) -1;\r
}\r
\r
-/**\r
- Allocate reset vector buffer.\r
-\r
- @param[in, out] CpuMpData The pointer to CPU MP Data structure.\r
-**/\r
-VOID\r
-AllocateResetVector (\r
- IN OUT CPU_MP_DATA *CpuMpData\r
- )\r
-{\r
- UINTN ApResetVectorSize;\r
-\r
- if (CpuMpData->WakeupBuffer == (UINTN) -1) {\r
- ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +\r
- sizeof (MP_CPU_EXCHANGE_INFO);\r
-\r
- CpuMpData->WakeupBuffer = GetWakeupBuffer (ApResetVectorSize);\r
- CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN)\r
- (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize);\r
- }\r
- BackupAndPrepareWakeupBuffer (CpuMpData);\r
-}\r
-\r
-/**\r
- Free AP reset vector buffer.\r
-\r
- @param[in] CpuMpData The pointer to CPU MP Data structure.\r
-**/\r
-VOID\r
-FreeResetVector (\r
- IN CPU_MP_DATA *CpuMpData\r
- )\r
-{\r
- RestoreWakeupBuffer (CpuMpData);\r
-}\r
-\r
/**\r
Checks APs status and updates APs status if needed.\r
\r
IN CPU_MP_DATA *CpuMpData\r
)\r
{\r
- EFI_STATUS Status;\r
-\r
SaveCpuMpData (CpuMpData);\r
-\r
- if (CpuMpData->CpuCount == 1) {\r
- //\r
- // If only BSP exists, return\r
- //\r
- return;\r
- }\r
-\r
- //\r
- // Register an event for EndOfPei\r
- //\r
- Status = PeiServicesNotifyPpi (&mMpInitLibNotifyList);\r
- ASSERT_EFI_ERROR (Status);\r
}\r
\r
/**\r