//\r
ApInitializeSync (CpuMpData);\r
//\r
- // Sync BSP's Control registers to APs\r
+ // CpuMpData->CpuData[0].VolatileRegisters is initialized based on BSP environment,\r
+ // to initialize AP in InitConfig path.\r
+ // NOTE: IDTR.BASE stored in CpuMpData->CpuData[0].VolatileRegisters points to a different IDT shared by all APs.\r
//\r
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);\r
InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack);\r
UINT32 MaxLogicalProcessorNumber;\r
UINT32 ApStackSize;\r
MP_ASSEMBLY_ADDRESS_MAP AddressMap;\r
+ CPU_VOLATILE_REGISTERS VolatileRegisters;\r
UINTN BufferSize;\r
UINT32 MonitorFilterSize;\r
VOID *MpBuffer;\r
UINTN Index;\r
UINTN ApResetVectorSize;\r
UINTN BackupBufferAddr;\r
+ UINTN ApIdtBase;\r
\r
OldCpuMpData = GetCpuMpDataFromGuidedHob ();\r
if (OldCpuMpData == NULL) {\r
ApStackSize = PcdGet32(PcdCpuApStackSize);\r
ApLoopMode = GetApLoopMode (&MonitorFilterSize);\r
\r
+ //\r
+ // Save BSP's Control registers for APs\r
+ //\r
+ SaveVolatileRegisters (&VolatileRegisters);\r
+\r
BufferSize = ApStackSize * MaxLogicalProcessorNumber;\r
BufferSize += MonitorFilterSize * MaxLogicalProcessorNumber;\r
- BufferSize += sizeof (CPU_MP_DATA);\r
BufferSize += ApResetVectorSize;\r
+ BufferSize = ALIGN_VALUE (BufferSize, 8);\r
+ BufferSize += VolatileRegisters.Idtr.Limit + 1;\r
+ BufferSize += sizeof (CPU_MP_DATA);\r
BufferSize += (sizeof (CPU_AP_DATA) + sizeof (CPU_INFO_IN_HOB))* MaxLogicalProcessorNumber;\r
MpBuffer = AllocatePages (EFI_SIZE_TO_PAGES (BufferSize));\r
ASSERT (MpBuffer != NULL);\r
ZeroMem (MpBuffer, BufferSize);\r
Buffer = (UINTN) MpBuffer;\r
\r
+ //\r
+ // The layout of the Buffer is as below:\r
+ //\r
+ // +--------------------+ <-- Buffer\r
+ // AP Stacks (N)\r
+ // +--------------------+ <-- MonitorBuffer\r
+ // AP Monitor Filters (N)\r
+ // +--------------------+ <-- BackupBufferAddr (CpuMpData->BackupBuffer)\r
+ // Backup Buffer\r
+ // +--------------------+\r
+ // Padding\r
+ // +--------------------+ <-- ApIdtBase (8-byte boundary)\r
+ // AP IDT All APs share one separate IDT. So AP can get address of CPU_MP_DATA from IDT Base.\r
+ // +--------------------+ <-- CpuMpData\r
+ // CPU_MP_DATA\r
+ // +--------------------+ <-- CpuMpData->CpuData\r
+ // CPU_AP_DATA (N)\r
+ // +--------------------+ <-- CpuMpData->CpuInfoInHob\r
+ // CPU_INFO_IN_HOB (N)\r
+ // +--------------------+\r
+ //\r
MonitorBuffer = (UINT8 *) (Buffer + ApStackSize * MaxLogicalProcessorNumber);\r
BackupBufferAddr = (UINTN) MonitorBuffer + MonitorFilterSize * MaxLogicalProcessorNumber;\r
- CpuMpData = (CPU_MP_DATA *) (BackupBufferAddr + ApResetVectorSize);\r
+ ApIdtBase = ALIGN_VALUE (BackupBufferAddr + ApResetVectorSize, 8);\r
+ CpuMpData = (CPU_MP_DATA *) (ApIdtBase + VolatileRegisters.Idtr.Limit + 1);\r
CpuMpData->Buffer = Buffer;\r
CpuMpData->CpuApStackSize = ApStackSize;\r
CpuMpData->BackupBuffer = BackupBufferAddr;\r
CpuMpData->MicrocodePatchAddress = PcdGet64 (PcdCpuMicrocodePatchAddress);\r
CpuMpData->MicrocodePatchRegionSize = PcdGet64 (PcdCpuMicrocodePatchRegionSize);\r
InitializeSpinLock(&CpuMpData->MpLock);\r
+\r
+ //\r
+ // Make sure no memory usage outside of the allocated buffer.\r
//\r
- // Save BSP's Control registers to APs\r
+ ASSERT ((CpuMpData->CpuInfoInHob + sizeof (CPU_INFO_IN_HOB) * MaxLogicalProcessorNumber) ==\r
+ Buffer + BufferSize);\r
+\r
+ //\r
+ // Duplicate BSP's IDT to APs.\r
+ // All APs share one separate IDT. So AP can get the address of CpuMpData by using IDTR.BASE + IDTR.LIMIT + 1\r
//\r
- SaveVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters);\r
+ CopyMem ((VOID *)ApIdtBase, (VOID *)VolatileRegisters.Idtr.Base, VolatileRegisters.Idtr.Limit + 1);\r
+ VolatileRegisters.Idtr.Base = ApIdtBase;\r
+ CopyMem (&CpuMpData->CpuData[0].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters));\r
//\r
// Set BSP basic information\r
//\r
}\r
CpuMpData->CpuData[Index].CpuHealthy = (CpuInfoInHob[Index].Health == 0)? TRUE:FALSE;\r
CpuMpData->CpuData[Index].ApFunction = 0;\r
- CopyMem (\r
- &CpuMpData->CpuData[Index].VolatileRegisters,\r
- &CpuMpData->CpuData[0].VolatileRegisters,\r
- sizeof (CPU_VOLATILE_REGISTERS)\r
- );\r
+ CopyMem (&CpuMpData->CpuData[Index].VolatileRegisters, &VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));\r
}\r
if (MaxLogicalProcessorNumber > 1) {\r
//\r