From nobody Tue Feb 10 01:58:54 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+76661+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one); dmarc=fail(p=none dis=none) header.from=arm.com Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1623923777353824.9227749636125; Thu, 17 Jun 2021 02:56:17 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id ZJCOYY1788612xx1thzs2wt0; Thu, 17 Jun 2021 02:56:17 -0700 X-Received: from EUR05-DB8-obe.outbound.protection.outlook.com (EUR05-DB8-obe.outbound.protection.outlook.com [40.107.20.42]) by mx.groups.io with SMTP id smtpd.web11.5403.1623923770839980278 for ; Thu, 17 Jun 2021 02:56:11 -0700 X-Received: from AM5PR0201CA0018.eurprd02.prod.outlook.com (2603:10a6:203:3d::28) by VI1PR08MB3536.eurprd08.prod.outlook.com (2603:10a6:803:79::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.24; Thu, 17 Jun 2021 09:56:07 +0000 X-Received: from AM5EUR03FT053.eop-EUR03.prod.protection.outlook.com (2603:10a6:203:3d:cafe::8a) by AM5PR0201CA0018.outlook.office365.com (2603:10a6:203:3d::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4242.19 via Frontend Transport; Thu, 17 Jun 2021 09:56:07 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; edk2.groups.io; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;edk2.groups.io; dmarc=pass action=none header.from=arm.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+76661+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; X-Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by AM5EUR03FT053.mail.protection.outlook.com (10.152.16.210) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4242.16 via Frontend Transport; Thu, 17 Jun 2021 09:56:06 +0000 X-Received: ("Tessian outbound 9d3d496fabe8:v93"); Thu, 17 Jun 2021 09:56:06 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: de599094081c67a4 X-CR-MTA-TID: 64aa7808 X-Received: from 1dbd225ac4df.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id DE767668-8837-4D1E-8864-F73986919F16.1; Thu, 17 Jun 2021 09:56:00 +0000 X-Received: from EUR04-DB3-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 1dbd225ac4df.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Thu, 17 Jun 2021 09:56:00 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NHUcQ2N0NTAZN4SeRA+UjUMMmdgoAZOpYsLsefmo+fB2VQKHzOV9KZFKUxHqsaRbu42lPhORsKUWEg/HucEylL7lDqcgNAJ5GUoUTvXvSyF4ZX5t/UKJT3Eb2BlcQzdj45PRBCiTjBsVQd3Rdpafwq+O0VRBafi+DY8Uu+XIK0RlOfk9XGjI26e6epIFCtKxWqId2+E3K2JS4QkKFG1v9FgCxMA+pbVRESh9156HYFqeUI2rozvYFVOlFwUObXyppcfBNE7o6knZFB0LrYKmK0U0ePPO9EYC93a45Hf4UJzxhr26gVaO1CiQqF/qq9kkKdqRw9GyZnIVUesNGaA69Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=KRNZ7KjU2LQXcUfNqTvxNTLbN+5MUPZWYW6WpXEAajs=; b=JY3wFvj3OXHdO8Ve/N6C6vQjNsYSguDjHxK6zTHYx4rnmYiG82E9iBJRMZX96adaGoUukAZOu7vqcJtFLmhzkIqwW8OepXVXDe/7WtQLrJz4+71LYUkqWLfmJmT+ho/cygG7POib15Zp+4XsALenpU/8FedcqTJkvYMQcnmwLgAy15/HjMFoAnjHT3MFdXMi1oDuvI4QNuNfmFPxDgpMn/pTjTwDswrUwJI/gor713GhvY0Ms+bc/X1La8/z30MUwxE4HnY0o3rZOR6e1oWN6PppvVBLbd0I/9khgT3oZyZ9HI2HaOly3AynMRFwfL+bK+ABtXA7Mwybzy/8l82FkQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 40.67.248.234) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none X-Received: from AM6P193CA0138.EURP193.PROD.OUTLOOK.COM (2603:10a6:209:85::43) by DB6PR0802MB2565.eurprd08.prod.outlook.com (2603:10a6:4:a1::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4219.24; Thu, 17 Jun 2021 09:55:54 +0000 X-Received: from AM5EUR03FT014.eop-EUR03.prod.protection.outlook.com (2603:10a6:209:85:cafe::3c) by AM6P193CA0138.outlook.office365.com (2603:10a6:209:85::43) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4242.18 via Frontend Transport; Thu, 17 Jun 2021 09:55:54 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 40.67.248.234) smtp.mailfrom=arm.com; edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 40.67.248.234 as permitted sender) receiver=protection.outlook.com; client-ip=40.67.248.234; helo=nebula.arm.com; X-Received: from nebula.arm.com (40.67.248.234) by AM5EUR03FT014.mail.protection.outlook.com (10.152.16.130) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.4242.16 via Frontend Transport; Thu, 17 Jun 2021 09:55:54 +0000 X-Received: from AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) by AZ-NEU-EX04.Arm.com (10.251.24.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.2176.14; Thu, 17 Jun 2021 09:55:47 +0000 X-Received: from AZ-NEU-EX03.Arm.com (10.251.24.31) by AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2176.14; Thu, 17 Jun 2021 09:55:45 +0000 X-Received: from E114225.Arm.com (10.1.196.43) by mail.arm.com (10.251.24.31) with Microsoft SMTP Server id 15.1.2176.14 via Frontend Transport; Thu, 17 Jun 2021 09:55:45 +0000 From: "Sami Mujawar" To: CC: Sami Mujawar , , , , , , Subject: [edk2-devel] [PATCH v2 8/8] DynamicTablesPkg: IORT generator updates for Rev E.b spec Date: Thu, 17 Jun 2021 10:55:37 +0100 Message-ID: <20210617095538.93280-9-sami.mujawar@arm.com> In-Reply-To: <20210617095538.93280-1-sami.mujawar@arm.com> References: <20210617095538.93280-1-sami.mujawar@arm.com> MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d0402f1f-339b-47b7-f8f3-08d931762066 X-MS-TrafficTypeDiagnostic: DB6PR0802MB2565:|VI1PR08MB3536: X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Oob-TLC-OOBClassifiers: OLM:6790;OLM:6790; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: F0bu2RncwaJg7rQA7CWtDzI+qfnkucENP4skqcOhvfY7uYfXeKYBtbcOKUWKJhyDJPCelRbYdScQIuohju+yXyzMKAk1FrPr3DpqS7IGhBjzAPtyi0FluqBkbfyrgQOEj8tMW6dPeceHlIkI+0MX0Ga7ubztOaptdRNWw2WfRLQ+M9NbznybraCP+xAnephZfJm995Gj9/2iPH8P2eAdYG4Ic350rZBgZdRTGJo3f7cKI73G5vT0yYpOI++2hAw9oTcRGxbiuVqzxByFknFxSJk1qITU72Ec0KqKKZJG4T2SG/s7P5KAB4VnrDNfWDXNRRFe3dzzJ4Um9QBE4T+y48g+nnZ8iLsesTt7WtJpVSWIkYxO9VBvKr/FmLNqVjMIEPofUnv2GuLbXccvsxkN7I04At7DBv4E5Epp8fyVA0Rtc7ggbVzzu2HkZVoBNDGgovVsx5cZqLtlmKchPreT+LLoJw644s4xQklri3qKvlNcX9P467YfE1CO2KjbmZ++ADV1G3jVUqWS+pXmV/ZGLyZEGyQ6NS75ekC85ve+Mi8k9I4uOXy3a6w1Kd6dkmycyodXnIvLF7PpwZdyEq8GmKbvpDrYxEz3zmRyStbMM3+UlWkFec/n7iCWN/d2RyVLRM3QWKsFpCZYaiZT2wYb23iEW/jAeNm4eNBBBLYrzTSmOole0o4Kf2rSK2sRQ8tRZHQOdD9VroCY/vxEzwpYjfqf0fa3nNC1JL1lr0vxRnHr5xIg8UIKpUFE5X+WpY4G1DNZCj+bqhr7n+g7nte6JLWTMSSdUeJtdbCLOCf5sqAGCy5tp51X5ZbDxpIfx6tCeN1hib60jp7OGLeFbgG2qrQ1SIWV7mQQTyDJ2Q+FcrE= X-Forefront-Antispam-Report-Untrusted: CIP:40.67.248.234;CTRY:IE;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:nebula.arm.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(4636009)(346002)(136003)(376002)(39850400004)(396003)(46966006)(36840700001)(5660300002)(336012)(426003)(1076003)(36756003)(83380400001)(4326008)(82310400003)(86362001)(36860700001)(6916009)(19627235002)(15650500001)(2906002)(30864003)(316002)(82740400003)(2616005)(7696005)(81166007)(6666004)(356005)(8676002)(8936002)(70206006)(26005)(186003)(54906003)(47076005)(478600001)(70586007)(44832011)(36900700001)(579004);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB6PR0802MB2565 X-MS-Exchange-Transport-CrossTenantHeadersStripped: AM5EUR03FT053.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: 6b414ce2-3724-49dd-09b2-08d9317618bf X-Microsoft-Antispam-Message-Info: 4mdwf2GauJmEDnQJOKqJlaBXNDZ9RTCwY0NCpSYnlx97/UCHe3dxBajX05wNcggnjLwZTYk3aY0E1DbaW6AuNk8Y5W4aTKxcNT+0nUKEb9vAxTNAzxFj8vXzCr04/s73l0DSeDN5/r3HbHtTFvEChZtkpzUzV7ar51C80eOgAspCInczSqxHqmHUa6SER2Fp7Bu4o5NPEC43PK/X7xi6qUSElKrLm00n21+vkFYrKZRu3+zO+feZfCEtcwnPjlYZOYMIftfLAjIhp6ynDPQ/0kCY/d/6SBTg51w2yw9wvdbJXhXyQ+A3OtomA1QQxEXg3HM2AAe3fv8R1Z18T4nf5Wb+6qRIC2lBBvxQamNAzl/TuHiyUpqD37fVkZ/MVU+dn7AsU/u+r8iUtj3fB8gczBnoojjDCeuLUX3vvzFTO2cs/Q0YyI6UKEwVpk1e6g5+iWZOIEN5stLrdYCXaEM6tEEU2sqsRBCrti4o9w4Rn36fzejZm6eqBWwv3b1mriWjKi8Kf0o7sxLesIGZWaZcbzi+Hf6Xu+tfHVUnlHr9S2dIncVpDGEB5GlbBF5EwhbA7QTadH1g2JHD+hvS8RipfydgpA3KwwOgZylgr0IQtLQcz2g85WTY/wQcx+O6ba+g2kmoKs/0vcTLNLAVZKv4h/Wykd05BolNNymWCOIWFrXrWnmUxaqi0ZVpfLiGBi4LZTUkRyQ4DcGmLYbFnnS7+WwV62dS06qYleMOz49jrPPhWqnVK+70micT8nYtcyGvWkWBmRRjetBcauvT9JQ7QHIX6jqG/eBaeOPAvDTBN/SsKLnQU1u/SSfBLRJs/xds X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jun 2021 09:56:06.8457 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: d0402f1f-339b-47b7-f8f3-08d931762066 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d;Ip=[63.35.35.123];Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: AM5EUR03FT053.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR08MB3536 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,sami.mujawar@arm.com X-Gm-Message-State: EwLwadykBc6AN0OnFWKlxuHrx1787277AA= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1623923777; bh=0cDYoZXHreMBan5gAlk4FU8uDLqF/aW4X56qo9NMGUo=; h=CC:Content-Type:Date:From:Reply-To:Subject:To; b=QIoFAUq5U6v91beOVYKFCBZtS7cbEZdPFm8LkCTeJxFScapE8EHBoZXAAPRA63r+pG3 nv+TSf9po3t0AoR87GB7NGrsF14Hkrce6qJHZtRVlknNumlaLMmvU/Xbg8RGB0mtPaBHr KDluTWKg46H8IvJs7n91/sxIFQnEKseB5+Q= X-ZohoMail-DKIM: pass (identity @groups.io) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Bugzilla: 3458 - Add support IORT Rev E.b specification updates (https://bugzilla.tianocore.org/show_bug.cgi?id=3D3458) The IO Remapping Table, Platform Design Document, Revision E.b, Feb 2021 (https://developer.arm.com/documentation/den0049/) introduces the following updates, collectively including the updates and errata fixes to Rev E and Rev E.a: - increments the IORT table revision to 3. - updates the node definition to add an 'Identifier' field. - adds definition of node type 6 - Reserved Memory Range node. - adds definition for Memory Range Descriptors. - adds flag to indicate PRI support for root complexes. - adds flag to indicate if the root complex supports forwarding of PASID information on translated transactions to the SMMU. Therefore, update the IORT generator to: - increment IORT table revision count to 3. - populate Identifier filed if revision is greater than 2. - add support to populate Reserved Memory Range nodes and the Memory range descriptors. - add validation to check that the Identifier field is unique. Signed-off-by: Sami Mujawar Reviewed-by: Pierre Gondois --- Notes: v2: - The macro EFI_ACPI_IO_REMAPPING_TABLE_REVISION was set to [SAMI] Rev 0 as setting to Rev 3 will break existing platforms. Therefore, set the max supported IORT generator revision to 3. DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c | 661 +++= +++++++++++++++-- DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h | 5 +- 2 files changed, 624 insertions(+), 42 deletions(-) diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator= .c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c index 9ccf72594db378878d4e3abbafe98e749d9963da..9b687f0165e6136f2f24749d27d= ee27edaff1b31 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c @@ -5,8 +5,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent =20 @par Reference(s): - - IO Remapping Table, Platform Design Document, - Document number: ARM DEN 0049D, Issue D, March 2018 + - IO Remapping Table, Platform Design Document, Revision E.b, Feb 2021 + (https://developer.arm.com/documentation/den0049/) =20 **/ =20 @@ -37,9 +37,11 @@ Requirements: - EArmObjSmmuV1SmmuV2 - EArmObjSmmuV3 - EArmObjPmcg + - EArmObjRmr - EArmObjGicItsIdentifierArray - EArmObjIdMappingArray - - EArmObjGicItsIdentifierArray + - EArmObjSmmuInterruptArray + - EArmObjMemoryRangeDescriptor */ =20 /** This macro expands to a function that retrieves the ITS @@ -96,6 +98,24 @@ GET_OBJECT_LIST ( CM_ARM_PMCG_NODE ); =20 +/** This macro expands to a function that retrieves the + RMR node information from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjRmr, + CM_ARM_RMR_NODE + ); + +/** This macro expands to a function that retrieves the + Memory Range Descriptor Array information from the Configuration Manag= er. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceArm, + EArmObjMemoryRangeDescriptor, + CM_ARM_MEMORY_RANGE_DESCRIPTOR + ); + /** This macro expands to a function that retrieves the ITS Identifier Array information from the Configuration Manager. */ @@ -177,13 +197,16 @@ GetSizeofItsGroupNodes ( (*NodeIndexer)->Token =3D NodeList->Token; (*NodeIndexer)->Object =3D (VOID*)NodeList; (*NodeIndexer)->Offset =3D (UINT32)(Size + NodeStartOffset); + (*NodeIndexer)->Identifier =3D NodeList->Identifier; DEBUG (( DEBUG_INFO, - "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset =3D = 0x%x\n", + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p," + " Offset =3D 0x%x, Identifier =3D 0x%x\n", *NodeIndexer, (*NodeIndexer)->Token, (*NodeIndexer)->Object, - (*NodeIndexer)->Offset + (*NodeIndexer)->Offset, + (*NodeIndexer)->Identifier )); =20 Size +=3D GetItsGroupNodeSize (NodeList); @@ -250,13 +273,16 @@ GetSizeofNamedComponentNodes ( (*NodeIndexer)->Token =3D NodeList->Token; (*NodeIndexer)->Object =3D (VOID*)NodeList; (*NodeIndexer)->Offset =3D (UINT32)(Size + NodeStartOffset); + (*NodeIndexer)->Identifier =3D NodeList->Identifier; DEBUG (( DEBUG_INFO, - "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset =3D = 0x%x\n", + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p," + " Offset =3D 0x%x, Identifier =3D 0x%x\n", *NodeIndexer, (*NodeIndexer)->Token, (*NodeIndexer)->Object, - (*NodeIndexer)->Offset + (*NodeIndexer)->Offset, + (*NodeIndexer)->Identifier )); =20 Size +=3D GetNamedComponentNodeSize (NodeList); @@ -322,13 +348,16 @@ GetSizeofRootComplexNodes ( (*NodeIndexer)->Token =3D NodeList->Token; (*NodeIndexer)->Object =3D (VOID*)NodeList; (*NodeIndexer)->Offset =3D (UINT32)(Size + NodeStartOffset); + (*NodeIndexer)->Identifier =3D NodeList->Identifier; DEBUG (( DEBUG_INFO, - "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset =3D = 0x%x\n", + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p," + " Offset =3D 0x%x, Identifier =3D 0x%x\n", *NodeIndexer, (*NodeIndexer)->Token, (*NodeIndexer)->Object, - (*NodeIndexer)->Offset + (*NodeIndexer)->Offset, + (*NodeIndexer)->Identifier )); =20 Size +=3D GetRootComplexNodeSize (NodeList); @@ -400,13 +429,16 @@ GetSizeofSmmuV1V2Nodes ( (*NodeIndexer)->Token =3D NodeList->Token; (*NodeIndexer)->Object =3D (VOID*)NodeList; (*NodeIndexer)->Offset =3D (UINT32)(Size + NodeStartOffset); + (*NodeIndexer)->Identifier =3D NodeList->Identifier; DEBUG (( DEBUG_INFO, - "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset =3D = 0x%x\n", + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p," + " Offset =3D 0x%x, Identifier =3D 0x%x\n", *NodeIndexer, (*NodeIndexer)->Token, (*NodeIndexer)->Object, - (*NodeIndexer)->Offset + (*NodeIndexer)->Offset, + (*NodeIndexer)->Identifier )); =20 Size +=3D GetSmmuV1V2NodeSize (NodeList); @@ -471,13 +503,16 @@ GetSizeofSmmuV3Nodes ( (*NodeIndexer)->Token =3D NodeList->Token; (*NodeIndexer)->Object =3D (VOID*)NodeList; (*NodeIndexer)->Offset =3D (UINT32)(Size + NodeStartOffset); + (*NodeIndexer)->Identifier =3D NodeList->Identifier; DEBUG (( DEBUG_INFO, - "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset =3D = 0x%x\n", + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p," + " Offset =3D 0x%x, Identifier =3D 0x%x\n", *NodeIndexer, (*NodeIndexer)->Token, (*NodeIndexer)->Object, - (*NodeIndexer)->Offset + (*NodeIndexer)->Offset, + (*NodeIndexer)->Identifier )); =20 Size +=3D GetSmmuV3NodeSize (NodeList); @@ -542,13 +577,16 @@ GetSizeofPmcgNodes ( (*NodeIndexer)->Token =3D NodeList->Token; (*NodeIndexer)->Object =3D (VOID*)NodeList; (*NodeIndexer)->Offset =3D (UINT32)(Size + NodeStartOffset); + (*NodeIndexer)->Identifier =3D NodeList->Identifier; DEBUG (( DEBUG_INFO, - "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset =3D = 0x%x\n", + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p," + " Offset =3D 0x%x, Identifier =3D 0x%x\n", *NodeIndexer, (*NodeIndexer)->Token, (*NodeIndexer)->Object, - (*NodeIndexer)->Offset + (*NodeIndexer)->Offset, + (*NodeIndexer)->Identifier )); =20 Size +=3D GetPmcgNodeSize (NodeList); @@ -558,6 +596,83 @@ GetSizeofPmcgNodes ( return Size; } =20 +/** Returns the size of the RMR node. + + @param [in] Node Pointer to RMR node. + + @retval Size of the RMR node. +**/ +STATIC +UINT32 +GetRmrNodeSize ( + IN CONST CM_ARM_RMR_NODE * Node + ) +{ + ASSERT (Node !=3D NULL); + + /* Size of RMR node + + Size of ID mapping array + + Size of Memory Range Descriptor array + */ + return (UINT32)(sizeof (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE) + + (Node->IdMappingCount * + sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE)) + + (Node->MemRangeDescCount * + sizeof (EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC))); +} + +/** Returns the total size required for the RMR nodes 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 + IORT where this node group starts. + @param [in] NodeList Pointer to RMR node list. + @param [in] NodeCount Count of the RMR nodes. + @param [in, out] NodeIndexer Pointer to the next Node Indexer. + + @retval Total size of the RMR nodes. +**/ +STATIC +UINT64 +GetSizeofRmrNodes ( + IN CONST UINT32 NodeStartOffset, + IN CONST CM_ARM_RMR_NODE * NodeList, + IN UINT32 NodeCount, + IN OUT IORT_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); + (*NodeIndexer)->Identifier =3D NodeList->Identifier; + DEBUG (( + DEBUG_INFO, + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p," + " Offset =3D 0x%x, Identifier =3D 0x%x\n", + *NodeIndexer, + (*NodeIndexer)->Token, + (*NodeIndexer)->Object, + (*NodeIndexer)->Offset, + (*NodeIndexer)->Identifier + )); + + Size +=3D GetRmrNodeSize (NodeList); + (*NodeIndexer)++; + NodeList++; + } + return Size; +} + /** Returns the offset of the Node referenced by the Token. =20 @param [in] NodeIndexer Pointer to node indexer array. @@ -707,6 +822,7 @@ AddIdMappingArray ( @param [in] This Pointer to the table Generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager Protocol Interface. + @param [in] AcpiTableInfo Pointer to the ACPI table info struct= ure. @param [in] Iort Pointer to IORT table structure. @param [in] NodesStartOffset Offset for the start of the ITS Group Nodes. @@ -723,6 +839,7 @@ EFI_STATUS AddItsGroupNodes ( IN CONST ACPI_TABLE_GENERATOR * CONST This, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, IN CONST UINT32 NodesStartOffset, IN CONST CM_ARM_ITS_GROUP_NODE * NodeList, @@ -759,11 +876,17 @@ AddItsGroupNodes ( // Populate the node header ItsGroupNode->Node.Type =3D EFI_ACPI_IORT_TYPE_ITS_GROUP; ItsGroupNode->Node.Length =3D (UINT16)NodeLength; - ItsGroupNode->Node.Revision =3D 0; - ItsGroupNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; ItsGroupNode->Node.NumIdMappings =3D 0; ItsGroupNode->Node.IdReference =3D 0; =20 + if (AcpiTableInfo->AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REV= 3) { + ItsGroupNode->Node.Revision =3D 0; + ItsGroupNode->Node.Identifier =3D EFI_ACPI_RESERVED_DWORD; + } else { + ItsGroupNode->Node.Revision =3D 1; + ItsGroupNode->Node.Identifier =3D NodeList->Identifier; + } + // IORT specific data ItsGroupNode->NumItsIdentifiers =3D NodeList->ItsIdCount; ItsIds =3D (UINT32*)((UINT8*)ItsGroupNode + @@ -814,6 +937,7 @@ AddItsGroupNodes ( @param [in] This Pointer to the table Generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager Protocol Interface. + @param [in] AcpiTableInfo Pointer to the ACPI table info struct= ure. @param [in] Iort Pointer to IORT table structure. @param [in] NodesStartOffset Offset for the start of the Named Component Nodes. @@ -830,6 +954,7 @@ EFI_STATUS AddNamedComponentNodes ( IN CONST ACPI_TABLE_GENERATOR * CONST This, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProto= col, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableIn= fo, IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, IN CONST UINT32 NodesStartO= ffset, IN CONST CM_ARM_NAMED_COMPONENT_NODE * NodeList, @@ -865,10 +990,16 @@ AddNamedComponentNodes ( // Populate the node header NcNode->Node.Type =3D EFI_ACPI_IORT_TYPE_NAMED_COMP; NcNode->Node.Length =3D (UINT16)NodeLength; - NcNode->Node.Revision =3D 2; - NcNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; NcNode->Node.NumIdMappings =3D NodeList->IdMappingCount; =20 + if (AcpiTableInfo->AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REV= 3) { + NcNode->Node.Revision =3D 2; + NcNode->Node.Identifier =3D EFI_ACPI_RESERVED_DWORD; + } else { + NcNode->Node.Revision =3D 4; + NcNode->Node.Identifier =3D NodeList->Identifier; + } + ObjectNameLength =3D AsciiStrLen (NodeList->ObjectName) + 1; NcNode->Node.IdReference =3D (NodeList->IdMappingCount =3D=3D 0) ? 0 : ((UINT32)(sizeof (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE) + @@ -899,8 +1030,19 @@ AddNamedComponentNodes ( return Status; } =20 - if ((NodeList->IdMappingCount > 0) && - (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { + if (NodeList->IdMappingCount > 0) { + if (NodeList->IdMappingToken =3D=3D CM_NULL_TOKEN) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Invalid Id Mapping token," + " Token =3D 0x%x, Status =3D%r\n", + NodeList->IdMappingToken, + Status + )); + return Status; + } + // Ids for Named Component IdMapArray =3D (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)NcNode + NcNode->Node.IdReference); @@ -938,6 +1080,7 @@ AddNamedComponentNodes ( @param [in] This Pointer to the table Generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager Protocol Interface. + @param [in] AcpiTableInfo Pointer to the ACPI table info struct= ure. @param [in] Iort Pointer to IORT table structure. @param [in] NodesStartOffset Offset for the start of the Root Comp= lex Nodes. @@ -954,6 +1097,7 @@ EFI_STATUS AddRootComplexNodes ( IN CONST ACPI_TABLE_GENERATOR * CONST This, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProto= col, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableIn= fo, IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, IN CONST UINT32 NodesStartO= ffset, IN CONST CM_ARM_ROOT_COMPLEX_NODE * NodeList, @@ -987,12 +1131,18 @@ AddRootComplexNodes ( // Populate the node header RcNode->Node.Type =3D EFI_ACPI_IORT_TYPE_ROOT_COMPLEX; RcNode->Node.Length =3D (UINT16)NodeLength; - RcNode->Node.Revision =3D 1; - RcNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; RcNode->Node.NumIdMappings =3D NodeList->IdMappingCount; RcNode->Node.IdReference =3D (NodeList->IdMappingCount =3D=3D 0) ? 0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE); =20 + if (AcpiTableInfo->AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REV= 3) { + RcNode->Node.Revision =3D 1; + RcNode->Node.Identifier =3D EFI_ACPI_RESERVED_DWORD; + } else { + RcNode->Node.Revision =3D 3; + RcNode->Node.Identifier =3D NodeList->Identifier; + } + // Root Complex specific data RcNode->CacheCoherent =3D NodeList->CacheCoherent; RcNode->AllocationHints =3D NodeList->AllocationHints; @@ -1005,8 +1155,19 @@ AddRootComplexNodes ( RcNode->Reserved1[1] =3D EFI_ACPI_RESERVED_BYTE; RcNode->Reserved1[2] =3D EFI_ACPI_RESERVED_BYTE; =20 - if ((NodeList->IdMappingCount > 0) && - (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { + if (NodeList->IdMappingCount > 0) { + if (NodeList->IdMappingToken =3D=3D CM_NULL_TOKEN) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Invalid Id Mapping token," + " Token =3D 0x%x, Status =3D%r\n", + NodeList->IdMappingToken, + Status + )); + return Status; + } + // Ids for Root Complex IdMapArray =3D (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)RcNode + RcNode->Node.IdReference); @@ -1107,6 +1268,7 @@ AddSmmuInterruptArray ( @param [in] This Pointer to the table Generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager Protocol Interface. + @param [in] AcpiTableInfo Pointer to the ACPI table info struct= ure. @param [in] Iort Pointer to IORT table structure. @param [in] NodesStartOffset Offset for the start of the SMMU v1/v2 Nodes. @@ -1123,6 +1285,7 @@ EFI_STATUS AddSmmuV1V2Nodes ( IN CONST ACPI_TABLE_GENERATOR * CONST This, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtoc= ol, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInf= o, IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, IN CONST UINT32 NodesStartOf= fset, IN CONST CM_ARM_SMMUV1_SMMUV2_NODE * NodeList, @@ -1159,8 +1322,6 @@ AddSmmuV1V2Nodes ( // Populate the node header SmmuNode->Node.Type =3D EFI_ACPI_IORT_TYPE_SMMUv1v2; SmmuNode->Node.Length =3D (UINT16)NodeLength; - SmmuNode->Node.Revision =3D 0; - SmmuNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; SmmuNode->Node.NumIdMappings =3D NodeList->IdMappingCount; SmmuNode->Node.IdReference =3D (NodeList->IdMappingCount =3D=3D 0) ? 0 : (sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE) + @@ -1169,6 +1330,14 @@ AddSmmuV1V2Nodes ( (NodeList->PmuInterruptCount * sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT))); =20 + if (AcpiTableInfo->AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REV= 3) { + SmmuNode->Node.Revision =3D 1; + SmmuNode->Node.Identifier =3D EFI_ACPI_RESERVED_DWORD; + } else { + SmmuNode->Node.Revision =3D 3; + SmmuNode->Node.Identifier =3D NodeList->Identifier; + } + // SMMU v1/v2 specific data SmmuNode->Base =3D NodeList->BaseAddress; SmmuNode->Span =3D NodeList->Span; @@ -1263,8 +1432,19 @@ AddSmmuV1V2Nodes ( } } =20 - if ((NodeList->IdMappingCount > 0) && - (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { + if (NodeList->IdMappingCount > 0) { + if (NodeList->IdMappingToken =3D=3D CM_NULL_TOKEN) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Invalid Id Mapping token," + " Token =3D 0x%x, Status =3D%r\n", + NodeList->IdMappingToken, + Status + )); + return Status; + } + // Ids for SMMU v1/v2 Node IdMapArray =3D (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)SmmuNod= e + SmmuNode->Node.IdReference); @@ -1300,6 +1480,7 @@ AddSmmuV1V2Nodes ( @param [in] This Pointer to the table Generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager Protocol Interface. + @param [in] AcpiTableInfo Pointer to the ACPI table info struct= ure. @param [in] Iort Pointer to IORT table structure. @param [in] NodesStartOffset Offset for the start of the SMMUv3 No= des. @param [in] NodeList Pointer to an array of SMMUv3 Node Ob= jects. @@ -1314,6 +1495,7 @@ EFI_STATUS AddSmmuV3Nodes ( IN CONST ACPI_TABLE_GENERATOR * CONST This, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtoc= ol, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInf= o, IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, IN CONST UINT32 NodesStartOf= fset, IN CONST CM_ARM_SMMUV3_NODE * NodeList, @@ -1346,12 +1528,18 @@ AddSmmuV3Nodes ( // Populate the node header SmmuV3Node->Node.Type =3D EFI_ACPI_IORT_TYPE_SMMUv3; SmmuV3Node->Node.Length =3D (UINT16)NodeLength; - SmmuV3Node->Node.Revision =3D 2; - SmmuV3Node->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; SmmuV3Node->Node.NumIdMappings =3D NodeList->IdMappingCount; SmmuV3Node->Node.IdReference =3D (NodeList->IdMappingCount =3D=3D 0) ? 0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE); =20 + if (AcpiTableInfo->AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REV= 3) { + SmmuV3Node->Node.Revision =3D 2; + SmmuV3Node->Node.Identifier =3D EFI_ACPI_RESERVED_DWORD; + } else { + SmmuV3Node->Node.Revision =3D 4; + SmmuV3Node->Node.Identifier =3D NodeList->Identifier; + } + // SMMUv3 specific data SmmuV3Node->Base =3D NodeList->BaseAddress; SmmuV3Node->Flags =3D NodeList->Flags; @@ -1379,8 +1567,19 @@ AddSmmuV3Nodes ( SmmuV3Node->DeviceIdMappingIndex =3D NodeList->DeviceIdMappingIndex; } =20 - if ((NodeList->IdMappingCount > 0) && - (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { + if (NodeList->IdMappingCount > 0) { + if (NodeList->IdMappingToken =3D=3D CM_NULL_TOKEN) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Invalid Id Mapping token," + " Token =3D 0x%x, Status =3D%r\n", + NodeList->IdMappingToken, + Status + )); + return Status; + } + // Ids for SMMUv3 node IdMapArray =3D (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)SmmuV3N= ode + SmmuV3Node->Node.IdReference); @@ -1417,6 +1616,7 @@ AddSmmuV3Nodes ( @param [in] This Pointer to the table Generator. @param [in] CfgMgrProtocol Pointer to the Configuration Manager Protocol Interface. + @param [in] AcpiTableInfo Pointer to the ACPI table info struct= ure. @param [in] Iort Pointer to IORT table structure. @param [in] NodesStartOffset Offset for the start of the PMCG Node= s. @param [in] NodeList Pointer to an array of PMCG Node Obje= cts. @@ -1431,6 +1631,7 @@ EFI_STATUS AddPmcgNodes ( IN CONST ACPI_TABLE_GENERATOR * CONST This, IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtoc= ol, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInf= o, IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, IN CONST UINT32 NodesStartOf= fset, IN CONST CM_ARM_PMCG_NODE * NodeList, @@ -1465,12 +1666,18 @@ AddPmcgNodes ( // Populate the node header PmcgNode->Node.Type =3D EFI_ACPI_IORT_TYPE_PMCG; PmcgNode->Node.Length =3D (UINT16)NodeLength; - PmcgNode->Node.Revision =3D 1; - PmcgNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; PmcgNode->Node.NumIdMappings =3D NodeList->IdMappingCount; PmcgNode->Node.IdReference =3D (NodeList->IdMappingCount =3D=3D 0) ? 0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE); =20 + if (AcpiTableInfo->AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REV= 3) { + PmcgNode->Node.Revision =3D 1; + PmcgNode->Node.Identifier =3D EFI_ACPI_RESERVED_DWORD; + } else { + PmcgNode->Node.Revision =3D 2; + PmcgNode->Node.Identifier =3D NodeList->Identifier; + } + // PMCG specific data PmcgNode->Base =3D NodeList->BaseAddress; PmcgNode->OverflowInterruptGsiv =3D NodeList->OverflowInterrupt; @@ -1494,8 +1701,19 @@ AddPmcgNodes ( return Status; } =20 - if ((NodeList->IdMappingCount > 0) && - (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { + if (NodeList->IdMappingCount > 0) { + if (NodeList->IdMappingToken =3D=3D CM_NULL_TOKEN) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Invalid Id Mapping token," + " Token =3D 0x%x, Status =3D%r\n", + NodeList->IdMappingToken, + Status + )); + return Status; + } + // Ids for PMCG node IdMapArray =3D (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)PmcgNod= e + PmcgNode->Node.IdReference); @@ -1526,6 +1744,273 @@ AddPmcgNodes ( return EFI_SUCCESS; } =20 +/** Update the Memory Range Descriptor Array. + + This function retrieves the Memory Range Descriptor objects referenced= by + MemRangeDescToken and updates the Memory Range Descriptor array. + + @param [in] This Pointer to the table Generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] DescArray Pointer to an array of Memory Range + Descriptors. + @param [in] DescCount Number of Id Descriptors. + @param [in] DescToken Reference Token for retrieving the + Memory Range Descriptor Array. + + @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 +AddMemRangeDescArray ( + IN CONST ACPI_TABLE_GENERATOR * CONST This, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtoc= ol, + IN EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC * DescArray, + IN UINT32 DescCount, + IN CONST CM_OBJECT_TOKEN DescToken + ) +{ + EFI_STATUS Status; + CM_ARM_MEMORY_RANGE_DESCRIPTOR * MemRangeDesc; + UINT32 MemRangeDescCount; + + ASSERT (DescArray !=3D NULL); + + // Get the Id Mapping Array + Status =3D GetEArmObjMemoryRangeDescriptor ( + CfgMgrProtocol, + DescToken, + &MemRangeDesc, + &MemRangeDescCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Failed to get Memory Range Descriptor array. Status = =3D %r\n", + Status + )); + return Status; + } + + if (MemRangeDescCount < DescCount) { + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Failed to get the required number of Memory" + " Range Descriptors.\n" + )); + return EFI_NOT_FOUND; + } + + // Populate the Memory Range Descriptor array + while (DescCount-- !=3D 0) { + + DescArray->Base =3D MemRangeDesc->BaseAddress; + DescArray->Length =3D MemRangeDesc->Length; + DescArray->Reserved =3D EFI_ACPI_RESERVED_DWORD; + + DescArray++; + MemRangeDesc++; + } + + return EFI_SUCCESS; +} + +/** Update the RMR Node Information. + + This function updates the RMR node information in the IORT table. + + @param [in] This Pointer to the table Generator. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] AcpiTableInfo Pointer to the ACPI table info struct= ure. + @param [in] Iort Pointer to IORT table structure. + @param [in] NodesStartOffset Offset for the start of the PMCG Node= s. + @param [in] NodeList Pointer to an array of PMCG Node Obje= cts. + @param [in] NodeCount Number of PMCG 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 +AddRmrNodes ( + IN CONST ACPI_TABLE_GENERATOR * CONST This, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtoc= ol, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInf= o, + IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, + IN CONST UINT32 NodesStartOf= fset, + IN CONST CM_ARM_RMR_NODE * NodeList, + IN UINT32 NodeCount + ) +{ + EFI_STATUS Status; + EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE * RmrNode; + EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray; + EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC * MemRangeDescArray; + UINT64 NodeLength; + + ASSERT (Iort !=3D NULL); + + RmrNode =3D (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE*)((UINT8*)Iort + + NodesStartOffset); + + while (NodeCount-- !=3D 0) { + NodeLength =3D GetRmrNodeSize (NodeList); + if (NodeLength > MAX_UINT16) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: RMR Node length 0x%lx > MAX_UINT16. Status =3D %r\n", + NodeLength, + Status + )); + return Status; + } + + if (NodeList->MemRangeDescCount =3D=3D 0) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Memory Range Desc count =3D %d. Status =3D %r\n", + NodeList->MemRangeDescCount, + Status + )); + return Status; + } + + if (NodeList->MemRangeDescToken =3D=3D CM_NULL_TOKEN) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Invalid Memory Range Descriptor token," + " Token =3D 0x%x. Status =3D %r\n", + NodeList->MemRangeDescToken, + Status + )); + return Status; + } + + // Populate the node header + RmrNode->Node.Type =3D EFI_ACPI_IORT_TYPE_RMR; + RmrNode->Node.Length =3D (UINT16)NodeLength; + RmrNode->Node.Revision =3D 1; + RmrNode->Node.Identifier =3D NodeList->Identifier; + RmrNode->Node.NumIdMappings =3D NodeList->IdMappingCount; + RmrNode->Node.IdReference =3D (NodeList->IdMappingCount =3D=3D 0) ? + 0 : sizeof (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE); + + // RMR specific data + RmrNode->Flags =3D NodeList->Flags; + RmrNode->NumMemRangeDesc =3D NodeList->MemRangeDescCount; + RmrNode->MemRangeDescRef =3D (NodeList->MemRangeDescCount =3D=3D 0) ? + 0 : (sizeof (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE) + + (NodeList->IdMappingCount * + sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE))); + + if (NodeList->IdMappingCount > 0) { + if (NodeList->IdMappingToken =3D=3D CM_NULL_TOKEN) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Invalid Id Mapping token," + " Token =3D 0x%x, Status =3D%r\n", + NodeList->IdMappingToken, + Status + )); + return Status; + } + + // Ids for RMR node + IdMapArray =3D (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)RmrNode= + + RmrNode->Node.IdReference); + + Status =3D AddIdMappingArray ( + This, + CfgMgrProtocol, + IdMapArray, + NodeList->IdMappingCount, + NodeList->IdMappingToken + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Failed to add Id Mapping Array. Status =3D %r\n", + Status + )); + return Status; + } + } + + // Memory Range Descriptors for RMR node + MemRangeDescArray =3D (EFI_ACPI_6_0_IO_REMAPPING_MEM_RANGE_DESC*)( + (UINT8*)RmrNode + + RmrNode->MemRangeDescRef + ); + + Status =3D AddMemRangeDescArray ( + This, + CfgMgrProtocol, + MemRangeDescArray, + NodeList->MemRangeDescCount, + NodeList->MemRangeDescToken + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Failed to Memory Range Descriptor Array. Status =3D = %r\n", + Status + )); + return Status; + } + + // Next RMR Node + RmrNode =3D (EFI_ACPI_6_0_IO_REMAPPING_RMR_NODE*)((UINT8*)RmrNode + + RmrNode->Node.Length); + NodeList++; + } // RMR Node + + return EFI_SUCCESS; +} + +/** Validates that the IORT nodes Identifier are unique. + + @param [in] NodeIndexer Pointer to the Node Indexer. + @param [in] NodeCount Number of IORT Nodes. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER Identifier field not unique. +**/ +STATIC +EFI_STATUS +ValidateNodeIdentifiers ( + IN CONST IORT_NODE_INDEXER * CONST NodeIndexer, + IN UINT32 NodeCount + ) +{ + UINT32 IndexI; + UINT32 IndexJ; + + for (IndexI =3D 0; IndexI < NodeCount; IndexI++) { + for (IndexJ =3D 0; IndexJ < NodeCount; IndexJ++) { + if ((IndexI !=3D IndexJ) && + (NodeIndexer[IndexI].Identifier =3D=3D NodeIndexer[IndexJ].Ident= ifier)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: UID %d of Token %p matches with that of Token %p.\= n", + NodeIndexer[IndexI].Identifier, + NodeIndexer[IndexI].Token, + NodeIndexer[IndexJ].Token + )); + return EFI_INVALID_PARAMETER; + } + }// IndexJ + } // IndexI + return EFI_SUCCESS; +} + /** Construct the IORT ACPI table. =20 This function invokes the Configuration Manager protocol interface @@ -1570,6 +2055,7 @@ BuildIortTable ( UINT32 SmmuV1V2NodeCount; UINT32 SmmuV3NodeCount; UINT32 PmcgNodeCount; + UINT32 RmrNodeCount; =20 UINT32 ItsGroupOffset; UINT32 NamedComponentOffset; @@ -1577,6 +2063,7 @@ BuildIortTable ( UINT32 SmmuV1V2Offset; UINT32 SmmuV3Offset; UINT32 PmcgOffset; + UINT32 RmrOffset; =20 CM_ARM_ITS_GROUP_NODE * ItsGroupNodeList; CM_ARM_NAMED_COMPONENT_NODE * NamedComponentNodeList; @@ -1584,6 +2071,7 @@ BuildIortTable ( CM_ARM_SMMUV1_SMMUV2_NODE * SmmuV1V2NodeList; CM_ARM_SMMUV3_NODE * SmmuV3NodeList; CM_ARM_PMCG_NODE * PmcgNodeList; + CM_ARM_RMR_NODE * RmrNodeList; =20 EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort; IORT_NODE_INDEXER * NodeIndexer; @@ -1726,6 +2214,27 @@ BuildIortTable ( // Add the PMCG node count IortNodeCount +=3D PmcgNodeCount; =20 + if (AcpiTableInfo->AcpiTableRevision >=3D EFI_ACPI_IO_REMAPPING_TABLE_RE= V3) { + // Get the RMR node info + Status =3D GetEArmObjRmr ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &RmrNodeList, + &RmrNodeCount + ); + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Failed to get RMR Node Info. Status =3D %r\n", + Status + )); + goto error_handler; + } + + // Add the RMR node count + IortNodeCount +=3D RmrNodeCount; + } + // Allocate Node Indexer array NodeIndexer =3D (IORT_NODE_INDEXER*)AllocateZeroPool ( (sizeof (IORT_NODE_INDEXER) * @@ -1929,6 +2438,37 @@ BuildIortTable ( )); } =20 + // RMR Nodes + if ((AcpiTableInfo->AcpiTableRevision >=3D EFI_ACPI_IO_REMAPPING_TABLE_R= EV3) && + (RmrNodeCount > 0)) { + RmrOffset =3D (UINT32)TableSize; + // Size of RMR node list. + NodeSize =3D GetSizeofRmrNodes ( + RmrOffset, + RmrNodeList, + RmrNodeCount, + &NodeIndexer + ); + if (NodeSize > MAX_UINT32) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Invalid Size of RMR Nodes. Status =3D %r\n", + Status + )); + goto error_handler; + } + TableSize +=3D NodeSize; + + DEBUG (( + DEBUG_INFO, + " RmrNodeCount =3D %d\n" \ + " RmrOffset =3D %d\n", + RmrNodeCount, + RmrOffset + )); + } + DEBUG (( DEBUG_INFO, "INFO: IORT:\n" \ @@ -1950,6 +2490,19 @@ BuildIortTable ( goto error_handler; } =20 + // Validate that the identifiers for the nodes are unique + if (AcpiTableInfo->AcpiTableRevision >=3D EFI_ACPI_IO_REMAPPING_TABLE_RE= V3) { + Status =3D ValidateNodeIdentifiers (Generator->NodeIndexer, IortNodeCo= unt); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Node Identifier not unique. Status =3D %r\n", + Status + )); + goto error_handler; + } + } + // Allocate the Buffer for IORT table *Table =3D (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize); if (*Table =3D=3D NULL) { @@ -1998,6 +2551,7 @@ BuildIortTable ( Status =3D AddItsGroupNodes ( This, CfgMgrProtocol, + AcpiTableInfo, Iort, ItsGroupOffset, ItsGroupNodeList, @@ -2017,6 +2571,7 @@ BuildIortTable ( Status =3D AddNamedComponentNodes ( This, CfgMgrProtocol, + AcpiTableInfo, Iort, NamedComponentOffset, NamedComponentNodeList, @@ -2036,6 +2591,7 @@ BuildIortTable ( Status =3D AddRootComplexNodes ( This, CfgMgrProtocol, + AcpiTableInfo, Iort, RootComplexOffset, RootComplexNodeList, @@ -2055,6 +2611,7 @@ BuildIortTable ( Status =3D AddSmmuV1V2Nodes ( This, CfgMgrProtocol, + AcpiTableInfo, Iort, SmmuV1V2Offset, SmmuV1V2NodeList, @@ -2074,6 +2631,7 @@ BuildIortTable ( Status =3D AddSmmuV3Nodes ( This, CfgMgrProtocol, + AcpiTableInfo, Iort, SmmuV3Offset, SmmuV3NodeList, @@ -2093,6 +2651,7 @@ BuildIortTable ( Status =3D AddPmcgNodes ( This, CfgMgrProtocol, + AcpiTableInfo, Iort, PmcgOffset, PmcgNodeList, @@ -2101,7 +2660,27 @@ BuildIortTable ( if (EFI_ERROR (Status)) { DEBUG (( DEBUG_ERROR, - "ERROR: IORT: Failed to add SMMUv3 Node. Status =3D %r\n", + "ERROR: IORT: Failed to add PMCG Node. Status =3D %r\n", + Status + )); + goto error_handler; + } + } + + if (RmrNodeCount > 0) { + Status =3D AddRmrNodes ( + This, + CfgMgrProtocol, + AcpiTableInfo, + Iort, + RmrOffset, + RmrNodeList, + RmrNodeCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: IORT: Failed to add RMR Node. Status =3D %r\n", Status )); goto error_handler; @@ -2184,11 +2763,11 @@ ACPI_IORT_GENERATOR IortGenerator =3D { // Generator Description L"ACPI.STD.IORT.GENERATOR", // ACPI Table Signature - EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, + EFI_ACPI_6_3_IO_REMAPPING_TABLE_SIGNATURE, // ACPI Table Revision supported by this Generator - EFI_ACPI_IO_REMAPPING_TABLE_REVISION, + EFI_ACPI_IO_REMAPPING_TABLE_REV3, // Minimum supported ACPI Table Revision - EFI_ACPI_IO_REMAPPING_TABLE_REVISION, + EFI_ACPI_IO_REMAPPING_TABLE_REV0, // Creator ID TABLE_GENERATOR_CREATOR_ID_ARM, // Creator Revision diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator= .h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h index bbf8aaf9efa38a75626a49af6f380b1c8c1a0629..afe2089b1dc20ed671583e2a309= cc1a46c3404c6 100644 --- a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h +++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h @@ -1,6 +1,6 @@ /** @file =20 - Copyright (c) 2018, ARM Limited. All rights reserved. + Copyright (c) 2018 - 2021, ARM Limited. All rights reserved. =20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -25,6 +25,9 @@ typedef struct IortNodeIndexer { VOID * Object; /// Node offset from the start of the IORT table UINT32 Offset; + + /// Unique identifier for the Node + UINT32 Identifier; } IORT_NODE_INDEXER; =20 typedef struct AcpiIortGenerator { --=20 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#76661): https://edk2.groups.io/g/devel/message/76661 Mute This Topic: https://groups.io/mt/83600726/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-