From 7033f359a99121fd2c3fefe03d9f0c64e8bfaa10 Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Tue, 28 May 2024 11:22:10 +0800 Subject: [PATCH] UefiCpuPkg: Preserve Local APIC Timer Settings During BSP Switch This update ensures the consistency of Local APIC timer settings across all processors when a BSP switch occurs. The Local APIC timer is utilized in two distinct scenarios: 1. As a delay mechanism within the timer library. 2. To generate periodic timer interrupts during the DXE phase. For scenario 1, APs can simply inherit the initial settings from the BSP. Even the local APIC timer setting is changed by BSP later, AP can still use the old setting. Therefore, the code to save the Local APIC timer can be moved to MpInitLibInitialize(). For scenario 2, because normal AP doesn't enable timer interrupt, we only need to care SwitchBsp case. It is crucial that the periodic timer interrupts remain operational after BSP is switched. To achieve this, the Local APIC timer settings on old BSP are now preserved and synced to new BSP. Signed-off-by: Zhiguang Liu --- UefiCpuPkg/Library/MpInitLib/MpLib.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c index 78eeaa6de2..69c53c6228 100644 --- a/UefiCpuPkg/Library/MpInitLib/MpLib.c +++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c @@ -1258,7 +1258,6 @@ WakeUpAP ( AllocateResetVectorBelow1Mb (CpuMpData); AllocateSevEsAPMemory (CpuMpData); FillExchangeInfoData (CpuMpData); - SaveLocalApicTimerSetting (CpuMpData); } if (CpuMpData->ApLoopMode == ApInMwaitLoop) { @@ -2236,6 +2235,7 @@ MpInitLibInitialize ( // Enable the local APIC for Virtual Wire Mode. // ProgramVirtualWireMode (); + SaveLocalApicTimerSetting (CpuMpData); if (FirstMpHandOff == NULL) { if (MaxLogicalProcessorNumber > 1) { @@ -2611,6 +2611,11 @@ SwitchBSPWorker ( ApicBaseMsr.Bits.BSP = 0; AsmWriteMsr64 (MSR_IA32_APIC_BASE, ApicBaseMsr.Uint64); + // + // Save BSP's local APIC timer setting. + // + SaveLocalApicTimerSetting (CpuMpData); + // // Need to wakeUp AP (future BSP). //