UefiCpuPkg/MpInitLib: Allocate and initialize memory of MP Data buffer
v5: 1. Add comment block for enum AP_INIT_STATE and structure CPU_AP_DATA. 2. Add more comment for structure CPU_INFO_IN_HOB. 3. Add more clarification in structure _CPU_MP_DATA for those fields pass from PEI to DXE. Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Feng Tian <feng.tian@intel.com> Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Michael Kinney <michael.d.kinney@intel.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Michael Kinney <michael.d.kinney@intel.com>
This commit is contained in:
parent
9ebcf0f400
commit
e59f8f6b36
@ -93,15 +93,64 @@ MpInitLibInitialize (
|
|||||||
VOID
|
VOID
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
UINT32 MaxLogicalProcessorNumber;
|
||||||
|
UINT32 ApStackSize;
|
||||||
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
|
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
|
||||||
|
UINTN BufferSize;
|
||||||
UINT32 MonitorFilterSize;
|
UINT32 MonitorFilterSize;
|
||||||
|
VOID *MpBuffer;
|
||||||
|
UINTN Buffer;
|
||||||
|
CPU_MP_DATA *CpuMpData;
|
||||||
UINT8 ApLoopMode;
|
UINT8 ApLoopMode;
|
||||||
|
UINT8 *MonitorBuffer;
|
||||||
UINTN ApResetVectorSize;
|
UINTN ApResetVectorSize;
|
||||||
|
UINTN BackupBufferAddr;
|
||||||
|
MaxLogicalProcessorNumber = PcdGet32(PcdCpuMaxLogicalProcessorNumber);
|
||||||
|
|
||||||
AsmGetAddressMap (&AddressMap);
|
AsmGetAddressMap (&AddressMap);
|
||||||
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
|
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
|
||||||
|
ApStackSize = PcdGet32(PcdCpuApStackSize);
|
||||||
ApLoopMode = GetApLoopMode (&MonitorFilterSize);
|
ApLoopMode = GetApLoopMode (&MonitorFilterSize);
|
||||||
|
|
||||||
|
BufferSize = ApStackSize * MaxLogicalProcessorNumber;
|
||||||
|
BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber;
|
||||||
|
BufferSize += sizeof (CPU_MP_DATA);
|
||||||
|
BufferSize += ApResetVectorSize;
|
||||||
|
BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* MaxLogicalProcessorNumber;
|
||||||
|
MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));
|
||||||
|
ASSERT (MpBuffer != NULL);
|
||||||
|
ZeroMem (MpBuffer, BufferSize);
|
||||||
|
Buffer = (UINTN) MpBuffer;
|
||||||
|
|
||||||
|
MonitorBuffer = (UINT8 *) (Buffer + ApStackSize * MaxLogicalProcessorNumber);
|
||||||
|
BackupBufferAddr = (UINTN) MonitorBuffer + MonitorFilterSize * MaxLogicalProcessorNumber;
|
||||||
|
CpuMpData = (CPU_MP_DATA *) (BackupBufferAddr + ApResetVectorSize);
|
||||||
|
CpuMpData->Buffer = Buffer;
|
||||||
|
CpuMpData->CpuApStackSize = ApStackSize;
|
||||||
|
CpuMpData->BackupBuffer = BackupBufferAddr;
|
||||||
|
CpuMpData->BackupBufferSize = ApResetVectorSize;
|
||||||
|
CpuMpData->EndOfPeiFlag = FALSE;
|
||||||
|
CpuMpData->WakeupBuffer = (UINTN) -1;
|
||||||
|
CpuMpData->CpuCount = 1;
|
||||||
|
CpuMpData->BspNumber = 0;
|
||||||
|
CpuMpData->WaitEvent = NULL;
|
||||||
|
CpuMpData->CpuData = (CPU_AP_DATA *) (CpuMpData + 1);
|
||||||
|
CpuMpData->CpuInfoInHob = (UINT64) (UINTN) (CpuMpData->CpuData + MaxLogicalProcessorNumber);
|
||||||
|
InitializeSpinLock(&CpuMpData->MpLock);
|
||||||
|
//
|
||||||
|
// Save assembly code information
|
||||||
|
//
|
||||||
|
CopyMem (&CpuMpData->AddressMap, &AddressMap, sizeof (MP_ASSEMBLY_ADDRESS_MAP));
|
||||||
|
//
|
||||||
|
// Finally set AP loop mode
|
||||||
|
//
|
||||||
|
CpuMpData->ApLoopMode = ApLoopMode;
|
||||||
|
DEBUG ((DEBUG_INFO, "AP Loop Mode is %d\n", CpuMpData->ApLoopMode));
|
||||||
|
//
|
||||||
|
// Store BSP's MTRR setting
|
||||||
|
//
|
||||||
|
MtrrGetAllMtrrs (&CpuMpData->MtrrTable);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,47 @@ typedef enum {
|
|||||||
ApInRunLoop = 3
|
ApInRunLoop = 3
|
||||||
} AP_LOOP_MODE;
|
} AP_LOOP_MODE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// AP initialization state during APs wakeup
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
ApInitConfig = 1,
|
||||||
|
ApInitReconfig = 2,
|
||||||
|
ApInitDone = 3
|
||||||
|
} AP_INIT_STATE;
|
||||||
|
|
||||||
|
//
|
||||||
|
// AP related data
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
SPIN_LOCK ApLock;
|
||||||
|
volatile UINT32 *StartupApSignal;
|
||||||
|
volatile UINTN ApFunction;
|
||||||
|
volatile UINTN ApFunctionArgument;
|
||||||
|
UINT32 InitialApicId;
|
||||||
|
UINT32 ApicId;
|
||||||
|
UINT32 Health;
|
||||||
|
BOOLEAN CpuHealthy;
|
||||||
|
BOOLEAN Waiting;
|
||||||
|
BOOLEAN *Finished;
|
||||||
|
UINT64 ExpectedTime;
|
||||||
|
UINT64 CurrentTime;
|
||||||
|
UINT64 TotalTime;
|
||||||
|
EFI_EVENT WaitEvent;
|
||||||
|
} CPU_AP_DATA;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Basic CPU information saved in Guided HOB.
|
||||||
|
// Because the contents will be shard between PEI and DXE,
|
||||||
|
// we need to make sure the each fields offset same in different
|
||||||
|
// architecture.
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
UINT32 InitialApicId;
|
||||||
|
UINT32 ApicId;
|
||||||
|
UINT32 Health;
|
||||||
|
} CPU_INFO_IN_HOB;
|
||||||
|
|
||||||
//
|
//
|
||||||
// AP reset code information including code address and size,
|
// AP reset code information including code address and size,
|
||||||
// this structure will be shared be C code and assembly code.
|
// this structure will be shared be C code and assembly code.
|
||||||
@ -58,6 +99,8 @@ typedef struct {
|
|||||||
UINTN RelocateApLoopFuncSize;
|
UINTN RelocateApLoopFuncSize;
|
||||||
} MP_ASSEMBLY_ADDRESS_MAP;
|
} MP_ASSEMBLY_ADDRESS_MAP;
|
||||||
|
|
||||||
|
typedef struct _CPU_MP_DATA CPU_MP_DATA;
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -79,9 +122,54 @@ typedef struct {
|
|||||||
UINTN DataSegment;
|
UINTN DataSegment;
|
||||||
UINTN EnableExecuteDisable;
|
UINTN EnableExecuteDisable;
|
||||||
UINTN Cr3;
|
UINTN Cr3;
|
||||||
|
CPU_MP_DATA *CpuMpData;
|
||||||
} MP_CPU_EXCHANGE_INFO;
|
} MP_CPU_EXCHANGE_INFO;
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
//
|
||||||
|
// CPU MP Data save in memory
|
||||||
|
//
|
||||||
|
struct _CPU_MP_DATA {
|
||||||
|
UINT64 CpuInfoInHob;
|
||||||
|
UINT32 CpuCount;
|
||||||
|
UINT32 BspNumber;
|
||||||
|
//
|
||||||
|
// The above fields data will be passed from PEI to DXE
|
||||||
|
// Please make sure the fields offset same in the different
|
||||||
|
// architecture.
|
||||||
|
//
|
||||||
|
SPIN_LOCK MpLock;
|
||||||
|
UINTN Buffer;
|
||||||
|
UINTN CpuApStackSize;
|
||||||
|
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
|
||||||
|
UINTN WakeupBuffer;
|
||||||
|
UINTN BackupBuffer;
|
||||||
|
UINTN BackupBufferSize;
|
||||||
|
BOOLEAN EndOfPeiFlag;
|
||||||
|
|
||||||
|
volatile UINT32 StartCount;
|
||||||
|
volatile UINT32 FinishedCount;
|
||||||
|
volatile UINT32 RunningCount;
|
||||||
|
BOOLEAN SingleThread;
|
||||||
|
EFI_AP_PROCEDURE Procedure;
|
||||||
|
VOID *ProcArguments;
|
||||||
|
BOOLEAN *Finished;
|
||||||
|
UINT64 ExpectedTime;
|
||||||
|
UINT64 CurrentTime;
|
||||||
|
UINT64 TotalTime;
|
||||||
|
EFI_EVENT WaitEvent;
|
||||||
|
UINTN **FailedCpuList;
|
||||||
|
|
||||||
|
AP_INIT_STATE InitFlag;
|
||||||
|
BOOLEAN X2ApicEnable;
|
||||||
|
MTRR_SETTINGS MtrrTable;
|
||||||
|
UINT8 ApLoopMode;
|
||||||
|
UINT8 ApTargetCState;
|
||||||
|
UINT16 PmCodeSegment;
|
||||||
|
CPU_AP_DATA *CpuData;
|
||||||
|
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
Assembly code to place AP into safe loop mode.
|
Assembly code to place AP into safe loop mode.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user