X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FCpuMpPei%2FCpuMpPei.h;h=fb57669de51667a7afc5f537407ac1151a4026bd;hp=611a296dce6d7e7102e3e80c0fd692d9435ce997;hb=a1a4c7a467d12db1c4652fda504ada4f368c1e26;hpb=f9d30595ae2f17d7a8e281b9ef1eb05047155d23 diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h index 611a296dce..fb57669de5 100644 --- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h +++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h @@ -1,56 +1,320 @@ -/** @file - Definitions to install Multiple Processor PPI. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _CPU_MP_PEI_H_ -#define _CPU_MP_PEI_H_ - -#include - - -#include -#include - -#pragma pack(1) -typedef union { - struct { - UINT32 LimitLow : 16; - UINT32 BaseLow : 16; - UINT32 BaseMid : 8; - UINT32 Type : 4; - UINT32 System : 1; - UINT32 Dpl : 2; - UINT32 Present : 1; - UINT32 LimitHigh : 4; - UINT32 Software : 1; - UINT32 Reserved : 1; - UINT32 DefaultSize : 1; - UINT32 Granularity : 1; - UINT32 BaseHigh : 8; - } Bits; - UINT64 Uint64; -} IA32_GDT; -#pragma pack() -/** - Assembly code to load GDT table and update segment accordingly. - - @param Gdtr Pointer to GDT descriptor -**/ -VOID -EFIAPI -AsmInitializeGdt ( - IN IA32_DESCRIPTOR *Gdtr - ); - - -#endif +/** @file + Definitions to install Multiple Processor PPI. + + Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _CPU_MP_PEI_H_ +#define _CPU_MP_PEI_H_ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Microcode.h" + +// +// AP state +// +typedef enum { + CpuStateIdle, + CpuStateBusy, + CpuStateDisabled +} CPU_STATE; + +#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P') + +typedef enum { + ApInHltLoop = 1, + ApInMwaitLoop = 2, + ApInRunLoop = 3 +} AP_LOOP_MODE; + +// +// AP reset code information +// +typedef struct { + UINT8 *RendezvousFunnelAddress; + UINTN ModeEntryOffset; + UINTN RendezvousFunnelSize; +} MP_ASSEMBLY_ADDRESS_MAP; + +// +// CPU exchange information for switch BSP +// +typedef struct { + UINT8 State; // offset 0 + UINTN StackPointer; // offset 4 / 8 + IA32_DESCRIPTOR Gdtr; // offset 8 / 16 + IA32_DESCRIPTOR Idtr; // offset 14 / 26 +} CPU_EXCHANGE_ROLE_INFO; + +typedef struct _PEI_CPU_MP_DATA PEI_CPU_MP_DATA; + +#pragma pack(1) + +// +// MP CPU exchange information for AP reset code +// This structure is required to be packed because fixed field offsets +// into this structure are used in assembly code in this module +// +typedef struct { + UINTN Lock; + UINTN StackStart; + UINTN StackSize; + UINTN CFunction; + IA32_DESCRIPTOR GdtrProfile; + IA32_DESCRIPTOR IdtrProfile; + UINTN BufferStart; + UINTN ModeOffset; + UINTN NumApsExecuting; + UINTN CodeSegment; + UINTN DataSegment; + UINTN Cr3; + PEI_CPU_MP_DATA *PeiCpuMpData; +} MP_CPU_EXCHANGE_INFO; + +#pragma pack() + +typedef struct { + UINTN Cr0; + UINTN Cr3; + UINTN Cr4; + UINTN Dr0; + UINTN Dr1; + UINTN Dr2; + UINTN Dr3; + UINTN Dr6; + UINTN Dr7; +} CPU_VOLATILE_REGISTERS; + +typedef struct { + volatile UINT32 *StartupApSignal; + UINT32 ApicId; + EFI_HEALTH_FLAGS Health; + CPU_STATE State; + BOOLEAN CpuHealthy; + CPU_VOLATILE_REGISTERS VolatileRegisters; +} PEI_CPU_DATA; + +// +// PEI CPU MP Data save in memory +// +struct _PEI_CPU_MP_DATA { + SPIN_LOCK MpLock; + UINT32 CpuCount; + UINT32 BspNumber; + UINTN Buffer; + UINTN CpuApStackSize; + MP_ASSEMBLY_ADDRESS_MAP AddressMap; + UINTN WakeupBuffer; + UINTN BackupBuffer; + UINTN BackupBufferSize; + UINTN ApFunction; + UINTN ApFunctionArgument; + volatile UINT32 FinishedCount; + BOOLEAN EndOfPeiFlag; + BOOLEAN InitFlag; + BOOLEAN X2ApicEnable; + CPU_EXCHANGE_ROLE_INFO BSPInfo; + CPU_EXCHANGE_ROLE_INFO APInfo; + MTRR_SETTINGS MtrrTable; + UINT8 ApLoopMode; + UINT8 ApTargetCState; + PEI_CPU_DATA *CpuData; + volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo; +}; +extern EFI_PEI_PPI_DESCRIPTOR mPeiCpuMpPpiDesc; + + +/** + Assembly code to get starting address and size of the rendezvous entry for APs. + Information for fixing a jump instruction in the code is also returned. + + @param AddressMap Output buffer for address map information. +**/ +VOID +EFIAPI +AsmGetAddressMap ( + OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap + ); + +/** + Assembly code to load GDT table and update segment accordingly. + + @param Gdtr Pointer to GDT descriptor +**/ +VOID +EFIAPI +AsmInitializeGdt ( + IN IA32_DESCRIPTOR *Gdtr + ); + +/** + Get available system memory below 1MB by specified size. + + @param PeiCpuMpData Pointer to PEI CPU MP Data +**/ +STATIC +VOID +BackupAndPrepareWakeupBuffer( + IN PEI_CPU_MP_DATA *PeiCpuMpData + ); + +/** + Restore wakeup buffer data. + + @param PeiCpuMpData Pointer to PEI CPU MP Data +**/ +STATIC +VOID +RestoreWakeupBuffer( + IN PEI_CPU_MP_DATA *PeiCpuMpData + ); + +/** + Notify function on End Of Pei PPI. + + On S3 boot, this function will restore wakeup buffer data. + On normal boot, this function will flag wakeup buffer to be un-used type. + + @param PeiServices The pointer to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. + @param Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS When everything is OK. + +**/ +STATIC +EFI_STATUS +EFIAPI +CpuMpEndOfPeiCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ); + +/** + This function will be called by BSP to wakeup AP. + + @param PeiCpuMpData Pointer to PEI CPU MP Data + @param Broadcast TRUE: Send broadcast IPI to all APs + FALSE: Send IPI to AP by ApicId + @param ProcessorNumber The handle number of specified processor + @param Procedure The function to be invoked by AP + @param ProcedureArgument The argument to be passed into AP function +**/ +STATIC +VOID +WakeUpAP ( + IN PEI_CPU_MP_DATA *PeiCpuMpData, + IN BOOLEAN Broadcast, + IN UINTN ProcessorNumber, + IN EFI_AP_PROCEDURE Procedure, OPTIONAL + IN VOID *ProcedureArgument OPTIONAL + ); + +/** + Get CPU MP Data pointer from the Guided HOB. + + @return Pointer to Pointer to PEI CPU MP Data +**/ +PEI_CPU_MP_DATA * +GetMpHobData ( + VOID + ); + +/** + Find the current Processor number by APIC ID. + + @param PeiCpuMpData Pointer to PEI CPU MP Data + @param ProcessorNumber Return the pocessor number found + + @retval EFI_SUCCESS ProcessorNumber is found and returned. + @retval EFI_NOT_FOUND ProcessorNumber is not found. +**/ +STATIC +EFI_STATUS +GetProcessorNumber ( + IN PEI_CPU_MP_DATA *PeiCpuMpData, + OUT UINTN *ProcessorNumber + ); + +/** + Collects BIST data from PPI. + + This function collects BIST data from Sec Platform Information2 PPI + or SEC Platform Information PPI. + + @param PeiServices Pointer to PEI Services Table + +**/ +VOID +CollectBistDataFromPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +/** + Implementation of the PlatformInformation2 service in EFI_SEC_PLATFORM_INFORMATION2_PPI. + + @param PeiServices The pointer to the PEI Services Table. + @param StructureSize The pointer to the variable describing size of the input buffer. + @param PlatformInformationRecord2 The pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD2. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. The current buffer size needed to + hold the record is returned in StructureSize. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation2 ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD2 *PlatformInformationRecord2 + ); + +/** + Detect whether specified processor can find matching microcode patch and load it. + + @param PeiCpuMpData Pointer to PEI CPU MP Data +**/ +VOID +MicrocodeDetect ( + IN PEI_CPU_MP_DATA *PeiCpuMpData + ); + +#endif