/** 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); }
/** 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); }
/** 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); }
/** 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); }