[edk2-platforms] [PATCH 1/1] Platform/Sgi: Add support to disable isolated cpus


Nishant Sharma
 

Isolated CPUs are those that are not to be used on the platform for
various reasons. The isolated CPU list is an array of MPID values of
the CPUs that have to be isolated. This list is supplied via the
NT_FW_CONFIG dtb.

Add support to search for isolated CPUs MPID list and, if present,
update the MADT table to disable the corresponding CPUs.

Signed-off-by: Nishant Sharma <nishant.sharma@...>
---
Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf | 1 -
Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPei.inf | 8 +-
Platform/ARM/SgiPkg/Include/SgiPlatform.h | 7 ++
Platform/ARM/SgiPkg/Drivers/PlatformDxe/PlatformDxe.c | 131 ++++++=
+++++++++++++-
Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPeim.c | 45 ++++++-
5 files changed, 186 insertions(+), 6 deletions(-)

diff --git a/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf b/Platfo=
rm/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
index 4b36c3e5ceb2..e13c2f08ce6e 100644
--- a/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
+++ b/Platform/ARM/SgiPkg/AcpiTables/RdN2Cfg1AcpiTables.inf
@@ -18,7 +18,6 @@
Dbg2.aslc=0D
Fadt.aslc=0D
Gtdt.aslc=0D
- Iort.aslc=0D
Mcfg.aslc=0D
RdN2Cfg1/Dsdt.asl=0D
RdN2Cfg1/Madt.aslc=0D
diff --git a/Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPei.inf =
b/Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPei.inf
index 407160c07563..fbf061ad3bdb 100644
--- a/Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPei.inf
+++ b/Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPei.inf
@@ -1,5 +1,5 @@
#=0D
-# Copyright (c) 2018, ARM Limited. All rights reserved.=0D
+# Copyright (c) 2018-2022, ARM Limited. All rights reserved.=0D
#=0D
# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
#=0D
@@ -13,6 +13,7 @@
ENTRY_POINT =3D SgiPlatformPeim=0D
=0D
[Packages]=0D
+ ArmPlatformPkg/ArmPlatformPkg.dec=0D
EmbeddedPkg/EmbeddedPkg.dec=0D
MdePkg/MdePkg.dec=0D
Platform/ARM/SgiPkg/SgiPlatform.dec=0D
@@ -21,6 +22,11 @@
FdtLib=0D
PeimEntryPoint=0D
=0D
+[FixedPcd]=0D
+ gArmSgiTokenSpaceGuid.PcdChipCount=0D
+ gArmPlatformTokenSpaceGuid.PcdCoreCount=0D
+ gArmPlatformTokenSpaceGuid.PcdClusterCount=0D
+=0D
[Sources]=0D
SgiPlatformPeim.c=0D
=0D
diff --git a/Platform/ARM/SgiPkg/Include/SgiPlatform.h b/Platform/ARM/SgiPk=
g/Include/SgiPlatform.h
index dddb58832d73..311286ce5337 100644
--- a/Platform/ARM/SgiPkg/Include/SgiPlatform.h
+++ b/Platform/ARM/SgiPkg/Include/SgiPlatform.h
@@ -65,11 +65,18 @@
#define DRAM_BLOCK2_BASE_REMOTE(ChipId) \=0D
(SGI_REMOTE_CHIP_MEM_OFFSET (ChipId) + FixedPcdGet64 (PcdDramBlo=
ck2Base))=0D
=0D
+// List of isolated CPUs MPID=0D
+typedef struct {=0D
+ UINT64 Count; // Number of elements present in the list=
=0D
+ UINT64 Mpid[]; // List containing isolated CPU MPIDs=0D
+} SGI_ISOLATED_CPU_LIST;=0D
+=0D
// ARM platform description data.=0D
typedef struct {=0D
UINTN PlatformId;=0D
UINTN ConfigId;=0D
UINTN MultiChipMode;=0D
+ SGI_ISOLATED_CPU_LIST IsolatedCpuList;=0D
} SGI_PLATFORM_DESCRIPTOR;=0D
=0D
// Arm SGI/RD Product IDs=0D
diff --git a/Platform/ARM/SgiPkg/Drivers/PlatformDxe/PlatformDxe.c b/Platfo=
rm/ARM/SgiPkg/Drivers/PlatformDxe/PlatformDxe.c
index 2f72e7152ff3..80190120ff32 100644
--- a/Platform/ARM/SgiPkg/Drivers/PlatformDxe/PlatformDxe.c
+++ b/Platform/ARM/SgiPkg/Drivers/PlatformDxe/PlatformDxe.c
@@ -1,14 +1,17 @@
/** @file=0D
*=0D
-* Copyright (c) 2018, ARM Limited. All rights reserved.=0D
+* Copyright (c) 2018 - 2022, ARM Limited. All rights reserved.=0D
*=0D
* SPDX-License-Identifier: BSD-2-Clause-Patent=0D
*=0D
**/=0D
=0D
+#include <IndustryStandard/Acpi.h>=0D
+=0D
#include <Library/AcpiLib.h>=0D
#include <Library/DebugLib.h>=0D
#include <Library/HobLib.h>=0D
+#include <Library/UefiBootServicesTableLib.h>=0D
#include <SgiPlatform.h>=0D
=0D
VOID=0D
@@ -16,6 +19,127 @@ InitVirtioDevices (
VOID=0D
);=0D
=0D
+/**=0D
+ Search for a MPID in a list=0D
+=0D
+ Performs a linear search for a specified MPID on the given linear=0D
+ list of MPIDs.=0D
+=0D
+ @param[in] MpidList Pointer to list.=0D
+ @param[in] Count Number of the elements in the list.=0D
+ @param[in] Mpid Target MPID.=0D
+=0D
+ @retval TRUE MPID is present.=0D
+ @retval FALSE MPID is not present.=0D
+**/=0D
+STATIC=0D
+BOOLEAN=0D
+CheckIfMpidIsPresent (=0D
+ IN UINT64 *MpidList,=0D
+ IN UINT64 Count,=0D
+ IN UINT64 Mpid=0D
+ )=0D
+{=0D
+ UINT64 Idx;=0D
+=0D
+ for (Idx =3D 0; Idx < Count; Idx++) {=0D
+ if (MpidList[Idx] =3D=3D Mpid) {=0D
+ return TRUE;=0D
+ }=0D
+ }=0D
+=0D
+ return FALSE;=0D
+}=0D
+=0D
+/**=0D
+ Disables isolated CPUs in the MADT table=0D
+=0D
+ Parse the IsolatedCpuInfo from the Hob list and updates the MADT table t=
o=0D
+ disable cpu's which are not available on the platfrom.=0D
+=0D
+ @param[in] AcpiHeader Points to the Madt table.=0D
+ @param[in] HobData Points to the unusable cpuinfo in hoblist.=0D
+**/=0D
+STATIC=0D
+VOID=0D
+UpdateMadtTable (=0D
+ IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader,=0D
+ IN SGI_PLATFORM_DESCRIPTOR *HobData=0D
+ )=0D
+{=0D
+ UINT8 *StructureListHead;=0D
+ UINT8 *StructureListTail;=0D
+ EFI_ACPI_6_4_GIC_STRUCTURE *GicStructure;=0D
+ BOOLEAN MpidPresent;=0D
+=0D
+ if (HobData->IsolatedCpuList.Count =3D=3D 0) {=0D
+ return;=0D
+ }=0D
+=0D
+ StructureListHead =3D=0D
+ ((UINT8 *)AcpiHeader) +=0D
+ sizeof(EFI_ACPI_6_4_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);=0D
+ StructureListTail =3D (UINT8 *)AcpiHeader + AcpiHeader->Length;=0D
+=0D
+ // Locate ACPI GICC structure in the MADT table.=0D
+ while (StructureListHead < StructureListTail) {=0D
+ if (StructureListHead[0] =3D=3D EFI_ACPI_6_4_GIC) {=0D
+ GicStructure =3D (EFI_ACPI_6_4_GIC_STRUCTURE *)StructureListHead;=0D
+ // Disable the CPU if its MPID is present in the list.=0D
+ MpidPresent =3D CheckIfMpidIsPresent(=0D
+ HobData->IsolatedCpuList.Mpid,=0D
+ HobData->IsolatedCpuList.Count,=0D
+ GicStructure->MPIDR=0D
+ );=0D
+ if (MpidPresent =3D=3D TRUE) {=0D
+ DEBUG ((=0D
+ DEBUG_INFO,=0D
+ "Disabling Core: %lu, MPID: 0x%llx in MADT\n",=0D
+ GicStructure->AcpiProcessorUid,=0D
+ GicStructure->MPIDR=0D
+ ));=0D
+ GicStructure->Flags =3D 0;=0D
+ }=0D
+ }=0D
+=0D
+ // Second element in the structure component header is length=0D
+ StructureListHead +=3D StructureListHead[1];=0D
+ }=0D
+}=0D
+=0D
+/**=0D
+ Callback to validate and/or update ACPI table.=0D
+=0D
+ On finding a MADT table, disable the isolated CPUs in the MADT table. Th=
e=0D
+ list of isolated CPUs are obtained from the HOB data.=0D
+=0D
+ @param[in] AcpiHeader Target ACPI table.=0D
+=0D
+ @retval TURE Table validated/updated successfully.=0D
+ @retval FALSE Error in Table validation/updation.=0D
+**/=0D
+STATIC=0D
+BOOLEAN=0D
+CheckAndUpdateAcpiTable (=0D
+ IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader=0D
+ )=0D
+{=0D
+ VOID *SystemIdHob;=0D
+ SGI_PLATFORM_DESCRIPTOR *HobData;=0D
+=0D
+ // This check updates the MADT table to disable isolated CPUs present on=
the=0D
+ // platform.=0D
+ if (AcpiHeader->Signature =3D=3D EFI_ACPI_1_0_APIC_SIGNATURE) {=0D
+ SystemIdHob =3D GetFirstGuidHob (&gArmSgiPlatformIdDescriptorGuid);=0D
+ if (SystemIdHob !=3D NULL) {=0D
+ HobData =3D (SGI_PLATFORM_DESCRIPTOR *)GET_GUID_HOB_DATA (SystemIdHo=
b);=0D
+ UpdateMadtTable (AcpiHeader, HobData);=0D
+ }=0D
+ }=0D
+=0D
+ return TRUE;=0D
+}=0D
+=0D
EFI_STATUS=0D
EFIAPI=0D
ArmSgiPkgEntryPoint (=0D
@@ -25,7 +149,10 @@ ArmSgiPkgEntryPoint (
{=0D
EFI_STATUS Status;=0D
=0D
- Status =3D LocateAndInstallAcpiFromFv (&gArmSgiAcpiTablesGuid);=0D
+ Status =3D LocateAndInstallAcpiFromFvConditional (=0D
+ &gArmSgiAcpiTablesGuid,=0D
+ &CheckAndUpdateAcpiTable=0D
+ );=0D
if (EFI_ERROR (Status)) {=0D
DEBUG ((DEBUG_ERROR, "%a: Failed to install ACPI tables\n", __FUNCTION=
__));=0D
return Status;=0D
diff --git a/Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPeim.c b=
/Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPeim.c
index 7df52cc4fd7c..f778dc8ac7c1 100644
--- a/Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPeim.c
+++ b/Platform/ARM/SgiPkg/Library/SgiPlatformPei/SgiPlatformPeim.c
@@ -1,6 +1,6 @@
/** @file=0D
*=0D
-* Copyright (c) 2018, ARM Limited. All rights reserved.=0D
+* Copyright (c) 2018-2022, ARM Limited. All rights reserved.=0D
*=0D
* SPDX-License-Identifier: BSD-2-Clause-Patent=0D
*=0D
@@ -38,6 +38,8 @@ GetSgiSystemId (
CONST VOID *NtFwCfgDtBlob;=0D
SGI_NT_FW_CONFIG_INFO_PPI *NtFwConfigInfoPpi;=0D
EFI_STATUS Status;=0D
+ UINT64 IsolatedCpuCount;=0D
+ UINT64 CoreCount;=0D
=0D
Status =3D PeiServicesLocatePpi (&gNtFwConfigDtInfoPpiGuid, 0, NULL,=0D
(VOID**)&NtFwConfigInfoPpi);=0D
@@ -83,6 +85,32 @@ GetSgiSystemId (
HobData->MultiChipMode =3D fdt32_to_cpu (*Property);=0D
}=0D
=0D
+ Property =3D fdt_getprop (NtFwCfgDtBlob, Offset, "isolated-cpu-list", NU=
LL);=0D
+ if (Property =3D=3D NULL) {=0D
+ DEBUG ((DEBUG_INFO, "%s property not found\n", "isolated-cpu-list"));=
=0D
+ HobData->IsolatedCpuList.Count =3D 0;=0D
+ } else {=0D
+ CopyMem (&IsolatedCpuCount, Property, sizeof (IsolatedCpuCount));=0D
+ CoreCount =3D=0D
+ FixedPcdGet32 (PcdChipCount) *=0D
+ FixedPcdGet32 (PcdClusterCount) *=0D
+ FixedPcdGet32 (PcdCoreCount);=0D
+ if (IsolatedCpuCount > CoreCount) {=0D
+ DEBUG ((=0D
+ DEBUG_ERROR,=0D
+ "IsolatedCpuCount(%u) is higher than CoreCount(%u)\n",=0D
+ IsolatedCpuCount,=0D
+ CoreCount=0D
+ ));=0D
+ return EFI_SUCCESS;=0D
+ }=0D
+ CopyMem (=0D
+ &HobData->IsolatedCpuList,=0D
+ Property,=0D
+ sizeof(HobData->IsolatedCpuList) + (CoreCount * sizeof(UINT64))=0D
+ );=0D
+ }=0D
+=0D
return EFI_SUCCESS;=0D
}=0D
=0D
@@ -104,11 +132,24 @@ SgiPlatformPeim (
{=0D
SGI_PLATFORM_DESCRIPTOR *HobData;=0D
EFI_STATUS Status;=0D
+ UINT64 CoreCount;=0D
+ UINTN HobSize;=0D
=0D
+ CoreCount =3D=0D
+ FixedPcdGet32 (PcdChipCount) *=0D
+ FixedPcdGet32 (PcdClusterCount) *=0D
+ FixedPcdGet32 (PcdCoreCount);=0D
+=0D
+ // Additional size for SGI_ISOLATED_CPU_LIST.=0D
+ // Size =3D (MPID register size in bytes * CoreCount) +=0D
+ // sizeof(SGI_PLATFORM_DESCRIPTOR)=0D
+ HobSize =3D=0D
+ sizeof (SGI_PLATFORM_DESCRIPTOR) +=0D
+ (CoreCount * sizeof(UINT64));=0D
// Create platform descriptor HOB=0D
HobData =3D (SGI_PLATFORM_DESCRIPTOR *)BuildGuidHob (=0D
&gArmSgiPlatformIdDescriptorGuid,=
=0D
- sizeof (SGI_PLATFORM_DESCRIPTOR))=
;=0D
+ HobSize);=0D
=0D
// Get the system id from the platform specific nt_fw_config device tree=
=0D
if (HobData =3D=3D NULL) {=0D
--=20
2.25.1

Join devel@edk2.groups.io to automatically receive all group messages.