]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
UefiCpuPkg/Include/MpInitLib.h: Add MpInitLibStartupAllCPUs API.
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / PeiMpLib.c
CommitLineData
3e8ad6bd
JF
1/** @file\r
2 MP initialize support functions for PEI phase.\r
3\r
5986cf38 4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
0acd8697 5 SPDX-License-Identifier: BSD-2-Clause-Patent\r
3e8ad6bd
JF
6\r
7**/\r
8\r
9#include "MpLib.h"\r
58942277
ED
10#include <Library/PeiServicesLib.h>\r
11#include <Guid/S3SmmInitDone.h>\r
12\r
13/**\r
14 S3 SMM Init Done notification function.\r
15\r
16 @param PeiServices Indirect reference to the PEI Services Table.\r
17 @param NotifyDesc Address of the notification descriptor data structure.\r
18 @param InvokePpi Address of the PPI that was invoked.\r
19\r
20 @retval EFI_SUCCESS The function completes successfully.\r
21\r
22**/\r
23EFI_STATUS\r
24EFIAPI\r
25NotifyOnS3SmmInitDonePpi (\r
26 IN EFI_PEI_SERVICES **PeiServices,\r
27 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
28 IN VOID *InvokePpi\r
29 );\r
30\r
31\r
32//\r
33// Global function\r
34//\r
35EFI_PEI_NOTIFY_DESCRIPTOR mS3SmmInitDoneNotifyDesc = {\r
36 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
37 &gEdkiiS3SmmInitDoneGuid,\r
38 NotifyOnS3SmmInitDonePpi\r
39};\r
40\r
58942277
ED
41/**\r
42 S3 SMM Init Done notification function.\r
43\r
44 @param PeiServices Indirect reference to the PEI Services Table.\r
45 @param NotifyDesc Address of the notification descriptor data structure.\r
46 @param InvokePpi Address of the PPI that was invoked.\r
47\r
48 @retval EFI_SUCCESS The function completes successfully.\r
49\r
50**/\r
51EFI_STATUS\r
52EFIAPI\r
53NotifyOnS3SmmInitDonePpi (\r
54 IN EFI_PEI_SERVICES **PeiServices,\r
55 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,\r
56 IN VOID *InvokePpi\r
57 )\r
58{\r
59 CPU_MP_DATA *CpuMpData;\r
60\r
61 CpuMpData = GetCpuMpData ();\r
62\r
63 //\r
64 // PiSmmCpuDxeSmm driver hardcode change the loop mode to HLT mode.\r
65 // So in this notify function, code need to check the current loop\r
66 // mode, if it is not HLT mode, code need to change loop mode back\r
67 // to the original mode.\r
68 //\r
69 if (CpuMpData->ApLoopMode != ApInHltLoop) {\r
70 CpuMpData->WakeUpByInitSipiSipi = TRUE;\r
71 }\r
72\r
73 return EFI_SUCCESS;\r
74}\r
75\r
43c9fdcc
JF
76\r
77/**\r
78 Enable Debug Agent to support source debugging on AP function.\r
79\r
80**/\r
81VOID\r
82EnableDebugAgent (\r
83 VOID\r
84 )\r
85{\r
86}\r
87\r
93ca4c0f
JF
88/**\r
89 Get pointer to CPU MP Data structure.\r
c563077a
RN
90 For BSP, the pointer is retrieved from HOB.\r
91 For AP, the structure is just after IDT.\r
93ca4c0f
JF
92\r
93 @return The pointer to CPU MP Data structure.\r
94**/\r
95CPU_MP_DATA *\r
96GetCpuMpData (\r
97 VOID\r
98 )\r
99{\r
c563077a
RN
100 CPU_MP_DATA *CpuMpData;\r
101 MSR_IA32_APIC_BASE_REGISTER ApicBaseMsr;\r
102 IA32_DESCRIPTOR Idtr;\r
93ca4c0f 103\r
c563077a
RN
104 ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
105 if (ApicBaseMsr.Bits.BSP == 1) {\r
106 CpuMpData = GetCpuMpDataFromGuidedHob ();\r
107 ASSERT (CpuMpData != NULL);\r
108 } else {\r
109 AsmReadIdtr (&Idtr);\r
110 CpuMpData = (CPU_MP_DATA *) (Idtr.Base + Idtr.Limit + 1);\r
111 }\r
93ca4c0f
JF
112 return CpuMpData;\r
113}\r
114\r
115/**\r
116 Save the pointer to CPU MP Data structure.\r
117\r
118 @param[in] CpuMpData The pointer to CPU MP Data structure will be saved.\r
119**/\r
120VOID\r
121SaveCpuMpData (\r
122 IN CPU_MP_DATA *CpuMpData\r
123 )\r
124{\r
125 UINT64 Data64;\r
126 //\r
127 // Build location of CPU MP DATA buffer in HOB\r
128 //\r
129 Data64 = (UINT64) (UINTN) CpuMpData;\r
130 BuildGuidDataHob (\r
131 &mCpuInitMpLibHobGuid,\r
132 (VOID *) &Data64,\r
133 sizeof (UINT64)\r
134 );\r
135}\r
136\r
ed66e0e3
JF
137/**\r
138 Check if AP wakeup buffer is overlapped with existing allocated buffer.\r
139\r
140 @param[in] WakeupBufferStart AP wakeup buffer start address.\r
141 @param[in] WakeupBufferEnd AP wakeup buffer end address.\r
142\r
143 @retval TRUE There is overlap.\r
144 @retval FALSE There is no overlap.\r
145**/\r
146BOOLEAN\r
147CheckOverlapWithAllocatedBuffer (\r
5986cf38
RN
148 IN UINT64 WakeupBufferStart,\r
149 IN UINT64 WakeupBufferEnd\r
ed66e0e3
JF
150 )\r
151{\r
152 EFI_PEI_HOB_POINTERS Hob;\r
153 EFI_HOB_MEMORY_ALLOCATION *MemoryHob;\r
154 BOOLEAN Overlapped;\r
5986cf38
RN
155 UINT64 MemoryStart;\r
156 UINT64 MemoryEnd;\r
ed66e0e3
JF
157\r
158 Overlapped = FALSE;\r
159 //\r
160 // Get the HOB list for processing\r
161 //\r
162 Hob.Raw = GetHobList ();\r
163 //\r
164 // Collect memory ranges\r
165 //\r
166 while (!END_OF_HOB_LIST (Hob)) {\r
167 if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {\r
168 MemoryHob = Hob.MemoryAllocation;\r
5986cf38
RN
169 MemoryStart = MemoryHob->AllocDescriptor.MemoryBaseAddress;\r
170 MemoryEnd = MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength;\r
ed66e0e3
JF
171 if (!((WakeupBufferStart >= MemoryEnd) || (WakeupBufferEnd <= MemoryStart))) {\r
172 Overlapped = TRUE;\r
173 break;\r
174 }\r
175 }\r
176 Hob.Raw = GET_NEXT_HOB (Hob);\r
177 }\r
178 return Overlapped;\r
179}\r
180\r
181/**\r
182 Get available system memory below 1MB by specified size.\r
183\r
184 @param[in] WakeupBufferSize Wakeup buffer size required\r
185\r
186 @retval other Return wakeup buffer address below 1MB.\r
187 @retval -1 Cannot find free memory below 1MB.\r
188**/\r
189UINTN\r
190GetWakeupBuffer (\r
191 IN UINTN WakeupBufferSize\r
192 )\r
193{\r
194 EFI_PEI_HOB_POINTERS Hob;\r
5986cf38
RN
195 UINT64 WakeupBufferStart;\r
196 UINT64 WakeupBufferEnd;\r
ed66e0e3
JF
197\r
198 WakeupBufferSize = (WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1);\r
199\r
200 //\r
201 // Get the HOB list for processing\r
202 //\r
203 Hob.Raw = GetHobList ();\r
204\r
205 //\r
206 // Collect memory ranges\r
207 //\r
208 while (!END_OF_HOB_LIST (Hob)) {\r
209 if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
210 if ((Hob.ResourceDescriptor->PhysicalStart < BASE_1MB) &&\r
211 (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&\r
212 ((Hob.ResourceDescriptor->ResourceAttribute &\r
213 (EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |\r
214 EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |\r
215 EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED\r
216 )) == 0)\r
217 ) {\r
218 //\r
219 // Need memory under 1MB to be collected here\r
220 //\r
5986cf38 221 WakeupBufferEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;\r
ed66e0e3
JF
222 if (WakeupBufferEnd > BASE_1MB) {\r
223 //\r
224 // Wakeup buffer should be under 1MB\r
225 //\r
226 WakeupBufferEnd = BASE_1MB;\r
227 }\r
228 while (WakeupBufferEnd > WakeupBufferSize) {\r
229 //\r
230 // Wakeup buffer should be aligned on 4KB\r
231 //\r
232 WakeupBufferStart = (WakeupBufferEnd - WakeupBufferSize) & ~(SIZE_4KB - 1);\r
233 if (WakeupBufferStart < Hob.ResourceDescriptor->PhysicalStart) {\r
234 break;\r
235 }\r
236 if (CheckOverlapWithAllocatedBuffer (WakeupBufferStart, WakeupBufferEnd)) {\r
237 //\r
238 // If this range is overlapped with existing allocated buffer, skip it\r
239 // and find the next range\r
240 //\r
241 WakeupBufferEnd -= WakeupBufferSize;\r
242 continue;\r
243 }\r
244 DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n",\r
245 WakeupBufferStart, WakeupBufferSize));\r
5986cf38 246 return (UINTN)WakeupBufferStart;\r
ed66e0e3
JF
247 }\r
248 }\r
249 }\r
250 //\r
251 // Find the next HOB\r
252 //\r
253 Hob.Raw = GET_NEXT_HOB (Hob);\r
254 }\r
255\r
256 return (UINTN) -1;\r
257}\r
258\r
f32bfe6d
JW
259/**\r
260 Get available EfiBootServicesCode memory below 4GB by specified size.\r
261\r
262 This buffer is required to safely transfer AP from real address mode to\r
263 protected mode or long mode, due to the fact that the buffer returned by\r
264 GetWakeupBuffer() may be marked as non-executable.\r
265\r
266 @param[in] BufferSize Wakeup transition buffer size.\r
267\r
268 @retval other Return wakeup transition buffer address below 4GB.\r
269 @retval 0 Cannot find free memory below 4GB.\r
270**/\r
271UINTN\r
272GetModeTransitionBuffer (\r
273 IN UINTN BufferSize\r
274 )\r
275{\r
276 //\r
277 // PEI phase doesn't need to do such transition. So simply return 0.\r
278 //\r
279 return 0;\r
280}\r
281\r
08085f08
JF
282/**\r
283 Checks APs status and updates APs status if needed.\r
284\r
285**/\r
286VOID\r
287CheckAndUpdateApsStatus (\r
288 VOID\r
289 )\r
290{\r
291}\r
292\r
93ca4c0f
JF
293/**\r
294 Initialize global data for MP support.\r
295\r
296 @param[in] CpuMpData The pointer to CPU MP Data structure.\r
297**/\r
298VOID\r
299InitMpGlobalData (\r
300 IN CPU_MP_DATA *CpuMpData\r
301 )\r
302{\r
58942277
ED
303 EFI_STATUS Status;\r
304\r
93ca4c0f 305 SaveCpuMpData (CpuMpData);\r
58942277
ED
306\r
307 ///\r
308 /// Install Notify\r
309 ///\r
310 Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc);\r
311 ASSERT_EFI_ERROR (Status);\r
93ca4c0f
JF
312}\r
313\r
3e8ad6bd
JF
314/**\r
315 This service executes a caller provided function on all enabled APs.\r
316\r
317 @param[in] Procedure A pointer to the function to be run on\r
318 enabled APs of the system. See type\r
319 EFI_AP_PROCEDURE.\r
320 @param[in] SingleThread If TRUE, then all the enabled APs execute\r
321 the function specified by Procedure one by\r
322 one, in ascending order of processor handle\r
323 number. If FALSE, then all the enabled APs\r
324 execute the function specified by Procedure\r
325 simultaneously.\r
326 @param[in] WaitEvent The event created by the caller with CreateEvent()\r
327 service. If it is NULL, then execute in\r
328 blocking mode. BSP waits until all APs finish\r
329 or TimeoutInMicroSeconds expires. If it's\r
330 not NULL, then execute in non-blocking mode.\r
331 BSP requests the function specified by\r
332 Procedure to be started on all the enabled\r
333 APs, and go on executing immediately. If\r
334 all return from Procedure, or TimeoutInMicroSeconds\r
335 expires, this event is signaled. The BSP\r
336 can use the CheckEvent() or WaitForEvent()\r
337 services to check the state of event. Type\r
338 EFI_EVENT is defined in CreateEvent() in\r
339 the Unified Extensible Firmware Interface\r
340 Specification.\r
367284e7 341 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for\r
3e8ad6bd
JF
342 APs to return from Procedure, either for\r
343 blocking or non-blocking mode. Zero means\r
344 infinity. If the timeout expires before\r
345 all APs return from Procedure, then Procedure\r
346 on the failed APs is terminated. All enabled\r
347 APs are available for next function assigned\r
348 by MpInitLibStartupAllAPs() or\r
349 MPInitLibStartupThisAP().\r
350 If the timeout expires in blocking mode,\r
351 BSP returns EFI_TIMEOUT. If the timeout\r
352 expires in non-blocking mode, WaitEvent\r
353 is signaled with SignalEvent().\r
354 @param[in] ProcedureArgument The parameter passed into Procedure for\r
355 all APs.\r
356 @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,\r
357 if all APs finish successfully, then its\r
358 content is set to NULL. If not all APs\r
359 finish before timeout expires, then its\r
360 content is set to address of the buffer\r
361 holding handle numbers of the failed APs.\r
362 The buffer is allocated by MP Initialization\r
363 library, and it's the caller's responsibility to\r
364 free the buffer with FreePool() service.\r
365 In blocking mode, it is ready for consumption\r
366 when the call returns. In non-blocking mode,\r
367 it is ready when WaitEvent is signaled. The\r
368 list of failed CPU is terminated by\r
369 END_OF_CPU_LIST.\r
370\r
371 @retval EFI_SUCCESS In blocking mode, all APs have finished before\r
372 the timeout expired.\r
373 @retval EFI_SUCCESS In non-blocking mode, function has been dispatched\r
374 to all enabled APs.\r
375 @retval EFI_UNSUPPORTED A non-blocking mode request was made after the\r
376 UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was\r
377 signaled.\r
378 @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not\r
379 supported.\r
380 @retval EFI_DEVICE_ERROR Caller processor is AP.\r
381 @retval EFI_NOT_STARTED No enabled APs exist in the system.\r
382 @retval EFI_NOT_READY Any enabled APs are busy.\r
383 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
384 @retval EFI_TIMEOUT In blocking mode, the timeout expired before\r
385 all enabled APs have finished.\r
386 @retval EFI_INVALID_PARAMETER Procedure is NULL.\r
387\r
388**/\r
389EFI_STATUS\r
390EFIAPI\r
391MpInitLibStartupAllAPs (\r
392 IN EFI_AP_PROCEDURE Procedure,\r
393 IN BOOLEAN SingleThread,\r
394 IN EFI_EVENT WaitEvent OPTIONAL,\r
395 IN UINTN TimeoutInMicroseconds,\r
396 IN VOID *ProcedureArgument OPTIONAL,\r
397 OUT UINTN **FailedCpuList OPTIONAL\r
398 )\r
399{\r
86efe976
JF
400 if (WaitEvent != NULL) {\r
401 return EFI_UNSUPPORTED;\r
402 }\r
403\r
404 return StartupAllAPsWorker (\r
405 Procedure,\r
406 SingleThread,\r
407 NULL,\r
408 TimeoutInMicroseconds,\r
409 ProcedureArgument,\r
410 FailedCpuList\r
411 );\r
3e8ad6bd
JF
412}\r
413\r
414/**\r
415 This service lets the caller get one enabled AP to execute a caller-provided\r
416 function.\r
417\r
418 @param[in] Procedure A pointer to the function to be run on the\r
419 designated AP of the system. See type\r
420 EFI_AP_PROCEDURE.\r
421 @param[in] ProcessorNumber The handle number of the AP. The range is\r
422 from 0 to the total number of logical\r
423 processors minus 1. The total number of\r
424 logical processors can be retrieved by\r
425 MpInitLibGetNumberOfProcessors().\r
426 @param[in] WaitEvent The event created by the caller with CreateEvent()\r
427 service. If it is NULL, then execute in\r
428 blocking mode. BSP waits until this AP finish\r
429 or TimeoutInMicroSeconds expires. If it's\r
430 not NULL, then execute in non-blocking mode.\r
431 BSP requests the function specified by\r
432 Procedure to be started on this AP,\r
433 and go on executing immediately. If this AP\r
434 return from Procedure or TimeoutInMicroSeconds\r
435 expires, this event is signaled. The BSP\r
436 can use the CheckEvent() or WaitForEvent()\r
437 services to check the state of event. Type\r
438 EFI_EVENT is defined in CreateEvent() in\r
439 the Unified Extensible Firmware Interface\r
440 Specification.\r
367284e7 441 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for\r
3e8ad6bd
JF
442 this AP to finish this Procedure, either for\r
443 blocking or non-blocking mode. Zero means\r
444 infinity. If the timeout expires before\r
445 this AP returns from Procedure, then Procedure\r
446 on the AP is terminated. The\r
447 AP is available for next function assigned\r
448 by MpInitLibStartupAllAPs() or\r
449 MpInitLibStartupThisAP().\r
450 If the timeout expires in blocking mode,\r
451 BSP returns EFI_TIMEOUT. If the timeout\r
452 expires in non-blocking mode, WaitEvent\r
453 is signaled with SignalEvent().\r
454 @param[in] ProcedureArgument The parameter passed into Procedure on the\r
455 specified AP.\r
456 @param[out] Finished If NULL, this parameter is ignored. In\r
457 blocking mode, this parameter is ignored.\r
458 In non-blocking mode, if AP returns from\r
459 Procedure before the timeout expires, its\r
460 content is set to TRUE. Otherwise, the\r
461 value is set to FALSE. The caller can\r
462 determine if the AP returned from Procedure\r
463 by evaluating this value.\r
464\r
465 @retval EFI_SUCCESS In blocking mode, specified AP finished before\r
466 the timeout expires.\r
467 @retval EFI_SUCCESS In non-blocking mode, the function has been\r
468 dispatched to specified AP.\r
469 @retval EFI_UNSUPPORTED A non-blocking mode request was made after the\r
470 UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was\r
471 signaled.\r
472 @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not\r
473 supported.\r
474 @retval EFI_DEVICE_ERROR The calling processor is an AP.\r
475 @retval EFI_TIMEOUT In blocking mode, the timeout expired before\r
476 the specified AP has finished.\r
477 @retval EFI_NOT_READY The specified AP is busy.\r
478 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
479 @retval EFI_NOT_FOUND The processor with the handle specified by\r
480 ProcessorNumber does not exist.\r
481 @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.\r
482 @retval EFI_INVALID_PARAMETER Procedure is NULL.\r
483\r
484**/\r
485EFI_STATUS\r
486EFIAPI\r
487MpInitLibStartupThisAP (\r
488 IN EFI_AP_PROCEDURE Procedure,\r
489 IN UINTN ProcessorNumber,\r
490 IN EFI_EVENT WaitEvent OPTIONAL,\r
491 IN UINTN TimeoutInMicroseconds,\r
492 IN VOID *ProcedureArgument OPTIONAL,\r
493 OUT BOOLEAN *Finished OPTIONAL\r
494 )\r
495{\r
20ae5774
JF
496 if (WaitEvent != NULL) {\r
497 return EFI_UNSUPPORTED;\r
498 }\r
499\r
500 return StartupThisAPWorker (\r
501 Procedure,\r
502 ProcessorNumber,\r
503 NULL,\r
504 TimeoutInMicroseconds,\r
505 ProcedureArgument,\r
506 Finished\r
507 );\r
3e8ad6bd
JF
508}\r
509\r
510/**\r
511 This service switches the requested AP to be the BSP from that point onward.\r
512 This service changes the BSP for all purposes. This call can only be performed\r
513 by the current BSP.\r
514\r
515 @param[in] ProcessorNumber The handle number of AP that is to become the new\r
516 BSP. The range is from 0 to the total number of\r
517 logical processors minus 1. The total number of\r
518 logical processors can be retrieved by\r
519 MpInitLibGetNumberOfProcessors().\r
520 @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an\r
521 enabled AP. Otherwise, it will be disabled.\r
522\r
523 @retval EFI_SUCCESS BSP successfully switched.\r
524 @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to\r
525 this service returning.\r
526 @retval EFI_UNSUPPORTED Switching the BSP is not supported.\r
527 @retval EFI_DEVICE_ERROR The calling processor is an AP.\r
528 @retval EFI_NOT_FOUND The processor with the handle specified by\r
529 ProcessorNumber does not exist.\r
530 @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or\r
531 a disabled AP.\r
532 @retval EFI_NOT_READY The specified AP is busy.\r
533 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
534\r
535**/\r
536EFI_STATUS\r
537EFIAPI\r
538MpInitLibSwitchBSP (\r
539 IN UINTN ProcessorNumber,\r
540 IN BOOLEAN EnableOldBSP\r
541 )\r
542{\r
41be0da5 543 return SwitchBSPWorker (ProcessorNumber, EnableOldBSP);\r
3e8ad6bd
JF
544}\r
545\r
546/**\r
547 This service lets the caller enable or disable an AP from this point onward.\r
548 This service may only be called from the BSP.\r
549\r
550 @param[in] ProcessorNumber The handle number of AP.\r
551 The range is from 0 to the total number of\r
552 logical processors minus 1. The total number of\r
553 logical processors can be retrieved by\r
554 MpInitLibGetNumberOfProcessors().\r
555 @param[in] EnableAP Specifies the new state for the processor for\r
556 enabled, FALSE for disabled.\r
557 @param[in] HealthFlag If not NULL, a pointer to a value that specifies\r
558 the new health status of the AP. This flag\r
559 corresponds to StatusFlag defined in\r
560 EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only\r
561 the PROCESSOR_HEALTH_STATUS_BIT is used. All other\r
562 bits are ignored. If it is NULL, this parameter\r
563 is ignored.\r
564\r
565 @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.\r
566 @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed\r
567 prior to this service returning.\r
568 @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.\r
569 @retval EFI_DEVICE_ERROR The calling processor is an AP.\r
570 @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber\r
571 does not exist.\r
572 @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.\r
573 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
574\r
575**/\r
576EFI_STATUS\r
577EFIAPI\r
578MpInitLibEnableDisableAP (\r
579 IN UINTN ProcessorNumber,\r
580 IN BOOLEAN EnableAP,\r
581 IN UINT32 *HealthFlag OPTIONAL\r
582 )\r
583{\r
e37109bc 584 return EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag);\r
3e8ad6bd
JF
585}\r
586\r
587\r