Esempio n. 1
0
/**
  Initialize global data for MP support.

  @param[in] CpuMpData  The pointer to CPU MP Data structure.
**/
VOID
InitMpGlobalData (
  IN CPU_MP_DATA               *CpuMpData
  )
{
  EFI_STATUS      Status;

  SaveCpuMpData (CpuMpData);
  //
  // Register an event for EndOfPei
  //
  Status  = PeiServicesNotifyPpi (&mMpInitLibNotifyList);
  ASSERT_EFI_ERROR (Status);
}
/**
  Initialize global data for MP support.

  @param[in] CpuMpData  The pointer to CPU MP Data structure.
**/
VOID
InitMpGlobalData (
  IN CPU_MP_DATA               *CpuMpData
  )
{
  EFI_STATUS  Status;

  SaveCpuMpData (CpuMpData);

  ///
  /// Install Notify
  ///
  Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc);
  ASSERT_EFI_ERROR (Status);
}
Esempio n. 3
0
/**
  Initialize global data for MP support.

  @param[in] CpuMpData  The pointer to CPU MP Data structure.
**/
VOID
InitMpGlobalData (
  IN CPU_MP_DATA               *CpuMpData
  )
{
  EFI_STATUS      Status;

  SaveCpuMpData (CpuMpData);

  if (CpuMpData->CpuCount == 1) {
    //
    // If only BSP exists, return
    //
    return;
  }

  //
  // Register an event for EndOfPei
  //
  Status  = PeiServicesNotifyPpi (&mMpInitLibNotifyList);
  ASSERT_EFI_ERROR (Status);
}
Esempio n. 4
0
/**
  Initialize global data for MP support.

  @param[in] CpuMpData  The pointer to CPU MP Data structure.
**/
VOID
InitMpGlobalData (
  IN CPU_MP_DATA               *CpuMpData
  )
{
  EFI_STATUS                          Status;
  EFI_PHYSICAL_ADDRESS                Address;
  UINTN                               ApSafeBufferSize;
  UINTN                               Index;
  EFI_GCD_MEMORY_SPACE_DESCRIPTOR     MemDesc;
  UINTN                               StackBase;
  CPU_INFO_IN_HOB                     *CpuInfoInHob;

  SaveCpuMpData (CpuMpData);

  if (CpuMpData->CpuCount == 1) {
    //
    // If only BSP exists, return
    //
    return;
  }

  if (PcdGetBool (PcdCpuStackGuard)) {
    //
    // One extra page at the bottom of the stack is needed for Guard page.
    //
    if (CpuMpData->CpuApStackSize <= EFI_PAGE_SIZE) {
      DEBUG ((DEBUG_ERROR, "PcdCpuApStackSize is not big enough for Stack Guard!\n"));
      ASSERT (FALSE);
    }

    //
    // DXE will reuse stack allocated for APs at PEI phase if it's available.
    // Let's check it here.
    //
    // Note: BSP's stack guard is set at DxeIpl phase. But for the sake of
    // BSP/AP exchange, stack guard for ApTopOfStack of cpu 0 will still be
    // set here.
    //
    CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
    for (Index = 0; Index < CpuMpData->CpuCount; ++Index) {
      if (CpuInfoInHob != NULL && CpuInfoInHob[Index].ApTopOfStack != 0) {
        StackBase = (UINTN)CpuInfoInHob[Index].ApTopOfStack - CpuMpData->CpuApStackSize;
      } else {
        StackBase = CpuMpData->Buffer + Index * CpuMpData->CpuApStackSize;
      }

      Status = gDS->GetMemorySpaceDescriptor (StackBase, &MemDesc);
      ASSERT_EFI_ERROR (Status);

      Status = gDS->SetMemorySpaceAttributes (
                      StackBase,
                      EFI_PAGES_TO_SIZE (1),
                      MemDesc.Attributes | EFI_MEMORY_RP
                      );
      ASSERT_EFI_ERROR (Status);

      DEBUG ((DEBUG_INFO, "Stack Guard set at %lx [cpu%lu]!\n",
              (UINT64)StackBase, (UINT64)Index));
    }
  }

  //
  // Avoid APs access invalid buffer data which allocated by BootServices,
  // so we will allocate reserved data for AP loop code. We also need to
  // allocate this buffer below 4GB due to APs may be transferred to 32bit
  // protected mode on long mode DXE.
  // Allocating it in advance since memory services are not available in
  // Exit Boot Services callback function.
  //
  ApSafeBufferSize  = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (
                        CpuMpData->AddressMap.RelocateApLoopFuncSize
                        ));
  Address = BASE_4GB - 1;
  Status  = gBS->AllocatePages (
                   AllocateMaxAddress,
                   EfiReservedMemoryType,
                   EFI_SIZE_TO_PAGES (ApSafeBufferSize),
                   &Address
                   );
  ASSERT_EFI_ERROR (Status);

  mReservedApLoopFunc = (VOID *) (UINTN) Address;
  ASSERT (mReservedApLoopFunc != NULL);

  //
  // Make sure that the buffer memory is executable if NX protection is enabled
  // for EfiReservedMemoryType.
  //
  // TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
  //       service.
  //
  Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc);
  if (!EFI_ERROR (Status)) {
    gDS->SetMemorySpaceAttributes (
           Address,
           ApSafeBufferSize,
           MemDesc.Attributes & (~EFI_MEMORY_XP)
           );
  }

  ApSafeBufferSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (
                       CpuMpData->CpuCount * AP_SAFE_STACK_SIZE
                       ));
  Address = BASE_4GB - 1;
  Status  = gBS->AllocatePages (
                   AllocateMaxAddress,
                   EfiReservedMemoryType,
                   EFI_SIZE_TO_PAGES (ApSafeBufferSize),
                   &Address
                   );
  ASSERT_EFI_ERROR (Status);

  mReservedTopOfApStack = (UINTN) Address + ApSafeBufferSize;
  ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
  CopyMem (
    mReservedApLoopFunc,
    CpuMpData->AddressMap.RelocateApLoopFuncAddress,
    CpuMpData->AddressMap.RelocateApLoopFuncSize
    );

  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  CheckApsStatus,
                  NULL,
                  &mCheckAllApsEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Set timer to check all APs status.
  //
  Status = gBS->SetTimer (
                  mCheckAllApsEvent,
                  TimerPeriodic,
                  AP_CHECK_INTERVAL
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->CreateEvent (
                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
                  TPL_CALLBACK,
                  MpInitChangeApLoopCallback,
                  NULL,
                  &mMpInitExitBootServicesEvent
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  MpInitChangeApLoopCallback,
                  NULL,
                  &gEfiEventLegacyBootGuid,
                  &mLegacyBootEvent
                  );
  ASSERT_EFI_ERROR (Status);
}
Esempio n. 5
0
/**
  Initialize global data for MP support.

  @param[in] CpuMpData  The pointer to CPU MP Data structure.
**/
VOID
InitMpGlobalData (
  IN CPU_MP_DATA               *CpuMpData
  )
{
  EFI_STATUS                 Status;
  EFI_PHYSICAL_ADDRESS       Address;
  UINTN                      ApSafeBufferSize;

  SaveCpuMpData (CpuMpData);

  if (CpuMpData->CpuCount == 1) {
    //
    // If only BSP exists, return
    //
    return;
  }

  //
  // Avoid APs access invalid buffer data which allocated by BootServices,
  // so we will allocate reserved data for AP loop code. We also need to
  // allocate this buffer below 4GB due to APs may be transferred to 32bit
  // protected mode on long mode DXE.
  // Allocating it in advance since memory services are not available in
  // Exit Boot Services callback function.
  //
  ApSafeBufferSize  = CpuMpData->AddressMap.RelocateApLoopFuncSize;
  ApSafeBufferSize += CpuMpData->CpuCount * AP_SAFE_STACK_SIZE;

  Address = BASE_4GB - 1;
  Status  = gBS->AllocatePages (
                   AllocateMaxAddress,
                   EfiReservedMemoryType,
                   EFI_SIZE_TO_PAGES (ApSafeBufferSize),
                   &Address
                   );
  ASSERT_EFI_ERROR (Status);
  mReservedApLoopFunc = (VOID *) (UINTN) Address;
  ASSERT (mReservedApLoopFunc != NULL);
  mReservedTopOfApStack = (UINTN) Address + EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (ApSafeBufferSize));
  ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
  CopyMem (
    mReservedApLoopFunc,
    CpuMpData->AddressMap.RelocateApLoopFuncAddress,
    CpuMpData->AddressMap.RelocateApLoopFuncSize
    );

  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  CheckApsStatus,
                  NULL,
                  &mCheckAllApsEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Set timer to check all APs status.
  //
  Status = gBS->SetTimer (
                  mCheckAllApsEvent,
                  TimerPeriodic,
                  AP_CHECK_INTERVAL
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->CreateEvent (
                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
                  TPL_CALLBACK,
                  MpInitChangeApLoopCallback,
                  NULL,
                  &mMpInitExitBootServicesEvent
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  MpInitChangeApLoopCallback,
                  NULL,
                  &gEfiEventLegacyBootGuid,
                  &mLegacyBootEvent
                  );
  ASSERT_EFI_ERROR (Status);
}