From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (NAM11-BN8-obe.outbound.protection.outlook.com [40.107.236.40]) by mx.groups.io with SMTP id smtpd.web10.20510.1660681116516684608 for ; Tue, 16 Aug 2022 13:18:36 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nvidia.com header.s=selector2 header.b=CxXMUoQf; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: nvidia.com, ip: 40.107.236.40, mailfrom: username@nvidia.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cx7nqZTfFSGukwotzIgE/bjUJpOCH/plibsTXfgbMHfynBEnM6GI0aiPiy0vlKg5VE1IFS5uMDLdjpFxeavqdqTi7YSjPSUghWail5WYF3xsZ+c8zxp9+oHYwu8HN1q7A9hIt2lh3rI2nrO0hwx/JrWTMFtbyBKrZ5Jfre1X2aiCcAkD4Y9DZxUIsObWPr90n0ZvWsuLLWt/2UGdcoo+PiSsccHFmRmwCwRHwz5lFKxEVV9DwYA2vQOJaRYzZRkG04z5iygpyiclE4kjo0J9HYp3FfQm0iEeQl/gUQFuDLe4SnI0mQmzkD+fnOv5VxFoxgwac9DGAGypPIOWFt2hWw== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=J34DKyv0HEEoQprQ6DUjh+MkhqO4wT+N4NYwgiJEJ3I=; b=UNwKiFPOXN2wzk7exAoIYQE6RqnTRcBTrVH6HpKRpmT7uMgxBpL0KM1fJoXbR06IYgV37n4hOjRHNOSCJJGseedlHl5Yb5qXATExikej76J6CVNH6ihsB0wZkFa06STluaA4UVQDO0Jr+3udS6iS1A6YZMmQ5+IwLaJVaAlObZmCOyJIQEDKUvWLLynUcc+o67q+pBLSOLkZhUjEcjhuItAIvBsGKwUoFHI7AaqP8u+yJIdctXZiXRJNcaozjNNbm/vA+e1VzWCfZZLIQ0Z33AEh050AUi44caPvYv1Eqb+Iy1a+g6/9cxp5U0/qO3SffGP10peA8vSjpmhd8HMUpg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 12.22.5.235) smtp.rcpttodomain=intel.com smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=J34DKyv0HEEoQprQ6DUjh+MkhqO4wT+N4NYwgiJEJ3I=; b=CxXMUoQfkHAY92XDLNUWRaTtH7eerxZ4+WkSq+pbKonQZeEpcKRzBRIVwqxupevPXbOH5InG/tqwyuyB6dv5n8MP3hQ8AF/wCakG9gN4iHm+23ZpdaV/30oUu9tWoQ/oBKJsZnloHg4A+G9k411BKxi/sPYQKKkztZ5GVZfnVubgCc2vLD9L+Cx0tvYTYIzpZI8LnWCOAAOvPvYAjk7pEMnLAEPxNnwX3mtPrckDJhgLqIS9bbyoaD+vDVm/D5LxTfPALbfY9vi8NlGYKgs8Qax3RWCN6FcXkp/EFToKr4SlSpHcTctkk6EYcxLhTaUpI57pnHWxa5NeG+PehsN1mw== Received: from DS7PR05CA0053.namprd05.prod.outlook.com (2603:10b6:8:2f::34) by BN8PR12MB4978.namprd12.prod.outlook.com (2603:10b6:408:76::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5525.10; Tue, 16 Aug 2022 20:18:33 +0000 Received: from DM6NAM11FT056.eop-nam11.prod.protection.outlook.com (2603:10b6:8:2f:cafe::6e) by DS7PR05CA0053.outlook.office365.com (2603:10b6:8:2f::34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5546.12 via Frontend Transport; Tue, 16 Aug 2022 20:18:33 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 12.22.5.235) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 12.22.5.235 as permitted sender) receiver=protection.outlook.com; client-ip=12.22.5.235; helo=mail.nvidia.com; pr=C Received: from mail.nvidia.com (12.22.5.235) by DM6NAM11FT056.mail.protection.outlook.com (10.13.173.99) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.5525.11 via Frontend Transport; Tue, 16 Aug 2022 20:18:32 +0000 Received: from rnnvmail204.nvidia.com (10.129.68.6) by DRHQMAIL107.nvidia.com (10.27.9.16) with Microsoft SMTP Server (TLS) id 15.0.1497.38; Tue, 16 Aug 2022 20:18:32 +0000 Received: from rnnvmail205.nvidia.com (10.129.68.10) by rnnvmail204.nvidia.com (10.129.68.6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Tue, 16 Aug 2022 13:18:31 -0700 Received: from swatisrik-X299-A.nvidia.com (10.127.8.9) by mail.nvidia.com (10.129.68.10) with Microsoft SMTP Server id 15.2.986.29 via Frontend Transport; Tue, 16 Aug 2022 13:18:31 -0700 From: Name To: , , , , , CC: Swatisri Kantamsetti Subject: [PATCH 2/2] Dynamic Tbl Mgr: MPAM: MPAM Generator and supporting files Date: Tue, 16 Aug 2022 14:18:22 -0600 Message-ID: <6fcb277bec0d58c11a6af6b2cbbea57177f3722e.1660667637.git.swatisrik@nvidia.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <7f8a5c9bbdf1a1f01c6fc822fa298067d280079a.1660667637.git.swatisrik@nvidia.com> References: <7f8a5c9bbdf1a1f01c6fc822fa298067d280079a.1660667637.git.swatisrik@nvidia.com> Return-Path: username@nvidia.com MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0c250bb3-c6ae-4f57-b6e6-08da7fc47e09 X-MS-TrafficTypeDiagnostic: BN8PR12MB4978:EE_ X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 6eK8t8TVhu16yip3yMq3qVzIERtWL78oUYdEb3tcsx8h7S6wr5kqe4QIszb5kLTLfsTLRvRq5WLo28Gme7cag8BnZ/ZlmRVDWeVojtbVfxKVT5nzmmD4ElVLNQIovkMQhZJLaSFTivdj5D0dlNJSMarbtUeWxjW6ZwljfqQ8PB1J8bXDQYvZdq/vWsv1pXDipt4OuDNIxJjsinthjHgpMDdD07GidMWxmEqVxcmRXZzALrTbwTCsIynMxDi1DAzvl/vAH5M+XHdl3UarDEntE/2d07YtW9P0s00HMY1jF82fGruyM2K4Mbd4TYUP8fALrqE4itTVC8XJ9+78w9hOsfo1hIyBJfLXWxIy0UoaC4xvyQkbopNBvVLhy48r79CKIzJTQqKvUgHetnM8MC3OBSXkyUiKK5fVxa3wrmwbqXbxI5Wa6qYq9Y0SxU7At7NsEuRUju6686wln/M29AbHoFZsi/BmM2Ty6t55wea639YTf1QfXp/lK9F6dg6+tx+PTqErW8b6LHa6smZpmSp6BbtZNFPxUZ+iQ4mm60zFcgNeJ45/kxsrs8aE7i4IaKKtBoTyFh6Jnir9metd7oApQZCwRBzXEg+vMK1Sr4NpcYJR6Hqajlg+RR+BHNvBWLhIXYG1O2N+TWdedOwYknrBIMlEs2E0eOMFNbh5yz/KtoDh1i9ZraQerc2+gKYJ7BWCSMCeSC67pAH+jASPqBCNpsaCudi3Ut21E/fyKyfJl7tjOpqmoOshP182AaA91AXxQeS/9EQObX0E26zln7u5bbyVVKDX5AjdSkq2xacej1qfVNcdgJarapM5OqCHKZ6MwxcYyC1mKFwChfEPOju5Wg== X-Forefront-Antispam-Report: CIP:12.22.5.235;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:mail.nvidia.com;PTR:InfoNoRecords;CAT:NONE;SFS:(13230016)(4636009)(136003)(376002)(346002)(39860400002)(396003)(36840700001)(46966006)(40470700004)(70206006)(30864003)(5660300002)(316002)(6666004)(70586007)(41300700001)(110136005)(86362001)(8676002)(36756003)(4326008)(2906002)(26005)(8936002)(7696005)(81166007)(356005)(40480700001)(40460700003)(82740400003)(36860700001)(47076005)(2616005)(82310400005)(186003)(83380400001)(107886003)(426003)(478600001)(336012)(36900700001);DIR:OUT;SFP:1101; X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Aug 2022 20:18:32.9823 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 0c250bb3-c6ae-4f57-b6e6-08da7fc47e09 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[12.22.5.235];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT056.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN8PR12MB4978 Content-Type: text/plain From: Swatisri Kantamsetti ACPI header, MSC and Resource Nodes are populated in the MPAM Table Signed-off-by: Swatisri Kantamsetti --- DynamicTablesPkg/DynamicTables.dsc.inc | 2 + DynamicTablesPkg/Include/AcpiTableGenerator.h | 1 + .../Include/ArmNameSpaceObjects.h | 68 ++ .../Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf | 30 + .../Acpi/Arm/AcpiMpamLibArm/MpamGenerator.c | 649 ++++++++++++++++++ .../Acpi/Arm/AcpiMpamLibArm/MpamGenerator.h | 47 ++ 6 files changed, 797 insertions(+) create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.h diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc index 3d4fa0c4c4..745d5f0633 100644 --- a/DynamicTablesPkg/DynamicTables.dsc.inc +++ b/DynamicTablesPkg/DynamicTables.dsc.inc @@ -29,6 +29,7 @@ DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf + DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf @@ -54,6 +55,7 @@ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibArm.inf + NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm.inf diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h index f962dbff57..56d7375b4a 100644 --- a/DynamicTablesPkg/Include/AcpiTableGenerator.h +++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h @@ -94,6 +94,7 @@ typedef enum StdAcpiTableId { EStdAcpiTableIdIort, ///< IORT Generator EStdAcpiTableIdPptt, ///< PPTT Generator EStdAcpiTableIdSrat, ///< SRAT Generator + EStdAcpiTableIdMpam, ///< MPAM Generator EStdAcpiTableIdSsdtSerialPort, ///< SSDT Serial-Port Generator EStdAcpiTableIdSsdtCmn600, ///< SSDT Cmn-600 Generator EStdAcpiTableIdSsdtCpuTopology, ///< SSDT Cpu Topology diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h index 102e0f96be..39a14ed0b3 100644 --- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h @@ -63,6 +63,8 @@ typedef enum ArmObjectID { EArmObjPciInterruptMapInfo, ///< 39 - Pci Interrupt Map Info EArmObjRmr, ///< 40 - Reserved Memory Range Node EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor + EArmObjMscNodeInfo, ///< 40 - Msc Memory System Controller Node Info + EArmObjResNodeInfo, ///< 41 - Res Resource Node Info EArmObjMax } EARM_OBJECT_ID; @@ -1070,6 +1072,72 @@ typedef struct CmArmRmrDescriptor { UINT64 Length; } CM_ARM_MEMORY_RANGE_DESCRIPTOR; +/** A structure that describes Memory System Controller Node. + + MPAM Memory System Component Nodes are described by + this object. + + ID: EArmObjMscNodeInfo +*/ +typedef struct CmArmMscNodeInfo { + /// An unique token used to identify this object + CM_OBJECT_TOKEN Token; + + /// MPAM Base Address + UINT64 BaseAddress; + /// MMIO Size + UINT32 MmioSize; + /// Overflow Interrupt + UINT32 OverflowInterrupt; + /// Overflow Interrupt Flags + UINT32 OverflowInterruptFlags; + /// Overflow Interrupt Affinity + UINT32 OverflowInterruptAff; + /// Error Interrupt + UINT32 ErrorInterrupt; + /// Error Interrupt Flags + UINT32 ErrorInterruptFlags; + /// Error Interrupt Affinity + UINT32 ErrorInterruptAff; + /// Not Ready Signal time + UINT32 MaxNRdyUsec; + /// Linked Device HWID + UINT64 LinkedDeviceHwId; + /// Linked Device Instance ID + UINT32 LinkedDeviceInstanceHwId; + /// Number of Resource nodes + UINT32 NumResourceNodes; + /// Reference token for the list of resource nodes + //CM_OBJECT_TOKEN ResourceNodeListToken; + +} CM_ARM_MSC_NODE_INFO; + +/** A structure that describes Memory System Controller Node. + + MPAM Memory System Component Nodes are described by + this object. + + ID: EArmObjResNodeInfo +*/ +typedef struct CmArmResNodeInfo { + /// An unique token used to identify this object + CM_OBJECT_TOKEN Token; + + /// Identifier + UINT32 Identifier; + /// RIS Index + UINT8 RisIndex; + /// Locator Type + UINT8 LocatorType; + /// Locator + UINT64 Locator; + /// Num functional dependencies + UINT32 NumFuncDep; + /// Reference token for the list of resource nodes + CM_OBJECT_TOKEN FuncDepListToken; + +} CM_ARM_RESOURCE_NODE_INFO; + #pragma pack() #endif // ARM_NAMESPACE_OBJECTS_H_ diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf new file mode 100644 index 0000000000..480130dc21 --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf @@ -0,0 +1,30 @@ +## @file +# MPAM Table Generator Inf file +# +# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2022, ARM Limited. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = AcpiMpamLibArm + FILE_GUID = 02d0c79f-41cd-45c9-9835-781229c619d1 + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = NULL|DXE_DRIVER + CONSTRUCTOR = AcpiMpamLibConstructor + DESTRUCTOR = AcpiMpamLibDestructor + +[Sources] + MpamGenerator.c + MpamGenerator.h + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + DynamicTablesPkg/DynamicTablesPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.c new file mode 100644 index 0000000000..db3e8e95bc --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.c @@ -0,0 +1,649 @@ +/** @file + MPAM Table Generator + + Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + Copyright (c) 2022, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.4 Specification, January 2021 + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include + +#include "MpamGenerator.h" + +/** + ARM standard MPAM Generator + + Requirements: + The following Configuration Manager Object(s) are used by this Generator: + - EArmObjMscNodeInfo (REQUIRED) + - EArmObjResNodeInfo +*/ + +/** + This macro expands to a function that retrieves the MSC Node information + from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjMscNodeInfo, + CM_ARM_MSC_NODE_INFO + ); + +/** + This macro expands to a function that retrieves the Resource Node + information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjResNodeInfo, + CM_ARM_RESOURCE_NODE_INFO + ); + +/** + Returns the size of the MPAM Memory System Controller (MSC) Node + + @param [in] Node Pointer to MSC Node Info CM object + + @retval Size of the MSC Node in bytes. +**/ +STATIC +UINT32 +GetMscNodeSize ( + IN CONST CM_ARM_MSC_NODE_INFO *Node + ) +{ + ASSERT (Node != NULL); + + // + return (UINT32)(sizeof (EFI_ACPI_6_4_MPAM_MSC_NODE) + + Node->NumResourceNodes * sizeof (EFI_ACPI_6_4_MPAM_RESOURCE_NODE)); +} + +/** Returns the total size required for the MSC and + updates the Node Indexer. + + This function calculates the size required for the node group + and also populates the Node Indexer array with offsets for the + individual nodes. + + @param [in] NodeStartOffset Offset from the start of the + MPAM where this node group starts. + @param [in] NodeList Pointer to MSC Group node list. + @param [in] NodeCount Count of the MSC Group nodes. + @param [in, out] NodeIndexer Pointer to the next Node Indexer. + + @retval Total size of the ITS Group Nodes. +**/ +STATIC +UINT64 +GetSizeofMscGroupNodes ( + IN CONST UINT32 NodeStartOffset, + IN CONST CM_ARM_MSC_NODE_INFO *NodeList, + IN UINT32 NodeCount, + IN OUT MPAM_NODE_INDEXER **CONST NodeIndexer + ) +{ + UINT64 Size; + + ASSERT (NodeList != NULL); + + Size = 0; + while (NodeCount-- != 0) { + (*NodeIndexer)->Token = NodeList->Token; + (*NodeIndexer)->Object = (VOID *)NodeList; + (*NodeIndexer)->Offset = (UINT32)(Size + NodeStartOffset); + DEBUG (( + DEBUG_INFO, + "MPAM: MSC Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n", + *NodeIndexer, + (*NodeIndexer)->Token, + (*NodeIndexer)->Object, + (*NodeIndexer)->Offset + )); + + Size += GetMscNodeSize (NodeList); + + (*NodeIndexer)++; + NodeList++; + } + + return Size; +} + +/** Update the MSC Group Node Information. + + @param [in] This Pointer to the table Generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Mpam Pointer to MPAM table structure. + @param [in] NodesStartOffset Offset for the start of the Msc Group + Nodes. + @param [in] NodeList Pointer to an array of Msc Group Node + Objects. + @param [in] NodeCount Number of Msc Group Node Objects. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. +**/ +STATIC +EFI_STATUS +AddMscNodes ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_HEADER *Mpam, + IN CONST UINT32 NodesStartOffset, + IN CONST CM_ARM_MSC_NODE_INFO *NodeList, + IN UINT32 NodeCount + ) +{ + EFI_STATUS Status; + EFI_ACPI_6_4_MPAM_MSC_NODE *MscNode; + EFI_ACPI_6_4_MPAM_RESOURCE_NODE *ResourceNodeArray; + CM_ARM_RESOURCE_NODE_INFO *ResourceNodeList; + UINT64 NodeLength; + UINT32 ResourceNodeCount; + + ASSERT (Mpam != NULL); + + MscNode = (EFI_ACPI_6_4_MPAM_MSC_NODE *)((UINT8 *)Mpam + NodesStartOffset); + + // Get the Resource Node info to update the MPAM MSC node + Status = GetEArmObjResNodeInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &ResourceNodeList, + &ResourceNodeCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to add resource nodes info. Status = %r\n", + Status + )); + return Status; + } + + while (NodeCount-- != 0) { + NodeLength = GetMscNodeSize (NodeList); + + if (NodeLength > MAX_UINT16) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: MSC Node length 0x%lx > MAX_UINT16. Status = %r\n", + NodeLength, + Status + )); + return Status; + } + + // Populate the node header + MscNode->Length = (UINT16)NodeLength; + MscNode->Reserved = EFI_ACPI_RESERVED_WORD; + MscNode->Identifier = EFI_ACPI_RESERVED_DWORD; + MscNode->BaseAddress = NodeList->BaseAddress; + MscNode->MmioSize = NodeList->MmioSize; + MscNode->OverflowInterrupt = NodeList->OverflowInterrupt; + MscNode->OverflowInterruptFlags = NodeList->OverflowInterruptFlags; + MscNode->Reserved1 = EFI_ACPI_RESERVED_DWORD; + MscNode->OverflowInterruptAff = NodeList->OverflowInterruptAff; + MscNode->ErrorInterrupt = NodeList->ErrorInterrupt; + MscNode->ErrorInterruptFlags = NodeList->ErrorInterruptFlags; + MscNode->Reserved2 = EFI_ACPI_RESERVED_DWORD; + MscNode->ErrorInterruptAff = NodeList->ErrorInterruptAff; + MscNode->MaxNRdyUsec = NodeList->MaxNRdyUsec; + MscNode->LinkedDeviceHwId = NodeList->LinkedDeviceHwId; + MscNode->LinkedDeviceInstanceHwId = NodeList->LinkedDeviceInstanceHwId; + MscNode->NumResourceNodes = NodeList->NumResourceNodes; + + // ResourceNode List for each MSC + if (MscNode->NumResourceNodes > 0) { + // Resource Node array for this Msc node + ResourceNodeArray = (EFI_ACPI_6_4_MPAM_RESOURCE_NODE *)((UINT8 *)MscNode + sizeof (EFI_ACPI_6_4_MPAM_MSC_NODE)); + // Adding Resource Node content + while ( MscNode->NumResourceNodes-- != 0 ) { + ResourceNodeArray->Identifier = ResourceNodeList->Identifier; + ResourceNodeArray->RisIndex = ResourceNodeList->RisIndex; + ResourceNodeArray->Reserved1 = EFI_ACPI_RESERVED_WORD; + ResourceNodeArray->LocatorType = ResourceNodeList->LocatorType; + ResourceNodeArray->Locator = ResourceNodeList->Locator; + ResourceNodeArray->NumFuncDep = ResourceNodeList->NumFuncDep; + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to add Resource Node List. Status = %r\n", + Status + )); + return Status; + } + + ResourceNodeList++; + ResourceNodeArray++; + } + } + + // Next MSC Node + MscNode = (EFI_ACPI_6_4_MPAM_MSC_NODE *)((UINT8 *)MscNode + MscNode->Length); + NodeList++; + } // Msc Node + + return EFI_SUCCESS; +} + +/** + Construct the MPAM ACPI table. + + This function invokes the Configuration Manager protocol interface + to get the required hardware information for generating the ACPI + table. + + If this function allocates any resources then they must be freed + in the FreeXXXXTableResources function. + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI table generator to be used. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [out] Table Pointer to the constructed ACPI Table. + + @retval EFI_SUCCESS Table generated successfully. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The required object was not found. + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration + Manager is less than the Object size for + the requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildMpamTable ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + EFI_STATUS Status; + UINT64 TableSize; + UINT64 NodeSize; + UINT32 MpamNodeCount; + + UINT32 MscNodeCount; + UINT32 MscNodeOffset; + + EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_HEADER *Mpam; + ACPI_MPAM_GENERATOR *Generator; + CM_ARM_MSC_NODE_INFO *MscNodeList; + MPAM_NODE_INDEXER *NodeIndexer; + + ASSERT ( + (This != NULL) && + (AcpiTableInfo != NULL) && + (CfgMgrProtocol != NULL) && + (Table != NULL) && + (AcpiTableInfo->TableGeneratorId == This->GeneratorID) && + (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature) + ); + + DEBUG (( + DEBUG_ERROR, + "DEBUG PRINT: MPAM: Requested table revision = %d\n", + AcpiTableInfo->AcpiTableRevision + )); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Requested table revision = %d is not supported. " + "Supported table revisions: Minimum = %d. Maximum = %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + Generator = (ACPI_MPAM_GENERATOR *)This; + *Table = NULL; + + // Get the Memory System Controller Node info and update the MPAM + // structure count with MSC Node count (Type 0) + Status = GetEArmObjMscNodeInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &MscNodeList, + &MscNodeCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to get memory system controller node info. Status = %r\n", + Status + )); + goto error_handler; + } + + MpamNodeCount = MscNodeCount; + Generator->MscNodeCount = MscNodeCount; + + // Allocate Node Indexer array + NodeIndexer = (MPAM_NODE_INDEXER *)AllocateZeroPool ( + sizeof (MPAM_NODE_INDEXER) * + MpamNodeCount + ); + if (NodeIndexer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to allocate memory for Node Indexer. Status = %r\n ", + Status + )); + goto error_handler; + } + + DEBUG ((DEBUG_INFO, "MPAM INFO: NodeIndexer = %p\n", NodeIndexer)); + Generator->MpamNodeCount = MpamNodeCount; + Generator->NodeIndexer = NodeIndexer; + + // Calculate the size of the MPAM table + TableSize = sizeof (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_HEADER); + + // Include the size of MSC Nodes and index them + if (Generator->MscNodeCount != 0) { + MscNodeOffset = TableSize; + // Size of MSC nodes. + NodeSize = GetSizeofMscGroupNodes ( + MscNodeOffset, + MscNodeList, + Generator->MscNodeCount, + &NodeIndexer + ); + if (NodeSize > MAX_UINT32) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Invalid Size of Group Nodes. Status = %r\n", + Status + )); + goto error_handler; + } + + TableSize += NodeSize; + + DEBUG (( + DEBUG_INFO, + " MscNodeCount = %d\n" \ + " MscNodeOffset = 0x%x\n", + Generator->MscNodeCount, + MscNodeOffset + )); + } + + DEBUG (( + DEBUG_INFO, + "INFO: MPAM:\n" \ + " MpamNodeCount = %d\n" \ + " TableSize = 0x%X\n", + MpamNodeCount, + TableSize + )); + + if (TableSize > MAX_UINT32) { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: MPAM Table Size 0x%lx > MAX_UINT32," \ + " Status = %r\n", + TableSize, + Status + )); + goto error_handler; + } + + // Allocate the Buffer for the MPAM table + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); + if (*Table == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to allocate memory for MPAM Table. " \ + "Size = %d. Status = %r\n", + TableSize, + Status + )); + goto error_handler; + } + + Mpam = (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_HEADER *)*Table; + + DEBUG (( + DEBUG_INFO, + "MPAM: Mpam = 0x%p. TableSize = 0x%x\n", + Mpam, + TableSize + )); + + // Add ACPI header + Status = AddAcpiHeader ( + CfgMgrProtocol, + This, + &Mpam->Header, + AcpiTableInfo, + TableSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to add ACPI header. Status = %r\n", + Status + )); + goto error_handler; + } + + // Update MPAM table + Mpam->NumNodes = MscNodeCount; + Mpam->NodeOffset = sizeof (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_HEADER); + Mpam->Reserved = EFI_ACPI_RESERVED_DWORD; + + // Add MSC Nodes to the generated table + if (Mpam->NumNodes != 0) { + Status = AddMscNodes ( + This, + CfgMgrProtocol, + Mpam, + MscNodeOffset, + MscNodeList, + MscNodeCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to add MSC Nodes. Status = %r\n", + Status + )); + goto error_handler; + } + } + + return Status; + +error_handler: + if (Generator->NodeIndexer != NULL) { + FreePool (Generator->NodeIndexer); + Generator->NodeIndexer = NULL; + } + + if (*Table != NULL) { + FreePool (*Table); + *Table = NULL; + } + + return Status; +} + +/** Free any resources allocated for constructing the MPAM + + @param [in] This Pointer to the table generator. + @param [in] AcpiTableInfo Pointer to the ACPI Table Info. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in, out] Table Pointer to the ACPI Table. + + @retval EFI_SUCCESS The resources were freed successfully. + @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid. +**/ +STATIC +EFI_STATUS +FreeMpamTableResources ( + IN CONST ACPI_TABLE_GENERATOR *CONST This, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + ACPI_MPAM_GENERATOR *Generator; + + ASSERT (This != NULL); + ASSERT (AcpiTableInfo != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); + + Generator = (ACPI_MPAM_GENERATOR *)This; + + // Free any memory allocated by the generator + if (Generator->NodeIndexer != NULL) { + FreePool (Generator->NodeIndexer); + Generator->NodeIndexer = NULL; + } + + if ((Table == NULL) || (*Table == NULL)) { + DEBUG ((DEBUG_ERROR, "ERROR: MPAM: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + FreePool (*Table); + *Table = NULL; + + return EFI_SUCCESS; +} + +/** The MPAM Table Generator revision. +*/ +#define MPAM_GENERATOR_REVISION CREATE_REVISION (1, 0) + +/** The interface for the MPAM Table Generator. +*/ +STATIC +ACPI_MPAM_GENERATOR MpamGenerator = { + // ACPI table generator header + { + // Generator ID + CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMpam), + // Generator Description + L"ACPI.STD.MPAM.GENERATOR", + // ACPI Table Signature + EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_STRUCTURE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_REVISION, + // Minimum supported ACPI Table Revision + EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_REVISION, + // Creator ID + TABLE_GENERATOR_CREATOR_ID_ARM, + // Creator Revision + MPAM_GENERATOR_REVISION, + // Build Table function + BuildMpamTable, + // Free Resource function + FreeMpamTableResources, + // Extended build function not needed + NULL, + // Extended build function not implemented by the generator. + // Hence extended free resource function is not required. + NULL + }, + + // MPAM Generator private data + + // MPAM node count + 0, + // MSC node count + 0, + + // Pointer to MPAM Node Indexer + NULL +}; + +/** + Register the Generator with the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is registered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_ALREADY_STARTED The Generator for the Table ID + is already registered. +**/ +EFI_STATUS +EFIAPI +AcpiMpamLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = RegisterAcpiTableGenerator (&MpamGenerator.Header); + DEBUG ((DEBUG_INFO, "MPAM: Register Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Deregister the Generator from the ACPI Table Factory. + + @param [in] ImageHandle The handle to the image. + @param [in] SystemTable Pointer to the System Table. + + @retval EFI_SUCCESS The Generator is deregistered. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND The Generator is not registered. +**/ +EFI_STATUS +EFIAPI +AcpiMpamLibDestructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DeregisterAcpiTableGenerator (&MpamGenerator.Header); + DEBUG ((DEBUG_INFO, "MPAM: Deregister Generator. Status = %r\n", Status)); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.h new file mode 100644 index 0000000000..1075bd8c6c --- /dev/null +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGenerator.h @@ -0,0 +1,47 @@ +/** @file + Header file for the dynamic MPAM generator + + Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + Copyright (c) 2022, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.4 Specification, January 2021 + - ARM Architecture Reference Manual ARMv8 + + @par Glossary: + - Cm or CM - Configuration Manager + - Obj or OBJ - Object +**/ + +#ifndef MPAM_GENERATOR_H_ +#define MPAM_GENERATOR_H_ + +#pragma pack(1) + +/** A structure that describes the Node indexer + used for indexing the MPAM MSC nodes. +*/ +typedef struct MpamNodeIndexer { + /// Index token for the Node + CM_OBJECT_TOKEN Token; + /// Pointer to the node + VOID *Object; + /// Node offset from the start of the MPAM table + UINT32 Offset; +} MPAM_NODE_INDEXER; + +typedef struct AcpiMpamGenerator { + /// ACPI Table generator header + ACPI_TABLE_GENERATOR Header; + /// MPAM structure count + UINT32 MpamNodeCount; + /// Count of Msc Nodes + UINT32 MscNodeCount; + /// List of indexed CM objects for MPAM generation + MPAM_NODE_INDEXER *NodeIndexer; +} ACPI_MPAM_GENERATOR; + +#pragma pack() + +#endif // MPAM_GENERATOR_H_ -- 2.17.1