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