UefiCpuPkg/PiSmmCpuDxeSmm: Handle the NULL gMpInformation2HobGuid
If gMpInformation2HobGuid HOB is NULL,
then fall back to an older way of collecting
CPU information from the MP services library.
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
index 499f979..74e494f 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
@@ -3,7 +3,7 @@
Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
-Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -751,6 +751,85 @@
}
/**
+ Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from gEfiMpServiceProtocolGuid.
+
+ @param[out] NumberOfCpus Pointer to NumberOfCpus.
+ @param[out] MaxNumberOfCpus Pointer to MaxNumberOfCpus.
+
+ @retval ProcessorInfo Pointer to EFI_PROCESSOR_INFORMATION buffer.
+**/
+EFI_PROCESSOR_INFORMATION *
+GetMpInformationFromMpServices (
+ OUT UINTN *NumberOfCpus,
+ OUT UINTN *MaxNumberOfCpus
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN NumberOfEnabledProcessors;
+ UINTN NumberOfProcessors;
+ EFI_MP_SERVICES_PROTOCOL *MpService;
+ EFI_PROCESSOR_INFORMATION *ProcessorInfo;
+
+ if ((NumberOfCpus == NULL) || (MaxNumberOfCpus == NULL)) {
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ ProcessorInfo = NULL;
+ *NumberOfCpus = 0;
+ *MaxNumberOfCpus = 0;
+
+ /// Get the MP Services Protocol
+ Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpService);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return NULL;
+ }
+
+ /// Get the number of processors
+ Status = MpService->GetNumberOfProcessors (MpService, &NumberOfProcessors, &NumberOfEnabledProcessors);
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return NULL;
+ }
+
+ ASSERT (NumberOfProcessors <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+
+ /// Allocate buffer for processor information
+ ProcessorInfo = AllocateZeroPool (sizeof (EFI_PROCESSOR_INFORMATION) * NumberOfProcessors);
+ if (ProcessorInfo == NULL) {
+ ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+ return NULL;
+ }
+
+ /// Get processor information
+ for (Index = 0; Index < NumberOfProcessors; Index++) {
+ Status = MpService->GetProcessorInfo (MpService, Index | CPU_V2_EXTENDED_TOPOLOGY, &ProcessorInfo[Index]);
+ if (EFI_ERROR (Status)) {
+ FreePool (ProcessorInfo);
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get processor information for processor %d\n", __func__, Index));
+ ASSERT_EFI_ERROR (Status);
+ return NULL;
+ }
+ }
+
+ *NumberOfCpus = NumberOfEnabledProcessors;
+
+ ASSERT (*NumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
+ //
+ // If support CPU hot plug, we need to allocate resources for possibly hot-added processors
+ //
+ if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
+ *MaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
+ } else {
+ *MaxNumberOfCpus = *NumberOfCpus;
+ }
+
+ return ProcessorInfo;
+}
+
+/**
Extract NumberOfCpus, MaxNumberOfCpus and EFI_PROCESSOR_INFORMATION for all CPU from MpInformation2 HOB.
@param[out] NumberOfCpus Pointer to NumberOfCpus.
@@ -784,7 +863,11 @@
HobCount = 0;
FirstMpInfo2Hob = GetFirstGuidHob (&gMpInformation2HobGuid);
- ASSERT (FirstMpInfo2Hob != NULL);
+ if (FirstMpInfo2Hob == NULL) {
+ DEBUG ((DEBUG_INFO, "%a: [INFO] gMpInformation2HobGuid HOB not found.\n", __func__));
+ return GetMpInformationFromMpServices (NumberOfCpus, MaxNumberOfCpus);
+ }
+
GuidHob = FirstMpInfo2Hob;
while (GuidHob != NULL) {
MpInformation2HobData = GET_GUID_HOB_DATA (GuidHob);
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
index a018954..db99a63 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
@@ -6,7 +6,7 @@
#
# Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
-# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
+# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -114,6 +114,7 @@
gEdkiiSmmMemoryAttributeProtocolGuid ## PRODUCES
gEfiMmMpProtocolGuid ## PRODUCES
gEdkiiSmmCpuRendezvousProtocolGuid ## PRODUCES
+ gEfiMpServiceProtocolGuid ## CONSUMES
[Guids]
gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is used for S3 boot.