/** @file\r
Common header file for MP Initialize Library.\r
\r
- Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2020, AMD Inc. All rights reserved.<BR>\r
\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
#include <Library/MtrrLib.h>\r
#include <Library/HobLib.h>\r
#include <Library/PcdLib.h>\r
+#include <Library/MicrocodeLib.h>\r
\r
#include <Guid/MicrocodePatchHob.h>\r
\r
-#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')\r
+#define WAKEUP_AP_SIGNAL SIGNATURE_32 ('S', 'T', 'A', 'P')\r
\r
#define CPU_INIT_MP_LIB_HOB_GUID \\r
{ \\r
//\r
// The MP data for switch BSP\r
//\r
-#define CPU_SWITCH_STATE_IDLE 0\r
-#define CPU_SWITCH_STATE_STORED 1\r
-#define CPU_SWITCH_STATE_LOADED 2\r
+#define CPU_SWITCH_STATE_IDLE 0\r
+#define CPU_SWITCH_STATE_STORED 1\r
+#define CPU_SWITCH_STATE_LOADED 2\r
\r
//\r
// Default maximum number of entries to store the microcode patches information\r
//\r
-#define DEFAULT_MAX_MICROCODE_PATCH_NUM 8\r
+#define DEFAULT_MAX_MICROCODE_PATCH_NUM 8\r
\r
//\r
// Data structure for microcode patch information\r
// CPU exchange information for switch BSP\r
//\r
typedef struct {\r
- UINT8 State; // offset 0\r
- UINTN StackPointer; // offset 4 / 8\r
- IA32_DESCRIPTOR Gdtr; // offset 8 / 16\r
- IA32_DESCRIPTOR Idtr; // offset 14 / 26\r
+ UINT8 State; // offset 0\r
+ UINTN StackPointer; // offset 4 / 8\r
+ IA32_DESCRIPTOR Gdtr; // offset 8 / 16\r
+ IA32_DESCRIPTOR Idtr; // offset 14 / 26\r
} CPU_EXCHANGE_ROLE_INFO;\r
\r
//\r
// CPU volatile registers around INIT-SIPI-SIPI\r
//\r
typedef struct {\r
- UINTN Cr0;\r
- UINTN Cr3;\r
- UINTN Cr4;\r
- UINTN Dr0;\r
- UINTN Dr1;\r
- UINTN Dr2;\r
- UINTN Dr3;\r
- UINTN Dr6;\r
- UINTN Dr7;\r
- IA32_DESCRIPTOR Gdtr;\r
- IA32_DESCRIPTOR Idtr;\r
- UINT16 Tr;\r
+ UINTN Cr0;\r
+ UINTN Cr3;\r
+ UINTN Cr4;\r
+ UINTN Dr0;\r
+ UINTN Dr1;\r
+ UINTN Dr2;\r
+ UINTN Dr3;\r
+ UINTN Dr6;\r
+ UINTN Dr7;\r
+ IA32_DESCRIPTOR Gdtr;\r
+ IA32_DESCRIPTOR Idtr;\r
+ UINT16 Tr;\r
} CPU_VOLATILE_REGISTERS;\r
\r
//\r
// AP related data\r
//\r
typedef struct {\r
- SPIN_LOCK ApLock;\r
- volatile UINT32 *StartupApSignal;\r
- volatile UINTN ApFunction;\r
- volatile UINTN ApFunctionArgument;\r
- BOOLEAN CpuHealthy;\r
- volatile CPU_STATE State;\r
- CPU_VOLATILE_REGISTERS VolatileRegisters;\r
- BOOLEAN Waiting;\r
- BOOLEAN *Finished;\r
- UINT64 ExpectedTime;\r
- UINT64 CurrentTime;\r
- UINT64 TotalTime;\r
- EFI_EVENT WaitEvent;\r
- UINT32 ProcessorSignature;\r
- UINT8 PlatformId;\r
- UINT64 MicrocodeEntryAddr;\r
+ SPIN_LOCK ApLock;\r
+ volatile UINT32 *StartupApSignal;\r
+ volatile UINTN ApFunction;\r
+ volatile UINTN ApFunctionArgument;\r
+ BOOLEAN CpuHealthy;\r
+ volatile CPU_STATE State;\r
+ CPU_VOLATILE_REGISTERS VolatileRegisters;\r
+ BOOLEAN Waiting;\r
+ BOOLEAN *Finished;\r
+ UINT64 ExpectedTime;\r
+ UINT64 CurrentTime;\r
+ UINT64 TotalTime;\r
+ EFI_EVENT WaitEvent;\r
+ UINT32 ProcessorSignature;\r
+ UINT8 PlatformId;\r
+ UINT64 MicrocodeEntryAddr;\r
+ UINT32 MicrocodeRevision;\r
} CPU_AP_DATA;\r
\r
//\r
//\r
#pragma pack (1)\r
typedef struct {\r
- UINT32 InitialApicId;\r
- UINT32 ApicId;\r
- UINT32 Health;\r
- UINT64 ApTopOfStack;\r
+ UINT32 InitialApicId;\r
+ UINT32 ApicId;\r
+ UINT32 Health;\r
+ UINT64 ApTopOfStack;\r
} CPU_INFO_IN_HOB;\r
#pragma pack ()\r
\r
// It is natural aligned by design.\r
//\r
typedef struct {\r
- UINT8 *RendezvousFunnelAddress;\r
- UINTN ModeEntryOffset;\r
- UINTN RendezvousFunnelSize;\r
- UINT8 *RelocateApLoopFuncAddress;\r
- UINTN RelocateApLoopFuncSize;\r
- UINTN ModeTransitionOffset;\r
- UINTN SwitchToRealSize;\r
- UINTN SwitchToRealOffset;\r
- UINTN SwitchToRealNoNxOffset;\r
- UINTN SwitchToRealPM16ModeOffset;\r
- UINTN SwitchToRealPM16ModeSize;\r
+ UINT8 *RendezvousFunnelAddress;\r
+ UINTN ModeEntryOffset;\r
+ UINTN RendezvousFunnelSize;\r
+ UINT8 *RelocateApLoopFuncAddress;\r
+ UINTN RelocateApLoopFuncSize;\r
+ UINTN ModeTransitionOffset;\r
+ UINTN SwitchToRealSize;\r
+ UINTN SwitchToRealOffset;\r
+ UINTN SwitchToRealNoNxOffset;\r
+ UINTN SwitchToRealPM16ModeOffset;\r
+ UINTN SwitchToRealPM16ModeSize;\r
} MP_ASSEMBLY_ADDRESS_MAP;\r
\r
-typedef struct _CPU_MP_DATA CPU_MP_DATA;\r
+typedef struct _CPU_MP_DATA CPU_MP_DATA;\r
\r
#pragma pack(1)\r
\r
// into this structure are used in assembly code in this module\r
//\r
typedef struct {\r
- UINTN Lock;\r
- UINTN StackStart;\r
- UINTN StackSize;\r
- UINTN CFunction;\r
- IA32_DESCRIPTOR GdtrProfile;\r
- IA32_DESCRIPTOR IdtrProfile;\r
- UINTN BufferStart;\r
- UINTN ModeOffset;\r
- UINTN ApIndex;\r
- UINTN CodeSegment;\r
- UINTN DataSegment;\r
- UINTN EnableExecuteDisable;\r
- UINTN Cr3;\r
- UINTN InitFlag;\r
- CPU_INFO_IN_HOB *CpuInfo;\r
- UINTN NumApsExecuting;\r
- CPU_MP_DATA *CpuMpData;\r
- UINTN InitializeFloatingPointUnitsAddress;\r
- UINT32 ModeTransitionMemory;\r
- UINT16 ModeTransitionSegment;\r
- UINT32 ModeHighMemory;\r
- UINT16 ModeHighSegment;\r
+ UINTN StackStart;\r
+ UINTN StackSize;\r
+ UINTN CFunction;\r
+ IA32_DESCRIPTOR GdtrProfile;\r
+ IA32_DESCRIPTOR IdtrProfile;\r
+ UINTN BufferStart;\r
+ UINTN ModeOffset;\r
+ UINTN ApIndex;\r
+ UINTN CodeSegment;\r
+ UINTN DataSegment;\r
+ UINTN EnableExecuteDisable;\r
+ UINTN Cr3;\r
+ UINTN InitFlag;\r
+ CPU_INFO_IN_HOB *CpuInfo;\r
+ UINTN NumApsExecuting;\r
+ CPU_MP_DATA *CpuMpData;\r
+ UINTN InitializeFloatingPointUnitsAddress;\r
+ UINT32 ModeTransitionMemory;\r
+ UINT16 ModeTransitionSegment;\r
+ UINT32 ModeHighMemory;\r
+ UINT16 ModeHighSegment;\r
//\r
// Enable5LevelPaging indicates whether 5-level paging is enabled in long mode.\r
//\r
- BOOLEAN Enable5LevelPaging;\r
- BOOLEAN SevEsIsEnabled;\r
- UINTN GhcbBase;\r
+ BOOLEAN Enable5LevelPaging;\r
+ BOOLEAN SevEsIsEnabled;\r
+ UINTN GhcbBase;\r
} MP_CPU_EXCHANGE_INFO;\r
\r
#pragma pack()\r
// CPU MP Data save in memory\r
//\r
struct _CPU_MP_DATA {\r
- UINT64 CpuInfoInHob;\r
- UINT32 CpuCount;\r
- UINT32 BspNumber;\r
+ UINT64 CpuInfoInHob;\r
+ UINT32 CpuCount;\r
+ UINT32 BspNumber;\r
//\r
// The above fields data will be passed from PEI to DXE\r
// Please make sure the fields offset same in the different\r
// architecture.\r
//\r
- SPIN_LOCK MpLock;\r
- UINTN Buffer;\r
- UINTN CpuApStackSize;\r
- MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
- UINTN WakeupBuffer;\r
- UINTN WakeupBufferHigh;\r
- UINTN BackupBuffer;\r
- UINTN BackupBufferSize;\r
-\r
- volatile UINT32 FinishedCount;\r
- UINT32 RunningCount;\r
- BOOLEAN SingleThread;\r
- EFI_AP_PROCEDURE Procedure;\r
- VOID *ProcArguments;\r
- BOOLEAN *Finished;\r
- UINT64 ExpectedTime;\r
- UINT64 CurrentTime;\r
- UINT64 TotalTime;\r
- EFI_EVENT WaitEvent;\r
- UINTN **FailedCpuList;\r
-\r
- AP_INIT_STATE InitFlag;\r
- BOOLEAN SwitchBspFlag;\r
- UINTN NewBspNumber;\r
- CPU_EXCHANGE_ROLE_INFO BSPInfo;\r
- CPU_EXCHANGE_ROLE_INFO APInfo;\r
- MTRR_SETTINGS MtrrTable;\r
- UINT8 ApLoopMode;\r
- UINT8 ApTargetCState;\r
- UINT16 PmCodeSegment;\r
- UINT16 Pm16CodeSegment;\r
- CPU_AP_DATA *CpuData;\r
- volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;\r
-\r
- UINT32 CurrentTimerCount;\r
- UINTN DivideValue;\r
- UINT8 Vector;\r
- BOOLEAN PeriodicMode;\r
- BOOLEAN TimerInterruptState;\r
- UINT64 MicrocodePatchAddress;\r
- UINT64 MicrocodePatchRegionSize;\r
+ SPIN_LOCK MpLock;\r
+ UINTN Buffer;\r
+ UINTN CpuApStackSize;\r
+ MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
+ UINTN WakeupBuffer;\r
+ UINTN WakeupBufferHigh;\r
+ UINTN BackupBuffer;\r
+ UINTN BackupBufferSize;\r
+\r
+ volatile UINT32 FinishedCount;\r
+ UINT32 RunningCount;\r
+ BOOLEAN SingleThread;\r
+ EFI_AP_PROCEDURE Procedure;\r
+ VOID *ProcArguments;\r
+ BOOLEAN *Finished;\r
+ UINT64 ExpectedTime;\r
+ UINT64 CurrentTime;\r
+ UINT64 TotalTime;\r
+ EFI_EVENT WaitEvent;\r
+ UINTN **FailedCpuList;\r
+\r
+ AP_INIT_STATE InitFlag;\r
+ BOOLEAN SwitchBspFlag;\r
+ UINTN NewBspNumber;\r
+ CPU_EXCHANGE_ROLE_INFO BSPInfo;\r
+ CPU_EXCHANGE_ROLE_INFO APInfo;\r
+ MTRR_SETTINGS MtrrTable;\r
+ UINT8 ApLoopMode;\r
+ UINT8 ApTargetCState;\r
+ UINT16 PmCodeSegment;\r
+ UINT16 Pm16CodeSegment;\r
+ CPU_AP_DATA *CpuData;\r
+ volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;\r
+\r
+ UINT32 CurrentTimerCount;\r
+ UINTN DivideValue;\r
+ UINT8 Vector;\r
+ BOOLEAN PeriodicMode;\r
+ BOOLEAN TimerInterruptState;\r
+ UINT64 MicrocodePatchAddress;\r
+ UINT64 MicrocodePatchRegionSize;\r
\r
//\r
// Whether need to use Init-Sipi-Sipi to wake up the APs.\r
// will be hardcode change to HLT mode by PiSmmCpuDxeSmm\r
// driver.\r
//\r
- BOOLEAN WakeUpByInitSipiSipi;\r
+ BOOLEAN WakeUpByInitSipiSipi;\r
\r
- BOOLEAN SevEsIsEnabled;\r
- UINTN SevEsAPBuffer;\r
- UINTN SevEsAPResetStackStart;\r
- CPU_MP_DATA *NewCpuMpData;\r
+ BOOLEAN SevEsIsEnabled;\r
+ UINTN SevEsAPBuffer;\r
+ UINTN SevEsAPResetStackStart;\r
+ CPU_MP_DATA *NewCpuMpData;\r
\r
- UINT64 GhcbBase;\r
+ UINT64 GhcbBase;\r
};\r
\r
-#define AP_RESET_STACK_SIZE 64\r
+#define AP_SAFE_STACK_SIZE 128\r
+#define AP_RESET_STACK_SIZE AP_SAFE_STACK_SIZE\r
\r
#pragma pack(1)\r
\r
typedef struct {\r
- UINT8 InsnBuffer[8];\r
- UINT16 Rip;\r
- UINT16 Segment;\r
+ UINT8 InsnBuffer[8];\r
+ UINT16 Rip;\r
+ UINT16 Segment;\r
} SEV_ES_AP_JMP_FAR;\r
\r
#pragma pack()\r
**/\r
typedef\r
VOID\r
-(EFIAPI AP_RESET) (\r
+(EFIAPI AP_RESET)(\r
IN UINTN BufferStart,\r
IN UINT16 Code16,\r
IN UINT16 Code32,\r
IN UINTN StackStart\r
);\r
\r
-extern EFI_GUID mCpuInitMpLibHobGuid;\r
+extern EFI_GUID mCpuInitMpLibHobGuid;\r
\r
/**\r
Assembly code to place AP into safe loop mode.\r
**/\r
typedef\r
VOID\r
-(EFIAPI * ASM_RELOCATE_AP_LOOP) (\r
+(EFIAPI *ASM_RELOCATE_AP_LOOP)(\r
IN BOOLEAN MwaitSupport,\r
IN UINTN ApTargetCState,\r
IN UINTN PmCodeSegment,\r
IN UINTN TopOfApStack,\r
- IN UINTN NumberToFinish\r
+ IN UINTN NumberToFinish,\r
+ IN UINTN Pm16CodeSegment,\r
+ IN UINTN SevEsAPJumpTable,\r
+ IN UINTN WakeupBuffer\r
);\r
\r
/**\r
VOID\r
EFIAPI\r
AsmGetAddressMap (\r
- OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap\r
+ OUT MP_ASSEMBLY_ADDRESS_MAP *AddressMap\r
);\r
\r
/**\r
VOID\r
EFIAPI\r
AsmExchangeRole (\r
- IN CPU_EXCHANGE_ROLE_INFO *MyInfo,\r
- IN CPU_EXCHANGE_ROLE_INFO *OthersInfo\r
+ IN CPU_EXCHANGE_ROLE_INFO *MyInfo,\r
+ IN CPU_EXCHANGE_ROLE_INFO *OthersInfo\r
);\r
\r
/**\r
**/\r
VOID\r
SaveCpuMpData (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData\r
);\r
\r
-\r
/**\r
Get available system memory below 1MB by specified size.\r
\r
**/\r
UINTN\r
GetWakeupBuffer (\r
- IN UINTN WakeupBufferSize\r
+ IN UINTN WakeupBufferSize\r
);\r
\r
/**\r
**/\r
UINTN\r
GetModeTransitionBuffer (\r
- IN UINTN BufferSize\r
+ IN UINTN BufferSize\r
);\r
\r
/**\r
**/\r
VOID\r
WakeUpAP (\r
- IN CPU_MP_DATA *CpuMpData,\r
- IN BOOLEAN Broadcast,\r
- IN UINTN ProcessorNumber,\r
- IN EFI_AP_PROCEDURE Procedure, OPTIONAL\r
- IN VOID *ProcedureArgument, OPTIONAL\r
- IN BOOLEAN WakeUpDisabledAps OPTIONAL\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ IN BOOLEAN Broadcast,\r
+ IN UINTN ProcessorNumber,\r
+ IN EFI_AP_PROCEDURE Procedure OPTIONAL,\r
+ IN VOID *ProcedureArgument OPTIONAL,\r
+ IN BOOLEAN WakeUpDisabledAps OPTIONAL\r
);\r
\r
/**\r
**/\r
VOID\r
InitMpGlobalData (\r
- IN CPU_MP_DATA *CpuMpData\r
+ IN CPU_MP_DATA *CpuMpData\r
);\r
\r
/**\r
**/\r
EFI_STATUS\r
StartupAllCPUsWorker (\r
- IN EFI_AP_PROCEDURE Procedure,\r
- IN BOOLEAN SingleThread,\r
- IN BOOLEAN ExcludeBsp,\r
- IN EFI_EVENT WaitEvent OPTIONAL,\r
- IN UINTN TimeoutInMicroseconds,\r
- IN VOID *ProcedureArgument OPTIONAL,\r
- OUT UINTN **FailedCpuList OPTIONAL\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN BOOLEAN SingleThread,\r
+ IN BOOLEAN ExcludeBsp,\r
+ IN EFI_EVENT WaitEvent OPTIONAL,\r
+ IN UINTN TimeoutInMicroseconds,\r
+ IN VOID *ProcedureArgument OPTIONAL,\r
+ OUT UINTN **FailedCpuList OPTIONAL\r
);\r
\r
/**\r
**/\r
EFI_STATUS\r
StartupThisAPWorker (\r
- IN EFI_AP_PROCEDURE Procedure,\r
- IN UINTN ProcessorNumber,\r
- IN EFI_EVENT WaitEvent OPTIONAL,\r
- IN UINTN TimeoutInMicroseconds,\r
- IN VOID *ProcedureArgument OPTIONAL,\r
- OUT BOOLEAN *Finished OPTIONAL\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN UINTN ProcessorNumber,\r
+ IN EFI_EVENT WaitEvent OPTIONAL,\r
+ IN UINTN TimeoutInMicroseconds,\r
+ IN VOID *ProcedureArgument OPTIONAL,\r
+ OUT BOOLEAN *Finished OPTIONAL\r
);\r
\r
/**\r
**/\r
EFI_STATUS\r
SwitchBSPWorker (\r
- IN UINTN ProcessorNumber,\r
- IN BOOLEAN EnableOldBSP\r
+ IN UINTN ProcessorNumber,\r
+ IN BOOLEAN EnableOldBSP\r
);\r
\r
/**\r
**/\r
EFI_STATUS\r
EnableDisableApWorker (\r
- IN UINTN ProcessorNumber,\r
- IN BOOLEAN EnableAP,\r
- IN UINT32 *HealthFlag OPTIONAL\r
+ IN UINTN ProcessorNumber,\r
+ IN BOOLEAN EnableAP,\r
+ IN UINT32 *HealthFlag OPTIONAL\r
);\r
\r
/**\r
**/\r
EFI_STATUS\r
CheckThisAP (\r
- IN UINTN ProcessorNumber\r
+ IN UINTN ProcessorNumber\r
);\r
\r
/**\r
**/\r
VOID\r
MicrocodeDetect (\r
- IN CPU_MP_DATA *CpuMpData,\r
- IN UINTN ProcessorNumber\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ IN UINTN ProcessorNumber\r
);\r
\r
/**\r
**/\r
VOID\r
ShadowMicrocodeUpdatePatch (\r
- IN OUT CPU_MP_DATA *CpuMpData\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
);\r
\r
/**\r
**/\r
BOOLEAN\r
GetMicrocodePatchInfoFromHob (\r
- UINT64 *Address,\r
- UINT64 *RegionSize\r
+ UINT64 *Address,\r
+ UINT64 *RegionSize\r
);\r
\r
/**\r
**/\r
EFI_STATUS\r
GetProcessorNumber (\r
- IN CPU_MP_DATA *CpuMpData,\r
- OUT UINTN *ProcessorNumber\r
+ IN CPU_MP_DATA *CpuMpData,\r
+ OUT UINTN *ProcessorNumber\r
);\r
\r
/**\r
**/\r
EFI_STATUS\r
PlatformShadowMicrocode (\r
- IN OUT CPU_MP_DATA *CpuMpData\r
+ IN OUT CPU_MP_DATA *CpuMpData\r
);\r
\r
#endif\r
-\r