UefiCpuPkg/CpuMpPei: Implementation of PeiStartupThisAP ()

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18009 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Jeff Fan 2015-07-15 03:43:34 +00:00 committed by vanjeff
parent 60ca9e8c18
commit d11bbfff1f
2 changed files with 178 additions and 0 deletions

View File

@ -497,6 +497,127 @@ PeiStartupAllAPs (
return Status; return Status;
} }
/**
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 An indirect pointer to the PEI Services Table
published by the PEI Foundation.
@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.
@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] TimeoutInMicroseconds
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 This return the handle number for the calling processor. This service may be
called from the BSP and APs. called from the BSP and APs.

View File

@ -172,6 +172,63 @@ PeiStartupAllAPs (
IN VOID *ProcedureArgument OPTIONAL 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 An indirect pointer to the PEI Services Table
published by the PEI Foundation.
@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.
@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] TimeoutInMicroseconds
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 This return the handle number for the calling processor. This service may be