]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/MpLib.h
UefiCpuPkg/MpInitLib: Fix X64 XCODE5/NASM compatibility issues
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / MpLib.h
index 0453c22d5cf5eb02663fe71b0dab74c35012cf40..ea56412cbce04adb575786e214165032f4ddbf67 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Common header file for MP Initialize Library.\r
 \r
-  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #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
+//\r
+typedef enum {\r
+  ApInHltLoop   = 1,\r
+  ApInMwaitLoop = 2,\r
+  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
+// It is natural aligned by design.\r
+//\r
+typedef struct {\r
+  UINT8             *RendezvousFunnelAddress;\r
+  UINTN             ModeEntryOffset;\r
+  UINTN             RendezvousFunnelSize;\r
+  UINT8             *RelocateApLoopFuncAddress;\r
+  UINTN             RelocateApLoopFuncSize;\r
+} MP_ASSEMBLY_ADDRESS_MAP;\r
+\r
+typedef struct _CPU_MP_DATA  CPU_MP_DATA;\r
 \r
 #pragma pack(1)\r
 \r
@@ -55,10 +172,404 @@ typedef struct {
   UINTN                 NumApsExecuting;\r
   UINTN                 CodeSegment;\r
   UINTN                 DataSegment;\r
+  UINTN                 EnableExecuteDisable;\r
   UINTN                 Cr3;\r
-  PEI_CPU_MP_DATA       *PeiCpuMpData;\r
+  UINTN                 InitFlag;\r
+  CPU_INFO_IN_HOB       *CpuInfo;\r
+  CPU_MP_DATA           *CpuMpData;\r
+  UINTN                 InitializeFloatingPointUnitsAddress;\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
+  UINT32                         CurrentTimerCount;\r
+  UINTN                          DivideValue;\r
+  UINT8                          Vector;\r
+  BOOLEAN                        PeriodicMode;\r
+  BOOLEAN                        TimerInterruptState;\r
+};\r
+\r
+extern EFI_GUID mCpuInitMpLibHobGuid;\r
+\r
+/**\r
+  Assembly code to place AP into safe loop mode.\r
+\r
+  Place AP into targeted C-State if MONITOR is supported, otherwise\r
+  place AP into hlt state.\r
+  Place AP in protected mode if the current is long mode. Due to AP maybe\r
+  wakeup by some hardware event. It could avoid accessing page table that\r
+  may not available during booting to OS.\r
+\r
+  @param[in] MwaitSupport    TRUE indicates MONITOR is supported.\r
+                             FALSE indicates MONITOR is not supported.\r
+  @param[in] ApTargetCState  Target C-State value.\r
+  @param[in] PmCodeSegment   Protected mode code segment value.\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI * ASM_RELOCATE_AP_LOOP) (\r
+  IN BOOLEAN                 MwaitSupport,\r
+  IN UINTN                   ApTargetCState,\r
+  IN UINTN                   PmCodeSegment,\r
+  IN UINTN                   TopOfApStack,\r
+  IN UINTN                   NumberToFinish\r
+  );\r
+\r
+/**\r
+  Assembly code to get starting address and size of the rendezvous entry for APs.\r
+  Information for fixing a jump instruction in the code is also returned.\r
+\r
+  @param[out] AddressMap  Output buffer for address map information.\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmGetAddressMap (\r
+  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
+  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
+/**\r
+  Enable Debug Agent to support source debugging on AP function.\r
+\r
+**/\r
+VOID\r
+EnableDebugAgent (\r
+  VOID\r
+  );\r
+\r
 #endif\r
 \r