public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [edk2-platforms] MinPlatformPkg: Sort ApicIdOrderTable by special rules
@ 2024-03-28  8:43 duntan
  0 siblings, 0 replies; only message in thread
From: duntan @ 2024-03-28  8:43 UTC (permalink / raw)
  To: devel; +Cc: Ray Ni, Jason Lou, Chasel Chiu, Nate DeSimone, Liming Gao,
	Eric Dong

Sort ApicIdOrderTable by following special rules:
1. Make sure BSP is the first entry.
2. For APs, big core first, then small core.
3. For APs, if the core type are the same,
   sort them by AcpiProcessorUid.

With this implementation, BIOS can present cores in order
of relative performance in MADT. Linux OS would schedule
cores by the order that they are presented in the MADT
LocalX2ApicStruct entries.Then Linux OS would think of
this as relative performance order. This implementation
can benefit the linux os usage case.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Jason Lou <yun.lou@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Eric Dong <eric.dong@intel.com>
---
 Platform/Intel/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 109 insertions(+), 4 deletions(-)

diff --git a/Platform/Intel/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c b/Platform/Intel/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
index 2a833ec99c..1216a42eb4 100644
--- a/Platform/Intel/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
+++ b/Platform/Intel/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
@@ -18,6 +18,8 @@ typedef struct {
   UINT32   Flags;
   UINT32   SocketNum;
   UINT32   Thread;
+  UINT8    CoreType;
+  BOOLEAN  IsBsp;
 } EFI_CPU_ID_ORDER_MAP;
 
 //
