Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff....@intel.com>
CC: Feng Tian <feng.t...@intel.com>
CC: Jiewen Yao <jiewen....@intel.com>
CC: Michael Kinney <michael.d.kin...@intel.com>
---
 UefiCpuPkg/CpuMpPei/PeiMpServices.c | 126 ++++++++++++++++++++++++++++++++++++
 UefiCpuPkg/CpuMpPei/PeiMpServices.h |  62 ++++++++++++++++++
 2 files changed, 188 insertions(+)

diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.c 
b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
index 50145b3..bf10a48 100644
--- a/UefiCpuPkg/CpuMpPei/PeiMpServices.c
+++ b/UefiCpuPkg/CpuMpPei/PeiMpServices.c
@@ -507,6 +507,132 @@ PeiStartupAllAPs (
 }
 
 /**
+  This service lets the caller get one enabled AP to execute a caller-provided
+  function. The caller can request the BSP to wait for the completion
+  of the AP. This service may only be called from the BSP.
+
+  This function is used to dispatch one enabled AP to the function specified by
+  Procedure passing in the argument specified by ProcedureArgument.
+  The execution is in blocking mode. The BSP waits until the AP finishes or
+  TimeoutInMicroSecondss expires.
+
+  If the timeout specified by TimeoutInMicroseconds expires before the AP 
returns
+  from Procedure, then execution of Procedure by the AP is terminated. The AP 
is
+  available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and
+  EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
+
+  @param[in]  PeiServices             General purpose services available to 
every PEIM.
+  @param[in]  This                    A pointer to the EFI_PEI_MP_SERVICES_PPI
+                                      instance.
+  @param[in]  Procedure               A pointer to the function to be run on
+                                      enabled APs of the system. See type
+                                      EFI_AP_PROCEDURE.
+  @param[in]  ProcessorNumber         The handle number of the AP. The range is
+                                      from 0 to the total number of logical
+                                      processors minus 1. The total number of
+                                      logical processors can be retrieved by
+                                      
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+  @param[in]  TimeoutInMicrosecsond   Indicates the time limit in microseconds 
for
+                                      APs to return from Procedure, for
+                                      blocking mode only. Zero means
+                                      infinity.  If the timeout expires before
+                                      all APs return from Procedure, then 
Procedure
+                                      on the failed APs is terminated. All 
enabled
+                                      APs are available for next function 
assigned
+                                      by 
EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+                                      or 
EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
+                                      If the timeout expires in blocking mode,
+                                      BSP returns EFI_TIMEOUT.
+  @param[in]  ProcedureArgument       The parameter passed into Procedure for
+                                      all APs.
+
+  @retval EFI_SUCCESS             In blocking mode, specified AP finished 
before
+                                  the timeout expires.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_TIMEOUT             In blocking mode, the timeout expired before
+                                  the specified AP has finished.
+  @retval EFI_NOT_FOUND           The processor with the handle specified by
+                                  ProcessorNumber does not exist.
+  @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP or 
disabled AP.
+  @retval EFI_INVALID_PARAMETER   Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiStartupThisAP (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices,
+  IN  EFI_PEI_MP_SERVICES_PPI   *This,
+  IN  EFI_AP_PROCEDURE          Procedure,
+  IN  UINTN                     ProcessorNumber,
+  IN  UINTN                     TimeoutInMicroseconds,
+  IN  VOID                      *ProcedureArgument      OPTIONAL
+  )
+{
+  PEI_CPU_MP_DATA         *PeiCpuMpData;
+  UINTN                   CallerNumber;
+  volatile UINT32         *FinishedCount;
+  EFI_STATUS              Status;
+  UINTN                   WaitCountIndex;
+  UINTN                   WaitCountNumber;
+
+  PeiCpuMpData = GetMpHobData ();
+  if (PeiCpuMpData == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Check whether caller processor is BSP
+  //
+  PeiWhoAmI (PeiServices, This, &CallerNumber);
+  if (CallerNumber != PeiCpuMpData->BspNumber) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (ProcessorNumber >= PeiCpuMpData->CpuCount) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (ProcessorNumber == PeiCpuMpData->BspNumber || Procedure == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check whether specified AP is disabled
+  //
+  if (PeiCpuMpData->CpuData[ProcessorNumber].State == CpuStateDisabled) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  WaitCountNumber = TimeoutInMicroseconds / CPU_CHECK_AP_INTERVAL + 1;
+  WaitCountIndex = 0;
+  FinishedCount = &PeiCpuMpData->FinishedCount;
+
+  WakeUpAP (PeiCpuMpData, FALSE, 
PeiCpuMpData->CpuData[ProcessorNumber].ApicId, Procedure, ProcedureArgument);
+
+  //
+  // Wait to finish
+  //
+  if (TimeoutInMicroseconds == 0) {
+    while (*FinishedCount < 1) {
+      CpuPause() ;
+    }
+    Status = EFI_SUCCESS;
+  } else {
+    Status = EFI_TIMEOUT;
+    for (WaitCountIndex = 0; WaitCountIndex < WaitCountNumber; 
WaitCountIndex++) {
+      MicroSecondDelay (CPU_CHECK_AP_INTERVAL);
+      if (*FinishedCount >= 1) {
+        Status = EFI_SUCCESS;
+        break;
+      }
+    }
+  }
+
+  return Status;
+}
+
+
+/**
   This return the handle number for the calling processor.  This service may be
   called from the BSP and APs.
 
diff --git a/UefiCpuPkg/CpuMpPei/PeiMpServices.h 
b/UefiCpuPkg/CpuMpPei/PeiMpServices.h
index 71f5a04..cafa783 100644
--- a/UefiCpuPkg/CpuMpPei/PeiMpServices.h
+++ b/UefiCpuPkg/CpuMpPei/PeiMpServices.h
@@ -181,6 +181,68 @@ PeiStartupAllAPs (
   IN  VOID                      *ProcedureArgument      OPTIONAL
   );
 
+/**
+  This service lets the caller get one enabled AP to execute a caller-provided
+  function. The caller can request the BSP to wait for the completion
+  of the AP. This service may only be called from the BSP.
+
+  This function is used to dispatch one enabled AP to the function specified by
+  Procedure passing in the argument specified by ProcedureArgument.
+  The execution is in blocking mode. The BSP waits until the AP finishes or
+  TimeoutInMicroSecondss expires.
+
+  If the timeout specified by TimeoutInMicroseconds expires before the AP 
returns
+  from Procedure, then execution of Procedure by the AP is terminated. The AP 
is
+  available for subsequent calls to EFI_PEI_MP_SERVICES_PPI.StartupAllAPs() and
+  EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
+
+  @param[in]  PeiServices             General purpose services available to 
every PEIM.
+  @param[in]  This                    A pointer to the EFI_PEI_MP_SERVICES_PPI
+                                      instance.
+  @param[in]  Procedure               A pointer to the function to be run on
+                                      enabled APs of the system. See type
+                                      EFI_AP_PROCEDURE.
+  @param[in]  ProcessorNumber         The handle number of the AP. The range is
+                                      from 0 to the total number of logical
+                                      processors minus 1. The total number of
+                                      logical processors can be retrieved by
+                                      
EFI_PEI_MP_SERVICES_PPI.GetNumberOfProcessors().
+  @param[in]  TimeoutInMicrosecsond   Indicates the time limit in microseconds 
for
+                                      APs to return from Procedure, for
+                                      blocking mode only. Zero means
+                                      infinity.  If the timeout expires before
+                                      all APs return from Procedure, then 
Procedure
+                                      on the failed APs is terminated. All 
enabled
+                                      APs are available for next function 
assigned
+                                      by 
EFI_PEI_MP_SERVICES_PPI.StartupAllAPs()
+                                      or 
EFI_PEI_MP_SERVICES_PPI.StartupThisAP().
+                                      If the timeout expires in blocking mode,
+                                      BSP returns EFI_TIMEOUT.
+  @param[in]  ProcedureArgument       The parameter passed into Procedure for
+                                      all APs.
+
+  @retval EFI_SUCCESS             In blocking mode, specified AP finished 
before
+                                  the timeout expires.
+  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
+  @retval EFI_TIMEOUT             In blocking mode, the timeout expired before
+                                  the specified AP has finished.
+  @retval EFI_NOT_FOUND           The processor with the handle specified by
+                                  ProcessorNumber does not exist.
+  @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP or 
disabled AP.
+  @retval EFI_INVALID_PARAMETER   Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+PeiStartupThisAP (
+  IN  CONST EFI_PEI_SERVICES    **PeiServices,
+  IN  EFI_PEI_MP_SERVICES_PPI       *This,
+  IN  EFI_AP_PROCEDURE          Procedure,
+  IN  UINTN                     ProcessorNumber,
+  IN  UINTN                     TimeoutInMicroseconds,
+  IN  VOID                      *ProcedureArgument      OPTIONAL
+  );
+
 
 /**
   This return the handle number for the calling processor.  This service may be
-- 
1.9.5.msysgit.0


------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to