CpuMpData->FinishedCount = 0;\r
ResetVectorRequired = FALSE;\r
\r
- if (CpuMpData->ApLoopMode == ApInHltLoop ||\r
+ if (CpuMpData->WakeUpByInitSipiSipi ||\r
CpuMpData->InitFlag != ApInitDone) {\r
ResetVectorRequired = TRUE;\r
AllocateResetVector (CpuMpData);\r
FillExchangeInfoData (CpuMpData);\r
SaveLocalApicTimerSetting (CpuMpData);\r
- } else if (CpuMpData->ApLoopMode == ApInMwaitLoop) {\r
+ }\r
+\r
+ if (CpuMpData->ApLoopMode == ApInMwaitLoop) {\r
//\r
// Get AP target C-state each time when waking up AP,\r
// for it maybe updated by platform again\r
if (ResetVectorRequired) {\r
FreeResetVector (CpuMpData);\r
}\r
+\r
+ //\r
+ // After one round of Wakeup Ap actions, need to re-sync ApLoopMode with\r
+ // WakeUpByInitSipiSipi flag. WakeUpByInitSipiSipi flag maybe changed by\r
+ // S3SmmInitDone Ppi.\r
+ //\r
+ CpuMpData->WakeUpByInitSipiSipi = (CpuMpData->ApLoopMode == ApInHltLoop);\r
}\r
\r
/**\r
//\r
CpuMpData->ApLoopMode = ApLoopMode;\r
DEBUG ((DEBUG_INFO, "AP Loop Mode is %d\n", CpuMpData->ApLoopMode));\r
+\r
+ CpuMpData->WakeUpByInitSipiSipi = (CpuMpData->ApLoopMode == ApInHltLoop);\r
+\r
//\r
// Set up APs wakeup signal buffer\r
//\r
UINT32 ProcessorFlags;\r
UINT64 MicrocodeDataAddress;\r
UINT32 MicrocodeRevision;\r
+\r
+ //\r
+ // Whether need to use Init-Sipi-Sipi to wake up the APs.\r
+ // Two cases need to set this value to TRUE. One is in HLT\r
+ // loop mode, the other is resume from S3 which loop mode\r
+ // will be hardcode change to HLT mode by PiSmmCpuDxeSmm \r
+ // driver.\r
+ //\r
+ BOOLEAN WakeUpByInitSipiSipi;\r
};\r
\r
extern EFI_GUID mCpuInitMpLibHobGuid;\r
**/\r
\r
#include "MpLib.h"\r
+#include <Library/PeiServicesLib.h>\r
+#include <Guid/S3SmmInitDone.h>\r
+\r
+/**\r
+ S3 SMM Init Done notification function.\r
+\r
+ @param PeiServices Indirect reference to the PEI Services Table.\r
+ @param NotifyDesc Address of the notification descriptor data structure.\r
+ @param InvokePpi Address of the PPI that was invoked.\r
+\r
+ @retval EFI_SUCCESS The function completes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NotifyOnS3SmmInitDonePpi (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+ IN VOID *InvokePpi\r
+ );\r
+\r
+\r
+//\r
+// Global function\r
+//\r
+EFI_PEI_NOTIFY_DESCRIPTOR mS3SmmInitDoneNotifyDesc = {\r
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+ &gEdkiiS3SmmInitDoneGuid,\r
+ NotifyOnS3SmmInitDonePpi\r
+};\r
+\r
+/**\r
+ The function prototype for invoking a function on an Application Processor.\r
+\r
+ This definition is used by the UEFI MP Serices Protocol, and the\r
+ PI SMM System Table.\r
+\r
+ @param[in,out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+EmptyApProcedure (\r
+ IN OUT VOID * Buffer\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ S3 SMM Init Done notification function.\r
+\r
+ @param PeiServices Indirect reference to the PEI Services Table.\r
+ @param NotifyDesc Address of the notification descriptor data structure.\r
+ @param InvokePpi Address of the PPI that was invoked.\r
+\r
+ @retval EFI_SUCCESS The function completes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NotifyOnS3SmmInitDonePpi (\r
+ IN EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
+ IN VOID *InvokePpi\r
+ )\r
+{\r
+ CPU_MP_DATA *CpuMpData;\r
+\r
+ CpuMpData = GetCpuMpData ();\r
+\r
+ //\r
+ // PiSmmCpuDxeSmm driver hardcode change the loop mode to HLT mode.\r
+ // So in this notify function, code need to check the current loop\r
+ // mode, if it is not HLT mode, code need to change loop mode back\r
+ // to the original mode.\r
+ //\r
+ if (CpuMpData->ApLoopMode != ApInHltLoop) {\r
+ CpuMpData->WakeUpByInitSipiSipi = TRUE;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
\r
/**\r
Enable Debug Agent to support source debugging on AP function.\r
IN CPU_MP_DATA *CpuMpData\r
)\r
{\r
+ EFI_STATUS Status;\r
+\r
SaveCpuMpData (CpuMpData);\r
+\r
+ ///\r
+ /// Install Notify\r
+ ///\r
+ Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc);\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
\r
/**\r