diff --git a/UefiCpuPkg/Include/AcpiCpuData.h b/UefiCpuPkg/Include/AcpiCpuData.h
index 77da5d4455..b5a69ad80c 100644
--- a/UefiCpuPkg/Include/AcpiCpuData.h
+++ b/UefiCpuPkg/Include/AcpiCpuData.h
@@ -1,7 +1,7 @@
/** @file
Definitions for CPU S3 data.
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2013 - 2020, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -60,14 +60,24 @@ typedef struct {
UINT32 MaxThreadCount;
//
// This field points to an array.
- // This array saves valid core count (type UINT32) of each package.
+ // This array saves thread count (type UINT32) of each package.
// The array has PackageCount elements.
//
// If the platform does not support MSR setting at S3 resume, and
// therefore it doesn't need the dependency semaphores, it should set
// this field to 0.
//
- EFI_PHYSICAL_ADDRESS ValidCoreCountPerPackage;
+ EFI_PHYSICAL_ADDRESS ThreadCountPerPackage;
+ //
+ // This field points to an array.
+ // This array saves thread count (type UINT8) of each core.
+ // The array has PackageCount * MaxCoreCount elements.
+ //
+ // If the platform does not support MSR setting at S3 resume, and
+ // therefore it doesn't need the dependency semaphores, it should set
+ // this field to 0.
+ //
+ EFI_PHYSICAL_ADDRESS ThreadCountPerCore;
} CPU_STATUS_INFORMATION;
//
diff --git a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c
index 5c673fa8cf..d4a576385f 100644
--- a/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c
+++ b/UefiCpuPkg/Library/RegisterCpuFeaturesLib/CpuFeaturesInitialize.c
@@ -103,14 +103,13 @@ CpuInitDataInitialize (
UINT32 Package;
UINT32 Thread;
EFI_CPU_PHYSICAL_LOCATION *Location;
- BOOLEAN *CoresVisited;
- UINTN Index;
UINT32 PackageIndex;
UINT32 CoreIndex;
UINT32 First;
ACPI_CPU_DATA *AcpiCpuData;
CPU_STATUS_INFORMATION *CpuStatus;
- UINT32 *ValidCoreCountPerPackage;
+ UINT32 *ThreadCountPerPackage;
+ UINT8 *ThreadCountPerCore;
UINTN NumberOfCpus;
UINTN NumberOfEnabledProcessors;
@@ -202,36 +201,33 @@ CpuInitDataInitialize (
//
// Collect valid core count in each package because not all cores are valid.
//
- ValidCoreCountPerPackage= AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount);
- ASSERT (ValidCoreCountPerPackage != 0);
- CpuStatus->ValidCoreCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)ValidCoreCountPerPackage;
- CoresVisited = AllocatePool (sizeof (BOOLEAN) * CpuStatus->MaxCoreCount);
- ASSERT (CoresVisited != NULL);
+ ThreadCountPerPackage = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount);
+ ASSERT (ThreadCountPerPackage != NULL);
+ CpuStatus->ThreadCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)ThreadCountPerPackage;
- for (Index = 0; Index < CpuStatus->PackageCount; Index ++ ) {
- ZeroMem (CoresVisited, sizeof (BOOLEAN) * CpuStatus->MaxCoreCount);
- //
- // Collect valid cores in Current package.
- //
- for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
- Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;
- if (Location->Package == Index && !CoresVisited[Location->Core] ) {
- //
- // The ValidCores position for Location->Core is valid.
- // The possible values in ValidCores[Index] are 0 or 1.
- // FALSE means no valid threads in this Core.
- // TRUE means have valid threads in this core, no matter the thead count is 1 or more.
- //
- CoresVisited[Location->Core] = TRUE;
- ValidCoreCountPerPackage[Index]++;
+ ThreadCountPerCore = AllocateZeroPool (sizeof (UINT8) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount);
+ ASSERT (ThreadCountPerCore != NULL);
+ CpuStatus->ThreadCountPerCore = (EFI_PHYSICAL_ADDRESS)(UINTN)ThreadCountPerCore;
+
+ for (ProcessorNumber = 0; ProcessorNumber < NumberOfCpus; ProcessorNumber++) {
+ Location = &CpuFeaturesData->InitOrder[ProcessorNumber].CpuInfo.ProcessorInfo.Location;
+ ThreadCountPerPackage[Location->Package]++;
+ ThreadCountPerCore[Location->Package * CpuStatus->MaxCoreCount + Location->Core]++;
+ }
+
+ for (PackageIndex = 0; PackageIndex < CpuStatus->PackageCount; PackageIndex++) {
+ if (ThreadCountPerPackage[PackageIndex] != 0) {
+ DEBUG ((DEBUG_INFO, "P%02d: Thread Count = %d\n", PackageIndex, ThreadCountPerPackage[PackageIndex]));
+ for (CoreIndex = 0; CoreIndex < CpuStatus->MaxCoreCount; CoreIndex++) {
+ if (ThreadCountPerCore[PackageIndex * CpuStatus->MaxCoreCount + CoreIndex] != 0) {
+ DEBUG ((
+ DEBUG_INFO, " P%02d C%04d, Thread Count = %d\n", PackageIndex, CoreIndex,
+ ThreadCountPerCore[PackageIndex * CpuStatus->MaxCoreCount + CoreIndex]
+ ));
+ }
}
}
}
- FreePool (CoresVisited);
-
- for (Index = 0; Index <= Package; Index++) {
- DEBUG ((DEBUG_INFO, "Package: %d, Valid Core : %d\n", Index, ValidCoreCountPerPackage[Index]));
- }
CpuFeaturesData->CpuFlags.CoreSemaphoreCount = AllocateZeroPool (sizeof (UINT32) * CpuStatus->PackageCount * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount);
ASSERT (CpuFeaturesData->CpuFlags.CoreSemaphoreCount != NULL);
@@ -894,11 +890,11 @@ ProgramProcessorRegister (
CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead;
volatile UINT32 *SemaphorePtr;
UINT32 FirstThread;
- UINT32 PackageThreadsCount;
UINT32 CurrentThread;
+ UINT32 CurrentCore;
UINTN ProcessorIndex;
- UINTN ValidThreadCount;
- UINT32 *ValidCoreCountPerPackage;
+ UINT32 *ThreadCountPerPackage;
+ UINT8 *ThreadCountPerCore;
EFI_STATUS Status;
UINT64 CurrentValue;
@@ -1029,28 +1025,44 @@ ProgramProcessorRegister (
switch (RegisterTableEntry->Value) {
case CoreDepType:
SemaphorePtr = CpuFlags->CoreSemaphoreCount;
+ ThreadCountPerCore = (UINT8 *)(UINTN)CpuStatus->ThreadCountPerCore;
+
+ CurrentCore = ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core;
//
// Get Offset info for the first thread in the core which current thread belongs to.
//
- FirstThread = (ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core) * CpuStatus->MaxThreadCount;
+ FirstThread = CurrentCore * CpuStatus->MaxThreadCount;
CurrentThread = FirstThread + ApLocation->Thread;
+
//
- // First Notify all threads in current Core that this thread has ready.
+ // Different cores may have different valid threads in them. If driver maintail clearly
+ // thread index in different cores, the logic will be much complicated.
+ // Here driver just simply records the max thread number in all cores and use it as expect
+ // thread number for all cores.
+ // In below two steps logic, first current thread will Release semaphore for each thread
+ // in current core. Maybe some threads are not valid in this core, but driver don't
+ // care. Second, driver will let current thread wait semaphore for all valid threads in
+ // current core. Because only the valid threads will do release semaphore for this
+ // thread, driver here only need to wait the valid thread count.
+ //
+
+ //
+ // First Notify ALL THREADs in current Core that this thread is ready.
//
for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) {
- LibReleaseSemaphore ((UINT32 *) &SemaphorePtr[FirstThread + ProcessorIndex]);
+ LibReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
}
//
- // Second, check whether all valid threads in current core have ready.
+ // Second, check whether all VALID THREADs (not all threads) in current core are ready.
//
- for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) {
+ for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerCore[CurrentCore]; ProcessorIndex ++) {
LibWaitForSemaphore (&SemaphorePtr[CurrentThread]);
}
break;
case PackageDepType:
SemaphorePtr = CpuFlags->PackageSemaphoreCount;
- ValidCoreCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ValidCoreCountPerPackage;
+ ThreadCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ThreadCountPerPackage;
//
// Get Offset info for the first thread in the package which current thread belongs to.
//
@@ -1058,18 +1070,13 @@ ProgramProcessorRegister (
//
// Get the possible threads count for current package.
//
- PackageThreadsCount = CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount;
CurrentThread = FirstThread + CpuStatus->MaxThreadCount * ApLocation->Core + ApLocation->Thread;
- //
- // Get the valid thread count for current package.
- //
- ValidThreadCount = CpuStatus->MaxThreadCount * ValidCoreCountPerPackage[ApLocation->Package];
//
- // Different packages may have different valid cores in them. If driver maintail clearly
- // cores number in different packages, the logic will be much complicated.
- // Here driver just simply records the max core number in all packages and use it as expect
- // core number for all packages.
+ // Different packages may have different valid threads in them. If driver maintail clearly
+ // thread index in different packages, the logic will be much complicated.
+ // Here driver just simply records the max thread number in all packages and use it as expect
+ // thread number for all packages.
// In below two steps logic, first current thread will Release semaphore for each thread
// in current package. Maybe some threads are not valid in this package, but driver don't
// care. Second, driver will let current thread wait semaphore for all valid threads in
@@ -1078,15 +1085,15 @@ ProgramProcessorRegister (
//
//
- // First Notify ALL THREADS in current package that this thread has ready.
+ // First Notify ALL THREADS in current package that this thread is ready.
//
- for (ProcessorIndex = 0; ProcessorIndex < PackageThreadsCount ; ProcessorIndex ++) {
- LibReleaseSemaphore ((UINT32 *) &SemaphorePtr[FirstThread + ProcessorIndex]);
+ for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount; ProcessorIndex ++) {
+ LibReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
}
//
- // Second, check whether VALID THREADS (not all threads) in current package have ready.
+ // Second, check whether VALID THREADS (not all threads) in current package are ready.
//
- for (ProcessorIndex = 0; ProcessorIndex < ValidThreadCount; ProcessorIndex ++) {
+ for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerPackage[ApLocation->Package]; ProcessorIndex ++) {
LibWaitForSemaphore (&SemaphorePtr[CurrentThread]);
}
break;
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
index 29e9ba92b4..9592430636 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
@@ -1,7 +1,7 @@
/** @file
Code for Processor S3 restoration
-Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -235,11 +235,11 @@ ProgramProcessorRegister (
CPU_REGISTER_TABLE_ENTRY *RegisterTableEntryHead;
volatile UINT32 *SemaphorePtr;
UINT32 FirstThread;
- UINT32 PackageThreadsCount;
UINT32 CurrentThread;
+ UINT32 CurrentCore;
UINTN ProcessorIndex;
- UINTN ValidThreadCount;
- UINT32 *ValidCoreCountPerPackage;
+ UINT32 *ThreadCountPerPackage;
+ UINT8 *ThreadCountPerCore;
EFI_STATUS Status;
UINT64 CurrentValue;
@@ -372,35 +372,52 @@ ProgramProcessorRegister (
//
ASSERT (
(ApLocation != NULL) &&
- (CpuStatus->ValidCoreCountPerPackage != 0) &&
+ (CpuStatus->ThreadCountPerPackage != 0) &&
+ (CpuStatus->ThreadCountPerCore != 0) &&
(CpuFlags->CoreSemaphoreCount != NULL) &&
(CpuFlags->PackageSemaphoreCount != NULL)
);
switch (RegisterTableEntry->Value) {
case CoreDepType:
SemaphorePtr = CpuFlags->CoreSemaphoreCount;
+ ThreadCountPerCore = (UINT8 *)(UINTN)CpuStatus->ThreadCountPerCore;
+
+ CurrentCore = ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core;
//
// Get Offset info for the first thread in the core which current thread belongs to.
//
- FirstThread = (ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core) * CpuStatus->MaxThreadCount;
+ FirstThread = CurrentCore * CpuStatus->MaxThreadCount;
CurrentThread = FirstThread + ApLocation->Thread;
+
//
- // First Notify all threads in current Core that this thread has ready.
+ // Different cores may have different valid threads in them. If driver maintail clearly
+ // thread index in different cores, the logic will be much complicated.
+ // Here driver just simply records the max thread number in all cores and use it as expect
+ // thread number for all cores.
+ // In below two steps logic, first current thread will Release semaphore for each thread
+ // in current core. Maybe some threads are not valid in this core, but driver don't
+ // care. Second, driver will let current thread wait semaphore for all valid threads in
+ // current core. Because only the valid threads will do release semaphore for this
+ // thread, driver here only need to wait the valid thread count.
+ //
+
+ //
+ // First Notify ALL THREADs in current Core that this thread is ready.
//
for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) {
S3ReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
}
//
- // Second, check whether all valid threads in current core have ready.
+ // Second, check whether all VALID THREADs (not all threads) in current core are ready.
//
- for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex ++) {
+ for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerCore[CurrentCore]; ProcessorIndex ++) {
S3WaitForSemaphore (&SemaphorePtr[CurrentThread]);
}
break;
case PackageDepType:
SemaphorePtr = CpuFlags->PackageSemaphoreCount;
- ValidCoreCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ValidCoreCountPerPackage;
+ ThreadCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ThreadCountPerPackage;
//
// Get Offset info for the first thread in the package which current thread belongs to.
//
@@ -408,18 +425,13 @@ ProgramProcessorRegister (
//
// Get the possible threads count for current package.
//
- PackageThreadsCount = CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount;
CurrentThread = FirstThread + CpuStatus->MaxThreadCount * ApLocation->Core + ApLocation->Thread;
- //
- // Get the valid thread count for current package.
- //
- ValidThreadCount = CpuStatus->MaxThreadCount * ValidCoreCountPerPackage[ApLocation->Package];
//
- // Different packages may have different valid cores in them. If driver maintail clearly
- // cores number in different packages, the logic will be much complicated.
- // Here driver just simply records the max core number in all packages and use it as expect
- // core number for all packages.
+ // Different packages may have different valid threads in them. If driver maintail clearly
+ // thread index in different packages, the logic will be much complicated.
+ // Here driver just simply records the max thread number in all packages and use it as expect
+ // thread number for all packages.
// In below two steps logic, first current thread will Release semaphore for each thread
// in current package. Maybe some threads are not valid in this package, but driver don't
// care. Second, driver will let current thread wait semaphore for all valid threads in
@@ -428,15 +440,15 @@ ProgramProcessorRegister (
//
//
- // First Notify all threads in current package that this thread has ready.
+ // First Notify ALL THREADS in current package that this thread is ready.
//
- for (ProcessorIndex = 0; ProcessorIndex < PackageThreadsCount ; ProcessorIndex ++) {
+ for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount; ProcessorIndex ++) {
S3ReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
}
//
- // Second, check whether all valid threads in current package have ready.
+ // Second, check whether VALID THREADS (not all threads) in current package are ready.
//
- for (ProcessorIndex = 0; ProcessorIndex < ValidThreadCount; ProcessorIndex ++) {
+ for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerPackage[ApLocation->Package]; ProcessorIndex ++) {
S3WaitForSemaphore (&SemaphorePtr[CurrentThread]);
}
break;
@@ -1059,12 +1071,19 @@ GetAcpiCpuData (
CpuStatus = &mAcpiCpuData.CpuStatus;
CopyMem (CpuStatus, &AcpiCpuData->CpuStatus, sizeof (CPU_STATUS_INFORMATION));
- if (AcpiCpuData->CpuStatus.ValidCoreCountPerPackage != 0) {
- CpuStatus->ValidCoreCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (
+ if (AcpiCpuData->CpuStatus.ThreadCountPerPackage != 0) {
+ CpuStatus->ThreadCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (
sizeof (UINT32) * CpuStatus->PackageCount,
- (UINT32 *)(UINTN)AcpiCpuData->CpuStatus.ValidCoreCountPerPackage
+ (UINT32 *)(UINTN)AcpiCpuData->CpuStatus.ThreadCountPerPackage
);
- ASSERT (CpuStatus->ValidCoreCountPerPackage != 0);
+ ASSERT (CpuStatus->ThreadCountPerPackage != 0);
+ }
+ if (AcpiCpuData->CpuStatus.ThreadCountPerCore != 0) {
+ CpuStatus->ThreadCountPerCore = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (
+ sizeof (UINT8) * (CpuStatus->PackageCount * CpuStatus->MaxCoreCount),
+ (UINT32 *)(UINTN)AcpiCpuData->CpuStatus.ThreadCountPerCore
+ );
+ ASSERT (CpuStatus->ThreadCountPerCore != 0);
}
if (AcpiCpuData->ApLocation != 0) {
mAcpiCpuData.ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (