/** @file
  Construct MP Services Protocol.

  The MP Services Protocol provides a generalized way of performing following tasks:
    - Retrieving information of multi-processor environment and MP-related status of
      specific processors.
    - Dispatching user-provided function to APs.
    - Maintain MP-related processor status.

  The MP Services Protocol must be produced on any system with more than one logical
  processor.

  The Protocol is available only during boot time.

  MP Services Protocol is hardware-independent. Most of the logic of this protocol
  is architecturally neutral. It abstracts the multi-processor environment and
  status of processors, and provides interfaces to retrieve information, maintain,
  and dispatch.

  MP Services Protocol may be consumed by ACPI module. The ACPI module may use this
  protocol to retrieve data that are needed for an MP platform and report them to OS.
  MP Services Protocol may also be used to program and configure processors, such
  as MTRR synchronization for memory space attributes setting in DXE Services.
  MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot
  by taking advantage of the processing capabilities of the APs, for example, using
  APs to help test system memory in parallel with other device initialization.
  Diagnostics applications may also use this protocol for multi-processor.

  Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiDxe.h>

#include <Library/ArmLib.h>
#include <Library/ArmMmuLib.h>
#include <Library/ArmPlatformLib.h>
#include <Library/ArmSmcLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/CpuExceptionHandlerLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <IndustryStandard/ArmStdSmc.h>
#include <Ppi/ArmMpCoreInfo.h>
#include <Protocol/LoadedImage.h>

#include "MpServicesInternal.h"

#define POLL_INTERVAL_US  50000

STATIC CPU_MP_DATA  mCpuMpData;
STATIC BOOLEAN      mNonBlockingModeAllowed;
UINT64              *gApStacksBase;
UINT64              *gProcessorIDs;
CONST UINT64        gApStackSize = AP_STACK_SIZE;
VOID                *gTtbr0;
UINTN               gTcr;
UINTN               gMair;

STATIC
BOOLEAN
IsCurrentProcessorBSP (
  VOID
  );

/** Turns on the specified core using PSCI and executes the user-supplied
    function that's been configured via a previous call to SetApProcedure.

    @param ProcessorIndex The index of the core to turn on.

    @retval EFI_SUCCESS      Success.
    @retval EFI_DEVICE_ERROR The processor could not be turned on.

**/
STATIC
EFI_STATUS
EFIAPI
DispatchCpu (
  IN UINTN  ProcessorIndex
  )
{
  ARM_SMC_ARGS  Args;
  EFI_STATUS    Status;

  Status = EFI_SUCCESS;

  mCpuMpData.CpuData[ProcessorIndex].State = CpuStateBusy;

  /* Turn the AP on */
  if (sizeof (Args.Arg0) == sizeof (UINT32)) {
    Args.Arg0 = ARM_SMC_ID_PSCI_CPU_ON_AARCH32;
  } else {
    Args.Arg0 = ARM_SMC_ID_PSCI_CPU_ON_AARCH64;
  }

  Args.Arg1 = gProcessorIDs[ProcessorIndex];
  Args.Arg2 = (UINTN)ApEntryPoint;

  ArmCallSmc (&Args);

  if (Args.Arg0 != ARM_SMC_PSCI_RET_SUCCESS) {
    DEBUG ((DEBUG_ERROR, "PSCI_CPU_ON call failed: %d\n", Args.Arg0));
    Status = EFI_DEVICE_ERROR;
  }

  return Status;
}

/** Returns whether the specified processor is the BSP.

  @param[in] ProcessorIndex The index the processor to check.

  @return TRUE if the processor is the BSP, FALSE otherwise.
**/
STATIC
BOOLEAN
IsProcessorBSP (
  UINTN  ProcessorIndex
  )
{
  EFI_PROCESSOR_INFORMATION  *CpuInfo;

  CpuInfo = &mCpuMpData.CpuData[ProcessorIndex].Info;

  return (CpuInfo->StatusFlag & PROCESSOR_AS_BSP_BIT) != 0;
}

/** Get the Application Processors state.

  @param[in]  CpuData    The pointer to CPU_AP_DATA of specified AP.

  @return The AP status.
**/
CPU_STATE
GetApState (
  IN  CPU_AP_DATA  *CpuData
  )
{
  return CpuData->State;
}

/** Configures the processor context with the user-supplied procedure and
    argument.

   @param CpuData           The processor context.
   @param Procedure         The user-supplied procedure.
   @param ProcedureArgument The user-supplied procedure argument.

**/
STATIC
VOID
SetApProcedure (
  IN   CPU_AP_DATA       *CpuData,
  IN   EFI_AP_PROCEDURE  Procedure,
  IN   VOID              *ProcedureArgument
  )
{
  ASSERT (CpuData != NULL);
  ASSERT (Procedure != NULL);

  CpuData->Parameter = ProcedureArgument;
  CpuData->Procedure = Procedure;
}

