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