If x2APIC is supported by processor, get the APIC ID from
CPUID.(EAX=0BH, ECX=0H):EDX instead of legacy APIC ID. It is used to check if
need to enable x2APIC mode.

Cc: Feng Tian <[email protected]>
Cc: Michael Kinney <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <[email protected]>
---
 UefiCpuPkg/CpuMpPei/CpuMpPei.c | 65 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 63 insertions(+), 2 deletions(-)

diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
index 8e35f28..a301fe5 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -102,6 +102,62 @@ SortApicId (
 }
 
 /**
+  Check if x2APIC is supported by processor.
+
+  @retval  TRUE    x2APIC is supported.
+  @retval  FALSE   x2APIC isn't supported.
+**/
+BOOLEAN
+IsX2ApicModeSupport (
+  VOID
+  )
+{
+  UINT32                        RegEcx;
+  //
+  // Check if processor supports x2APIC feature
+  //
+  AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &RegEcx, NULL);
+  if ((RegEcx & BIT21) != 0) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  Return x2APIC ID from CPUID.
+
+  @retval -1      Invalid x2APIC ID
+  @retval others  x2APIC ID returned
+**/
+UINT32
+GetX2ApicIdFromCpuId (
+  VOID
+  )
+{
+  UINT32                        RegEdx;
+  UINT32                        MaxCpuIdIndex;
+
+  //
+  // The APIC ID value of FFFF_FFFFH is reserved and cannot be assigned
+  // to any logical processor.
+  //
+  RegEdx = 0xFFFFFFFF;
+  //
+  // Get the maximum index of basic CPUID
+  //
+  AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
+  //
+  // If the extended topology enumeration leaf is available,
+  // get x2APIC ID from CPUID.(EAX=0BH, ECX=0H):EDX
+  //
+  if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
+    AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, NULL, NULL, NULL, &RegEdx);
+  }
+  return RegEdx;
+}
+
+/**
   Get CPU MP Data pointer from the Guided HOB.
 
   @return  Pointer to Pointer to PEI CPU MP Data
@@ -146,11 +202,16 @@ ApCFunction (
   PeiCpuMpData = ExchangeInfo->PeiCpuMpData;
   if (PeiCpuMpData->InitFlag) {
     //
-    // This is first time AP wakeup, get BIST inforamtion from AP stack
+    // This is first time AP wakeup, get BIST information from AP stack
     //
     BistData = *(UINTN *) (PeiCpuMpData->Buffer + NumApsExecuting * 
PeiCpuMpData->CpuApStackSize - sizeof (UINTN));
-    PeiCpuMpData->CpuData[NumApsExecuting].ApicId        = GetInitialApicId ();
     PeiCpuMpData->CpuData[NumApsExecuting].Health.Uint32 = (UINT32) BistData;
+    if (!IsX2ApicModeSupport()) {
+      PeiCpuMpData->CpuData[NumApsExecuting].ApicId = GetInitialApicId ();
+    } else {
+      PeiCpuMpData->CpuData[NumApsExecuting].ApicId = GetX2ApicIdFromCpuId ();
+      ASSERT (PeiCpuMpData->CpuData[NumApsExecuting].ApicId != 0xFFFFFFFF);
+    }
     //
     // Sync BSP's Mtrr table to all wakeup APs and load microcode on APs.
     //
-- 
1.9.5.msysgit.0

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to