From nobody Mon Feb 9 01:16:15 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+68508+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+68508+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1607505868942752.3876787289811; Wed, 9 Dec 2020 01:24:28 -0800 (PST) Return-Path: X-Received: by 127.0.0.2 with SMTP id apEQYY1788612xvNrYwAy49E; Wed, 09 Dec 2020 01:24:28 -0800 X-Received: from NAM11-CO1-obe.outbound.protection.outlook.com (NAM11-CO1-obe.outbound.protection.outlook.com [40.107.220.110]) by mx.groups.io with SMTP id smtpd.web08.4052.1607505866843263792 for ; Wed, 09 Dec 2020 01:24:27 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=COb4PgF0tJtpw7FAyG5GpbIaJOGwBe0BgbV2JjxHaU4TW9iPpk+V1iAZ96dCWXI8OxMXcoKCB/zVSp6urFCW2sKbbOBdTbD6oOMGLqOVy+FgLE9newycoyHTEyZWSrZo4PHcT7ZhZQ4Ozd2CZKMHhzN9zYCsXOvmfgNT17eCUWOeXT+JYqgFyC+c5EqNMc8hMvBb/qGZlC/U1TZhQbe4Oedz8jdXT6qnDRHQwDWDrG3mpdF7JaUl/n/0d8WLOwqDECuD9qKK8JHzw7lWyyG89unyJ4VstknKsRzGdBvQOuIBS5e3j8SuNKLjJW2SKoSr5uNkzdcguAs4t+PWJvRTfQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=MJ7eG/g1Paq7WIxV6ZacWXnU1hTRVE4Chmth4m2lqCk=; b=NkAZQXHEQF0J6pHwNmbKjaB84XprxLEEeeY00ic8aQmNlwvYfYJENRy48qcAMHtcO0JKNqccUcanH2c6TO0T9SQOSithK45hnuQ3qI7nMhT0tvfkfP5bUuUs8Gi0a1eu3eGWorfuB9J3oRRowaM7V/+KFOdXgH4HEBBmok+OgjIP2CP0pOJFVcQQ/xf5ANDkgMuVN2hAQg10MvuTWU4RkTFdF+GNQs5ZttyuRw9SNNsygbSIH1XTYhz6lmJ6roXVCgy45AFryw2qN7yViTbQS/RRj118AA/ogfAk1ZRAMx4oPfbUZ8kXFjo45Rm0whbZmIzn/YkiWU8VOu1cuQ4e2w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=os.amperecomputing.com; dmarc=pass action=none header.from=os.amperecomputing.com; dkim=pass header.d=os.amperecomputing.com; arc=none X-Received: from DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) by DM6PR01MB5609.prod.exchangelabs.com (2603:10b6:5:157::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3632.21; Wed, 9 Dec 2020 09:24:24 +0000 X-Received: from DM6PR01MB5849.prod.exchangelabs.com ([fe80::c814:9a08:5c2e:4076]) by DM6PR01MB5849.prod.exchangelabs.com ([fe80::c814:9a08:5c2e:4076%5]) with mapi id 15.20.3632.023; Wed, 9 Dec 2020 09:24:24 +0000 From: "Nhi Pham via groups.io" To: devel@edk2.groups.io Cc: Nhi Pham Subject: [edk2-devel] [edk2-platforms][PATCH 09/34] JadePkg: Install some ACPI tables at runtime Date: Wed, 9 Dec 2020 16:25:06 +0700 Message-Id: <20201209092531.30867-10-nhi@os.amperecomputing.com> In-Reply-To: <20201209092531.30867-1-nhi@os.amperecomputing.com> References: <20201209092531.30867-1-nhi@os.amperecomputing.com> X-Originating-IP: [118.69.219.201] X-ClientProxiedBy: HK0PR01CA0054.apcprd01.prod.exchangelabs.com (2603:1096:203:a6::18) To DM6PR01MB5849.prod.exchangelabs.com (2603:10b6:5:205::20) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-Received: from sw004.amperecomputing.com (118.69.219.201) by HK0PR01CA0054.apcprd01.prod.exchangelabs.com (2603:1096:203:a6::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.12 via Frontend Transport; Wed, 9 Dec 2020 09:24:23 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 1638da46-cf3f-4c49-e3e9-08d89c243822 X-MS-TrafficTypeDiagnostic: DM6PR01MB5609: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5516; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Message-Info: qwO9NrnwqJX+cJCx8jpkg1yghzFjSlFvBV3SYhF3ctMt7gJdRJgBPjkv2sPj5hSxOwGp6fHIC70zKVrHg7Kr1WiPoDIMBEEtPcU6OKvSSg46x0qxHWJAatTo0dlcsBPt9X50s2vZRiSopg1mZj4y06Rvge2We19CWAQjgnoou58RRPSa5ioGvmcVkTP61UdnjgZh6YvLnNUUDX9nUC8L6fVQupjmGLt6geJXxZxqMiDtCQxPqPMZDRp3PHydKFHvjQmiatC6gYBwWSJZpfktpmz347D0gkT+peRYml6fhdQnSscH2Atx1KlA2E+sNxO9DlHJXzdOhl1dYw7zoxMoMgahWjNFqNvCQvK6pQuViByGCZp9GtO+ReD52TqzFdXg54wl2L09hQXVQnlJqMNbPA== X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?QaPtPt26UZeAdP42S1SZViyYKOqs5FUEcE1tmz2/Gm7cCaT8+6NaFI5T1hnv?= =?us-ascii?Q?2kqs+xZ/pGaDlLTEHJdJumw2SRILdqgOkw4rpyEt07um3aVPx+B9fDA0mXjS?= =?us-ascii?Q?wGfLT8FfJisrOwpzaI0iEFb9NZmnYV/mHxRuh6uyCGca13h8YYapzjp1xnRY?= =?us-ascii?Q?Q8fOKpJTn6IyHfdiSaEioNBSaCpPAoBafXzrO+0GlLHHWEYXmxyc0EOGChV/?= =?us-ascii?Q?4nnZkgF3YKWVlDYsH2WSr28P09Fg5MV0dPw84F+7BBTIH+/etqYol4BGJBV6?= =?us-ascii?Q?iq7h15NCJ832nB0tCeqiDE4V8jfFSnkR7xRfWL0eW1G3L4QJKJTCfydb/hLN?= =?us-ascii?Q?zluJYDA3ukT/cBtBF6Wod9UPD9TrsQ8Bdwr2jcFXVkddQ40OJJt5QnUAKfR/?= =?us-ascii?Q?V5EPkIFXIT3s9RyqSRfuIVeXXoPaff6lLvyMUbgTHfJZwaeTvPVhiAjeuGKm?= =?us-ascii?Q?Qt5iclWED6HUAoh2Jy2nUb3yW4BVjx1fAMzAnws+GlqkNwd+b1DI9ptVNBAI?= =?us-ascii?Q?hMEUyAW+i7d2bNiW8bQRbAuWWZPmPPGJE3wW+pOhAvRVL6EXN544dPS8dz1F?= =?us-ascii?Q?FSFXh2vVhkIuwL4JygVuyoduPC5+a+Y+1QWwz5pi1rKYrl+19mc8zh3KRi6T?= =?us-ascii?Q?1g+Jn0w8PJ6IrlgDsIthrOG1kUXlqgw2KW/f/zq6JgxhkwsX9vvil2/7uQgk?= =?us-ascii?Q?2vEf82de0jx9YwfDl4lNh7DykOuJLRgZemvkog/ocvIZAf7lFr5EzDkhCVjL?= =?us-ascii?Q?BQ2IIN3A5q4KpQYBTrsjEtx5gnzCLjBxadGYbjhqcFlYu/nrPVEnkd9F2Lu3?= =?us-ascii?Q?GIjie80ZWRLJ6IjsrsZoB+znK926PoD8tycSPwE/0wLx4vsMapQS/zqpCQSF?= =?us-ascii?Q?oyzu9qdBaikLVC3Gp1N2Z04YYjTaWT9bd9d+MqPFZarkCEo3Pubea08dk2lH?= =?us-ascii?Q?akpv0CUq0B4Ph0YE4EpVVM5boUHbUO4+Gp2LWRMJoFcKBPy2M9tKH9OWWzPn?= =?us-ascii?Q?d+Ej?= X-OriginatorOrg: os.amperecomputing.com X-MS-Exchange-CrossTenant-AuthSource: DM6PR01MB5849.prod.exchangelabs.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Dec 2020 09:24:24.6512 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3bc2b170-fd94-476d-b0ce-4229bdc904a7 X-MS-Exchange-CrossTenant-Network-Message-Id: 1638da46-cf3f-4c49-e3e9-08d89c243822 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 8bj3VRctzEMmhd2mxMo6NuI8fPM7oLi/WWPfZvUJzWjZTbRhFpDLMdAipdMqpBxjKtvYtHBe3HNW0a9g5lsRHojm1taNHuRdsMidKhXHN7Q= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR01MB5609 Precedence: Bulk List-Unsubscribe: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,nhi@os.amperecomputing.com X-Gm-Message-State: WyCNyf6kKRYlBTlBbc6O4NFux1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1607505868; bh=0n8p/pfcETOQscZz+sIgg5jWv67JuchdbxE6JFWj1PQ=; h=Cc:Content-Type:Date:From:Reply-To:Subject:To; b=cQ6lws9CtMlIgEGC5bNfs25W8gbM8CEQfhEoTDaNRFntLNRghBtDK/78OkID8RjZ84e r47hQIzThzDF7NwEqwJtGTxQ1hWkEqsmfNE+//tU6YSZxby8p1Lrvp9v8uhePvYSkY3Cw K2JqGyHTAiia6hzvXZ0pp6zsjp9iBJZ4s0o= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This supports to create MADT, PPTT, PCCT, SLIT, SRAT, NFIT tables at runtime. It also updates DSDT table based on the system information. Signed-off-by: Nhi Pham --- Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf | 22 = ++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h | 48 = +++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c | 221 = ++++++++++++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMADT.c | 372 = ++++++++++++++++++++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c | 268 = ++++++++++++++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPCCT.c | 264 = ++++++++++++++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPPTT.c | 338 = ++++++++++++++++++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c | 84 = +++++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSLIT.c | 85 = +++++ Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSRAT.c | 268 = ++++++++++++++ 10 files changed, 1970 insertions(+) diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDx= e.inf b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf index 1ec8602aede5..d9caca9438de 100644 --- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -15,6 +15,13 @@ [Defines] ENTRY_POINT =3D AcpiPlatformDxeInitialize =20 [Sources.common] + AcpiDsdt.c + AcpiMADT.c + AcpiNfit.c + AcpiPCCT.c + AcpiPPTT.c + AcpiSLIT.c + AcpiSRAT.c AcpiPlatform.h AcpiPlatformDxe.c =20 @@ -35,10 +42,25 @@ [LibraryClasses] BaseLib UefiLib AcpiLib + AcpiPccLib + AcpiHelperLib + AmpereCpuLib + +[Pcd] + gArmPlatformTokenSpaceGuid.PcdCoreCount + gArmPlatformTokenSpaceGuid.PcdClusterCount + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision + gAmpereTokenSpaceGuid.PcdPmproDbBaseReg + gAmpereTokenSpaceGuid.PcdSmproDbBaseReg =20 [Guids] gArmMpCoreInfoGuid gEfiAcpiTableGuid + gEfiEventReadyToBootGuid =20 [Protocols] gEfiAcpiTableProtocolGuid ## ALWAYS_CONSUMED diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h= b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h index 60b2ed22d05b..ba5d704a3fc0 100644 --- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h @@ -22,5 +22,53 @@ #include #include #include +#include +#include + +#include +#include +#include +#include +#include + +EFI_STATUS +AcpiPatchDsdtTable ( + VOID + ); + +EFI_STATUS +AcpiInstallMadtTable ( + VOID + ); + +EFI_STATUS +AcpiInstallNfitTable ( + VOID + ); + +EFI_STATUS +AcpiPcctInit ( + VOID + ); + +EFI_STATUS +AcpiInstallPcctTable ( + VOID + ); + +EFI_STATUS +AcpiInstallPpttTable ( + VOID + ); + +EFI_STATUS +AcpiInstallSlitTable ( + VOID + ); + +EFI_STATUS +AcpiInstallSratTable ( + VOID + ); =20 #endif /* _ACPI_PLATFORM_H_ */ diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c b/P= latform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c new file mode 100755 index 000000000000..7d4501311a9f --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c @@ -0,0 +1,221 @@ +/** @file + + Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "AcpiPlatform.h" + +#define SUBNUMA_MODE_MONOLITHIC 0 +#define SUBNUMA_MODE_HEMISPHERE 1 +#define SUBNUMA_MODE_QUADRANT 2 + +STATIC VOID +AcpiPatchCmn600 (VOID) +{ + CHAR8 NodePath[MAX_ACPI_NODE_PATH]; + UINTN Index; + + for (Index =3D 0; Index < GetNumberSupportedSockets (); Index++) { + AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.CMN%1X._STA", Index); + if (GetNumberActiveCPMsPerSocket (Index)) { + AcpiDSDTSetNodeStatusValue (NodePath, 0xf); + } else { + AcpiDSDTSetNodeStatusValue (NodePath, 0x0); + } + } +} + +STATIC VOID +AcpiPatchDmc620 (VOID) +{ + CHAR8 NodePath[MAX_ACPI_NODE_PATH]; + UINTN Index, Index1; + EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V2; + PlatformInfoHob_V2 *PlatformHob; + UINT32 McuMask; + VOID *Hob; + + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return; + } + + PlatformHob =3D (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob); + + for (Index =3D 0; Index < GetNumberSupportedSockets (); Index++) { + McuMask =3D PlatformHob->DramInfo.McuMask[Index]; + for (Index1 =3D 0; Index1 < sizeof (McuMask) * 8; Index1++) { + AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.MC%1X%1X._STA", Ind= ex, Index1); + if (McuMask & (0x1 << Index1)) { + AcpiDSDTSetNodeStatusValue (NodePath, 0xf); + } else { + AcpiDSDTSetNodeStatusValue (NodePath, 0x0); + } + } + } +} + +STATIC VOID +AcpiPatchNvdimm (VOID) +{ + CHAR8 NodePath[MAX_ACPI_NODE_PATH]; + UINTN NvdRegionNum, Count; + EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V2; + PlatformInfoHob_V2 *PlatformHob; + VOID *Hob; + + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return; + } + + PlatformHob =3D (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob); + + NvdRegionNum =3D 0; + for (Count =3D 0; Count < PlatformHob->DramInfo.NumRegion; Count++) { + if (PlatformHob->DramInfo.NvdRegion[Count]) { + NvdRegionNum +=3D 1; + } + } + + if (NvdRegionNum =3D=3D PLATFORM_MAX_NUM_NVDIMM_DEVICE) { + return; + } + + /* Disable NVDIMM Root Device */ + if (NvdRegionNum =3D=3D 0) { + AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR._STA"); + AcpiDSDTSetNodeStatusValue (NodePath, 0x0); + } + + /* Disable NVDIMM Device which is not available */ + Count =3D NvdRegionNum + 1; + while (Count <=3D PLATFORM_MAX_NUM_NVDIMM_DEVICE) { + AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD%1X._STA", Co= unt); + AcpiDSDTSetNodeStatusValue (NodePath, 0x0); + Count++; + } +} + +STATIC VOID +AcpiPatchHwmon (VOID) +{ + CHAR8 NodePath[MAX_ACPI_NODE_PATH]; + UINTN Index; + + // PCC Hardware Monitor Devices + for (Index =3D 0; Index < GetNumberSupportedSockets (); Index++) { + AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.HM0%1X._STA", Index); + if (GetNumberActiveCPMsPerSocket (Index)) { + AcpiDSDTSetNodeStatusValue (NodePath, 0xf); + } else { + AcpiDSDTSetNodeStatusValue (NodePath, 0x0); + } + } + + // Ampere Altra SoC Hardware Monitor Devices + for (Index =3D 0; Index < GetNumberSupportedSockets (); Index++) { + AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.HM0%1X._STA", Index += 2); + if (GetNumberActiveCPMsPerSocket (Index)) { + AcpiDSDTSetNodeStatusValue (NodePath, 0xf); + } else { + AcpiDSDTSetNodeStatusValue (NodePath, 0x0); + } + } +} + +STATIC VOID +AcpiPatchDsu (VOID) +{ + CHAR8 NodePath[MAX_ACPI_NODE_PATH]; + UINTN Index; + + for (Index =3D 0; Index < PLATFORM_CPU_MAX_NUM_CORES; Index +=3D PLATFOR= M_CPU_NUM_CORES_PER_CPM) { + AsciiSPrint (NodePath, sizeof(NodePath), "\\_SB.DU%2X._STA", Index / P= LATFORM_CPU_NUM_CORES_PER_CPM); + if (IsCpuEnabled (Index)) { + AcpiDSDTSetNodeStatusValue (NodePath, 0xf); + } else { + AcpiDSDTSetNodeStatusValue (NodePath, 0x0); + } + } +} + +STATIC UINT8 +PcieGetSubNumaMode ( + VOID + ) +{ + EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V= 2; + PlatformInfoHob_V2 *PlatformHob; + VOID *Hob; + + /* Get the Platform HOB */ + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return SUBNUMA_MODE_MONOLITHIC; + } + PlatformHob =3D (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob); + + return PlatformHob->SubNumaMode[0]; +} + +VOID +AcpiPatchPcieNuma ( + VOID + ) +{ + CHAR8 NodePath[MAX_ACPI_NODE_PATH]; + UINTN Index; + UINTN NumaIdx; + UINTN NumPciePort; + UINTN NumaAssignment[3][16] =3D { + { 0, 0, 0, 0, 0, 0, 0, 0, // Monolitic Node 0 (S0) + 1, 1, 1, 1, 1, 1, 1, 1 }, // Monolitic Node 1 (S1) + { 0, 1, 0, 1, 0, 0, 1, 1, // Hemisphere Node 0, 1 (S0) + 2, 3, 2, 3, 2, 2, 3, 3 }, // Hemisphere Node 2, 3 (S1) + { 0, 2, 1, 3, 1, 1, 3, 3, // Quadrant Node 0, 1, 2, 3 (S0) + 4, 6, 5, 7, 5, 5, 7, 7 }, // Quadrant Node 4, 5, 6, 7 (S1) + }; + + switch (PcieGetSubNumaMode ()) { + case SUBNUMA_MODE_MONOLITHIC: + NumaIdx =3D 0; + break; + case SUBNUMA_MODE_HEMISPHERE: + NumaIdx =3D 1; + break; + case SUBNUMA_MODE_QUADRANT: + NumaIdx =3D 2; + break; + default: + NumaIdx =3D 0; + break; + } + + if (GetNumberActiveSockets () > 1) { + NumPciePort =3D 16; // 16 ports total (8 per socket) + } else { + NumPciePort =3D 8; // 8 ports total + } + + for (Index =3D 0; Index < NumPciePort; Index++) { + AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.PCI%X._PXM", Index); + AcpiDSDTSetNodeStatusValue (NodePath, NumaAssignment[NumaIdx][Index]); + } +} + +EFI_STATUS +AcpiPatchDsdtTable (VOID) +{ + AcpiPatchCmn600 (); + AcpiPatchDmc620 (); + AcpiPatchDsu (); + AcpiPatchHwmon (); + AcpiPatchNvdimm (); + AcpiPatchPcieNuma (); + + return EFI_SUCCESS; +} diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMADT.c b/P= latform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMADT.c new file mode 100755 index 000000000000..fc34801fa340 --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMADT.c @@ -0,0 +1,372 @@ +/** @file + + Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "AcpiPlatform.h" + +EFI_ACPI_6_3_GIC_ITS_STRUCTURE GicItsTemplate =3D { + EFI_ACPI_6_3_GIC_ITS, + sizeof (EFI_ACPI_6_3_GIC_ITS_STRUCTURE), + EFI_ACPI_RESERVED_WORD, + 0, /* GicItsId */ + 0, /* PhysicalBaseAddress */ + 0, /* Reserved2 */ +}; + +EFI_ACPI_6_3_GICR_STRUCTURE GicRTemplate =3D { + EFI_ACPI_6_3_GICR, + sizeof (EFI_ACPI_6_3_GICR_STRUCTURE), + EFI_ACPI_RESERVED_WORD, + GICR_MASTER_BASE_REG, /* DiscoveryRangeBaseAddress */ + 0x1000000, /* DiscoveryRangeLength */ +}; + +EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE GicDTemplate =3D { + EFI_ACPI_6_3_GICD, + sizeof (EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE), + EFI_ACPI_RESERVED_WORD, + 0, /* GicDistHwId */ + GICD_BASE_REG, /* GicDistBase */ + 0, /* GicDistVector */ + 0x3, /* GicVersion */ + {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE} +}; + +EFI_ACPI_6_3_GIC_STRUCTURE GiccTemplate =3D { + EFI_ACPI_6_3_GIC, + sizeof (EFI_ACPI_6_3_GIC_STRUCTURE), + EFI_ACPI_RESERVED_WORD, + 0, /* GicId */ + 0, /* AcpiCpuUid */ + 0, /* Flags */ + 0, + 23, /* PmuIrq */ + 0, + 0, + 0, + 0, + 25, /* GsivId */ + 0, /* GicRBase */ + 0, /* Mpidr */ + 0, /* ProcessorPowerEfficiencyClass */ + 0, /* Reserved2 */ + 21, /* SPE irq */ +}; + +EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MADTTableHeaderTemplat= e =3D { + __ACPI_HEADER ( + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, + 0, /* need fill in */ + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION + ), +}; + +UINT32 Ac01CoreOrderMonolithic[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_COR= ES_PER_CPM] =3D { + 36, 52, 40, 56, 32, 48, 44, 60, + 20, 68, 24, 72, 16, 64, 28, 76, + 4, 8, 0, 12, 38, 54, 42, 58, + 34, 50, 46, 62, 22, 70, 26, 74, + 18, 66, 30, 78, 6, 10, 2, 14, + 37, 53, 41, 57, 33, 49, 45, 61, + 21, 69, 25, 73, 17, 65, 29, 77, + 5, 9, 1, 13, 39, 55, 43, 59, + 35, 51, 47, 63, 23, 71, 27, 75, + 19, 67, 31, 79, 7, 11, 3, 15, +}; + +UINT32 Ac01CoreOrderHemisphere[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_COR= ES_PER_CPM] =3D { + 32, 48, 16, 64, 36, 52, 0, 20, + 68, 4, 34, 50, 18, 66, 38, 54, + 2, 22, 70, 6, 33, 49, 17, 65, + 37, 53, 1, 21, 69, 5, 35, 51, + 19, 67, 39, 55, 3, 23, 71, 7, + 44, 60, 28, 76, 40, 56, 12, 24, + 72, 8, 46, 62, 30, 78, 42, 58, + 14, 26, 74, 10, 45, 61, 29, 77, + 41, 57, 13, 25, 73, 9, 47, 63, + 31, 79, 43, 59, 15, 27, 75, 11, +}; + +UINT32 Ac01CoreOrderQuadrant[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES= _PER_CPM] =3D { + 16, 32, 0, 20, 4, 18, 34, 2, + 22, 6, 17, 33, 1, 21, 5, 19, + 35, 3, 23, 7, 48, 64, 52, 68, + 36, 50, 66, 54, 70, 38, 49, 65, + 53, 69, 37, 51, 67, 55, 71, 39, + 28, 44, 12, 24, 8, 30, 46, 14, + 26, 10, 29, 45, 13, 25, 9, 31, + 47, 15, 27, 11, 60, 76, 56, 72, + 40, 62, 78, 58, 74, 42, 61, 77, + 57, 73, 41, 63, 79, 59, 75, 43, +}; + +EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtTablePointer; + +STATIC UINT32 * +CPUGetCoreOrder (VOID) +{ + EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V= 2; + PlatformInfoHob_V2 *PlatformHob; + VOID *Hob; + UINT32 SubNumaMode; + UINT8 Ac01Chip =3D 1; + + /* Get the Platform HOB */ + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return SUBNUMA_MODE_MONOLITHIC; + } + PlatformHob =3D (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob); + Ac01Chip =3D ((PlatformHob->ScuProductId[0] & 0xFF) =3D=3D 0x1) ? 1 : 0; + + SubNumaMode =3D CPUGetSubNumaMode(); + switch (SubNumaMode) { + case SUBNUMA_MODE_MONOLITHIC: + if (Ac01Chip !=3D 0) { + return (UINT32 *) &Ac01CoreOrderMonolithic; + } + case SUBNUMA_MODE_HEMISPHERE: + if (Ac01Chip !=3D 0) { + return (UINT32 *) &Ac01CoreOrderHemisphere; + } + return (UINT32 *) &Ac01CoreOrderHemisphere; + case SUBNUMA_MODE_QUADRANT: + if (Ac01Chip !=3D 0) { + return (UINT32 *) &Ac01CoreOrderQuadrant; + } + } + + if (Ac01Chip !=3D 0) { + return (UINT32 *) &Ac01CoreOrderMonolithic; + } + + return NULL; +} + +STATIC UINT32 +AcpiInstallMadtProcessorNode ( + VOID *EntryPointer, + UINT32 CpuId + ) +{ + EFI_ACPI_6_3_GIC_STRUCTURE *MadtProcessorEntryPointer =3D EntryPointer; + UINT32 SocketId; + UINT32 ClusterId; + UINTN Size; + + Size =3D sizeof (GiccTemplate); + CopyMem (MadtProcessorEntryPointer, &GiccTemplate, Size); + + SocketId =3D CpuId / (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_= CPM); + ClusterId =3D CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM; + if (SocketId =3D=3D 1) { + ClusterId -=3D PLATFORM_CPU_MAX_CPM; + } + + MadtProcessorEntryPointer->CPUInterfaceNumber =3D CpuId; + MadtProcessorEntryPointer->AcpiProcessorUid =3D + (SocketId << PLATFORM_SOCKET_UID_BIT_OFFSET) + + (ClusterId << 8) + (CpuId % PLATFORM_CPU_NUM_CORES_PER_CPM); + MadtProcessorEntryPointer->Flags =3D 1; + MadtProcessorEntryPointer->MPIDR =3D + (((ClusterId << 8) + (CpuId % PLATFORM_CPU_NUM_CORES_PER_CPM)) << 8) ; + MadtProcessorEntryPointer->MPIDR +=3D (((UINT64) SocketId) << 32); + + return Size; +} + +STATIC UINT32 +AcpiInstallMadtGicD ( + VOID *EntryPointer + ) +{ + EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE *GicDEntryPointer =3D EntryPointe= r; + UINTN Size; + + Size =3D sizeof (GicDTemplate); + CopyMem (GicDEntryPointer, &GicDTemplate, Size); + + return Size; +} + +STATIC UINT32 +AcpiInstallMadtGicR ( + VOID *EntryPointer, + UINT32 SocketId + ) +{ + EFI_ACPI_6_3_GICR_STRUCTURE *GicREntryPointer =3D EntryPointer; + UINTN Size; + + /* + * If the Slave socket is not present, discard the Slave socket + * GIC redistributor region + */ + if ((SocketId =3D=3D 1) && (GetNumberActiveCPMsPerSocket (SocketId) =3D= =3D 0)) { + return 0; + } + + Size =3D sizeof (GicRTemplate); + CopyMem (GicREntryPointer, &GicRTemplate, Size); + + if (SocketId =3D=3D 1) { + GicREntryPointer->DiscoveryRangeBaseAddress =3D GICR_SLAVE_BASE_REG; + } + + return Size; +} + +STATIC UINT32 +AcpiInstallMadtGicIts ( + VOID *EntryPointer, + UINT32 Index + ) +{ + EFI_ACPI_6_3_GIC_ITS_STRUCTURE *GicItsEntryPointer =3D EntryPointer; + UINTN Size, Offset; + UINT64 GicBase =3D GICD_BASE_REG; + UINT32 ItsId =3D Index; + + if (Index > SOCKET0_LAST_RC) { /* Socket 1, Index: 8-15 */ + GicBase =3D GICD_SLAVE_BASE_REG; + Index -=3D (SOCKET0_LAST_RC + 1); /* Socket 1, Index:8 -> RCA0 */ + } + Size =3D sizeof(GicItsTemplate); + CopyMem (GicItsEntryPointer, &GicItsTemplate, Size); + Offset =3D 0x40000 + Index * 0x20000; + GicItsEntryPointer->GicItsId =3D ItsId; + GicItsEntryPointer->PhysicalBaseAddress =3D Offset + GicBase; + + return Size; +} + +/* + * Install MADT table. + */ +EFI_STATUS +AcpiInstallMadtTable (VOID) +{ + EFI_ACPI_6_3_GIC_STRUCTURE *GiccEntryPointer =3D NULL; + EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; + UINTN MadtTableKey =3D 0; + INTN Count, Index; + EFI_STATUS Status; + UINTN Size; + UINT32 *CoreOrder; + UINT32 SktMaxCoreNum; + + if (IsAcpiInstalled (EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNAT= URE)) { + DEBUG ((DEBUG_INFO, "APIC table is already installed. Skipping...\n")= ); + return EFI_ABORTED; + } + + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, + NULL, (VOID **) &AcpiTableProtocol); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Count =3D 0; Count < gST->NumberOfTableEntries; Count++) { + if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Count]= .VendorGuid))) { + Size =3D sizeof(MADTTableHeaderTemplate) + + (PLATFORM_CPU_MAX_NUM_CORES * sizeof (GiccTemplate)) + + sizeof (GicDTemplate) + + (PLATFORM_CPU_MAX_SOCKET * sizeof (GicRTemplate)) + + ((SOCKET0_LAST_RC - SOCKET0_FIRST_RC + 1) * sizeof (GicItsTe= mplate)); + if (GetNumberActiveSockets () > 1) { + Size +=3D ((SOCKET1_LAST_RC - SOCKET1_FIRST_RC + 1) * sizeof (Gic= ItsTemplate)); + } else if (!PlatSlaveSocketPresent ()) { + Size +=3D 2 * sizeof(GicItsTemplate); /* RCA0/1 */ + } + + MadtTablePointer =3D + (EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *) AllocateZe= roPool(Size); + if (MadtTablePointer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + GiccEntryPointer =3D + (EFI_ACPI_6_3_GIC_STRUCTURE *) ((UINT64) MadtTablePointer + + sizeof (MADTTableHeaderTemplate)); + + /* Install Gic interface for each processor */ + Size =3D 0; + CoreOrder =3D CPUGetCoreOrder (); + ASSERT (CoreOrder !=3D NULL); + SktMaxCoreNum =3D PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_= CPM; + for (Index =3D 0; Index < SktMaxCoreNum; Index++) { + if (IsCpuEnabled (CoreOrder[Index])) { + Size +=3D AcpiInstallMadtProcessorNode ((VOID *) ((UINT64) GiccE= ntryPointer + Size), CoreOrder[Index]); + } + } + + for (Index =3D 0; Index < SktMaxCoreNum; Index++) { + if (IsCpuEnabled (CoreOrder[Index] + SktMaxCoreNum)) { + Size +=3D AcpiInstallMadtProcessorNode ((VOID *) ((UINT64) GiccE= ntryPointer + Size), CoreOrder[Index] + SktMaxCoreNum); + } + } + + /* Install Gic Distributor */ + Size +=3D AcpiInstallMadtGicD ((VOID *) ((UINT64) GiccEntryPointer += Size)); + + /* Install Gic Redistributor */ + for (Index =3D 0; Index < PLATFORM_CPU_MAX_SOCKET; Index++) { + Size +=3D AcpiInstallMadtGicR ((VOID *) ((UINT64) GiccEntryPointer= + Size), Index); + } + + /* Install Gic ITS */ + if (!PlatSlaveSocketPresent ()) { + for (Index =3D 0; Index <=3D 1; Index++) { /* RCA0/1 */ + Size +=3D AcpiInstallMadtGicIts ((VOID *) ((UINT64) GiccEntryPoi= nter + Size), Index); + } + } + for (Index =3D SOCKET0_FIRST_RC; Index <=3D SOCKET0_LAST_RC; Index++= ) { + Size +=3D AcpiInstallMadtGicIts ((VOID *) ((UINT64) GiccEntryPoint= er + Size), Index); + } + if (GetNumberActiveSockets () > 1) { + for (Index =3D SOCKET1_FIRST_RC; Index <=3D SOCKET1_LAST_RC; Index= ++) { + Size +=3D AcpiInstallMadtGicIts ((VOID *) ((UINT64) GiccEntryPoi= nter + Size), Index); + } + } + CopyMem (MadtTablePointer, &MADTTableHeaderTemplate, + sizeof (MADTTableHeaderTemplate)); + + Size +=3D sizeof (MADTTableHeaderTemplate); + MadtTablePointer->Header.Length =3D Size; + CopyMem ( + MadtTablePointer->Header.OemId, + PcdGetPtr (PcdAcpiDefaultOemId), + sizeof (MadtTablePointer->Header.OemId) + ); + MadtTablePointer->Header.OemTableId =3D EFI_ACPI_OEM_TABLE_ID; + MadtTablePointer->Header.OemRevision =3D 3; + MadtTablePointer->Header.CreatorId =3D EFI_ACPI_CREATOR_ID; + MadtTablePointer->Header.CreatorRevision =3D EFI_ACPI_CREATOR_REVISI= ON; + + AcpiTableChecksum ((UINT8 *) MadtTablePointer, + MadtTablePointer->Header.Length); + + Status =3D AcpiTableProtocol->InstallAcpiTable ( + AcpiTableProtocol, + (VOID *) MadtTablePointer, + MadtTablePointer->Header.Length, + &MadtTableKey + ); + FreePool ((VOID *) MadtTablePointer); + if (EFI_ERROR (Status)) { + return Status; + } + break; + } + } + + if (Count =3D=3D gST->NumberOfTableEntries) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c b/P= latform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c new file mode 100644 index 000000000000..fb22deef0aec --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c @@ -0,0 +1,268 @@ +/** @file + + Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "AcpiPlatform.h" + +EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE NfitSPATemplate = =3D { + EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE, + sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE), + 0, // The uniue index - need to be filled. + 0, // The flags - need to be filled. + 0, // Reserved. + 0, // Proximity domain - need to be filled. + EFI_ACPI_6_3_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION, // PM = range type. + 0, // Start address - need to be filled. + 0, // Size - need to be filled. + EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMO= RY_WP | EFI_MEMORY_UCE, // attribute - need to be filled. +}; + +EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE NvdimmControlRegionTempl= ate =3D { + EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE, + sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE), + 0, // The unique index - need to be filled. + 0x1122, // The vendor id - dummy value. + 0x3344, // The device id - dummy value. + 0, // The revision - dummy value. + 0x5566, // The subsystem nvdimm id - dummy value. + 0x7788, // The subsystem nvdimm device id - dummy value. + 0x0, // The subsystem revision - dummy value. + 0, // The valid field. + 0, // The manufacturing location - not valid. + 0, // The manufacturing date - not valid. + {0}, // Reserved. + 0xaabbccdd, // The serial number - dummy value. + 0, // The region format interface code - dummy value. + 0, // The number of block control windows. + 0, // The size of block control windows. + 0, // The Command Register Offset in Block Control Window. + 0, // The Size of Command Register in Block Control Windows. + 0, // The Status Register Offset in Block Control Window. + 0, // Size of Status Register in Block Control Windows. + 0, // The NVDIMM Control Region Flag. + {0}, // Reserved. +}; + +EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE NvdimmRegionMappingTempl= ate =3D { + EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE_TYPE, + sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE), + {0}, // _ADR of the NVDIMM device - need to be filled. + 0, // Dimm smbios handle index - need to be filled. + 0, // The unique region index - need to be filled. + 0, // The SPA range index - need to be filled. + 0, // The control region index - need to be filled. + 0, // The region size - need to be filled. + 0, // The region offset - need to be filled. + 0, // The region base - need to be filled. + 0, // The interleave structure index - need to be filled. + 0, // The interleave ways - need to be filled. + 0, // NVDIMM flags - need to be filled. + 0, // Reserved. +}; + +EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE NFITTableHeaderTemplate =3D { + __ACPI_HEADER ( + EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE, + 0, /* need fill in */ + EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION + ), + 0x00000000, // Reserved +}; + +/* + * Count NVDIMM Region + */ +EFI_STATUS +AcpiGetNvdRegionNumber ( + IN OUT UINTN *NvdRegionNum + ) +{ + CONST EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V2; + PlatformInfoHob_V2 *PlatformHob; + UINTN Count; + VOID *Hob; + + /* Get the Platform HOB */ + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + PlatformHob =3D (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob); + + *NvdRegionNum =3D 0; + for (Count =3D 0; Count < PlatformHob->DramInfo.NumRegion; Count++) { + if (PlatformHob->DramInfo.NvdRegion[Count]) { + *NvdRegionNum +=3D 1; + } + } + + if (*NvdRegionNum =3D=3D 0) { + DEBUG ((DEBUG_INFO, "No NVDIMM Region\n")); + return EFI_INVALID_PARAMETER; /* No NVDIMM Region */ + } + + return EFI_SUCCESS; +} + +/* + * Fill in SPA strucutre + */ +VOID +AcpiNfitFillSPA ( + IN OUT EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSp= aPointer, + IN UINTN NvdRegionIndex, + IN UINT64 NvdRegionBase, + IN UINT64 NvdRegionSize + ) +{ + NfitSpaPointer->Flags =3D 0; + NfitSpaPointer->SPARangeStructureIndex =3D NvdRegionIndex; + NfitSpaPointer->SystemPhysicalAddressRangeBase =3D NvdRegionBase; + NfitSpaPointer->SystemPhysicalAddressRangeLength =3D NvdRegionSize; +} + +VOID +NfitFillControlRegion ( + IN OUT EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *NfitControlReg= ionPointer, + IN UINTN NvdRegionIndex + ) +{ + NfitControlRegionPointer->NVDIMMControlRegionStructureIndex =3D NvdRegio= nIndex; +} + +VOID +NfitFillRegionMapping ( + IN OUT EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE *NfitRegionMapp= ingPointer, + IN EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *NfitControlRegionP= ointer, + IN EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPoi= nter + ) +{ + NfitRegionMappingPointer->NVDIMMControlRegionStructureIndex =3D NfitC= ontrolRegionPointer->NVDIMMControlRegionStructureIndex; + NfitRegionMappingPointer->SPARangeStructureIndex =3D NfitS= paPointer->SPARangeStructureIndex; + NfitRegionMappingPointer->NVDIMMPhysicalAddressRegionBase =3D NfitS= paPointer->SystemPhysicalAddressRangeBase; + NfitRegionMappingPointer->NVDIMMRegionSize =3D NfitS= paPointer->SystemPhysicalAddressRangeLength; + NfitRegionMappingPointer->NFITDeviceHandle.DIMMNumber =3D 1; //= Hardcoded for now. + NfitRegionMappingPointer->NFITDeviceHandle.MemoryChannelNumber =3D 0; //= Hardcoded for now. + NfitRegionMappingPointer->NFITDeviceHandle.MemoryControllerID =3D 0; //= Hardcoded for now. + NfitRegionMappingPointer->NFITDeviceHandle.NodeControllerID =3D 0; //= Hardcoded for now. + NfitRegionMappingPointer->NFITDeviceHandle.SocketID =3D 0; //= Hardcoded for now. + NfitRegionMappingPointer->RegionOffset =3D 0; //= Hardcoded for now. +} + +EFI_STATUS +AcpiNfitFillTable ( + IN EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *NfitTablePointer + ) +{ + EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPoin= ter; + EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE *NfitRegionM= appingPointer; + EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *NfitControl= RegionPointer; + CONST EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V2; + PlatformInfoHob_V2 *PlatformHob; + UINTN Count; + VOID *Hob; + UINTN NvdRegionIndex; + UINT64 NvdRegionBase; + UINT64 NvdRegionSize; + + /* Get the Platform HOB */ + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + PlatformHob =3D (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob); + + NfitSpaPointer =3D (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRU= CTURE *) + (NfitTablePointer + 1); + NvdRegionIndex =3D 0; + for (Count =3D 0; Count < PlatformHob->DramInfo.NumRegion; Count++) { + if (PlatformHob->DramInfo.NvdRegion[Count] !=3D 0) { + NvdRegionIndex++; + NvdRegionBase =3D PlatformHob->DramInfo.Base[Count]; + NvdRegionSize =3D PlatformHob->DramInfo.Size[Count]; + + CopyMem ((VOID *) NfitSpaPointer, (VOID *) &NfitSPATemplate, sizeof = (NfitSPATemplate)); + AcpiNfitFillSPA (NfitSpaPointer, NvdRegionIndex, NvdRegionBase, NvdR= egionSize); + + NfitControlRegionPointer =3D (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGIO= N_STRUCTURE *) + (NfitSpaPointer + 1); + CopyMem ((VOID *) NfitControlRegionPointer, + (VOID *) &NvdimmControlRegionTemplate, + sizeof (NvdimmControlRegionTemplate)); + NfitFillControlRegion (NfitControlRegionPointer, NvdRegionIndex); + + NfitRegionMappingPointer =3D (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPIN= G_STRUCTURE *) + (NfitControlRegionPointer + 1); + CopyMem ((VOID *) NfitRegionMappingPointer, + (VOID *) &NvdimmRegionMappingTemplate, + sizeof (NvdimmRegionMappingTemplate)); + NfitFillRegionMapping (NfitRegionMappingPointer, + NfitControlRegionPointer, + NfitSpaPointer); + /* Next Region */ + NfitSpaPointer =3D (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_= STRUCTURE *) + (NfitRegionMappingPointer + 1); + } + } + + return EFI_SUCCESS; +} + +/* + * Install NFIT table. + */ +EFI_STATUS +AcpiInstallNfitTable (VOID) +{ + EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *NfitTablePo= inter; + EFI_ACPI_TABLE_PROTOCOL *AcpiTablePr= otocol; + UINTN NfitTableKey= =3D 0; + EFI_STATUS Status; + UINTN Size; + UINTN NvdRegionNum; + + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, + NULL, (VOID **) &AcpiTableProtocol); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D AcpiGetNvdRegionNumber (&NvdRegionNum); + if (EFI_ERROR (Status)) { + return Status; + } + + Size =3D sizeof (EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE) + + ((sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTU= RE) + + sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE) + + sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE)) * N= vdRegionNum); + NfitTablePointer =3D (EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *) Al= locateZeroPool (Size); + if (NfitTablePointer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem ((VOID *) NfitTablePointer, + (VOID *) &NFITTableHeaderTemplate, + sizeof (NFITTableHeaderTemplate)); + NfitTablePointer->Header.Length =3D Size; + + Status =3D AcpiNfitFillTable (NfitTablePointer); + if (EFI_ERROR (Status)) { + FreePool ((VOID *) NfitTablePointer); + return Status; + } + + AcpiTableChecksum ((UINT8 *)NfitTablePointer, NfitTablePointer->Header.L= ength); + Status =3D AcpiTableProtocol->InstallAcpiTable (AcpiTableProtocol, + (VOID *) NfitTablePointer, + NfitTablePointer->Header.L= ength, + &NfitTableKey); + if (EFI_ERROR (Status)) { + FreePool ((VOID *) NfitTablePointer); + } + + return Status; +} diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPCCT.c b/P= latform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPCCT.c new file mode 100644 index 000000000000..c27e91f06375 --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPCCT.c @@ -0,0 +1,264 @@ +/** @file + + Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include "AcpiPlatform.h" + +EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS PCCTSubspaceTemplat= e =3D { + 2, /* HW-Reduced Communication Subspace Type 2 */ + sizeof(EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS), + 0, /* DoorbellInterrupt: need fill in */ + 0, + 0, + 0, /* BaseAddress: need fill in */ + 0x100, + {0, 0x20, 0, 0x3, 0x0}, /* DoorbellRegister: need fill in */ + 0, + 0x53000040, + 1, + 1, + 1, + {0, 0x20, 0, 0x3, 0x0}, /* DoorbellAckRegister: need fill in */ + 0, + 0x10001, +}; + +EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER PCCTTableHeaderTe= mplate =3D { + { + EFI_ACPI_6_3_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE, + 0, /* need fill in */ + EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION, // Revi= sion + 0x00, // Checksum will be updated at runtime + // + // It is expected that these values will be updated at EntryPoint. + // + {0}, // OEM ID is a 6 bytes long field + 0, // OEM Table ID(8 bytes long) + 0, // OEM Revision + 0, // Creator ID + 0, // Creator Revision + }, + EFI_ACPI_6_3_PCCT_FLAGS_PLATFORM_INTERRUPT, +}; + +STATIC BOOLEAN +AcpiPcctIsV2 (VOID) +{ + CONST EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V2; + VOID *Hob; + + /* Get the Platform HOB */ + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return FALSE; + } + + return TRUE; +} + +STATIC UINT32 +AcpiPcctGetNumOfSocket (VOID) +{ + UINTN NumberSockets, NumberActiveSockets, Count, Index, I= ndex1; + CONST EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V2; + PlatformInfoHob_V2 *PlatformHob; + PlatformClusterEn *Socket; + VOID *Hob; + + /* Get the Platform HOB */ + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return 1; + } + PlatformHob =3D (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob); + + NumberSockets =3D sizeof (PlatformHob->ClusterEn) / sizeof (PlatformClus= terEn); + NumberActiveSockets =3D 0; + + for (Index =3D 0; Index < NumberSockets; Index++) { + Socket =3D &PlatformHob->ClusterEn[Index]; + Count =3D sizeof (Socket->EnableMask) / sizeof (Socket->EnableMask[0]); + for (Index1 =3D 0; Index1 < Count; Index1++) { + if (Socket->EnableMask[Index1] !=3D 0) { + NumberActiveSockets++; + break; + } + } + } + + return NumberActiveSockets; +} + +EFI_STATUS +AcpiPcctInit (VOID) +{ + INTN NumOfSocket =3D AcpiPcctGetNumOfSocket (); + INTN Subspace; + INTN Socket; + + for (Socket =3D 0; Socket < NumOfSocket; Socket++) { + for (Subspace =3D 0; Subspace < PCC_MAX_SUBSPACES_PER_SOCKET; Subspace= ++ ) { + if (AcpiPcctIsV2 ()) { + AcpiPccSharedMemInitV2 (Socket, Subspace); + } else { + AcpiPccSharedMemInit (Socket, Subspace); + } + AcpiPccSyncSharedMemAddr (Socket, Subspace); + AcpiPccUnmaskInt (Socket, Subspace); + } + } + + return EFI_SUCCESS; +} + +/* + * Install PCCT table. + * + * Each socket has 16 PCC subspaces + * 0 - 7 : PMPro subspaces + * 8 - 15 : SMPro subspaces + */ +EFI_STATUS +AcpiInstallPcctTable (VOID) +{ + EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *PcctTablePoint= er =3D NULL; + EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *PcctEntryPointer= =3D NULL; + INTN NumOfSocket =3D AcpiPcctGetNumOfSocket (); + UINT64 PccSharedMemPointer =3D 0; + EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; + UINTN PcctTableKey =3D 0; + INTN Count, Subspace; + INTN SubspaceIdx; + INTN NumOfSubspace; + INTN IntNum =3D 0; + EFI_STATUS Status; + UINTN Size; + INTN Socket; + + if (IsAcpiInstalled (EFI_ACPI_6_3_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_= SIGNATURE)) { + DEBUG ((DEBUG_INFO, "PCCT table is already installed. Skipping...\n")= ); + return EFI_ABORTED; + } + + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, + NULL, (VOID **) &AcpiTableProtocol); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Count =3D 0; Count < gST->NumberOfTableEntries; Count++) { + if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Count]= .VendorGuid))) { + NumOfSubspace =3D PCC_MAX_SUBSPACES_PER_SOCKET * NumOfSocket; + + Size =3D sizeof(EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HE= ADER) + + NumOfSubspace * sizeof(EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW= _REDUCED_COMMUNICATIONS); + + PcctTablePointer =3D (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TA= BLE_HEADER *)AllocateZeroPool(Size); + if (PcctTablePointer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + /* Allocation PCC shared memory */ + AcpiPccAllocSharedMemory (&PccSharedMemPointer, NumOfSubspace); + if (PccSharedMemPointer =3D=3D 0) { + FreePool ((VOID *)PcctTablePointer); + return EFI_OUT_OF_RESOURCES; + } + + PcctEntryPointer =3D (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUN= ICATIONS *) ((UINT64) PcctTablePointer + + sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER= )); + + for (Socket =3D 0; Socket < NumOfSocket; Socket++) { + for (Subspace =3D 0; Subspace < PCC_MAX_SUBSPACES_PER_SOCKET; Subs= pace++ ) { + SubspaceIdx =3D Subspace + PCC_MAX_SUBSPACES_PER_SOCKET * Socket; + + CopyMem (&PcctEntryPointer[SubspaceIdx], &PCCTSubspaceTemplate, + sizeof(EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICA= TIONS)); + + PcctEntryPointer[SubspaceIdx].BaseAddress =3D PccSharedMemPointe= r + + PCC_SUBSPACE_SHARED_= MEM_SIZE * SubspaceIdx; + PcctEntryPointer[SubspaceIdx].AddressLength =3D PCC_SUBSPACE_SHA= RED_MEM_SIZE; + + IntNum =3D 0; + if (Socket > 0) { + IntNum =3D Socket * PLATFORM_SLAVE_SOCKET_SPI_INTERRUPT_START = - 32; + } + if (Subspace < PMPRO_MAX_DB) { + IntNum +=3D PMPRO_DB0_IRQ_NUM + Subspace; + /* PCC subspaces for 8 PMpro Doorbells */ + PcctEntryPointer[SubspaceIdx].DoorbellRegister.Address =3D PMP= RO_DBx_REG (Socket, Subspace, DB_OUT); + PcctEntryPointer[SubspaceIdx].PlatformInterrupt =3D IntNum; + PcctEntryPointer[SubspaceIdx].PlatformInterruptAckRegister.Add= ress =3D PMPRO_DBx_REG (Socket, Subspace, DB_STATUS); + } else { + IntNum +=3D SMPRO_DB0_IRQ_NUM + Subspace - PMPRO_MAX_DB; + /* PCC subspaces for 8 SMpro Doorbells */ + PcctEntryPointer[SubspaceIdx].DoorbellRegister.Address =3D SMP= RO_DBx_REG (Socket,Subspace - PMPRO_MAX_DB, DB_OUT); + PcctEntryPointer[SubspaceIdx].PlatformInterrupt =3D IntNum; + PcctEntryPointer[SubspaceIdx].PlatformInterruptAckRegister.Add= ress =3D SMPRO_DBx_REG (Socket, Subspace - PMPRO_MAX_DB, DB_STATUS); + } + + /* Timing */ + PcctEntryPointer[SubspaceIdx].NominalLatency =3D PCC_NOMINAL_LAT= ENCY; + PcctEntryPointer[SubspaceIdx].MaximumPeriodicAccessRate =3D PCC_= MAX_PERIOD_ACCESS; + PcctEntryPointer[SubspaceIdx].MinimumRequestTurnaroundTime =3D P= CC_MIN_REQ_TURNAROUND_TIME; + + /* Initialize subspace used for CPPC queries */ + if (Subspace =3D=3D PCC_CPPC_SUBSPACE) { + /* Configure CPPC control byte for CPPC : 0x100 */ + PcctEntryPointer[SubspaceIdx].DoorbellWrite =3D PCC_MSG | PCC_= CPPC_URG_MSG | PCC_CPPC_MSG; + PcctEntryPointer[SubspaceIdx].NominalLatency =3D PCC_CPPC_NOMI= NAL_LATENCY; + PcctEntryPointer[SubspaceIdx].MinimumRequestTurnaroundTime =3D= PCC_CPPC_MIN_REQ_TURNAROUND_TIME; + } else { + PcctEntryPointer[SubspaceIdx].DoorbellWrite =3D PCC_MSG; + } + if (!AcpiPcctIsV2 ()) { + /* Store the upper address (Bit 40-43) of PCC shared memory */ + PcctEntryPointer[SubspaceIdx].DoorbellWrite |=3D + (PcctEntryPointer[SubspaceIdx].BaseAddress >> 40) & PCP_MS= G_UPPER_ADDR_MASK; + } + } + } + + CopyMem (PcctTablePointer, &PCCTTableHeaderTemplate, + sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HE= ADER)); + + PcctTablePointer->Header.Length =3D Size; + CopyMem ( + PcctTablePointer->Header.OemId, + PcdGetPtr (PcdAcpiDefaultOemId), + sizeof (PcctTablePointer->Header.OemId) + ); + PcctTablePointer->Header.OemTableId =3D EFI_ACPI_OEM_TABLE_ID; + PcctTablePointer->Header.OemRevision =3D 3; + PcctTablePointer->Header.CreatorId =3D EFI_ACPI_CREATOR_ID; + PcctTablePointer->Header.CreatorRevision =3D EFI_ACPI_CREATOR_REVISI= ON; + + AcpiTableChecksum ((UINT8 *) PcctTablePointer, + PcctTablePointer->Header.Length); + + Status =3D AcpiTableProtocol->InstallAcpiTable ( + AcpiTableProtocol, + (VOID *) PcctTablePointer, + PcctTablePointer->Header.Length, + &PcctTableKey + ); + if (EFI_ERROR (Status)) { + AcpiPccFreeSharedMemory (&PccSharedMemPointer, NumOfSubspace); + FreePool ((VOID *) PcctTablePointer); + return Status; + } + break; + } + } + + if (Count =3D=3D gST->NumberOfTableEntries) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPPTT.c b/P= latform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPPTT.c new file mode 100755 index 000000000000..59a8701aa2e7 --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPPTT.c @@ -0,0 +1,338 @@ +/** @file + + Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "AcpiPlatform.h" + +EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR PPTTProcessorTemplate =3D { + EFI_ACPI_6_3_PPTT_TYPE_PROCESSOR, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR), + { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE }, + {0}, /* Flags */ + 0, /* Parent */ + 0, /* AcpiProcessorId */ + 0 /* NumberOfPrivateResources */ +}; + +EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE PPTTCacheTemplate =3D { + EFI_ACPI_6_3_PPTT_TYPE_CACHE, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE), + { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE }, + {0}, /* Flags */ + 0, /* NextLevelOfCache */ + 0, /* Size */ + 0, /* NumberOfSets */ + 0, /* Associativity */ + {0}, /* Attributes */ + 0 +}; + +EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER PPTTTableHeaderTem= plate =3D { + __ACPI_HEADER ( + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, + 0, /* need fill in */ + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION + ), +}; + +STATIC EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *PpttTableP= ointer; +STATIC UINT32 PpttCoreOffset[PLATFORM_CPU_MAX_NUM_CORES]; +STATIC UINT32 PpttClusterOffset[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SO= CKET]; +STATIC UINT32 PpttSocketOffset[PLATFORM_CPU_MAX_SOCKET]; +STATIC UINT32 PpttRootOffset; +STATIC UINT32 PpttL1DataCacheOffset[PLATFORM_CPU_MAX_NUM_CORES]; +STATIC UINT32 PpttL1InstructionCacheOffset[PLATFORM_CPU_MAX_NUM_CORES]; +STATIC UINT32 PpttL2CacheOffset[PLATFORM_CPU_MAX_NUM_CORES]; + +STATIC UINT32 +AcpiPpttProcessorThreadNode ( + VOID *EntryPointer, + UINT32 CpuId + ) +{ + EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer =3D Ent= ryPointer; + UINT32 *ResPointer; + UINTN ClusterIdPerSocket, CoreIdPerCpm, = SocketId; + + CopyMem (PpttProcessorEntryPointer, &PPTTProcessorTemplate, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)); + + ClusterIdPerSocket =3D (CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM) % PLATFO= RM_CPU_MAX_CPM; + SocketId =3D (CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM) / PLATFORM_CPU_MAX= _CPM; + CoreIdPerCpm =3D CpuId % PLATFORM_CPU_NUM_CORES_PER_CPM; + PpttProcessorEntryPointer->Flags.AcpiProcessorIdValid =3D 1; + PpttProcessorEntryPointer->Flags.NodeIsALeaf =3D 1; + PpttProcessorEntryPointer->Flags.IdenticalImplementation =3D 1; + PpttProcessorEntryPointer->AcpiProcessorId =3D (SocketId << PLATFORM_SOC= KET_UID_BIT_OFFSET) | (ClusterIdPerSocket << 8) | CoreIdPerCpm; + PpttProcessorEntryPointer->Parent =3D (UINT32) PpttCoreOffset[CpuId]; + PpttProcessorEntryPointer->NumberOfPrivateResources =3D 2; /* L1I + L1D = */ + + ResPointer =3D (UINT32 *) ((UINT64) EntryPointer + + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)); + ResPointer[0] =3D PpttL1InstructionCacheOffset[CpuId]; + ResPointer[1] =3D PpttL1DataCacheOffset[CpuId]; + + PpttProcessorEntryPointer->Length =3D sizeof (EFI_ACPI_6_3_PPTT_STRUCTUR= E_PROCESSOR) + 2 * sizeof (UINT32); + + return PpttProcessorEntryPointer->Length; +} + +STATIC UINT32 +AcpiPpttProcessorCoreNode ( + VOID *EntryPointer, + UINT32 CpuId + ) +{ + EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer =3D Ent= ryPointer; + + PpttCoreOffset[CpuId] =3D (UINT64) EntryPointer - (UINT64) PpttTablePoin= ter; + + CopyMem (PpttProcessorEntryPointer, &PPTTProcessorTemplate, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)); + + PpttProcessorEntryPointer->Parent =3D (UINT32) PpttClusterOffset[CpuId /= PLATFORM_CPU_NUM_CORES_PER_CPM]; + PpttProcessorEntryPointer->Flags.IdenticalImplementation =3D 1; + + return PpttProcessorEntryPointer->Length; +} + +STATIC UINT32 +AcpiPpttClusterNode ( + VOID *EntryPointer, + UINT32 ClusterId + ) +{ + EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer =3D Ent= ryPointer; + + PpttClusterOffset[ClusterId] =3D (UINT64) EntryPointer - (UINT64) PpttTa= blePointer; + + CopyMem (PpttProcessorEntryPointer, &PPTTProcessorTemplate, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)); + + PpttProcessorEntryPointer->Parent =3D (UINT32) PpttSocketOffset[ClusterI= d / PLATFORM_CPU_MAX_CPM]; + PpttProcessorEntryPointer->Flags.IdenticalImplementation =3D 1; + + return PpttProcessorEntryPointer->Length; +} + +STATIC UINT32 +AcpiPpttSocketNode ( + VOID *EntryPointer, + UINT32 SocketId + ) +{ + EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer =3D Ent= ryPointer; + + PpttSocketOffset[SocketId] =3D (UINT64) EntryPointer - (UINT64) PpttTabl= ePointer; + + CopyMem (PpttProcessorEntryPointer, &PPTTProcessorTemplate, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)); + + PpttProcessorEntryPointer->Flags.PhysicalPackage =3D 1; + PpttProcessorEntryPointer->Flags.IdenticalImplementation =3D 1; + PpttProcessorEntryPointer->Parent =3D (UINT32) PpttRootOffset; + + return PpttProcessorEntryPointer->Length; +} + +STATIC UINT32 +AcpiPpttRootNode ( + VOID *EntryPointer + ) +{ + EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer =3D Ent= ryPointer; + + PpttRootOffset =3D (UINT64) EntryPointer - (UINT64) PpttTablePointer; + + CopyMem (PpttProcessorEntryPointer, &PPTTProcessorTemplate, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)); + + PpttProcessorEntryPointer->Flags.IdenticalImplementation =3D 1; + + return PpttProcessorEntryPointer->Length; +} + +STATIC VOID +AcpiPpttFillCacheSizeInfo ( + EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *Node, + UINT32 Level + ) +{ + UINT64 CacheCCSIDR =3D AArch64ReadCCSIDRReg (Level); + UINT32 CacheLineSize; + UINT32 Count; + + CacheLineSize =3D 1; + Count =3D CCSIDR_LINE_SIZE (CacheCCSIDR) + 4; + while (Count-- > 0) { + CacheLineSize *=3D 2; + } + + Node->Flags.LineSizeValid =3D 1; + Node->Flags.NumberOfSetsValid =3D 1; + Node->Flags.AssociativityValid =3D 1; + Node->Flags.SizePropertyValid =3D 1; + Node->Flags.CacheTypeValid =3D 1; + Node->NumberOfSets =3D CCSIDR_NUMSETS (CacheCCSIDR) + 1; + Node->Associativity =3D CCSIDR_ASSOCIATIVITY (CacheCCSIDR) + 1; + Node->LineSize =3D CacheLineSize; + Node->Size =3D Node->NumberOfSets * + Node->Associativity * + Node->LineSize; +} + +STATIC UINT32 +AcpiPpttL1DataCacheNode ( + VOID *EntryPointer, + UINT32 CpuId + ) +{ + EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer =3D EntryPointe= r; + + PpttL1DataCacheOffset[CpuId] =3D (UINT64) EntryPointer - (UINT64) PpttTa= blePointer; + CopyMem (PpttCacheEntryPointer, &PPTTCacheTemplate, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)); + + AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 1); + PpttCacheEntryPointer->Attributes.CacheType =3D 0x0; /* Data Cache */ + PpttCacheEntryPointer->NextLevelOfCache =3D PpttL2CacheOffset[CpuId]; + + return PpttCacheEntryPointer->Length; +} + +STATIC UINT32 +AcpiPpttL1InstructionCacheNode ( + VOID *EntryPointer, + UINT32 CpuId + ) +{ + EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer =3D EntryPointe= r; + + PpttL1InstructionCacheOffset[CpuId] =3D (UINT64) EntryPointer - (UINT64)= PpttTablePointer; + CopyMem (PpttCacheEntryPointer, &PPTTCacheTemplate, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)); + + AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 1); + PpttCacheEntryPointer->Attributes.CacheType =3D 0x1; /* Instruction Cach= e */ + PpttCacheEntryPointer->NextLevelOfCache =3D PpttL2CacheOffset[CpuId]; + + return PpttCacheEntryPointer->Length; +} + +STATIC UINT32 +AcpiPpttL2CacheNode ( + VOID *EntryPointer, + UINT32 CpuId + ) +{ + EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer =3D EntryPointe= r; + + PpttL2CacheOffset[CpuId] =3D (UINT64) EntryPointer - (UINT64) PpttTableP= ointer; + CopyMem (PpttCacheEntryPointer, &PPTTCacheTemplate, + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)); + + AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 2); + PpttCacheEntryPointer->Attributes.CacheType =3D 0x3; /* Unified Cache */ + PpttCacheEntryPointer->NextLevelOfCache =3D 0; + + return PpttCacheEntryPointer->Length; +} + +/* + * Install PPTT table. + */ +EFI_STATUS +AcpiInstallPpttTable (VOID) +{ + EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer =3D N= ULL; + EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; + UINTN PpttTableKey =3D 0; + INTN Count, Count1; + EFI_STATUS Status; + UINTN Size; + + if (IsAcpiInstalled (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_ST= RUCTURE_SIGNATURE)) { + DEBUG ((DEBUG_INFO, "PPTT table is already installed. Skipping...\n")= ); + return EFI_ABORTED; + } + + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, + NULL, (VOID **) &AcpiTableProtocol); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Count =3D 0; Count < gST->NumberOfTableEntries; Count++) { + if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Count]= .VendorGuid))) { + Size =3D sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HE= ADER) + + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + /* Root nod= e */ + (PLATFORM_CPU_MAX_SOCKET * sizeof (EFI_ACPI_6_3_PPTT_STRUCTU= RE_PROCESSOR)) + /* Socket node */ + (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET * sizeof (EF= I_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)) + /* Cluster node */ + (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRU= CTURE_PROCESSOR)) + /* Core node */ + (PLATFORM_CPU_MAX_NUM_CORES * (sizeof (EFI_ACPI_6_3_PPTT_STR= UCTURE_PROCESSOR) + 2 * sizeof (UINT32))) + /* Thread node */ + (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRU= CTURE_CACHE)) + /* L1I node */ + (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRU= CTURE_CACHE)) + /* L1D node */ + (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRU= CTURE_CACHE)); /* L2 node */ + + PpttTablePointer =3D + (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *) Alloca= teZeroPool (Size); + if (PpttTablePointer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + PpttProcessorEntryPointer =3D + (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *) ((UINT64) PpttTablePoi= nter + + sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER)= ); + + Size =3D 0; + Size +=3D AcpiPpttRootNode ((VOID *)((UINT64) PpttProcessorEntryPoin= ter + Size)); + + for (Count1 =3D 0; Count1 < PLATFORM_CPU_MAX_SOCKET; Count1++) { + Size +=3D AcpiPpttSocketNode ((VOID *)((UINT64) PpttProcessorEntry= Pointer + Size), Count1); + } + + for (Count1 =3D 0; Count1 < PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_= SOCKET; Count1++) { + Size +=3D AcpiPpttClusterNode ((VOID *)((UINT64) PpttProcessorEntr= yPointer + Size), Count1); + } + + for (Count1 =3D 0; Count1 < PLATFORM_CPU_MAX_NUM_CORES; Count1++) { + Size +=3D AcpiPpttL2CacheNode ((VOID *)((UINT64) PpttProcessorEntr= yPointer + Size), Count1); + Size +=3D AcpiPpttL1InstructionCacheNode ((VOID *) ((UINT64) PpttP= rocessorEntryPointer + Size), Count1); + Size +=3D AcpiPpttL1DataCacheNode ((VOID *)((UINT64) PpttProcessor= EntryPointer + Size), Count1); + Size +=3D AcpiPpttProcessorCoreNode ((VOID *)((UINT64) PpttProcess= orEntryPointer + Size), Count1); + Size +=3D AcpiPpttProcessorThreadNode ((VOID *)((UINT64) PpttProce= ssorEntryPointer + Size), Count1); + } + + CopyMem (PpttTablePointer, &PPTTTableHeaderTemplate, + sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEA= DER)); + + Size +=3D sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_H= EADER); + PpttTablePointer->Header.Length =3D Size; + + AcpiTableChecksum ((UINT8 *) PpttTablePointer, + PpttTablePointer->Header.Length); + + Status =3D AcpiTableProtocol->InstallAcpiTable ( + AcpiTableProtocol, + (VOID *)PpttTablePointer, + PpttTablePointer->Header.Length, + &PpttTableKey + ); + FreePool ((VOID *)PpttTablePointer); + if (EFI_ERROR (Status)) { + return Status; + } + break; + } + } + + if (Count =3D=3D gST->NumberOfTableEntries) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDx= e.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c index 346f23cbe5fb..31b635db2b7b 100644 --- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c @@ -47,6 +47,67 @@ AcpiNotificationEvent ( } } =20 +VOID +EFIAPI +InstallAcpiOnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + Status =3D AcpiInstallMadtTable (); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Installed MADT table\n")); + } + + Status =3D AcpiInstallPpttTable (); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Installed PPTT table\n")); + } + + Status =3D AcpiInstallSlitTable (); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Installed SLIT table\n")); + } + + Status =3D AcpiInstallSratTable (); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Installed SRAT table\n")); + } + + Status =3D AcpiInstallPcctTable (); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Installed PCCT table\n")); + } + + Status =3D AcpiInstallNfitTable (); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Installed NFIT table\n")); + } +} + +VOID +EFIAPI +UpdateAcpiOnExitBootServices( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + Status =3D AcpiPatchDsdtTable (); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "DSDT Table updated!\n")); + } + + // Configure PCC mailbox base address and unmask interrupt + Status =3D AcpiPcctInit(); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "PCCT Table updated!\n")); + } +} + EFI_STATUS EFIAPI AcpiPlatformDxeInitialize ( @@ -54,6 +115,10 @@ AcpiPlatformDxeInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { + EFI_EVENT ReadyToBootEvent; + EFI_EVENT ExitBootServicesEvent; + EFI_STATUS Status; + EfiCreateProtocolNotifyEvent ( &gEfiAcpiTableProtocolGuid, TPL_CALLBACK, @@ -62,5 +127,24 @@ AcpiPlatformDxeInitialize ( &mAcpiRegistration ); =20 + Status =3D gBS->CreateEvent ( + EVT_SIGNAL_EXIT_BOOT_SERVICES, + TPL_CALLBACK, + UpdateAcpiOnExitBootServices, + NULL, + &ExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + InstallAcpiOnReadyToBoot, + NULL, + &gEfiEventReadyToBootGuid, + &ReadyToBootEvent + ); + ASSERT_EFI_ERROR(Status); + return EFI_SUCCESS; } diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSLIT.c b/P= latform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSLIT.c new file mode 100755 index 000000000000..1b69abf9693b --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSLIT.c @@ -0,0 +1,85 @@ +/** @file + + Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "AcpiPlatform.h" + +#define SELF_DISTANCE 10 +#define REMOTE_DISTANCE 20 + +EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER SLITTableHe= aderTemplate =3D { + __ACPI_HEADER ( + EFI_ACPI_6_3_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE, + 0, /* need fill in */ + EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION + ), + 0, +}; + +EFI_STATUS +AcpiInstallSlitTable (VOID) +{ + EFI_ACPI_TABLE_PROTOCOL *AcpiTab= leProtocol; + EFI_STATUS Status; + UINTN NumDomai= n, Count, Count1; + EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER *SlitTab= lePointer; + UINT8 *TmpPtr; + UINTN SlitTabl= eKey; + UINTN NumDomai= nPerSocket; + + if (IsAcpiInstalled (EFI_ACPI_6_3_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGN= ATURE)) { + DEBUG ((DEBUG_INFO, "SLIT table is already installed. Skipping...\n")= ); + return EFI_ABORTED; + } + + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, + NULL, (VOID **) &AcpiTableProtocol); + if (EFI_ERROR (Status)) { + return Status; + } + + NumDomainPerSocket =3D CPUGetNumOfSubNuma (); + NumDomain =3D NumDomainPerSocket * GetNumberActiveSockets (); + + SlitTablePointer =3D (EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_= TABLE_HEADER *) + AllocateZeroPool (sizeof (SLITTableHeaderTemplate) + Num= Domain * NumDomain); + if (SlitTablePointer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem ((VOID *) SlitTablePointer, (VOID *) &SLITTableHeaderTemplate, s= izeof (SLITTableHeaderTemplate)); + SlitTablePointer->NumberOfSystemLocalities =3D NumDomain; + TmpPtr =3D (UINT8 *) SlitTablePointer + sizeof (SLITTableHeaderTemplate); + for (Count =3D 0; Count < NumDomain; Count++) { + for (Count1 =3D 0; Count1 < NumDomain; Count1++, TmpPtr++) { + if (Count =3D=3D Count1) { + *TmpPtr =3D (UINT8) SELF_DISTANCE; + continue; + } + if ((Count1 / NumDomainPerSocket) =3D=3D (Count / NumDomainPerSocket= )) { + *TmpPtr =3D (UINT8) (SELF_DISTANCE + 1); + } else { + *TmpPtr =3D (UINT8) (REMOTE_DISTANCE); + } + } + } + + SlitTablePointer->Header.Length =3D sizeof (SLITTableHeaderTemplate) + N= umDomain * NumDomain; + + AcpiTableChecksum ((UINT8 *) SlitTablePointer, + SlitTablePointer->Header.Length); + + Status =3D AcpiTableProtocol->InstallAcpiTable ( + AcpiTableProtocol, + (VOID *) SlitTablePointer, + SlitTablePointer->Header.Length, + &SlitTableKey + ); + FreePool ((VOID *) SlitTablePointer); + + return Status; +} + diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSRAT.c b/P= latform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSRAT.c new file mode 100755 index 000000000000..39b6936f6ed0 --- /dev/null +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSRAT.c @@ -0,0 +1,268 @@ +/** @file + + Copyright (c) 2020, Ampere Computing LLC. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include "AcpiPlatform.h" + +EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER SRATTableHeaderTemplate= =3D { + __ACPI_HEADER ( + EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE, + 0, /* need fill in */ + EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION + ), + 0x00000001, + 0x0000000000000000, +}; + +EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE GicItsAffinityTemplate =3D { + .Type =3D EFI_ACPI_6_3_GIC_ITS_AFFINITY, + sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE), + .ProximityDomain =3D 0, /* ProximityDomain */ + { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE }, + .ItsId =3D 0, +}; + +STATIC +UINTN +SratCalculateNumMemoryRegion (VOID) +{ + EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V= 2; + PlatformInfoHob_V2 *PlatformHob; + UINTN Count; + UINT64 TmpVal; + VOID *Hob; + UINTN Result; + + /* Get the Platform HOB */ + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return 0; + } + PlatformHob =3D (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob); + + Result =3D 0; + for (Count =3D 0; Count < PlatformHob->DramInfo.NumRegion; Count++) { + TmpVal =3D PlatformHob->DramInfo.Size[Count]; + if (TmpVal > 0) { + Result++; + } + } + + return Result; +} + +STATIC +EFI_STATUS +SratAddMemAffinity ( + EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *SratMemAffinity + ) +{ + EFI_GUID PlatformHobGuid =3D PLATFORM_INFO_HOB_GUID_V= 2; + PlatformInfoHob_V2 *PlatformHob; + UINTN Count, NumRegion; + UINT64 RegionSize, RegionBase; + VOID *Hob; + UINTN ProximityDomain; + + /* Get the Platform HOB */ + Hob =3D GetFirstGuidHob (&PlatformHobGuid); + if (Hob =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + PlatformHob =3D (PlatformInfoHob_V2 *) GET_GUID_HOB_DATA (Hob); + + NumRegion =3D 0; + + for (Count =3D 0; Count < PlatformHob->DramInfo.NumRegion; Count++) { + RegionSize =3D PlatformHob->DramInfo.Size[Count]; + RegionBase =3D PlatformHob->DramInfo.Base[Count]; + ProximityDomain =3D PlatformHob->DramInfo.Node[Count]; + if (RegionSize > 0) { + ZeroMem ((VOID *) &SratMemAffinity[NumRegion], sizeof (SratMemAffini= ty[NumRegion])); + SratMemAffinity[NumRegion].Flags =3D 1; + SratMemAffinity[NumRegion].LengthLow =3D + (UINT32) (RegionSize & 0xFFFFFFFF); + SratMemAffinity[NumRegion].LengthHigh =3D + (UINT32) ((RegionSize & 0xFFFFFFFF00000000ULL) >> 32); + SratMemAffinity[NumRegion].AddressBaseLow =3D + (UINT32) (RegionBase & 0xFFFFFFFF); + SratMemAffinity[NumRegion].AddressBaseHigh =3D + (UINT32) ((RegionBase & 0xFFFFFFFF00000000ULL) >> 32); + SratMemAffinity[NumRegion].ProximityDomain =3D (UINT32) (ProximityDo= main); + SratMemAffinity[NumRegion].Type =3D EFI_ACPI_6_3_MEMORY_AFFINITY; + SratMemAffinity[NumRegion].Length =3D sizeof (EFI_ACPI_6_3_MEMORY_AF= FINITY_STRUCTURE); + NumRegion++; + } + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +SratAddGiccAffinity ( + EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *SratGiccAffinity + ) +{ + ARM_PROCESSOR_TABLE *ArmProcessorTab= le; + ARM_CORE_INFO *ArmCoreInfoTabl= e; + UINTN Count, NumNode, = Idx; + UINT32 AcpiProcessorUid; + UINT8 Socket; + UINT8 Cpm; + + for (Idx =3D 0; Idx < gST->NumberOfTableEntries; Idx++) { + if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Idx].V= endorGuid))) { + ArmProcessorTable =3D (ARM_PROCESSOR_TABLE *) gST->ConfigurationTabl= e[Idx].VendorTable; + ArmCoreInfoTable =3D ArmProcessorTable->ArmCpus; + break; + } + } + + if (Idx =3D=3D gST->NumberOfTableEntries) { + return EFI_INVALID_PARAMETER; + } + + Count =3D 0; + NumNode =3D 0; + while (Count !=3D ArmProcessorTable->NumberOfEntries) { + for (Idx =3D 0; Idx < ArmProcessorTable->NumberOfEntries; Idx++ ) { + Socket =3D ArmCoreInfoTable[Idx].ClusterId; + Cpm =3D (ArmCoreInfoTable[Idx].CoreId >> PLATFORM_CPM_UID_BIT_OFFSET= ); + if (CPUGetSubNumNode (Socket, Cpm) !=3D NumNode) { + /* We add nodes based on ProximityDomain order */ + continue; + } + AcpiProcessorUid =3D (ArmCoreInfoTable[Idx].ClusterId << PLATFORM_SO= CKET_UID_BIT_OFFSET) + + ArmCoreInfoTable[Idx].CoreId; + ZeroMem ((VOID *) &SratGiccAffinity[Count], sizeof (SratGiccAffinity= [Count])); + SratGiccAffinity[Count].AcpiProcessorUid =3D AcpiProcessorUid; + SratGiccAffinity[Count].Flags =3D 1; + SratGiccAffinity[Count].Length =3D sizeof (EFI_ACPI_6_3_GICC_AFFINIT= Y_STRUCTURE); + SratGiccAffinity[Count].Type =3D EFI_ACPI_6_3_GICC_AFFINITY; + SratGiccAffinity[Count].ProximityDomain =3D CPUGetSubNumNode (Socket= , Cpm); + Count++; + } + NumNode++; + } + + return EFI_SUCCESS; +} + +STATIC UINT32 +InstallGicItsAffinity ( + VOID *EntryPointer, + UINT32 Index + ) +{ + EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *ItsAffinityEntryPointer =3D Ent= ryPointer; + UINTN Size; + + Size =3D sizeof (GicItsAffinityTemplate); + CopyMem (ItsAffinityEntryPointer, &GicItsAffinityTemplate, Size); + return Size; +} + +STATIC +EFI_STATUS +SratAddGicItsAffinity ( + VOID *TmpPtr + ) +{ + UINTN Size =3D 0; + UINTN Index; + + /* Install Gic ITSAffinity */ + if (!PlatSlaveSocketPresent ()) { + for (Index =3D 0; Index <=3D 1; Index++) { /* RCA0/1 */ + GicItsAffinityTemplate.ItsId =3D Index; + GicItsAffinityTemplate.ProximityDomain =3D 0; + Size +=3D InstallGicItsAffinity ((VOID *) ((UINT64) TmpPtr + Size), = Index); + } + } + + for (Index =3D SOCKET0_FIRST_RC; Index <=3D SOCKET0_LAST_RC; Index++) { + GicItsAffinityTemplate.ItsId =3D Index; + GicItsAffinityTemplate.ProximityDomain =3D 0; + Size +=3D InstallGicItsAffinity ((VOID *) ((UINT64) TmpPtr + Size), In= dex); + } + + if (GetNumberActiveSockets () > 1) { + for (Index =3D SOCKET1_FIRST_RC; Index <=3D SOCKET1_LAST_RC; Index++) { + GicItsAffinityTemplate.ItsId =3D Index; + GicItsAffinityTemplate.ProximityDomain =3D 1; + Size +=3D InstallGicItsAffinity ((VOID *) ((UINT64) TmpPtr + Size), = Index); + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS +AcpiInstallSratTable (VOID) +{ + EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; + EFI_STATUS Status; + EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratTablePointer; + UINT8 *TmpPtr; + UINTN SratTableKey; + UINTN Size; + + if (IsAcpiInstalled (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATU= RE)) { + DEBUG ((DEBUG_INFO, "SRAT table is already installed. Skipping...\n")= ); + return EFI_ABORTED; + } + + Status =3D gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, + NULL, (VOID **) &AcpiTableProtocol); + if (EFI_ERROR (Status)) { + return Status; + } + + Size =3D sizeof (SRATTableHeaderTemplate) + + SratCalculateNumMemoryRegion () * sizeof (EFI_ACPI_6_3= _MEMORY_AFFINITY_STRUCTURE) + + GetNumberActiveCores () * sizeof (EFI_ACPI_6_3_GICC_AF= FINITY_STRUCTURE) + + ((SOCKET0_LAST_RC - SOCKET0_FIRST_RC + 1) * sizeof (G= icItsAffinityTemplate)); + if (GetNumberActiveSockets () > 1) { + Size +=3D (SOCKET1_LAST_RC - SOCKET1_FIRST_RC + 1) * sizeof (GicI= tsAffinityTemplate); + } else if (!PlatSlaveSocketPresent ()){ + Size +=3D 2 * sizeof(GicItsAffinityTemplate); /* RCA0/1 */ + } + + SratTablePointer =3D (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER= *) AllocateZeroPool (Size); + if (SratTablePointer =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem ((VOID *) SratTablePointer, (VOID *) &SRATTableHeaderTemplate, s= izeof (SRATTableHeaderTemplate)); + + TmpPtr =3D (UINT8 *) SratTablePointer + sizeof (SRATTableHeaderTemplate); + Status =3D SratAddMemAffinity ((EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *= ) TmpPtr); + ASSERT_EFI_ERROR (Status); + + TmpPtr +=3D SratCalculateNumMemoryRegion () * sizeof (EFI_ACPI_6_3_MEMOR= Y_AFFINITY_STRUCTURE); + Status =3D SratAddGiccAffinity ((EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)= TmpPtr); + ASSERT_EFI_ERROR (Status); + + TmpPtr +=3D GetNumberActiveCores () * sizeof (EFI_ACPI_6_3_GICC_AFFINITY= _STRUCTURE); + SratAddGicItsAffinity ((VOID*) (UINT64) TmpPtr); + SratTablePointer->Header.Length =3D Size; + + AcpiTableChecksum ((UINT8 *) SratTablePointer, + SratTablePointer->Header.Length); + + Status =3D AcpiTableProtocol->InstallAcpiTable ( + AcpiTableProtocol, + (VOID *) SratTablePointer, + SratTablePointer->Header.Length, + &SratTableKey + ); + FreePool ((VOID *) SratTablePointer); + + return Status; +} + --=20 2.17.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#68508): https://edk2.groups.io/g/devel/message/68508 Mute This Topic: https://groups.io/mt/78825492/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-