/** @file
  Construct MP Services Protocol on top of the EMU Thread protocol.
  This code makes APs show up in the emulator. PcdEmuApCount is the
  number of APs the emulator should produce.

  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) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
Portitions Copyright (c) 2011, Apple Inc. All rights reserved.
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.


**/

#include "CpuDriver.h"


MP_SYSTEM_DATA                gMPSystem;
EMU_THREAD_THUNK_PROTOCOL     *gThread = NULL;
EFI_EVENT                     gReadToBootEvent;
BOOLEAN                       gReadToBoot = FALSE;
UINTN                         gPollInterval;


BOOLEAN
IsBSP (
  VOID
  )
{
  EFI_STATUS  Status;
  UINTN       ProcessorNumber;

  Status = CpuMpServicesWhoAmI (&mMpServicesTemplate, &ProcessorNumber);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  return (gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0;
}


VOID
SetApProcedure (
  IN   PROCESSOR_DATA_BLOCK  *Processor,
  IN   EFI_AP_PROCEDURE      Procedure,
  IN   VOID                  *ProcedureArgument
  )
{
  gThread->MutexLock (Processor->ProcedureLock);
  Processor->Parameter  = ProcedureArgument;
  Processor->Procedure  = Procedure;
  gThread->MutexUnlock (Processor->ProcedureLock);
}


EFI_STATUS
GetNextBlockedNumber (
  OUT UINTN                               *NextNumber
  )
{
  UINTN                 Number;
  PROCESSOR_STATE       ProcessorState;
  PROCESSOR_DATA_BLOCK  *Data;

  for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
    Data = &gMPSystem.ProcessorData[Number];
    if ((Data->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
      // Skip BSP
      continue;
    }

    gThread->MutexLock (Data->StateLock);
    ProcessorState = Data->State;
    gThread->MutexUnlock (Data->StateLock);

    if (ProcessorState == CPU_STATE_BLOCKED) {
      *NextNumber = Number;
      return EFI_SUCCESS;
    }
  }

  return EFI_NOT_FOUND;
}

/**
 * Calculated and stalled the interval time by BSP to check whether
 * the APs have finished.
 *
 * @param[in]  Timeout    The time limit in microseconds for
 *                        APs to return from Procedure.
 *
 * @retval     StallTime  Time of execution stall.
**/
UINTN
CalculateAndStallInterval (
  IN UINTN                  Timeout
  )
{
  UINTN                 StallTime;

  if (Timeout < gPollInterval && Timeout != 0) {
    StallTime = Timeout;
  } else {
    StallTime = gPollInterval;
  }
  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 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.

**/
EFI_STATUS
EFIAPI
CpuMpServicesGetNumberOfProcessors (
  IN  EFI_MP_SERVICES_PROTOCOL  *This,
  OUT UINTN                     *NumberOfProcessors,
  OUT UINTN                     *NumberOfEnabledProcessors
  )
{
  if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  *NumberOfProcessors        = gMPSystem.NumberOfProcessors;
  *NumberOfEnabledProcessors = gMPSystem.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]  ProcessorNumber       The handle number of 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.

**/
EFI_STATUS
EFIAPI
CpuMpServicesGetProcessorInfo (
  IN  EFI_MP_SERVICES_PROTOCOL   *This,
  IN  UINTN                      ProcessorNumber,
  OUT EFI_PROCESSOR_INFORMATION  *ProcessorInfoBuffer
  )
{
  if (ProcessorInfoBuffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!IsBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  if (ProcessorNumber >= gMPSystem.NumberOfProcessors) {
    return EFI_NOT_FOUND;
  }

  CopyMem (ProcessorInfoBuffer, &gMPSystem.ProcessorData[ProcessorNumber], 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]  TimeoutInMicrosecsond   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.

**/
EFI_STATUS
EFIAPI
CpuMpServicesStartupAllAps (
  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;
  PROCESSOR_DATA_BLOCK  *ProcessorData;
  UINTN                 Number;
  UINTN                 NextNumber;
  PROCESSOR_STATE       APInitialState;
  PROCESSOR_STATE       ProcessorState;
  UINTN                 Timeout;


  if (!IsBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  if (gMPSystem.NumberOfProcessors == 1) {
    return EFI_NOT_STARTED;
  }

  if (Procedure == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if ((WaitEvent != NULL)  && gReadToBoot) {
    return EFI_UNSUPPORTED;
  }

  for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
    ProcessorData = &gMPSystem.ProcessorData[Number];
    if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
      // Skip BSP
      continue;
    }

    if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
      // Skip Disabled processors
      continue;
    }
    gThread->MutexLock(ProcessorData->StateLock);
    if (ProcessorData->State != CPU_STATE_IDLE) {
      gThread->MutexUnlock (ProcessorData->StateLock);
      return EFI_NOT_READY;
    }
    gThread->MutexUnlock(ProcessorData->StateLock);
  }

  if (FailedCpuList != NULL) {
    gMPSystem.FailedList = AllocatePool ((gMPSystem.NumberOfProcessors + 1) * sizeof (UINTN));
    if (gMPSystem.FailedList == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    SetMemN (gMPSystem.FailedList, (gMPSystem.NumberOfProcessors + 1) * sizeof (UINTN), END_OF_CPU_LIST);
    gMPSystem.FailedListIndex = 0;
    *FailedCpuList = gMPSystem.FailedList;
  }

  Timeout = TimeoutInMicroseconds;

  ProcessorData               = NULL;

  gMPSystem.FinishCount   = 0;
  gMPSystem.StartCount    = 0;
  gMPSystem.SingleThread  = SingleThread;
  APInitialState          = CPU_STATE_READY;

  for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
    ProcessorData = &gMPSystem.ProcessorData[Number];

    if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
      // Skip BSP
      continue;
    }

    if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
      // Skip Disabled processors
      gMPSystem.FailedList[gMPSystem.FailedListIndex++] = Number;
      continue;
    }

    //
    // Get APs prepared, and put failing APs into FailedCpuList
    // if "SingleThread", only 1 AP will put to ready state, other AP will be put to ready
    // state 1 by 1, until the previous 1 finished its task
    // if not "SingleThread", all APs are put to ready state from the beginning
    //
    gThread->MutexLock(ProcessorData->StateLock);
    ASSERT (ProcessorData->State == CPU_STATE_IDLE);
    ProcessorData->State = APInitialState;
    gThread->MutexUnlock (ProcessorData->StateLock);

    gMPSystem.StartCount++;
    if (SingleThread) {
      APInitialState = CPU_STATE_BLOCKED;
    }
  }

  if (WaitEvent != NULL) {
    for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
      ProcessorData = &gMPSystem.ProcessorData[Number];
      if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
       // Skip BSP
        continue;
      }

      if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
        // Skip Disabled processors
        continue;
      }

      gThread->MutexLock (ProcessorData->StateLock);
      ProcessorState = ProcessorData->State;
      gThread->MutexUnlock (ProcessorData->StateLock);

      if (ProcessorState == CPU_STATE_READY) {
        SetApProcedure (ProcessorData, Procedure, ProcedureArgument);
      }
    }

    //
    // Save data into private data structure, and create timer to poll AP state before exiting
    //
    gMPSystem.Procedure         = Procedure;
    gMPSystem.ProcedureArgument = ProcedureArgument;
    gMPSystem.WaitEvent         = WaitEvent;
    gMPSystem.Timeout           = TimeoutInMicroseconds;
    gMPSystem.TimeoutActive     = (BOOLEAN)(TimeoutInMicroseconds != 0);
    Status = gBS->SetTimer (
                    gMPSystem.CheckAllAPsEvent,
                    TimerPeriodic,
                    gPollInterval
                    );
    return Status;

  }

  while (TRUE) {
    for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
      ProcessorData = &gMPSystem.ProcessorData[Number];
      if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
       // Skip BSP
        continue;
      }

      if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
        // Skip Disabled processors
        continue;
      }

      gThread->MutexLock (ProcessorData->StateLock);
      ProcessorState = ProcessorData->State;
      gThread->MutexUnlock (ProcessorData->StateLock);

      switch (ProcessorState) {
      case CPU_STATE_READY:
        SetApProcedure (ProcessorData, Procedure, ProcedureArgument);
        break;

      case CPU_STATE_FINISHED:
        gMPSystem.FinishCount++;
        if (SingleThread) {
          Status = GetNextBlockedNumber (&NextNumber);
          if (!EFI_ERROR (Status)) {
            gThread->MutexLock (gMPSystem.ProcessorData[NextNumber].StateLock);
            gMPSystem.ProcessorData[NextNumber].State = CPU_STATE_READY;
            gThread->MutexUnlock (gMPSystem.ProcessorData[NextNumber].StateLock);
          }
        }

        gThread->MutexLock (ProcessorData->StateLock);
        ProcessorData->State = CPU_STATE_IDLE;
        gThread->MutexUnlock (ProcessorData->StateLock);

        break;

      default:
        break;
      }
    }

    if (gMPSystem.FinishCount == gMPSystem.StartCount) {
      Status = EFI_SUCCESS;
      goto Done;
    }

    if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {
      Status = EFI_TIMEOUT;
      goto Done;
    }

    Timeout -= CalculateAndStallInterval (Timeout);
  }

Done:
  if (FailedCpuList != NULL) {
    if (gMPSystem.FailedListIndex == 0) {
      FreePool (*FailedCpuList);
      *FailedCpuList = NULL;
    }
  }

  return EFI_SUCCESS;
}


/**
  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]  TimeoutInMicrosecsond   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.

**/
EFI_STATUS
EFIAPI
CpuMpServicesStartupThisAP (
  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
  )
{
  UINTN            Timeout;

  if (!IsBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  if (Procedure == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (ProcessorNumber >= gMPSystem.NumberOfProcessors) {
    return EFI_NOT_FOUND;
  }

  if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  gThread->MutexLock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);
  if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {
    gThread->MutexUnlock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);
    return EFI_NOT_READY;
  }
  gThread->MutexUnlock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);

  if ((WaitEvent != NULL)  && gReadToBoot) {
    return EFI_UNSUPPORTED;
  }

  Timeout = TimeoutInMicroseconds;

  gMPSystem.StartCount   = 1;
  gMPSystem.FinishCount  = 0;

  SetApProcedure (&gMPSystem.ProcessorData[ProcessorNumber], Procedure, ProcedureArgument);

  if (WaitEvent != NULL) {
    // Non Blocking
    gMPSystem.WaitEvent = WaitEvent;
    gBS->SetTimer (
           gMPSystem.ProcessorData[ProcessorNumber].CheckThisAPEvent,
           TimerPeriodic,
           gPollInterval
           );
    return EFI_SUCCESS;
  }

  // Blocking
  while (TRUE) {
    gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
    if (gMPSystem.ProcessorData[ProcessorNumber].State == CPU_STATE_FINISHED) {
      gMPSystem.ProcessorData[ProcessorNumber].State = CPU_STATE_IDLE;
      gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
      break;
    }

    gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);

    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.