@@ -72,15 +74,16 @@ DebugDisplayReOrderTable (
 {
   UINT32 Index;
 
-  DEBUG ((DEBUG_INFO, "Index  AcpiProcId  ApicId   Thread  Flags   Skt\n"));
+  DEBUG ((DEBUG_INFO, "Index  AcpiProcId  ApicId   Thread  Flags   Skt  CoreType\n"));
   for (Index = 0; Index < mNumberOfCpus; Index++) {
-    DEBUG ((DEBUG_INFO, " %02d       0x%02X      0x%02X       %d      %d      %d\n",
+    DEBUG ((DEBUG_INFO, " %02d       0x%02X      0x%02X       %d      %d      %d      0X%x\n",
                            Index,
                            CpuApicIdOrderTable[Index].AcpiProcessorUid,
                            CpuApicIdOrderTable[Index].ApicId,
                            CpuApicIdOrderTable[Index].Thread,
                            CpuApicIdOrderTable[Index].Flags,
-                           CpuApicIdOrderTable[Index].SocketNum));
+                           CpuApicIdOrderTable[Index].SocketNum,
+                           CpuApicIdOrderTable[Index].CoreType));
   }
 }
 
@@ -131,6 +134,82 @@ AppendCpuMapTableEntry (
 
 }
 
+/**
+  Get CPU core type.
+
+  @param[in] CpuApicIdOrderTable         Point to a buffer which will be filled in Core type information.
+**/
+VOID
+EFIAPI
+CollectCpuCoreType (
+  IN EFI_CPU_ID_ORDER_MAP  *CpuApicIdOrderTable
+  )
+{
+  UINTN                                    ApNumber;
+  EFI_STATUS                               Status;
+  CPUID_NATIVE_MODEL_ID_AND_CORE_TYPE_EAX  NativeModelIdAndCoreTypeEax;
+
+  Status = mMpService->WhoAmI (
+                         mMpService,
+                         &ApNumber
+                         );
+  ASSERT_EFI_ERROR (Status);
+
+  AsmCpuidEx (CPUID_HYBRID_INFORMATION, CPUID_HYBRID_INFORMATION_MAIN_LEAF, &NativeModelIdAndCoreTypeEax.Uint32, NULL, NULL, NULL);
+  CpuApicIdOrderTable[ApNumber].CoreType = (UINT8)NativeModelIdAndCoreTypeEax.Bits.CoreType;
+}
+
+/**
+  Function to compare 2 EFI_CPU_ID_ORDER_MAP entry based on special rules.
+
+  @param[in] Buffer1            pointer to EFI_CPU_ID_ORDER_MAP poiner to compare
+  @param[in] Buffer2            pointer to second EFI_CPU_ID_ORDER_MAP pointer to compare
+
+  @retval 0                     Buffer1 equal to Buffer2
+  @retval <0                    Buffer1 is less than Buffer2
+  @retval >0                    Buffer1 is greater than Buffer2
+**/
+INTN
+EFIAPI
+ApicIdOrderTableCompare (
+  IN  CONST VOID  *Buffer1,
+  IN  CONST VOID  *Buffer2
+  )
+{
+  //
+  // Make sure BSP is the first entry.
+  //
+  if (((EFI_CPU_ID_ORDER_MAP *)Buffer1)->IsBsp) {
+    return -1;
+  } else if (((EFI_CPU_ID_ORDER_MAP *)Buffer2)->IsBsp) {
+    return 1;
+  }
+
+  //
+  // Make sure big core first, then small core
+  //
+  if ((((EFI_CPU_ID_ORDER_MAP *)Buffer1)->CoreType == CPUID_CORE_TYPE_INTEL_CORE) &&
+      ((((EFI_CPU_ID_ORDER_MAP *)Buffer2)->CoreType == CPUID_CORE_TYPE_INTEL_ATOM)))
+  {
+    return -1;
+  } else if ((((EFI_CPU_ID_ORDER_MAP *)Buffer1)->CoreType == CPUID_CORE_TYPE_INTEL_ATOM) &&
+             ((((EFI_CPU_ID_ORDER_MAP *)Buffer2)->CoreType == CPUID_CORE_TYPE_INTEL_CORE)))
+  {
+    return 1;
+  }
+
+  //
+  // If both cores are not BSP and the core type are the same, sort them by AcpiProcessorUid.
+  //
+  if (((EFI_CPU_ID_ORDER_MAP *)Buffer1)->AcpiProcessorUid < ((EFI_CPU_ID_ORDER_MAP *)Buffer2)->AcpiProcessorUid) {
+    return -1;
+  } else if (((EFI_CPU_ID_ORDER_MAP *)Buffer1)->AcpiProcessorUid > ((EFI_CPU_ID_ORDER_MAP *)Buffer2)->AcpiProcessorUid) {
+    return 1;
+  }
+
+  return 0;
+}
+
 /**
   Collect all processors information and create a Cpu Apic Id table.
 
@@ -147,8 +226,24 @@ CreateCpuLocalApicInTable (
   UINT32                                    CurrProcessor;
   EFI_CPU_ID_ORDER_MAP                      *CpuIdMapPtr;
   UINT32                                    Socket;
+  UINT32                                    CpuidMaxInput;
+  EFI_CPU_ID_ORDER_MAP                      SortBuffer;
+
+  Status = EFI_SUCCESS;
 
-  Status     = EFI_SUCCESS;
+  AsmCpuid (CPUID_SIGNATURE, &CpuidMaxInput, NULL, NULL, NULL);
+  if (CpuidMaxInput >= CPUID_HYBRID_INFORMATION) {
+    CollectCpuCoreType (CpuApicIdOrderTable);
+    mMpService->StartupAllAPs (
+                  mMpService,                               // This
+                  (EFI_AP_PROCEDURE) CollectCpuCoreType,    // Procedure
+                  TRUE,                                     // SingleThread
+                  NULL,                                     // WaitEvent
+                  0,                                        // TimeoutInMicrosecsond
+                  CpuApicIdOrderTable,                      // ProcedureArgument
+                  NULL                                      // FailedCpuList
+                  );
+  }
 
   for (CurrProcessor = 0, Index = 0; CurrProcessor < mNumberOfCpus; CurrProcessor++, Index++) {
     Status = mMpService->GetProcessorInfo (
@@ -158,6 +253,11 @@ CreateCpuLocalApicInTable (
                            );
 
     CpuIdMapPtr = (EFI_CPU_ID_ORDER_MAP *) &CpuApicIdOrderTable[Index];
+
+    if (ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) {
+      CpuIdMapPtr->IsBsp = TRUE;
+    }
+
     if ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) != 0) {
       CpuIdMapPtr->ApicId  = (UINT32)ProcessorInfoBuffer.ProcessorId;
       CpuIdMapPtr->Thread  = ProcessorInfoBuffer.Location.Thread;
@@ -197,6 +297,11 @@ CreateCpuLocalApicInTable (
     }
   }
 
+  //
+  // Perform quick sort
+  //
+  QuickSort (CpuApicIdOrderTable, mNumberOfCpus, sizeof (EFI_CPU_ID_ORDER_MAP), (BASE_SORT_COMPARE)ApicIdOrderTableCompare, &SortBuffer);
+
   DEBUG ((DEBUG_INFO, "::ACPI::  APIC ID Order Table Init.   mNumOfBitShift = %x\n", mNumOfBitShift));
   DebugDisplayReOrderTable (CpuApicIdOrderTable);
 
-- 
2.31.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117201): https://edk2.groups.io/g/devel/message/117201
Mute This Topic: https://groups.io/mt/105193257/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2024-03-28  8:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-28  8:43 [edk2-devel] [edk2-platforms] MinPlatformPkg: Sort ApicIdOrderTable by special rules duntan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox