From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.76]) by mx.groups.io with SMTP id smtpd.web08.1069.1661277108624608289 for ; Tue, 23 Aug 2022 10:51:48 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nvidia.com header.s=selector2 header.b=KgUwuLUD; 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.93.76, mailfrom: swatisrik@nvidia.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=WqkpBNHsljd5OtXhwLrK6Zizoa6aopLxJ6i+baIGSH8AHaqE5uX0ZaAeg153Z2IImmeURBuVAEk23ZojAV6/mB9fhfcvepK5fsepLzBoYHwCo5PjIszOdrb804GS+NQckAe/5Df1M0Pdy+nMBseZTqU8ZAVH7dlSZxN25ws/RcGFVG8ZMcnxqcKfgXbjdtsPGPzNfeU6pV+NF0zXyv4CbKG4Pd0wI2HrTib591okgjBBnQqN4Vz7fuQPoL/EkT8L3v2Zy5fSK29fmRXyZ4H/4hYx/rxf/dQi0O1d7U5DBXV5thp769P/UMOL9DIG6hbJZre3AJ9VFxJ2g60XATFtyQ== 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=Rstz58C0SLZzS4sRmPmsLOoF8zjEWuNLv7ztZvJm3YA=; b=C43zO+xqVs4sNvk3piwpiLrLddiz12/fOxEe9gL7NW5u0w8pNxrJCxclbDV11+j4o2t98pt3qkOtgrEo0LgOExGh6d/9N878knnx2UPWO8H5upvgdJVCiUhPSJlOQKcT0UdXqRlLROeUEbL5KaRL/NDk6c3CL91IOLCdiNIlSE52R29tFOZMRaBNVJm8C08m7ZyTWtq6gAgz8fKculrcGGL3oSPS4xi5Zhd/WHUuMMNZtnRvWaTNYyKNfciTC/H4g/QEYrnSOROScClJuRYP2w6raCdkAeeISpxr2FvN2RoG2KkBgNzB//bKKB0RSZJzA7JFZYu+Ia4HmoI8U4jL8g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; 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=Rstz58C0SLZzS4sRmPmsLOoF8zjEWuNLv7ztZvJm3YA=; b=KgUwuLUDnBGeSJSk9Gy25XEX8DWGi3vUlfk8JVvsPga9fj4R6YO24eU4aetmHAMp9h87ncW867AmRlbPxz/m/RiB4aZxd3Ir2hoZDlooE/v4Mx4IMfTQd1ASrkVLxXbLZBRwNMx/4QdKEIa+JiJHvFE8iTht2hCRO8sIAmfVte0QNz9cZi6B4JlfX3EdkyImYZh/N9bcZOJofoaqV2XeLZG0ToDcLovcO8itaPDlDicA3WFnuccKlxsliRHyriF226H/TU3vEcvTFhpJnM4cUO9Ay7YyWn5wF8+tgvOC6zvZzS9dthsxBAQzWG+ZM5Sw00lklyi6yH3rxyd0X8rCbg== Received: from BY5PR12MB5543.namprd12.prod.outlook.com (2603:10b6:a03:1d1::23) by MWHPR12MB1693.namprd12.prod.outlook.com (2603:10b6:301:10::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5546.19; Tue, 23 Aug 2022 17:51:45 +0000 Received: from BY5PR12MB5543.namprd12.prod.outlook.com ([fe80::1146:5508:a211:f8f1]) by BY5PR12MB5543.namprd12.prod.outlook.com ([fe80::1146:5508:a211:f8f1%4]) with mapi id 15.20.5546.022; Tue, 23 Aug 2022 17:51:45 +0000 From: Swatisri Kantamsetti To: "devel@edk2.groups.io" , "Sami.Mujawar@arm.com" , "Alexei.Fedorov@arm.com" , "michael.d.kinney@intel.com" , "gaoliming@byosoft.com.cn" , "zhiguang.liu@intel.com" CC: Jeff Brasen Subject: Re: [PATCH 2/2] Dynamic Tbl Mgr: MPAM: MPAM Generator and supporting files Thread-Topic: [PATCH 2/2] Dynamic Tbl Mgr: MPAM: MPAM Generator and supporting files Thread-Index: AQHYsY8wmKWMA6yrykexAntV3Etxpq28adeg Date: Tue, 23 Aug 2022 17:51:44 +0000 Message-ID: References: <7f8a5c9bbdf1a1f01c6fc822fa298067d280079a.1660667637.git.swatisrik@nvidia.com> <6fcb277bec0d58c11a6af6b2cbbea57177f3722e.1660667637.git.swatisrik@nvidia.com> In-Reply-To: <6fcb277bec0d58c11a6af6b2cbbea57177f3722e.1660667637.git.swatisrik@nvidia.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: e8c1e264-be04-43c8-2d13-08da853024d4 x-ms-traffictypediagnostic: MWHPR12MB1693:EE_ x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: HxtK5jFuxEappzbAGjgXlFLFG6zeRtkj0scjF3s7YwM6inqY81vH9qz3g98ibZUiwBB6x8yHHn07Qa5S0aFm52DkqbLXBX6DllD0DjS5Ufolmme3OZ9xGDr1XdBOMh3DwroJlL/nP4GNK4/HT36upUjRnkd5pbu1NMKizn0cPGAja/mGXwkIvGaxOXfUPToBmcdW7n119ENyDbLu+F7MSdK5bD0WcRaw7k4zbrrv8iKWdt2i2TvhaZ19OrXcwKWBvnJzLDBEntI+Ip05S0P7uGZXO+Oy1cOdNlj9gGjsfT7uN/+zOp9/LVaqz8bYk4tVrQRYWe6394B3KI/Lfq0CQtXjGmPPh/AO88h1RBbPcyBo+O7MNaagFBqX4gnkTTO8opQ7npb6EJg44lvZxyswCQ4QTC2YuBJbbPVNkTIKVMCJU0+LPamNkHeI0RsDAAhHwTtC1BdGklKWa1DslMEQBtymBeBB51PmGnkA9aU3Sb2eu6OAD4De3R8mD+f2VE9DYD1onp4DuJFz6DxzI3hGoPagTBjI5nMYBaCKXLa5ZcKaCG6eM1AgspJ7FsaCVF5l5oeDPAwv4pF8LgMcA9Aj+lvJnAZgwYsr9k5wx9RPpiYpjd6FU9F5oef7KHrkBWFF5J0xFiHIome/B636FUpzx0nsCt0H/F+09kJ3cGPdf4aaUETVaEKnaUyJDiR936OCw5vvXIfcvm4NJAu5d86Bgr9nkdVLNPeQYRWCiiIdT49gbP5tlVFRgAVzoaSnvbsJqijtTS6yWoPkV0QfJnGuqg== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BY5PR12MB5543.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230016)(4636009)(136003)(39860400002)(396003)(346002)(376002)(366004)(33656002)(83380400001)(186003)(107886003)(30864003)(4326008)(8676002)(5660300002)(41300700001)(19627405001)(6506007)(55016003)(71200400001)(26005)(7696005)(53546011)(478600001)(9686003)(38070700005)(86362001)(110136005)(66476007)(316002)(2906002)(8936002)(52536014)(66446008)(64756008)(122000001)(66946007)(76116006)(38100700002)(66556008)(559001)(579004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?xoK5wPX/iTznLbRurX300hDKnbPIhJsxrQAZLMvHq7KsqX14mNTsNC5HsXwp?= =?us-ascii?Q?2hI3dEDy+qRjR82FJaqisa7wMyYN306koB0MfiEmkLd3fez+2qSXTt1Y7Z7r?= =?us-ascii?Q?YF0abT+ayUPIMQVC0BDEKlUkB/1i6FxPmoJlOZMs/YrhLi3vTieddt5rwPMr?= =?us-ascii?Q?bYUgRC2R2k6ZtjLDhkR/INzru8YRWcgzFVhti7PkLhc9yhmOpFn9Q5nH8/YB?= =?us-ascii?Q?9W91LkQU2C2P9zBCFZhQihSUhIwH222ST2wBsaCHKQZyxV25rAKNJJPoULS/?= =?us-ascii?Q?/hnJnyvAQvceK2dNgJVQ+mhEmTi95tMCK+HMqv1c58xCFUQFpRTPKgViydwW?= =?us-ascii?Q?W2x9z1280iKQJWiSpSDYwYyOaL3CMFTjmmxffJYZVWbgjZgBX1yqAlq8nX7i?= =?us-ascii?Q?fwKYJbjbxUgDLZgbK4+zwpWtrPhOt59x6tEiBE7yXD730ZQtPzITafrN4No3?= =?us-ascii?Q?py7j/388YRCjGCoUEJFrpYc6nd/9qaQvZe1C8wnrTTcTPpKOMJOD8CZJJGVv?= =?us-ascii?Q?DuQnyP7SqX/8gwd3TaEaPFK0kEMoikFvmZTGejNcMJTVeadoDCru6Fbt5BgP?= =?us-ascii?Q?hfaUfb3dLUFiv52Hy7W65LVFySUZpoLuLO5hd3U5/wd9sLUwlUanW7Vi6DHP?= =?us-ascii?Q?/uuTjarKusBbYu+LRnEXZCWtaVjTjtbRKwcybDvQuzY5gVvGhLYmsA4Jciut?= =?us-ascii?Q?Sw//eym/Kupx/e3tEn1oohJZOFYdukmTRaIQ6xJ/jZ+Vw3Snf2pPIH4OuyBj?= =?us-ascii?Q?qUuURbK1s3uUcnMeqpgBRz+qUuJe465qqtBzmcIfUPTjoEyygZXzYsupZ0bL?= =?us-ascii?Q?rAU0qZ+gFyY78SMPvf5wRDTtpdu2aWZNbJzQADkf53QfEXvCEqeM/5r1QVsH?= =?us-ascii?Q?ut31YwPVK9qk6f2UAOsT3UXbEh9Hut567srBz/001JG1CpzDcYrq/J38bXT2?= =?us-ascii?Q?m3uyImZ6s/hAd4oP7lhfyNDgxZ3WQmV+ifQuyiKYSa9CfG/P+tf78waVAh42?= =?us-ascii?Q?Mj2qBjnx412oyvx8zRRUG9kdbRC+nqOi2dDd37Qzb3h/RmQPniUshhDqPWgi?= =?us-ascii?Q?hODH5028yBrnxNSN+MhAnkyGkKKaoMsZhQQXgZP/2rJYct3M5AnukgDCYZtI?= =?us-ascii?Q?SbfhCZD7T6LAvZzDciF0OTZiFArmARFvQoKeudMWEvCJXXx42yA+DpMlmAlz?= =?us-ascii?Q?hLzhuUJii7jaA9csxhs2wZsCUNKhW5a7VzpcjMxFfQaW4deuBlqiYLAhwUh+?= =?us-ascii?Q?D44IQziti6PW6e9l+/CRL3H0/bXCZ5Myw3eGcz8GayuC1OuDKDBDwt7Yq2v8?= =?us-ascii?Q?QRN3o78WuK00kXPKbF6zAABUSxScIpNW7/D1s8knNmA/VBbQ+J60yBQk9ROm?= =?us-ascii?Q?9yCMVsDt2xVTtIIAbzSPisqmZAsrSJ/0vSGPzMkLDRX+87Pr0WpYUnjMuLCj?= =?us-ascii?Q?QEf16yARbs1ormUSv81fXDHPGWCNBHZgnNFzkOI12f4c4gUqHTUlsuFjApl6?= =?us-ascii?Q?SrW52uRw9CjF58qckKPxVdXXIeCqZxbSlRZBcbixeYfpspTbWa+ZhrObFLOZ?= =?us-ascii?Q?oY79zMgrWV4+ewxveiItz+4C/d0dK+Un4M735ign?= MIME-Version: 1.0 X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BY5PR12MB5543.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: e8c1e264-be04-43c8-2d13-08da853024d4 X-MS-Exchange-CrossTenant-originalarrivaltime: 23 Aug 2022 17:51:44.8532 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 2mO+b1J8iXtzZtoSGQziVWaB6LzO7mbqcRv0Tlm2DtGCW7hHuD16nslFsHIRoDRBVEdvC5JkEyqxoBRAXY3yDg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1693 Content-Language: en-US Content-Type: multipart/alternative; boundary="_000_BY5PR12MB5543E4231D39A36F34F60678D3709BY5PR12MB5543namp_" --_000_BY5PR12MB5543E4231D39A36F34F60678D3709BY5PR12MB5543namp_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hello, Just a reminder to provide feedback on this patch. Thanks, Swati swatisrik@nvidia.com ________________________________ From: Name Sent: Tuesday, August 16, 2022 2:18 PM To: devel@edk2.groups.io ; Sami.Mujawar@arm.com ; Alexei.Fedorov@arm.com ; michael= .d.kinney@intel.com ; gaoliming@byosoft.com.cn = ; zhiguang.liu@intel.com Cc: Swatisri Kantamsetti Subject: [PATCH 2/2] Dynamic Tbl Mgr: MPAM: MPAM Generator and supporting f= iles 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/AcpiMp= amLibArm.inf create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGe= nerator.c create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/MpamGe= nerator.h diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/Dyna= micTables.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.i= nf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm= .inf NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSratLibArm/AcpiSratLibArm= .inf diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesP= kg/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 Gene= rator EStdAcpiTableIdSsdtCmn600, ///< SSDT Cmn-600 Generato= r EStdAcpiTableIdSsdtCpuTopology, ///< SSDT Cpu Topology diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTables= Pkg/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 Nod= e EArmObjMemoryRangeDescriptor, ///< 41 - Memory Range Descriptor + EArmObjMscNodeInfo, ///< 40 - Msc Memory System Control= ler 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/AcpiMpamLibAr= m.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 =3D 0x0001001B + BASE_NAME =3D AcpiMpamLibArm + FILE_GUID =3D 02d0c79f-41cd-45c9-9835-781229c619d1 + VERSION_STRING =3D 1.0 + MODULE_TYPE =3D DXE_DRIVER + LIBRARY_CLASS =3D NULL|DXE_DRIVER + CONSTRUCTOR =3D AcpiMpamLibConstructor + DESTRUCTOR =3D 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 Generat= or: + - 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 !=3D NULL); + + // + return (UINT32)(sizeof (EFI_ACPI_6_4_MPAM_MSC_NODE) + + Node->NumResourceNodes * sizeof (EFI_ACPI_6_4_MPAM_RESOU= RCE_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 !=3D NULL); + + Size =3D 0; + while (NodeCount-- !=3D 0) { + (*NodeIndexer)->Token =3D NodeList->Token; + (*NodeIndexer)->Object =3D (VOID *)NodeList; + (*NodeIndexer)->Offset =3D (UINT32)(Size + NodeStartOffset); + DEBUG (( + DEBUG_INFO, + "MPAM: MSC Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset = =3D 0x%x\n", + *NodeIndexer, + (*NodeIndexer)->Token, + (*NodeIndexer)->Object, + (*NodeIndexer)->Offset + )); + + Size +=3D 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_MONITORIN= G_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 !=3D NULL); + + MscNode =3D (EFI_ACPI_6_4_MPAM_MSC_NODE *)((UINT8 *)Mpam + NodesStartOff= set); + + // Get the Resource Node info to update the MPAM MSC node + Status =3D GetEArmObjResNodeInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &ResourceNodeList, + &ResourceNodeCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to add resource nodes info. Status =3D %r\n", + Status + )); + return Status; + } + + while (NodeCount-- !=3D 0) { + NodeLength =3D GetMscNodeSize (NodeList); + + if (NodeLength > MAX_UINT16) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: MSC Node length 0x%lx > MAX_UINT16. Status =3D %r\n"= , + NodeLength, + Status + )); + return Status; + } + + // Populate the node header + MscNode->Length =3D (UINT16)NodeLength; + MscNode->Reserved =3D EFI_ACPI_RESERVED_WORD; + MscNode->Identifier =3D EFI_ACPI_RESERVED_DWORD; + MscNode->BaseAddress =3D NodeList->BaseAddress; + MscNode->MmioSize =3D NodeList->MmioSize; + MscNode->OverflowInterrupt =3D NodeList->OverflowInterrupt; + MscNode->OverflowInterruptFlags =3D NodeList->OverflowInterruptFlags= ; + MscNode->Reserved1 =3D EFI_ACPI_RESERVED_DWORD; + MscNode->OverflowInterruptAff =3D NodeList->OverflowInterruptAff; + MscNode->ErrorInterrupt =3D NodeList->ErrorInterrupt; + MscNode->ErrorInterruptFlags =3D NodeList->ErrorInterruptFlags; + MscNode->Reserved2 =3D EFI_ACPI_RESERVED_DWORD; + MscNode->ErrorInterruptAff =3D NodeList->ErrorInterruptAff; + MscNode->MaxNRdyUsec =3D NodeList->MaxNRdyUsec; + MscNode->LinkedDeviceHwId =3D NodeList->LinkedDeviceHwId; + MscNode->LinkedDeviceInstanceHwId =3D NodeList->LinkedDeviceInstanceHw= Id; + MscNode->NumResourceNodes =3D NodeList->NumResourceNodes; + + // ResourceNode List for each MSC + if (MscNode->NumResourceNodes > 0) { + // Resource Node array for this Msc node + ResourceNodeArray =3D (EFI_ACPI_6_4_MPAM_RESOURCE_NODE *)((UINT8 *)M= scNode + sizeof (EFI_ACPI_6_4_MPAM_MSC_NODE)); + // Adding Resource Node content + while ( MscNode->NumResourceNodes-- !=3D 0 ) { + ResourceNodeArray->Identifier =3D ResourceNodeList->Identifier; + ResourceNodeArray->RisIndex =3D ResourceNodeList->RisIndex; + ResourceNodeArray->Reserved1 =3D EFI_ACPI_RESERVED_WORD; + ResourceNodeArray->LocatorType =3D ResourceNodeList->LocatorType; + ResourceNodeArray->Locator =3D ResourceNodeList->Locator; + ResourceNodeArray->NumFuncDep =3D ResourceNodeList->NumFuncDep; + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to add Resource Node List. Status =3D %r\= n", + Status + )); + return Status; + } + + ResourceNodeList++; + ResourceNodeArray++; + } + } + + // Next MSC Node + MscNode =3D (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 f= or + 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 !=3D NULL) && + (AcpiTableInfo !=3D NULL) && + (CfgMgrProtocol !=3D NULL) && + (Table !=3D NULL) && + (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID) && + (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTableSignature) + ); + + DEBUG (( + DEBUG_ERROR, + "DEBUG PRINT: MPAM: Requested table revision =3D %d\n", + AcpiTableInfo->AcpiTableRevision + )); + + if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) || + (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision)) + { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Requested table revision =3D %d is not supported. " + "Supported table revisions: Minimum =3D %d. Maximum =3D %d\n", + AcpiTableInfo->AcpiTableRevision, + This->MinAcpiTableRevision, + This->AcpiTableRevision + )); + return EFI_INVALID_PARAMETER; + } + + Generator =3D (ACPI_MPAM_GENERATOR *)This; + *Table =3D NULL; + + // Get the Memory System Controller Node info and update the MPAM + // structure count with MSC Node count (Type 0) + Status =3D GetEArmObjMscNodeInfo ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &MscNodeList, + &MscNodeCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to get memory system controller node info. Stat= us =3D %r\n", + Status + )); + goto error_handler; + } + + MpamNodeCount =3D MscNodeCount; + Generator->MscNodeCount =3D MscNodeCount; + + // Allocate Node Indexer array + NodeIndexer =3D (MPAM_NODE_INDEXER *)AllocateZeroPool ( + sizeof (MPAM_NODE_INDEXER) * + MpamNodeCount + ); + if (NodeIndexer =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to allocate memory for Node Indexer. Status =3D= %r\n ", + Status + )); + goto error_handler; + } + + DEBUG ((DEBUG_INFO, "MPAM INFO: NodeIndexer =3D %p\n", NodeIndexer)); + Generator->MpamNodeCount =3D MpamNodeCount; + Generator->NodeIndexer =3D NodeIndexer; + + // Calculate the size of the MPAM table + TableSize =3D sizeof (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_M= ONITORING_TABLE_HEADER); + + // Include the size of MSC Nodes and index them + if (Generator->MscNodeCount !=3D 0) { + MscNodeOffset =3D TableSize; + // Size of MSC nodes. + NodeSize =3D GetSizeofMscGroupNodes ( + MscNodeOffset, + MscNodeList, + Generator->MscNodeCount, + &NodeIndexer + ); + if (NodeSize > MAX_UINT32) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Invalid Size of Group Nodes. Status =3D %r\n", + Status + )); + goto error_handler; + } + + TableSize +=3D NodeSize; + + DEBUG (( + DEBUG_INFO, + " MscNodeCount =3D %d\n" \ + " MscNodeOffset =3D 0x%x\n", + Generator->MscNodeCount, + MscNodeOffset + )); + } + + DEBUG (( + DEBUG_INFO, + "INFO: MPAM:\n" \ + " MpamNodeCount =3D %d\n" \ + " TableSize =3D 0x%X\n", + MpamNodeCount, + TableSize + )); + + if (TableSize > MAX_UINT32) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: MPAM Table Size 0x%lx > MAX_UINT32," \ + " Status =3D %r\n", + TableSize, + Status + )); + goto error_handler; + } + + // Allocate the Buffer for the MPAM table + *Table =3D (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSize); + if (*Table =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to allocate memory for MPAM Table. " \ + "Size =3D %d. Status =3D %r\n", + TableSize, + Status + )); + goto error_handler; + } + + Mpam =3D (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TA= BLE_HEADER *)*Table; + + DEBUG (( + DEBUG_INFO, + "MPAM: Mpam =3D 0x%p. TableSize =3D 0x%x\n", + Mpam, + TableSize + )); + + // Add ACPI header + Status =3D AddAcpiHeader ( + CfgMgrProtocol, + This, + &Mpam->Header, + AcpiTableInfo, + TableSize + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to add ACPI header. Status =3D %r\n", + Status + )); + goto error_handler; + } + + // Update MPAM table + Mpam->NumNodes =3D MscNodeCount; + Mpam->NodeOffset =3D sizeof (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITI= ONING_MONITORING_TABLE_HEADER); + Mpam->Reserved =3D EFI_ACPI_RESERVED_DWORD; + + // Add MSC Nodes to the generated table + if (Mpam->NumNodes !=3D 0) { + Status =3D AddMscNodes ( + This, + CfgMgrProtocol, + Mpam, + MscNodeOffset, + MscNodeList, + MscNodeCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: MPAM: Failed to add MSC Nodes. Status =3D %r\n", + Status + )); + goto error_handler; + } + } + + return Status; + +error_handler: + if (Generator->NodeIndexer !=3D NULL) { + FreePool (Generator->NodeIndexer); + Generator->NodeIndexer =3D NULL; + } + + if (*Table !=3D NULL) { + FreePool (*Table); + *Table =3D 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 AcpiTableInf= o, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtoc= ol, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **CONST Table + ) +{ + ACPI_MPAM_GENERATOR *Generator; + + ASSERT (This !=3D NULL); + ASSERT (AcpiTableInfo !=3D NULL); + ASSERT (CfgMgrProtocol !=3D NULL); + ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID); + ASSERT (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTableSignatur= e); + + Generator =3D (ACPI_MPAM_GENERATOR *)This; + + // Free any memory allocated by the generator + if (Generator->NodeIndexer !=3D NULL) { + FreePool (Generator->NodeIndexer); + Generator->NodeIndexer =3D NULL; + } + + if ((Table =3D=3D NULL) || (*Table =3D=3D NULL)) { + DEBUG ((DEBUG_ERROR, "ERROR: MPAM: Invalid Table Pointer\n")); + return EFI_INVALID_PARAMETER; + } + + FreePool (*Table); + *Table =3D 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 =3D { + // 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_STRU= CTURE_SIGNATURE, + // ACPI Table Revision supported by this Generator + EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_REVI= SION, + // Minimum supported ACPI Table Revision + EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_REVI= SION, + // 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 =3D RegisterAcpiTableGenerator (&MpamGenerator.Header); + DEBUG ((DEBUG_INFO, "MPAM: Register Generator. Status =3D %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 =3D DeregisterAcpiTableGenerator (&MpamGenerator.Header); + DEBUG ((DEBUG_INFO, "MPAM: Deregister Generator. Status =3D %r\n", Statu= s)); + 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 --_000_BY5PR12MB5543E4231D39A36F34F60678D3709BY5PR12MB5543namp_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable
Hello,
Just a reminder to provide feedback on this patch.

Thanks,
Swati

swatisrik@nvidia.com

From: Name <username@nvi= dia.com>
Sent: Tuesday, August 16, 2022 2:18 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>; Sami.Mujawar@= arm.com <Sami.Mujawar@arm.com>; Alexei.Fedorov@arm.com <Alexei.Fed= orov@arm.com>; michael.d.kinney@intel.com <michael.d.kinney@intel.com= >; gaoliming@byosoft.com.cn <gaoliming@byosoft.com.cn>; zhiguang.liu@intel.com <zhiguang.liu@intel.com>
Cc: Swatisri Kantamsetti <swatisrik@nvidia.com>
Subject: [PATCH 2/2] Dynamic Tbl Mgr: MPAM: MPAM Generator and suppo= rting files
 
From: Swatisri Kantamsetti <swatisrik@nvidia.co= m>

ACPI header, MSC and Resource Nodes are populated
in the MPAM Table

Signed-off-by: Swatisri Kantamsetti <swatisrik@nvidia.com>
---
 DynamicTablesPkg/DynamicTables.dsc.inc     &= nbsp;  |   2 +
 DynamicTablesPkg/Include/AcpiTableGenerator.h |   1 +
 .../Include/ArmNameSpaceObjects.h      =        |  68 ++
 .../Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf     |&n= bsp; 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/A= cpiMpamLibArm.inf
 create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/M= pamGenerator.c
 create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/M= pamGenerator.h

diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/Dyna= micTables.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/AcpiIortLibAr= m.inf
   DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibAr= m.inf
   DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibAr= m.inf
+  DynamicTablesPkg/Library/Acpi/Arm/AcpiMpamLibArm/AcpiMpamLibArm.inf=
   DynamicTablesPkg/Library/Acpi/Arm/AcpiPpttLibArm/AcpiPpttLibAr= m.inf
   DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.= inf
   DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibAr= m.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/Acpi= MpamLibArm/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/DynamicTablesP= kg/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,       =             &nb= sp;      ///< IORT Generator
   EStdAcpiTableIdPptt,       =             &nb= sp;      ///< PPTT Generator
   EStdAcpiTableIdSrat,       =             &nb= sp;      ///< SRAT Generator
+  EStdAcpiTableIdMpam,        = ;            &n= bsp;     ///< MPAM Generator
   EStdAcpiTableIdSsdtSerialPort,     &n= bsp;          ///< SSDT Ser= ial-Port Generator
   EStdAcpiTableIdSsdtCmn600,      =             &nb= sp; ///< SSDT Cmn-600 Generator
   EStdAcpiTableIdSsdtCpuTopology,     &= nbsp;         ///< SSDT Cpu Topo= logy
diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTables= Pkg/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,        &nb= sp;            =      ///< 40 - Reserved Memory Range Node
   EArmObjMemoryRangeDescriptor,     &nb= sp;  ///< 41 - Memory Range Descriptor
