diff options
Diffstat (limited to 'ReferenceCode/Haswell/CpuInit/Dxe/MpService.h')
-rw-r--r-- | ReferenceCode/Haswell/CpuInit/Dxe/MpService.h | 670 |
1 files changed, 670 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/CpuInit/Dxe/MpService.h b/ReferenceCode/Haswell/CpuInit/Dxe/MpService.h new file mode 100644 index 0000000..7fa7544 --- /dev/null +++ b/ReferenceCode/Haswell/CpuInit/Dxe/MpService.h @@ -0,0 +1,670 @@ +/** @file + Some definitions for MP services Protocol. + +@copyright + Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#ifndef _MP_SERVICE_H_ +#define _MP_SERVICE_H_ + +#include "MpCommon.h" + +/// +/// Driver Produced Protocol. +/// +#include EFI_PROTOCOL_PRODUCER (MpService) +#include EFI_PROTOCOL_PRODUCER (PiMpService) + +// +// Constant definitions +// +#define FOURGB 0x100000000 +#define ONEPAGE 0x1000 + +#define RENDEZVOUS_PROC_LENGTH 0x1000 +#define STACK_SIZE_PER_PROC 0x8000 +#define MAX_CPU_S3_MTRR_ENTRY 0x0020 +#define MAX_CPU_S3_TABLE_SIZE 0x0400 + +#define AP_HALT_CODE_SIZE 10 + +#define CPU_CHECK_AP_INTERVAL 10 // multiply to microseconds for gBS->SetTimer in 100nsec. +#define CPU_WAIT_FOR_TASK_TO_BE_COMPLETED 100000 // microseconds +/// +/// The MP data structure follows. +/// +#define CPU_SWITCH_STATE_IDLE 0 +#define CPU_SWITCH_STATE_STORED 1 +#define CPU_SWITCH_STATE_LOADED 2 + +#define MSR_L3_CACHE_DISABLE 0x40 + +typedef struct { + UINT8 Lock; ///< offset 0 + UINT8 State; ///< offset 1 + UINTN StackPointer; ///< offset 4 / 8 + PSEUDO_DESCRIPTOR Gdtr; ///< offset 8 / 16 + PSEUDO_DESCRIPTOR Idtr; ///< offset 14 / 26 +} CPU_EXCHANGE_ROLE_INFO; + +// +// MTRR table definitions +// +typedef struct { + UINT16 Index; + UINT64 Value; +} EFI_MTRR_VALUES; + +typedef enum { + CPU_STATE_IDLE, + CPU_STATE_BLOCKED, + CPU_STATE_READY, + CPU_STATE_BUSY, + CPU_STATE_FINISHED, + CPU_STATE_DISABLED +} CPU_STATE; + +// +// Define CPU feature information +// +#define MAX_FEATURE_NUM 6 +typedef struct { + UINTN Index; + UINT32 ApicId; + UINT32 Version; + UINT32 FeatureDelta; + UINT32 Features[MAX_FEATURE_NUM]; +} LEAST_FEATURE_PROC; + +/// +/// Define Individual Processor Data block. +/// +typedef struct { + UINT32 ApicID; + EFI_AP_PROCEDURE Procedure; + VOID *Parameter; + UINT8 StateLock; + UINT8 ProcedureLock; + EFI_MP_HEALTH_FLAGS Health; + BOOLEAN SecondaryCpu; + UINTN NumberOfCores; + UINTN NumberOfThreads; + UINT64 ActualFsbFrequency; + EFI_STATUS MicrocodeStatus; + UINT32 FailedRevision; + PHYSICAL_LOCATION PhysicalLocation; + CPU_STATE State; + CPU_DATA_FOR_DATAHUB CpuDataforDatahub; + + // + // for PI MP Services Protocol + // + BOOLEAN *Finished; + UINT64 ExpectedTime; + EFI_EVENT WaitEvent; + EFI_EVENT CheckThisAPEvent; +} CPU_DATA_BLOCK; + +typedef struct { + UINT32 ApicId; + UINT32 MsrIndex; + UINT64 MsrValue; +} MP_CPU_S3_SCRIPT_DATA; + +typedef struct { + UINT32 S3BootScriptTable; + UINT32 S3BspMtrrTable; +} MP_CPU_S3_DATA_POINTER; + +#pragma pack(1) +typedef struct { + UINT32 ApicId; + EFI_MP_HEALTH_FLAGS Health; +} BIST_HOB_DATA; +#pragma pack() + +/// +/// Define MP data block which consumes individual processor block. +/// +typedef struct { + UINT8 APSerializeLock; + + BOOLEAN LimitCpuidMaximumValue; ///< make processor look like < F40 + BOOLEAN VmxEnable; + BOOLEAN ProcessorVmxEnable; + BOOLEAN ProcessorBistEnable; + BOOLEAN TxtEnable; + BOOLEAN MonitorMwaitEnable; + BOOLEAN ExecuteDisableBit; + BOOLEAN MachineCheckEnable; + BOOLEAN XapicEnable; + BOOLEAN AesEnable; + BOOLEAN DebugInterfaceEnable; + BOOLEAN DebugInterfaceLockEnable; + BOOLEAN EnableSecondaryCpu; + UINTN NumberOfCpus; + UINTN MaximumCpusForThisSystem; + + CPU_EXCHANGE_ROLE_INFO BSPInfo; + CPU_EXCHANGE_ROLE_INFO APInfo; + + EFI_CPU_ARCH_PROTOCOL *CpuArch; + EFI_EVENT CheckAllAPsEvent; + EFI_EVENT WaitEvent; + UINTN BSP; + BIST_HOB_DATA *BistHobData; + UINTN BistHobSize; + + UINTN FinishCount; + UINTN StartCount; + EFI_AP_PROCEDURE Procedure; + VOID *ProcArguments; + BOOLEAN SingleThread; + UINTN StartedCpuNumber; + + CPU_DATA_BLOCK CpuData[MAXIMUM_CPU_NUMBER]; + CPU_STATE_CHANGE_CAUSE DisableCause[MAXIMUM_CPU_NUMBER]; + + UINT8 S3BootScriptLock; + UINT32 S3BootScriptCount; + MP_CPU_S3_DATA_POINTER S3DataPointer; + MP_CPU_S3_SCRIPT_DATA S3BootScriptTable[MAX_CPU_S3_TABLE_SIZE]; + EFI_MTRR_VALUES S3BspMtrrTable[MAX_CPU_S3_MTRR_ENTRY]; + + /// + /// for PI MP Services Protocol + /// + BOOLEAN CpuList[MAXIMUM_CPU_NUMBER]; + UINTN **FailedCpuList; + UINT64 ExpectedTime; + EFI_EVENT CheckAPsEvent; +} MP_SYSTEM_DATA; + +typedef struct { + ACPI_CPU_DATA AcpiCpuData; + MP_SYSTEM_DATA MPSystemData; + PSEUDO_DESCRIPTOR GdtrProfile; + PSEUDO_DESCRIPTOR IdtrProfile; + EFI_CPU_MICROCODE_HEADER *MicrocodePointerBuffer[NUMBER_OF_MICROCODE_UPDATE + 1]; +} MP_CPU_RESERVED_DATA; + +extern MP_SYSTEM_DATA *mMPSystemData; +extern ACPI_CPU_DATA *mAcpiCpuData; +extern EFI_MP_SERVICES_PROTOCOL mMpService; +extern EFI_PI_MP_SERVICES_PROTOCOL mPiMpService; + +/// +/// Prototypes. +/// + +/** + Get general MP information + + @param[in] This - EFI_MP_SERVICE_PROTOCOL + @param[in] NumberOfCPUs - Number of processors + @param[in] MaxiumNumberOfCPUs - Max supported number of processors + @param[in] NumberOfEnabledCPUs - Number of processors enabled + @param[in] RendezvousIntNumber - number of Rendezvous procedure + @param[in] RendezvousProcLength - length of Rendezvous procedure + + @retval EFI_SUCCESS - always return success +**/ +EFI_STATUS +EFIAPI +GetGeneralMPInfo ( + IN EFI_MP_SERVICES_PROTOCOL *This, + OUT UINTN *NumberOfCPUs, + OUT UINTN *MaxiumNumberOfCPUs, + OUT UINTN *NumberOfEnabledCPUs, + OUT UINTN *RendezvousIntNumber, + OUT UINTN *RendezvousProcLength + ); + +/** + Get processor context + + @param[in] This - EFI_MP_SERVICE_PROTOCOL + @param[in] ProcessorNumber - The handle number of processor. + @param[in] BufferLength - buffer length + @param[in] ProcessorContextBuffer - pointer to the buffer that will be updated + + @retval EFI_INVALID_PARAMETER - buffer is NULL or CpuNumber our of range + @retval EFI_BUFFER_TOO_SMALL - buffer too small + @retval EFI_SUCCESS - got processor context successfully +**/ +EFI_STATUS +EFIAPI +GetProcessorContext ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN OUT UINTN *BufferLength, + IN OUT EFI_MP_PROC_CONTEXT *ProcessorContextBuffer + ); + +/** + MP Service to get specified application processor (AP) + to execute a caller-provided code stream. + + @param[in] This - Pointer to MP Service Protocol + @param[in] Procedure - The procedure to be assigned to AP. + @param[in] ProcessorNumber - The handle number of processor. + @param[in] WaitEvent - If timeout, the event to be triggered after this AP finishes. + @param[in] TimeoutInMicroSecs - The timeout value in microsecond. Zero means infinity. + @param[in] ProcArguments - Argument for Procedure. + + @retval EFI_INVALID_PARAMETER - Procudure is NULL. + @retval EFI_INVALID_PARAMETER - Number of CPU out of range, or it belongs to BSP. + @retval EFI_INVALID_PARAMETER - Specified CPU is not idle. + @retval EFI_SUCCESS - The AP has finished. + @retval EFI_TIMEOUT - Time goes out before the AP has finished. +**/ +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 TimeoutInMicroSecs OPTIONAL, + IN OUT VOID *ProcArguments OPTIONAL + ); + +/** + MP Service to get all the available application processors (APs) + to execute a caller-provided code stream. + + @param[in] This - Pointer to MP Service Protocol + @param[in] Procedure - The procedure to be assigned to APs. + @param[in] SingleThread - If true, all APs execute in block mode. + Otherwise, all APs exceute in non-block mode. + @param[in] WaitEvent - If timeout, the event to be triggered after all APs finish. + @param[in] TimeoutInMicroSecs - The timeout value in microsecond. Zero means infinity. + @param[in] ProcArguments - Argument for Procedure. + @param[in] FailedCPUList - If not NULL, all APs that fail to start will be recorded in the list. + + @retval EFI_INVALID_PARAMETER - Procudure is NULL. + @retval EFI_SUCCESS - Only 1 logical processor exists. + @retval EFI_SUCCESS - All APs have finished. + @retval EFI_TIMEOUT - Time goes out before all APs have finished. +**/ +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 TimeoutInMicroSecs OPTIONAL, + IN OUT VOID *ProcArguments OPTIONAL, + OUT UINTN *FailedCPUList OPTIONAL + ); + +/** + MP Service to makes the current BSP into an AP and then switches the + designated AP into the AP. This procedure is usually called after a CPU + test that has found that BSP is not healthy to continue it's responsbilities. + + @param[in] This - Pointer to MP Service Protocol. + @param[in] ProcessorNumber - The handle number of processor. + @param[in] EnableOldBSPState - Whether to enable or disable the original BSP. + + @retval EFI_INVALID_PARAMETER - Number for Specified AP out of range. + @retval EFI_INVALID_PARAMETER - Number of specified CPU belongs to BSP. + @retval EFI_NOT_READY - Specified AP is not idle. + @retval EFI_SUCCESS - BSP successfully switched. +**/ +EFI_STATUS +EFIAPI +SwitchBSP ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN BOOLEAN EnableOldBSPState + ); + +/** + This procedure sends an IPI to the designated processor in + the requested delivery mode with the requested vector. + + @param[in] This - Pointer to MP Service Protocol. + @param[in] ProcessorNumber - The handle number of processor. + @param[in] VectorNumber - Vector number. + @param[in] DeliveryMode - I/O APIC Interrupt Deliver Modes + + @retval EFI_INVALID_PARAMETER - Input paramters were not correct. + @retval Other status - Status returned by SendInterrupt () +**/ +EFI_STATUS +EFIAPI +SendIPI ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN UINTN VectorNumber, + IN UINTN DeliveryMode + ); + +/** + Implementation of EnableDisableAP() service of MP Services Protocol. + + This service lets the caller enable or disable an AP. + This service may only be called from the BSP. + + @param[in] This - A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[in] ProcessorNumber - The handle number of processor. + @param[in] NewAPState - Indicates whether the newstate of the AP is enabled or disabled. + @param[in] HealthState - Indicates new health state of the AP.. + + @retval EFI_SUCCESS - AP successfully enabled or disabled. + @retval EFI_DEVICE_ERROR - Caller processor is AP. + @retval EFI_NOT_FOUND - Processor with the handle specified by ProcessorNumber does not exist. + @retval EFI_INVALID_PARAMETERS - ProcessorNumber specifies the BSP. +**/ +EFI_STATUS +EFIAPI +EnableDisableAP ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN BOOLEAN NewAPState, + IN EFI_MP_HEALTH *HealthState OPTIONAL + ); + +/** + Initialize multiple processors and collect MP related data + + @retval EFI_SUCCESS - Multiple processors get initialized and data collected successfully + @retval Other - The operation failed due to some reason +**/ +EFI_STATUS +InitializeMpSystemData ( + VOID + ); + +/** + Wake up all the application processors + + @param[in] ImageHandle - The firmware allocated handle for the EFI image. + @param[in] SystemTable - A pointer to the EFI System Table. + + @retval EFI_SUCCESS - APs are successfully waked up +**/ +EFI_STATUS +WakeUpAPs ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Exchange 2 processors (BSP to AP or AP to BSP) + + @param[in] MyInfo - CPU info for current processor + @param[in] OthersInfo - CPU info that will be exchanged with +**/ +VOID +AsmExchangeRole ( + IN CPU_EXCHANGE_ROLE_INFO *MyInfo, + IN CPU_EXCHANGE_ROLE_INFO *OthersInfo + ); + +/** + Switch current BSP processor to AP + + @param[in] MPSystemData - Pointer to the data structure containing MP related data +**/ +VOID +FutureBSPProc ( + IN MP_SYSTEM_DATA *MPSystemData + ); + +/** + Searches the HOB list provided by the core to find + if a MP guided HOB list exists or not. If it does, it copies it to the driver + data area, else returns 0 + + @param[in] MPSystemData - Pointer to an MP_SYSTEM_DATA structure + + @retval EFI_SUCCESS - Success + @retval EFI_NOT_FOUND - HOB not found or else +**/ +EFI_STATUS +GetMpBistStatus ( + IN MP_SYSTEM_DATA *MPSystemData + ); + +/** + Initialize the state information for the MP DXE Protocol. +**/ +VOID +EFIAPI +InitializeMpServices ( + VOID + ); + +/** + Prepare for MTRR synchronization. + + @retval CR4 value before changing. +**/ +UINTN +MpMtrrSynchUpEntry ( + VOID + ); + +/** + Restoration after MTRR synchronization. + + @param[in] Cr4 - CR4 value before changing. +**/ +VOID +MpMtrrSynchUpExit ( + UINTN Cr4 + ); + +/** + Copy Global MTRR data to S3 +**/ +VOID +SaveBspMtrrForS3 ( + VOID + ); + +/** + This function is called by all processors (both BSP and AP) once and collects MP related data + + @param[in] MPSystemData - Pointer to the data structure containing MP related data + @param[in] BSP - TRUE if the CPU is BSP + @param[in] BistParam - BIST (build-in self test) data for the processor. This data + is only valid for processors that are waked up for the 1st + time in this CPU DXE driver. + + @retval EFI_SUCCESS - Data for the processor collected and filled in +**/ +EFI_STATUS +FillInProcessorInformation ( + IN MP_SYSTEM_DATA *MPSystemData, + IN BOOLEAN BSP, + IN UINT32 BistParam + ); + +/** + Set APIC BSP bit + + @param[in] Enable - enable as BSP or not + + @retval EFI_SUCCESS - always return success +**/ +EFI_STATUS +SetApicBSPBit ( + IN BOOLEAN Enable + ); + +/** + Switch BSP to the processor which has least features + + @param[in] MpServices - EFI_MP_SERVICES_PROTOCOL + + @retval EFI_STATUS - status code returned from each sub-routines +**/ +EFI_STATUS +SwitchToLowestFeatureProcess ( + IN EFI_MP_SERVICES_PROTOCOL *MpServices + ); + +/** + Change CPU state + + @param[in] CpuNumber - CPU number + @param[in] NewState - the new state that will be changed to + @param[in] Cause - Cause + + @retval EFI_SUCCESS - always return success +**/ +EFI_STATUS +ChangeCpuState ( + IN UINTN CpuNumber, + IN BOOLEAN NewState, + IN CPU_STATE_CHANGE_CAUSE Cause + ); + +/** + Check if this is non-core processor - HT AP thread + + @retval TRUE if this is HT AP thread + @retval FALSE if this is core thread +**/ +BOOLEAN +IsSecondaryThread ( + VOID + ); + +/** + If timeout occurs in StartupAllAps(), a timer is set, which invokes this + procedure periodically to check whether all APs have finished. + + @param[in] Event - Event triggered. + @param[in] Context - Parameter passed with the event. +**/ +VOID +CheckAllAPsStatus ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Check if this AP has finished task + + @param[in] Event - Event triggered. + @param[in] Context - Parameter passed with the event. +**/ +VOID +CheckThisAPStatus ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Convert the timeout value to TSC value + + @param[in] TimeoutInMicroSecs - how many microseconds the timeout is + + @retval expected TSC value for timeout +**/ +UINT64 +CalculateTimeout ( + IN UINTN TimeoutInMicroSecs + ); + +/** + Check if timeout happened + + @param[in] ExpectedTsc - the TSC value for timeout + + @retval TRUE if timeout happened + @retval FALSE if timeout not yet happened +**/ +BOOLEAN +CheckTimeout ( + IN UINT64 ExpectedTsc + ); + +/** + Get the next blocked processor + + @param[in] NextCpuNumber - that will be updated for next blocked CPU number + + @retval EFI_SUCCESS - The next blocked CPU found + @retval EFI_NOT_FOUND - cannot find blocked CPU +**/ +EFI_STATUS +GetNextBlockedCpuNumber ( + OUT UINTN *NextCpuNumber + ); + +/** + Update data hub for processor status + + @param[in] CpuNumber - CPU number + @param[in] CpuDataforDatahub - the data hub that will be updated +**/ +VOID +UpdateDataforDatahub ( + IN UINTN CpuNumber, + OUT CPU_DATA_FOR_DATAHUB *CpuDataforDatahub + ); + +/** + Procedure for detailed initialization of APs. It will be assigned to all APs while + they are waken up for the second time. +**/ +VOID +DetailedMpInitialization ( + VOID + ); + +/** + Function to wake up a specified AP and assign procedure to it. + + @param[in] CpuData - CPU data block for the specified AP. + @param[in] Procedure - Procedure to assign. + @param[in] Parameter - Argument for Procedure. +**/ +VOID +WakeUpAp ( + IN CPU_DATA_BLOCK *CpuData, + IN EFI_AP_PROCEDURE Procedure, + IN VOID *Parameter + ); + +/** + Check number of cores in the package. + + @retval Number of cores in the package. +**/ +UINT8 +GetCoreNumber ( + VOID + ); + +/** + Re-load microcode patch before boot. + + @retval EFI_SUCCESS - Multiple processors re-load microcode patch +**/ +EFI_STATUS +ReLoadMicrocodeBeforeBoot ( + VOID + ); + +#endif |