]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/CpuMpPei/PeiMpServices.c
UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / PeiMpServices.c
index e06fdf14fad5b1dfa0f0d22ac121cb5a9480d81f..44e8f211c7498a5e4171cd54b8c810bb22ba1bde 100644 (file)
@@ -33,12 +33,14 @@ EFI_PEI_PPI_DESCRIPTOR           mPeiCpuMpPpiDesc = {
   &mMpServicesPpi\r
 };\r
 \r
+\r
 /**\r
   Get CPU Package/Core/Thread location information.\r
 \r
   @param InitialApicId     CPU APIC ID\r
   @param Location          Pointer to CPU location information\r
 **/\r
+STATIC\r
 VOID\r
 ExtractProcessorLocation (\r
   IN  UINT32                     InitialApicId,\r
@@ -143,34 +145,6 @@ ExtractProcessorLocation (
   Location->Package = (InitialApicId >> (ThreadBits + CoreBits));\r
 }\r
 \r
-/**\r
-  Find the current Processor number by APIC ID.\r
-\r
-  @param PeiCpuMpData        Pointer to PEI CPU MP Data\r
-  @param ProcessorNumber     Return the pocessor number found\r
-\r
-  @retval EFI_SUCCESS        ProcessorNumber is found and returned.\r
-  @retval EFI_NOT_FOUND      ProcessorNumber is not found.\r
-**/\r
-EFI_STATUS\r
-GetProcessorNumber (\r
-  IN PEI_CPU_MP_DATA         *PeiCpuMpData,\r
-  OUT UINTN                  *ProcessorNumber\r
-  )\r
-{\r
-  UINTN                   TotalProcessorNumber;\r
-  UINTN                   Index;\r
-\r
-  TotalProcessorNumber = PeiCpuMpData->CpuCount;\r
-  for (Index = 0; Index < TotalProcessorNumber; Index ++) {\r
-    if (PeiCpuMpData->CpuData[Index].ApicId == GetInitialApicId ()) {\r
-      *ProcessorNumber = Index;\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
 /**\r
   Worker function for SwitchBSP().\r
 \r
@@ -178,6 +152,7 @@ GetProcessorNumber (
 \r
   @param Buffer        Pointer to CPU MP Data\r
 **/\r
+STATIC\r
 VOID\r
 EFIAPI\r
 FutureBSPProc (\r
@@ -233,41 +208,14 @@ PeiGetNumberOfProcessors (
   OUT UINTN                     *NumberOfEnabledProcessors\r
   )\r
 {\r
-  PEI_CPU_MP_DATA         *PeiCpuMpData;\r
-  UINTN                   CallerNumber;\r
-  UINTN                   ProcessorNumber;\r
-  UINTN                   EnabledProcessorNumber;\r
-  UINTN                   Index;\r
-\r
-  PeiCpuMpData = GetMpHobData ();\r
-  if (PeiCpuMpData == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
   if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  //\r
-  // Check whether caller processor is BSP\r
-  //\r
-  PeiWhoAmI (PeiServices, This, &CallerNumber);\r
-  if (CallerNumber != PeiCpuMpData->BspNumber) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  ProcessorNumber        = PeiCpuMpData->CpuCount;\r
-  EnabledProcessorNumber = 0;\r
-  for (Index = 0; Index < ProcessorNumber; Index++) {\r
-    if (PeiCpuMpData->CpuData[Index].State != CpuStateDisabled) {\r
-      EnabledProcessorNumber ++;\r
-    }\r
-  }\r
-\r
-  *NumberOfProcessors = ProcessorNumber;\r
-  *NumberOfEnabledProcessors = EnabledProcessorNumber;\r
-\r
-  return EFI_SUCCESS;\r
+  return MpInitLibGetNumberOfProcessors (\r
+           NumberOfProcessors,\r
+           NumberOfEnabledProcessors\r
+           );\r
 }\r
 \r
 /**\r
@@ -305,50 +253,7 @@ PeiGetProcessorInfo (
   OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer\r
   )\r
 {\r
-  PEI_CPU_MP_DATA         *PeiCpuMpData;\r
-  UINTN                   CallerNumber;\r
-\r
-  PeiCpuMpData = GetMpHobData ();\r
-  if (PeiCpuMpData == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Check whether caller processor is BSP\r
-  //\r
-  PeiWhoAmI (PeiServices, This, &CallerNumber);\r
-  if (CallerNumber != PeiCpuMpData->BspNumber) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (ProcessorInfoBuffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (ProcessorNumber >= PeiCpuMpData->CpuCount) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  ProcessorInfoBuffer->ProcessorId = (UINT64) PeiCpuMpData->CpuData[ProcessorNumber].ApicId;\r
-  ProcessorInfoBuffer->StatusFlag  = 0;\r
-  if (PeiCpuMpData->CpuData[ProcessorNumber].ApicId == GetInitialApicId()) {\r
-    ProcessorInfoBuffer->StatusFlag |= PROCESSOR_AS_BSP_BIT;\r
-  }\r
-  if (PeiCpuMpData->CpuData[ProcessorNumber].CpuHealthy) {\r
-    ProcessorInfoBuffer->StatusFlag |= PROCESSOR_HEALTH_STATUS_BIT;\r
-  }\r
-  if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {\r
-    ProcessorInfoBuffer->StatusFlag &= ~PROCESSOR_ENABLED_BIT;\r
-  } else {\r
-    ProcessorInfoBuffer->StatusFlag |= PROCESSOR_ENABLED_BIT;\r
-  }\r
-\r
-  //\r
-  // Get processor location information\r
-  //\r
-  ExtractProcessorLocation (PeiCpuMpData->CpuData[ProcessorNumber].ApicId, &ProcessorInfoBuffer->Location);\r
-\r
-  return EFI_SUCCESS;\r
+  return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);\r
 }\r
 \r
 /**\r
@@ -425,131 +330,14 @@ PeiStartupAllAPs (
   IN  VOID                      *ProcedureArgument      OPTIONAL\r
   )\r
 {\r
-  PEI_CPU_MP_DATA         *PeiCpuMpData;\r
-  UINTN                   ProcessorNumber;\r
-  UINTN                   Index;\r
-  UINTN                   CallerNumber;\r
-  BOOLEAN                 HasEnabledAp;\r
-  BOOLEAN                 HasEnabledIdleAp;\r
-  volatile UINT32         *FinishedCount;\r
-  EFI_STATUS              Status;\r
-  UINTN                   WaitCountIndex;\r
-  UINTN                   WaitCountNumber;\r
-\r
-  PeiCpuMpData = GetMpHobData ();\r
-  if (PeiCpuMpData == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if (Procedure == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Check whether caller processor is BSP\r
-  //\r
-  PeiWhoAmI (PeiServices, This, &CallerNumber);\r
-  if (CallerNumber != PeiCpuMpData->BspNumber) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  ProcessorNumber = PeiCpuMpData->CpuCount;\r
-\r
-  HasEnabledAp     = FALSE;\r
-  HasEnabledIdleAp = FALSE;\r
-  for (Index = 0; Index < ProcessorNumber; Index ++) {\r
-    if (Index == CallerNumber) {\r
-      //\r
-      // Skip BSP\r
-      //\r
-      continue;\r
-    }\r
-    if (PeiCpuMpData->CpuData[Index].State != CpuStateDisabled) {\r
-      HasEnabledAp = TRUE;\r
-      if (PeiCpuMpData->CpuData[Index].State != CpuStateBusy) {\r
-        HasEnabledIdleAp = TRUE;\r
-      }\r
-    }\r
-  }\r
-  if (!HasEnabledAp) {\r
-    //\r
-    // If no enabled AP exists, return EFI_NOT_STARTED.\r
-    //\r
-    return EFI_NOT_STARTED;\r
-  }\r
-  if (!HasEnabledIdleAp) {\r
-    //\r
-    // If any enabled APs are busy, return EFI_NOT_READY.\r
-    //\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  if (PeiCpuMpData->EndOfPeiFlag) {\r
-    //\r
-    // Backup original data and copy AP reset vector in it\r
-    //\r
-    BackupAndPrepareWakeupBuffer(PeiCpuMpData);\r
-  }\r
-\r
-  WaitCountNumber = TimeoutInMicroSeconds / CPU_CHECK_AP_INTERVAL + 1;\r
-  WaitCountIndex = 0;\r
-  FinishedCount = &PeiCpuMpData->FinishedCount;\r
-  if (!SingleThread) {\r
-    WakeUpAP (PeiCpuMpData, TRUE, 0, Procedure, ProcedureArgument);\r
-    //\r
-    // Wait to finish\r
-    //\r
-    if (TimeoutInMicroSeconds == 0) {\r
-      while (*FinishedCount < ProcessorNumber - 1) {\r
-        CpuPause ();\r
-      }\r
-      Status = EFI_SUCCESS;\r
-    } else {\r
-      Status = EFI_TIMEOUT;\r
-      for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {\r
-        MicroSecondDelay (CPU_CHECK_AP_INTERVAL);\r
-        if (*FinishedCount >= ProcessorNumber - 1) {\r
-          Status = EFI_SUCCESS;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-  } else {\r
-    Status = EFI_SUCCESS;\r
-    for (Index = 0; Index < ProcessorNumber; Index++) {\r
-      if (Index == CallerNumber) {\r
-        continue;\r
-      }\r
-      WakeUpAP (PeiCpuMpData, FALSE, Index, Procedure, ProcedureArgument);\r
-      //\r
-      // Wait to finish\r
-      //\r
-      if (TimeoutInMicroSeconds == 0) {\r
-        while (*FinishedCount < 1) {\r
-          CpuPause ();\r
-        }\r
-      } else {\r
-        for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {\r
-          MicroSecondDelay (CPU_CHECK_AP_INTERVAL);\r
-          if (*FinishedCount >= 1) {\r
-            break;\r
-          }\r
-        }\r
-        if (WaitCountIndex == WaitCountNumber) {\r
-          Status = EFI_TIMEOUT;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (PeiCpuMpData->EndOfPeiFlag) {\r
-    //\r
-    // Restore original data\r
-    //\r
-    RestoreWakeupBuffer(PeiCpuMpData);\r
-  }\r
-\r
-  return Status;\r
+  return MpInitLibStartupAllAPs (\r
+           Procedure,\r
+           SingleThread,\r
+           NULL,\r
+           TimeoutInMicroSeconds,\r
+           ProcedureArgument,\r
+           NULL\r
+           );\r
 }\r
 \r
 /**\r
@@ -609,81 +397,14 @@ PeiStartupThisAP (
   IN  VOID                      *ProcedureArgument      OPTIONAL\r
   )\r
 {\r
-  PEI_CPU_MP_DATA         *PeiCpuMpData;\r
-  UINTN                   CallerNumber;\r
-  volatile UINT32         *FinishedCount;\r
-  EFI_STATUS              Status;\r
-  UINTN                   WaitCountIndex;\r
-  UINTN                   WaitCountNumber;\r
-\r
-  PeiCpuMpData = GetMpHobData ();\r
-  if (PeiCpuMpData == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Check whether caller processor is BSP\r
-  //\r
-  PeiWhoAmI (PeiServices, This, &CallerNumber);\r
-  if (CallerNumber != PeiCpuMpData->BspNumber) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (ProcessorNumber >= PeiCpuMpData->CpuCount) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if (ProcessorNumber == PeiCpuMpData->BspNumber || Procedure == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Check whether specified AP is disabled\r
-  //\r
-  if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (PeiCpuMpData->EndOfPeiFlag) {\r
-    //\r
-    // Backup original data and copy AP reset vector in it\r
-    //\r
-    BackupAndPrepareWakeupBuffer(PeiCpuMpData);\r
-  }\r
-\r
-  WaitCountNumber = TimeoutInMicroseconds / CPU_CHECK_AP_INTERVAL + 1;\r
-  WaitCountIndex = 0;\r
-  FinishedCount = &PeiCpuMpData->FinishedCount;\r
-\r
-  WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, Procedure, ProcedureArgument);\r
-\r
-  //\r
-  // Wait to finish\r
-  //\r
-  if (TimeoutInMicroseconds == 0) {\r
-    while (*FinishedCount < 1) {\r
-      CpuPause() ;\r
-    }\r
-    Status = EFI_SUCCESS;\r
-  } else {\r
-    Status = EFI_TIMEOUT;\r
-    for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; WaitCountIndex++) {\r
-      MicroSecondDelay (CPU_CHECK_AP_INTERVAL);\r
-      if (*FinishedCount >= 1) {\r
-        Status = EFI_SUCCESS;\r
-        break;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (PeiCpuMpData->EndOfPeiFlag) {\r
-    //\r
-    // Backup original data and copy AP reset vector in it\r
-    //\r
-    RestoreWakeupBuffer(PeiCpuMpData);\r
-  }\r
-\r
-  return Status;\r
+  return MpInitLibStartupThisAP (\r
+           Procedure,\r
+           ProcessorNumber,\r
+           NULL,\r
+           TimeoutInMicroseconds,\r
+           ProcedureArgument,\r
+           NULL\r
+           );\r
 }\r
 \r
 /**\r
@@ -729,97 +450,7 @@ PeiSwitchBSP (
   IN  BOOLEAN                  EnableOldBSP\r
   )\r
 {\r
-  PEI_CPU_MP_DATA              *PeiCpuMpData;\r
-  UINTN                        CallerNumber;\r
-  MSR_IA32_APIC_BASE_REGISTER  ApicBaseMsr;\r
-\r
-  PeiCpuMpData = GetMpHobData ();\r
-  if (PeiCpuMpData == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Check whether caller processor is BSP\r
-  //\r
-  PeiWhoAmI (PeiServices, This, &CallerNumber);\r
-  if (CallerNumber != PeiCpuMpData->BspNumber) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (ProcessorNumber >= PeiCpuMpData->CpuCount) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Check whether specified AP is disabled\r
-  //\r
-  if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Check whether ProcessorNumber specifies the current BSP\r
-  //\r
-  if (ProcessorNumber == PeiCpuMpData->BspNumber) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Check whether specified AP is busy\r
-  //\r
-  if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateBusy) {\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  //\r
-  // Clear the BSP bit of MSR_IA32_APIC_BASE\r
-  //\r
-  ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
-  ApicBaseMsr.Bits.BSP = 0;\r
-  AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
-\r
-  PeiCpuMpData->BSPInfo.State = CPU_SWITCH_STATE_IDLE;\r
-  PeiCpuMpData->APInfo.State  = CPU_SWITCH_STATE_IDLE;\r
-\r
-  if (PeiCpuMpData->EndOfPeiFlag) {\r
-    //\r
-    // Backup original data and copy AP reset vector in it\r
-    //\r
-    BackupAndPrepareWakeupBuffer(PeiCpuMpData);\r
-  }\r
-\r
-  //\r
-  // Need to wakeUp AP (future BSP).\r
-  //\r
-  WakeUpAP (PeiCpuMpData, FALSE, ProcessorNumber, FutureBSPProc, PeiCpuMpData);\r
-\r
-  AsmExchangeRole (&PeiCpuMpData->BSPInfo, &PeiCpuMpData->APInfo);\r
-\r
-  if (PeiCpuMpData->EndOfPeiFlag) {\r
-    //\r
-    // Backup original data and copy AP reset vector in it\r
-    //\r
-    RestoreWakeupBuffer(PeiCpuMpData);\r
-  }\r
-\r
-  //\r
-  // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP\r
-  //\r
-  ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
-  ApicBaseMsr.Bits.BSP = 1;\r
-  AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64);\r
-  //\r
-  // Set old BSP enable state\r
-  //\r
-  if (!EnableOldBSP) {\r
-    PeiCpuMpData->CpuData[PeiCpuMpData->BspNumber].State = CpuStateDisabled;\r
-  }\r
-  //\r
-  // Save new BSP number\r
-  //\r
-  PeiCpuMpData->BspNumber = (UINT32) ProcessorNumber;\r
-\r
-  return EFI_SUCCESS;\r
+  return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);\r
 }\r
 \r
 /**\r
@@ -871,41 +502,7 @@ PeiEnableDisableAP (
   IN  UINT32                    *HealthFlag OPTIONAL\r
   )\r
 {\r
-  PEI_CPU_MP_DATA         *PeiCpuMpData;\r
-  UINTN                   CallerNumber;\r
-\r
-  PeiCpuMpData = GetMpHobData ();\r
-  if (PeiCpuMpData == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Check whether caller processor is BSP\r
-  //\r
-  PeiWhoAmI (PeiServices, This, &CallerNumber);\r
-  if (CallerNumber != PeiCpuMpData->BspNumber) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (ProcessorNumber == PeiCpuMpData->BspNumber) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (ProcessorNumber >= PeiCpuMpData->CpuCount) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if (!EnableAP) {\r
-    PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateDisabled;\r
-  } else {\r
-    PeiCpuMpData->CpuData[ProcessorNumber].State = CpuStateIdle;\r
-  }\r
-\r
-  if (HealthFlag != NULL) {\r
-    PeiCpuMpData->CpuData[ProcessorNumber].CpuHealthy =\r
-          (BOOLEAN) ((*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT) != 0);\r
-  }\r
-  return EFI_SUCCESS;\r
+  return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);\r
 }\r
 \r
 /**\r
@@ -940,17 +537,5 @@ PeiWhoAmI (
   OUT UINTN                    *ProcessorNumber\r
   )\r
 {\r
-  PEI_CPU_MP_DATA         *PeiCpuMpData;\r
-\r
-  PeiCpuMpData = GetMpHobData ();\r
-  if (PeiCpuMpData == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  if (ProcessorNumber == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  return GetProcessorNumber (PeiCpuMpData, ProcessorNumber);\r
+  return MpInitLibWhoAmI (ProcessorNumber);\r
 }\r
-\r