diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index e708b3fef4..4e28ff3fe4 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -758,6 +758,12 @@ ApWakeupFunction ( CurrentApicMode = GetApicMode (); while (TRUE) { if (CpuMpData->InitFlag == ApInitConfig) { + // + // Synchronize APIC mode with BSP in the first time AP wakeup ONLY. + // + SetApicMode (CpuMpData->InitialBspApicMode); + CurrentApicMode = CpuMpData->InitialBspApicMode; + ProcessorNumber = ApIndex; // // This is first time AP wakeup, get BIST information from AP stack @@ -2221,6 +2227,11 @@ MpInitLibInitialize ( ); DEBUG ((DEBUG_INFO, "AP Vector: non-16-bit = %p/%x\n", CpuMpData->WakeupBufferHigh, ApResetVectorSizeAbove1Mb)); + // + // Save APIC mode for AP to sync + // + CpuMpData->InitialBspApicMode = GetApicMode (); + // // Enable the local APIC for Virtual Wire Mode. // diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.h b/UefiCpuPkg/Library/MpInitLib/MpLib.h index e92991d5dc..690b7b0e1b 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.h +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.h @@ -250,11 +250,23 @@ typedef struct { // in assembly code. // struct _CPU_MP_DATA { - UINT64 CpuInfoInHob; - UINT32 CpuCount; - UINT32 BspNumber; - SPIN_LOCK MpLock; - UINTN Buffer; + UINT64 CpuInfoInHob; + UINT32 CpuCount; + UINT32 BspNumber; + SPIN_LOCK MpLock; + UINTN Buffer; + + // + // InitialBspApicMode stores the initial BSP APIC mode. + // It is used to synchronize the BSP APIC mode with APs + // in the first time APs wake up. + // Its value doesn't reflect the current APIC mode since there are + // two cases the APIC mode is changed: + // 1. MpLib explicitly switches to X2 APIC mode because number of threads is greater than 255, + // or there are any logical processors reporting an initial APIC ID of 255 or greater. + // 2. Some code switches to X2 APIC mode in all threads through MP services PPI/Protocol. + // + UINTN InitialBspApicMode; UINTN CpuApStackSize; MP_ASSEMBLY_ADDRESS_MAP AddressMap; UINTN WakeupBuffer;