Beispiel #1
0
/**
  Do sync on APs.

  @param[in, out] Buffer  Pointer to private data buffer.
**/
VOID
EFIAPI
RelocateApLoop (
  IN OUT VOID  *Buffer
  )
{
  CPU_MP_DATA            *CpuMpData;
  BOOLEAN                MwaitSupport;
  ASM_RELOCATE_AP_LOOP   AsmRelocateApLoopFunc;
  UINTN                  ProcessorNumber;

  MpInitLibWhoAmI (&ProcessorNumber);
  CpuMpData    = GetCpuMpData ();
  MwaitSupport = IsMwaitSupport ();
  AsmRelocateApLoopFunc = (ASM_RELOCATE_AP_LOOP) (UINTN) mReservedApLoopFunc;
  AsmRelocateApLoopFunc (
    MwaitSupport,
    CpuMpData->ApTargetCState,
    CpuMpData->PmCodeSegment,
    mReservedTopOfApStack - ProcessorNumber * AP_SAFE_STACK_SIZE,
    (UINTN) &mNumberToFinish
    );
  //
  // It should never reach here
  //
  ASSERT (FALSE);
}
Beispiel #2
0
/**
  Notify function on End Of PEI PPI.

  On S3 boot, this function will restore wakeup buffer data.
  On normal boot, this function will flag wakeup buffer to be un-used type.

  @param[in]  PeiServices        The pointer to the PEI Services Table.
  @param[in]  NotifyDescriptor   Address of the notification descriptor data structure.
  @param[in]  Ppi                Address of the PPI that was installed.

  @retval EFI_SUCCESS        When everything is OK.
**/
EFI_STATUS
EFIAPI
CpuMpEndOfPeiCallback (
  IN EFI_PEI_SERVICES             **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR    *NotifyDescriptor,
  IN VOID                         *Ppi
  )
{
  EFI_STATUS                Status;
  EFI_BOOT_MODE             BootMode;
  CPU_MP_DATA               *CpuMpData;
  EFI_PEI_HOB_POINTERS      Hob;
  EFI_HOB_MEMORY_ALLOCATION *MemoryHob;

  DEBUG ((DEBUG_INFO, "PeiMpInitLib: CpuMpEndOfPeiCallback () invoked\n"));

  Status = PeiServicesGetBootMode (&BootMode);
  ASSERT_EFI_ERROR (Status);

  CpuMpData = GetCpuMpData ();
  if (BootMode != BOOT_ON_S3_RESUME) {
    //
    // Get the HOB list for processing
    //
    Hob.Raw = GetHobList ();
    //
    // Collect memory ranges
    //
    while (!END_OF_HOB_LIST (Hob)) {
      if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
        MemoryHob = Hob.MemoryAllocation;
        if (MemoryHob->AllocDescriptor.MemoryBaseAddress == CpuMpData->WakeupBuffer) {
          //
          // Flag this HOB type to un-used
          //
          GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED;
          break;
        }
      }
      Hob.Raw = GET_NEXT_HOB (Hob);
    }
  } else {
    CpuMpData->SaveRestoreFlag = TRUE;
    RestoreWakeupBuffer (CpuMpData);
  }
  return EFI_SUCCESS;
}
Beispiel #3
0
/**
  Callback function for ExitBootServices.

  @param[in]  Event             Event whose notification function is being invoked.
  @param[in]  Context           The pointer to the notification function's context,
                                which is implementation-dependent.

**/
VOID
EFIAPI
MpInitChangeApLoopCallback (
  IN EFI_EVENT                Event,
  IN VOID                     *Context
  )
{
  CPU_MP_DATA               *CpuMpData;

  CpuMpData = GetCpuMpData ();
  CpuMpData->PmCodeSegment = GetProtectedModeCS ();
  CpuMpData->ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
  mNumberToFinish = CpuMpData->CpuCount - 1;
  WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE);
  while (mNumberToFinish > 0) {
    CpuPause ();
  }
  DEBUG ((DEBUG_INFO, "%a() done!\n", __FUNCTION__));
}
Beispiel #4
0
/**
  Checks APs status and updates APs status if needed.

**/
VOID
CheckAndUpdateApsStatus (
  VOID
  )
{
  UINTN                   ProcessorNumber;
  EFI_STATUS              Status;
  CPU_MP_DATA             *CpuMpData;

  CpuMpData = GetCpuMpData ();

  //
  // First, check whether pending StartupAllAPs() exists.
  //
  if (CpuMpData->WaitEvent != NULL) {

    Status = CheckAllAPs ();
    //
    // If all APs finish for StartupAllAPs(), signal the WaitEvent for it.
    //
    if (Status != EFI_NOT_READY) {
      Status = gBS->SignalEvent (CpuMpData->WaitEvent);
      CpuMpData->WaitEvent = NULL;
    }
  }

  //
  // Second, check whether pending StartupThisAPs() callings exist.
  //
  for (ProcessorNumber = 0; ProcessorNumber < CpuMpData->CpuCount; ProcessorNumber++) {

    if (CpuMpData->CpuData[ProcessorNumber].WaitEvent == NULL) {
      continue;
    }

    Status = CheckThisAP (ProcessorNumber);

    if (Status != EFI_NOT_READY) {
      gBS->SignalEvent (CpuMpData->CpuData[ProcessorNumber].WaitEvent);
     CpuMpData->CpuData[ProcessorNumber].WaitEvent = NULL;
    }
  }
}
/**
  S3 SMM Init Done notification function.

  @param  PeiServices      Indirect reference to the PEI Services Table.
  @param  NotifyDesc       Address of the notification descriptor data structure.
  @param  InvokePpi        Address of the PPI that was invoked.

  @retval EFI_SUCCESS      The function completes successfully.

**/
EFI_STATUS
EFIAPI
NotifyOnS3SmmInitDonePpi (
  IN  EFI_PEI_SERVICES                              **PeiServices,
  IN  EFI_PEI_NOTIFY_DESCRIPTOR                     *NotifyDesc,
  IN  VOID                                          *InvokePpi
  )
{
  CPU_MP_DATA     *CpuMpData;

  CpuMpData = GetCpuMpData ();

  //
  // PiSmmCpuDxeSmm driver hardcode change the loop mode to HLT mode.
  // So in this notify function, code need to check the current loop
  // mode, if it is not HLT mode, code need to change loop mode back
  // to the original mode.
  //
  if (CpuMpData->ApLoopMode != ApInHltLoop) {
    CpuMpData->WakeUpByInitSipiSipi = TRUE;
  }

  return EFI_SUCCESS;
}