+  EArmObjMscNodeInfo,        =           ///< 40 - Msc Mem= ory System Controller Node Info
+  EArmObjResNodeInfo,        =           ///< 41 - Res Res= ource 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          &= nbsp;    BaseAddress;
+  /// MMIO Size
+  UINT32          &= nbsp;    MmioSize;
+  /// Overflow Interrupt
+  UINT32          &= nbsp;    OverflowInterrupt;
+  /// Overflow Interrupt Flags
+  UINT32          &= nbsp;    OverflowInterruptFlags;
+  /// Overflow Interrupt Affinity
+  UINT32          &= nbsp;    OverflowInterruptAff;
+  /// Error Interrupt
+  UINT32          &= nbsp;    ErrorInterrupt;
+  /// Error Interrupt Flags
+  UINT32          &= nbsp;    ErrorInterruptFlags;
+  /// Error Interrupt Affinity
+  UINT32          &= nbsp;    ErrorInterruptAff;
+  /// Not Ready Signal time
+  UINT32          &= nbsp;    MaxNRdyUsec;
+  /// Linked Device HWID
+  UINT64          &= nbsp;    LinkedDeviceHwId;
+  /// Linked Device Instance ID
+  UINT32          &= nbsp;    LinkedDeviceInstanceHwId;
+  /// Number of Resource nodes
+  UINT32          &= nbsp;    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          &= nbsp;  Identifier;
+  /// RIS Index
+  UINT8          &n= bsp;   RisIndex;
+  /// Locator Type
+  UINT8          &n= bsp;   LocatorType;
+  /// Locator
+  UINT64          &= nbsp;  Locator;
+  /// Num functional dependencies
+  UINT32          &= nbsp;  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/AcpiMpamLibAr= m.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    =3D 0x0001001B
+  BASE_NAME      =3D AcpiMpamLibArm
+  FILE_GUID      =3D 02d0c79f-41cd-45c9-9835= -781229c619d1
+  VERSION_STRING =3D 1.0
+  MODULE_TYPE    =3D DXE_DRIVER
+  LIBRARY_CLASS  =3D NULL|DXE_DRIVER
+  CONSTRUCTOR    =3D AcpiMpamLibConstructor
+  DESTRUCTOR     =3D 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 <IndustryStandard/Mpam.h>
+#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#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 inform= ation
+  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 !=3D NULL);
+
+  // <size of Memory System Controller Node>
+  return (UINT32)(sizeof (EFI_ACPI_6_4_MPAM_MSC_NODE) +
+            &n= bsp;     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]       NodeSta= rtOffset Offset from the start of the
+            &n= bsp;            = ;             M= PAM where this node group starts.
+    @param [in]       NodeLis= t        Pointer to MSC Group node list.=
+    @param [in]       NodeCou= nt       Count of the MSC Group nodes.
+    @param [in, out]  NodeIndexer   &nb= sp; Pointer to the next Node Indexer.
+
+    @retval Total size of the ITS Group Nodes.
+**/
+STATIC
+UINT64
+GetSizeofMscGroupNodes (
+  IN      CONST UINT32   &nbs= p;            &= nbsp;        NodeStartOffset,
+  IN      CONST CM_ARM_MSC_NODE_INFO &n= bsp;         *NodeList,
+  IN           = ; UINT32           &= nbsp;           &nbs= p; NodeCount,
+  IN OUT        MPAM_NODE_INDEXER&= nbsp;    **CONST  NodeIndexer
+  )
+{
+  UINT64  Size;
+
+  ASSERT (NodeList !=3D NULL);
+
+  Size =3D 0;
+  while (NodeCount-- !=3D 0) {
+    (*NodeIndexer)->Token  =3D NodeList->Token;<= br> +    (*NodeIndexer)->Object =3D (VOID *)NodeList;
+    (*NodeIndexer)->Offset =3D (UINT32)(Size + NodeStart= Offset);
+    DEBUG ((
+      DEBUG_INFO,
+      "MPAM: MSC Node Indexer =3D %p, Token = =3D %p, Object =3D %p, Offset =3D 0x%x\n",
+      *NodeIndexer,
+      (*NodeIndexer)->Token,
+      (*NodeIndexer)->Object,
+      (*NodeIndexer)->Offset
+      ));
+
+    Size +=3D GetMscNodeSize (NodeList);
+
+    (*NodeIndexer)++;
+    NodeList++;
+  }
+
+  return Size;
+}
+
+/** Update the MSC Group Node Information.
+
+    @param [in]     This  &nb= sp;          Pointer to the ta= ble Generator.
+    @param [in]     CfgMgrProtocol = ;  Pointer to the Configuration Manager
+            &n= bsp;            = ;            Protoco= l Interface.
+    @param [in]     Mpam  &nb= sp;          Pointer to MPAM t= able structure.
+    @param [in]     NodesStartOffset Of= fset for the start of the Msc Group
+            &n= bsp;            = ;            Nodes.<= br> +    @param [in]     NodeList  = ;       Pointer to an array of Msc Group Node=
+            &n= bsp;            = ;            Objects= .
+    @param [in]     NodeCount &nbs= p;      Number of Msc Group Node Objects.
+
+    @retval EFI_SUCCESS      =      Table generated successfully.
+    @retval EFI_INVALID_PARAMETER A parameter is invalid. +    @retval EFI_NOT_FOUND     &nbs= p;   The required object was not found.
+**/
+STATIC
+EFI_STATUS
+AddMscNodes (
+  IN      CONST ACPI_TABLE_GENERATOR &n= bsp;            = ;            &n= bsp;            = ;            &n= bsp;   *CONST  This,
+  IN      CONST EDKII_CONFIGURATION_MANAGER_= PROTOCOL           &= nbsp;           &nbs= p;            &= nbsp;  *CONST  CfgMgrProtocol,
+  IN      CONST EFI_ACPI_6_4_MEMORY_SYSTEM_R= ESOURCE_PARTITIONING_MONITORING_TABLE_HEADER     &= nbsp;     *Mpam,
+  IN      CONST UINT32   &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;          NodesStartOffse= t,
+  IN      CONST CM_ARM_MSC_NODE_INFO &n= bsp;            = ;            &n= bsp;            = ;            &n= bsp;           *NodeList,=
+  IN           = ; UINT32           &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;   NodeCount
+  )
+{
+  EFI_STATUS         &nb= sp;            = Status;
+  EFI_ACPI_6_4_MPAM_MSC_NODE       *Msc= Node;
+  EFI_ACPI_6_4_MPAM_RESOURCE_NODE  *ResourceNodeArray;
+  CM_ARM_RESOURCE_NODE_INFO       = *ResourceNodeList;
+  UINT64          &= nbsp;           &nbs= p;    NodeLength;
+  UINT32          &= nbsp;           &nbs= p;    ResourceNodeCount;
+
+  ASSERT (Mpam !=3D NULL);
+
+  MscNode =3D (EFI_ACPI_6_4_MPAM_MSC_NODE *)((UINT8 *)Mpam + NodesSta= rtOffset);
+
+  // Get the Resource Node info to update the MPAM MSC node
+  Status =3D GetEArmObjResNodeInfo (
+             C= fgMgrProtocol,
+             C= M_NULL_TOKEN,
+             &= amp;ResourceNodeList,
+             &= amp;ResourceNodeCount
+             )= ;
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MPAM: Failed to add resource n= odes info. Status =3D %r\n",
+      Status
+      ));
+    return Status;
+  }
+
+  while (NodeCount-- !=3D 0) {
+    NodeLength =3D GetMscNodeSize (NodeList);
+
+    if (NodeLength > MAX_UINT16) {
+      Status =3D EFI_INVALID_PARAMETER;
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: MPAM: MSC Node len= gth 0x%lx > MAX_UINT16. Status =3D %r\n",
+        NodeLength,
+        Status
+        ));
+      return Status;
+    }
+
+    // Populate the node header
+    MscNode->Length      &= nbsp;            =3D= (UINT16)NodeLength;
+    MscNode->Reserved      = ;           =3D EFI_ACPI_= RESERVED_WORD;
+    MscNode->Identifier     &nb= sp;         =3D EFI_ACPI_RESERVED_D= WORD;
+    MscNode->BaseAddress     &n= bsp;        =3D NodeList->BaseAddress= ;
+    MscNode->MmioSize      = ;           =3D NodeList-= >MmioSize;
+    MscNode->OverflowInterrupt    &n= bsp;   =3D NodeList->OverflowInterrupt;
+    MscNode->OverflowInterruptFlags   =3D Node= List->OverflowInterruptFlags;
+    MscNode->Reserved1     &nbs= p;          =3D EFI_ACPI_RESER= VED_DWORD;
+    MscNode->OverflowInterruptAff    = ; =3D NodeList->OverflowInterruptAff;
+    MscNode->ErrorInterrupt     = ;      =3D NodeList->ErrorInterrupt;
+    MscNode->ErrorInterruptFlags    =   =3D NodeList->ErrorInterruptFlags;
+    MscNode->Reserved2     &nbs= p;          =3D EFI_ACPI_RESER= VED_DWORD;
+    MscNode->ErrorInterruptAff    &n= bsp;   =3D NodeList->ErrorInterruptAff;
+    MscNode->MaxNRdyUsec     &n= bsp;        =3D NodeList->MaxNRdyUsec= ;
+    MscNode->LinkedDeviceHwId    &nb= sp;    =3D NodeList->LinkedDeviceHwId;
+    MscNode->LinkedDeviceInstanceHwId =3D NodeList->L= inkedDeviceInstanceHwId;
+    MscNode->NumResourceNodes    &nb= sp;    =3D NodeList->NumResourceNodes;
+
+    // ResourceNode List for each MSC
+    if (MscNode->NumResourceNodes > 0) {
+      // Resource Node array for this Msc node +      ResourceNodeArray =3D (EFI_ACPI_6_4_MPAM_RE= SOURCE_NODE *)((UINT8 *)MscNode + sizeof (EFI_ACPI_6_4_MPAM_MSC_NODE));
+      // Adding Resource Node content
+      while ( MscNode->NumResourceNodes-- !=3D= 0 ) {
+        ResourceNodeArray->Identifie= r  =3D ResourceNodeList->Identifier;
+        ResourceNodeArray->RisIndex&= nbsp;   =3D ResourceNodeList->RisIndex;
+        ResourceNodeArray->Reserved1=    =3D EFI_ACPI_RESERVED_WORD;
+        ResourceNodeArray->LocatorTy= pe =3D ResourceNodeList->LocatorType;
+        ResourceNodeArray->Locator&n= bsp;    =3D ResourceNodeList->Locator;
+        ResourceNodeArray->NumFuncDe= p  =3D ResourceNodeList->NumFuncDep;
+
+        if (EFI_ERROR (Status)) {
+          DEBUG ((
+            DEBUG_E= RROR,
+            "E= RROR: MPAM: Failed to add Resource Node List. Status =3D %r\n",
+            Status<= br> +            ));
+          return Status;
+        }
+
+        ResourceNodeList++;
+        ResourceNodeArray++;
+      }
+    }
+
+    // Next MSC Node
+    MscNode =3D (EFI_ACPI_6_4_MPAM_MSC_NODE *)((UINT8 *)Msc= Node + MscNode->Length);
+    NodeList++;
+  } // Msc Node
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Construct the MPAM ACPI table.
+
+  This function invokes the Configuration Manager protocol interface<= br> +  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       &nb= sp;         Pointer to the table ge= nerator.
+  @param [in]  AcpiTableInfo      =   Pointer to the ACPI table generator to be used.
+  @param [in]  CfgMgrProtocol      = ; Pointer to the Configuration Manager
+            &n= bsp;            = ;           Protocol Inte= rface.
+  @param [out] Table        &= nbsp;       Pointer to the constructed ACPI T= able.
+
+  @retval EFI_SUCCESS        =        Table generated successfully.
+  @retval EFI_INVALID_PARAMETER     A parameter i= s invalid.
+  @retval EFI_NOT_FOUND       &nbs= p;     The required object was not found.
+  @retval EFI_BAD_BUFFER_SIZE       The= size returned by the Configuration
+            &n= bsp;            = ;           Manager is le= ss than the Object size for
+            &n= bsp;            = ;           the requested= object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildMpamTable (
+  IN  CONST ACPI_TABLE_GENERATOR     &n= bsp;            *CON= ST  This,
+  IN  CONST CM_STD_OBJ_ACPI_TABLE_INFO    &n= bsp;       *CONST  AcpiTableInfo,
+  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST&nb= sp; CfgMgrProtocol,
+  OUT       EFI_ACPI_DESCRIPTION_HEADER=           **CONST  Table<= br> +  )
+{
+  EFI_STATUS  Status;
+  UINT64      TableSize;
+  UINT64      NodeSize;
+  UINT32      MpamNodeCount;
+
+  UINT32  MscNodeCount;
+  UINT32  MscNodeOffset;
+
+  EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORING_TABLE_H= EADER  *Mpam;
+  ACPI_MPAM_GENERATOR        =             &nb= sp;            =             &nb= sp;         *Generator;
+  CM_ARM_MSC_NODE_INFO        = ;            &n= bsp;            = ;            &n= bsp;        *MscNodeList;
+  MPAM_NODE_INDEXER        &n= bsp;            = ;            &n= bsp;            = ;           *NodeIndexer;=
+
+  ASSERT (
+    (This !=3D NULL) &&
+    (AcpiTableInfo !=3D NULL) &&
+    (CfgMgrProtocol !=3D NULL) &&
+    (Table !=3D NULL) &&
+    (AcpiTableInfo->TableGeneratorId =3D=3D This->Gen= eratorID) &&
+    (AcpiTableInfo->AcpiTableSignature =3D=3D This->A= cpiTableSignature)
+    );
+
+  DEBUG ((
+    DEBUG_ERROR,
+    "DEBUG PRINT: MPAM: Requested table revision =3D %= d\n",
+    AcpiTableInfo->AcpiTableRevision
+    ));
+
+  if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTable= Revision) ||
+      (AcpiTableInfo->AcpiTableRevision > T= his->AcpiTableRevision))
+  {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MPAM: Requested table revision= =3D %d is not supported. "
+      "Supported table revisions: Minimum = =3D %d. Maximum =3D %d\n",
+      AcpiTableInfo->AcpiTableRevision,
+      This->MinAcpiTableRevision,
+      This->AcpiTableRevision
+      ));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Generator =3D (ACPI_MPAM_GENERATOR *)This;
+  *Table    =3D NULL;
+
+  // Get the Memory System Controller Node info and update the MPAM +  // structure count with MSC Node count (Type 0)
+  Status =3D GetEArmObjMscNodeInfo (
+             C= fgMgrProtocol,
+             C= M_NULL_TOKEN,
+             &= amp;MscNodeList,
+             &= amp;MscNodeCount
+             )= ;
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MPAM: Failed to get memory sys= tem controller node info. Status =3D %r\n",
+      Status
+      ));
+    goto error_handler;
+  }
+
+  MpamNodeCount         =   =3D MscNodeCount;
+  Generator->MscNodeCount =3D MscNodeCount;
+
+  // Allocate Node Indexer array
+  NodeIndexer =3D (MPAM_NODE_INDEXER *)AllocateZeroPool (
+            &n= bsp;            = ;            &n= bsp; sizeof (MPAM_NODE_INDEXER) *
+            &n= bsp;            = ;            &n= bsp; MpamNodeCount
+            &n= bsp;            = ;            &n= bsp; );
+  if (NodeIndexer =3D=3D NULL) {
+    Status =3D EFI_OUT_OF_RESOURCES;
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MPAM: Failed to allocate memor= y for Node Indexer. Status =3D %r\n ",
+      Status
+      ));
+    goto error_handler;
+  }
+
+  DEBUG ((DEBUG_INFO, "MPAM INFO: NodeIndexer =3D %p\n", No= deIndexer));
+  Generator->MpamNodeCount =3D MpamNodeCount;
+  Generator->NodeIndexer   =3D NodeIndexer;
+
+  // Calculate the size of the MPAM table
+  TableSize =3D sizeof (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITION= ING_MONITORING_TABLE_HEADER);
+
+  // Include the size of MSC Nodes and index them
+  if (Generator->MscNodeCount !=3D 0) {
+    MscNodeOffset =3D TableSize;
+    // Size of MSC nodes.
+    NodeSize =3D GetSizeofMscGroupNodes (
+            &n= bsp;    MscNodeOffset,
+            &n= bsp;    MscNodeList,
+            &n= bsp;    Generator->MscNodeCount,
+            &n= bsp;    &NodeIndexer
+            &n= bsp;    );
+    if (NodeSize > MAX_UINT32) {
+      Status =3D EFI_INVALID_PARAMETER;
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: MPAM: Invalid Size= of Group Nodes. Status =3D %r\n",
+        Status
+        ));
+      goto error_handler;
+    }
+
+    TableSize +=3D NodeSize;
+
+    DEBUG ((
+      DEBUG_INFO,
+      " MscNodeCount =3D %d\n" \
+      " MscNodeOffset =3D 0x%x\n",
+      Generator->MscNodeCount,
+      MscNodeOffset
+      ));
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "INFO: MPAM:\n" \
+    " MpamNodeCount =3D %d\n" \
+    " TableSize =3D 0x%X\n",
+    MpamNodeCount,
+    TableSize
+    ));
+
+  if (TableSize > MAX_UINT32) {
+    Status =3D EFI_INVALID_PARAMETER;
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MPAM: MPAM Table Size 0x%lx &g= t; MAX_UINT32," \
+      " Status =3D %r\n",
+      TableSize,
+      Status
+      ));
+    goto error_handler;
+  }
+
+  // Allocate the Buffer for the MPAM table
+  *Table =3D (EFI_ACPI_DESCRIPTION_HEADER *)AllocateZeroPool (TableSi= ze);
+  if (*Table =3D=3D NULL) {
+    Status =3D EFI_OUT_OF_RESOURCES;
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MPAM: Failed to allocate memor= y for MPAM Table. " \
+      "Size =3D %d. Status =3D %r\n", +      TableSize,
+      Status
+      ));
+    goto error_handler;
+  }
+
+  Mpam =3D (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITORI= NG_TABLE_HEADER *)*Table;
+
+  DEBUG ((
+    DEBUG_INFO,
+    "MPAM: Mpam =3D 0x%p. TableSize =3D 0x%x\n",<= br> +    Mpam,
+    TableSize
+    ));
+
+  // Add ACPI header
+  Status =3D AddAcpiHeader (
+             C= fgMgrProtocol,
+             T= his,
+             &= amp;Mpam->Header,
+             A= cpiTableInfo,
+             T= ableSize
+             )= ;
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: MPAM: Failed to add ACPI heade= r. Status =3D %r\n",
+      Status
+      ));
+    goto error_handler;
+  }
+
+  // Update MPAM table
+  Mpam->NumNodes   =3D MscNodeCount;
+  Mpam->NodeOffset =3D sizeof (EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE= _PARTITIONING_MONITORING_TABLE_HEADER);
+  Mpam->Reserved   =3D EFI_ACPI_RESERVED_DWORD;
+
+  // Add MSC Nodes to the generated table
+  if (Mpam->NumNodes !=3D 0) {
+    Status =3D AddMscNodes (
+            &n= bsp;  This,
+            &n= bsp;  CfgMgrProtocol,
+            &n= bsp;  Mpam,
+            &n= bsp;  MscNodeOffset,
+            &n= bsp;  MscNodeList,
+            &n= bsp;  MscNodeCount
+            &n= bsp;  );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: MPAM: Failed to ad= d MSC Nodes. Status =3D %r\n",
+        Status
+        ));
+      goto error_handler;
+    }
+  }
+
+  return Status;
+
+error_handler:
+  if (Generator->NodeIndexer !=3D NULL) {
+    FreePool (Generator->NodeIndexer);
+    Generator->NodeIndexer =3D NULL;
+  }
+
+  if (*Table !=3D NULL) {
+    FreePool (*Table);
+    *Table =3D NULL;
+  }
+
+  return Status;
+}
+
+/** Free any resources allocated for constructing the MPAM
+
+  @param [in]      This   &nb= sp;       Pointer to the table generator.
+  @param [in]      AcpiTableInfo  Point= er to the ACPI Table Info.
+  @param [in]      CfgMgrProtocol Pointer to= the Configuration Manager
+            &n= bsp;            = ;         Protocol Interface.
+  @param [in, out] Table       &nb= sp;  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 &n= bsp;            = ;    *CONST  This,
+  IN      CONST CM_STD_OBJ_ACPI_TABLE_INFO&n= bsp;           *CONST&nbs= p; AcpiTableInfo,
+  IN      CONST EDKII_CONFIGURATION_MANAGER_= PROTOCOL  *CONST  CfgMgrProtocol,
+  IN OUT        EFI_ACPI_DESCRIPTI= ON_HEADER          **CONST&nbs= p; Table
+  )
+{
+  ACPI_MPAM_GENERATOR  *Generator;
+
+  ASSERT (This !=3D NULL);
+  ASSERT (AcpiTableInfo !=3D NULL);
+  ASSERT (CfgMgrProtocol !=3D NULL);
+  ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->Generato= rID);
+  ASSERT (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTa= bleSignature);
+
+  Generator =3D (ACPI_MPAM_GENERATOR *)This;
+
+  // Free any memory allocated by the generator
+  if (Generator->NodeIndexer !=3D NULL) {
+    FreePool (Generator->NodeIndexer);
+    Generator->NodeIndexer =3D NULL;
+  }
+
+  if ((Table =3D=3D NULL) || (*Table =3D=3D NULL)) {
+    DEBUG ((DEBUG_ERROR, "ERROR: MPAM: Invalid Table P= ointer\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  FreePool (*Table);
+  *Table =3D 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 =3D {
+  // 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_MONITO= RING_TABLE_STRUCTURE_SIGNATURE,
+    // ACPI Table Revision supported by this Generator
+    EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITO= RING_TABLE_REVISION,
+    // Minimum supported ACPI Table Revision
+    EFI_ACPI_6_4_MEMORY_SYSTEM_RESOURCE_PARTITIONING_MONITO= RING_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 gener= ator.
+    // Hence extended free resource function is not require= d.
+    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      &n= bsp; The handle to the image.
+  @param [in]  SystemTable      &n= bsp; 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 f= or the Table ID
+            &n= bsp;            = ;         is already registered. +**/
+EFI_STATUS
+EFIAPI
+AcpiMpamLibConstructor (
+  IN  EFI_HANDLE        Image= Handle,
+  IN  EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status =3D RegisterAcpiTableGenerator (&MpamGenerator.Header);<= br> +  DEBUG ((DEBUG_INFO, "MPAM: Register Generator. Status =3D %r\n= ", Status));
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
+
+/**
+  Deregister the Generator from the ACPI Table Factory.
+
+  @param [in]  ImageHandle      &n= bsp; The handle to the image.
+  @param [in]  SystemTable      &n= bsp; Pointer to the System Table.
+
+  @retval EFI_SUCCESS        =      The Generator is deregistered.
+  @retval EFI_INVALID_PARAMETER   A parameter is invalid. +  @retval EFI_NOT_FOUND       &nbs= p;   The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiMpamLibDestructor (
+  IN  EFI_HANDLE        Image= Handle,
+  IN  EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status =3D DeregisterAcpiTableGenerator (&MpamGenerator.Header)= ;
+  DEBUG ((DEBUG_INFO, "MPAM: Deregister Generator. Status =3D %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          &nb= sp;    *Object;
+  /// Node offset from the start of the MPAM table
+  UINT32          &= nbsp;  Offset;
+} MPAM_NODE_INDEXER;
+
+typedef struct AcpiMpamGenerator {
+  /// ACPI Table generator header
+  ACPI_TABLE_GENERATOR    Header;
+  /// MPAM structure count
+  UINT32          &= nbsp;       MpamNodeCount;
+  /// Count of Msc Nodes
+  UINT32          &= nbsp;       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

--_000_BY5PR12MB5543E4231D39A36F34F60678D3709BY5PR12MB5543namp_--