54#define POLL_INTERVAL_US 50000
57STATIC BOOLEAN mNonBlockingModeAllowed;
60CONST UINT64 gApStackSize = AP_STACK_SIZE;
92 mCpuMpData.CpuData[ProcessorIndex].State = CpuStateBusy;
95 if (
sizeof (Args.Arg0) == sizeof (UINT32)) {
96 Args.Arg0 = ARM_SMC_ID_PSCI_CPU_ON_AARCH32;
98 Args.Arg0 = ARM_SMC_ID_PSCI_CPU_ON_AARCH64;
101 Args.Arg1 = gProcessorIDs[ProcessorIndex];
106 if (Args.Arg0 == ARM_SMC_PSCI_RET_ALREADY_ON) {
107 Status = EFI_NOT_READY;
108 }
else if (Args.Arg0 != ARM_SMC_PSCI_RET_SUCCESS) {
109 DEBUG ((DEBUG_ERROR,
"PSCI_CPU_ON call failed: %d\n", Args.Arg0));
110 Status = EFI_DEVICE_ERROR;
130 CpuInfo = &mCpuMpData.CpuData[ProcessorIndex].Info;
146 return CpuData->State;
162 IN VOID *ProcedureArgument
165 ASSERT (CpuData !=
NULL);
166 ASSERT (Procedure !=
NULL);
168 CpuData->Parameter = ProcedureArgument;
169 CpuData->Procedure = Procedure;
190 for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
191 CpuData = &mCpuMpData.CpuData[Index];
197 State = CpuData->State;
199 if (State == CpuStateBlocked) {
205 return EFI_NOT_FOUND;
223 if ((Timeout < POLL_INTERVAL_US) && (Timeout != 0)) {
226 StallTime = POLL_INTERVAL_US;
229 gBS->Stall (StallTime);
276 OUT UINTN *NumberOfEnabledProcessors
279 if ((NumberOfProcessors ==
NULL) || (NumberOfEnabledProcessors ==
NULL)) {
280 return EFI_INVALID_PARAMETER;
284 return EFI_DEVICE_ERROR;
287 *NumberOfProcessors = mCpuMpData.NumberOfProcessors;
288 *NumberOfEnabledProcessors = mCpuMpData.NumberOfEnabledProcessors;
327 if (ProcessorInfoBuffer ==
NULL) {
328 return EFI_INVALID_PARAMETER;
332 return EFI_DEVICE_ERROR;
335 ProcessorIndex &= ~CPU_V2_EXTENDED_TOPOLOGY;
337 if (ProcessorIndex >= mCpuMpData.NumberOfProcessors) {
338 return EFI_NOT_FOUND;
343 &mCpuMpData.CpuData[ProcessorIndex].Info,
500 IN BOOLEAN SingleThread,
502 IN UINTN TimeoutInMicroseconds,
503 IN VOID *ProcedureArgument OPTIONAL,
510 return EFI_DEVICE_ERROR;
513 if ((mCpuMpData.NumberOfProcessors == 1) || (mCpuMpData.NumberOfEnabledProcessors == 1)) {
514 return EFI_NOT_STARTED;
517 if (Procedure ==
NULL) {
518 return EFI_INVALID_PARAMETER;
521 if ((WaitEvent !=
NULL) && !mNonBlockingModeAllowed) {
522 return EFI_UNSUPPORTED;
525 if (FailedCpuList !=
NULL) {
527 (mCpuMpData.NumberOfProcessors + 1) *
530 if (mCpuMpData.FailedList ==
NULL) {
531 return EFI_OUT_OF_RESOURCES;
535 mCpuMpData.FailedList,
536 (mCpuMpData.NumberOfProcessors + 1) *
540 mCpuMpData.FailedListIndex = 0;
541 *FailedCpuList = mCpuMpData.FailedList;
547 if (mCpuMpData.StartCount != (mCpuMpData.NumberOfEnabledProcessors - 1)) {
548 return EFI_NOT_READY;
551 if (WaitEvent !=
NULL) {
556 TimeoutInMicroseconds,
561 if (EFI_ERROR (Status) && (FailedCpuList !=
NULL)) {
562 if (mCpuMpData.FailedListIndex == 0) {
564 *FailedCpuList =
NULL;
571 TimeoutInMicroseconds,
576 if (FailedCpuList !=
NULL) {
577 if (mCpuMpData.FailedListIndex == 0) {
579 *FailedCpuList =
NULL;
681 IN UINTN TimeoutInMicroseconds,
682 IN VOID *ProcedureArgument OPTIONAL,
683 OUT BOOLEAN *Finished OPTIONAL
691 return EFI_DEVICE_ERROR;
694 if (Procedure ==
NULL) {
695 return EFI_INVALID_PARAMETER;
698 if (ProcessorNumber >= mCpuMpData.NumberOfProcessors) {
699 return EFI_NOT_FOUND;
702 CpuData = &mCpuMpData.CpuData[ProcessorNumber];
705 return EFI_INVALID_PARAMETER;
709 return EFI_INVALID_PARAMETER;
715 return EFI_NOT_READY;
718 if ((WaitEvent !=
NULL) && !mNonBlockingModeAllowed) {
719 return EFI_UNSUPPORTED;
722 Timeout = TimeoutInMicroseconds;
724 CpuData->Timeout = TimeoutInMicroseconds;
725 CpuData->TimeTaken = 0;
726 CpuData->TimeoutActive = (BOOLEAN)(TimeoutInMicroseconds != 0);
735 if (EFI_ERROR (Status)) {
736 CpuData->State = CpuStateIdle;
737 return EFI_NOT_READY;
740 if (WaitEvent !=
NULL) {
742 if (Finished !=
NULL) {
743 CpuData->SingleApFinished = Finished;
747 CpuData->WaitEvent = WaitEvent;
748 Status =
gBS->SetTimer (
749 CpuData->CheckThisAPEvent,
759 if (
GetApState (CpuData) == CpuStateFinished) {
760 CpuData->State = CpuStateIdle;
764 if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {
815 IN BOOLEAN EnableOldBSP
818 return EFI_UNSUPPORTED;
869 IN UINT32 *HealthFlag OPTIONAL
875 StatusFlag = mCpuMpData.CpuData[ProcessorNumber].Info.
StatusFlag;
876 CpuData = &mCpuMpData.CpuData[ProcessorNumber];
879 return EFI_DEVICE_ERROR;
882 if (ProcessorNumber >= mCpuMpData.NumberOfProcessors) {
883 return EFI_NOT_FOUND;
887 return EFI_INVALID_PARAMETER;
891 return EFI_UNSUPPORTED;
896 mCpuMpData.NumberOfEnabledProcessors++;
902 mCpuMpData.NumberOfEnabledProcessors--;
905 StatusFlag &= ~PROCESSOR_ENABLED_BIT;
909 StatusFlag &= ~PROCESSOR_HEALTH_STATUS_BIT;
913 mCpuMpData.CpuData[ProcessorNumber].Info.
StatusFlag = StatusFlag;
952 if (ProcessorNumber ==
NULL) {
953 return EFI_INVALID_PARAMETER;
956 ProcessorId = GET_MPIDR_AFFINITY_BITS (ArmReadMpidr ());
957 for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
958 if (ProcessorId == gProcessorIDs[Index]) {
959 *ProcessorNumber = Index;
986 UINTN ProcessorIndex,
995 if ((mCpuMpData.FailedList ==
NULL) ||
996 (ApState == CpuStateIdle) ||
997 (ApState == CpuStateFinished) ||
1004 for (Index = 0; Index < mCpuMpData.FailedListIndex; Index++) {
1005 if (mCpuMpData.FailedList[Index] == ProcessorIndex) {
1013 mCpuMpData.FailedList[mCpuMpData.FailedListIndex++] = ProcessorIndex;
1029 if (mCpuMpData.FailedList ==
NULL) {
1033 for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
1034 CpuData = &mCpuMpData.CpuData[Index];
1045 CpuData = &mCpuMpData.CpuData[Index];
1066 CpuData = &mCpuMpData.CpuData[ProcessorIndex];
1081 case CpuStateFinished:
1082 if (mCpuMpData.SingleThread) {
1084 if (!EFI_ERROR (Status)) {
1085 NextCpuData = &mCpuMpData.CpuData[NextNumber];
1087 NextCpuData->State = CpuStateReady;
1091 mCpuMpData.Procedure,
1092 mCpuMpData.ProcedureArgument
1096 if (!EFI_ERROR (Status)) {
1097 mCpuMpData.StartCount++;
1104 CpuData->State = CpuStateIdle;
1105 mCpuMpData.FinishCount++;
1131 mCpuMpData.AllTimeTaken += POLL_INTERVAL_US;
1133 for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
1137 if (mCpuMpData.AllTimeoutActive && (mCpuMpData.AllTimeTaken > mCpuMpData.AllTimeout)) {
1141 mCpuMpData.FinishCount = mCpuMpData.StartCount;
1144 if (mCpuMpData.FinishCount != mCpuMpData.StartCount) {
1149 mCpuMpData.CheckAllAPsEvent,
1154 if (mCpuMpData.FailedListIndex == 0) {
1155 if (mCpuMpData.FailedList !=
NULL) {
1162 Status =
gBS->SignalEvent (mCpuMpData.AllWaitEvent);
1164 mCpuMpData.AllWaitEvent =
NULL;
1187 CpuData->TimeTaken += POLL_INTERVAL_US;
1191 if (State == CpuStateFinished) {
1192 Status =
gBS->SetTimer (CpuData->CheckThisAPEvent,
TimerCancel, 0);
1195 if (CpuData->SingleApFinished !=
NULL) {
1196 *(CpuData->SingleApFinished) =
TRUE;
1199 if (CpuData->WaitEvent !=
NULL) {
1200 Status =
gBS->SignalEvent (CpuData->WaitEvent);
1204 CpuData->State = CpuStateIdle;
1207 if (CpuData->TimeoutActive && (CpuData->TimeTaken > CpuData->Timeout)) {
1208 Status =
gBS->SetTimer (CpuData->CheckThisAPEvent,
TimerCancel, 0);
1209 if (CpuData->WaitEvent !=
NULL) {
1210 Status =
gBS->SignalEvent (CpuData->WaitEvent);
1212 CpuData->WaitEvent =
NULL;
1239 CpuInfo = &mCpuMpData.CpuData[ProcessorIndex].Info;
1241 CpuInfo->
ProcessorId = GET_MPIDR_AFFINITY_BITS (Mpidr);
1248 if ((Mpidr & MPIDR_MT_BIT) > 0) {
1268 mCpuMpData.CpuData[ProcessorIndex].State = BSP ? CpuStateBusy : CpuStateIdle;
1270 mCpuMpData.CpuData[ProcessorIndex].Procedure =
NULL;
1271 mCpuMpData.CpuData[ProcessorIndex].Parameter =
NULL;
1301 mCpuMpData.NumberOfProcessors = NumberOfProcessors;
1302 mCpuMpData.NumberOfEnabledProcessors = NumberOfProcessors;
1305 mCpuMpData.NumberOfProcessors * sizeof (
CPU_AP_DATA)
1308 if (mCpuMpData.CpuData ==
NULL) {
1309 return EFI_OUT_OF_RESOURCES;
1313 gProcessorIDs =
AllocateZeroPool ((mCpuMpData.NumberOfProcessors + 1) * sizeof (UINT64));
1314 ASSERT (gProcessorIDs !=
NULL);
1316 Status =
gBS->CreateEvent (
1317 EVT_TIMER | EVT_NOTIFY_SIGNAL,
1321 &mCpuMpData.CheckAllAPsEvent
1327 mCpuMpData.NumberOfProcessors *
1331 ASSERT (gApStacksBase !=
NULL);
1333 for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
1334 if (GET_MPIDR_AFFINITY_BITS (ArmReadMpidr ()) == CoreInfo[Index].Mpidr) {
1342 gProcessorIDs[Index] = mCpuMpData.CpuData[Index].Info.
ProcessorId;
1344 Status =
gBS->CreateEvent (
1345 EVT_TIMER | EVT_NOTIFY_SIGNAL,
1348 (VOID *)&mCpuMpData.CpuData[Index],
1349 &mCpuMpData.CpuData[Index].CheckThisAPEvent
1354 gProcessorIDs[Index] = MAX_UINT64;
1356 gTcr = ArmGetTCR ();
1357 gMair = ArmGetMAIR ();
1358 gTtbr0 = ArmGetTTBR0BaseAddress ();
1369 (mCpuMpData.NumberOfProcessors + 1) * sizeof (UINT64)
1372 mNonBlockingModeAllowed =
TRUE;
1402 mNonBlockingModeAllowed =
FALSE;
1431 Status =
gBS->HandleProtocol (
1433 &gEfiLoadedImageProtocolGuid,
1447 HobData = GET_GUID_HOB_DATA (Hob);
1448 HobDataSize = GET_GUID_HOB_DATA_SIZE (Hob);
1454 DEBUG ((DEBUG_WARN,
"Trying to use EFI_MP_SERVICES_PROTOCOL on a UP system"));
1456 return EFI_NOT_FOUND;
1469 Status =
gBS->InstallMultipleProtocolInterfaces (
1471 &gEfiMpServiceProtocolGuid,
1472 &mMpServicesProtocol,
1497 UINTN ProcessorIndex;
1499 Mpidr = GET_MPIDR_AFFINITY_BITS (ArmReadMpidr ());
1502 ProcessorIndex = MAX_UINT64;
1505 if (gProcessorIDs[Index] == Mpidr) {
1506 ProcessorIndex = Index;
1511 }
while (gProcessorIDs[Index] != MAX_UINT64);
1513 if (ProcessorIndex != MAX_UINT64) {
1514 mCpuMpData.CpuData[ProcessorIndex].State = CpuStateFinished;
1515 ArmDataMemoryBarrier ();
1518 Args.Arg0 = ARM_SMC_ID_PSCI_CPU_OFF;
1537 VOID *UserApParameter;
1538 UINTN ProcessorIndex;
1542 WhoAmI (&mMpServicesProtocol, &ProcessorIndex);
1545 UserApProcedure = mCpuMpData.CpuData[ProcessorIndex].Procedure;
1546 UserApParameter = mCpuMpData.CpuData[ProcessorIndex].Parameter;
1548 InitializeCpuExceptionHandlers (
NULL);
1554 UserApProcedure (UserApParameter);
1556 mCpuMpData.CpuData[ProcessorIndex].State = CpuStateFinished;
1558 ArmDataMemoryBarrier ();
1561 Args.Arg0 = ARM_SMC_ID_PSCI_CPU_OFF;
1580 UINTN ProcessorIndex;
1582 Status =
WhoAmI (&mMpServicesProtocol, &ProcessorIndex);
1583 if (EFI_ERROR (Status)) {
1600 UINTN ProcessorIndex
1605 CpuInfo = &mCpuMpData.CpuData[ProcessorIndex].Info;
1618 IN BOOLEAN SingleThread
1622 CPU_STATE APInitialState;
1625 mCpuMpData.FinishCount = 0;
1626 mCpuMpData.StartCount = 0;
1627 mCpuMpData.SingleThread = SingleThread;
1629 APInitialState = CpuStateReady;
1631 for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
1632 CpuData = &mCpuMpData.CpuData[Index];
1649 if (mCpuMpData.FailedList !=
NULL) {
1650 mCpuMpData.FailedList[mCpuMpData.FailedListIndex++] = Index;
1657 if (
GetApState (CpuData) == CpuStateFinished) {
1658 CpuData->State = CpuStateIdle;
1663 if (mCpuMpData.FailedList !=
NULL) {
1664 mCpuMpData.FailedList[mCpuMpData.FailedListIndex++] = Index;
1668 CpuData->State = APInitialState;
1670 mCpuMpData.StartCount++;
1672 APInitialState = CpuStateBlocked;
1694 IN VOID *ProcedureArgument,
1696 IN UINTN TimeoutInMicroseconds,
1697 IN BOOLEAN SingleThread,
1705 for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
1706 CpuData = &mCpuMpData.CpuData[Index];
1719 if ((mCpuMpData.StartCount == 0) || !SingleThread) {
1721 if (EFI_ERROR (Status)) {
1729 if (EFI_ERROR (Status)) {
1730 return EFI_NOT_READY;
1737 mCpuMpData.Procedure = Procedure;
1738 mCpuMpData.ProcedureArgument = ProcedureArgument;
1739 mCpuMpData.AllWaitEvent = WaitEvent;
1740 mCpuMpData.AllTimeout = TimeoutInMicroseconds;
1741 mCpuMpData.AllTimeTaken = 0;
1742 mCpuMpData.AllTimeoutActive = (BOOLEAN)(TimeoutInMicroseconds != 0);
1743 Status =
gBS->SetTimer (
1744 mCpuMpData.CheckAllAPsEvent,
1767 IN VOID *ProcedureArgument,
1768 IN UINTN TimeoutInMicroseconds,
1769 IN BOOLEAN SingleThread,
1778 BOOLEAN DispatchError;
1780 Timeout = TimeoutInMicroseconds;
1781 DispatchError =
FALSE;
1784 for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
1785 CpuData = &mCpuMpData.CpuData[Index];
1800 if (EFI_ERROR (Status)) {
1802 CpuData->State = CpuStateIdle;
1803 mCpuMpData.StartCount--;
1804 DispatchError =
TRUE;
1809 if (!EFI_ERROR (Status)) {
1810 mCpuMpData.CpuData[NextIndex].State = CpuStateReady;
1817 case CpuStateFinished:
1818 mCpuMpData.FinishCount++;
1821 if (!EFI_ERROR (Status)) {
1822 mCpuMpData.CpuData[NextIndex].State = CpuStateReady;
1826 CpuData->State = CpuStateIdle;
1834 if (mCpuMpData.FinishCount == mCpuMpData.StartCount) {
1839 if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {
1840 Status = EFI_TIMEOUT;
1847 if (Status == EFI_TIMEOUT) {
1849 if (FailedCpuList !=
NULL) {
1850 for (Index = 0; Index < mCpuMpData.NumberOfProcessors; Index++) {
1856 if (DispatchError) {
1857 Status = EFI_NOT_READY;
VOID *EFIAPI WriteBackDataCacheRange(IN VOID *Address, IN UINTN Length)
STATIC EFI_STATUS MpServicesInitialize(IN UINTN NumberOfProcessors, IN CONST ARM_CORE_INFO *CoreInfo)
STATIC EFI_STATUS EFIAPI StartupThisAP(IN EFI_MP_SERVICES_PROTOCOL *This, IN EFI_AP_PROCEDURE Procedure, IN UINTN ProcessorNumber, IN EFI_EVENT WaitEvent OPTIONAL, IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL, OUT BOOLEAN *Finished OPTIONAL)
CPU_STATE GetApState(IN CPU_AP_DATA *CpuData)
STATIC EFI_STATUS FillInProcessorInformation(IN BOOLEAN BSP, IN UINTN Mpidr, IN UINTN ProcessorIndex)
STATIC EFI_STATUS EFIAPI SwitchBSP(IN EFI_MP_SERVICES_PROTOCOL *This, IN UINTN ProcessorNumber, IN BOOLEAN EnableOldBSP)
STATIC EFI_STATUS EFIAPI DispatchCpu(IN UINTN ProcessorIndex)
STATIC EFI_STATUS StartupAllAPsWithWaitEvent(IN EFI_AP_PROCEDURE Procedure, IN VOID *ProcedureArgument, IN EFI_EVENT WaitEvent, IN UINTN TimeoutInMicroseconds, IN BOOLEAN SingleThread, IN UINTN **FailedCpuList)
STATIC BOOLEAN IsProcessorBSP(UINTN ProcessorIndex)
EFI_STATUS EFIAPI ArmPsciMpServicesDxeInitialize(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
STATIC VOID StartupAllAPsPrepareState(IN BOOLEAN SingleThread)
STATIC EFI_STATUS EFIAPI EnableDisableAP(IN EFI_MP_SERVICES_PROTOCOL *This, IN UINTN ProcessorNumber, IN BOOLEAN EnableAP, IN UINT32 *HealthFlag OPTIONAL)
STATIC EFI_STATUS EFIAPI GetProcessorInfo(IN EFI_MP_SERVICES_PROTOCOL *This, IN UINTN ProcessorIndex, OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer)
STATIC EFI_STATUS EFIAPI WhoAmI(IN EFI_MP_SERVICES_PROTOCOL *This, OUT UINTN *ProcessorNumber)
STATIC BOOLEAN IsProcessorEnabled(UINTN ProcessorIndex)
STATIC UINTN CalculateAndStallInterval(IN UINTN Timeout)
STATIC VOID EFIAPI CheckAllAPsStatus(IN EFI_EVENT Event, IN VOID *Context)
STATIC VOID EFIAPI ReadyToBootSignaled(IN EFI_EVENT Event, IN VOID *Context)
STATIC EFI_STATUS EFIAPI StartupAllAPs(IN EFI_MP_SERVICES_PROTOCOL *This, IN EFI_AP_PROCEDURE Procedure, IN BOOLEAN SingleThread, IN EFI_EVENT WaitEvent OPTIONAL, IN UINTN TimeoutInMicroseconds, IN VOID *ProcedureArgument OPTIONAL, OUT UINTN **FailedCpuList OPTIONAL)
STATIC VOID UpdateApStatus(IN UINTN ProcessorIndex)
STATIC EFI_STATUS StartupAllAPsNoWaitEvent(IN EFI_AP_PROCEDURE Procedure, IN VOID *ProcedureArgument, IN UINTN TimeoutInMicroseconds, IN BOOLEAN SingleThread, IN UINTN **FailedCpuList)
STATIC VOID SetApProcedure(IN CPU_AP_DATA *CpuData, IN EFI_AP_PROCEDURE Procedure, IN VOID *ProcedureArgument)
STATIC EFI_STATUS EFIAPI GetNumberOfProcessors(IN EFI_MP_SERVICES_PROTOCOL *This, OUT UINTN *NumberOfProcessors, OUT UINTN *NumberOfEnabledProcessors)
STATIC VOID AddProcessorToFailedList(UINTN ProcessorIndex, CPU_STATE ApState)
STATIC VOID EFIAPI CheckThisAPStatus(IN EFI_EVENT Event, IN VOID *Context)
STATIC BOOLEAN IsCurrentProcessorBSP(VOID)
STATIC VOID ProcessStartupAllAPsTimeout(VOID)
STATIC EFI_STATUS GetNextBlockedNumber(OUT UINTN *NextNumber)
STATIC VOID EFIAPI ApExceptionHandler(IN CONST EFI_EXCEPTION_TYPE InterruptType, IN CONST EFI_SYSTEM_CONTEXT SystemContext)
VOID ArmCallSmc(IN OUT ARM_SMC_ARGS *Args)
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
VOID EFIAPI CpuDeadLoop(VOID)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMemN(OUT VOID *Buffer, IN UINTN Length, IN UINTN Value)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS
#define PROCESSOR_HEALTH_STATUS_BIT
#define PROCESSOR_AS_BSP_BIT
#define PROCESSOR_ENABLED_BIT
VOID(EFIAPI * EFI_AP_PROCEDURE)(IN OUT VOID *Buffer)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
#define EFI_SIZE_TO_PAGES(Size)
EFI_STATUS EFIAPI EfiCreateEventReadyToBootEx(IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction OPTIONAL, IN VOID *NotifyContext OPTIONAL, OUT EFI_EVENT *ReadyToBootEvent)
UINT64 ImageSize
The size in bytes of the loaded image.
VOID * ImageBase
The base address at which the image was loaded.
EXTENDED_PROCESSOR_INFORMATION ExtendedInformation
EFI_CPU_PHYSICAL_LOCATION Location
EFI_CPU_PHYSICAL_LOCATION2 Location2