]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
UefiCpuPkg/MpInitLib: 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
ee0c39fa 4 Copyright (c) 2016 - 2019, 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
ee0c39fa 404 return StartupAllCPUsWorker (\r
86efe976
JF
405 Procedure,\r
406 SingleThread,\r
ee0c39fa 407 TRUE,\r
86efe976
JF
408 NULL,\r
409 TimeoutInMicroseconds,\r
410 ProcedureArgument,\r
411 FailedCpuList\r
412 );\r
3e8ad6bd
JF
413}\r
414\r
415/**\r
416 This service lets the caller get one enabled AP to execute a caller-provided\r
417 function.\r
418\r
419 @param[in] Procedure A pointer to the function to be run on the\r
420 designated AP of the system. See type\r
421 EFI_AP_PROCEDURE.\r
422 @param[in] ProcessorNumber The handle number of the AP. The range is\r
423 from 0 to the total number of logical\r
424 processors minus 1. The total number of\r
425 logical processors can be retrieved by\r
426 MpInitLibGetNumberOfProcessors().\r
427 @param[in] WaitEvent The event created by the caller with CreateEvent()\r
428 service. If it is NULL, then execute in\r
429 blocking mode. BSP waits until this AP finish\r
430 or TimeoutInMicroSeconds expires. If it's\r
431 not NULL, then execute in non-blocking mode.\r
432 BSP requests the function specified by\r
433 Procedure to be started on this AP,\r
434 and go on executing immediately. If this AP\r
435 return from Procedure or TimeoutInMicroSeconds\r
436 expires, this event is signaled. The BSP\r
437 can use the CheckEvent() or WaitForEvent()\r
438 services to check the state of event. Type\r
439 EFI_EVENT is defined in CreateEvent() in\r
440 the Unified Extensible Firmware Interface\r
441 Specification.\r
367284e7 442 @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for\r
3e8ad6bd
JF
443 this AP to finish this Procedure, either for\r
444 blocking or non-blocking mode. Zero means\r
445 infinity. If the timeout expires before\r
446 this AP returns from Procedure, then Procedure\r
447 on the AP is terminated. The\r
448 AP is available for next function assigned\r
449 by MpInitLibStartupAllAPs() or\r
450 MpInitLibStartupThisAP().\r
451 If the timeout expires in blocking mode,\r
452 BSP returns EFI_TIMEOUT. If the timeout\r
453 expires in non-blocking mode, WaitEvent\r
454 is signaled with SignalEvent().\r
455 @param[in] ProcedureArgument The parameter passed into Procedure on the\r
456 specified AP.\r
457 @param[out] Finished If NULL, this parameter is ignored. In\r
458 blocking mode, this parameter is ignored.\r
459 In non-blocking mode, if AP returns from\r
460 Procedure before the timeout expires, its\r
461 content is set to TRUE. Otherwise, the\r
462 value is set to FALSE. The caller can\r
463 determine if the AP returned from Procedure\r
464 by evaluating this value.\r
465\r
466 @retval EFI_SUCCESS In blocking mode, specified AP finished before\r
467 the timeout expires.\r
468 @retval EFI_SUCCESS In non-blocking mode, the function has been\r
469 dispatched to specified AP.\r
470 @retval EFI_UNSUPPORTED A non-blocking mode request was made after the\r
471 UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was\r
472 signaled.\r
473 @retval EFI_UNSUPPORTED WaitEvent is not NULL if non-blocking mode is not\r
474 supported.\r
475 @retval EFI_DEVICE_ERROR The calling processor is an AP.\r
476 @retval EFI_TIMEOUT In blocking mode, the timeout expired before\r
477 the specified AP has finished.\r
478 @retval EFI_NOT_READY The specified AP is busy.\r
479 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
480 @retval EFI_NOT_FOUND The processor with the handle specified by\r
481 ProcessorNumber does not exist.\r
482 @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.\r
483 @retval EFI_INVALID_PARAMETER Procedure is NULL.\r
484\r
485**/\r
486EFI_STATUS\r
487EFIAPI\r
488MpInitLibStartupThisAP (\r
489 IN EFI_AP_PROCEDURE Procedure,\r
490 IN UINTN ProcessorNumber,\r
491 IN EFI_EVENT WaitEvent OPTIONAL,\r
492 IN UINTN TimeoutInMicroseconds,\r
493 IN VOID *ProcedureArgument OPTIONAL,\r
494 OUT BOOLEAN *Finished OPTIONAL\r
495 )\r
496{\r
20ae5774
JF
497 if (WaitEvent != NULL) {\r
498 return EFI_UNSUPPORTED;\r
499 }\r
500\r
501 return StartupThisAPWorker (\r
502 Procedure,\r
503 ProcessorNumber,\r
504 NULL,\r
505 TimeoutInMicroseconds,\r
506 ProcedureArgument,\r
507 Finished\r
508 );\r
3e8ad6bd
JF
509}\r
510\r
511/**\r
512 This service switches the requested AP to be the BSP from that point onward.\r
513 This service changes the BSP for all purposes. This call can only be performed\r
514 by the current BSP.\r
515\r
516 @param[in] ProcessorNumber The handle number of AP that is to become the new\r
517 BSP. The range is from 0 to the total number of\r
518 logical processors minus 1. The total number of\r
519 logical processors can be retrieved by\r
520 MpInitLibGetNumberOfProcessors().\r
521 @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an\r
522 enabled AP. Otherwise, it will be disabled.\r
523\r
524 @retval EFI_SUCCESS BSP successfully switched.\r
525 @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to\r
526 this service returning.\r
527 @retval EFI_UNSUPPORTED Switching the BSP is not supported.\r
528 @retval EFI_DEVICE_ERROR The calling processor is an AP.\r
529 @retval EFI_NOT_FOUND The processor with the handle specified by\r
530 ProcessorNumber does not exist.\r
531 @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or\r
532 a disabled AP.\r
533 @retval EFI_NOT_READY The specified AP is busy.\r
534 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
535\r
536**/\r
537EFI_STATUS\r
538EFIAPI\r
539MpInitLibSwitchBSP (\r
540 IN UINTN ProcessorNumber,\r
541 IN BOOLEAN EnableOldBSP\r
542 )\r
543{\r
41be0da5 544 return SwitchBSPWorker (ProcessorNumber, EnableOldBSP);\r
3e8ad6bd
JF
545}\r
546\r
547/**\r
548 This service lets the caller enable or disable an AP from this point onward.\r
549 This service may only be called from the BSP.\r
550\r
551 @param[in] ProcessorNumber The handle number of AP.\r
552 The range is from 0 to the total number of\r
553 logical processors minus 1. The total number of\r
554 logical processors can be retrieved by\r
555 MpInitLibGetNumberOfProcessors().\r
556 @param[in] EnableAP Specifies the new state for the processor for\r
557 enabled, FALSE for disabled.\r
558 @param[in] HealthFlag If not NULL, a pointer to a value that specifies\r
559 the new health status of the AP. This flag\r
560 corresponds to StatusFlag defined in\r
561 EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only\r
562 the PROCESSOR_HEALTH_STATUS_BIT is used. All other\r
563 bits are ignored. If it is NULL, this parameter\r
564 is ignored.\r
565\r
566 @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.\r
567 @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed\r
568 prior to this service returning.\r
569 @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.\r
570 @retval EFI_DEVICE_ERROR The calling processor is an AP.\r
571 @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber\r
572 does not exist.\r
573 @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.\r
574 @retval EFI_NOT_READY MP Initialize Library is not initialized.\r
575\r
576**/\r
577EFI_STATUS\r
578EFIAPI\r
579MpInitLibEnableDisableAP (\r
580 IN UINTN ProcessorNumber,\r
581 IN BOOLEAN EnableAP,\r
582 IN UINT32 *HealthFlag OPTIONAL\r
583 )\r
584{\r
e37109bc 585 return EnableDisableApWorker (ProcessorNumber, EnableAP, HealthFlag);\r
3e8ad6bd
JF
586}\r
587\r
588\r