]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/MpLib.h
UefiCpuPkg: Make the comments align with the functions
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.h
index 317facc80ce83132815a61af3a11ebd489a39f50..9861a5c859300a88b891621026ee202d92f01765 100644 (file)
 #include <Library/MtrrLib.h>\r
 #include <Library/HobLib.h>\r
 \r
+#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')\r
+\r
+#define CPU_INIT_MP_LIB_HOB_GUID \\r
+  { \\r
+    0x58eb6a19, 0x3699, 0x4c68, { 0xa8, 0x36, 0xda, 0xcd, 0x8e, 0xdc, 0xad, 0x4a } \\r
+  }\r
+\r
+//\r
+//  The MP data for switch BSP\r
+//\r
+#define CPU_SWITCH_STATE_IDLE   0\r
+#define CPU_SWITCH_STATE_STORED 1\r
+#define CPU_SWITCH_STATE_LOADED 2\r
+\r
+//\r
+// CPU exchange information for switch BSP\r
+//\r
+typedef struct {\r
+  UINT8             State;        // offset 0\r
+  UINTN             StackPointer; // offset 4 / 8\r
+  IA32_DESCRIPTOR   Gdtr;         // offset 8 / 16\r
+  IA32_DESCRIPTOR   Idtr;         // offset 14 / 26\r
+} CPU_EXCHANGE_ROLE_INFO;\r
+\r
 //\r
 // AP loop state when APs are in idle state\r
 // It's value is the same with PcdCpuApLoopMode\r
@@ -45,6 +69,75 @@ typedef enum {
   ApInRunLoop   = 3\r
 } AP_LOOP_MODE;\r
 \r
+//\r
+// AP initialization state during APs wakeup\r
+//\r
+typedef enum {\r
+  ApInitConfig   = 1,\r
+  ApInitReconfig = 2,\r
+  ApInitDone     = 3\r
+} AP_INIT_STATE;\r
+\r
+//\r
+// AP state\r
+//\r
+typedef enum {\r
+  CpuStateIdle,\r
+  CpuStateReady,\r
+  CpuStateBusy,\r
+  CpuStateFinished,\r
+  CpuStateDisabled\r
+} CPU_STATE;\r
+\r
+//\r
+// CPU volatile registers around INIT-SIPI-SIPI\r
+//\r
+typedef struct {\r
+  UINTN                          Cr0;\r
+  UINTN                          Cr3;\r
+  UINTN                          Cr4;\r
+  UINTN                          Dr0;\r
+  UINTN                          Dr1;\r
+  UINTN                          Dr2;\r
+  UINTN                          Dr3;\r
+  UINTN                          Dr6;\r
+  UINTN                          Dr7;\r
+} CPU_VOLATILE_REGISTERS;\r
+\r
+//\r
+// AP related data\r
+//\r
+typedef struct {\r
+  SPIN_LOCK                      ApLock;\r
+  volatile UINT32                *StartupApSignal;\r
+  volatile UINTN                 ApFunction;\r
+  volatile UINTN                 ApFunctionArgument;\r
+  BOOLEAN                        CpuHealthy;\r
+  volatile CPU_STATE             State;\r
+  CPU_VOLATILE_REGISTERS         VolatileRegisters;\r
+  BOOLEAN                        Waiting;\r
+  BOOLEAN                        *Finished;\r
+  UINT64                         ExpectedTime;\r
+  UINT64                         CurrentTime;\r
+  UINT64                         TotalTime;\r
+  EFI_EVENT                      WaitEvent;\r
+} CPU_AP_DATA;\r
+\r
+//\r
+// Basic CPU information saved in Guided HOB.\r
+// Because the contents will be shard between PEI and DXE,\r
+// we need to make sure the each fields offset same in different\r
+// architecture.\r
+//\r
+#pragma pack (1)\r
+typedef struct {\r
+  UINT32                         InitialApicId;\r
+  UINT32                         ApicId;\r
+  UINT32                         Health;\r
+  UINT64                         ApTopOfStack;\r
+} CPU_INFO_IN_HOB;\r
+#pragma pack ()\r
+\r
 //\r
 // AP reset code information including code address and size,\r
 // this structure will be shared be C code and assembly code.\r
@@ -58,6 +151,8 @@ typedef struct {
   UINTN             RelocateApLoopFuncSize;\r
 } MP_ASSEMBLY_ADDRESS_MAP;\r
 \r
+typedef struct _CPU_MP_DATA  CPU_MP_DATA;\r
+\r
 #pragma pack(1)\r
 \r
 //\r
