#define CPU_FEATURE_END MAX_UINT32\r
/// @}\r
\r
+///\r
+/// The bit field to indicate whether the processor is the first in its parent scope.\r
+///\r
+typedef struct {\r
+ //\r
+ // Set to 1 when current processor is the first thread in the core it resides in.\r
+ //\r
+ UINT32 Thread : 1;\r
+ //\r
+ // Set to 1 when current processor is a thread of the first core in the module it resides in.\r
+ //\r
+ UINT32 Core : 1;\r
+ //\r
+ // Set to 1 when current processor is a thread of the first module in the tile it resides in.\r
+ //\r
+ UINT32 Module : 1;\r
+ //\r
+ // Set to 1 when current processor is a thread of the first tile in the die it resides in.\r
+ //\r
+ UINT32 Tile : 1;\r
+ //\r
+ // Set to 1 when current processor is a thread of the first die in the package it resides in.\r
+ //\r
+ UINT32 Die : 1;\r
+ //\r
+ // Set to 1 when current processor is a thread of the first package in the system.\r
+ //\r
+ UINT32 Package : 1;\r
+ UINT32 Reserved : 26;\r
+} REGISTER_CPU_FEATURE_FIRST_PROCESSOR;\r
+\r
///\r
/// CPU Information passed into the SupportFunc and InitializeFunc of the\r
/// RegisterCpuFeature() library function. This structure contains information\r
/// The package that the CPU resides\r
///\r
EFI_PROCESSOR_INFORMATION ProcessorInfo;\r
+\r
+ ///\r
+ /// The bit flag indicating whether the CPU is the first Thread/Core/Module/Tile/Die/Package in its parent scope.\r
+ ///\r
+ REGISTER_CPU_FEATURE_FIRST_PROCESSOR First;\r
///\r
/// The Display Family of the CPU computed from CPUID leaf CPUID_VERSION_INFO\r
///\r
/** @file\r
CPU Features Initialize functions.\r
\r
- Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2017 - 2020, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
EFI_CPU_PHYSICAL_LOCATION *Location;\r
BOOLEAN *CoresVisited;\r
UINTN Index;\r
+ UINT32 PackageIndex;\r
+ UINT32 CoreIndex;\r
+ UINT32 First;\r
ACPI_CPU_DATA *AcpiCpuData;\r
CPU_STATUS_INFORMATION *CpuStatus;\r
UINT32 *ValidCoreCountPerPackage;\r
ASSERT (CpuFeaturesData->CpuFlags.CoreSemaphoreCount != NULL);\r
CpuFeaturesData->CpuFlags.PackageSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount);\r
ASSERT (CpuFeaturesData->CpuFlags.PackageSemaphoreCount != NULL);\r
+\r
+ //\r
+ // Initialize CpuFeaturesData->InitOrder[].CpuInfo.First\r
+ //\r
+\r
+ //\r
+ // Set First.Package for each thread belonging to the first package.\r
+ //\r
+ First = MAX_UINT32;\r
+ for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
+ Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
+ First = MIN (Location->Package, First);\r
+ }\r
+ for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
+ Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
+ if (Location->Package == First) {\r
+ CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Package = 1;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set First.Die/Tile/Module for each thread assuming:\r
+ // single Die under each package, single Tile under each Die, single Module under each Tile\r
+ //\r
+ for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
+ CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Die = 1;\r
+ CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Tile = 1;\r
+ CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Module = 1;\r
+ }\r
+\r
+ for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) {\r
+ //\r
+ // Set First.Core for each thread in the first core of each package.\r
+ //\r
+ First = MAX_UINT32;\r
+ for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
+ Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
+ if (Location->Package == PackageIndex) {\r
+ First = MIN (Location->Core, First);\r
+ }\r
+ }\r
+\r
+ for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
+ Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
+ if (Location->Package == PackageIndex && Location->Core == First) {\r
+ CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Core = 1;\r
+ }\r
+ }\r
+ }\r
+\r
+ for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) {\r
+ for (CoreIndex = 0; CoreIndex < CpuStatus->MaxCoreCount; CoreIndex++) {\r
+ //\r
+ // Set First.Thread for the first thread of each core.\r
+ //\r
+ First = MAX_UINT32;\r
+ for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
+ Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
+ if (Location->Package == PackageIndex && Location->Core == CoreIndex) {\r
+ First = MIN (Location->Thread, First);\r
+ }\r
+ }\r
+\r
+ for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {\r
+ Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;\r
+ if (Location->Package == PackageIndex && Location->Core == CoreIndex && Location->Thread == First) {\r
+ CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.First.Thread = 1;\r
+ }\r
+ }\r
+ }\r
+ }\r
}\r
\r
/**\r