**/
EFI_STATUS
EFIAPI
CpuMpServicesSwitchBSP (
  IN EFI_MP_SERVICES_PROTOCOL  *This,
  IN  UINTN                    ProcessorNumber,
  IN  BOOLEAN                  EnableOldBSP
  )
{
  UINTN   Index;

  if (!IsBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  if (ProcessorNumber >= gMPSystem.NumberOfProcessors) {
    return EFI_NOT_FOUND;
  }

  if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  for (Index = 0; Index < gMPSystem.NumberOfProcessors; Index++) {
    if ((gMPSystem.ProcessorData[Index].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
      break;
    }
  }
  ASSERT (Index != gMPSystem.NumberOfProcessors);

  gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
  if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {
    gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
    return EFI_NOT_READY;
  }
  gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);

  // Skip for now as we need switch a bunch of stack stuff around and it's complex
  // May not be worth it?
  return EFI_NOT_READY;
}


/**
  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.

**/
EFI_STATUS
EFIAPI
CpuMpServicesEnableDisableAP (
  IN  EFI_MP_SERVICES_PROTOCOL  *This,
  IN  UINTN                     ProcessorNumber,
  IN  BOOLEAN                   EnableAP,
  IN  UINT32                    *HealthFlag OPTIONAL
  )
{
  if (!IsBSP ()) {
    return EFI_DEVICE_ERROR;
  }

  if (ProcessorNumber >= gMPSystem.NumberOfProcessors) {
    return EFI_NOT_FOUND;
  }

  if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
  if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {
    gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
    return EFI_UNSUPPORTED;
  }
  gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);

  if (EnableAP) {
    if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0 ) {
      gMPSystem.NumberOfEnabledProcessors++;
    }
    gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag |= PROCESSOR_ENABLED_BIT;
  } else {
    if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == PROCESSOR_ENABLED_BIT ) {
      gMPSystem.NumberOfEnabledProcessors--;
    }
    gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag &= ~PROCESSOR_ENABLED_BIT;
  }

  if (HealthFlag != NULL) {
    gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag &= ~PROCESSOR_HEALTH_STATUS_BIT;
    gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag |= (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT);
  }

  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[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().

  @retval EFI_SUCCESS             The current processor handle number was returned
                                  in ProcessorNumber.
  @retval EFI_INVALID_PARAMETER   ProcessorNumber is NULL.

**/
EFI_STATUS
EFIAPI
CpuMpServicesWhoAmI (
  IN EFI_MP_SERVICES_PROTOCOL  *This,
  OUT UINTN                    *ProcessorNumber
  )
{
  UINTN   Index;
  UINT64  ProcessorId;

  if (ProcessorNumber == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  ProcessorId = gThread->Self ();
  for (Index = 0; Index < gMPSystem.NumberOfProcessors; Index++) {
    if (gMPSystem.ProcessorData[Index].Info.ProcessorId == ProcessorId) {
      break;
    }
  }

  *ProcessorNumber = Index;
  return EFI_SUCCESS;
}



EFI_MP_SERVICES_PROTOCOL  mMpServicesTemplate = {
  CpuMpServicesGetNumberOfProcessors,
  CpuMpServicesGetProcessorInfo,
  CpuMpServicesStartupAllAps,
  CpuMpServicesStartupThisAP,
  CpuMpServicesSwitchBSP,
  CpuMpServicesEnableDisableAP,
  CpuMpServicesWhoAmI
};



/*++
  If timeout occurs in StartupAllAps(), a timer is set, which invokes this
  procedure periodically to check whether all APs have finished.


--*/
VOID
EFIAPI
CpuCheckAllAPsStatus (
  IN  EFI_EVENT   Event,
  IN  VOID        *Context
  )
{
  UINTN                 ProcessorNumber;
  UINTN                 NextNumber;
  PROCESSOR_DATA_BLOCK  *ProcessorData;
  PROCESSOR_DATA_BLOCK  *NextData;
  EFI_STATUS            Status;
  PROCESSOR_STATE       ProcessorState;
  UINTN                 Cpu;
  BOOLEAN               Found;

  if (gMPSystem.TimeoutActive) {
    gMPSystem.Timeout -= CalculateAndStallInterval (gMPSystem.Timeout);
  }

  for (ProcessorNumber = 0; ProcessorNumber < gMPSystem.NumberOfProcessors; ProcessorNumber++) {
    ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];
    if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
     // Skip BSP
      continue;
    }

    if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
      // Skip Disabled processors
      continue;
    }

    // This is an Interrupt Service routine.
    // This can grab a lock that is held in a non-interrupt
    // context. Meaning deadlock. Which is a bad thing.
    // So, try lock it. If we can get it, cool, do our thing.
    // otherwise, just dump out & try again on the next iteration.
    Status = gThread->MutexTryLock (ProcessorData->StateLock);
    if (EFI_ERROR(Status)) {
      return;
    }
    ProcessorState = ProcessorData->State;
    gThread->MutexUnlock (ProcessorData->StateLock);

    switch (ProcessorState) {
    case CPU_STATE_FINISHED:
      if (gMPSystem.SingleThread) {
        Status = GetNextBlockedNumber (&NextNumber);
        if (!EFI_ERROR (Status)) {
          NextData = &gMPSystem.ProcessorData[NextNumber];

          gThread->MutexLock (NextData->StateLock);
          NextData->State = CPU_STATE_READY;
          gThread->MutexUnlock (NextData->StateLock);

          SetApProcedure (NextData, gMPSystem.Procedure, gMPSystem.ProcedureArgument);
        }
      }

      gThread->MutexLock (ProcessorData->StateLock);
      ProcessorData->State = CPU_STATE_IDLE;
      gThread->MutexUnlock (ProcessorData->StateLock);
      gMPSystem.FinishCount++;
      break;

    default:
      break;
    }
  }

  if (gMPSystem.TimeoutActive && gMPSystem.Timeout == 0) {
    //
    // Timeout
    //
    if (gMPSystem.FailedList != NULL) {
      for (ProcessorNumber = 0; ProcessorNumber < gMPSystem.NumberOfProcessors; ProcessorNumber++) {
        ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];
        if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
         // Skip BSP
          continue;
        }

        if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
          // Skip Disabled processors
          continue;
        }

        // Mark the
        Status = gThread->MutexTryLock (ProcessorData->StateLock);
        if (EFI_ERROR(Status)) {
          return;
        }
        ProcessorState = ProcessorData->State;
        gThread->MutexUnlock (ProcessorData->StateLock);

        if (ProcessorState != CPU_STATE_IDLE) {
          // If we are retrying make sure we don't double count
          for (Cpu = 0, Found = FALSE; Cpu < gMPSystem.NumberOfProcessors; Cpu++) {
            if (gMPSystem.FailedList[Cpu] == END_OF_CPU_LIST) {
              break;
            }
            if (gMPSystem.FailedList[ProcessorNumber] == Cpu) {
              Found = TRUE;
              break;
            }
          }
          if (!Found) {
            gMPSystem.FailedList[gMPSystem.FailedListIndex++] = Cpu;
          }
        }
      }
    }
    // Force terminal exit
    gMPSystem.FinishCount = gMPSystem.StartCount;
  }

  if (gMPSystem.FinishCount != gMPSystem.StartCount) {
    return;
  }

  gBS->SetTimer (
         gMPSystem.CheckAllAPsEvent,
         TimerCancel,
         0
         );

  if (gMPSystem.FailedListIndex == 0) {
    if (gMPSystem.FailedList != NULL) {
      FreePool (gMPSystem.FailedList);
      gMPSystem.FailedList = NULL;
    }
  }

  Status = gBS->SignalEvent (gMPSystem.WaitEvent);

  return ;
}

VOID
EFIAPI
CpuCheckThisAPStatus (
  IN  EFI_EVENT                           Event,
  IN  VOID                                *Context
  )
{
  EFI_STATUS            Status;
  PROCESSOR_DATA_BLOCK  *ProcessorData;
  PROCESSOR_STATE       ProcessorState;

  ProcessorData = (PROCESSOR_DATA_BLOCK *) Context;

  //
  // This is an Interrupt Service routine.
  // that can grab a lock that is held in a non-interrupt
  // context. Meaning deadlock. Which is a badddd thing.
  // So, try lock it. If we can get it, cool, do our thing.
  // otherwise, just dump out & try again on the next iteration.
  //
  Status = gThread->MutexTryLock (ProcessorData->StateLock);
  if (EFI_ERROR(Status)) {
    return;
  }
  ProcessorState = ProcessorData->State;
  gThread->MutexUnlock (ProcessorData->StateLock);

  if (ProcessorState == CPU_STATE_FINISHED) {
    Status = gBS->SetTimer (ProcessorData->CheckThisAPEvent, TimerCancel, 0);
    ASSERT_EFI_ERROR (Status);

    Status = gBS->SignalEvent (gMPSystem.WaitEvent);
    ASSERT_EFI_ERROR (Status);

    gThread->MutexLock (ProcessorData->StateLock);
    ProcessorData->State = CPU_STATE_IDLE;
    gThread->MutexUnlock (ProcessorData->StateLock);
  }

  return ;
}