@@ -79,9 +174,63 @@ typedef struct {
   UINTN                 DataSegment;\r
   UINTN                 EnableExecuteDisable;\r
   UINTN                 Cr3;\r
+  UINTN                 InitFlag;\r
+  CPU_INFO_IN_HOB       *CpuInfo;\r
+  CPU_MP_DATA           *CpuMpData;\r
 } MP_CPU_EXCHANGE_INFO;\r
 \r
 #pragma pack()\r
+\r
+//\r
+// CPU MP Data save in memory\r
+//\r
+struct _CPU_MP_DATA {\r
+  UINT64                         CpuInfoInHob;\r
+  UINT32                         CpuCount;\r
+  UINT32                         BspNumber;\r
+  //\r
+  // The above fields data will be passed from PEI to DXE\r
+  // Please make sure the fields offset same in the different\r
+  // architecture.\r
+  //\r
+  SPIN_LOCK                      MpLock;\r
+  UINTN                          Buffer;\r
+  UINTN                          CpuApStackSize;\r
+  MP_ASSEMBLY_ADDRESS_MAP        AddressMap;\r
+  UINTN                          WakeupBuffer;\r
+  UINTN                          BackupBuffer;\r
+  UINTN                          BackupBufferSize;\r
+  BOOLEAN                        SaveRestoreFlag;\r
+\r
+  volatile UINT32                StartCount;\r
+  volatile UINT32                FinishedCount;\r
+  volatile UINT32                RunningCount;\r
+  BOOLEAN                        SingleThread;\r
+  EFI_AP_PROCEDURE               Procedure;\r
+  VOID                           *ProcArguments;\r
+  BOOLEAN                        *Finished;\r
+  UINT64                         ExpectedTime;\r
+  UINT64                         CurrentTime;\r
+  UINT64                         TotalTime;\r
+  EFI_EVENT                      WaitEvent;\r
+  UINTN                          **FailedCpuList;\r
+\r
+  AP_INIT_STATE                  InitFlag;\r
+  BOOLEAN                        X2ApicEnable;\r
+  BOOLEAN                        SwitchBspFlag;\r
+  UINTN                          NewBspNumber;\r
+  CPU_EXCHANGE_ROLE_INFO         BSPInfo;\r
+  CPU_EXCHANGE_ROLE_INFO         APInfo;\r
+  MTRR_SETTINGS                  MtrrTable;\r
+  UINT8                          ApLoopMode;\r
+  UINT8                          ApTargetCState;\r
+  UINT16                         PmCodeSegment;\r
+  CPU_AP_DATA                    *CpuData;\r
+  volatile MP_CPU_EXCHANGE_INFO  *MpCpuExchangeInfo;\r
+};\r
+\r
+extern EFI_GUID mCpuInitMpLibHobGuid;\r
+\r
 /**\r
   Assembly code to place AP into safe loop mode.\r
 \r
@@ -101,7 +250,9 @@ VOID
 (EFIAPI * ASM_RELOCATE_AP_LOOP) (\r
   IN BOOLEAN                 MwaitSupport,\r
   IN UINTN                   ApTargetCState,\r
-  IN UINTN                   PmCodeSegment\r
+  IN UINTN                   PmCodeSegment,\r
+  IN UINTN                   TopOfApStack,\r
+  IN UINTN                   NumberToFinish\r
   );\r
 \r
 /**\r
@@ -116,5 +267,313 @@ AsmGetAddressMap (
   OUT MP_ASSEMBLY_ADDRESS_MAP    *AddressMap\r
   );\r
 \r
+/**\r
+  This function is called by both the BSP and the AP which is to become the BSP to\r
+  Exchange execution context including stack between them. After return from this\r
+  function, the BSP becomes AP and the AP becomes the BSP.\r
+\r
+  @param[in] MyInfo      Pointer to buffer holding the exchanging information for the executing processor.\r
+  @param[in] OthersInfo  Pointer to buffer holding the exchanging information for the peer.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmExchangeRole (\r
+  IN CPU_EXCHANGE_ROLE_INFO    *MyInfo,\r
+  IN CPU_EXCHANGE_ROLE_INFO    *OthersInfo\r
+  );\r
+\r
+/**\r
+  Get the pointer to CPU MP Data structure.\r
+\r
+  @return  The pointer to CPU MP Data structure.\r
+**/\r
+CPU_MP_DATA *\r
+GetCpuMpData (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Save the pointer to CPU MP Data structure.\r
+\r
+  @param[in] CpuMpData  The pointer to CPU MP Data structure will be saved.\r
+**/\r
+VOID\r
+SaveCpuMpData (\r
+  IN CPU_MP_DATA   *CpuMpData\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
+/**\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
+/**\r
+  This function will be called by BSP to wakeup AP.\r
+\r
+  @param[in] CpuMpData          Pointer to CPU MP Data\r
+  @param[in] Broadcast          TRUE:  Send broadcast IPI to all APs\r
+                                FALSE: Send IPI to AP by ApicId\r
+  @param[in] ProcessorNumber    The handle number of specified processor\r
+  @param[in] Procedure          The function to be invoked by AP\r
+  @param[in] ProcedureArgument  The argument to be passed into AP function\r
+**/\r
+VOID\r
+WakeUpAP (\r
+  IN CPU_MP_DATA               *CpuMpData,\r
+  IN BOOLEAN                   Broadcast,\r
+  IN UINTN                     ProcessorNumber,\r
+  IN EFI_AP_PROCEDURE          Procedure,              OPTIONAL\r
+  IN VOID                      *ProcedureArgument      OPTIONAL\r
+  );\r
+\r
+/**\r
+  Initialize global data for MP support.\r
+\r
+  @param[in] CpuMpData  The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+InitMpGlobalData (\r
+  IN CPU_MP_DATA               *CpuMpData\r
+  );\r
+\r
+/**\r
+  Worker function to execute a caller provided function on all enabled APs.\r
+\r
+  @param[in]  Procedure               A pointer to the function to be run on\r
+                                      enabled APs of the system.\r
+  @param[in]  SingleThread            If TRUE, then all the enabled APs execute\r
+                                      the function specified by Procedure one by\r
+                                      one, in ascending order of processor handle\r
+                                      number.  If FALSE, then all the enabled APs\r
+                                      execute the function specified by Procedure\r
+                                      simultaneously.\r
+  @param[in]  WaitEvent               The event created by the caller with CreateEvent()\r
+                                      service.\r
+  @param[in]  TimeoutInMicroseconds   Indicates the time limit in microseconds for\r
+                                      APs to return from Procedure, either for\r
+                                      blocking or non-blocking mode.\r
+  @param[in]  ProcedureArgument       The parameter passed into Procedure for\r
+                                      all APs.\r
+  @param[out] FailedCpuList           If all APs finish successfully, then its\r
+                                      content is set to NULL. If not all APs\r
+                                      finish before timeout expires, then its\r
+                                      content is set to address of the buffer\r
+                                      holding handle numbers of the failed APs.\r
+\r
+  @retval EFI_SUCCESS             In blocking mode, all APs have finished before\r
+                                  the timeout expired.\r
+  @retval EFI_SUCCESS             In non-blocking mode, function has been dispatched\r
+                                  to all enabled APs.\r
+  @retval others                  Failed to Startup all APs.\r
+\r
+**/\r
+EFI_STATUS\r
+StartupAllAPsWorker (\r
+  IN  EFI_AP_PROCEDURE          Procedure,\r
+  IN  BOOLEAN                   SingleThread,\r
+  IN  EFI_EVENT                 WaitEvent               OPTIONAL,\r
+  IN  UINTN                     TimeoutInMicroseconds,\r
+  IN  VOID                      *ProcedureArgument      OPTIONAL,\r
+  OUT UINTN                     **FailedCpuList         OPTIONAL\r
+  );\r
+\r
+/**\r
+  Worker function to let the caller get one enabled AP to execute a caller-provided\r
+  function.\r
+\r
+  @param[in]  Procedure               A pointer to the function to be run on\r
+                                      enabled APs of the system.\r
+  @param[in]  ProcessorNumber         The handle number of the AP.\r
+  @param[in]  WaitEvent               The event created by the caller with CreateEvent()\r
+                                      service.\r
+  @param[in]  TimeoutInMicroseconds   Indicates the time limit in microseconds for\r
+                                      APs to return from Procedure, either for\r
+                                      blocking or non-blocking mode.\r
+  @param[in]  ProcedureArgument       The parameter passed into Procedure for\r
+                                      all APs.\r
+  @param[out] Finished                If AP returns from Procedure before the\r
+                                      timeout expires, its content is set to TRUE.\r
+                                      Otherwise, the value is set to FALSE.\r
+\r
+  @retval EFI_SUCCESS             In blocking mode, specified AP finished before\r
+                                  the timeout expires.\r
+  @retval others                  Failed to Startup AP.\r
+\r
+**/\r
+EFI_STATUS\r
+StartupThisAPWorker (\r
+  IN  EFI_AP_PROCEDURE          Procedure,\r
+  IN  UINTN                     ProcessorNumber,\r
+  IN  EFI_EVENT                 WaitEvent               OPTIONAL,\r
+  IN  UINTN                     TimeoutInMicroseconds,\r
+  IN  VOID                      *ProcedureArgument      OPTIONAL,\r
+  OUT BOOLEAN                   *Finished               OPTIONAL\r
+  );\r
+\r
+/**\r
+  Worker function to switch the requested AP to be the BSP from that point onward.\r
+\r
+  @param[in] ProcessorNumber   The handle number of AP that is to become the new BSP.\r
+  @param[in] EnableOldBSP      If TRUE, then the old BSP will be listed as an\r
+                               enabled AP. Otherwise, it will be disabled.\r
+\r
+  @retval EFI_SUCCESS          BSP successfully switched.\r
+  @retval others               Failed to switch BSP. \r
+\r
+**/\r
+EFI_STATUS\r
+SwitchBSPWorker (\r
+  IN UINTN                     ProcessorNumber,\r
+  IN BOOLEAN                   EnableOldBSP\r
+  );\r
+\r
+/**\r
+  Worker function to let the caller enable or disable an AP from this point onward.\r
+  This service may only be called from the BSP.\r
+\r
+  @param[in] ProcessorNumber   The handle number of AP.\r
+  @param[in] EnableAP          Specifies the new state for the processor for\r
+                               enabled, FALSE for disabled.\r
+  @param[in] HealthFlag        If not NULL, a pointer to a value that specifies\r
+                               the new health status of the AP.\r
+\r
+  @retval EFI_SUCCESS          The specified AP was enabled or disabled successfully.\r
+  @retval others               Failed to Enable/Disable AP.\r
+\r
+**/\r
+EFI_STATUS\r
+EnableDisableApWorker (\r
+  IN  UINTN                     ProcessorNumber,\r
+  IN  BOOLEAN                   EnableAP,\r
+  IN  UINT32                    *HealthFlag OPTIONAL\r
+  );\r
+\r
+/**\r
+  Get pointer to CPU MP Data structure from GUIDed HOB.\r
+\r
+  @return  The pointer to CPU MP Data structure.\r
+**/\r
+CPU_MP_DATA *\r
+GetCpuMpDataFromGuidedHob (\r
+  VOID\r
+  );\r
+\r
+/** Checks status of specified AP.\r
+\r
+  This function checks whether the specified AP has finished the task assigned\r
+  by StartupThisAP(), and whether timeout expires.\r
+\r
+  @param[in]  ProcessorNumber       The handle number of processor.\r
+\r
+  @retval EFI_SUCCESS           Specified AP has finished task assigned by StartupThisAPs().\r
+  @retval EFI_TIMEOUT           The timeout expires.\r
+  @retval EFI_NOT_READY         Specified AP has not finished task and timeout has not expired.\r
+**/\r
+EFI_STATUS\r
+CheckThisAP (\r
+  IN UINTN        ProcessorNumber\r
+  );\r
+\r
+/**\r
+  Checks status of all APs.\r
+\r
+  This function checks whether all APs have finished task assigned by StartupAllAPs(),\r
+  and whether timeout expires.\r
+\r
+  @retval EFI_SUCCESS           All APs have finished task assigned by StartupAllAPs().\r
+  @retval EFI_TIMEOUT           The timeout expires.\r
+  @retval EFI_NOT_READY         APs have not finished task and timeout has not expired.\r
+**/\r
+EFI_STATUS\r
+CheckAllAPs (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Checks APs status and updates APs status if needed.\r
+\r
+**/\r
+VOID\r
+CheckAndUpdateApsStatus (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Detect whether specified processor can find matching microcode patch and load it.\r
+\r
+  @param[in]  CpuMpData  The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+MicrocodeDetect (\r
+  IN CPU_MP_DATA             *CpuMpData\r
+  );\r
+\r
+/**\r
+  Detect whether Mwait-monitor feature is supported.\r
+\r
+  @retval TRUE    Mwait-monitor feature is supported.\r
+  @retval FALSE   Mwait-monitor feature is not supported.\r
+**/\r
+BOOLEAN\r
+IsMwaitSupport (\r
+  VOID\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
+/**\r
+  Get available system memory below 1MB by specified size.\r
+\r
+  @param[in]  CpuMpData  The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+BackupAndPrepareWakeupBuffer(\r
+  IN CPU_MP_DATA              *CpuMpData\r
+  );\r
+\r
+/**\r
+  Restore wakeup buffer data.\r
+\r
+  @param[in]  CpuMpData  The pointer to CPU MP Data structure.\r
+**/\r
+VOID\r
+RestoreWakeupBuffer(\r
+  IN CPU_MP_DATA              *CpuMpData\r
+  );\r
+\r
 #endif\r
 \r