/* This function is intended to be invoked by the BSP in order to wake up the AP. The BSP accomplishes this by triggering a start-up signal, which in turn causes any APs that are currently in a loop on the PEI-prepared memory to awaken and begin running the procedure called SwitchContextPerAp. This procedure allows the AP to switch to another section of memory and continue its loop there. */
VOID SwitchApContext(IN MP_HAND_OFF *MpHandOff)
/* This function is intended to be invoked by the BSP in order to wake up the AP. The BSP accomplishes this by triggering a start-up signal, which in turn causes any APs that are currently in a loop on the PEI-prepared memory to awaken and begin running the procedure called SwitchContextPerAp. This procedure allows the AP to switch to another section of memory and continue its loop there. */
VOID SwitchApContext(IN MP_HAND_OFF *MpHandOff)
{
  UINTN   Index;
  UINT32  BspNumber;
  BspNumber = GetBspNumber (MpHandOff);
  for (Index = 0; Index < MpHandOff->CpuCount; Index++) {
    if (Index != BspNumber) {
      *(UINTN *)(UINTN)MpHandOff->Info[Index].StartupProcedureAddress = (UINTN)SwitchContextPerAp;
      *(UINT32 *)(UINTN)MpHandOff->Info[Index].StartupSignalAddress   = MpHandOff->StartupSignalValue;
    }
  }
  for (Index = 0; Index < MpHandOff->CpuCount; Index++) {
    if (Index != BspNumber) {
      WaitApWakeup ((UINT32 *)(UINTN)(MpHandOff->Info[Index].StartupSignalAddress));
    }
  }
}