2 CPU MP Initialize Library common functions.
4 Copyright (c) 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.
17 EFI_GUID mCpuInitMpLibHobGuid
= CPU_INIT_MP_LIB_HOB_GUID
;
20 The function will check if BSP Execute Disable is enabled.
21 DxeIpl may have enabled Execute Disable for BSP,
22 APs need to get the status and sync up the settings.
24 @retval TRUE BSP Execute Disable is enabled.
25 @retval FALSE BSP Execute Disable is not enabled.
28 IsBspExecuteDisableEnabled (
33 CPUID_EXTENDED_CPU_SIG_EDX Edx
;
34 MSR_IA32_EFER_REGISTER EferMsr
;
38 AsmCpuid (CPUID_EXTENDED_FUNCTION
, &Eax
, NULL
, NULL
, NULL
);
39 if (Eax
>= CPUID_EXTENDED_CPU_SIG
) {
40 AsmCpuid (CPUID_EXTENDED_CPU_SIG
, NULL
, NULL
, NULL
, &Edx
.Uint32
);
43 // Bit 20: Execute Disable Bit available.
45 if (Edx
.Bits
.NX
!= 0) {
46 EferMsr
.Uint64
= AsmReadMsr64 (MSR_IA32_EFER
);
49 // Bit 11: Execute Disable Bit enable.
51 if (EferMsr
.Bits
.NXE
!= 0) {
61 Get the Application Processors state.
63 @param[in] CpuData The pointer to CPU_AP_DATA of specified AP
69 IN CPU_AP_DATA
*CpuData
72 return CpuData
->State
;
76 Set the Application Processors state.
78 @param[in] CpuData The pointer to CPU_AP_DATA of specified AP
79 @param[in] State The AP status
83 IN CPU_AP_DATA
*CpuData
,
87 AcquireSpinLock (&CpuData
->ApLock
);
88 CpuData
->State
= State
;
89 ReleaseSpinLock (&CpuData
->ApLock
);
93 Save the volatile registers required to be restored following INIT IPI.
95 @param[out] VolatileRegisters Returns buffer saved the volatile resisters
98 SaveVolatileRegisters (
99 OUT CPU_VOLATILE_REGISTERS
*VolatileRegisters
102 CPUID_VERSION_INFO_EDX VersionInfoEdx
;
104 VolatileRegisters
->Cr0
= AsmReadCr0 ();
105 VolatileRegisters
->Cr3
= AsmReadCr3 ();
106 VolatileRegisters
->Cr4
= AsmReadCr4 ();
108 AsmCpuid (CPUID_VERSION_INFO
, NULL
, NULL
, NULL
, &VersionInfoEdx
.Uint32
);
109 if (VersionInfoEdx
.Bits
.DE
!= 0) {
111 // If processor supports Debugging Extensions feature
112 // by CPUID.[EAX=01H]:EDX.BIT2
114 VolatileRegisters
->Dr0
= AsmReadDr0 ();
115 VolatileRegisters
->Dr1
= AsmReadDr1 ();
116 VolatileRegisters
->Dr2
= AsmReadDr2 ();
117 VolatileRegisters
->Dr3
= AsmReadDr3 ();
118 VolatileRegisters
->Dr6
= AsmReadDr6 ();
119 VolatileRegisters
->Dr7
= AsmReadDr7 ();
124 Restore the volatile registers following INIT IPI.
126 @param[in] VolatileRegisters Pointer to volatile resisters
127 @param[in] IsRestoreDr TRUE: Restore DRx if supported
128 FALSE: Do not restore DRx
131 RestoreVolatileRegisters (
132 IN CPU_VOLATILE_REGISTERS
*VolatileRegisters
,
133 IN BOOLEAN IsRestoreDr
136 CPUID_VERSION_INFO_EDX VersionInfoEdx
;
138 AsmWriteCr0 (VolatileRegisters
->Cr0
);
139 AsmWriteCr3 (VolatileRegisters
->Cr3
);
140 AsmWriteCr4 (VolatileRegisters
->Cr4
);
143 AsmCpuid (CPUID_VERSION_INFO
, NULL
, NULL
, NULL
, &VersionInfoEdx
.Uint32
);
144 if (VersionInfoEdx
.Bits
.DE
!= 0) {
146 // If processor supports Debugging Extensions feature
147 // by CPUID.[EAX=01H]:EDX.BIT2
149 AsmWriteDr0 (VolatileRegisters
->Dr0
);
150 AsmWriteDr1 (VolatileRegisters
->Dr1
);
151 AsmWriteDr2 (VolatileRegisters
->Dr2
);
152 AsmWriteDr3 (VolatileRegisters
->Dr3
);
153 AsmWriteDr6 (VolatileRegisters
->Dr6
);
154 AsmWriteDr7 (VolatileRegisters
->Dr7
);
160 Detect whether Mwait-monitor feature is supported.
162 @retval TRUE Mwait-monitor feature is supported.
163 @retval FALSE Mwait-monitor feature is not supported.
170 CPUID_VERSION_INFO_ECX VersionInfoEcx
;
172 AsmCpuid (CPUID_VERSION_INFO
, NULL
, NULL
, &VersionInfoEcx
.Uint32
, NULL
);
173 return (VersionInfoEcx
.Bits
.MONITOR
== 1) ? TRUE
: FALSE
;
179 @param[out] MonitorFilterSize Returns the largest monitor-line size in bytes.
181 @return The AP loop mode.
185 OUT UINT32
*MonitorFilterSize
189 CPUID_MONITOR_MWAIT_EBX MonitorMwaitEbx
;
191 ASSERT (MonitorFilterSize
!= NULL
);
193 ApLoopMode
= PcdGet8 (PcdCpuApLoopMode
);
194 ASSERT (ApLoopMode
>= ApInHltLoop
&& ApLoopMode
<= ApInRunLoop
);
195 if (ApLoopMode
== ApInMwaitLoop
) {
196 if (!IsMwaitSupport ()) {
198 // If processor does not support MONITOR/MWAIT feature,
199 // force AP in Hlt-loop mode
201 ApLoopMode
= ApInHltLoop
;
205 if (ApLoopMode
!= ApInMwaitLoop
) {
206 *MonitorFilterSize
= sizeof (UINT32
);
209 // CPUID.[EAX=05H]:EBX.BIT0-15: Largest monitor-line size in bytes
210 // CPUID.[EAX=05H].EDX: C-states supported using MWAIT
212 AsmCpuid (CPUID_MONITOR_MWAIT
, NULL
, &MonitorMwaitEbx
.Uint32
, NULL
, NULL
);
213 *MonitorFilterSize
= MonitorMwaitEbx
.Bits
.LargestMonitorLineSize
;
222 @param[in, out] Buffer Pointer to private data buffer.
230 CPU_MP_DATA
*CpuMpData
;
232 CpuMpData
= (CPU_MP_DATA
*) Buffer
;
234 // Sync BSP's MTRR table to AP
236 MtrrSetAllMtrrs (&CpuMpData
->MtrrTable
);
238 // Load microcode on AP
240 MicrocodeDetect (CpuMpData
);
244 Find the current Processor number by APIC ID.
246 @param[in] CpuMpData Pointer to PEI CPU MP Data
247 @param[in] ProcessorNumber Return the pocessor number found
249 @retval EFI_SUCCESS ProcessorNumber is found and returned.
250 @retval EFI_NOT_FOUND ProcessorNumber is not found.
254 IN CPU_MP_DATA
*CpuMpData
,
255 OUT UINTN
*ProcessorNumber
258 UINTN TotalProcessorNumber
;
261 TotalProcessorNumber
= CpuMpData
->CpuCount
;
262 for (Index
= 0; Index
< TotalProcessorNumber
; Index
++) {
263 if (CpuMpData
->CpuData
[Index
].ApicId
== GetApicId ()) {
264 *ProcessorNumber
= Index
;
268 return EFI_NOT_FOUND
;
272 Initialize CPU AP Data when AP is wakeup at the first time.
274 @param[in, out] CpuMpData Pointer to PEI CPU MP Data
275 @param[in] ProcessorNumber The handle number of processor
276 @param[in] BistData Processor BIST data
281 IN OUT CPU_MP_DATA
*CpuMpData
,
282 IN UINTN ProcessorNumber
,
286 CpuMpData
->CpuData
[ProcessorNumber
].Waiting
= FALSE
;
287 CpuMpData
->CpuData
[ProcessorNumber
].Health
= BistData
;
288 CpuMpData
->CpuData
[ProcessorNumber
].CpuHealthy
= (BistData
== 0) ? TRUE
: FALSE
;
289 CpuMpData
->CpuData
[ProcessorNumber
].ApicId
= GetApicId ();
290 CpuMpData
->CpuData
[ProcessorNumber
].InitialApicId
= GetInitialApicId ();
291 if (CpuMpData
->CpuData
[ProcessorNumber
].InitialApicId
>= 0xFF) {
293 // Set x2APIC mode if there are any logical processor reporting
294 // an Initial APIC ID of 255 or greater.
296 AcquireSpinLock(&CpuMpData
->MpLock
);
297 CpuMpData
->X2ApicEnable
= TRUE
;
298 ReleaseSpinLock(&CpuMpData
->MpLock
);
301 InitializeSpinLock(&CpuMpData
->CpuData
[ProcessorNumber
].ApLock
);
302 SetApState (&CpuMpData
->CpuData
[ProcessorNumber
], CpuStateIdle
);
306 This function will be called from AP reset code if BSP uses WakeUpAP.
308 @param[in] ExchangeInfo Pointer to the MP exchange info buffer
309 @param[in] NumApsExecuting Number of current executing AP
314 IN MP_CPU_EXCHANGE_INFO
*ExchangeInfo
,
315 IN UINTN NumApsExecuting
318 CPU_MP_DATA
*CpuMpData
;
319 UINTN ProcessorNumber
;
320 EFI_AP_PROCEDURE Procedure
;
323 volatile UINT32
*ApStartupSignalBuffer
;
326 // AP finished assembly code and begin to execute C code
328 CpuMpData
= ExchangeInfo
->CpuMpData
;
330 ProgramVirtualWireMode ();
333 if (CpuMpData
->InitFlag
== ApInitConfig
) {
337 InterlockedIncrement ((UINT32
*) &CpuMpData
->CpuCount
);
338 ProcessorNumber
= NumApsExecuting
;
340 // This is first time AP wakeup, get BIST information from AP stack
342 BistData
= *(UINT32
*) (CpuMpData
->Buffer
+ ProcessorNumber
* CpuMpData
->CpuApStackSize
- sizeof (UINTN
));
344 // Do some AP initialize sync
346 ApInitializeSync (CpuMpData
);
348 // Sync BSP's Control registers to APs
350 RestoreVolatileRegisters (&CpuMpData
->CpuData
[0].VolatileRegisters
, FALSE
);
351 InitializeApData (CpuMpData
, ProcessorNumber
, BistData
);
352 ApStartupSignalBuffer
= CpuMpData
->CpuData
[ProcessorNumber
].StartupApSignal
;
355 // Execute AP function if AP is ready
357 GetProcessorNumber (CpuMpData
, &ProcessorNumber
);
359 // Clear AP start-up signal when AP waken up
361 ApStartupSignalBuffer
= CpuMpData
->CpuData
[ProcessorNumber
].StartupApSignal
;
362 InterlockedCompareExchange32 (
363 (UINT32
*) ApStartupSignalBuffer
,
367 if (CpuMpData
->ApLoopMode
== ApInHltLoop
) {
369 // Restore AP's volatile registers saved
371 RestoreVolatileRegisters (&CpuMpData
->CpuData
[ProcessorNumber
].VolatileRegisters
, TRUE
);
374 if (GetApState (&CpuMpData
->CpuData
[ProcessorNumber
]) == CpuStateReady
) {
375 Procedure
= (EFI_AP_PROCEDURE
)CpuMpData
->CpuData
[ProcessorNumber
].ApFunction
;
376 Parameter
= (VOID
*) CpuMpData
->CpuData
[ProcessorNumber
].ApFunctionArgument
;
377 if (Procedure
!= NULL
) {
378 SetApState (&CpuMpData
->CpuData
[ProcessorNumber
], CpuStateBusy
);
380 // Invoke AP function here
382 Procedure (Parameter
);
384 // Re-get the CPU APICID and Initial APICID
386 CpuMpData
->CpuData
[ProcessorNumber
].ApicId
= GetApicId ();
387 CpuMpData
->CpuData
[ProcessorNumber
].InitialApicId
= GetInitialApicId ();
389 SetApState (&CpuMpData
->CpuData
[ProcessorNumber
], CpuStateFinished
);
394 // AP finished executing C code
396 InterlockedIncrement ((UINT32
*) &CpuMpData
->FinishedCount
);
399 // Place AP is specified loop mode
401 if (CpuMpData
->ApLoopMode
== ApInHltLoop
) {
403 // Save AP volatile registers
405 SaveVolatileRegisters (&CpuMpData
->CpuData
[ProcessorNumber
].VolatileRegisters
);
407 // Place AP in HLT-loop
410 DisableInterrupts ();
416 DisableInterrupts ();
417 if (CpuMpData
->ApLoopMode
== ApInMwaitLoop
) {
419 // Place AP in MWAIT-loop
421 AsmMonitor ((UINTN
) ApStartupSignalBuffer
, 0, 0);
422 if (*ApStartupSignalBuffer
!= WAKEUP_AP_SIGNAL
) {
424 // Check AP start-up signal again.
425 // If AP start-up signal is not set, place AP into
426 // the specified C-state
428 AsmMwait (CpuMpData
->ApTargetCState
<< 4, 0);
430 } else if (CpuMpData
->ApLoopMode
== ApInRunLoop
) {
432 // Place AP in Run-loop
440 // If AP start-up signal is written, AP is waken up
441 // otherwise place AP in loop again
443 if (*ApStartupSignalBuffer
== WAKEUP_AP_SIGNAL
) {
451 Wait for AP wakeup and write AP start-up signal till AP is waken up.
453 @param[in] ApStartupSignalBuffer Pointer to AP wakeup signal
457 IN
volatile UINT32
*ApStartupSignalBuffer
461 // If AP is waken up, StartupApSignal should be cleared.
462 // Otherwise, write StartupApSignal again till AP waken up.
464 while (InterlockedCompareExchange32 (
465 (UINT32
*) ApStartupSignalBuffer
,
474 This function will fill the exchange info structure.
476 @param[in] CpuMpData Pointer to CPU MP Data
480 FillExchangeInfoData (
481 IN CPU_MP_DATA
*CpuMpData
484 volatile MP_CPU_EXCHANGE_INFO
*ExchangeInfo
;
486 ExchangeInfo
= CpuMpData
->MpCpuExchangeInfo
;
487 ExchangeInfo
->Lock
= 0;
488 ExchangeInfo
->StackStart
= CpuMpData
->Buffer
;
489 ExchangeInfo
->StackSize
= CpuMpData
->CpuApStackSize
;
490 ExchangeInfo
->BufferStart
= CpuMpData
->WakeupBuffer
;
491 ExchangeInfo
->ModeOffset
= CpuMpData
->AddressMap
.ModeEntryOffset
;
493 ExchangeInfo
->CodeSegment
= AsmReadCs ();
494 ExchangeInfo
->DataSegment
= AsmReadDs ();
496 ExchangeInfo
->Cr3
= AsmReadCr3 ();
498 ExchangeInfo
->CFunction
= (UINTN
) ApWakeupFunction
;
499 ExchangeInfo
->NumApsExecuting
= 0;
500 ExchangeInfo
->CpuMpData
= CpuMpData
;
502 ExchangeInfo
->EnableExecuteDisable
= IsBspExecuteDisableEnabled ();
505 // Get the BSP's data of GDT and IDT
507 AsmReadGdtr ((IA32_DESCRIPTOR
*) &ExchangeInfo
->GdtrProfile
);
508 AsmReadIdtr ((IA32_DESCRIPTOR
*) &ExchangeInfo
->IdtrProfile
);
512 This function will be called by BSP to wakeup AP.
514 @param[in] CpuMpData Pointer to CPU MP Data
515 @param[in] Broadcast TRUE: Send broadcast IPI to all APs
516 FALSE: Send IPI to AP by ApicId
517 @param[in] ProcessorNumber The handle number of specified processor
518 @param[in] Procedure The function to be invoked by AP
519 @param[in] ProcedureArgument The argument to be passed into AP function
523 IN CPU_MP_DATA
*CpuMpData
,
524 IN BOOLEAN Broadcast
,
525 IN UINTN ProcessorNumber
,
526 IN EFI_AP_PROCEDURE Procedure
, OPTIONAL
527 IN VOID
*ProcedureArgument OPTIONAL
530 volatile MP_CPU_EXCHANGE_INFO
*ExchangeInfo
;
532 CPU_AP_DATA
*CpuData
;
533 BOOLEAN ResetVectorRequired
;
535 CpuMpData
->FinishedCount
= 0;
536 ResetVectorRequired
= FALSE
;
538 if (CpuMpData
->ApLoopMode
== ApInHltLoop
||
539 CpuMpData
->InitFlag
!= ApInitDone
) {
540 ResetVectorRequired
= TRUE
;
541 AllocateResetVector (CpuMpData
);
542 FillExchangeInfoData (CpuMpData
);
543 } else if (CpuMpData
->ApLoopMode
== ApInMwaitLoop
) {
545 // Get AP target C-state each time when waking up AP,
546 // for it maybe updated by platform again
548 CpuMpData
->ApTargetCState
= PcdGet8 (PcdCpuApTargetCstate
);
551 ExchangeInfo
= CpuMpData
->MpCpuExchangeInfo
;
554 for (Index
= 0; Index
< CpuMpData
->CpuCount
; Index
++) {
555 if (Index
!= CpuMpData
->BspNumber
) {
556 CpuData
= &CpuMpData
->CpuData
[Index
];
557 CpuData
->ApFunction
= (UINTN
) Procedure
;
558 CpuData
->ApFunctionArgument
= (UINTN
) ProcedureArgument
;
559 SetApState (CpuData
, CpuStateReady
);
560 if (CpuMpData
->InitFlag
!= ApInitConfig
) {
561 *(UINT32
*) CpuData
->StartupApSignal
= WAKEUP_AP_SIGNAL
;
565 if (ResetVectorRequired
) {
569 SendInitSipiSipiAllExcludingSelf ((UINT32
) ExchangeInfo
->BufferStart
);
571 if (CpuMpData
->InitFlag
!= ApInitConfig
) {
573 // Wait all APs waken up if this is not the 1st broadcast of SIPI
575 for (Index
= 0; Index
< CpuMpData
->CpuCount
; Index
++) {
576 CpuData
= &CpuMpData
->CpuData
[Index
];
577 if (Index
!= CpuMpData
->BspNumber
) {
578 WaitApWakeup (CpuData
->StartupApSignal
);
583 CpuData
= &CpuMpData
->CpuData
[ProcessorNumber
];
584 CpuData
->ApFunction
= (UINTN
) Procedure
;
585 CpuData
->ApFunctionArgument
= (UINTN
) ProcedureArgument
;
586 SetApState (CpuData
, CpuStateReady
);
588 // Wakeup specified AP
590 ASSERT (CpuMpData
->InitFlag
!= ApInitConfig
);
591 *(UINT32
*) CpuData
->StartupApSignal
= WAKEUP_AP_SIGNAL
;
592 if (ResetVectorRequired
) {
595 (UINT32
) ExchangeInfo
->BufferStart
599 // Wait specified AP waken up
601 WaitApWakeup (CpuData
->StartupApSignal
);
604 if (ResetVectorRequired
) {
605 FreeResetVector (CpuMpData
);
610 MP Initialize Library initialization.
612 This service will allocate AP reset vector and wakeup all APs to do APs
615 This service must be invoked before all other MP Initialize Library
618 @retval EFI_SUCCESS MP initialization succeeds.
619 @retval Others MP initialization fails.
624 MpInitLibInitialize (
628 UINT32 MaxLogicalProcessorNumber
;
630 MP_ASSEMBLY_ADDRESS_MAP AddressMap
;
632 UINT32 MonitorFilterSize
;
635 CPU_MP_DATA
*CpuMpData
;
637 UINT8
*MonitorBuffer
;
639 UINTN ApResetVectorSize
;
640 UINTN BackupBufferAddr
;
641 MaxLogicalProcessorNumber
= PcdGet32(PcdCpuMaxLogicalProcessorNumber
);
643 AsmGetAddressMap (&AddressMap
);
644 ApResetVectorSize
= AddressMap
.RendezvousFunnelSize
+ sizeof (MP_CPU_EXCHANGE_INFO
);
645 ApStackSize
= PcdGet32(PcdCpuApStackSize
);
646 ApLoopMode
= GetApLoopMode (&MonitorFilterSize
);
648 BufferSize
= ApStackSize
* MaxLogicalProcessorNumber
;
649 BufferSize
+= MonitorFilterSize
* MaxLogicalProcessorNumber
;
650 BufferSize
+= sizeof (CPU_MP_DATA
);
651 BufferSize
+= ApResetVectorSize
;
652 BufferSize
+= (sizeof (CPU_AP_DATA
) + sizeof (CPU_INFO_IN_HOB
))* MaxLogicalProcessorNumber
;
653 MpBuffer
= AllocatePages (EFI_SIZE_TO_PAGES (BufferSize
));
654 ASSERT (MpBuffer
!= NULL
);
655 ZeroMem (MpBuffer
, BufferSize
);
656 Buffer
= (UINTN
) MpBuffer
;
658 MonitorBuffer
= (UINT8
*) (Buffer
+ ApStackSize
* MaxLogicalProcessorNumber
);
659 BackupBufferAddr
= (UINTN
) MonitorBuffer
+ MonitorFilterSize
* MaxLogicalProcessorNumber
;
660 CpuMpData
= (CPU_MP_DATA
*) (BackupBufferAddr
+ ApResetVectorSize
);
661 CpuMpData
->Buffer
= Buffer
;
662 CpuMpData
->CpuApStackSize
= ApStackSize
;
663 CpuMpData
->BackupBuffer
= BackupBufferAddr
;
664 CpuMpData
->BackupBufferSize
= ApResetVectorSize
;
665 CpuMpData
->EndOfPeiFlag
= FALSE
;
666 CpuMpData
->WakeupBuffer
= (UINTN
) -1;
667 CpuMpData
->CpuCount
= 1;
668 CpuMpData
->BspNumber
= 0;
669 CpuMpData
->WaitEvent
= NULL
;
670 CpuMpData
->CpuData
= (CPU_AP_DATA
*) (CpuMpData
+ 1);
671 CpuMpData
->CpuInfoInHob
= (UINT64
) (UINTN
) (CpuMpData
->CpuData
+ MaxLogicalProcessorNumber
);
672 InitializeSpinLock(&CpuMpData
->MpLock
);
674 // Save BSP's Control registers to APs
676 SaveVolatileRegisters (&CpuMpData
->CpuData
[0].VolatileRegisters
);
678 // Set BSP basic information
680 InitializeApData (CpuMpData
, 0, 0);
682 // Save assembly code information
684 CopyMem (&CpuMpData
->AddressMap
, &AddressMap
, sizeof (MP_ASSEMBLY_ADDRESS_MAP
));
686 // Finally set AP loop mode
688 CpuMpData
->ApLoopMode
= ApLoopMode
;
689 DEBUG ((DEBUG_INFO
, "AP Loop Mode is %d\n", CpuMpData
->ApLoopMode
));
691 // Set up APs wakeup signal buffer
693 for (Index
= 0; Index
< MaxLogicalProcessorNumber
; Index
++) {
694 CpuMpData
->CpuData
[Index
].StartupApSignal
=
695 (UINT32
*)(MonitorBuffer
+ MonitorFilterSize
* Index
);
698 // Load Microcode on BSP
700 MicrocodeDetect (CpuMpData
);
702 // Store BSP's MTRR setting
704 MtrrGetAllMtrrs (&CpuMpData
->MtrrTable
);
708 // Initialize global data for MP support
710 InitMpGlobalData (CpuMpData
);
716 Gets detailed MP-related information on the requested processor at the
717 instant this call is made. This service may only be called from the BSP.
719 @param[in] ProcessorNumber The handle number of processor.
720 @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
721 the requested processor is deposited.
722 @param[out] HealthData Return processor health data.
724 @retval EFI_SUCCESS Processor information was returned.
725 @retval EFI_DEVICE_ERROR The calling processor is an AP.
726 @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
727 @retval EFI_NOT_FOUND The processor with the handle specified by
728 ProcessorNumber does not exist in the platform.
729 @retval EFI_NOT_READY MP Initialize Library is not initialized.
734 MpInitLibGetProcessorInfo (
735 IN UINTN ProcessorNumber
,
736 OUT EFI_PROCESSOR_INFORMATION
*ProcessorInfoBuffer
,
737 OUT EFI_HEALTH_FLAGS
*HealthData OPTIONAL
740 return EFI_UNSUPPORTED
;
743 This return the handle number for the calling processor. This service may be
744 called from the BSP and APs.
746 @param[out] ProcessorNumber Pointer to the handle number of AP.
747 The range is from 0 to the total number of
748 logical processors minus 1. The total number of
749 logical processors can be retrieved by
750 MpInitLibGetNumberOfProcessors().
752 @retval EFI_SUCCESS The current processor handle number was returned
754 @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
755 @retval EFI_NOT_READY MP Initialize Library is not initialized.
761 OUT UINTN
*ProcessorNumber
764 return EFI_UNSUPPORTED
;
767 Retrieves the number of logical processor in the platform and the number of
768 those logical processors that are enabled on this boot. This service may only
769 be called from the BSP.
771 @param[out] NumberOfProcessors Pointer to the total number of logical
772 processors in the system, including the BSP
774 @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
775 processors that exist in system, including
778 @retval EFI_SUCCESS The number of logical processors and enabled
779 logical processors was retrieved.
780 @retval EFI_DEVICE_ERROR The calling processor is an AP.
781 @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL and NumberOfEnabledProcessors
783 @retval EFI_NOT_READY MP Initialize Library is not initialized.
788 MpInitLibGetNumberOfProcessors (
789 OUT UINTN
*NumberOfProcessors
, OPTIONAL
790 OUT UINTN
*NumberOfEnabledProcessors OPTIONAL
793 return EFI_UNSUPPORTED
;
796 Get pointer to CPU MP Data structure from GUIDed HOB.
798 @return The pointer to CPU MP Data structure.
801 GetCpuMpDataFromGuidedHob (
805 EFI_HOB_GUID_TYPE
*GuidHob
;
807 CPU_MP_DATA
*CpuMpData
;
810 GuidHob
= GetFirstGuidHob (&mCpuInitMpLibHobGuid
);
811 if (GuidHob
!= NULL
) {
812 DataInHob
= GET_GUID_HOB_DATA (GuidHob
);
813 CpuMpData
= (CPU_MP_DATA
*) (*(UINTN
*) DataInHob
);