/*++
  This function is called by all processors (both BSP and AP) once and collects MP related data

  MPSystemData  - Pointer to the data structure containing MP related data
  BSP           - TRUE if the CPU is BSP

  EFI_SUCCESS   - Data for the processor collected and filled in

--*/
EFI_STATUS
FillInProcessorInformation (
  IN     BOOLEAN              BSP,
  IN     UINTN                ProcessorNumber
  )
{
  gMPSystem.ProcessorData[ProcessorNumber].Info.ProcessorId  = gThread->Self ();
  gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag   = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;
  if (BSP) {
    gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;
  }

  gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Package = (UINT32) ProcessorNumber;
  gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Core    = 0;
  gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Thread  = 0;
  gMPSystem.ProcessorData[ProcessorNumber].State = BSP ? CPU_STATE_BUSY : CPU_STATE_IDLE;

  gMPSystem.ProcessorData[ProcessorNumber].Procedure        = NULL;
  gMPSystem.ProcessorData[ProcessorNumber].Parameter        = NULL;
  gMPSystem.ProcessorData[ProcessorNumber].StateLock        = gThread->MutexInit ();
  gMPSystem.ProcessorData[ProcessorNumber].ProcedureLock    = gThread->MutexInit ();

  return EFI_SUCCESS;
}

VOID *
EFIAPI
CpuDriverApIdolLoop (
  VOID  *Context
  )
{
  EFI_AP_PROCEDURE      Procedure;
  VOID                  *Parameter;
  UINTN                 ProcessorNumber;
  PROCESSOR_DATA_BLOCK  *ProcessorData;

  ProcessorNumber = (UINTN)Context;
  ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];

  ProcessorData->Info.ProcessorId = gThread->Self ();

  while (TRUE) {
    //
    // Make a local copy on the stack to be extra safe
    //
    gThread->MutexLock (ProcessorData->ProcedureLock);
    Procedure = ProcessorData->Procedure;
    Parameter = ProcessorData->Parameter;
    gThread->MutexUnlock (ProcessorData->ProcedureLock);

    if (Procedure != NULL) {
      gThread->MutexLock (ProcessorData->StateLock);
      ProcessorData->State = CPU_STATE_BUSY;
      gThread->MutexUnlock (ProcessorData->StateLock);

      Procedure (Parameter);

      gThread->MutexLock (ProcessorData->ProcedureLock);
      ProcessorData->Procedure = NULL;
      gThread->MutexUnlock (ProcessorData->ProcedureLock);

      gThread->MutexLock (ProcessorData->StateLock);
      ProcessorData->State = CPU_STATE_FINISHED;
      gThread->MutexUnlock (ProcessorData->StateLock);
    }

    // Poll 5 times a seconds, 200ms
    // Don't want to burn too many system resources doing nothing.
    gEmuThunk->Sleep (200 * 1000);
  }

  return 0;
}


EFI_STATUS
InitializeMpSystemData (
  IN   UINTN     NumberOfProcessors
  )
{
  EFI_STATUS              Status;
  UINTN                   Index;


  //
  // Clear the data structure area first.
  //
  ZeroMem (&gMPSystem, sizeof (MP_SYSTEM_DATA));

  //
  // First BSP fills and inits all known values, including it's own records.
  //
  gMPSystem.NumberOfProcessors         = NumberOfProcessors;
  gMPSystem.NumberOfEnabledProcessors  = NumberOfProcessors;

  gMPSystem.ProcessorData = AllocateZeroPool (gMPSystem.NumberOfProcessors * sizeof (PROCESSOR_DATA_BLOCK));
  ASSERT (gMPSystem.ProcessorData != NULL);

  FillInProcessorInformation (TRUE, 0);

  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  CpuCheckAllAPsStatus,
                  NULL,
                  &gMPSystem.CheckAllAPsEvent
                  );
  ASSERT_EFI_ERROR (Status);


  for (Index = 0; Index < gMPSystem.NumberOfProcessors; Index++) {
    if ((gMPSystem.ProcessorData[Index].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
     // Skip BSP
      continue;
    }

    FillInProcessorInformation (FALSE, Index);

    Status = gThread->CreateThread (
                        (VOID *)&gMPSystem.ProcessorData[Index].Info.ProcessorId,
                        NULL,
                        CpuDriverApIdolLoop,
                        (VOID *)Index
                        );


    Status = gBS->CreateEvent (
                         EVT_TIMER | EVT_NOTIFY_SIGNAL,
                         TPL_CALLBACK,
                         CpuCheckThisAPStatus,
                         (VOID *)  &gMPSystem.ProcessorData[Index],
                         &gMPSystem.ProcessorData[Index].CheckThisAPEvent
                         );
  }

  return EFI_SUCCESS;
}



/**
  Invoke a notification event

  @param  Event                 Event whose notification function is being invoked.
  @param  Context               The pointer to the notification function's context,
                                which is implementation-dependent.

**/
VOID
EFIAPI
CpuReadToBootFunction (
  IN  EFI_EVENT                Event,
  IN  VOID                     *Context
  )
{
  gReadToBoot = TRUE;
}



EFI_STATUS
CpuMpServicesInit (
  OUT UINTN *MaxCpus
  )
{
  EFI_STATUS              Status;
  EFI_HANDLE              Handle;
  EMU_IO_THUNK_PROTOCOL   *IoThunk;

  *MaxCpus = 1; // BSP
  IoThunk = GetIoThunkInstance (&gEmuThreadThunkProtocolGuid, 0);
  if (IoThunk != NULL) {
    Status = IoThunk->Open (IoThunk);
    if (!EFI_ERROR (Status)) {
      if (IoThunk->ConfigString != NULL) {
        *MaxCpus += StrDecimalToUintn (IoThunk->ConfigString);
        gThread = IoThunk->Interface;
      }
    }
  }

  if (*MaxCpus == 1) {
    // We are not MP so nothing to do
    return EFI_SUCCESS;
  }

  gPollInterval = (UINTN) PcdGet64 (PcdEmuMpServicesPollingInterval);

  Status  = InitializeMpSystemData (*MaxCpus);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = EfiCreateEventReadyToBootEx (TPL_CALLBACK, CpuReadToBootFunction, NULL, &gReadToBootEvent);
  ASSERT_EFI_ERROR (Status);

  //
  // Now install the MP services protocol.
  //
  Handle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEfiMpServiceProtocolGuid,   &mMpServicesTemplate,
                  NULL
                  );
  return Status;
}


