diff options
author | Ray Ni <ray.ni@intel.com> | 2023-04-14 13:58:15 +0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2024-08-28 17:46:17 +0000 |
commit | 7ed398916605be3e9fd3b1bfc8f49cc36e86fd3f (patch) | |
tree | 6a44c60a330b07634c061d0441b54eb9d7b4e611 /UefiCpuPkg/Library | |
parent | 94f68d0b56a36d84e038751f9cd907c2cf637626 (diff) | |
download | edk2-7ed398916605be3e9fd3b1bfc8f49cc36e86fd3f.tar.gz edk2-7ed398916605be3e9fd3b1bfc8f49cc36e86fd3f.tar.bz2 edk2-7ed398916605be3e9fd3b1bfc8f49cc36e86fd3f.zip |
UefiCpuPkg/MpInitLib: Sync BSP's APIC mode to APs in InitConfig path
The change saves the BSP's initial APIC mode and syncs to all APs
in first time wakeup. It allows certain platforms to switch to X2 APIC
as early as possible and also independent on CpuFeaturePei/Dxe.
The platform should switch BSP to X2 APIC mode first before the
CpuMpPeim runs.
Signed-off-by: Ray Ni <ray.ni@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'UefiCpuPkg/Library')
-rw-r--r-- | UefiCpuPkg/Library/MpInitLib/MpLib.c | 11 | ||||
-rw-r--r-- | UefiCpuPkg/Library/MpInitLib/MpLib.h | 22 |
2 files changed, 28 insertions, 5 deletions
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
@@ -2222,6 +2228,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.
//
ProgramVirtualWireMode ();
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;
|