From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail05.groups.io (mail05.groups.io [45.79.224.7]) by spool.mail.gandi.net (Postfix) with ESMTPS id 5AD27740032 for ; Wed, 15 May 2024 03:52:14 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=SolHrqcvtbwkAxG6z95ABV5q+BqGlaQ9239ZNhJBXhE=; c=relaxed/simple; d=groups.io; h=Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Received-SPF:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Resent-From:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20240206; t=1715745132; v=1; b=R+cftZsZ9DmFscwIjSz1d21H8AQgiLkhs64tME8+oWp/R6AWXjmiMhW3o+tDobm/UXUyg8DF mq/RDJTeBOcXtbkMaA7oUxNz58Lo5MFlyIwmr+Vy+kEwwz46kHrNh4NERqA8KvLkIAHH1BKSRz5 sIKwjQMoTdl1mTR5umdXG5pD/yfz1U+QdkwMYYo8UERuTJ+bB08L/HGLyR+g/GUUrCMZffXiJDY Dqzwo1WA8iptvkkIpOhVc+3YlMC49lwVxYSuusTFSN/YPK9QNW2fdApSjY3Nz8+hdX7QtXTV1zW z+imgDaIOU5jqQGaQgeRUwEtb3LcpAIPqyH9ulb+7eBOQ== X-Received: by 127.0.0.2 with SMTP id VKpkYY7687511xD9cVc3TyOG; Tue, 14 May 2024 20:52:12 -0700 X-Received: from NAM02-SN1-obe.outbound.protection.outlook.com (NAM02-SN1-obe.outbound.protection.outlook.com [40.107.96.73]) by mx.groups.io with SMTP id smtpd.web11.6395.1715745132057233228 for ; Tue, 14 May 2024 20:52:12 -0700 X-Received: from DM6PR03CA0017.namprd03.prod.outlook.com (2603:10b6:5:40::30) by PH0PR12MB7931.namprd12.prod.outlook.com (2603:10b6:510:289::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7544.55; Wed, 15 May 2024 03:52:08 +0000 X-Received: from DS3PEPF0000C37D.namprd04.prod.outlook.com (2603:10b6:5:40:cafe::ec) by DM6PR03CA0017.outlook.office365.com (2603:10b6:5:40::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7587.26 via Frontend Transport; Wed, 15 May 2024 03:52:07 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB03.amd.com; pr=C X-Received: from SATLEXMB03.amd.com (165.204.84.17) by DS3PEPF0000C37D.mail.protection.outlook.com (10.167.23.7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7587.21 via Frontend Transport; Wed, 15 May 2024 03:52:07 +0000 X-Received: from SATLEXMB04.amd.com (10.181.40.145) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Tue, 14 May 2024 22:52:03 -0500 X-Received: from BLR-LAB-SFW01.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35 via Frontend Transport; Tue, 14 May 2024 22:52:02 -0500 From: "Abdul Lateef Attar via groups.io" To: CC: Abdul Lateef Attar , Abner Chang , Paul Grimes Subject: [edk2-devel] [RESEND 7/7] AmdPlatformPkg: Adds ACPI common driver Date: Wed, 15 May 2024 09:20:25 +0530 Message-ID: In-Reply-To: References: MIME-Version: 1.0 Received-SPF: None (SATLEXMB03.amd.com: AbdulLateef.Attar@amd.com does not designate permitted sender hosts) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS3PEPF0000C37D:EE_|PH0PR12MB7931:EE_ X-MS-Office365-Filtering-Correlation-Id: a58bb34f-c1a2-4481-3f68-08dc74926454 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?9wLDgC+vPFWJhvHtM9ByGOvhKfeP+jMA4MOiZIt7rB7/H1EJ2T15EGeLVKhj?= =?us-ascii?Q?7EVQ/xtlOWeLVXio0oD3q39SKcHWuAIfXKdBYcOO2+rK+96VjMVwyyItiF/O?= =?us-ascii?Q?RoCFQd8mU8xfN0nYwaOZ+3n3ZznngdZq6FxziqRc1M0wgXZA65atInp4VjuH?= =?us-ascii?Q?dA2RYYRjQDDvQV8XiZlN1JKKPmnC2skfjE+YokC1p3AKclcmQyi6GuZb/U3y?= =?us-ascii?Q?yDGq4fOXYQWos8X9ex1VgHA40ClE+j8fjpgeAqTButgOxGcjlet+yOV9YVZx?= =?us-ascii?Q?sTtn8Rt86W/9hSN8XPFUZAkcaXUL/jOd7Se5BdSDfyPn40MYmJcn5y6yMMDx?= =?us-ascii?Q?zz2Nv02cj3/1Q/6GL44IzWfO+u5V5YixJHstZFrZWm3ufAulFkLPs/SKvHBj?= =?us-ascii?Q?9rkYXzH3Cj478Tezu77cd/BBtYhV1O+9dNcLigEZFTOwgoH06xDjabKXKRM0?= =?us-ascii?Q?SZBjG3dHlKrA8kln80RAKR8aLBm1d/rkBNV558HBuFR69iP2b2+8xlHwvGZT?= =?us-ascii?Q?0v17n//edaDVH0l40AuzCyQcL6F/NtVwh3syE/vaaiwTwiGdOEaTBqI5HjZG?= =?us-ascii?Q?E1jSdHvQOoTKqT3fo2Oe/qDtr50S7GtYQ6vGln0t1yJSsvL2I+7wSMSSEt9V?= =?us-ascii?Q?AWaGaxM0dTA9hpxf0uyd3bvxq9nOWVq5k0dmcUY6N+m2k3GfUBMSdkY6RyL+?= =?us-ascii?Q?Hyl5vEfhDkEEQWxGko/upyZnkQ7uDIUosgqP6tA1Us4aw+Rkuz2s9pd9AwOI?= =?us-ascii?Q?KcPcqLEw8R2L8pY2slsqG6bdas6H7s3/tTmHXahRxisM3GCL6WDph+nhdwMj?= =?us-ascii?Q?B3ZjrghT8PNc+DbEXUx5zMfIoRCqYphTURPKgsS9nJc6JgX1Om2fznm34zIr?= =?us-ascii?Q?d0If0GDFz6UfUJ+phStAyCxkJVQjHsEWZyrLt+HXPE2MPnj4NNb9zwHfL2/H?= =?us-ascii?Q?8mGddroF5Lxy9qUcuovyRLymxEO+MylkgE3ZC8bXI2SGjVXVGBhPxInnu/rn?= =?us-ascii?Q?O5ZncbBYdqwHzZnuuz5rNYPZ97A0vdKH4vFq/qI8QTXuXyfIco4kFlL/zw3F?= =?us-ascii?Q?/44fNixDYQf7zK5BdQQfZY44+oWh9Sv+8/oe2C7zUyAfFesxTuhoT2+zxj26?= =?us-ascii?Q?GSYxiw9cunUpLnlbEF9asnY9FyqG8SjNW8XlwY+q60zA+Ln+Fvb4NstbWvu6?= =?us-ascii?Q?2+mHuehFnVrUbt9Oez0MbbgiqjB6VXIMSavaeQX0LQKPtDoklC+BUyzUkI5n?= =?us-ascii?Q?cfqfDVDkfr1DW0ojvzwqcwgl4JtVAf2qgk9KibcioxYbG39BoqdNY5lXGpgG?= =?us-ascii?Q?sBu8I1lkpRbcJMCdl6eA8eQoxOQxPwHbJkAbRbubdOMP2dY1uKHIvqX1P1bE?= =?us-ascii?Q?Gvs4/ovMrWdAw3p4K/K+EVvMSuWR?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 May 2024 03:52:07.6276 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: a58bb34f-c1a2-4481-3f68-08dc74926454 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB03.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS3PEPF0000C37D.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR12MB7931 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Tue, 14 May 2024 20:52:12 -0700 Resent-From: AbdulLateef.Attar@amd.com Reply-To: devel@edk2.groups.io,AbdulLateef.Attar@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 1l1YAaCWsyEZctpcNCKd0p4mx7686176AA= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=R+cftZsZ; dmarc=pass (policy=none) header.from=groups.io; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.7 as permitted sender) smtp.mailfrom=bounce@groups.io Adds ACPI common driver which generates. Generates CPU topology SSDT table. Generates PCIe topology SSDT table. Generates SPMI table. Cc: Abner Chang Cc: Paul Grimes Signed-off-by: Abdul Lateef Attar --- .../AMD/AmdPlatformPkg/AmdPlatformPkg.dec | 13 +- .../AMD/AmdPlatformPkg/AmdPlatformPkg.dsc | 7 +- .../Universal/Acpi/AcpiCommon/AcpiCommon.c | 226 +++ .../Universal/Acpi/AcpiCommon/AcpiCommon.h | 118 ++ .../Universal/Acpi/AcpiCommon/AcpiCommon.inf | 74 + .../Universal/Acpi/AcpiCommon/CpuSsdt.c | 345 ++++ .../Universal/Acpi/AcpiCommon/PciSsdt.c | 1381 +++++++++++++++++ .../Universal/Acpi/AcpiCommon/Spmi.c | 111 ++ 8 files changed, 2273 insertions(+), 2 deletions(-) create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/A= cpiCommon.c create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/A= cpiCommon.h create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/A= cpiCommon.inf create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/C= puSsdt.c create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/P= ciSsdt.c create mode 100644 Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/S= pmi.c diff --git a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec b/Platform/AMD/= AmdPlatformPkg/AmdPlatformPkg.dec index 4cb66d2a36..83f57f6d0a 100644 --- a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec +++ b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dec @@ -1,7 +1,7 @@ ## @file # AMD Platform common Package DEC file # This is the package provides the AMD edk2 common platform drivers -# and libraries for AMD Server, Clinet and Gaming console platforms. +# and libraries for AMD Server, Client and Gaming console platforms. # # Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserv= ed.
# SPDX-License-Identifier: BSD-2-Clause-Patent @@ -31,3 +31,14 @@ # Platform DSC can set this value to another event GUID. # gAmdPlatformPkgTokenSpaceGuid.PcdAmdDisplayLogoEventGuid|{0xdc, 0xd5, 0x= b3, 0x8e, 0xe7, 0xf4, 0x57, 0x4b, 0xa9, 0xe7, 0x27, 0x39, 0x10, 0xf2, 0x18,= 0x9f}|VOID*|0x00010001 + +[PcdsFixedAtBuild] + # + # IPMI Interface Type + # + # 0 - Unknown + # 1 - KCS + # 2 - SMIC + # 3 - BT + # 4 - SSIF + gAmdPlatformPkgTokenSpaceGuid.PcdIpmiInterfaceType|0|UINT8|0x00020001 diff --git a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc b/Platform/AMD/= AmdPlatformPkg/AmdPlatformPkg.dsc index 40ed5ea07c..99dd5b341f 100644 --- a/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc +++ b/Platform/AMD/AmdPlatformPkg/AmdPlatformPkg.dsc @@ -1,7 +1,7 @@ ## @file # AMD Platform common Package DSC file # This is the package provides the AMD edk2 common platform drivers -# and libraries for AMD Server, Clinet and Gaming console platforms. +# and libraries for AMD Server, Client and Gaming console platforms. # # Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserv= ed.
# SPDX-License-Identifier: BSD-2-Clause-Patent @@ -24,6 +24,8 @@ !include MdePkg/MdeLibs.dsc.inc =20 [LibraryClasses.Common] + AmlLib|DynamicTablesPkg/Library/Common/AmlLib/AmlLib.inf + AcpiHelperLib|DynamicTablesPkg/Library/Common/AcpiHelperLib/AcpiHelperLi= b.inf AlwaysFalseDepexLib|AmdPlatformPkg/Library/BaseAlwaysFalseDepexLib/BaseA= lwaysFalseDepexLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf BaseLib|MdePkg/Library/BaseLib/BaseLib.inf @@ -33,6 +35,7 @@ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf PlatformPKProtectionLib|SecurityPkg/Library/PlatformPKProtectionLibVarPo= licy/PlatformPKProtectionLibVarPolicy.inf @@ -41,6 +44,7 @@ SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBo= otVariableLib.inf SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariablePro= visionLib/SecureBootVariableProvisionLib.inf SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull= .inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplat= e.inf UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBoo= tServicesTableLib.inf UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry= Point.inf @@ -62,6 +66,7 @@ AmdPlatformPkg/Library/BaseAlwaysFalseDepexLib/BaseAlwaysFalseDepexLib.i= nf AmdPlatformPkg/Library/DxePlatformSocLib/DxePlatformSocLibNull.inf AmdPlatformPkg/Library/SimulatorSerialPortLibPort80/SimulatorSerialPortL= ibPort80.inf + AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiCommon.inf AmdPlatformPkg/Universal/SecureBoot/SecureBootDefaultKeysInit/SecureBoot= DefaultKeysInit.inf AmdPlatformPkg/Universal/HiiConfigRouting/AmdConfigRouting.inf AmdPlatformPkg/Universal/LogoDxe/JpegLogoDxe.inf = # Server platform JPEG logo driver diff --git a/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiComm= on.c b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiCommon.c new file mode 100644 index 0000000000..f373115a5f --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiCommon.c @@ -0,0 +1,226 @@ +/** @file + + FV block I/O protocol driver for SPI flash libary. + + Copyright (C) 2023-2024 Advanced Micro Devices, Inc. All rights reserved= . + + SPDX-License-Identifier BSD-2-Clause-Patent +**/ + +#include "AcpiCommon.h" + +EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol; +EFI_ACPI_SDT_PROTOCOL *mAcpiSdtProtocol; + +/** + Locates an existing ACPI Table + + @param[in] Signature - The Acpi table signature + @param[in] OemTableId - The Acpi table OEM Table ID. Ignored if = 0 + @param[out] Table - Table if Found or NULL + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +GetExistingAcpiTable ( + IN UINT32 Signature, + IN UINT64 OemTableId, + OUT EFI_ACPI_SDT_HEADER **Table + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_ACPI_SDT_HEADER *LocalTable; + EFI_ACPI_TABLE_VERSION LocalVersion; + UINTN LocalTableKey; + + Status =3D EFI_NOT_FOUND; + *Table =3D NULL; + + for (Index =3D 0; ; Index++) { + Status =3D mAcpiSdtProtocol->GetAcpiTable (Index, &LocalTable, &LocalV= ersion, &LocalTableKey); + if (EFI_ERROR (Status)) { + return Status; + } + + if (!(LocalTable->Signature =3D=3D Signature)) { + continue; + } + + // Accept table if OemTableId is zero. + if ((OemTableId =3D=3D 0) || + (CompareMem (&LocalTable->OemTableId, &OemTableId, 8) =3D=3D 0)) + { + *Table =3D LocalTable; + return EFI_SUCCESS; + } + } +} + +/** + Appends generated AML to an existing ACPI Table + + 1. Locate the existing ACPI table + 2. Allocate pool for original table plus new data size + 3. Copy original table to new buffer + 4. Append new data to buffer + 5. Update Table header length (Checksum will be calculated on install) + 6. Uninstall original ACPI table + 7. Install appended table + 8. Free new table buffer since ACPI made a copy. + + @param[in] Signature - The Acpi table signature + @param[in] OemId - The Acpi table OEM ID + @param[in] AmlData - The AML data to append + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +AppendExistingAcpiTable ( + IN UINT32 Signature, + IN UINT64 OemId, + IN EFI_ACPI_DESCRIPTION_HEADER *AmlData + ) +{ + EFI_STATUS Status; + UINTN Index; + EFI_ACPI_SDT_HEADER *Table; + EFI_ACPI_TABLE_VERSION Version; + UINTN TableKey; + EFI_ACPI_SDT_HEADER *ReplacementAcpiTable; + UINT32 ReplacementAcpiTableLength; + UINTN TableHandle; + + for (Index =3D 0; ; Index++) { + Status =3D mAcpiSdtProtocol->GetAcpiTable (Index, &Table, &Version, &T= ableKey); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR: ACPI table not found with signature=3D0= x%X\n", Signature)); + return Status; + } + + if ((Table->Signature =3D=3D Signature) && + (CompareMem (&Table->OemTableId, &OemId, 8) =3D=3D 0)) + { + break; + } + } + + // Calculate new DSDT Length and allocate space + ReplacementAcpiTableLength =3D Table->Length + (UINT32)(AmlData->Length = - sizeof (EFI_ACPI_DESCRIPTION_HEADER)); + ReplacementAcpiTable =3D AllocatePool (ReplacementAcpiTableLength= ); + if (ReplacementAcpiTable =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "ERROR: Unable to allocate Replacement Table spac= e.\n")); + return EFI_OUT_OF_RESOURCES; + } + + // Copy the old DSDT to the new buffer + CopyMem (ReplacementAcpiTable, Table, Table->Length); + // Append new data to DSDT + CopyMem ( + (UINT8 *)ReplacementAcpiTable + Table->Length, + (UINT8 *)AmlData + sizeof (EFI_ACPI_DESCRIPTION_HEADER), + AmlData->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER) + ); + ReplacementAcpiTable->Length =3D ReplacementAcpiTableLength; + + // Uninstall the original DSDT + Status =3D mAcpiTableProtocol->UninstallAcpiTable ( + mAcpiTableProtocol, + TableKey + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR: Unable to uninstall original ACPI Table s= ignature=3D0x%X\n", Signature)); + } else { + // Install ACPI table + Status =3D mAcpiTableProtocol->InstallAcpiTable ( + mAcpiTableProtocol, + ReplacementAcpiTable, + ReplacementAcpiTableLength, + &TableHandle + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ERROR: Unable to re-install ACPI Table signatu= re=3D0x%X\n", Signature)); + } + } + + // Release this copy of table + FreePool (ReplacementAcpiTable); + return Status; +} + +/** + Install common platform SSDTs and DSDT additions + + Place to install all generically identifiable SSDT tables. These tables= will + be programmatically created from UEFI or other resources and should cove= r + many different Processor Family IPs. + + Might need to split this driver into LibraryClasses for each + functionality/SSDT while keeping a single driver to reduce the AmlLib ov= erhead. + + @param[in] ImageHandle - Standard UEFI entry point Image Handle + @param[in] SystemTable - Standard UEFI entry point System Table + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InstallAllAcpiTables ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + // Get Acpi Table Protocol + Status =3D gBS->LocateProtocol ( + &gEfiAcpiTableProtocolGuid, + NULL, + (VOID **)&mAcpiTableProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // Get Acpi SDT Protocol + Status =3D gBS->LocateProtocol ( + &gEfiAcpiSdtProtocolGuid, + NULL, + (VOID **)&mAcpiSdtProtocol + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D InstallCpuAcpi (ImageHandle, SystemTable); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: CPU SSDT install error: Status=3D%r\n", + __FUNCTION__, + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D InstallPciAcpi (ImageHandle, SystemTable); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: PCI SSDT install error: Status=3D%r\n", + __FUNCTION__, + Status + )); + ASSERT_EFI_ERROR (Status); + return Status; + } + + InstallAcpiSpmiTable (); + + return Status; +} diff --git a/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiComm= on.h b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiCommon.h new file mode 100644 index 0000000000..b9db33ac76 --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiCommon.h @@ -0,0 +1,118 @@ +/** @file + + FV block I/O protocol driver for SPI flash libary. + + Copyright (C) 2023-2024 Advanced Micro Devices, Inc. All rights reserved= . + + SPDX-License-Identifier BSD-2-Clause-Patent +**/ + +#ifndef ACPI_COMMON_H_ +#define ACPI_COMMON_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AMD_DSDT_OEMID SIGNATURE_64 ('A', 'm', 'd', = 'T','a','b','l','e') +#define CREATOR_REVISION 2 +#define MAX_LOCAL_STRING_SIZE 20 +#define OEM_REVISION_NUMBER 0 +#define CXL_EARLY_DISCOVERY_TABLE_SIGNATURE SIGNATURE_32 ('C', 'E', 'D', = 'T') /// "CEDT" CXL Early Discovery Table + +extern EFI_ACPI_TABLE_PROTOCOL *mAcpiTableProtocol; +extern EFI_ACPI_SDT_PROTOCOL *mAcpiSdtProtocol; + +/** + Locates an existing ACPI Table + + @param[in] Signature - The Acpi table signature + @param[in] OemTableId - The Acpi table OEM Table ID. Ignored if = 0 + @param[out] Table - Table if Found or NULL + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +GetExistingAcpiTable ( + IN UINT32 Signature, + IN UINT64 OemTableId, + OUT EFI_ACPI_SDT_HEADER **Table + ); + +/** + Appends generated AML to an existing ACPI Table + + 1. Locate the existing ACPI table + 2. Allocate pool for original table plus new data size + 3. Copy original table to new buffer + 4. Append new data to buffer + 5. Update Table header length (Checksum will be calculated on install) + 6. Uninstall original ACPI table + 7. Install appended table + 8. Free new table buffer since ACPI made a copy. + + @param[in] Signature - The Acpi table signature + @param[in] OemId - The Acpi table OEM ID + @param[in] AmlData - The AML data to append + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +AppendExistingAcpiTable ( + IN UINT32 Signature, + IN UINT64 OemId, + IN EFI_ACPI_DESCRIPTION_HEADER *AmlData + ); + +/** + Install CPU devices scoped under \_SB into DSDT + + Determine all the CPU threads and create ACPI Device nodes for each thre= ad. + + @param[in] ImageHandle - Standard UEFI entry point Image Handle + @param[in] SystemTable - Standard UEFI entry point System Table + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InstallCpuAcpi ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Install PCI devices scoped under \_SB into DSDT + + Determine all the PCI Root Bridges and PCI root ports and install resour= ces + including needed _HID, _CID, _UID, _ADR, _CRS and _PRT Nodes. + + @param[in] ImageHandle - Standard UEFI entry point Image Handle + @param[in] SystemTable - Standard UEFI entry point System Table + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InstallPciAcpi ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +VOID +EFIAPI +InstallAcpiSpmiTable ( + VOID + ); + +#endif // ACPI_COMMON_H__ diff --git a/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiComm= on.inf b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiCommon.i= nf new file mode 100644 index 0000000000..2c17dbb500 --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/AcpiCommon.inf @@ -0,0 +1,74 @@ +## @file +# Creates ACPI tables for AMD platforms. +# +# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reser= ved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D AcpiCommon + FILE_GUID =3D 66838F31-1062-415C-957A-CC2871D9E6B7 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D InstallAllAcpiTables + +[Sources.common] + AcpiCommon.c + AcpiCommon.h + CpuSsdt.c + PciSsdt.c + Spmi.c + +[Packages] + AmdPlatformPkg/AmdPlatformPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + MinPlatformPkg/MinPlatformPkg.dec + PcAtChipsetPkg/PcAtChipsetPkg.dec + +[LibraryClasses] + AmlLib + BaseLib + BaseMemoryLib + DebugLib + HobLib + IoLib + MemoryAllocationLib + PcdLib + PlatformSocLib + SortLib + UefiDriverEntryPoint + +[Protocols] + gEfiAcpiSdtProtocolGuid ## CONSUMES + gEfiAcpiTableProtocolGuid ## CONSUMES + gEfiMpServiceProtocolGuid ## CONSUMES + gEfiPciRootBridgeIoProtocolGuid ## CONSUMES + +[Pcd] + gAmdPlatformPkgTokenSpaceGuid.PcdIpmiInterfaceType ## CONSUME= S + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## CONSUME= S + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## CONSUME= S + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## CONSUME= S + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## CONSUME= S + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId ## CONSUME= S + gEfiMdePkgTokenSpaceGuid.PcdIpmiKcsIoBaseAddress ## CONSUME= S + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUME= S + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseSize ## CONSUME= S + gMinPlatformPkgTokenSpaceGuid.PcdIoApicAddress ## CONSUME= S + gMinPlatformPkgTokenSpaceGuid.PcdMaxCpuSocketCount ## CONSUME= S + gMinPlatformPkgTokenSpaceGuid.PcdPcIoApicAddressBase + +[Guids] + gEfiHobListGuid + +[Depex] + gEfiMpServiceProtocolGuid AND + gEfiAcpiTableProtocolGuid AND + gEfiPciRootBridgeIoProtocolGuid AND + gEfiPciEnumerationCompleteProtocolGuid + diff --git a/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/CpuSsdt.= c b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/CpuSsdt.c new file mode 100644 index 0000000000..345fb4f8c9 --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/CpuSsdt.c @@ -0,0 +1,345 @@ +/** @file + + FV block I/O protocol driver for SPI flash libary. + + Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserv= ed. + + SPDX-License-Identifier BSD-2-Clause-Patent +**/ +#include "AcpiCommon.h" + +#include +#include +#include +#include // for CPUID_EXTENDED_TOPOLOGY + +#define AMD_CPUID_EXTENDED_TOPOLOGY_V2 0x26 +#define AMD_CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_CCD 0x04 +#define AMD_CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_CCX 0x03 +#define AMD_CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE 0x05 +#define CREATOR_REVISION 2 +#define DEVICE_BATTERY_BIT 0x0010// Control Me= thod Battery Device Only +#define DEVICE_ENABLED_BIT 0x0002 +#define DEVICE_HEALTH_BIT 0x0008 +#define DEVICE_IN_UI_BIT 0x0004 +#define DEVICE_PRESENT_BIT 0x0001 +#define MAX_TEST_CPU_STRING_SIZE 20 +#define OEM_REVISION_NUMBER 0 + +EFI_PROCESSOR_INFORMATION *mApicIdtoUidMap =3D NULL; +UINT32 mCcdOrder[16] =3D { 0, 4, 8, 12, 2, 6, 1= 0, 14, 3, 7, 11, 15, 1, 5, 9, 13 }; +UINTN mNumberOfCpus =3D 0; +UINTN mNumberOfEnabledCPUs =3D 0; + +/** + Callback compare function. + Compares CCD number of provided arguments. + + @param[in] LocalX2ApicLeft Pointer to Left Buffer. + @param[in] LocalX2ApicRight Pointer to Right Buffer. + @return 0 If both are same + -1 If left value is less than righ value. + 1 If left value is greater than righ value. + +**/ +INTN +EFIAPI +SortByCcd ( + IN CONST VOID *LocalX2ApicLeft, + IN CONST VOID *LocalX2ApicRight + ) +{ + EFI_PROCESSOR_INFORMATION *Left; + EFI_PROCESSOR_INFORMATION *Right; + UINT32 Index; + UINT32 LeftCcdIndex; + UINT32 RightCcdIndex; + + Left =3D (EFI_PROCESSOR_INFORMATION *)LocalX2ApicLeft; + Right =3D (EFI_PROCESSOR_INFORMATION *)LocalX2ApicRight; + + // Get the CCD Index number + LeftCcdIndex =3D MAX_UINT32; + for (Index =3D 0; Index < ARRAY_SIZE (mCcdOrder); Index++) { + if (Left->ExtendedInformation.Location2.Die =3D=3D mCcdOrder[Index]) { + LeftCcdIndex =3D Index; + break; + } + } + + RightCcdIndex =3D MAX_UINT32; + for (Index =3D 0; Index < ARRAY_SIZE (mCcdOrder); Index++) { + if (Right->ExtendedInformation.Location2.Die =3D=3D mCcdOrder[Index]) = { + RightCcdIndex =3D Index; + break; + } + } + + // Now compare for quick sort + if (LeftCcdIndex < RightCcdIndex) { + return -1; + } + + if (LeftCcdIndex > RightCcdIndex) { + return 1; + } + + return 0; +} + +/** + Generate ApicId to Processor UID map. + + @retval EFI_SUCCESS - ApicId to Processor UID map generated su= ccessfully. + @retval EFI_NOT_FOUND - MP Service Protocol not found. + @retval EFI_OUT_OF_RESOURCES - Memory allocation failed. +**/ +EFI_STATUS +GenerateApicIdtoUidMap ( + VOID + ) +{ + EFI_MP_SERVICES_PROTOCOL *MpService; + EFI_STATUS Status; + UINTN Index; + + // Get MP service + Status =3D gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID = **)&MpService); + if (EFI_ERROR (Status) || (MpService =3D=3D NULL)) { + return EFI_NOT_FOUND; + } + + // Load MpServices + Status =3D MpService->GetNumberOfProcessors (MpService, &mNumberOfCpus, = &mNumberOfEnabledCPUs); + if (EFI_ERROR (Status)) { + return Status; + } + + DEBUG ((DEBUG_ERROR, "%a: NumberOfCpus =3D %d mNumberOfEnabledCPUs =3D %= d\n", __func__, mNumberOfCpus, mNumberOfEnabledCPUs)); + + mApicIdtoUidMap =3D AllocateZeroPool (mNumberOfCpus * sizeof (EFI_PROCES= SOR_INFORMATION)); + if (mApicIdtoUidMap =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index =3D 0; Index < mNumberOfCpus; Index++) { + Status =3D MpService->GetProcessorInfo ( + MpService, + Index | CPU_V2_EXTENDED_TOPOLOGY, + &mApicIdtoUidMap[Index] + ); + } + + if (FixedPcdGet32 (PcdMaxCpuSocketCount) > 1) { + /// Sort by CCD location + PerformQuickSort (mApicIdtoUidMap, mNumberOfCpus/2, sizeof (EFI_PROCES= SOR_INFORMATION), SortByCcd); + PerformQuickSort (mApicIdtoUidMap+(mNumberOfCpus/2), mNumberOfCpus/2, = sizeof (EFI_PROCESSOR_INFORMATION), SortByCcd); + } else { + /// Sort by CCD location + PerformQuickSort (mApicIdtoUidMap, mNumberOfCpus, sizeof (EFI_PROCESSO= R_INFORMATION), SortByCcd); + } + + // Now allocate the Uid + for (Index =3D 0; Index < mNumberOfCpus; Index++) { + // Now make Processor as Uid + mApicIdtoUidMap[Index].ProcessorId =3D Index; + } + + return EFI_SUCCESS; +} + +/** + Install CPU devices scoped under \_SB into DSDT + + Determine all the CPU threads and create ACPI Device nodes for each thre= ad. + + @param[in] ImageHandle - Standard UEFI entry point Image Handle + @param[in] SystemTable - Standard UEFI entry point System Table + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InstallCpuAcpi ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + AML_OBJECT_NODE_HANDLE CpuInstanceNode; + AML_OBJECT_NODE_HANDLE CpuNode; + AML_OBJECT_NODE_HANDLE ScopeNode; + AML_ROOT_NODE_HANDLE RootNode; + CHAR8 *String; + CHAR8 Identifier[MAX_TEST_CPU_STRING_SIZE]; + EFI_ACPI_DESCRIPTION_HEADER *Table; + EFI_MP_SERVICES_PROTOCOL *MpServices; + EFI_STATUS Status; + EFI_STATUS Status1; + UINTN DeviceStatus; + UINTN Index; + UINTN NumberOfEnabledProcessors; + UINTN NumberOfLogicProcessors; + + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + String =3D &Identifier[0]; + + // Get MP service + MpServices =3D NULL; + Status =3D gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (V= OID **)&MpServices); + if (EFI_ERROR (Status) || (MpServices =3D=3D NULL)) { + return EFI_NOT_FOUND; + } + + // Generate ACPI UID Map + Status =3D GenerateApicIdtoUidMap (); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Could not generate ApicId to ProcessorUid ma= p.\n", __func__)); + return EFI_NOT_FOUND; + } + + // Load MpServices + Status =3D MpServices->GetNumberOfProcessors (MpServices, &NumberOfLogic= Processors, &NumberOfEnabledProcessors); + if (EFI_ERROR (Status)) { + return Status; + } + + Status =3D AmlCodeGenDefinitionBlock ( + "SSDT", + "AMD ", + "SSDTPROC", + 0x00, + &RootNode + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenScope ("\\_SB_", RootNode, &ScopeNode); // START: = Scope (\_SB) + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + CpuNode =3D ScopeNode; + + for (Index =3D 0; Index < NumberOfLogicProcessors; Index++) { + // Check for valid Processor under the current socket + if (!mApicIdtoUidMap[Index].StatusFlag) { + continue; + } + + AsciiSPrint (String, MAX_TEST_CPU_STRING_SIZE, "C%03X", Index); + Status =3D AmlCodeGenDevice (String, CpuNode, &CpuInstanceNode); // ST= ART: Device (CXXX) + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // _HID + Status =3D AmlCodeGenNameString ("_HID", "ACPI0007", CpuInstanceNode, = NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + DeviceStatus =3D DEVICE_PRESENT_BIT | DEVICE_IN_UI_BIT; + if (mApicIdtoUidMap[Index].StatusFlag & PROCESSOR_ENABLED_BIT) { + DeviceStatus |=3D DEVICE_ENABLED_BIT; + } + + if (mApicIdtoUidMap[Index].StatusFlag & PROCESSOR_HEALTH_STATUS_BIT) { + DeviceStatus |=3D DEVICE_HEALTH_BIT; + } + + // _UID - Must match ACPI Processor UID in MADT + Status =3D AmlCodeGenNameInteger ("_UID", mApicIdtoUidMap[Index].Proce= ssorId, CpuInstanceNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // _STA - As defined by 6.3.7 + Status =3D AmlCodeGenMethodRetInteger ("_STA", DeviceStatus, 0, FALSE,= 0, CpuInstanceNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // PACK -> Package + Status =3D AmlCodeGenNameInteger ("PACK", mApicIdtoUidMap[Index].Exten= dedInformation.Location2.Package, CpuInstanceNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // CCD_ -> Ccd + Status =3D AmlCodeGenNameInteger ("CCD_", mApicIdtoUidMap[Index].Exten= dedInformation.Location2.Die, CpuInstanceNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // CCX_ -> Ccx + Status =3D AmlCodeGenNameInteger ("CCX_", mApicIdtoUidMap[Index].Exten= dedInformation.Location2.Module, CpuInstanceNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // CORE -> Core Number + Status =3D AmlCodeGenNameInteger ("CORE", mApicIdtoUidMap[Index].Exten= dedInformation.Location2.Core, CpuInstanceNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // THRD -> Thread + Status =3D AmlCodeGenNameInteger ("THRD", mApicIdtoUidMap[Index].Exten= dedInformation.Location2.Thread, CpuInstanceNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + Table =3D NULL; + // Serialize the tree. + Status =3D AmlSerializeDefinitionBlock ( + RootNode, + &Table + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Failed to Serialize SSDT Table Data." + " Status =3D %r\n", + Status + )); + return (Status); + } + + // Cleanup + Status1 =3D AmlDeleteTree (RootNode); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Failed to cleanup AML tree." + " Status =3D %r\n", + Status1 + )); + // If Status was success but we failed to delete the AML Tree + // return Status1 else return the original error code, i.e. Status. + if (!EFI_ERROR (Status)) { + return Status1; + } + } + + Status =3D AppendExistingAcpiTable ( + EFI_ACPI_6_5_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATUR= E, + AMD_DSDT_OEMID, + Table + ); + + return Status; +} diff --git a/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/PciSsdt.= c b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/PciSsdt.c new file mode 100644 index 0000000000..a9d3c83a5e --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/PciSsdt.c @@ -0,0 +1,1381 @@ +/** @file + Creates SSDT table for PCIe devices + + Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserv= ed. + + SPDX-License-Identifier BSD-2-Clause-Patent +**/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "AcpiCommon.h" + +#define MAX_PCI_BUS_NUMBER_PER_SEGMENT 0x100 + +EFI_HANDLE mDriverHandle; + +/** + Collect and sort the root bridge devices + + Does not include the Root Bridge resources + + @param[in, out] RootBridge - RootBridge information pointer + @param[in, out] RootBridgeCount - Number of root bridges + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InternalCollectSortedRootBridges ( + IN OUT AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE **RootBridge, + IN OUT UINTN *RootBridgeCount + ) +{ + UINTN Index; + AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *LocalRootBridge; // do not free + AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *SortedRb; + AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *UnsortedRb; + AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE TempRootBridge; + UINTN LocalRootBridgeCount; + UINTN SortedIndex; + UINTN UnsortedIndex; + EFI_STATUS Status; + + if ((RootBridge =3D=3D NULL) || (RootBridgeCount =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + LocalRootBridge =3D NULL; + LocalRootBridgeCount =3D 0; + Status =3D GetPcieInfo (&LocalRootBridge, &LocalRootBridge= Count); + if (EFI_ERROR (Status) || (LocalRootBridge =3D=3D NULL) || (LocalRootBri= dgeCount =3D=3D 0)) { + DEBUG ((DEBUG_ERROR, "%a:%d Cannot obtain Platform PCIe configuration = information.\n", __func__, __LINE__)); + return EFI_NOT_FOUND; + } + + // Sort by PCIe bus number + for (SortedIndex =3D 0, SortedRb =3D LocalRootBridge; SortedIndex < Loca= lRootBridgeCount; SortedIndex++, SortedRb++) { + for (UnsortedIndex =3D 0, UnsortedRb =3D LocalRootBridge; UnsortedInde= x < LocalRootBridgeCount; UnsortedIndex++, UnsortedRb++) { + if (SortedRb->Object->BaseBusNumber < UnsortedRb->Object->BaseBusNum= ber) { + CopyMem (&TempRootBridge, UnsortedRb, sizeof (AMD_PCI_ROOT_BRIDGE_= OBJECT_INSTANCE)); + CopyMem (UnsortedRb, SortedRb, sizeof (AMD_PCI_ROOT_BRIDGE_OBJECT_= INSTANCE)); + CopyMem (SortedRb, &TempRootBridge, sizeof (AMD_PCI_ROOT_BRIDGE_OB= JECT_INSTANCE)); + } + } + } + + for (Index =3D 0; Index < LocalRootBridgeCount; Index++) { + // Assign Uid values + LocalRootBridge[Index].Uid =3D Index; + } + + *RootBridge =3D LocalRootBridge; + *RootBridgeCount =3D LocalRootBridgeCount; + return EFI_SUCCESS; +} + +/** + Insert Root Bridge interrupts into AML table + + @param[in] RootBridge - Single Root Bridge instance + @param[in, out] GlobalInterruptBase - Global interrupt base + @param[in, out] PciNode - AML tree node + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InternalInsertRootBridgeInterrupts ( + IN AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *RootBridge, + IN OUT UINTN *GlobalInterruptBase, + IN OUT AML_OBJECT_NODE_HANDLE PciNode + ) +{ + AML_OBJECT_NODE_HANDLE PrtNode; + EFI_STATUS Status; + UINTN Index; + + Status =3D AmlCodeGenNamePackage ("_PRT", NULL, &PrtNode); + ASSERT_EFI_ERROR (Status); + + if ((RootBridge->Object->BaseBusNumber =3D=3D 0) && (RootBridge->Object-= >Segment =3D=3D 0)) { + // Package () {0x0014FFFF, 0, 0, 16}, // 0 + 16 + Status =3D AmlAddPrtEntry ( + 0x0014FFFF, + 0, + NULL, + 16, + PrtNode + ); + ASSERT_EFI_ERROR (Status); + + // Package () {0x0014FFFF, 1, 0, 17}, // 0 + 17 + Status =3D AmlAddPrtEntry ( + 0x0014FFFF, + 1, + NULL, + 17, + PrtNode + ); + ASSERT_EFI_ERROR (Status); + + // Package () {0x0014FFFF, 2, 0, 18}, // 0 + 18 + Status =3D AmlAddPrtEntry ( + 0x0014FFFF, + 2, + NULL, + 18, + PrtNode + ); + ASSERT_EFI_ERROR (Status); + + // Package () {0x0014FFFF, 3, 0, 19}, // 0 + 19 + Status =3D AmlAddPrtEntry ( + 0x0014FFFF, + 3, + NULL, + 19, + PrtNode + ); + ASSERT_EFI_ERROR (Status); + } + + /// Add interrupt for Device 0 function 3 (generic to all function) + /// Value is taken from CRB BIOS + /// Fix the "pcie port 0000:XX:XX.3: can't derive routing for PCI INT A"= error + Status =3D AmlAddPrtEntry ( + 0xFFFF, + 0, + NULL, + (UINT32)(RootBridge->GlobalInterruptStart + 1), + PrtNode + ); + ASSERT_EFI_ERROR (Status); + + for (Index =3D 1; Index <=3D RootBridge->RootPortCount; Index++) { + if ((RootBridge->RootPort[Index]->PortPresent =3D=3D 0) && (RootBridge= ->RootPort[Index]->Enabled =3D=3D 0)) { + continue; + } + + // Only insert for Functions 1 - 4 (minus 1) + if (((RootBridge->RootPort[Index]->Function - 1) & ~0x3) =3D=3D 0) { + Status =3D AmlAddPrtEntry ( + (UINT32)((RootBridge->RootPort[Index]->Device << 16) | 0x= 0000FFFF), + (UINT8)(RootBridge->RootPort[Index]->Function - 1), + NULL, + (UINT32)(RootBridge->GlobalInterruptStart + RootBridge->R= ootPort[Index]->EndpointInterruptArray[RootBridge->RootPort[Index]->Functio= n - 1]), + PrtNode + ); + ASSERT_EFI_ERROR (Status); + } + } + + // Attach the _PRT entry. + Status =3D AmlAttachNode (PciNode, PrtNode); + if (EFI_ERROR (Status)) { + AmlDeleteTree (PrtNode); + ASSERT_EFI_ERROR (Status); + } + + PrtNode =3D NULL; + + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + Insert Root Bridge resources into AML table + + @param[in] RootBridge - Single Root Bridge instance + @param[in, out] CrsNode - AML tree node + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InternalInsertRootBridgeResources ( + IN AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *RootBridge, + IN OUT AML_OBJECT_NODE_HANDLE CrsNode + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumHandles; + EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *Io; + UINTN Index; + VOID *Configuration; // Never free = this buffer + EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR *LocalBuffer; + UINTN BaseBusNumber; + + BaseBusNumber =3D ~(UINTN)0; + // Get EFI Pci Root Bridge I/O Protocols + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciRootBridgeIoProtocolGuid, + NULL, + &NumHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // Locate the Root Bridge IO protocol for this root bridge. + LocalBuffer =3D NULL; + Configuration =3D NULL; + for (Index =3D 0; Index < NumHandles; Index++) { + Status =3D gBS->OpenProtocol ( + HandleBuffer[Index], + &gEfiPciRootBridgeIoProtocolGuid, + (VOID **)&Io, + mDriverHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Io->SegmentNumber =3D=3D RootBridge->Object->Segment) { + Status =3D Io->Configuration (Io, &Configuration); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: ERROR: Retrieve Root Bridge Configuratio= n failed\n", __func__)); + return Status; + } + + LocalBuffer =3D Configuration; + while (TRUE) { + if (LocalBuffer->Header.Header.Byte =3D=3D ACPI_END_TAG_DESCRIPTOR= ) { + LocalBuffer =3D NULL; + break; + } else if (LocalBuffer->Header.Header.Byte =3D=3D ACPI_QWORD_ADDRE= SS_SPACE_DESCRIPTOR) { + if ((LocalBuffer->ResType =3D=3D ACPI_ADDRESS_SPACE_TYPE_BUS) && + (LocalBuffer->AddrRangeMin =3D=3D RootBridge->Object->BaseBu= sNumber)) + { + BaseBusNumber =3D LocalBuffer->AddrRangeMin; + break; + } + } + + LocalBuffer++; + } + + if (BaseBusNumber =3D=3D RootBridge->Object->BaseBusNumber) { + break; + } + } + } + + if ((Configuration =3D=3D NULL) || (LocalBuffer =3D=3D NULL)) { + DEBUG ((DEBUG_ERROR, "%a: ERROR: Retrieve Root Bridge Configuration fa= iled\n", __func__)); + return EFI_NOT_FOUND; + } + + LocalBuffer =3D Configuration; + + // All Elements are sizeof (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) exc= ept + // for the End Tag + // Parse through Root Bridge resources and insert them in the ACPI Table + while (TRUE) { + if (LocalBuffer->Header.Header.Byte =3D=3D ACPI_END_TAG_DESCRIPTOR) { + break; + } else if (LocalBuffer->Header.Header.Byte =3D=3D ACPI_QWORD_ADDRESS_S= PACE_DESCRIPTOR) { + if (LocalBuffer->ResType =3D=3D ACPI_ADDRESS_SPACE_TYPE_BUS) { + BaseBusNumber =3D LocalBuffer->AddrRangeMin; + Status =3D AmlCodeGenRdWordBusNumber ( + FALSE, + TRUE, + TRUE, + TRUE, + 0, + (UINT16)LocalBuffer->AddrRangeMin, + (UINT16)LocalBuffer->AddrRangeMax, + (UINT16)LocalBuffer->AddrTranslationOffset, + (UINT16)LocalBuffer->AddrLen, + 0, + NULL, + CrsNode, + NULL + ); + } else if (LocalBuffer->ResType =3D=3D ACPI_ADDRESS_SPACE_TYPE_IO) { + Status =3D AmlCodeGenRdWordIo ( + FALSE, + TRUE, + TRUE, + TRUE, + 3, // entire ranges + 0, + (UINT16)LocalBuffer->AddrRangeMin, + (UINT16)LocalBuffer->AddrRangeMax, + (UINT16)LocalBuffer->AddrTranslationOffset, + (UINT16)LocalBuffer->AddrLen, + 0, + NULL, + TRUE, + TRUE, + CrsNode, + NULL + ); + } else if (LocalBuffer->ResType =3D=3D ACPI_ADDRESS_SPACE_TYPE_MEM) = { + Status =3D AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + FALSE, // non cacheable + TRUE, + 0, + LocalBuffer->AddrRangeMin, + LocalBuffer->AddrRangeMax, + LocalBuffer->AddrTranslationOffset, + LocalBuffer->AddrLen, + 0, + NULL, + 0, + TRUE, + CrsNode, + NULL + ); + } + } else { + DEBUG ((DEBUG_ERROR, "%a: ERROR: Invalid Configuration Entry\n", __f= unc__)); + return EFI_NOT_FOUND; + } + + LocalBuffer++; + } + + if ((RootBridge->Object->Segment =3D=3D 0) && (BaseBusNumber =3D=3D 0)) = { + Status =3D AmlCodeGenRdWordIo ( + FALSE, + TRUE, + TRUE, + FALSE, + 3, // entire ranges + 0, + 0, + 0x0FFF, + 0, + 0x1000, + 0, + NULL, + TRUE, + TRUE, + CrsNode, + NULL + ); + + Status =3D AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + FALSE, // non cacheable + TRUE, + 0, + PcdGet32 (PcdPcIoApicAddressBase), + 0xFED3FFFF, + 0x0, + 0x140000, + 0, + NULL, + 0, + TRUE, + CrsNode, + NULL + ); + + Status =3D AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + FALSE, // non cacheable + TRUE, + 0, + 0xFED45000, + 0xFEDC1FFF, + 0x0, + 0x7D000, + 0, + NULL, + 0, + TRUE, + CrsNode, + NULL + ); + + Status =3D AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + FALSE, // non cacheable + TRUE, + 0, + 0xFEDC7000, + 0xFEDCAFFF, + 0x0, + 0x4000, + 0, + NULL, + 0, + TRUE, + CrsNode, + NULL + ); + + Status =3D AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + FALSE, // non cacheable + TRUE, + 0, + 0xFEDCC000, + 0xFEDFFFFF, + 0x0, + 0x34000, + 0, + NULL, + 0, + TRUE, + CrsNode, + NULL + ); + + Status =3D AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + FALSE, // non cacheable + TRUE, + 0, + 0xFEE01000, + 0xFEFFFFFF, + 0x0, + 0x1FF000, + 0, + NULL, + 0, + TRUE, + CrsNode, + NULL + ); + } + + if (EFI_ERROR (Status)) { + Status =3D EFI_DEVICE_ERROR; + return Status; + } + + return EFI_SUCCESS; +} + +/** + Insert Root Port into the AML table + + @param[in] RootBridge - Single Root Bridge instance + @param[in] GlobalInterruptBase - Base to add to IOAPIC interrupt of= fset + @param[in,out] PciNode - AmlLib table node + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InternalInsertRootPorts ( + IN AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *RootBridge, + IN UINTN GlobalInterruptBase, + IN OUT AML_OBJECT_NODE_HANDLE PciNode + ) +{ + EFI_STATUS Status; + CHAR8 NameSeg[5]; + CHAR8 RpName[15]; + UINTN RPIndex; + UINTN Index; + AML_OBJECT_NODE_HANDLE DeviceNode; + AML_OBJECT_NODE_HANDLE PrtNode; + AML_OBJECT_NODE_HANDLE DsmMethod; + AML_OBJECT_NODE_HANDLE OstMethod; + AML_METHOD_PARAM MethodParam[7]; + + for (RPIndex =3D 1; RPIndex <=3D RootBridge->RootPortCount; RPIndex++) { + if ((RootBridge->RootPort[RPIndex]->PortPresent =3D=3D 0) && (RootBrid= ge->RootPort[RPIndex]->Enabled =3D=3D 0)) { + continue; + } + + CopyMem (NameSeg, "RPxx", AML_NAME_SEG_SIZE + 1); + NameSeg[AML_NAME_SEG_SIZE - 2] =3D AsciiFromHex (RootBridge->RootPort[= RPIndex]->Device & 0xF); + NameSeg[AML_NAME_SEG_SIZE - 1] =3D AsciiFromHex (RootBridge->RootPort[= RPIndex]->Function & 0xF); + + Status =3D AmlCodeGenDevice (NameSeg, PciNode, &DeviceNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenNameInteger ( + "_ADR", + (RootBridge->RootPort[RPIndex]->Device << 16) + RootBridge-= >RootPort[RPIndex]->Function, + DeviceNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Insert Slot User Number _SUN Record. + if (RootBridge->RootPort[RPIndex]->SlotNum !=3D 0) { + Status =3D AmlCodeGenNameInteger ( + "_SUN", + RootBridge->RootPort[RPIndex]->SlotNum, + DeviceNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + // _DSM and _OST, handling for root port EDR feature. + // Device 1 to 4 are external PCIe ports, only include them. + if ((RootBridge->RootPort[RPIndex]->Device > 0) && (RootBridge->RootPo= rt[RPIndex]->Device < 5)) { + DEBUG (( + DEBUG_INFO, + "%a:Add EDR support for Uid 0x%x Addr 0x%x\n", + __func__, + RootBridge->Uid, + ((RootBridge->RootPort[RPIndex]->Device << 16) + RootBridge->RootP= ort[RPIndex]->Function) + )); + + AsciiSPrint ( + RpName, + 5, + "P%01X%01X%01X", + RootBridge->Uid, + RootBridge->RootPort[RPIndex]->Device, + RootBridge->RootPort[RPIndex]->Function + ); + + Status =3D AmlCodeGenNameString ( + "RSTR", + RpName, + DeviceNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenNameInteger ( + "BRB_", + RootBridge->Object->BaseBusNumber, + DeviceNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + /// Create a _DSM method for the root port + Status =3D AmlCodeGenMethodRetNameString ( + "_DSM", + NULL, + 4, + TRUE, + 0, + DeviceNode, + &DsmMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + /// fill the AML_METHOD_PARAM structure to call the \\_SB.HDSM metho= d + ZeroMem (MethodParam, sizeof (MethodParam)); + MethodParam[0].Type =3D AmlMethodParamTypeArg; + MethodParam[0].Data.Arg =3D 0x0; // Arg0 is the first argument t= o the method + MethodParam[1].Type =3D AmlMethodParamTypeArg; + MethodParam[1].Data.Arg =3D 0x1; // Arg1 is the second argument = to the method + MethodParam[2].Type =3D AmlMethodParamTypeArg; + MethodParam[2].Data.Arg =3D 0x2; // Arg2 is the third argument t= o the method + MethodParam[3].Type =3D AmlMethodParamTypeArg; + MethodParam[3].Data.Arg =3D 0x3; // Arg3 is the fourth argument = to the method + MethodParam[4].Type =3D AmlMethodParamTypeInteger; + MethodParam[4].Data.Integer =3D RootBridge->Object->BaseBusNumber; + MethodParam[5].Type =3D AmlMethodParamTypeInteger; + MethodParam[5].Data.Integer =3D (RootBridge->RootPort[RPIndex]->Devi= ce << 16) + RootBridge->RootPort[RPIndex]->Function; + MethodParam[6].Type =3D AmlMethodParamTypeString; + MethodParam[6].Data.Buffer =3D RpName; + /// Call the \\_SB.HDSM method + Status =3D AmlCodeGenInvokeMethod ( + "\\_SB.HDSM", + 7, + MethodParam, + DsmMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + /// Create a _OST method for the root port + Status =3D AmlCodeGenMethodRetNameString ( + "_OST", + NULL, + 3, + TRUE, + 0, + DeviceNode, + &OstMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // fill the AML_METHOD_PARAM structure to call the \\_SB._OST method + ZeroMem (MethodParam, sizeof (MethodParam)); + MethodParam[0].Type =3D AmlMethodParamTypeArg; + MethodParam[0].Data.Arg =3D 0x0; // Arg0 is the first argument t= o the method + MethodParam[1].Type =3D AmlMethodParamTypeArg; + MethodParam[1].Data.Arg =3D 0x1; // Arg1 is the second argument = to the method + MethodParam[2].Type =3D AmlMethodParamTypeInteger; + MethodParam[2].Data.Integer =3D RootBridge->Object->BaseBusNumber; + MethodParam[3].Type =3D AmlMethodParamTypeInteger; + MethodParam[3].Data.Integer =3D (RootBridge->RootPort[RPIndex]->Devi= ce << 16) + RootBridge->RootPort[RPIndex]->Function; + // call the \\_SB._OST method + Status =3D AmlCodeGenInvokeMethod ( + "\\_SB.HOST", + 4, + MethodParam, + OstMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + // Build Root Port _PRT entry and insert in main ACPI Object list + Status =3D AmlCodeGenNamePackage ("_PRT", NULL, &PrtNode); + ASSERT_EFI_ERROR (Status); + + for (Index =3D 0; Index <=3D 3; Index++) { + Status =3D AmlAddPrtEntry ( + 0x0000FFFF, + (UINT8)Index, + NULL, + (UINT32)(GlobalInterruptBase + RootBridge->RootPort[RPInd= ex]->EndpointInterruptArray[Index]), + PrtNode + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + } + } + + // Attach the _PRT entry. + Status =3D AmlAttachNode (DeviceNode, PrtNode); + if (EFI_ERROR (Status)) { + AmlDeleteTree (PrtNode); + ASSERT_EFI_ERROR (Status); + } + + PrtNode =3D NULL; + } + + if (EFI_ERROR (Status)) { + Status =3D EFI_DEVICE_ERROR; + } + + return Status; +} + +/** + Insert CXL Root Bridge into the AML table + + @param[in] RootBridgeHead - RootBridge information pointer + @param[in] RootBridgeCount - Number of root bridges + @param[in,out] PciNode - AmlLib table node + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InternalInsertCxlRootBridge ( + IN AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *RootBridgeHead, + IN UINTN RootBridgeCount, + IN OUT AML_OBJECT_NODE_HANDLE PciNode + ) +{ + AMD_PCI_ADDR PciAddr; + AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *RootBridge; + AML_OBJECT_NODE_HANDLE CrsNode; + AML_OBJECT_NODE_HANDLE DeviceNode; + AML_OBJECT_NODE_HANDLE PackageNode; + CHAR8 NameSeg[5]; + EFI_STATUS Status; + UINT32 EisaId; + UINT8 DevIndex; + UINT8 Index; + AML_METHOD_PARAM MethodParam[7]; + AML_OBJECT_NODE_HANDLE OscMethod; + + DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__)); + ZeroMem ((VOID *)&PciAddr, sizeof (PciAddr)); + + // + // Populate the data structure for the CXL devices in the system to add = to + // the ACPI Table + // + DevIndex =3D 0; + for (Index =3D 0, RootBridge =3D RootBridgeHead; Index < RootBridgeCount= ; Index++, RootBridge++) { + if ((RootBridge->CxlCount =3D=3D 0) || (RootBridge->CxlPortInfo.IsCxl2= =3D=3D TRUE)) { + continue; + } + + DevIndex++; + + CopyMem (NameSeg, "CXLx", AML_NAME_SEG_SIZE + 1); + if (DevIndex < 0x10) { + NameSeg[AML_NAME_SEG_SIZE - 1] =3D AsciiFromHex (DevIndex); + } else { + NameSeg[AML_NAME_SEG_SIZE - 2] =3D AsciiFromHex (DevIndex); + } + + Status =3D AmlCodeGenDevice (NameSeg, PciNode, &DeviceNode); // RootBr= idge + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenNameString ("_HID", "ACPI0016", DeviceNode, NULL)= ; + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenNamePackage ("_CID", DeviceNode, &PackageNode); + ASSERT_EFI_ERROR (Status); + + // Name (_CID, EISAID("PNP0A03")) + Status =3D AmlGetEisaIdFromString ("PNP0A03", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlAddIntegerToNamedPackage (EisaId, PackageNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_CID, EISAID("PNP0A03")) + Status =3D AmlGetEisaIdFromString ("PNP0A08", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlAddIntegerToNamedPackage (EisaId, PackageNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_ADR,
) + Status =3D AmlCodeGenNameInteger ( + "_ADR", + (RootBridge->CxlPortInfo.EndPointBDF.Address.Device << 16) = + RootBridge->CxlPortInfo.EndPointBDF.Address.Function, + DeviceNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_UID, ) + Status =3D AmlCodeGenNameInteger ("_UID", DevIndex, DeviceNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_BBN, ) + Status =3D AmlCodeGenNameInteger ( + "_BBN", + RootBridge->CxlPortInfo.EndPointBDF.Address.Bus, + DeviceNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_SEG, ) + Status =3D AmlCodeGenNameInteger ( + "_SEG", + RootBridge->Object->BaseBusNumber / MAX_PCI_BUS_NUMBER_PER_= SEGMENT, + DeviceNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_PXM, SocketId>) + PciAddr.Address.Bus =3D (UINT32)RootBridge->Object->BaseBusNumber; + PciAddr.Address.Segment =3D (UINT32)RootBridge->Object->Segment; + + Status =3D AmlCodeGenNameInteger ( + "_PXM", + RootBridge->PxmDomain, + DeviceNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_CRS, ) + Status =3D AmlCodeGenNameResourceTemplate ("_CRS", DeviceNode, &CrsNod= e); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D InternalInsertRootBridgeResources (RootBridge, CrsNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + /// Create AML code for below method + /// Method (_OSC, 4, NotSerialized, 4) // _OSC: Operating= System Capabilities + /// { + /// \_SB.OSCI (Arg0, Arg1, Arg2, Arg3) + /// } + Status =3D AmlCodeGenMethodRetNameString ( + "_OSC", + NULL, + 4, + TRUE, + 0, + DeviceNode, + &OscMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // fill the AML_METHOD_PARAM structure to call the \\_SB.OSCI method + ZeroMem (MethodParam, sizeof (MethodParam)); + MethodParam[0].Type =3D AmlMethodParamTypeArg; + MethodParam[0].Data.Arg =3D 0x0; // Arg0 is the first argument to the = method + MethodParam[1].Type =3D AmlMethodParamTypeArg; + MethodParam[1].Data.Arg =3D 0x1; // Arg1 is the second argument to the= method + MethodParam[2].Type =3D AmlMethodParamTypeArg; + MethodParam[2].Data.Arg =3D 0x2; // Arg2 is the third argument to the = method + MethodParam[3].Type =3D AmlMethodParamTypeArg; + MethodParam[3].Data.Arg =3D 0x3; // Arg3 is the fourth argument to the= method + // call the \\_SB.OSCI method + Status =3D AmlCodeGenInvokeMethod ( + "\\_SB.OSCI", + 4, + MethodParam, + OscMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a: Failed with Status: %r, Not Critical return S= UCCESS\n", __func__, Status)); + Status =3D EFI_SUCCESS; + } + + return Status; +} + +/** + Insert Pcie base size into the AML table + + @param[in,out] CrsNode - AmlLib table node + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InternalInsertPciExpressBaseSize ( + IN OUT AML_OBJECT_NODE_HANDLE CrsNode + ) +{ + EFI_STATUS Status; + UINT64 RangeLen; + UINT64 RangeMax; + UINT64 RangeMin; + + RangeMin =3D PcdGet64 (PcdPciExpressBaseAddress); + RangeLen =3D PcdGet64 (PcdPciExpressBaseSize); + RangeMax =3D RangeMin + RangeLen - 1; + + Status =3D AmlCodeGenRdQWordMemory ( + FALSE, + TRUE, + TRUE, + TRUE, + FALSE, // non cacheable + TRUE, + 0x0, + RangeMin, + RangeMax, + 0x0, + RangeLen, + 0, + NULL, + 0, + TRUE, + CrsNode, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +/** + Install PCI devices scoped under \_SB into DSDT + + Determine all the PCI Root Bridges and PCI root ports and install resour= ces + including needed _HID, _CID, _UID, _ADR, _CRS and _PRT Nodes. + + @param[in] ImageHandle - Standard UEFI entry point Image Handle + @param[in] SystemTable - Standard UEFI entry point System Table + + @retval EFI_SUCCESS, various EFI FAILUREs. +**/ +EFI_STATUS +EFIAPI +InstallPciAcpi ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + AMD_PCI_ADDR PciAddr; + AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *RootBridge; + AMD_PCI_ROOT_BRIDGE_OBJECT_INSTANCE *RootBridgeHead; + AML_OBJECT_NODE_HANDLE AmdmNode; + AML_OBJECT_NODE_HANDLE CrsNode; + AML_OBJECT_NODE_HANDLE PackageNode; + AML_OBJECT_NODE_HANDLE PciNode; + AML_OBJECT_NODE_HANDLE ScopeNode; + AML_OBJECT_NODE_HANDLE CxldNode; + AML_OBJECT_NODE_HANDLE DsmMethod; + AML_ROOT_NODE_HANDLE RootNode; + CHAR8 AslName[AML_NAME_SEG_SIZE + 1]; + EFI_ACPI_DESCRIPTION_HEADER *Table; + EFI_ACPI_SDT_HEADER *SdtTable; + EFI_STATUS Status; + EFI_STATUS Status1; + UINT32 EisaId; + UINTN GlobalInterruptBase; + UINTN RbIndex; + UINTN RootBridgeCount; + AML_METHOD_PARAM MethodParam[7]; + AML_OBJECT_NODE_HANDLE OscMethod; + + DEBUG ((DEBUG_INFO, "%a: Entry\n", __func__)); + + Status =3D AmlCodeGenDefinitionBlock ( + "SSDT", + "AMD ", + "AmdTable", + 0x00, + &RootNode + ); + ASSERT_EFI_ERROR (Status); + + ZeroMem ((VOID *)&PciAddr, sizeof (PciAddr)); + mDriverHandle =3D ImageHandle; + GlobalInterruptBase =3D 0; + + Status =3D InternalCollectSortedRootBridges (&RootBridgeHead, &RootBridg= eCount); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenScope ("\\_SB_", RootNode, &ScopeNode); // START: = Scope (\_SB) + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Create Root Bridge PCXX devices + for (RbIndex =3D 0, RootBridge =3D RootBridgeHead; RbIndex < RootBridgeC= ount; RbIndex++, RootBridge++) { + GlobalInterruptBase =3D RootBridge->GlobalInterruptStart; + // Make sure there is always PCI0 since this is a defacto standard. An= d + // therefore PCI0-PCIF and then PC10-PCFF + CopyMem (AslName, "PCIx", AML_NAME_SEG_SIZE + 1); + AslName[AML_NAME_SEG_SIZE - 1] =3D AsciiFromHex (RootBridge->Uid & 0xF= ); + if (RootBridge->Uid > 0xF) { + AslName[AML_NAME_SEG_SIZE - 2] =3D AsciiFromHex ((RootBridge->Uid >>= 4) & 0xF); + } + + Status =3D AmlCodeGenDevice (AslName, ScopeNode, &PciNode); // RootBri= dge + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + if ((RootBridge->CxlCount > 0) && (RootBridge->CxlPortInfo.IsCxl2 =3D= =3D TRUE)) { + Status =3D AmlCodeGenNameString ("_HID", "ACPI0016", PciNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenNamePackage ("_CID", PciNode, &PackageNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + } + + // Name (_CID, EISAID("PNP0A03")) + Status =3D AmlGetEisaIdFromString ("PNP0A03", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlAddIntegerToNamedPackage (EisaId, PackageNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_CID, EISAID("PNP0A03")) + Status =3D AmlGetEisaIdFromString ("PNP0A08", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlAddIntegerToNamedPackage (EisaId, PackageNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } else { + // Name (_HID, EISAID("PNP0A08")) + Status =3D AmlGetEisaIdFromString ("PNP0A08", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenNameInteger ("_HID", EisaId, PciNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_CID, EISAID("PNP0A03")) + Status =3D AmlGetEisaIdFromString ("PNP0A03", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenNameInteger ("_CID", EisaId, PciNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + // Name (_UID, ) + Status =3D AmlCodeGenNameInteger ("_UID", RootBridge->Uid, PciNode, NU= LL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_BBN, ) + Status =3D AmlCodeGenNameInteger ( + "_BBN", + RootBridge->Object->BaseBusNumber, + PciNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_SEG, ) + Status =3D AmlCodeGenNameInteger ( + "_SEG", + RootBridge->Object->Segment, + PciNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_PXM, SocketId>) + PciAddr.Address.Bus =3D (UINT32)RootBridge->Object->BaseBusNumber; + PciAddr.Address.Segment =3D (UINT32)RootBridge->Object->Segment; + + Status =3D AmlCodeGenNameInteger ( + "_PXM", + RootBridge->PxmDomain, + PciNode, + NULL + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_CRS, ) + Status =3D AmlCodeGenNameResourceTemplate ("_CRS", PciNode, &CrsNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D InternalInsertRootBridgeResources (RootBridge, CrsNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_PRT, ) + Status =3D InternalInsertRootBridgeInterrupts (RootBridge, &GlobalInte= rruptBase, PciNode); + ASSERT_EFI_ERROR (Status); + + // Create Root Port PXXX devices + // Name (_ADR, ) + // Name (_PRT, ) + // Needs to be offset by previous IOAPICs interrupt count + InternalInsertRootPorts (RootBridge, RootBridge->GlobalInterruptStart,= PciNode); + + /// AML code to generate _OSC method + /// Method (_OSC, 4, NotSerialized, 4) // _OSC: Operating= System Capabilities + /// { + /// \_SB.OSCI (Arg0, Arg1, Arg2, Arg3) + /// } + Status =3D AmlCodeGenMethodRetNameString ( + "_OSC", + NULL, + 4, + TRUE, + 0, + PciNode, + &OscMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // fill the AML_METHOD_PARAM structure to call the \\_SB.OSCI method + ZeroMem (MethodParam, sizeof (MethodParam)); + MethodParam[0].Type =3D AmlMethodParamTypeArg; + MethodParam[0].Data.Arg =3D 0x0; // Arg0 is the first argument to the = method + MethodParam[1].Type =3D AmlMethodParamTypeArg; + MethodParam[1].Data.Arg =3D 0x1; // Arg1 is the second argument to the= method + MethodParam[2].Type =3D AmlMethodParamTypeArg; + MethodParam[2].Data.Arg =3D 0x2; // Arg2 is the third argument to the = method + MethodParam[3].Type =3D AmlMethodParamTypeArg; + MethodParam[3].Data.Arg =3D 0x3; // Arg3 is the fourth argument to the= method + // call the \\_SB.OSCI method + Status =3D AmlCodeGenInvokeMethod ( + "\\_SB.OSCI", + 4, + MethodParam, + OscMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + Status =3D GetExistingAcpiTable ( + CXL_EARLY_DISCOVERY_TABLE_SIGNATURE, + 0, + &SdtTable + ); + if (!EFI_ERROR (Status)) { + // CXL Root Device Specific Methods (_DSM) + Status =3D AmlCodeGenDevice ("CXLD", ScopeNode, &CxldNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // _DSM Functions that are associated with the CXL Root Device (HID=3D= "ACPI0017") + Status =3D AmlCodeGenNameString ("_HID", "ACPI0017", CxldNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Create a _DSM method + Status =3D AmlCodeGenMethodRetNameString ( + "_DSM", + NULL, + 4, + TRUE, + 0, + CxldNode, + &DsmMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // fill the AML_METHOD_PARAM structure to call the \\_SB.HDSM method + ZeroMem (MethodParam, sizeof (MethodParam)); + MethodParam[0].Type =3D AmlMethodParamTypeArg; + MethodParam[0].Data.Arg =3D 0x0; // Arg0 is the first argument to = the method + MethodParam[1].Type =3D AmlMethodParamTypeArg; + MethodParam[1].Data.Arg =3D 0x1; // Arg1 is the second argument to= the method + MethodParam[2].Type =3D AmlMethodParamTypeArg; + MethodParam[2].Data.Arg =3D 0x2; // Arg2 is the third argument to = the method + MethodParam[3].Type =3D AmlMethodParamTypeArg; + MethodParam[3].Data.Arg =3D 0x3; // Arg3 is the fourth argument to= the method + // + // Call the \\_SB.HDSM method + // The CXL DSM will look for UUID: f365f9a6-a7de-4071-a66a-b40c0b4f8e5= 2 + // + Status =3D AmlCodeGenInvokeMethod ( + "\\_SB.HDSM", + 4, + MethodParam, + DsmMethod + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + } + + // + // CXL device are added as Root Bridges but are not part of + // the AMD PCI Resource Protocol + // + InternalInsertCxlRootBridge (RootBridgeHead, RootBridgeCount, ScopeNode)= ; + + // Add Pcie Base Size + Status =3D AmlCodeGenDevice ("AMDM", ScopeNode, &AmdmNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_HID, EISAID("PNP0C02")) + Status =3D AmlGetEisaIdFromString ("PNP0C02", &EisaId); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenNameInteger ("_HID", EisaId, AmdmNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + // Name (_UID, ) + Status =3D AmlCodeGenNameInteger ("_UID", 0, AmdmNode, NULL); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D AmlCodeGenNameResourceTemplate ("_CRS", AmdmNode, &CrsNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Status =3D InternalInsertPciExpressBaseSize (CrsNode); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return Status; + } + + Table =3D NULL; + // Serialize the tree. + Status =3D AmlSerializeDefinitionBlock ( + RootNode, + &Table + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Failed to Serialize SSDT Table Data." + " Status =3D %r\n", + Status + )); + return (Status); + } + + // Cleanup + Status1 =3D AmlDeleteTree (RootNode); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SSDT-PCI: Failed to cleanup AML tree." + " Status =3D %r\n", + Status1 + )); + // If Status was success but we failed to delete the AML Tree + // return Status1 else return the original error code, i.e. Status. + if (!EFI_ERROR (Status)) { + return Status1; + } + } + + FreePool (RootBridgeHead); + + Status =3D AppendExistingAcpiTable ( + EFI_ACPI_6_5_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATUR= E, + AMD_DSDT_OEMID, + Table + ); + + return Status; +} diff --git a/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/Spmi.c b= /Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/Spmi.c new file mode 100644 index 0000000000..3520f29631 --- /dev/null +++ b/Platform/AMD/AmdPlatformPkg/Universal/Acpi/AcpiCommon/Spmi.c @@ -0,0 +1,111 @@ +/** @file + + FV block I/O protocol driver for SPI flash libary. + + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. + + SPDX-License-Identifier BSD-2-Clause-Patent +**/ +#include +#include +#include "AcpiCommon.h" + +EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_TABLE gSpmi =3D { + { + EFI_ACPI_6_5_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE, + sizeof (EFI_ACPI_SERVICE_PROCESSOR_MANAGEMENT_INTERFACE_TABLE), + 5, + // + // Checksum will be updated at runtime + // + 0x00, + // + // It is expected that these values will be programmed at runtime + // + { 'A', 'M', 'D', 'I', 'N', 'C' }, + SIGNATURE_64 ('S', 'P', 'M', 'I', 'T', 'a', 'b', 'l'), // updated duri= ng installation + 0x00, // Spmi revisio= n, + SIGNATURE_32 ('A', 'M', 'D', ' '), + 0x00 // OEM Revision + }, + 0x00, // Interface type + 0x01, // Reserved + 0x0200, // IPMI specification revision + 0x00, // InterruptType + 0x00, // Gpe + 0x00, // Reserved2 + 0x00, // PciDeviceFlag or _UID + 0x00, // GlobalSystemInterrupt + { // BaseAddress + EFI_ACPI_6_5_SYSTEM_IO, + 0x08, // BASE_ADDRESS_BIT_WIDTH, + 0x00, // BASE_ADDRESS_BIT_OFFSET, + 0x00, // RESERVED_BYTE, + 0x0CA2 // BASE_ADDRESS_ADDRESS, + }, + { + { 0x00000000 } + }, + 0x00 +}; + +/** + Installs the ACPI SPMI Table to the System Table. +**/ +VOID +EFIAPI +InstallAcpiSpmiTable ( + VOID + ) +{ + UINT64 AcpiTableOemId; + UINTN TurnKey; + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTablProtocol; + + if (!PcdGet8 (PcdIpmiInterfaceType)) { + return; + } + + Status =3D gBS->LocateProtocol ( + &gEfiAcpiTableProtocolGuid, + NULL, + (VOID **)&AcpiTablProtocol + ); + if (EFI_ERROR (Status)) { + // return if ACPI protocol not found + return; + } + + DEBUG ((DEBUG_ERROR, "Installing ACPI SPMI Table.\n")); + // OEM info + CopyMem ( + (VOID *)&gSpmi.Header.OemId, + PcdGetPtr (PcdAcpiDefaultOemId), + sizeof (gSpmi.Header.OemId) + ); + + AcpiTableOemId =3D PcdGet64 (PcdAcpiDefaultOemTableId); + CopyMem ( + (VOID *)&gSpmi.Header.OemTableId, + (VOID *)&AcpiTableOemId, + sizeof (gSpmi.Header.OemTableId) + ); + + gSpmi.Header.OemRevision =3D 0; + gSpmi.Header.CreatorId =3D PcdGet32 (PcdAcpiDefaultCreatorId); + gSpmi.Header.CreatorRevision =3D PcdGet32 (PcdAcpiDefaultCreatorRevision= ); + + gSpmi.InterfaceType =3D PcdGet8 (PcdIpmiInterfaceType); + gSpmi.BaseAddress.Address =3D PcdGet16 (PcdIpmiKcsIoBaseAddress); + // + // Add table + // + Status =3D AcpiTablProtocol->InstallAcpiTable ( + AcpiTablProtocol, + &gSpmi, + sizeof (EFI_ACPI_SERVICE_PROCESSOR_MANAGEME= NT_INTERFACE_TABLE), + &TurnKey + ); + ASSERT_EFI_ERROR (Status); +} --=20 2.34.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 (#118906): https://edk2.groups.io/g/devel/message/118906 Mute This Topic: https://groups.io/mt/106108335/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-