--- /dev/null
+/** @file\r
+\r
+Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Portions copyright (c) 2011, Apple Inc. All rights reserved.\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef MP_SERVICES_INTERNAL_H_\r
+#define MP_SERVICES_INTERNAL_H_\r
+\r
+#include <Protocol/Cpu.h>\r
+#include <Protocol/MpService.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#define AP_STACK_SIZE 0x1000\r
+\r
+//\r
+// Internal Data Structures\r
+//\r
+\r
+//\r
+// AP state\r
+//\r
+// The state transitions for an AP when it processes a procedure are:\r
+// Idle ----> Ready ----> Busy ----> Finished ----> Idle\r
+// [BSP] [BSP] [AP] [BSP]\r
+//\r
+typedef enum {\r
+ CpuStateIdle,\r
+ CpuStateReady,\r
+ CpuStateBlocked,\r
+ CpuStateBusy,\r
+ CpuStateFinished,\r
+ CpuStateDisabled\r
+} CPU_STATE;\r
+\r
+//\r
+// Define Individual Processor Data block.\r
+//\r
+typedef struct {\r
+ EFI_PROCESSOR_INFORMATION Info;\r
+ EFI_AP_PROCEDURE Procedure;\r
+ VOID *Parameter;\r
+ CPU_STATE State;\r
+ EFI_EVENT CheckThisAPEvent;\r
+ EFI_EVENT WaitEvent;\r
+ UINTN Timeout;\r
+ UINTN TimeTaken;\r
+ BOOLEAN TimeoutActive;\r
+ BOOLEAN *SingleApFinished;\r
+} CPU_AP_DATA;\r
+\r
+//\r
+// Define MP data block which consumes individual processor block.\r
+//\r
+typedef struct {\r
+ UINTN NumberOfProcessors;\r
+ UINTN NumberOfEnabledProcessors;\r
+ EFI_EVENT CheckAllAPsEvent;\r
+ EFI_EVENT AllWaitEvent;\r
+ UINTN FinishCount;\r
+ UINTN StartCount;\r
+ EFI_AP_PROCEDURE Procedure;\r
+ VOID *ProcedureArgument;\r
+ BOOLEAN SingleThread;\r
+ UINTN StartedNumber;\r
+ CPU_AP_DATA *CpuData;\r
+ UINTN *FailedList;\r
+ UINTN FailedListIndex;\r
+ UINTN AllTimeout;\r
+ UINTN AllTimeTaken;\r
+ BOOLEAN AllTimeoutActive;\r
+} CPU_MP_DATA;\r
+\r
+/** Secondary core entry point.\r
+\r
+**/\r
+VOID\r
+ApEntryPoint (\r
+ VOID\r
+ );\r
+\r
+/** C entry-point for the AP.\r
+ This function gets called from the assembly function ApEntryPoint.\r
+**/\r
+VOID\r
+ApProcedure (\r
+ VOID\r
+ );\r
+\r
+/** Turns on the specified core using PSCI and executes the user-supplied\r
+ function that's been configured via a previous call to SetApProcedure.\r
+\r
+ @param ProcessorIndex The index of the core to turn on.\r
+\r
+ @retval EFI_SUCCESS The processor was successfully turned on.\r
+ @retval EFI_DEVICE_ERROR An error occurred turning the processor on.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+DispatchCpu (\r
+ IN UINTN ProcessorIndex\r
+ );\r
+\r
+/** Returns whether the specified processor is the BSP.\r
+\r
+ @param[in] ProcessorIndex The index the processor to check.\r
+\r
+ @return TRUE if the processor is the BSP, FALSE otherwise.\r
+**/\r
+STATIC\r
+BOOLEAN\r
+IsProcessorBSP (\r
+ UINTN ProcessorIndex\r
+ );\r
+\r
+/** Returns whether the processor executing this function is the BSP.\r
+\r
+ @return Whether the current processor is the BSP.\r
+**/\r
+STATIC\r
+BOOLEAN\r
+IsCurrentProcessorBSP (\r
+ VOID\r
+ );\r
+\r
+/** Returns whether the specified processor is enabled.\r
+\r
+ @param[in] ProcessorIndex The index of the processor to check.\r
+\r
+ @return TRUE if the processor is enabled, FALSE otherwise.\r
+**/\r
+STATIC\r
+BOOLEAN\r
+IsProcessorEnabled (\r
+ UINTN ProcessorIndex\r
+ );\r
+\r
+/** Configures the processor context with the user-supplied procedure and\r
+ argument.\r
+\r
+ @param CpuData The processor context.\r
+ @param Procedure The user-supplied procedure.\r
+ @param ProcedureArgument The user-supplied procedure argument.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+SetApProcedure (\r
+ IN CPU_AP_DATA *CpuData,\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN VOID *ProcedureArgument\r
+ );\r
+\r
+/**\r
+ Get the Application Processors state.\r
+\r
+ @param[in] CpuData The pointer to CPU_AP_DATA of specified AP\r
+\r
+ @return The AP status\r
+**/\r
+CPU_STATE\r
+GetApState (\r
+ IN CPU_AP_DATA *CpuData\r
+ );\r
+\r
+/** Returns the index of the next processor that is blocked.\r
+\r
+ @param[out] NextNumber The index of the next blocked processor.\r
+\r
+ @retval EFI_SUCCESS Successfully found the next blocked processor.\r
+ @retval EFI_NOT_FOUND There are no blocked processors.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+GetNextBlockedNumber (\r
+ OUT UINTN *NextNumber\r
+ );\r
+\r
+/** Stalls the BSP for the minimum of gPollInterval and Timeout.\r
+\r
+ @param[in] Timeout The time limit in microseconds remaining for\r
+ APs to return from Procedure.\r
+\r
+ @retval StallTime Time of execution stall.\r
+**/\r
+STATIC\r
+UINTN\r
+CalculateAndStallInterval (\r
+ IN UINTN Timeout\r
+ );\r
+\r
+/** Sets up the state for the StartupAllAPs function.\r
+\r
+ @param SingleThread Whether the APs will execute sequentially.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+StartupAllAPsPrepareState (\r
+ IN BOOLEAN SingleThread\r
+ );\r
+\r
+/** Handles execution of StartupAllAPs when a WaitEvent has been specified.\r
+\r
+ @param Procedure The user-supplied procedure.\r
+ @param ProcedureArgument The user-supplied procedure argument.\r
+ @param WaitEvent The wait event to be signaled when the work is\r
+ complete or a timeout has occurred.\r
+ @param TimeoutInMicroseconds The timeout for the work to be completed. Zero\r
+ indicates an infinite timeout.\r
+ @param SingleThread Whether the APs will execute sequentially.\r
+ @param FailedCpuList User-supplied pointer for list of failed CPUs.\r
+\r
+ @return EFI_SUCCESS on success.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+StartupAllAPsWithWaitEvent (\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN VOID *ProcedureArgument,\r
+ IN EFI_EVENT WaitEvent,\r
+ IN UINTN TimeoutInMicroseconds,\r
+ IN BOOLEAN SingleThread,\r
+ IN UINTN **FailedCpuList\r
+ );\r
+\r
+/** Handles execution of StartupAllAPs when no wait event has been specified.\r
+\r
+ @param Procedure The user-supplied procedure.\r
+ @param ProcedureArgument The user-supplied procedure argument.\r
+ @param TimeoutInMicroseconds The timeout for the work to be completed. Zero\r
+ indicates an infinite timeout.\r
+ @param SingleThread Whether the APs will execute sequentially.\r
+ @param FailedCpuList User-supplied pointer for list of failed CPUs.\r
+\r
+ @return EFI_SUCCESS on success.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+StartupAllAPsNoWaitEvent (\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN VOID *ProcedureArgument,\r
+ IN UINTN TimeoutInMicroseconds,\r
+ IN BOOLEAN SingleThread,\r
+ IN UINTN **FailedCpuList\r
+ );\r
+\r
+/** Adds the specified processor the list of failed processors.\r
+\r
+ @param ProcessorIndex The processor index to add.\r
+ @param ApState Processor state.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+AddProcessorToFailedList (\r
+ UINTN ProcessorIndex,\r
+ CPU_STATE ApState\r
+ );\r
+\r
+/** Handles the StartupAllAPs case where the timeout has occurred.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+ProcessStartupAllAPsTimeout (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ If a timeout is specified in StartupAllAps(), a timer is set, which invokes\r
+ this procedure periodically to check whether all APs have finished.\r
+\r
+ @param[in] Event The WaitEvent the user supplied.\r
+ @param[in] Context The event context.\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+CheckAllAPsStatus (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+/** Invoked periodically via a timer to check the state of the processor.\r
+\r
+ @param Event The event supplied by the timer expiration.\r
+ @param Context The processor context.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+CheckThisAPStatus (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+/**\r
+ This function is called by all processors (both BSP and AP) once and collects\r
+ MP related data.\r
+\r
+ @param BSP TRUE if the processor is the BSP.\r
+ @param Mpidr The MPIDR for the specified processor. This should be\r
+ the full MPIDR and not only the affinity bits.\r
+ @param ProcessorIndex The index of the processor.\r
+\r
+ @return EFI_SUCCESS if the data for the processor collected and filled in.\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+FillInProcessorInformation (\r
+ IN BOOLEAN BSP,\r
+ IN UINTN Mpidr,\r
+ IN UINTN ProcessorIndex\r
+ );\r
+\r
+/**\r
+ Event notification function called when the EFI_EVENT_GROUP_READY_TO_BOOT is\r
+ signaled. After this point, non-blocking mode is no longer allowed.\r
+\r
+ @param Event Event whose notification function is being invoked.\r
+ @param Context The pointer to the notification function's context,\r
+ which is implementation-dependent.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+ReadyToBootSignaled (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+#endif /* MP_SERVICES_INTERNAL_H_ */\r