/** Returns the index of the next processor that is blocked.

   @param[out] NextNumber The index of the next blocked processor.

   @retval EFI_SUCCESS   Successfully found the next blocked processor.
   @retval EFI_NOT_FOUND There are no blocked processors.

**/
STATIC
EFI_STATUS
GetNextBlockedNumber (
  OUT UINTN  *NextNumber
  )
{
  UINTN        Index;
  CPU_STATE    State;
  CPU_AP_DATA  *CpuData;

  for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
    CpuData = &mCpuMpData.CpuData[Index];
    if (IsProcessorBSP (Index)) {
      // Skip BSP
      continue;
    }

    State = CpuData->State;

    if (State == CpuStateBlocked) {
      *NextNumber = Index;
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/** Stalls the BSP for the minimum of POLL_INTERVAL_US and Timeout.

   @param[in]  Timeout    The time limit in microseconds remaining for
                          APs to return from Procedure.

   @retval     StallTime  Time of execution stall.
**/
STATIC
UINTN
CalculateAndStallInterval (
  IN UINTN  Timeout
  )
{
  UINTN  StallTime;

  if ((Timeout < POLL_INTERVAL_US) && (Timeout != 0)) {
    StallTime = Timeout;
  } else {
    StallTime = POLL_INTERVAL_US;
  }

  gBS->Stall (StallTime);

  return StallTime;
}

/**
  This service retrieves the number of logical processor in the platform
  and the number of those logical processors that are enabled on this boot.
  This service may only be called from the BSP.

  This function is used to retrieve the following information:
    - The number of logical processors that are present in the system.
    - The number of enabled logical processors in the system at the instant
      this call is made.

  Because MP Service Protocol provides services to enable and disable processors
  dynamically, the number of enabled logical processors may vary during the
  course of a boot session.

  If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
  If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
  EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
  is returned in NumberOfProcessors, the number of currently enabled processor
  is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.

  @param[in]  This                        A pointer to the
                                          EFI_MP_SERVICES_PROTOCOL instance.
  @param[out] NumberOfProcessors          Pointer to the total number of logical
                                          processors in the system, including
                                          the BSP and disabled APs.
  @param[out] NumberOfEnabledProcessors   Pointer to the number of enabled
                                          logical processors that exist in the
                                          system, including the BSP.

  @retval EFI_SUCCESS             The number of logical processors and enabled
                                  logical processors was retrieved.
  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
  @retval EFI_INVALID_PARAMETER   NumberOfProcessors is NULL.
  @retval EFI_INVALID_PARAMETER   NumberOfEnabledProcessors is NULL.

**/
STATIC
EFI_STATUS
EFIAPI
GetNumberOfProcessors (
  IN  EFI_MP_SERVICES_PROTOCOL  *This,
  OUT UINTN                     *NumberOfProcessors,
  OUT UINTN                     *NumberOfEnabledProcessors
  )
{
  if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsCurrentProcessorBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  *NumberOfProcessors        = mCpuMpData.NumberOfProcessors;
  *NumberOfEnabledProcessors = mCpuMpData.NumberOfEnabledProcessors;
  return EFI_SUCCESS;
}

/**
  Gets detailed MP-related information on the requested processor at the
  instant this call is made. This service may only be called from the BSP.

  This service retrieves detailed MP-related information about any processor
  on the platform. Note the following:
    - The processor information may change during the course of a boot session.
    - The information presented here is entirely MP related.

  Information regarding the number of caches and their sizes, frequency of
  operation, slot numbers is all considered platform-related information and is
  not provided by this service.

  @param[in]  This                  A pointer to the EFI_MP_SERVICES_PROTOCOL
                                    instance.
  @param[in]  ProcessorIndex        The index of the processor.
  @param[out] ProcessorInfoBuffer   A pointer to the buffer where information
                                    for the requested processor is deposited.

  @retval EFI_SUCCESS             Processor information was returned.
  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
  @retval EFI_INVALID_PARAMETER   ProcessorInfoBuffer is NULL.
  @retval EFI_NOT_FOUND           The processor with the handle specified by
                                  ProcessorNumber does not exist in the platform.

**/
STATIC
EFI_STATUS
EFIAPI
GetProcessorInfo (
  IN  EFI_MP_SERVICES_PROTOCOL   *This,
  IN  UINTN                      ProcessorIndex,
  OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer
  )
{
  if (ProcessorInfoBuffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsCurrentProcessorBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  ProcessorIndex &= ~CPU_V2_EXTENDED_TOPOLOGY;

  if (ProcessorIndex >= mCpuMpData.NumberOfProcessors) {
    return EFI_NOT_FOUND;
  }

  CopyMem (
    ProcessorInfoBuffer,
    &mCpuMpData.CpuData[ProcessorIndex],
    sizeof (EFI_PROCESSOR_INFORMATION)
    );
  return EFI_SUCCESS;
}

/**
  This service executes a caller provided function on all enabled APs. APs can
  run either simultaneously or one at a time in sequence. This service supports
  both blocking and non-blocking requests. The non-blocking requests use EFI
  events so the BSP can detect when the APs have finished. This service may only
  be called from the BSP.

  This function is used to dispatch all the enabled APs to the function
  specified by Procedure.  If any enabled AP is busy, then EFI_NOT_READY is
  returned immediately and Procedure is not started on any AP.

  If SingleThread is TRUE, all the enabled APs execute the function specified by
  Procedure one by one, in ascending order of processor handle number.
  Otherwise, all the enabled APs execute the function specified by Procedure
  simultaneously.

  If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
  APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in
  non-blocking mode, and the BSP returns from this service without waiting for
  APs. If a non-blocking mode is requested after the UEFI Event
  EFI_EVENT_GROUP_READY_TO_BOOT is signaled, then EFI_UNSUPPORTED must be
  returned.

  If the timeout specified by TimeoutInMicroseconds expires before all APs
  return from Procedure, then Procedure on the failed APs is terminated.
  All enabled APs are always available for further calls to
  EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
  EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
  content points to the list of processor handle numbers in which Procedure was
  terminated.

  Note: It is the responsibility of the consumer of the
  EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() to make sure that the nature of the
  code that is executed on the BSP and the dispatched APs is well controlled.
  The MP Services Protocol does not guarantee that the Procedure function is
  MP-safe. Hence, the tasks that can be run in parallel are limited to certain
  independent tasks and well-controlled exclusive code. EFI services and
  protocols may not be called by APs unless otherwise specified.

  In blocking execution mode, BSP waits until all APs finish or
  TimeoutInMicroseconds expires.

  In non-blocking execution mode, BSP is freed to return to the caller and then
  proceed to the next task without having to wait for APs. The following
  sequence needs to occur in a non-blocking execution mode:

    -# The caller that intends to use this MP Services Protocol in non-blocking
       mode creates WaitEvent by calling the EFI CreateEvent() service.  The
       caller invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter
       WaitEvent is not NULL, then StartupAllAPs() executes in non-blocking
       mode. It requests the function specified by Procedure to be started on
       all the enabled APs, and releases the BSP to continue with other tasks.
    -# The caller can use the CheckEvent() and WaitForEvent() services to check
       the state of the WaitEvent created in step 1.
    -# When the APs complete their task or TimeoutInMicroSecondss expires, the
       MP Service signals WaitEvent by calling the EFI SignalEvent() function.
       If FailedCpuList is not NULL, its content is available when WaitEvent is
       signaled. If all APs returned from Procedure prior to the timeout, then
       FailedCpuList is set to NULL. If not all APs return from Procedure before
       the timeout, then FailedCpuList is filled in with the list of the failed
       APs. The buffer is allocated by MP Service Protocol using AllocatePool().
       It is the caller's responsibility to free the buffer with FreePool()
       service.
    -# This invocation of SignalEvent() function informs the caller that invoked
       EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs
       completed the specified task or a timeout occurred. The contents of
       FailedCpuList can be examined to determine which APs did not complete the
       specified task prior to the timeout.

  @param[in]  This                    A pointer to the EFI_MP_SERVICES_PROTOCOL
                                      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]  SingleThread            If TRUE, then all the enabled APs execute
                                      the function specified by Procedure one by
                                      one, in ascending order of processor
                                      handle number.  If FALSE, then all the
                                      enabled APs execute the function specified
                                      by Procedure simultaneously.
  @param[in]  WaitEvent               The event created by the caller with
                                      CreateEvent() service.  If it is NULL,
                                      then execute in blocking mode. BSP waits
                                      until all APs finish or
                                      TimeoutInMicroseconds expires.  If it's
                                      not NULL, then execute in non-blocking
                                      mode. BSP requests the function specified
                                      by Procedure to be started on all the
                                      enabled APs, and go on executing
                                      immediately. If all return from Procedure,
                                      or TimeoutInMicroseconds expires, this
                                      event is signaled. The BSP can use the
                                      CheckEvent() or WaitForEvent()
                                      services to check the state of event. Type
                                      EFI_EVENT is defined in CreateEvent() in
                                      the Unified Extensible Firmware Interface
                                      Specification.
  @param[in]  TimeoutInMicroseconds   Indicates the time limit in microseconds
                                      for APs to return from Procedure, either
                                      for blocking or non-blocking mode. 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_MP_SERVICES_PROTOCOL.StartupAllAPs()
                                      or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
                                      If the timeout expires in blocking mode,
                                      BSP returns EFI_TIMEOUT.  If the timeout
                                      expires in non-blocking mode, WaitEvent
                                      is signaled with SignalEvent().
  @param[in]  ProcedureArgument       The parameter passed into Procedure for
                                      all APs.
  @param[out] FailedCpuList           If NULL, this parameter is ignored.
                                      Otherwise, if all APs finish successfully,
                                      then its content is set to NULL. If not
                                      all APs finish before timeout expires,
                                      then its content is set to address of the
                                      buffer holding handle numbers of the
                                      failed APs.
                                      The buffer is allocated by MP Service
                                      Protocol, and it's the caller's
                                      responsibility to free the buffer with
                                      FreePool() service.
                                      In blocking mode, it is ready for
                                      consumption when the call returns. In
                                      non-blocking mode, it is ready when
                                      WaitEvent is signaled. The list of failed
                                      CPU is terminated by  END_OF_CPU_LIST.

  @retval EFI_SUCCESS             In blocking mode, all APs have finished before
                                  the timeout expired.
  @retval EFI_SUCCESS             In non-blocking mode, function has been
                                  dispatched to all enabled APs.
  @retval EFI_UNSUPPORTED         A non-blocking mode request was made after the
                                  UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
                                  signaled.
  @retval EFI_DEVICE_ERROR        Caller processor is AP.
  @retval EFI_NOT_STARTED         No enabled APs exist in the system.
  @retval EFI_NOT_READY           Any enabled APs are busy.
  @retval EFI_TIMEOUT             In blocking mode, the timeout expired before
                                  all enabled APs have finished.
  @retval EFI_INVALID_PARAMETER   Procedure is NULL.

**/
STATIC
EFI_STATUS
EFIAPI
StartupAllAPs (
  IN  EFI_MP_SERVICES_PROTOCOL  *This,
  IN  EFI_AP_PROCEDURE          Procedure,
  IN  BOOLEAN                   SingleThread,
  IN  EFI_EVENT                 WaitEvent               OPTIONAL,
  IN  UINTN                     TimeoutInMicroseconds,
  IN  VOID                      *ProcedureArgument      OPTIONAL,
  OUT UINTN                     **FailedCpuList         OPTIONAL
  )
{
  EFI_STATUS  Status;

  if (!IsCurrentProcessorBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  if ((mCpuMpData.NumberOfProcessors == 1) || (mCpuMpData.NumberOfEnabledProcessors == 1)) {
    return EFI_NOT_STARTED;
  }

  if (Procedure == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if ((WaitEvent != NULL) && !mNonBlockingModeAllowed) {
    return EFI_UNSUPPORTED;
  }

  if (FailedCpuList != NULL) {
    mCpuMpData.FailedList = AllocateZeroPool (
                              (mCpuMpData.NumberOfProcessors + 1) *
                              sizeof (UINTN)
                              );
    if (mCpuMpData.FailedList == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    SetMemN (
      mCpuMpData.FailedList,
      (mCpuMpData.NumberOfProcessors + 1) *
      sizeof (UINTN),
      END_OF_CPU_LIST
      );
    mCpuMpData.FailedListIndex = 0;
    *FailedCpuList             = mCpuMpData.FailedList;
  }

  StartupAllAPsPrepareState (SingleThread);

  // If any enabled APs are busy (ignoring the BSP), return EFI_NOT_READY
  if (mCpuMpData.StartCount != (mCpuMpData.NumberOfEnabledProcessors - 1)) {
    return EFI_NOT_READY;
  }

  if (WaitEvent != NULL) {
    Status = StartupAllAPsWithWaitEvent (
               Procedure,
               ProcedureArgument,
               WaitEvent,
               TimeoutInMicroseconds,
               SingleThread,
               FailedCpuList
               );

    if (EFI_ERROR (Status) && (FailedCpuList != NULL)) {
      if (mCpuMpData.FailedListIndex == 0) {
        FreePool (*FailedCpuList);
        *FailedCpuList = NULL;
      }
    }
  } else {
    Status = StartupAllAPsNoWaitEvent (
               Procedure,
               ProcedureArgument,
               TimeoutInMicroseconds,
               SingleThread,
               FailedCpuList
               );

    if (FailedCpuList != NULL) {
      if (mCpuMpData.FailedListIndex == 0) {
        FreePool (*FailedCpuList);
        *FailedCpuList = NULL;
      }
    }
  }

  return Status;
}

/**
  This service lets the caller get one enabled AP to execute a caller-provided
  function. The caller can request the BSP to either wait for the completion
  of the AP or just proceed with the next task by using the EFI event mechanism.
  See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
  execution support.  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.  If WaitEvent
  is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
  TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
  BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
  is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
  then EFI_UNSUPPORTED must be returned.

  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_MP_SERVICES_PROTOCOL.StartupAllAPs() and
  EFI_MP_SERVICES_PROTOCOL.StartupThisAP().

  @param[in]  This                    A pointer to the EFI_MP_SERVICES_PROTOCOL
                                      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_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
  @param[in]  WaitEvent               The event created by the caller with CreateEvent()
                                      service.  If it is NULL, then execute in
                                      blocking mode. BSP waits until all APs finish
                                      or TimeoutInMicroseconds expires.  If it's
                                      not NULL, then execute in non-blocking mode.
                                      BSP requests the function specified by
                                      Procedure to be started on all the enabled
                                      APs, and go on executing immediately. If
                                      all return from Procedure or TimeoutInMicroseconds
                                      expires, this event is signaled. The BSP
                                      can use the CheckEvent() or WaitForEvent()
                                      services to check the state of event.  Type
                                      EFI_EVENT is defined in CreateEvent() in
                                      the Unified Extensible Firmware Interface
                                      Specification.
  @param[in]  TimeoutInMicroseconds   Indicates the time limit in microseconds for
                                      APs to return from Procedure, either for
                                      blocking or non-blocking mode. 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_MP_SERVICES_PROTOCOL.StartupAllAPs()
                                      or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
                                      If the timeout expires in blocking mode,
                                      BSP returns EFI_TIMEOUT.  If the timeout
                                      expires in non-blocking mode, WaitEvent
                                      is signaled with SignalEvent().
  @param[in]  ProcedureArgument       The parameter passed into Procedure for
                                      all APs.
  @param[out] Finished                If NULL, this parameter is ignored.  In
                                      blocking mode, this parameter is ignored.
                                      In non-blocking mode, if AP returns from
                                      Procedure before the timeout expires, its
                                      content is set to TRUE. Otherwise, the
                                      value is set to FALSE. The caller can
                                      determine if the AP returned from Procedure
                                      by evaluating this value.

  @retval EFI_SUCCESS             In blocking mode, specified AP finished before
                                  the timeout expires.
  @retval EFI_SUCCESS             In non-blocking mode, the function has been
                                  dispatched to specified AP.
  @retval EFI_UNSUPPORTED         A non-blocking mode request was made after the
                                  UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
                                  signaled.
  @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_READY           The specified AP is busy.
  @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.

**/
STATIC
EFI_STATUS
EFIAPI
StartupThisAP (
  IN  EFI_MP_SERVICES_PROTOCOL  *This,
  IN  EFI_AP_PROCEDURE          Procedure,
  IN  UINTN                     ProcessorNumber,
  IN  EFI_EVENT                 WaitEvent               OPTIONAL,
  IN  UINTN                     TimeoutInMicroseconds,
  IN  VOID                      *ProcedureArgument      OPTIONAL,
  OUT BOOLEAN                   *Finished               OPTIONAL
  )
{
  EFI_STATUS   Status;
  UINTN        Timeout;
  CPU_AP_DATA  *CpuData;

  if (!IsCurrentProcessorBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  if (Procedure == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (ProcessorNumber >= mCpuMpData.NumberOfProcessors) {
    return EFI_NOT_FOUND;
  }

  CpuData = &mCpuMpData.CpuData[ProcessorNumber];

  if (IsProcessorBSP (ProcessorNumber)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsProcessorEnabled (ProcessorNumber)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((GetApState (CpuData) != CpuStateIdle) &&
      (GetApState (CpuData) != CpuStateFinished))
  {
    return EFI_NOT_READY;
  }

  if ((WaitEvent != NULL) && !mNonBlockingModeAllowed) {
    return EFI_UNSUPPORTED;
  }

  Timeout = TimeoutInMicroseconds;

  CpuData->Timeout       = TimeoutInMicroseconds;
  CpuData->TimeTaken     = 0;
  CpuData->TimeoutActive = (BOOLEAN)(TimeoutInMicroseconds != 0);

  SetApProcedure (
    CpuData,
    Procedure,
    ProcedureArgument
    );

  Status = DispatchCpu (ProcessorNumber);
  if (EFI_ERROR (Status)) {
    CpuData->State = CpuStateIdle;
    return EFI_NOT_READY;
  }

  if (WaitEvent != NULL) {
    // Non Blocking
    if (Finished != NULL) {
      CpuData->SingleApFinished = Finished;
      *Finished                 = FALSE;
    }

    CpuData->WaitEvent = WaitEvent;
    Status             = gBS->SetTimer (
                                CpuData->CheckThisAPEvent,
                                TimerPeriodic,
                                POLL_INTERVAL_US
                                );

    return EFI_SUCCESS;
  }

  // Blocking
  while (TRUE) {
    if (GetApState (CpuData) == CpuStateFinished) {
      CpuData->State = CpuStateIdle;
      break;
    }

    if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {
      return EFI_TIMEOUT;
    }

    Timeout -= CalculateAndStallInterval (Timeout);
  }

  return EFI_SUCCESS;
}

/**
  This service switches the requested AP to be the BSP from that point onward.
  This service changes the BSP for all purposes.   This call can only be
  performed by the current BSP.

  This service switches the requested AP to be the BSP from that point onward.
  This service changes the BSP for all purposes. The new BSP can take over the
  execution of the old BSP and continue seamlessly from where the old one left
  off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
  is signaled.

  If the BSP cannot be switched prior to the return from this service, then
  EFI_UNSUPPORTED must be returned.

  @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
  @param[in] ProcessorNumber   The handle number of AP that is to become the new
                               BSP. 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_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
  @param[in] EnableOldBSP      If TRUE, then the old BSP will be listed as an
                               enabled AP. Otherwise, it will be disabled.

  @retval EFI_SUCCESS             BSP successfully switched.
  @retval EFI_UNSUPPORTED         Switching the BSP cannot be completed prior to
                                  this service returning.
  @retval EFI_UNSUPPORTED         Switching the BSP is not supported.
  @retval EFI_SUCCESS             The calling processor is an AP.
  @retval EFI_NOT_FOUND           The processor with the handle specified by
                                  ProcessorNumber does not exist.
  @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the current BSP or
                                  a disabled AP.
  @retval EFI_NOT_READY           The specified AP is busy.

**/
STATIC
EFI_STATUS
EFIAPI
SwitchBSP (
  IN EFI_MP_SERVICES_PROTOCOL  *This,
  IN  UINTN                    ProcessorNumber,
  IN  BOOLEAN                  EnableOldBSP
  )
{
  return EFI_UNSUPPORTED;
}

/**
  This service lets the caller enable or disable an AP from this point onward.
  This service may only be called from the BSP.

  This service allows the caller enable or disable an AP from this point onward.
  The caller can optionally specify the health status of the AP by Health. If
  an AP is being disabled, then the state of the disabled AP is implementation
  dependent. If an AP is enabled, then the implementation must guarantee that a
  complete initialization sequence is performed on the AP, so the AP is in a state
  that is compatible with an MP operating system. This service may not be supported
  after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.

  If the enable or disable AP operation cannot be completed prior to the return
  from this service, then EFI_UNSUPPORTED must be returned.

  @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
  @param[in] ProcessorNumber   The handle number of AP that is to become the new
                               BSP. 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_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
  @param[in] EnableAP          Specifies the new state for the processor for
                               enabled, FALSE for disabled.
  @param[in] HealthFlag        If not NULL, a pointer to a value that specifies
                               the new health status of the AP. This flag
                               corresponds to StatusFlag defined in
                               EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
                               the PROCESSOR_HEALTH_STATUS_BIT is used. All other
                               bits are ignored.  If it is NULL, this parameter
                               is ignored.

  @retval EFI_SUCCESS             The specified AP was enabled or disabled successfully.
  @retval EFI_UNSUPPORTED         Enabling or disabling an AP cannot be completed
                                  prior to this service returning.
  @retval EFI_UNSUPPORTED         Enabling or disabling an AP is not supported.
  @retval EFI_DEVICE_ERROR        The calling processor is an AP.
  @retval EFI_NOT_FOUND           Processor with the handle specified by ProcessorNumber
                                  does not exist.
  @retval EFI_INVALID_PARAMETER   ProcessorNumber specifies the BSP.

**/
STATIC
EFI_STATUS
EFIAPI
EnableDisableAP (
  IN  EFI_MP_SERVICES_PROTOCOL  *This,
  IN  UINTN                     ProcessorNumber,
  IN  BOOLEAN                   EnableAP,
  IN  UINT32                    *HealthFlag OPTIONAL
  )
{
  UINTN        StatusFlag;
  CPU_AP_DATA  *CpuData;

  StatusFlag = mCpuMpData.CpuData[ProcessorNumber].Info.StatusFlag;
  CpuData    = &mCpuMpData.CpuData[ProcessorNumber];

  if (!IsCurrentProcessorBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  if (ProcessorNumber >= mCpuMpData.NumberOfProcessors) {
    return EFI_NOT_FOUND;
  }

  if (IsProcessorBSP (ProcessorNumber)) {
    return EFI_INVALID_PARAMETER;
  }

  if (GetApState (CpuData) != CpuStateIdle) {
    return EFI_UNSUPPORTED;
  }

  if (EnableAP) {
    if (!IsProcessorEnabled (ProcessorNumber)) {
      mCpuMpData.NumberOfEnabledProcessors++;
    }

    StatusFlag |= PROCESSOR_ENABLED_BIT;
  } else {
    if (IsProcessorEnabled (ProcessorNumber) && !IsProcessorBSP (ProcessorNumber)) {
      mCpuMpData.NumberOfEnabledProcessors--;
    }

    StatusFlag &= ~PROCESSOR_ENABLED_BIT;
  }

  if ((HealthFlag != NULL) && !IsProcessorBSP (ProcessorNumber)) {
    StatusFlag &= ~PROCESSOR_HEALTH_STATUS_BIT;
    StatusFlag |= (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT);
  }

  mCpuMpData.CpuData[ProcessorNumber].Info.StatusFlag = StatusFlag;
  return EFI_SUCCESS;
}

/**
  This return the handle number for the calling processor.  This service may be
  called from the BSP and APs.

  This service returns the processor handle number for the calling processor.
  The returned value is in the range from 0 to the total number of logical
  processors minus 1. The total number of logical processors can be retrieved
  with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
  called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
  is returned. Otherwise, the current processors handle number is returned in
  ProcessorNumber, and EFI_SUCCESS is returned.

  @param[in] This              A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
  @param[out] ProcessorNumber  The handle number of AP that is to become the new
                               BSP. 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_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().

  @retval EFI_SUCCESS             The current processor handle number was returned
                                  in ProcessorNumber.
  @retval EFI_INVALID_PARAMETER   ProcessorNumber is NULL.

**/
STATIC
EFI_STATUS
EFIAPI
WhoAmI (
  IN EFI_MP_SERVICES_PROTOCOL  *This,
  OUT UINTN                    *ProcessorNumber
  )
{
  UINTN   Index;
  UINT64  ProcessorId;

  if (ProcessorNumber == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ProcessorId = GET_MPIDR_AFFINITY_BITS (ArmReadMpidr ());
  for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
    if (ProcessorId == gProcessorIDs[Index]) {
      *ProcessorNumber = Index;
      break;
    }
  }

  return EFI_SUCCESS;
}

STATIC EFI_MP_SERVICES_PROTOCOL  mMpServicesProtocol = {
  GetNumberOfProcessors,
  GetProcessorInfo,
  StartupAllAPs,
  StartupThisAP,
  SwitchBSP,
  EnableDisableAP,
  WhoAmI
};

/** Adds the specified processor the list of failed processors.

   @param ProcessorIndex The processor index to add.
   @param ApState        Processor state.

**/
STATIC
VOID
AddProcessorToFailedList (
  UINTN      ProcessorIndex,
  CPU_STATE  ApState
  )
{
  UINTN    Index;
  BOOLEAN  Found;

  Found = FALSE;

  if ((mCpuMpData.FailedList == NULL) ||
      (ApState == CpuStateIdle) ||
      (ApState == CpuStateFinished) ||
      IsProcessorBSP (ProcessorIndex))
  {
    return;
  }

  // If we are retrying make sure we don't double count
  for (Index = 0; Index < mCpuMpData.FailedListIndex; Index++) {
    if (mCpuMpData.FailedList[Index] == ProcessorIndex) {
      Found = TRUE;
      break;
    }
  }

  /* If the CPU isn't already in the FailedList, add it */
  if (!Found) {
    mCpuMpData.FailedList[mCpuMpData.FailedListIndex++] = ProcessorIndex;
  }
}

/** Handles the StartupAllAPs case where the timeout has occurred.

**/
STATIC
VOID
ProcessStartupAllAPsTimeout (
  VOID
  )
{
  CPU_AP_DATA  *CpuData;
  UINTN        Index;

  if (mCpuMpData.FailedList == NULL) {
    return;
  }

  for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
    CpuData = &mCpuMpData.CpuData[Index];
    if (IsProcessorBSP (Index)) {
      // Skip BSP
      continue;
    }

    if (!IsProcessorEnabled (Index)) {
      // Skip Disabled processors
      continue;
    }

    CpuData = &mCpuMpData.CpuData[Index];
    AddProcessorToFailedList (Index, GetApState (CpuData));
  }
}

/** Updates the status of the APs.

   @param[in] ProcessorIndex The index of the AP to update.
**/
STATIC
VOID
UpdateApStatus (
  IN UINTN  ProcessorIndex
  )
{
  EFI_STATUS   Status;
  CPU_AP_DATA  *CpuData;
  CPU_AP_DATA  *NextCpuData;
  CPU_STATE    State;
  UINTN        NextNumber;

  CpuData = &mCpuMpData.CpuData[ProcessorIndex];

  if (IsProcessorBSP (ProcessorIndex)) {
    // Skip BSP
    return;
  }

  if (!IsProcessorEnabled (ProcessorIndex)) {
    // Skip Disabled processors
    return;
  }

  State = GetApState (CpuData);

  switch (State) {
    case CpuStateFinished:
      if (mCpuMpData.SingleThread) {
        Status = GetNextBlockedNumber (&NextNumber);
        if (!EFI_ERROR (Status)) {
          NextCpuData = &mCpuMpData.CpuData[NextNumber];

          NextCpuData->State = CpuStateReady;

          SetApProcedure (
            NextCpuData,
            mCpuMpData.Procedure,
            mCpuMpData.ProcedureArgument
            );

          Status = DispatchCpu (NextNumber);
          if (!EFI_ERROR (Status)) {
            mCpuMpData.StartCount++;
          } else {
            AddProcessorToFailedList (NextNumber, NextCpuData->State);
          }
        }
      }

      CpuData->State = CpuStateIdle;
      mCpuMpData.FinishCount++;
      break;

    default:
      break;
  }
}

/**
  If a timeout is specified in StartupAllAps(), a timer is set, which invokes
  this procedure periodically to check whether all APs have finished.

  @param[in] Event   The WaitEvent the user supplied.
  @param[in] Context The event context.
**/
STATIC
VOID
EFIAPI
CheckAllAPsStatus (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS  Status;
  UINTN       Index;

  mCpuMpData.AllTimeTaken += POLL_INTERVAL_US;

  for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
    UpdateApStatus (Index);
  }

  if (mCpuMpData.AllTimeoutActive && (mCpuMpData.AllTimeTaken > mCpuMpData.AllTimeout)) {
    ProcessStartupAllAPsTimeout ();

    // Force terminal exit
    mCpuMpData.FinishCount = mCpuMpData.StartCount;
  }

  if (mCpuMpData.FinishCount != mCpuMpData.StartCount) {
    return;
  }

  gBS->SetTimer (
         mCpuMpData.CheckAllAPsEvent,
         TimerCancel,
         0
         );

  if (mCpuMpData.FailedListIndex == 0) {
    if (mCpuMpData.FailedList != NULL) {
      // Since we don't have the original `FailedCpuList`
      // pointer here to set to NULL, don't free the
      // memory.
    }
  }

  Status = gBS->SignalEvent (mCpuMpData.AllWaitEvent);
  ASSERT_EFI_ERROR (Status);
  mCpuMpData.AllWaitEvent = NULL;
}

/** Invoked periodically via a timer to check the state of the processor.

   @param Event   The event supplied by the timer expiration.
   @param Context The processor context.

**/
STATIC
VOID
EFIAPI
CheckThisAPStatus (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS   Status;
  CPU_AP_DATA  *CpuData;
  CPU_STATE    State;

  CpuData = Context;

  CpuData->TimeTaken += POLL_INTERVAL_US;

  State = GetApState (CpuData);

  if (State == CpuStateFinished) {
    Status = gBS->SetTimer (CpuData->CheckThisAPEvent, TimerCancel, 0);
    ASSERT_EFI_ERROR (Status);

    if (CpuData->SingleApFinished != NULL) {
      *(CpuData->SingleApFinished) = TRUE;
    }

    if (CpuData->WaitEvent != NULL) {
      Status = gBS->SignalEvent (CpuData->WaitEvent);
      ASSERT_EFI_ERROR (Status);
    }

    CpuData->State = CpuStateIdle;
  }

  if (CpuData->TimeoutActive && (CpuData->TimeTaken > CpuData->Timeout)) {
    Status = gBS->SetTimer (CpuData->CheckThisAPEvent, TimerCancel, 0);
    if (CpuData->WaitEvent != NULL) {
      Status = gBS->SignalEvent (CpuData->WaitEvent);
      ASSERT_EFI_ERROR (Status);
      CpuData->WaitEvent = NULL;
    }
  }
}

/**
  This function is called by all processors (both BSP and AP) once and collects
  MP related data.

  @param BSP            TRUE if the processor is the BSP.
  @param Mpidr          The MPIDR for the specified processor. This should be
                        the full MPIDR and not only the affinity bits.
  @param ProcessorIndex The index of the processor.

  @return EFI_SUCCESS if the data for the processor collected and filled in.

**/
STATIC
EFI_STATUS
FillInProcessorInformation (
  IN BOOLEAN  BSP,
  IN UINTN    Mpidr,
  IN UINTN    ProcessorIndex
  )
{
  EFI_PROCESSOR_INFORMATION  *CpuInfo;

  CpuInfo = &mCpuMpData.CpuData[ProcessorIndex].Info;

  CpuInfo->ProcessorId = GET_MPIDR_AFFINITY_BITS (Mpidr);
  CpuInfo->StatusFlag  = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;

  if (BSP) {
    CpuInfo->StatusFlag |= PROCESSOR_AS_BSP_BIT;
  }

  if ((Mpidr & MPIDR_MT_BIT) > 0) {
    CpuInfo->Location.Package = GET_MPIDR_AFF2 (Mpidr);
    CpuInfo->Location.Core    = GET_MPIDR_AFF1 (Mpidr);
    CpuInfo->Location.Thread  = GET_MPIDR_AFF0 (Mpidr);

    CpuInfo->ExtendedInformation.Location2.Package = GET_MPIDR_AFF3 (Mpidr);
    CpuInfo->ExtendedInformation.Location2.Die     = GET_MPIDR_AFF2 (Mpidr);
    CpuInfo->ExtendedInformation.Location2.Core    = GET_MPIDR_AFF1 (Mpidr);
    CpuInfo->ExtendedInformation.Location2.Thread  = GET_MPIDR_AFF0 (Mpidr);
  } else {
    CpuInfo->Location.Package = GET_MPIDR_AFF1 (Mpidr);
    CpuInfo->Location.Core    = GET_MPIDR_AFF0 (Mpidr);
    CpuInfo->Location.Thread  = 0;

    CpuInfo->ExtendedInformation.Location2.Package = GET_MPIDR_AFF2 (Mpidr);
    CpuInfo->ExtendedInformation.Location2.Die     = GET_MPIDR_AFF1 (Mpidr);
    CpuInfo->ExtendedInformation.Location2.Core    = GET_MPIDR_AFF0 (Mpidr);
    CpuInfo->ExtendedInformation.Location2.Thread  = 0;
  }

  mCpuMpData.CpuData[ProcessorIndex].State = BSP ? CpuStateBusy : CpuStateIdle;

  mCpuMpData.CpuData[ProcessorIndex].Procedure = NULL;
  mCpuMpData.CpuData[ProcessorIndex].Parameter = NULL;

  return EFI_SUCCESS;
}

/** Initializes the MP Services system data

   @param NumberOfProcessors The number of processors, both BSP and AP.
   @param CoreInfo           CPU information gathered earlier during boot.

**/
STATIC
EFI_STATUS
MpServicesInitialize (
  IN   UINTN                NumberOfProcessors,
  IN   CONST ARM_CORE_INFO  *CoreInfo
  )
{
  EFI_STATUS  Status;
  UINTN       Index;
  EFI_EVENT   ReadyToBootEvent;
  BOOLEAN     IsBsp;

  //
  // Clear the data structure area first.
  //
  ZeroMem (&mCpuMpData, sizeof (CPU_MP_DATA));
  //
  // First BSP fills and inits all known values, including its own records.
  //
  mCpuMpData.NumberOfProcessors        = NumberOfProcessors;
  mCpuMpData.NumberOfEnabledProcessors = NumberOfProcessors;

  mCpuMpData.CpuData = AllocateZeroPool (
                         mCpuMpData.NumberOfProcessors * sizeof (CPU_AP_DATA)
                         );

  if (mCpuMpData.CpuData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  /* Allocate one extra for the sentinel entry at the end */
  gProcessorIDs = AllocateZeroPool ((mCpuMpData.NumberOfProcessors + 1) * sizeof (UINT64));
  ASSERT (gProcessorIDs != NULL);

  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  CheckAllAPsStatus,
                  NULL,
                  &mCpuMpData.CheckAllAPsEvent
                  );
  ASSERT_EFI_ERROR (Status);

  gApStacksBase = AllocatePages (
                    EFI_SIZE_TO_PAGES (
                      mCpuMpData.NumberOfProcessors *
                      gApStackSize
                      )
                    );
  ASSERT (gApStacksBase != NULL);

  for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
    if (GET_MPIDR_AFFINITY_BITS (ArmReadMpidr ()) == CoreInfo[Index].Mpidr) {
      IsBsp = TRUE;
    } else {
      IsBsp = FALSE;
    }

    FillInProcessorInformation (IsBsp, CoreInfo[Index].Mpidr, Index);

    gProcessorIDs[Index] = mCpuMpData.CpuData[Index].Info.ProcessorId;

    Status = gBS->CreateEvent (
                    EVT_TIMER | EVT_NOTIFY_SIGNAL,
                    TPL_CALLBACK,
                    CheckThisAPStatus,
                    (VOID *)&mCpuMpData.CpuData[Index],
                    &mCpuMpData.CpuData[Index].CheckThisAPEvent
                    );
    ASSERT_EFI_ERROR (Status);
  }

  gProcessorIDs[Index] = MAX_UINT64;

  gTcr   = ArmGetTCR ();
  gMair  = ArmGetMAIR ();
  gTtbr0 = ArmGetTTBR0BaseAddress ();

  //
  // The global pointer variables as well as the gProcessorIDs array contents
  // are accessed by the other cores so we must clean them to the PoC
  //
  WriteBackDataCacheRange (&gProcessorIDs, sizeof (UINT64 *));
  WriteBackDataCacheRange (&gApStacksBase, sizeof (UINT64 *));

  WriteBackDataCacheRange (
    gProcessorIDs,
    (mCpuMpData.NumberOfProcessors + 1) * sizeof (UINT64)
    );

  mNonBlockingModeAllowed = TRUE;

  Status = EfiCreateEventReadyToBootEx (
             TPL_CALLBACK,
             ReadyToBootSignaled,
             NULL,
             &ReadyToBootEvent
             );
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}

/**
  Event notification function called when the EFI_EVENT_GROUP_READY_TO_BOOT is
  signaled. After this point, non-blocking mode is no longer allowed.

  @param  Event     Event whose notification function is being invoked.
  @param  Context   The pointer to the notification function's context,
                    which is implementation-dependent.

**/
STATIC
VOID
EFIAPI
ReadyToBootSignaled (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  mNonBlockingModeAllowed = FALSE;
}

/** Initialize multi-processor support.

  @param ImageHandle  Image handle.
  @param SystemTable  System table.

  @return EFI_SUCCESS on success, or an error code.

**/
EFI_STATUS
EFIAPI
ArmPsciMpServicesDxeInitialize (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                 Status;
  EFI_HANDLE                 Handle;
  UINTN                      MaxCpus;
  EFI_LOADED_IMAGE_PROTOCOL  *Image;
  EFI_HOB_GENERIC_HEADER     *Hob;
  VOID                       *HobData;
  UINTN                      HobDataSize;
  CONST ARM_CORE_INFO        *CoreInfo;

  MaxCpus = 1;

  Status = gBS->HandleProtocol (
                  ImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **)&Image
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Parts of the code in this driver may be executed by other cores running
  // with the MMU off so we need to ensure that everything is clean to the
  // point of coherency (PoC)
  //
  WriteBackDataCacheRange (Image->ImageBase, Image->ImageSize);

  Hob = GetFirstGuidHob (&gArmMpCoreInfoGuid);
  if (Hob != NULL) {
    HobData     = GET_GUID_HOB_DATA (Hob);
    HobDataSize = GET_GUID_HOB_DATA_SIZE (Hob);
    CoreInfo    = (ARM_CORE_INFO *)HobData;
    MaxCpus     = HobDataSize / sizeof (ARM_CORE_INFO);
  }

  if (MaxCpus == 1) {
    DEBUG ((DEBUG_WARN, "Trying to use EFI_MP_SERVICES_PROTOCOL on a UP system"));
    // We are not MP so nothing to do
    return EFI_NOT_FOUND;
  }

  Status = MpServicesInitialize (MaxCpus, CoreInfo);
  if (Status != EFI_SUCCESS) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  //
  // Now install the MP services protocol.
  //
  Handle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEfiMpServiceProtocolGuid,
                  &mMpServicesProtocol,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** AP exception handler.

  @param InterruptType The AArch64 CPU exception type.
  @param SystemContext System context.

**/
STATIC
VOID
EFIAPI
ApExceptionHandler (
  IN CONST EFI_EXCEPTION_TYPE  InterruptType,
  IN CONST EFI_SYSTEM_CONTEXT  SystemContext
  )
{
  ARM_SMC_ARGS  Args;
  UINT64        Mpidr;
  UINTN         Index;
  UINTN         ProcessorIndex;

  Mpidr = GET_MPIDR_AFFINITY_BITS (ArmReadMpidr ());

  Index          = 0;
  ProcessorIndex = MAX_UINT64;

  do {
    if (gProcessorIDs[Index] == Mpidr) {
      ProcessorIndex = Index;
      break;
    }

    Index++;
  } while (gProcessorIDs[Index] != MAX_UINT64);

  if (ProcessorIndex != MAX_UINT64) {
    mCpuMpData.CpuData[ProcessorIndex].State = CpuStateFinished;
    ArmDataMemoryBarrier ();
  }

  Args.Arg0 = ARM_SMC_ID_PSCI_CPU_OFF;
  ArmCallSmc (&Args);

  /* Should never be reached */
  ASSERT (FALSE);
  CpuDeadLoop ();
}

/** C entry-point for the AP.
    This function gets called from the assembly function ApEntryPoint.

**/
VOID
ApProcedure (
  VOID
  )
{
  ARM_SMC_ARGS      Args;
  EFI_AP_PROCEDURE  UserApProcedure;
  VOID              *UserApParameter;
  UINTN             ProcessorIndex;

  ProcessorIndex = 0;

  WhoAmI (&mMpServicesProtocol, &ProcessorIndex);

  /* Fetch the user-supplied procedure and parameter to execute */
  UserApProcedure = mCpuMpData.CpuData[ProcessorIndex].Procedure;
  UserApParameter = mCpuMpData.CpuData[ProcessorIndex].Parameter;

  InitializeCpuExceptionHandlers (NULL);
  RegisterCpuInterruptHandler (EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, ApExceptionHandler);
  RegisterCpuInterruptHandler (EXCEPT_AARCH64_IRQ, ApExceptionHandler);
  RegisterCpuInterruptHandler (EXCEPT_AARCH64_FIQ, ApExceptionHandler);
  RegisterCpuInterruptHandler (EXCEPT_AARCH64_SERROR, ApExceptionHandler);

  UserApProcedure (UserApParameter);

  mCpuMpData.CpuData[ProcessorIndex].State = CpuStateFinished;

  ArmDataMemoryBarrier ();

  /* Since we're finished with this AP, turn it off */
  Args.Arg0 = ARM_SMC_ID_PSCI_CPU_OFF;
  ArmCallSmc (&Args);

  /* Should never be reached */
  ASSERT (FALSE);
  CpuDeadLoop ();
}

/** Returns whether the processor executing this function is the BSP.

    @return Whether the current processor is the BSP.
**/
STATIC
BOOLEAN
IsCurrentProcessorBSP (
  VOID
  )
{
  EFI_STATUS  Status;
  UINTN       ProcessorIndex;

  Status = WhoAmI (&mMpServicesProtocol, &ProcessorIndex);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return FALSE;
  }

  return IsProcessorBSP (ProcessorIndex);
}

/** Returns whether the specified processor is enabled.

   @param[in] ProcessorIndex The index of the processor to check.

   @return TRUE if the processor is enabled, FALSE otherwise.
**/
STATIC
BOOLEAN
IsProcessorEnabled (
  UINTN  ProcessorIndex
  )
{
  EFI_PROCESSOR_INFORMATION  *CpuInfo;

  CpuInfo = &mCpuMpData.CpuData[ProcessorIndex].Info;

  return (CpuInfo->StatusFlag & PROCESSOR_ENABLED_BIT) != 0;
}

/** Sets up the state for the StartupAllAPs function.

   @param SingleThread Whether the APs will execute sequentially.

**/
STATIC
VOID
StartupAllAPsPrepareState (
  IN BOOLEAN  SingleThread
  )
{
  UINTN        Index;
  CPU_STATE    APInitialState;
  CPU_AP_DATA  *CpuData;

  mCpuMpData.FinishCount  = 0;
  mCpuMpData.StartCount   = 0;
  mCpuMpData.SingleThread = SingleThread;

  APInitialState = CpuStateReady;

  for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
    CpuData = &mCpuMpData.CpuData[Index];

    //
    // Get APs prepared, and put failing APs into FailedCpuList.
    // If "SingleThread", only 1 AP will put into ready state, other AP will be
    // put into ready state 1 by 1, until the previous 1 finished its task.
    // If not "SingleThread", all APs are put into ready state from the
    // beginning
    //

    if (IsProcessorBSP (Index)) {
      // Skip BSP
      continue;
    }

    if (!IsProcessorEnabled (Index)) {
      // Skip Disabled processors
      if (mCpuMpData.FailedList != NULL) {
        mCpuMpData.FailedList[mCpuMpData.FailedListIndex++] = Index;
      }

      continue;
    }

    // If any APs finished after timing out, reset state to Idle
    if (GetApState (CpuData) == CpuStateFinished) {
      CpuData->State = CpuStateIdle;
    }

    if (GetApState (CpuData) != CpuStateIdle) {
      // Skip busy processors
      if (mCpuMpData.FailedList != NULL) {
        mCpuMpData.FailedList[mCpuMpData.FailedListIndex++] = Index;
      }
    }

    CpuData->State = APInitialState;

    mCpuMpData.StartCount++;
    if (SingleThread) {
      APInitialState = CpuStateBlocked;
    }
  }
}

/** Handles execution of StartupAllAPs when a WaitEvent has been specified.

  @param Procedure         The user-supplied procedure.
  @param ProcedureArgument The user-supplied procedure argument.
  @param WaitEvent         The wait event to be signaled when the work is
                           complete or a timeout has occurred.
  @param TimeoutInMicroseconds The timeout for the work to be completed. Zero
                               indicates an infinite timeout.
  @param SingleThread          Whether the APs will execute sequentially.
  @param FailedCpuList         User-supplied pointer for list of failed CPUs.

   @return EFI_SUCCESS on success.
**/
STATIC
EFI_STATUS
StartupAllAPsWithWaitEvent (
  IN EFI_AP_PROCEDURE  Procedure,
  IN VOID              *ProcedureArgument,
  IN EFI_EVENT         WaitEvent,
  IN UINTN             TimeoutInMicroseconds,
  IN BOOLEAN           SingleThread,
  IN UINTN             **FailedCpuList
  )
{
  EFI_STATUS   Status;
  UINTN        Index;
  CPU_AP_DATA  *CpuData;

  for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
    CpuData = &mCpuMpData.CpuData[Index];
    if (IsProcessorBSP (Index)) {
      // Skip BSP
      continue;
    }

    if (!IsProcessorEnabled (Index)) {
      // Skip Disabled processors
      continue;
    }

    if (GetApState (CpuData) == CpuStateReady) {
      SetApProcedure (CpuData, Procedure, ProcedureArgument);
      if ((mCpuMpData.StartCount == 0) || !SingleThread) {
        Status = DispatchCpu (Index);
        if (EFI_ERROR (Status)) {
          AddProcessorToFailedList (Index, CpuData->State);
          break;
        }
      }
    }
  }

  if (EFI_ERROR (Status)) {
    return EFI_NOT_READY;
  }

  //
  // Save data into private data structure, and create timer to poll AP state
  // before exiting
  //
  mCpuMpData.Procedure         = Procedure;
  mCpuMpData.ProcedureArgument = ProcedureArgument;
  mCpuMpData.AllWaitEvent      = WaitEvent;
  mCpuMpData.AllTimeout        = TimeoutInMicroseconds;
  mCpuMpData.AllTimeTaken      = 0;
  mCpuMpData.AllTimeoutActive  = (BOOLEAN)(TimeoutInMicroseconds != 0);
  Status                       = gBS->SetTimer (
                                        mCpuMpData.CheckAllAPsEvent,
                                        TimerPeriodic,
                                        POLL_INTERVAL_US
                                        );

  return Status;
}

/** Handles execution of StartupAllAPs when no wait event has been specified.

  @param Procedure             The user-supplied procedure.
  @param ProcedureArgument     The user-supplied procedure argument.
  @param TimeoutInMicroseconds The timeout for the work to be completed. Zero
                                indicates an infinite timeout.
  @param SingleThread          Whether the APs will execute sequentially.
  @param FailedCpuList         User-supplied pointer for list of failed CPUs.

  @return EFI_SUCCESS on success.
**/
STATIC
EFI_STATUS
StartupAllAPsNoWaitEvent (
  IN EFI_AP_PROCEDURE  Procedure,
  IN VOID              *ProcedureArgument,
  IN UINTN             TimeoutInMicroseconds,
  IN BOOLEAN           SingleThread,
  IN UINTN             **FailedCpuList
  )
{
  EFI_STATUS   Status;
  UINTN        Index;
  UINTN        NextIndex;
  UINTN        Timeout;
  CPU_AP_DATA  *CpuData;
  BOOLEAN      DispatchError;

  Timeout       = TimeoutInMicroseconds;
  DispatchError = FALSE;

  while (TRUE) {
    for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
      CpuData = &mCpuMpData.CpuData[Index];
      if (IsProcessorBSP (Index)) {
        // Skip BSP
        continue;
      }

      if (!IsProcessorEnabled (Index)) {
        // Skip Disabled processors
        continue;
      }

      switch (GetApState (CpuData)) {
        case CpuStateReady:
          SetApProcedure (CpuData, Procedure, ProcedureArgument);
          Status = DispatchCpu (Index);
          if (EFI_ERROR (Status)) {
            AddProcessorToFailedList (Index, CpuData->State);
            CpuData->State = CpuStateIdle;
            mCpuMpData.StartCount--;
            DispatchError = TRUE;

            if (SingleThread) {
              // Dispatch the next available AP
              Status = GetNextBlockedNumber (&NextIndex);
              if (!EFI_ERROR (Status)) {
                mCpuMpData.CpuData[NextIndex].State = CpuStateReady;
              }
            }
          }

          break;

        case CpuStateFinished:
          mCpuMpData.FinishCount++;
          if (SingleThread) {
            Status = GetNextBlockedNumber (&NextIndex);
            if (!EFI_ERROR (Status)) {
              mCpuMpData.CpuData[NextIndex].State = CpuStateReady;
            }
          }

          CpuData->State = CpuStateIdle;
          break;

        default:
          break;
      }
    }

    if (mCpuMpData.FinishCount == mCpuMpData.StartCount) {
      Status = EFI_SUCCESS;
      break;
    }

    if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {
      Status = EFI_TIMEOUT;
      break;
    }

    Timeout -= CalculateAndStallInterval (Timeout);
  }

  if (Status == EFI_TIMEOUT) {
    // Add any remaining CPUs to the FailedCpuList
    if (FailedCpuList != NULL) {
      for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
        AddProcessorToFailedList (Index, mCpuMpData.CpuData[Index].State);
      }
    }
  }

  if (DispatchError) {
    Status = EFI_NOT_READY;
  }

  return Status;
}
