diff options
Diffstat (limited to 'ReferenceCode/Haswell/CpuInit/Dxe/MpCommon.h')
-rw-r--r-- | ReferenceCode/Haswell/CpuInit/Dxe/MpCommon.h | 606 |
1 files changed, 606 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/CpuInit/Dxe/MpCommon.h b/ReferenceCode/Haswell/CpuInit/Dxe/MpCommon.h new file mode 100644 index 0000000..7677e80 --- /dev/null +++ b/ReferenceCode/Haswell/CpuInit/Dxe/MpCommon.h @@ -0,0 +1,606 @@ +/** @file + Some definitions for MP and HT driver. + +@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_COMMON_ +#define _MP_COMMON_ + +#include "ProcessorData.h" +#include "CacheData.h" +#include "Exception.h" +#include "ProcessorDef.h" + +// +// Protocol produced by this driver +// +#include EFI_PROTOCOL_PRODUCER (MpService) + +// +// Protocol consumed by this driver +// +#include EFI_PROTOCOL_DEFINITION (CpuPlatformPolicy) + +// +// GUID definitions +// +#include EFI_GUID_DEFINITION (HtBistHOB) +#include EFI_GUID_DEFINITION (SmramCpuDataVariable) +#include EFI_GUID_DEFINITION (SmramCpuDataHeader) + +#define VacantFlag 0x00 +#define NotVacantFlag 0xff +#define MICROSECOND 10 +#define MAXIMUM_CPU_NUMBER 0x40 +#define STACK_SIZE_PER_PROC 0x8000 + +#define IO_APIC_INDEX_REGISTER 0xFEC00000 +#define IO_APIC_DATA_REGISTER 0xFEC00010 + +/// +/// Data structure used in MP/HT driver +/// +#define MP_CPU_EXCHANGE_INFO_OFFSET (0x1000 - 0x400) +#define MP_CPU_LEGACY_RESET_INFO_OFFSET (0x100 - 0x20) + +#define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81 + +#pragma pack(1) +#define SIZE_OF_MCE_HANDLER 16 + +typedef struct { + UINT16 LimitLow; + UINT16 BaseLow; + UINT8 BaseMiddle; + UINT16 Attributes; + UINT8 BaseHigh; +} SEGMENT_DESCRIPTOR; + +#pragma pack() + +#define BREAK_TO_RUN_AP_SIGNAL 0x6E755200 +#define MONITOR_FILTER_SIZE 0x40 + +typedef enum { + WakeUpApCounterInit = 0, + WakeUpApPerHltLoop = 1, + WakeUpApPerMwaitLoop = 2, + WakeUpApPerRunLoop = 3, + WakeUpApPerMwaitLoop32= 4, + WakeUpApPerRunLoop32 = 5 +} WAKEUP_AP_MANNER; + +typedef struct { + UINTN BreakToRunApSignal; + UINTN HltLoopBreakCounter; + UINTN MwaitLoopBreakCounter; + UINTN RunLoopBreakCounter; + UINTN MwaitLoopBreakCounter32; + UINTN RunLoopBreakCounter32; + UINTN WakeUpApVectorChangeFlag; + UINTN MwaitTargetCstate; +} MONITOR_MWAIT_DATA; + +typedef struct { + UINT32 Number; + UINT32 BIST; +} BIST_INFO; + +typedef struct { + UINTN Lock; + VOID *StackStart; + UINTN StackSize; + VOID *ApFunction; + PSEUDO_DESCRIPTOR GdtrProfile; + PSEUDO_DESCRIPTOR IdtrProfile; + UINT32 BufferStart; + UINT32 Cr3; + UINT32 InitFlag; + WAKEUP_AP_MANNER WakeUpApManner; + BIST_INFO BistBuffer[MAXIMUM_CPU_NUMBER]; +} MP_CPU_EXCHANGE_INFO; + +extern ACPI_CPU_DATA *mAcpiCpuData; + +// +// Protocol interface functions +// +/** + 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 - Cpu number + @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 - Cpu number + @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] OldBSPState - 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 OldBSPState + ); + +/** + 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 + ); + +/** + This procedure enables or disables APs. + + @param[in] This - Pointer to MP Service Protocol. + @param[in] ProcessorNumber - The handle number of processor. + @param[in] NewAPState - Indicate new desired AP state + @param[in] HealthState - If not NULL, it points to the value that specifies the new health status of the AP. + If it is NULL, this parameter is ignored. + + @retval EFI_INVALID_PARAMETER - Input paramters were not correct. + @retval EFI_SUCCESS - Function completed successfully +**/ +EFI_STATUS +EFIAPI +EnableDisableAP ( + IN EFI_MP_SERVICES_PROTOCOL *This, + IN UINTN ProcessorNumber, + IN BOOLEAN NewAPState, + IN EFI_MP_HEALTH *HealthState OPTIONAL + ); + +/** + Implementation of WhoAmI() service of MP Services Protocol. + + This service lets the caller processor get its handle number. + This service may be called from the BSP and APs. + + @param[in] This - A pointer to the EFI_MP_SERVICES_PROTOCOL instance. + @param[in] ProcessorNumber - Pointer to the handle number of AP. + + @retval EFI_SUCCESS - Processor number successfully returned. + @retval EFI_INVALID_PARAMETER - ProcessorNumber is NULL +**/ +EFI_STATUS +EFIAPI +WhoAmI ( + IN EFI_MP_SERVICES_PROTOCOL *This, + OUT UINTN *ProcessorNumber + ); + +/// +/// Functions shared in MP/HT drivers +/// +/** + Send interrupt to CPU + + @param[in] BroadcastMode - interrupt broadcast mode + @param[in] ApicID - APIC ID for sending interrupt + @param[in] VectorNumber - Vector number + @param[in] DeliveryMode - Interrupt delivery mode + @param[in] TriggerMode - Interrupt trigger mode + @param[in] Assert - Interrupt pin polarity + + @retval EFI_INVALID_PARAMETER - input parameter not correct + @retval EFI_NOT_READY - there was a pending interrupt + @retval EFI_SUCCESS - interrupt sent successfully +**/ +EFI_STATUS +SendInterrupt ( + IN UINT32 BroadcastMode, + IN UINT32 ApicID, + IN UINT32 VectorNumber, + IN UINT32 DeliveryMode, + IN UINT32 TriggerMode, + IN BOOLEAN Assert + ); + +/** + Get APIC ID of processor + + @param[in] ApicBase - APIC base + @param[in] ApicVersionNumber - APIC version + + @retval APIC ID of processor +**/ +UINT32 +GetApicID ( + OUT EFI_PHYSICAL_ADDRESS *ApicBase OPTIONAL, + OUT UINT32 *ApicVersionNumber OPTIONAL + ); + +/** + Programs XAPIC registers. + + @param[in] BSP - Is this BSP +**/ +VOID +ProgramXApic ( + IN BOOLEAN BSP + ); + +/** + Allocate a temporary memory under 1MB for MP Init to perform INIT-SIPI. + This buffer also provides memory for stack/data for MP running. + + @param[in] WakeUpBuffer - Return buffer location + + @retval EFI_SUCCESS if ok to get a memory under 1MB for MP running. +**/ +EFI_STATUS +AllocateWakeUpBuffer ( + OUT EFI_PHYSICAL_ADDRESS *WakeUpBuffer + ); + +/// +/// Assembly functions implemented in MP/HT drivers +/// +/** + Lock APs + + @param[in] Lock - Lock state +**/ +VOID +AsmAcquireMPLock ( + IN UINT8 *Lock + ); + +/** + Release APs + + @param[in] Lock - Lock state +**/ +VOID +AsmReleaseMPLock ( + IN UINT8 *Lock + ); + +/** + Get GDTR and IDTR + + @param[in] Gdt - will be stored GDTR + @param[in] Idt - will be stored IDTR +**/ +VOID +AsmGetGdtrIdtr ( + OUT PSEUDO_DESCRIPTOR **Gdt, + OUT PSEUDO_DESCRIPTOR **Idt + ); + +/** + Prepare GDTR and IDTR for AP + + @param[in] GDTR - The GDTR profile + @param[in] IDTR - The IDTR profile + + @retval EFI_STATUS - status returned by each sub-routine + @retval EFI_SUCCESS - GDTR and IDTR has been prepared for AP +**/ +EFI_STATUS +PrepareGdtIdtForAP ( + OUT PSEUDO_DESCRIPTOR *GDTR, + OUT PSEUDO_DESCRIPTOR *IDTR + ); + +/** + Allocate Reserved Memory + + @param[in] Size - Memory Size + @param[in] Alignment - Alignment size + @param[in] Pointer - return memory location + + @retval EFI_SUCCESS - Allocate a reserved memory successfully +**/ +EFI_STATUS +AllocateAlignedReservedMemory ( + IN UINTN Size, + IN UINTN Alignment, + OUT VOID **Pointer + ); + +/** + Fill in CPU relevant information into data hub + + @param[in] CpuNumber - CPU number + @param[in] CpuDataForDatahub - pointer to data hub that will be updated + + @retval EFI_SUCCESS - always return success +**/ +EFI_STATUS +FillinDataforDataHub ( + IN UINTN CpuNumber, + OUT CPU_DATA_FOR_DATAHUB *CpuDataForDatahub + ); + +/** + This function is invoked when LegacyBios protocol is installed, we must + allocate reserved memory under 1M for AP. + + @param[in] Event - The triggered event. + @param[in] Context - Context for this event. +**/ +VOID +EFIAPI +ReAllocateEbdaMemoryForAP ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + This function is invoked when LegacyBios protocol is installed, we must + allocate reserved memory under 1M for AP. + + @param[in] Event - The triggered event. + @param[in] Context - Context for this event. +**/ +VOID +EFIAPI +ReAllocateMemoryForAP ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + This function is invoked by EFI_EVENT_SIGNAL_LEGACY_BOOT. + Before booting to legacy OS, reset it with memory allocated + by ReAllocateMemoryForAp() and set local APIC correctly. + + @param[in] Event - The triggered event. + @param[in] Context - Context for this event. +**/ +VOID +ResetAPs ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Prepare Wakeup Buffer and stack for APs. + + @param[in] WakeUpBuffer - Pointer to the address of wakeup buffer for output. + @param[in] StackAddressStart - Pointer to the stack address of APs for output. + @param[in] MaximumCPUsForThisSystem - Maximum CPUs in this system. + + @retval EFI_SUCCESS - Memory successfully prepared for APs. + @retval Other - Error occurred while allocating memory. +**/ +EFI_STATUS +PrepareMemoryForAPs ( + OUT EFI_PHYSICAL_ADDRESS *WakeUpBuffer, + OUT VOID **StackAddressStart, + IN UINTN MaximumCPUsForThisSystem + ); + +/** + Prepare exchange information for APs. + + @param[in] ExchangeInfo - Pointer to the exchange info buffer for output. + @param[in] StackAddressStart - Start address of APs' stacks. + @param[in] ApFunction - Address of function assigned to AP. + @param[in] WakeUpBuffer - Pointer to the address of wakeup buffer. + + @retval EFI_SUCCESS - Exchange Info successfully prepared for APs. + @retval Other - Error occurred while allocating memory. +**/ +EFI_STATUS +PrepareExchangeInfo ( + OUT MP_CPU_EXCHANGE_INFO *ExchangeInfo, + IN VOID *StackAddressStart, + IN VOID *ApFunction, + IN EFI_PHYSICAL_ADDRESS WakeUpBuffer + ); + +/** + Prepare Wakeup Buffer and stack for APs during S3. + + @param[in] WakeUpBuffer - Pointer to the address of wakeup buffer for output. + @param[in] StackAddressStart - Pointer to the stack address of APs for output. + + @retval EFI_SUCCESS - Memory successfully prepared for APs. +**/ +EFI_STATUS +S3PrepareMemoryForAPs ( + OUT EFI_PHYSICAL_ADDRESS *WakeUpBuffer, + OUT VOID **StackAddressStart + ); + +/** + Prepare exchange information for APs during S3. + + @param[in] ExchangeInfo - Pointer to the exchange info for output. + @param[in] StackAddressStart - Start address of APs' stacks. + @param[in] ApFunction - Address of function assigned to AP. + @param[in] WakeUpBuffer - Pointer to the address of wakeup buffer. + + @retval EFI_SUCCESS - Exchange Info successfully prepared for APs. +**/ +EFI_STATUS +S3PrepareExchangeInfo ( + OUT MP_CPU_EXCHANGE_INFO *ExchangeInfo, + IN VOID *StackAddressStart, + IN VOID *ApFunction, + IN EFI_PHYSICAL_ADDRESS WakeUpBuffer + ); + +/** + Check whether any AP is running for assigned task. + + @retval TRUE - Some APs are running. + @retval FALSE - No AP is running. +**/ +BOOLEAN +ApRunning ( + VOID + ); + +/** + Wrapper function for all procedures assigned to AP via MP service protocol. + It controls states of AP and invokes assigned precedure. +**/ +VOID +ApProcWrapper ( + VOID + ); + +/** + Allocate EfiReservedMemoryType below 4G memory address. + + @param[in] Size - Size of memory to allocate. + @param[in] Buffer - Allocated address for output. + + @retval EFI_SUCCESS - Memory successfully allocated. + @retval Other - Other errors occur. +**/ +EFI_STATUS +AllocateReservedMemoryBelow4G ( + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Dynamically write the far jump destination in APs' wakeup buffer, + in order to refresh APs' CS registers for mode switching. +**/ +VOID +RedirectFarJump ( + VOID + ); + +#endif |