2 CPU DXE Module to produce CPU MP Protocol.
4 Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 UINTN gMaxLogicalProcessorNumber
;
20 UINTN gPollInterval
= 100; // 100 microseconds
22 MP_SYSTEM_DATA mMpSystemData
;
23 EFI_HANDLE mMpServiceHandle
= NULL
;
24 UINTN mNumberOfProcessors
= 1;
25 EFI_EVENT mExitBootServicesEvent
= (EFI_EVENT
)NULL
;
27 VOID
*mCommonStack
= 0;
28 VOID
*mTopOfApCommonStack
= 0;
29 VOID
*mApStackStart
= 0;
31 volatile BOOLEAN mAPsAlreadyInitFinished
= FALSE
;
33 EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate
= {
34 GetNumberOfProcessors
,
46 @param CpuData the pointer to CPU_DATA_BLOCK of specified processor
51 IN CPU_DATA_BLOCK
*CpuData
54 while (!AcquireSpinLockOrFail (&CpuData
->CpuDataLock
)) {
57 CpuData
->LockSelf
= GetApicId ();
61 Release Mp Service Lock.
63 @param CpuData the pointer to CPU_DATA_BLOCK of specified processor
68 IN CPU_DATA_BLOCK
*CpuData
71 ReleaseSpinLock (&CpuData
->CpuDataLock
);
75 Check whether caller processor is BSP.
77 @retval TRUE the caller is BSP
78 @retval FALSE the caller is AP
87 CPU_DATA_BLOCK
*CpuData
;
91 WhoAmI (&mMpServicesTemplate
, &CpuIndex
);
92 CpuData
= &mMpSystemData
.CpuDatas
[CpuIndex
];
94 return CpuData
->Info
.StatusFlag
& PROCESSOR_AS_BSP_BIT
? TRUE
: FALSE
;
98 Get the Application Processors state.
100 @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
102 @retval CPU_STATE the AP status
108 IN CPU_DATA_BLOCK
*CpuData
113 GetMpSpinLock (CpuData
);
114 State
= CpuData
->State
;
115 ReleaseMpSpinLock (CpuData
);
121 Set the Application Processors state.
123 @param CpuData The pointer to CPU_DATA_BLOCK of specified AP
124 @param State The AP status
130 IN CPU_DATA_BLOCK
*CpuData
,
134 GetMpSpinLock (CpuData
);
135 CpuData
->State
= State
;
136 ReleaseMpSpinLock (CpuData
);
140 Set the Application Processor prepare to run a function specified
143 @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
144 @param Procedure A pointer to the function to be run on enabled APs of the system
145 @param ProcedureArgument Pointer to the optional parameter of the assigned function
150 IN CPU_DATA_BLOCK
*CpuData
,
151 IN EFI_AP_PROCEDURE Procedure
,
152 IN VOID
*ProcedureArgument
155 GetMpSpinLock (CpuData
);
156 CpuData
->Parameter
= ProcedureArgument
;
157 CpuData
->Procedure
= Procedure
;
158 ReleaseMpSpinLock (CpuData
);
162 Check the Application Processors Status whether contains the Flags.
164 @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
165 @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION
167 @retval TRUE the AP status includes the StatusFlag
168 @retval FALSE the AP status excludes the StatusFlag
173 IN CPU_DATA_BLOCK
*CpuData
,
179 GetMpSpinLock (CpuData
);
180 Ret
= CpuData
->Info
.StatusFlag
& Flags
;
181 ReleaseMpSpinLock (CpuData
);
183 return (BOOLEAN
) (Ret
!= 0);
187 Bitwise-Or of the Application Processors Status with the Flags.
189 @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
190 @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION
195 IN CPU_DATA_BLOCK
*CpuData
,
199 GetMpSpinLock (CpuData
);
200 CpuData
->Info
.StatusFlag
|= Flags
;
201 ReleaseMpSpinLock (CpuData
);
205 Bitwise-AndNot of the Application Processors Status with the Flags.
207 @param CpuData the pointer to CPU_DATA_BLOCK of specified AP
208 @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION
212 CpuStatusFlagAndNot (
213 IN CPU_DATA_BLOCK
*CpuData
,
217 GetMpSpinLock (CpuData
);
218 CpuData
->Info
.StatusFlag
&= ~Flags
;
219 ReleaseMpSpinLock (CpuData
);
223 Searches for the next blocking AP.
225 Search for the next AP that is put in blocking state by single-threaded StartupAllAPs().
227 @param NextNumber Pointer to the processor number of the next blocking AP.
229 @retval EFI_SUCCESS The next blocking AP has been found.
230 @retval EFI_NOT_FOUND No blocking AP exists.
234 GetNextBlockedNumber (
235 OUT UINTN
*NextNumber
240 CPU_DATA_BLOCK
*CpuData
;
242 for (Number
= 0; Number
< mMpSystemData
.NumberOfProcessors
; Number
++) {
243 CpuData
= &mMpSystemData
.CpuDatas
[Number
];
244 if (TestCpuStatusFlag (CpuData
, PROCESSOR_AS_BSP_BIT
)) {
251 CpuState
= GetApState (CpuData
);
252 if (CpuState
== CpuStateBlocked
) {
253 *NextNumber
= Number
;
258 return EFI_NOT_FOUND
;
262 Check if the APs state are finished, and update them to idle state
267 CheckAndUpdateAllAPsToIdleState (
271 UINTN ProcessorNumber
;
273 CPU_DATA_BLOCK
*CpuData
;
277 for (ProcessorNumber
= 0; ProcessorNumber
< mMpSystemData
.NumberOfProcessors
; ProcessorNumber
++) {
278 CpuData
= &mMpSystemData
.CpuDatas
[ProcessorNumber
];
279 if (TestCpuStatusFlag (CpuData
, PROCESSOR_AS_BSP_BIT
)) {
286 if (!TestCpuStatusFlag (CpuData
, PROCESSOR_ENABLED_BIT
)) {
288 // Skip Disabled processors
293 CpuState
= GetApState (CpuData
);
294 if (CpuState
== CpuStateFinished
) {
295 mMpSystemData
.FinishCount
++;
296 if (mMpSystemData
.SingleThread
) {
297 Status
= GetNextBlockedNumber (&NextNumber
);
298 if (!EFI_ERROR (Status
)) {
299 SetApState (&mMpSystemData
.CpuDatas
[NextNumber
], CpuStateReady
);
300 SetApProcedure (&mMpSystemData
.CpuDatas
[NextNumber
],
301 mMpSystemData
.Procedure
,
302 mMpSystemData
.ProcedureArgument
);
304 // If this AP previous state is blocked, we should
305 // wake up this AP by sent a SIPI. and avoid
306 // re-involve the sleeping state. we must call
307 // SetApProcedure() first.
309 ResetProcessorToIdleState (&mMpSystemData
.CpuDatas
[NextNumber
]);
312 SetApState (CpuData
, CpuStateIdle
);
318 Check if all APs are in state CpuStateSleeping.
320 Return TRUE if all APs are in the CpuStateSleeping state. Do not
321 check the state of the BSP or any disabled APs.
323 @retval TRUE All APs are in CpuStateSleeping state.
324 @retval FALSE One or more APs are not in CpuStateSleeping state.
328 CheckAllAPsSleeping (
332 UINTN ProcessorNumber
;
333 CPU_DATA_BLOCK
*CpuData
;
335 for (ProcessorNumber
= 0; ProcessorNumber
< mMpSystemData
.NumberOfProcessors
; ProcessorNumber
++) {
336 CpuData
= &mMpSystemData
.CpuDatas
[ProcessorNumber
];
337 if (TestCpuStatusFlag (CpuData
, PROCESSOR_AS_BSP_BIT
)) {
344 if (!TestCpuStatusFlag (CpuData
, PROCESSOR_ENABLED_BIT
)) {
346 // Skip Disabled processors
351 if (GetApState (CpuData
) != CpuStateSleeping
) {
359 If the timeout expires before all APs returns from Procedure,
360 we should forcibly terminate the executing AP and fill FailedList back
369 CPU_DATA_BLOCK
*CpuData
;
373 if (mMpSystemData
.FailedList
!= NULL
) {
374 *mMpSystemData
.FailedList
= AllocatePool ((mMpSystemData
.StartCount
- mMpSystemData
.FinishCount
+ 1) * sizeof(UINTN
));
375 ASSERT (*mMpSystemData
.FailedList
!= NULL
);
378 for (Number
= 0; Number
< mMpSystemData
.NumberOfProcessors
; Number
++) {
379 CpuData
= &mMpSystemData
.CpuDatas
[Number
];
380 if (TestCpuStatusFlag (CpuData
, PROCESSOR_AS_BSP_BIT
)) {
387 if (!TestCpuStatusFlag (CpuData
, PROCESSOR_ENABLED_BIT
)) {
389 // Skip Disabled processors
394 CpuState
= GetApState (CpuData
);
395 if (CpuState
!= CpuStateIdle
&&
396 CpuState
!= CpuStateSleeping
) {
397 if (mMpSystemData
.FailedList
!= NULL
) {
398 (*mMpSystemData
.FailedList
)[mMpSystemData
.FailedListIndex
++] = Number
;
400 ResetProcessorToIdleState (CpuData
);
404 if (mMpSystemData
.FailedList
!= NULL
) {
405 (*mMpSystemData
.FailedList
)[mMpSystemData
.FailedListIndex
] = END_OF_CPU_LIST
;
410 This service retrieves the number of logical processor in the platform
411 and the number of those logical processors that are enabled on this boot.
412 This service may only be called from the BSP.
414 This function is used to retrieve the following information:
415 - The number of logical processors that are present in the system.
416 - The number of enabled logical processors in the system at the instant
419 Because MP Service Protocol provides services to enable and disable processors
420 dynamically, the number of enabled logical processors may vary during the
421 course of a boot session.
423 If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
424 If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
425 EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
426 is returned in NumberOfProcessors, the number of currently enabled processor
427 is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
429 @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
431 @param[out] NumberOfProcessors Pointer to the total number of logical
432 processors in the system, including the BSP
434 @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
435 processors that exist in system, including
438 @retval EFI_SUCCESS The number of logical processors and enabled
439 logical processors was retrieved.
440 @retval EFI_DEVICE_ERROR The calling processor is an AP.
441 @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
442 @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL.
447 GetNumberOfProcessors (
448 IN EFI_MP_SERVICES_PROTOCOL
*This
,
449 OUT UINTN
*NumberOfProcessors
,
450 OUT UINTN
*NumberOfEnabledProcessors
453 if ((NumberOfProcessors
== NULL
) || (NumberOfEnabledProcessors
== NULL
)) {
454 return EFI_INVALID_PARAMETER
;
457 return MpInitLibGetNumberOfProcessors (
459 NumberOfEnabledProcessors
464 Gets detailed MP-related information on the requested processor at the
465 instant this call is made. This service may only be called from the BSP.
467 This service retrieves detailed MP-related information about any processor
468 on the platform. Note the following:
469 - The processor information may change during the course of a boot session.
470 - The information presented here is entirely MP related.
472 Information regarding the number of caches and their sizes, frequency of operation,
473 slot numbers is all considered platform-related information and is not provided
476 @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
478 @param[in] ProcessorNumber The handle number of processor.
479 @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
480 the requested processor is deposited.
482 @retval EFI_SUCCESS Processor information was returned.
483 @retval EFI_DEVICE_ERROR The calling processor is an AP.
484 @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
485 @retval EFI_NOT_FOUND The processor with the handle specified by
486 ProcessorNumber does not exist in the platform.
492 IN EFI_MP_SERVICES_PROTOCOL
*This
,
493 IN UINTN ProcessorNumber
,
494 OUT EFI_PROCESSOR_INFORMATION
*ProcessorInfoBuffer
497 return MpInitLibGetProcessorInfo (ProcessorNumber
, ProcessorInfoBuffer
, NULL
);
501 This service executes a caller provided function on all enabled APs. APs can
502 run either simultaneously or one at a time in sequence. This service supports
503 both blocking and non-blocking requests. The non-blocking requests use EFI
504 events so the BSP can detect when the APs have finished. This service may only
505 be called from the BSP.
507 This function is used to dispatch all the enabled APs to the function specified
508 by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
509 immediately and Procedure is not started on any AP.
511 If SingleThread is TRUE, all the enabled APs execute the function specified by
512 Procedure one by one, in ascending order of processor handle number. Otherwise,
513 all the enabled APs execute the function specified by Procedure simultaneously.
515 If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
516 APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in non-blocking
517 mode, and the BSP returns from this service without waiting for APs. If a
518 non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
519 is signaled, then EFI_UNSUPPORTED must be returned.
521 If the timeout specified by TimeoutInMicroseconds expires before all APs return
522 from Procedure, then Procedure on the failed APs is terminated. All enabled APs
523 are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
524 and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
525 content points to the list of processor handle numbers in which Procedure was
528 Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
529 to make sure that the nature of the code that is executed on the BSP and the
530 dispatched APs is well controlled. The MP Services Protocol does not guarantee
531 that the Procedure function is MP-safe. Hence, the tasks that can be run in
532 parallel are limited to certain independent tasks and well-controlled exclusive
533 code. EFI services and protocols may not be called by APs unless otherwise
536 In blocking execution mode, BSP waits until all APs finish or
537 TimeoutInMicroseconds expires.
539 In non-blocking execution mode, BSP is freed to return to the caller and then
540 proceed to the next task without having to wait for APs. The following
541 sequence needs to occur in a non-blocking execution mode:
543 -# The caller that intends to use this MP Services Protocol in non-blocking
544 mode creates WaitEvent by calling the EFI CreateEvent() service. The caller
545 invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
546 is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
547 the function specified by Procedure to be started on all the enabled APs,
548 and releases the BSP to continue with other tasks.
549 -# The caller can use the CheckEvent() and WaitForEvent() services to check
550 the state of the WaitEvent created in step 1.
551 -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
552 Service signals WaitEvent by calling the EFI SignalEvent() function. If
553 FailedCpuList is not NULL, its content is available when WaitEvent is
554 signaled. If all APs returned from Procedure prior to the timeout, then
555 FailedCpuList is set to NULL. If not all APs return from Procedure before
556 the timeout, then FailedCpuList is filled in with the list of the failed
557 APs. The buffer is allocated by MP Service Protocol using AllocatePool().
558 It is the caller's responsibility to free the buffer with FreePool() service.
559 -# This invocation of SignalEvent() function informs the caller that invoked
560 EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
561 the specified task or a timeout occurred. The contents of FailedCpuList
562 can be examined to determine which APs did not complete the specified task
563 prior to the timeout.
565 @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
567 @param[in] Procedure A pointer to the function to be run on
568 enabled APs of the system. See type
570 @param[in] SingleThread If TRUE, then all the enabled APs execute
571 the function specified by Procedure one by
572 one, in ascending order of processor handle
573 number. If FALSE, then all the enabled APs
574 execute the function specified by Procedure
576 @param[in] WaitEvent The event created by the caller with CreateEvent()
577 service. If it is NULL, then execute in
578 blocking mode. BSP waits until all APs finish
579 or TimeoutInMicroseconds expires. If it's
580 not NULL, then execute in non-blocking mode.
581 BSP requests the function specified by
582 Procedure to be started on all the enabled
583 APs, and go on executing immediately. If
584 all return from Procedure, or TimeoutInMicroseconds
585 expires, this event is signaled. The BSP
586 can use the CheckEvent() or WaitForEvent()
587 services to check the state of event. Type
588 EFI_EVENT is defined in CreateEvent() in
589 the Unified Extensible Firmware Interface
591 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
592 APs to return from Procedure, either for
593 blocking or non-blocking mode. Zero means
594 infinity. If the timeout expires before
595 all APs return from Procedure, then Procedure
596 on the failed APs is terminated. All enabled
597 APs are available for next function assigned
598 by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
599 or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
600 If the timeout expires in blocking mode,
601 BSP returns EFI_TIMEOUT. If the timeout
602 expires in non-blocking mode, WaitEvent
603 is signaled with SignalEvent().
604 @param[in] ProcedureArgument The parameter passed into Procedure for
606 @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
607 if all APs finish successfully, then its
608 content is set to NULL. If not all APs
609 finish before timeout expires, then its
610 content is set to address of the buffer
611 holding handle numbers of the failed APs.
612 The buffer is allocated by MP Service Protocol,
613 and it's the caller's responsibility to
614 free the buffer with FreePool() service.
615 In blocking mode, it is ready for consumption
616 when the call returns. In non-blocking mode,
617 it is ready when WaitEvent is signaled. The
618 list of failed CPU is terminated by
621 @retval EFI_SUCCESS In blocking mode, all APs have finished before
623 @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
625 @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
626 UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
628 @retval EFI_DEVICE_ERROR Caller processor is AP.
629 @retval EFI_NOT_STARTED No enabled APs exist in the system.
630 @retval EFI_NOT_READY Any enabled APs are busy.
631 @retval EFI_TIMEOUT In blocking mode, the timeout expired before
632 all enabled APs have finished.
633 @retval EFI_INVALID_PARAMETER Procedure is NULL.
639 IN EFI_MP_SERVICES_PROTOCOL
*This
,
640 IN EFI_AP_PROCEDURE Procedure
,
641 IN BOOLEAN SingleThread
,
642 IN EFI_EVENT WaitEvent OPTIONAL
,
643 IN UINTN TimeoutInMicroseconds
,
644 IN VOID
*ProcedureArgument OPTIONAL
,
645 OUT UINTN
**FailedCpuList OPTIONAL
648 return MpInitLibStartupAllAPs (
652 TimeoutInMicroseconds
,
659 This service lets the caller get one enabled AP to execute a caller-provided
660 function. The caller can request the BSP to either wait for the completion
661 of the AP or just proceed with the next task by using the EFI event mechanism.
662 See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
663 execution support. This service may only be called from the BSP.
665 This function is used to dispatch one enabled AP to the function specified by
666 Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
667 is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
668 TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
669 BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
670 is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
671 then EFI_UNSUPPORTED must be returned.
673 If the timeout specified by TimeoutInMicroseconds expires before the AP returns
674 from Procedure, then execution of Procedure by the AP is terminated. The AP is
675 available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
676 EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
678 @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
680 @param[in] Procedure A pointer to the function to be run on
681 enabled APs of the system. See type
683 @param[in] ProcessorNumber The handle number of the AP. The range is
684 from 0 to the total number of logical
685 processors minus 1. The total number of
686 logical processors can be retrieved by
687 EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
688 @param[in] WaitEvent The event created by the caller with CreateEvent()
689 service. If it is NULL, then execute in
690 blocking mode. BSP waits until all APs finish
691 or TimeoutInMicroseconds expires. If it's
692 not NULL, then execute in non-blocking mode.
693 BSP requests the function specified by
694 Procedure to be started on all the enabled
695 APs, and go on executing immediately. If
696 all return from Procedure or TimeoutInMicroseconds
697 expires, this event is signaled. The BSP
698 can use the CheckEvent() or WaitForEvent()
699 services to check the state of event. Type
700 EFI_EVENT is defined in CreateEvent() in
701 the Unified Extensible Firmware Interface
703 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for
704 APs to return from Procedure, either for
705 blocking or non-blocking mode. Zero means
706 infinity. If the timeout expires before
707 all APs return from Procedure, then Procedure
708 on the failed APs is terminated. All enabled
709 APs are available for next function assigned
710 by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
711 or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
712 If the timeout expires in blocking mode,
713 BSP returns EFI_TIMEOUT. If the timeout
714 expires in non-blocking mode, WaitEvent
715 is signaled with SignalEvent().
716 @param[in] ProcedureArgument The parameter passed into Procedure for
718 @param[out] Finished If NULL, this parameter is ignored. In
719 blocking mode, this parameter is ignored.
720 In non-blocking mode, if AP returns from
721 Procedure before the timeout expires, its
722 content is set to TRUE. Otherwise, the
723 value is set to FALSE. The caller can
724 determine if the AP returned from Procedure
725 by evaluating this value.
727 @retval EFI_SUCCESS In blocking mode, specified AP finished before
729 @retval EFI_SUCCESS In non-blocking mode, the function has been
730 dispatched to specified AP.
731 @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
732 UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
734 @retval EFI_DEVICE_ERROR The calling processor is an AP.
735 @retval EFI_TIMEOUT In blocking mode, the timeout expired before
736 the specified AP has finished.
737 @retval EFI_NOT_READY The specified AP is busy.
738 @retval EFI_NOT_FOUND The processor with the handle specified by
739 ProcessorNumber does not exist.
740 @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
741 @retval EFI_INVALID_PARAMETER Procedure is NULL.
747 IN EFI_MP_SERVICES_PROTOCOL
*This
,
748 IN EFI_AP_PROCEDURE Procedure
,
749 IN UINTN ProcessorNumber
,
750 IN EFI_EVENT WaitEvent OPTIONAL
,
751 IN UINTN TimeoutInMicroseconds
,
752 IN VOID
*ProcedureArgument OPTIONAL
,
753 OUT BOOLEAN
*Finished OPTIONAL
756 return MpInitLibStartupThisAP (
760 TimeoutInMicroseconds
,
767 This service switches the requested AP to be the BSP from that point onward.
768 This service changes the BSP for all purposes. This call can only be performed
771 This service switches the requested AP to be the BSP from that point onward.
772 This service changes the BSP for all purposes. The new BSP can take over the
773 execution of the old BSP and continue seamlessly from where the old one left
774 off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
777 If the BSP cannot be switched prior to the return from this service, then
778 EFI_UNSUPPORTED must be returned.
780 @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
781 @param[in] ProcessorNumber The handle number of AP that is to become the new
782 BSP. The range is from 0 to the total number of
783 logical processors minus 1. The total number of
784 logical processors can be retrieved by
785 EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
786 @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
787 enabled AP. Otherwise, it will be disabled.
789 @retval EFI_SUCCESS BSP successfully switched.
790 @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
791 this service returning.
792 @retval EFI_UNSUPPORTED Switching the BSP is not supported.
793 @retval EFI_SUCCESS The calling processor is an AP.
794 @retval EFI_NOT_FOUND The processor with the handle specified by
795 ProcessorNumber does not exist.
796 @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
798 @retval EFI_NOT_READY The specified AP is busy.
804 IN EFI_MP_SERVICES_PROTOCOL
*This
,
805 IN UINTN ProcessorNumber
,
806 IN BOOLEAN EnableOldBSP
809 return MpInitLibSwitchBSP (ProcessorNumber
, EnableOldBSP
);
813 This service lets the caller enable or disable an AP from this point onward.
814 This service may only be called from the BSP.
816 This service allows the caller enable or disable an AP from this point onward.
817 The caller can optionally specify the health status of the AP by Health. If
818 an AP is being disabled, then the state of the disabled AP is implementation
819 dependent. If an AP is enabled, then the implementation must guarantee that a
820 complete initialization sequence is performed on the AP, so the AP is in a state
821 that is compatible with an MP operating system. This service may not be supported
822 after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
824 If the enable or disable AP operation cannot be completed prior to the return
825 from this service, then EFI_UNSUPPORTED must be returned.
827 @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
828 @param[in] ProcessorNumber The handle number of AP that is to become the new
829 BSP. The range is from 0 to the total number of
830 logical processors minus 1. The total number of
831 logical processors can be retrieved by
832 EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
833 @param[in] EnableAP Specifies the new state for the processor for
834 enabled, FALSE for disabled.
835 @param[in] HealthFlag If not NULL, a pointer to a value that specifies
836 the new health status of the AP. This flag
837 corresponds to StatusFlag defined in
838 EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
839 the PROCESSOR_HEALTH_STATUS_BIT is used. All other
840 bits are ignored. If it is NULL, this parameter
843 @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
844 @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
845 prior to this service returning.
846 @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
847 @retval EFI_DEVICE_ERROR The calling processor is an AP.
848 @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
850 @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
856 IN EFI_MP_SERVICES_PROTOCOL
*This
,
857 IN UINTN ProcessorNumber
,
859 IN UINT32
*HealthFlag OPTIONAL
862 return MpInitLibEnableDisableAP (ProcessorNumber
, EnableAP
, HealthFlag
);
866 This return the handle number for the calling processor. This service may be
867 called from the BSP and APs.
869 This service returns the processor handle number for the calling processor.
870 The returned value is in the range from 0 to the total number of logical
871 processors minus 1. The total number of logical processors can be retrieved
872 with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
873 called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
874 is returned. Otherwise, the current processors handle number is returned in
875 ProcessorNumber, and EFI_SUCCESS is returned.
877 @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
878 @param[out] ProcessorNumber The handle number of AP that is to become the new
879 BSP. The range is from 0 to the total number of
880 logical processors minus 1. The total number of
881 logical processors can be retrieved by
882 EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
884 @retval EFI_SUCCESS The current processor handle number was returned
886 @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
892 IN EFI_MP_SERVICES_PROTOCOL
*This
,
893 OUT UINTN
*ProcessorNumber
896 return MpInitLibWhoAmI (ProcessorNumber
);;
900 Collects BIST data from HOB.
902 This function collects BIST data from HOB built from Sec Platform Information
903 PPI or SEC Platform Information2 PPI.
907 CollectBistDataFromHob (
911 EFI_HOB_GUID_TYPE
*GuidHob
;
912 EFI_SEC_PLATFORM_INFORMATION_RECORD2
*SecPlatformInformation2
;
913 EFI_SEC_PLATFORM_INFORMATION_RECORD
*SecPlatformInformation
;
915 EFI_SEC_PLATFORM_INFORMATION_CPU
*CpuInstance
;
916 EFI_SEC_PLATFORM_INFORMATION_CPU BspCpuInstance
;
917 UINTN ProcessorNumber
;
918 EFI_PROCESSOR_INFORMATION ProcessorInfo
;
919 EFI_HEALTH_FLAGS BistData
;
921 SecPlatformInformation2
= NULL
;
922 SecPlatformInformation
= NULL
;
925 // Get gEfiSecPlatformInformation2PpiGuid Guided HOB firstly
927 GuidHob
= GetFirstGuidHob (&gEfiSecPlatformInformation2PpiGuid
);
928 if (GuidHob
!= NULL
) {
930 // Sec Platform Information2 PPI includes BSP/APs' BIST information
932 SecPlatformInformation2
= GET_GUID_HOB_DATA (GuidHob
);
933 NumberOfData
= SecPlatformInformation2
->NumberOfCpus
;
934 CpuInstance
= SecPlatformInformation2
->CpuInstance
;
937 // Otherwise, get gEfiSecPlatformInformationPpiGuid Guided HOB
939 GuidHob
= GetFirstGuidHob (&gEfiSecPlatformInformationPpiGuid
);
940 if (GuidHob
!= NULL
) {
941 SecPlatformInformation
= GET_GUID_HOB_DATA (GuidHob
);
944 // SEC Platform Information only includes BSP's BIST information
945 // does not have BSP's APIC ID
947 BspCpuInstance
.CpuLocation
= GetApicId ();
948 BspCpuInstance
.InfoRecord
.IA32HealthFlags
.Uint32
= SecPlatformInformation
->IA32HealthFlags
.Uint32
;
949 CpuInstance
= &BspCpuInstance
;
951 DEBUG ((EFI_D_INFO
, "Does not find any HOB stored CPU BIST information!\n"));
953 // Does not find any HOB stored BIST information
959 while ((NumberOfData
--) > 0) {
960 for (ProcessorNumber
= 0; ProcessorNumber
< mNumberOfProcessors
; ProcessorNumber
++) {
961 MpInitLibGetProcessorInfo (ProcessorNumber
, &ProcessorInfo
, &BistData
);
962 if (ProcessorInfo
.ProcessorId
== CpuInstance
[NumberOfData
].CpuLocation
) {
964 // Update CPU health status for MP Services Protocol according to BIST data.
966 BistData
= CpuInstance
[NumberOfData
].InfoRecord
.IA32HealthFlags
;
968 if (BistData
.Uint32
!= 0) {
970 // Report Status Code that self test is failed
973 EFI_ERROR_CODE
| EFI_ERROR_MAJOR
,
974 (EFI_COMPUTING_UNIT_HOST_PROCESSOR
| EFI_CU_HP_EC_SELF_TEST
)
982 Callback function for ExitBootServices.
984 @param Event Event whose notification function is being invoked.
985 @param Context The pointer to the notification function's context,
986 which is implementation-dependent.
991 ExitBootServicesCallback (
997 // Avoid APs access invalid buff datas which allocated by BootServices,
998 // so we send INIT IPI to APs to let them wait for SIPI state.
1000 SendInitIpiAllExcludingSelf ();
1004 A minimal wrapper function that allows MtrrSetAllMtrrs() to be passed to
1005 EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() as Procedure.
1007 @param[in] Buffer Pointer to an MTRR_SETTINGS object, to be passed to
1012 SetMtrrsFromBuffer (
1016 MtrrSetAllMtrrs (Buffer
);
1020 Initialize Multi-processor support.
1024 InitializeMpSupport (
1029 UINTN NumberOfProcessors
;
1030 UINTN NumberOfEnabledProcessors
;
1032 NumberOfProcessors
= (UINTN
) PcdGet32 (PcdCpuMaxLogicalProcessorNumber
);
1033 if (NumberOfProcessors
< 1) {
1034 DEBUG ((DEBUG_ERROR
, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n"));
1039 // Only perform AP detection if PcdCpuMaxLogicalProcessorNumber is greater than 1
1041 if (NumberOfProcessors
> 1) {
1042 Status
= MpInitLibInitialize ();
1043 ASSERT_EFI_ERROR (Status
);
1045 MpInitLibGetNumberOfProcessors (&NumberOfProcessors
, &NumberOfEnabledProcessors
);
1046 mNumberOfProcessors
= NumberOfProcessors
;
1048 DEBUG ((EFI_D_ERROR
, "Detect CPU count: %d\n", mNumberOfProcessors
));
1051 // Update CPU healthy information from Guided HOB
1053 CollectBistDataFromHob ();
1055 Status
= gBS
->InstallMultipleProtocolInterfaces (
1057 &gEfiMpServiceProtocolGuid
, &mMpServicesTemplate
,
1060 ASSERT_EFI_ERROR (Status
);