summaryrefslogtreecommitdiff
path: root/ReferenceCode/Haswell/CpuInit/Dxe/MpService.h
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Haswell/CpuInit/Dxe/MpService.h')
-rw-r--r--ReferenceCode/Haswell/CpuInit/Dxe/MpService.h670
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