TianoCore EDK2 master
Loading...
Searching...
No Matches
CpuMpPei.c
Go to the documentation of this file.
1
9#include "CpuMpPei.h"
10
11extern EDKII_PEI_MP_SERVICES2_PPI mMpServices2Ppi;
12
13//
14// CPU MP PPI to be installed
15//
16EFI_PEI_MP_SERVICES_PPI mMpServicesPpi = {
24};
25
26EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiList[] = {
27 {
28 EFI_PEI_PPI_DESCRIPTOR_PPI,
29 &gEdkiiPeiMpServices2PpiGuid,
30 &mMpServices2Ppi
31 },
32 {
33 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
34 &gEfiPeiMpServicesPpiGuid,
35 &mMpServicesPpi
36 }
37};
38
74EFIAPI
76 IN CONST EFI_PEI_SERVICES **PeiServices,
78 OUT UINTN *NumberOfProcessors,
79 OUT UINTN *NumberOfEnabledProcessors
80 )
81{
82 if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
83 return EFI_INVALID_PARAMETER;
84 }
85
87 NumberOfProcessors,
88 NumberOfEnabledProcessors
89 );
90}
91
119EFIAPI
121 IN CONST EFI_PEI_SERVICES **PeiServices,
123 IN UINTN ProcessorNumber,
124 OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
125 )
126{
127 return MpInitLibGetProcessorInfo (ProcessorNumber, ProcessorInfoBuffer, NULL);
128}
129
194EFIAPI
196 IN CONST EFI_PEI_SERVICES **PeiServices,
198 IN EFI_AP_PROCEDURE Procedure,
199 IN BOOLEAN SingleThread,
200 IN UINTN TimeoutInMicroSeconds,
201 IN VOID *ProcedureArgument OPTIONAL
202 )
203{
205 Procedure,
206 SingleThread,
207 NULL,
208 TimeoutInMicroSeconds,
209 ProcedureArgument,
210 NULL
211 );
212}
213
261EFIAPI
263 IN CONST EFI_PEI_SERVICES **PeiServices,
265 IN EFI_AP_PROCEDURE Procedure,
266 IN UINTN ProcessorNumber,
267 IN UINTN TimeoutInMicroseconds,
268 IN VOID *ProcedureArgument OPTIONAL
269 )
270{
272 Procedure,
273 ProcessorNumber,
274 NULL,
275 TimeoutInMicroseconds,
276 ProcedureArgument,
277 NULL
278 );
279}
280
316EFIAPI
318 IN CONST EFI_PEI_SERVICES **PeiServices,
320 IN UINTN ProcessorNumber,
321 IN BOOLEAN EnableOldBSP
322 )
323{
324 return MpInitLibSwitchBSP (ProcessorNumber, EnableOldBSP);
325}
326
367EFIAPI
369 IN CONST EFI_PEI_SERVICES **PeiServices,
371 IN UINTN ProcessorNumber,
372 IN BOOLEAN EnableAP,
373 IN UINT32 *HealthFlag OPTIONAL
374 )
375{
376 return MpInitLibEnableDisableAP (ProcessorNumber, EnableAP, HealthFlag);
377}
378
404EFIAPI
406 IN CONST EFI_PEI_SERVICES **PeiServices,
408 OUT UINTN *ProcessorNumber
409 )
410{
411 return MpInitLibWhoAmI (ProcessorNumber);
412}
413
414//
415// Structure for InitializeSeparateExceptionStacks
416//
417typedef struct {
418 VOID *Buffer;
419 UINTN BufferSize;
420 EFI_STATUS Status;
422
432VOID
433EFIAPI
435 IN OUT VOID *Buffer
436 )
437{
438 EXCEPTION_STACK_SWITCH_CONTEXT *SwitchStackData;
439 UINTN Index;
440
441 MpInitLibWhoAmI (&Index);
442 SwitchStackData = (EXCEPTION_STACK_SWITCH_CONTEXT *)Buffer;
443
444 //
445 // This function may be called twice for each Cpu. Only run InitializeSeparateExceptionStacks
446 // if this is the first call or the first call failed because of size too small.
447 //
448 if ((SwitchStackData[Index].Status == EFI_NOT_STARTED) || (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL)) {
449 SwitchStackData[Index].Status = InitializeSeparateExceptionStacks (SwitchStackData[Index].Buffer, &SwitchStackData[Index].BufferSize);
450 }
451}
452
460VOID
462 VOID
463 )
464{
465 UINTN Index;
466 UINTN NumberOfProcessors;
467 EXCEPTION_STACK_SWITCH_CONTEXT *SwitchStackData;
468 UINTN BufferSize;
469 EFI_STATUS Status;
470 UINT8 *Buffer;
471
472 if (!PcdGetBool (PcdCpuStackGuard)) {
473 return;
474 }
475
476 Status = MpInitLibGetNumberOfProcessors (&NumberOfProcessors, NULL);
477 ASSERT_EFI_ERROR (Status);
478
479 if (EFI_ERROR (Status)) {
480 NumberOfProcessors = 1;
481 }
482
483 SwitchStackData = AllocatePages (EFI_SIZE_TO_PAGES (NumberOfProcessors * sizeof (EXCEPTION_STACK_SWITCH_CONTEXT)));
484 ASSERT (SwitchStackData != NULL);
485 ZeroMem (SwitchStackData, NumberOfProcessors * sizeof (EXCEPTION_STACK_SWITCH_CONTEXT));
486 for (Index = 0; Index < NumberOfProcessors; ++Index) {
487 //
488 // Because the procedure may runs multiple times, use the status EFI_NOT_STARTED
489 // to indicate the procedure haven't been run yet.
490 //
491 SwitchStackData[Index].Status = EFI_NOT_STARTED;
492 }
493
494 Status = MpInitLibStartupAllCPUs (
496 0,
497 SwitchStackData
498 );
499 ASSERT_EFI_ERROR (Status);
500
501 BufferSize = 0;
502 for (Index = 0; Index < NumberOfProcessors; ++Index) {
503 if (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL) {
504 ASSERT (SwitchStackData[Index].BufferSize != 0);
505 BufferSize += SwitchStackData[Index].BufferSize;
506 } else {
507 ASSERT (SwitchStackData[Index].Status == EFI_SUCCESS);
508 ASSERT (SwitchStackData[Index].BufferSize == 0);
509 }
510 }
511
512 if (BufferSize != 0) {
513 Buffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));
514 ASSERT (Buffer != NULL);
515 BufferSize = 0;
516 for (Index = 0; Index < NumberOfProcessors; ++Index) {
517 if (SwitchStackData[Index].Status == EFI_BUFFER_TOO_SMALL) {
518 SwitchStackData[Index].Buffer = (VOID *)(&Buffer[BufferSize]);
519 BufferSize += SwitchStackData[Index].BufferSize;
520 DEBUG ((
521 DEBUG_INFO,
522 "Buffer[cpu%lu] for InitializeExceptionStackSwitchHandlers: 0x%lX with size 0x%lX\n",
523 (UINT64)(UINTN)Index,
524 (UINT64)(UINTN)SwitchStackData[Index].Buffer,
525 (UINT64)(UINTN)SwitchStackData[Index].BufferSize
526 ));
527 }
528 }
529
530 Status = MpInitLibStartupAllCPUs (
532 0,
533 SwitchStackData
534 );
535 ASSERT_EFI_ERROR (Status);
536 for (Index = 0; Index < NumberOfProcessors; ++Index) {
537 ASSERT (SwitchStackData[Index].Status == EFI_SUCCESS);
538 }
539 }
540
541 FreePages (SwitchStackData, EFI_SIZE_TO_PAGES (NumberOfProcessors * sizeof (EXCEPTION_STACK_SWITCH_CONTEXT)));
542}
543
555 IN CONST EFI_PEI_SERVICES **PeiServices
556 )
557{
558 EFI_STATUS Status;
559 EFI_VECTOR_HANDOFF_INFO *VectorInfo;
560 EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;
561
562 //
563 // Get Vector Hand-off Info PPI
564 //
565 VectorInfo = NULL;
566 Status = PeiServicesLocatePpi (
567 &gEfiVectorHandoffInfoPpiGuid,
568 0,
569 NULL,
570 (VOID **)&VectorHandoffInfoPpi
571 );
572 if (Status == EFI_SUCCESS) {
573 VectorInfo = VectorHandoffInfoPpi->Info;
574 }
575
576 //
577 // Initialize default handlers
578 //
579 Status = InitializeCpuExceptionHandlers (VectorInfo);
580 if (EFI_ERROR (Status)) {
581 return Status;
582 }
583
584 Status = MpInitLibInitialize ();
585 if (EFI_ERROR (Status)) {
586 return Status;
587 }
588
589 //
590 // Special initialization for the sake of Stack Guard
591 //
593
594 //
595 // Update and publish CPU BIST information
596 //
597 CollectBistDataFromPpi (PeiServices);
598
599 //
600 // Install CPU MP PPI
601 //
602 Status = PeiServicesInstallPpi (mPeiCpuMpPpiList);
603 ASSERT_EFI_ERROR (Status);
604
605 return Status;
606}
607
621EFIAPI
623 IN EFI_PEI_FILE_HANDLE FileHandle,
624 IN CONST EFI_PEI_SERVICES **PeiServices
625 )
626{
627 EFI_STATUS Status;
628
629 //
630 // For the sake of special initialization needing to be done right after
631 // memory discovery.
632 //
633 Status = PeiServicesNotifyPpi (&mPostMemNotifyList[0]);
634 ASSERT_EFI_ERROR (Status);
635
636 return Status;
637}
UINT64 UINTN
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID CollectBistDataFromPpi(IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: CpuBist.c:157
VOID EFIAPI InitializeExceptionStackSwitchHandlers(IN OUT VOID *Buffer)
Definition: CpuMpPei.c:434
EFI_STATUS EFIAPI CpuMpPeimInit(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: CpuMpPei.c:622
EFI_STATUS EFIAPI PeiGetProcessorInfo(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_MP_SERVICES_PPI *This, IN UINTN ProcessorNumber, OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer)
Definition: CpuMpPei.c:120
VOID InitializeMpExceptionStackSwitchHandlers(VOID)
Definition: CpuMpPei.c:461
EFI_STATUS EFIAPI PeiWhoAmI(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_MP_SERVICES_PPI *This, OUT UINTN *ProcessorNumber)
Definition: CpuMpPei.c:405
EFI_STATUS EFIAPI PeiStartupAllAPs(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_MP_SERVICES_PPI *This, IN EFI_AP_PROCEDURE Procedure, IN BOOLEAN SingleThread, IN UINTN TimeoutInMicroSeconds, IN VOID *ProcedureArgument OPTIONAL)
Definition: CpuMpPei.c:195
EFI_STATUS EFIAPI PeiEnableDisableAP(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_MP_SERVICES_PPI *This, IN UINTN ProcessorNumber, IN BOOLEAN EnableAP, IN UINT32 *HealthFlag OPTIONAL)
Definition: CpuMpPei.c:368
EFI_STATUS EFIAPI PeiSwitchBSP(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_MP_SERVICES_PPI *This, IN UINTN ProcessorNumber, IN BOOLEAN EnableOldBSP)
Definition: CpuMpPei.c:317
EFI_STATUS InitializeCpuMpWorker(IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: CpuMpPei.c:554
EFI_STATUS EFIAPI PeiStartupThisAP(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_MP_SERVICES_PPI *This, IN EFI_AP_PROCEDURE Procedure, IN UINTN ProcessorNumber, IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL)
Definition: CpuMpPei.c:262
EFI_STATUS EFIAPI PeiGetNumberOfProcessors(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_MP_SERVICES_PPI *This, OUT UINTN *NumberOfProcessors, OUT UINTN *NumberOfEnabledProcessors)
Definition: CpuMpPei.c:75
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:445
#define DEBUG(Expression)
Definition: DebugLib.h:422
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesNotifyPpi(IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
EFI_STATUS EFIAPI MpInitLibEnableDisableAP(IN UINTN ProcessorNumber, IN BOOLEAN EnableAP, IN UINT32 *HealthFlag OPTIONAL)
Definition: DxeMpLib.c:976
EFI_STATUS EFIAPI MpInitLibStartupAllAPs(IN EFI_AP_PROCEDURE Procedure, IN BOOLEAN SingleThread, IN EFI_EVENT WaitEvent OPTIONAL, IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL, OUT UINTN **FailedCpuList OPTIONAL)
Definition: DxeMpLib.c:738
EFI_STATUS EFIAPI MpInitLibWhoAmI(OUT UINTN *ProcessorNumber)
Definition: MpLib.c:2631
EFI_STATUS EFIAPI MpInitLibGetNumberOfProcessors(OUT UINTN *NumberOfProcessors OPTIONAL, OUT UINTN *NumberOfEnabledProcessors OPTIONAL)
Definition: MpLib.c:2668
EFI_STATUS EFIAPI MpInitLibSwitchBSP(IN UINTN ProcessorNumber, IN BOOLEAN EnableOldBSP)
Definition: DxeMpLib.c:903
EFI_STATUS EFIAPI MpInitLibStartupAllCPUs(IN EFI_AP_PROCEDURE Procedure, IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL)
Definition: MpLib.c:3043
EFI_STATUS EFIAPI MpInitLibGetProcessorInfo(IN UINTN ProcessorNumber, OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer, OUT EFI_HEALTH_FLAGS *HealthData OPTIONAL)
Definition: MpLib.c:2331
EFI_STATUS EFIAPI MpInitLibInitialize(VOID)
Definition: MpLib.c:1987
EFI_STATUS EFIAPI MpInitLibStartupThisAP(IN EFI_AP_PROCEDURE Procedure, IN UINTN ProcessorNumber, IN EFI_EVENT WaitEvent OPTIONAL, IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL, OUT BOOLEAN *Finished OPTIONAL)
Definition: DxeMpLib.c:845
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
VOID(EFIAPI * EFI_AP_PROCEDURE)(IN OUT VOID *Buffer)
Definition: PiMultiPhase.h:191
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
VOID *EFIAPI AllocatePages(IN UINTN Pages)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112