From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a01:111:f400:fe02::608; helo=eur01-db5-obe.outbound.protection.outlook.com; envelope-from=evan.lloyd@arm.com; receiver=edk2-devel@lists.01.org Received: from EUR01-DB5-obe.outbound.protection.outlook.com (mail-db5eur01on0608.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe02::608]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 71DE0209574EE for ; Mon, 19 Mar 2018 09:10:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector1-arm-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=XN4NtGOKfOeipRJgN4Gqhrk2ayseybZ0VosjWhdkD4c=; b=cpzOc28/JDsHtzGPT6XL6avVsmss1lnv57eKmn4FfxO3YCnbOPANEZoNpNTFG81mm6W+W6AyPQoPrEkif6NtNTBRXyvJLWQKL2vGQYI0pP+pTtizDzGX7l5CgNWKlMyfO0knpDOH1Z8FSY8T4lLHN+KTWK+31Ojw/QkRbBuELXM= Received: from HE1PR0801MB1771.eurprd08.prod.outlook.com (10.168.150.14) by HE1PR0801MB1820.eurprd08.prod.outlook.com (10.168.150.140) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.588.14; Mon, 19 Mar 2018 16:16:35 +0000 Received: from HE1PR0801MB1771.eurprd08.prod.outlook.com ([fe80::69cc:3ecf:9c8c:f5a3]) by HE1PR0801MB1771.eurprd08.prod.outlook.com ([fe80::69cc:3ecf:9c8c:f5a3%17]) with mapi id 15.20.0588.016; Mon, 19 Mar 2018 16:16:35 +0000 From: Evan Lloyd To: Sami Mujawar , "edk2-devel@lists.01.org" CC: "leif.lindholm@linaro.org" , Matteo Carlini , Stephanie Hughes-Fitt , nd Thread-Topic: [staging/dynamictables PATCH 2/2] DynamicTablesPkg: Dynamic Tables Framework Thread-Index: AQHTv5Wb53rGNLnomUiwZ+kIu1KBU6PXvAWg Date: Mon, 19 Mar 2018 16:16:35 +0000 Message-ID: References: <20180319151847.85204-1-sami.mujawar@arm.com> <20180319151847.85204-3-sami.mujawar@arm.com> In-Reply-To: <20180319151847.85204-3-sami.mujawar@arm.com> Accept-Language: en-GB, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=Evan.Lloyd@arm.com; x-originating-ip: [217.140.96.140] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; HE1PR0801MB1820; 7:6DXD0jUIasQm5+rSIvIeV6j3j4bm0gnbzDu7SEr1hqcwBssfy8KIEuUD8G0a1cVILpmmteQze/QEx0PshzZA4y6ouzzSNc2pZiEcvoUXokRqQip3VIIN2TFrguTm6I9nxO0x8YrbJ+Ip2jI9Pake0xCFkhygEBDFNv6yfKRvG6UJTeEmCgzmZDVyKOn+rh8zXNyjHfrieySMy2T02h09xIxkTlEVI12Oj2pDOOHZk73IE8lNOF3gR+4ri5apD2ZK x-ms-exchange-antispam-srfa-diagnostics: SOS;SOR; x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: cee55894-15ff-4197-adfe-08d58db4c959 x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(48565401081)(5600026)(4604075)(3008032)(2017052603328)(7153060)(7193020); SRVR:HE1PR0801MB1820; x-ms-traffictypediagnostic: HE1PR0801MB1820: nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(158342451672863)(180628864354917)(162533806227266); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(10201501046)(3002001)(3231221)(944501300)(52105095)(93006095)(93001095)(6055026)(6041310)(20161123562045)(20161123564045)(20161123560045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011); SRVR:HE1PR0801MB1820; BCL:0; PCL:0; RULEID:; SRVR:HE1PR0801MB1820; x-forefront-prvs: 06167FAD59 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(376002)(39380400002)(366004)(346002)(39860400002)(396003)(189003)(13464003)(199004)(5250100002)(478600001)(33656002)(2501003)(14454004)(53946003)(4326008)(16200700003)(72206003)(3280700002)(53936002)(25786009)(6436002)(45080400002)(55016002)(8676002)(9686003)(6306002)(7696005)(105586002)(5660300001)(99286004)(53376002)(16799955002)(15188155005)(2900100001)(97736004)(2906002)(6246003)(76176011)(68736007)(26005)(54906003)(66066001)(305945005)(74316002)(86362001)(102836004)(6506007)(53546011)(59450400001)(7736002)(81166006)(6116002)(8936002)(106356001)(2950100002)(229853002)(81156014)(966005)(575784001)(3660700001)(110136005)(3846002)(316002)(569006); DIR:OUT; SFP:1101; SCL:1; SRVR:HE1PR0801MB1820; H:HE1PR0801MB1771.eurprd08.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-microsoft-antispam-message-info: Z2iHkYmMMfuQkSWM3BkvBoNamUIlmhlm9j/xfrSUN9vyJk82nG0cmq5gf9WPOtoCYop8NFVkhhOrmk8GbiMorIeo5UqByDjexMJSdBt/TWTDXspzKIVkI8Gb+b0CJm+DgCuDtCBzIcD3tESSgakqfFNjVuKiUo7422JNefQ33IH6ALsdFi72eGF+ylOTYHiWxI5Vm9l3JRldVILEr8iP1vqW1CIdHAJa3H6BHWdKRqM9DTFU/DBq3XF9AR/RKvlY5LqOJgrSueuZuK2DYrF3cjMlEuWmuA7y2g52Ijexi331th1TUUpGgLDdhI8YfQt+vwiDUXZTaj/jwopUdF8clg== spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-Network-Message-Id: cee55894-15ff-4197-adfe-08d58db4c959 X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Mar 2018 16:16:35.0614 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR0801MB1820 Subject: Re: [staging/dynamictables PATCH 2/2] DynamicTablesPkg: Dynamic Tables Framework X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Mar 2018 16:10:17 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > -----Original Message----- > From: Sami Mujawar [mailto:sami.mujawar@arm.com] > Sent: 19 March 2018 15:19 > To: edk2-devel@lists.01.org > Cc: Evan Lloyd ; leif.lindholm@linaro.org; Matteo > Carlini ; Stephanie Hughes-Fitt > ; nd > Subject: [staging/dynamictables PATCH 2/2] DynamicTablesPkg: Dynamic > Tables Framework >=20 > The dynamic tables framework is designed to generate standardised > firmware tables that describe the hardware information at > run-time. A goal of standardised firmware is to have a common > firmware for a platform capable of booting both Windows and Linux > operating systems. >=20 > Traditionally the firmware tables are handcrafted using ACPI > Source Language (ASL), Table Definition Language (TDL) and > C-code. This approach can be error prone and involves time > consuming debugging. In addition, it may be desirable to configure > platform hardware at runtime such as: configuring the number of > cores available for use by the OS, or turning SoC features ON or > OFF. >=20 > The dynamic tables framework simplifies this by providing a set > of standard table generators, that are implemented as libraries. > These generators query a platform specific component, the > 'Configuration Manager', to collate the information required > for generating the tables at run-time. >=20 > The framework also provides the ability to implement custom/OEM > generators; thereby facilitating support for custom tables. The > custom generators can also utilize the existing standard generators > and override any functionality if needed. >=20 > The framework currently implements a set of standard ACPI table > generators for ARM architecture, that can generate Server Base Boot > Requirement (SBBR) compliant tables. Support for generating SMBIOS > tables is planned to be added subsequently. Although, the set > of standard generators implement the functionality required for ARM > architecture; the framework is extensible, and support for other > architectures can be added easily. >=20 > Contributions from the community are invited. >=20 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Sami Mujawar Reviewed-by: Evan Lloyd > --- >=20 > DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/Acpi > TableFactory.c | 226 +++ >=20 > DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFactor > y/DeviceTreeTableFactory.c | 225 +++ >=20 > DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory. > h | 125 ++ >=20 > DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory > Dxe.c | 84 + >=20 > DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory > Dxe.inf | 59 + >=20 > DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/S > mbiosTableFactory.c | 226 +++ >=20 > DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManag > erDxe.c | 533 +++++ >=20 > DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManag > erDxe.inf | 48 + > DynamicTablesPkg/DynamicTables.dsc.inc > | 46 + > DynamicTablesPkg/DynamicTables.fdf.inc > | 35 + > DynamicTablesPkg/DynamicTablesPkg.dec > | 42 + > DynamicTablesPkg/Include/AcpiTableGenerator.h > | 282 +++ > DynamicTablesPkg/Include/ArmNameSpaceObjects.h > | 587 ++++++ > DynamicTablesPkg/Include/ConfigurationManagerHelper.h > | 119 ++ > DynamicTablesPkg/Include/ConfigurationManagerObject.h > | 176 ++ > DynamicTablesPkg/Include/DeviceTreeTableGenerator.h > | 182 ++ > DynamicTablesPkg/Include/Library/TableHelperLib.h > | 70 + > DynamicTablesPkg/Include/Protocol/ConfigurationManagerProtocol.h > | 128 ++ > DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h > | 140 ++ > DynamicTablesPkg/Include/SmbiosTableGenerator.h > | 240 +++ > DynamicTablesPkg/Include/StandardNameSpaceObjects.h > | 116 ++ > DynamicTablesPkg/Include/TableGenerator.h > | 252 +++ >=20 > DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf > | 47 + > DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c > | 440 +++++ > DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf > | 41 + > DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c > | 666 +++++++ > DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf > | 41 + > DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c > | 670 +++++++ > DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf > | 41 + > DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c > | 2046 ++++++++++++++++++++ > DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h > | 50 + >=20 > DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.in > f | 41 + > DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c > | 717 +++++++ > DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf > | 41 + > DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c > | 342 ++++ > DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf > | 41 + > DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c > | 142 ++ > DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf > | 41 + > DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c > | 324 ++++ > DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c > | 164 ++ > DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf > | 35 + > 41 files changed, 9871 insertions(+) >=20 > diff --git > a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/A > cpiTableFactory.c > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/A > cpiTableFactory.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..425b2f2d8feb959493 > 214d545aaa9b59a0fbeba2 > --- /dev/null > +++ > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/A > cpiTableFactory.c > @@ -0,0 +1,226 @@ > +/** @file > + ACPI Table Factory > + > + Copyright (c) 2017, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Std - Standard > +**/ > + > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > + > +#include "DynamicTableFactory.h" > + > +extern EFI_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo; > + > +/** Return a pointer to the ACPI table generator. > + > + @param [in] This Pointer to the Dynamic Table Factory Protoco= l. > + @param [in] GeneratorId The ACPI table generator ID for the > + requested generator. > + @param [out] Generator Pointer to the requested ACPI table > + generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +GetAcpiTableGenerator ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This, > + IN CONST ACPI_TABLE_GENERATOR_ID GeneratorId, > + OUT CONST ACPI_TABLE_GENERATOR ** CONST Generator > + ) > +{ > + UINT16 TableId; > + EFI_DYNAMIC_TABLE_FACTORY_INFO * FactoryInfo; > + > + ASSERT (This !=3D NULL); > + > + FactoryInfo =3D This->TableFactoryInfo; > + > + if (Generator =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: Invalid Generator pointer\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_ACPI (GeneratorId)) { > + DEBUG ((DEBUG_ERROR, "ERROR: Generator Type is not ACPI\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + *Generator =3D NULL; > + TableId =3D GET_TABLE_ID (GeneratorId); > + if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) { > + if (TableId >=3D (ESTD_ACPI_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_ACPI_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->StdAcpiTableGeneratorList[TableId] !=3D NULL) { > + *Generator =3D FactoryInfo->StdAcpiTableGeneratorList[TableId]; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >=3D FixedPcdGet16 (PcdMaxCustomACPIGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomACPIGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->CustomAcpiTableGeneratorList[TableId] !=3D NULL) { > + *Generator =3D FactoryInfo->CustomAcpiTableGeneratorList[TableId]; > + } else { > + return EFI_NOT_FOUND; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** Register ACPI table factory generator. > + > + The ACPI table factory maintains a list of the Standard and OEM ACPI > + table generators. > + > + @param [in] Generator Pointer to the ACPI table generator. > + > + @retval EFI_SUCCESS The Generator was registered > + successfully. > + @retval EFI_INVALID_PARAMETER The Generator ID is invalid or > + the Generator pointer is NULL. > + @retval EFI_ALREADY_STARTED The Generator for the Table ID is > + already registered. > +*/ > +EFI_STATUS > +EFIAPI > +RegisterAcpiTableGenerator ( > + IN CONST ACPI_TABLE_GENERATOR * CONST Generator > + ) > +{ > + UINT16 TableId; > + > + if (Generator =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: ACPI register - Invalid Generator\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_ACPI (Generator->GeneratorID)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: ACPI register - Generator" \ > + " Type is not ACPI\n" > + )); > + return EFI_INVALID_PARAMETER; > + } > + > + DEBUG ((DEBUG_INFO, "Registering %s\n", Generator->Description)); > + > + TableId =3D GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >=3D (ESTD_ACPI_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_ACPI_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdAcpiTableGeneratorList[TableId] =3D=3D NULL)= { > + TableFactoryInfo.StdAcpiTableGeneratorList[TableId] =3D Generator; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } else { > + if (TableId >=3D FixedPcdGet16 (PcdMaxCustomACPIGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomACPIGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] =3D=3D NU= LL) { > + TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] =3D Generat= or; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** Deregister ACPI generator. > + > + This function is called by the ACPI table generator to deregister itse= lf > + from the ACPI table factory. > + > + @param [in] Generator Pointer to the ACPI table generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER The generator is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +DeregisterAcpiTableGenerator ( > + IN CONST ACPI_TABLE_GENERATOR * CONST Generator > + ) > +{ > + UINT16 TableId; > + > + if (Generator =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: ACPI deregister - Invalid > Generator\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_ACPI (Generator->GeneratorID)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: ACPI deregister - Generator" \ > + " Type is not ACPI\n" > + )); > + return EFI_INVALID_PARAMETER; > + } > + > + TableId =3D GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >=3D (ESTD_ACPI_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_ACPI_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdAcpiTableGeneratorList[TableId] !=3D NULL) { > + if (Generator !=3D TableFactoryInfo.StdAcpiTableGeneratorList[Tabl= eId]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.StdAcpiTableGeneratorList[TableId] =3D NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >=3D FixedPcdGet16 (PcdMaxCustomACPIGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomACPIGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] !=3D NULL= ) { > + if (Generator !=3D > + TableFactoryInfo.CustomAcpiTableGeneratorList[TableId]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] =3D NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } > + > + DEBUG ((DEBUG_INFO, "Deregistering %s\n", Generator->Description)); > + return EFI_SUCCESS; > +} > diff --git > a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFact > ory/DeviceTreeTableFactory.c > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFac > tory/DeviceTreeTableFactory.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..9e4fa3f8ffce390f3aa8 > 5136f3508e139cca3326 > --- /dev/null > +++ > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFac > tory/DeviceTreeTableFactory.c > @@ -0,0 +1,225 @@ > +/** @file > + Device Tree Table Factory > + > + Copyright (c) 2017, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Std - Standard > +**/ > + > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > + > +#include "DynamicTableFactory.h" > + > +extern EFI_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo; > + > +/** Return a pointer to the DT table generator. > + > + @param [in] This Pointer to the Dynamic Table Factory Protoco= l. > + @param [in] GeneratorId The DT table generator ID for the > + requested generator. > + @param [out] Generator Pointer to the requested DT table > + generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +GetDtTableGenerator ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This, > + IN CONST DT_TABLE_GENERATOR_ID GeneratorId, > + OUT CONST DT_TABLE_GENERATOR ** CONST Generator > + ) > +{ > + UINT16 TableId; > + EFI_DYNAMIC_TABLE_FACTORY_INFO * FactoryInfo; > + > + ASSERT (This !=3D NULL); > + > + FactoryInfo =3D This->TableFactoryInfo; > + > + if (Generator =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: Invalid Generator pointer\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_DT (GeneratorId)) { > + DEBUG ((DEBUG_ERROR, "ERROR: Generator Type is not DT\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + *Generator =3D NULL; > + TableId =3D GET_TABLE_ID (GeneratorId); > + if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) { > + if (TableId >=3D (ESTD_DT_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_DT_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->StdDtTableGeneratorList[TableId] !=3D NULL) { > + *Generator =3D FactoryInfo->StdDtTableGeneratorList[TableId]; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >=3D FixedPcdGet16 (PcdMaxCustomDTGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomDTGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->CustomDtTableGeneratorList[TableId] !=3D NULL) { > + *Generator =3D FactoryInfo->CustomDtTableGeneratorList[TableId]; > + } else { > + return EFI_NOT_FOUND; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** Register DT table factory generator. > + > + The DT table factory maintains a list of the Standard and OEM DT > + table generators. > + > + @param [in] Generator Pointer to the DT table generator. > + > + @retval EFI_SUCCESS The Generator was registered > + successfully. > + @retval EFI_INVALID_PARAMETER The Generator ID is invalid or > + the Generator pointer is NULL. > + @retval EFI_ALREADY_STARTED The Generator for the Table ID is > + already registered. > +*/ > +EFI_STATUS > +EFIAPI > +RegisterDtTableGenerator ( > + IN CONST DT_TABLE_GENERATOR * CONST Generator > + ) > +{ > + UINT16 TableId; > + > + if (Generator =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: DT register - Invalid Generator\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_DT (Generator->GeneratorID)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: DT register - Generator" \ > + " Type is not DT\n" > + )); > + return EFI_INVALID_PARAMETER; > + } > + > + DEBUG ((DEBUG_INFO, "Registering %s\n", Generator->Description)); > + > + TableId =3D GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >=3D (ESTD_DT_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_DT_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdDtTableGeneratorList[TableId] =3D=3D NULL) { > + TableFactoryInfo.StdDtTableGeneratorList[TableId] =3D Generator; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } else { > + if (TableId >=3D FixedPcdGet16 (PcdMaxCustomDTGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomDTGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomDtTableGeneratorList[TableId] =3D=3D NULL= ) { > + TableFactoryInfo.CustomDtTableGeneratorList[TableId] =3D Generator= ; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** Deregister DT generator. > + > + This function is called by the DT table generator to deregister itself > + from the DT table factory. > + > + @param [in] Generator Pointer to the DT table generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER The generator is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +DeregisterDtTableGenerator ( > + IN CONST DT_TABLE_GENERATOR * CONST Generator > + ) > +{ > + UINT16 TableId; > + > + if (Generator =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: DT deregister - Invalid Generator\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_DT (Generator->GeneratorID)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: DT deregister - Generator" \ > + " Type is not DT\n" > + )); > + return EFI_INVALID_PARAMETER; > + } > + > + TableId =3D GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >=3D (ESTD_DT_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_DT_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdDtTableGeneratorList[TableId] !=3D NULL) { > + if (Generator !=3D TableFactoryInfo.StdDtTableGeneratorList[TableI= d]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.StdDtTableGeneratorList[TableId] =3D NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >=3D FixedPcdGet16 (PcdMaxCustomDTGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomDTGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomDtTableGeneratorList[TableId] !=3D NULL) = { > + if (Generator !=3D > + TableFactoryInfo.CustomDtTableGeneratorList[TableId]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.CustomDtTableGeneratorList[TableId] =3D NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } > + > + DEBUG ((DEBUG_INFO, "Deregistering %s\n", Generator->Description)); > + return EFI_SUCCESS; > +} > diff --git > a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactor > y.h > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFacto > ry.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..c0b4a2a11457933b1c > 86950338f5619111747dc3 > --- /dev/null > +++ > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFacto > ry.h > @@ -0,0 +1,125 @@ > +/** @file > + > + Copyright (c) 2017, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Std - Standard > + - ACPI - Advanced Configuration and Power Interface > + - SMBIOS - System Management BIOS > + - DT - Device Tree > +**/ > + > +#ifndef DYNAMIC_TABLE_FACTORY_H_ > +#define DYNAMIC_TABLE_FACTORY_H_ > + > +#pragma pack(1) > + > +/** A structure that holds the list of registered ACPI and > + SMBIOS table generators. > +*/ > +typedef struct DynamicTableFactoryInfo { > + /// An array for holding the list of Standard ACPI Table Generators. > + CONST ACPI_TABLE_GENERATOR * > + StdAcpiTableGeneratorList[ESTD_ACPI_TABLE_ID_MAX]; > + > + /// An array for holding the list of Custom ACPI Table Generators. > + CONST ACPI_TABLE_GENERATOR * > + CustomAcpiTableGeneratorList[FixedPcdGet16 ( > + PcdMaxCustomACPIGenerators > + )]; > + > + /// An array for holding the list of Standard SMBIOS Table Generators. > + CONST SMBIOS_TABLE_GENERATOR * > + StdSmbiosTableGeneratorList[ESTD_SMBIOS_TABLE_ID_MAX]; > + > + /// An array for holding the list of Custom SMBIOS Table Generators. > + CONST SMBIOS_TABLE_GENERATOR * > + CustomSmbiosTableGeneratorList[FixedPcdGet16 ( > + PcdMaxCustomSMBIOSGenerators > + )]; > + > + /// An array for holding the list of Standard DT Table Generators. > + CONST DT_TABLE_GENERATOR * > + StdDtTableGeneratorList[ESTD_DT_TABLE_ID_MAX]; > + > + /// An array for holding the list of Custom DT Table Generators. > + CONST DT_TABLE_GENERATOR * > + CustomDtTableGeneratorList[FixedPcdGet16 ( > + PcdMaxCustomDTGenerators > + )]; > +} EFI_DYNAMIC_TABLE_FACTORY_INFO; > + > +/** Return a pointer to the ACPI table generator. > + > + @param [in] This Pointer to the Dynamic Table Factory Protoco= l. > + @param [in] GeneratorId The ACPI table generator ID for the > + requested generator. > + @param [out] Generator Pointer to the requested ACPI table > + generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +GetAcpiTableGenerator ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This, > + IN CONST ACPI_TABLE_GENERATOR_ID GeneratorId, > + OUT CONST ACPI_TABLE_GENERATOR ** CONST Generator > + ); > + > +/** Return a pointer to the SMBIOS table generator. > + > + @param [in] This Pointer to the Dynamic Table Factory Protoco= l. > + @param [in] GeneratorId The SMBIOS table generator ID for the > + requested generator. > + @param [out] Generator Pointer to the requested SMBIOS table > + generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +GetSmbiosTableGenerator ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This, > + IN CONST SMBIOS_TABLE_GENERATOR_ID GeneratorId, > + OUT CONST SMBIOS_TABLE_GENERATOR ** CONST Generator > + ); > + > +/** Return a pointer to the DT table generator. > + > + @param [in] This Pointer to the Dynamic Table Factory Protoco= l. > + @param [in] GeneratorId The DT table generator ID for the > + requested generator. > + @param [out] Generator Pointer to the requested DT table > + generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +GetDtTableGenerator ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This, > + IN CONST DT_TABLE_GENERATOR_ID GeneratorId, > + OUT CONST DT_TABLE_GENERATOR ** CONST Generator > + ); > + > +#pragma pack() > + > +#endif // DYNAMIC_TABLE_FACTORY_H_ > diff --git > a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactor > yDxe.c > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFacto > ryDxe.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..6ac291ab29a8f44ed91 > 845f5e6f65e0e5248f80b > --- /dev/null > +++ > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFacto > ryDxe.c > @@ -0,0 +1,84 @@ > +/** @file > + Dynamic Table Factory Dxe > + > + Copyright (c) 2017, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "DynamicTableFactory.h" > + > +/** The Dynamic Table Factory protocol structure that holds the > + list of registered ACPI and SMBIOS table generators. > +*/ > +EFI_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo; > + > +/** A structure describing the Dynamic Table Factory protocol. > +*/ > +STATIC > +CONST > +EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL DynamicTableFactoryProtocol > =3D { > + CREATE_REVISION (1, 0), > + GetAcpiTableGenerator, > + GetSmbiosTableGenerator, > + GetDtTableGenerator, > + &TableFactoryInfo > +}; > + > +/** Entrypoint for Dynamic Table Factory Dxe. > + > + @param ImageHandle > + @param SystemTable > + > + @retval EFI_SUCCESS Success. > + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. > + @retval EFI_NOT_FOUND Required interface/object was not found. > + @retval EFI_INVALID_PARAMETER Some parameter is incorrect/invalid. > +*/ > +EFI_STATUS > +EFIAPI > +DynamicTableFactoryDxeInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + Status =3D gBS->InstallProtocolInterface ( > + &ImageHandle, > + &gEfiDynamicTableFactoryProtocolGuid, > + EFI_NATIVE_INTERFACE, > + (VOID*)&DynamicTableFactoryProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to install the Dynamic Table Factory Protocol." \ > + " Status =3D %r\n", > + Status > + )); > + } > + return Status; > +} > diff --git > a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactor > yDxe.inf > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFacto > ryDxe.inf > new file mode 100644 > index > 0000000000000000000000000000000000000000..346168d6b1496eb180 > 8565f830b9c0eae4b06f79 > --- /dev/null > +++ > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFacto > ryDxe.inf > @@ -0,0 +1,59 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D DynamicTableFactoryDxe > + FILE_GUID =3D FE846898-7403-4932-B8AD-A0491F0C2CB= A > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + ENTRY_POINT =3D DynamicTableFactoryDxeInitialize > + > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D ARM AARCH64 > +# > + > +[Sources] > + AcpiTableFactory/AcpiTableFactory.c > + DeviceTreeTableFactory/DeviceTreeTableFactory.c > + DynamicTableFactoryDxe.c > + SmbiosTableFactory/SmbiosTableFactory.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + MemoryAllocationLib > + PrintLib > + TableHelperLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + > +[FixedPcd] > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomACPIGenerators > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomSMBIOSGenerators > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomDTGenerators > + > +[Protocols] > + gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUM= ED > + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUM= ED > + gEfiConfigurationManagerProtocolGuid > + gEfiDynamicTableFactoryProtocolGuid > + > +[Depex] > + TRUE > diff --git > a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory > /SmbiosTableFactory.c > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory > /SmbiosTableFactory.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..01be8cd1ca5371770d > 179ca1ec12de387bd49cd7 > --- /dev/null > +++ > b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory > /SmbiosTableFactory.c > @@ -0,0 +1,226 @@ > +/** @file > + SMBIOS Table Factory > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Std - Standard > +**/ > + > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > + > +#include "DynamicTableFactory.h" > + > +extern EFI_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo; > + > +/** Return a pointer to the SMBIOS table generator. > + > + @param [in] This Pointer to the Dynamic Table Factory Protoco= l. > + @param [in] GeneratorId The SMBIOS table generator ID for the > + requested generator. > + @param [out] Generator Pointer to the requested SMBIOS table > + generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +GetSmbiosTableGenerator ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This, > + IN CONST SMBIOS_TABLE_GENERATOR_ID GeneratorId, > + OUT CONST SMBIOS_TABLE_GENERATOR ** CONST Generator > + ) > +{ > + UINT16 TableId; > + EFI_DYNAMIC_TABLE_FACTORY_INFO * FactoryInfo; > + > + ASSERT (This !=3D NULL); > + > + FactoryInfo =3D This->TableFactoryInfo; > + > + if (Generator =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: Invalid Generator pointer\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_SMBIOS (GeneratorId)) { > + DEBUG ((DEBUG_ERROR, "ERROR: Generator Type is not SMBIOS\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + *Generator =3D NULL; > + TableId =3D GET_TABLE_ID (GeneratorId); > + if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) { > + if (TableId >=3D (ESTD_SMBIOS_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_SMBIOS_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->StdSmbiosTableGeneratorList[TableId] !=3D NULL) { > + *Generator =3D FactoryInfo->StdSmbiosTableGeneratorList[TableId]; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >=3D FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->CustomSmbiosTableGeneratorList[TableId] !=3D NULL) = { > + *Generator =3D FactoryInfo->CustomSmbiosTableGeneratorList[TableId= ]; > + } else { > + return EFI_NOT_FOUND; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** Register SMBIOS table factory generator. > + > + The SMBIOS table factory maintains a list of the Standard and OEM > SMBIOS > + table generators. > + > + @param [in] Generator Pointer to the SMBIOS table generator. > + > + @retval EFI_SUCCESS The Generator was registered > + successfully. > + @retval EFI_INVALID_PARAMETER The Generator ID is invalid or > + the Generator pointer is NULL. > + @retval EFI_ALREADY_STARTED The Generator for the Table ID is > + already registered. > +*/ > +EFI_STATUS > +EFIAPI > +RegisterSmbiosTableGenerator ( > + IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator > + ) > +{ > + UINT16 TableId; > + > + if (Generator =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS register - Invalid > Generator\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_SMBIOS (Generator->GeneratorID)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SMBIOS register - Generator" \ > + " Type is not SMBIOS\n" > + )); > + return EFI_INVALID_PARAMETER; > + } > + > + DEBUG ((DEBUG_INFO, "Registering %s\n", Generator->Description)); > + > + TableId =3D GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >=3D (ESTD_SMBIOS_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_SMBIOS_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] =3D=3D NUL= L) { > + TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] =3D Generato= r; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } else { > + if (TableId >=3D FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] =3D=3D = NULL) > { > + TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] =3D > Generator; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** Deregister SMBIOS generator. > + > + This function is called by the SMBIOS table generator to deregister it= self > + from the SMBIOS table factory. > + > + @param [in] Generator Pointer to the SMBIOS table generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER The generator is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +DeregisterSmbiosTableGenerator ( > + IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator > + ) > +{ > + UINT16 TableId; > + > + if (Generator =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS deregister - Invalid > Generator\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_SMBIOS (Generator->GeneratorID)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SMBIOS deregister - Generator" \ > + " Type is not SMBIOS\n" > + )); > + return EFI_INVALID_PARAMETER; > + } > + > + TableId =3D GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >=3D (ESTD_SMBIOS_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_SMBIOS_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] !=3D NULL)= { > + if (Generator !=3D > TableFactoryInfo.StdSmbiosTableGeneratorList[TableId]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] =3D NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >=3D FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] !=3D NU= LL) > { > + if (Generator !=3D > + TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] =3D NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } > + > + DEBUG ((DEBUG_INFO, "Deregistering %s\n", Generator->Description)); > + return EFI_SUCCESS; > +} > diff --git > a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableMan > agerDxe.c > b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableMan > agerDxe.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..5a3ad21220bd924bab > ab3ca2a28c87c5a91efa0c > --- /dev/null > +++ > b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableMan > agerDxe.c > @@ -0,0 +1,533 @@ > +/** @file > + Dynamic Table Manager Dxe > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** This macro expands to a function that retrieves the ACPI Table > + List from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceStandard, > + EStdObjAcpiTableList, > + CM_STD_OBJ_ACPI_TABLE_INFO > + ) > + > +/** A helper function to invoke a Table generator > + > + This is a helper function that invokes the Table generator interface > + for building an ACPI table. It uses the AcpiTableProtocol to install t= he > + table, then frees the resources allocated for generating it. > + > + @param [in] TableFactoryProtocol Pointer to the Table Factory Protoco= l > + interface. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. > + @param [in] AcpiTableInfo Pointer to the ACPI table Info. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND Required object is not found. > + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration > Manager > + is less than the Object size for the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +BuildAndInstallAcpiTable ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST > TableFactoryProtocol, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN EFI_ACPI_TABLE_PROTOCOL * AcpiTableProtocol= , > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo > + ) > +{ > + EFI_STATUS Status; > + EFI_STATUS Status1; > + CONST ACPI_TABLE_GENERATOR * Generator =3D NULL; > + EFI_ACPI_DESCRIPTION_HEADER * AcpiTable =3D NULL; > + UINTN TableHandle; > + > + ASSERT (TableFactoryProtocol !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (AcpiTableProtocol !=3D NULL); > + ASSERT (AcpiTableInfo !=3D NULL); > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: EStdObjAcpiTableList: Address =3D 0x%p," \ > + " TableGeneratorId =3D 0x%x\n", > + AcpiTableInfo, > + AcpiTableInfo->TableGeneratorId > + )); > + > + Status =3D TableFactoryProtocol->GetAcpiTableGenerator ( > + TableFactoryProtocol, > + AcpiTableInfo->TableGeneratorId, > + &Generator > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Table Generator not found." \ > + " TableGeneratorId =3D 0x%x. Status =3D %r\n", > + AcpiTableInfo->TableGeneratorId, > + Status > + )); > + return Status; > + } > + > + ASSERT (Generator !=3D NULL); > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: Generator found : %s\n", > + Generator->Description > + )); > + > + if (Generator->BuildAcpiTable =3D=3D NULL) { > + Status =3D EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Table Generator does not implement the" \ > + " ACPI_TABLE_GENERATOR_BUILD_TABLE interface." \ > + " TableGeneratorId =3D 0x%x. Status =3D %r\n", > + AcpiTableInfo->TableGeneratorId, > + Status > + )); > + return Status; > + } > + > + Status =3D Generator->BuildAcpiTable ( > + Generator, > + AcpiTableInfo, > + CfgMgrProtocol, > + &AcpiTable > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to Build Table." \ > + " TableGeneratorId =3D 0x%x. Status =3D %r\n", > + AcpiTableInfo->TableGeneratorId, > + Status > + )); > + // Free any allocated resources. > + goto exit_handler; > + } > + > + ASSERT (AcpiTable !=3D NULL); > + > + // Dump ACPI Table Header > + DUMP_ACPI_TABLE_HEADER (AcpiTable); > + > + // Install ACPI table > + Status =3D AcpiTableProtocol->InstallAcpiTable ( > + AcpiTableProtocol, > + AcpiTable, > + AcpiTable->Length, > + &TableHandle > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to Install ACPI Table. Status =3D %r\n", > + Status > + )); > + // Free any allocated resources. > + goto exit_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: ACPI Table installed. Status =3D %r\n", > + Status > + )); > + > +exit_handler: > + // Free any resources allocated for generating the tables. > + if (Generator->FreeTableResources !=3D NULL) { > + Status1 =3D Generator->FreeTableResources ( > + Generator, > + AcpiTableInfo, > + CfgMgrProtocol, > + &AcpiTable > + ); > + if (EFI_ERROR (Status1)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to Free Table Resources." \ > + "TableGeneratorId =3D 0x%x. Status =3D %r\n", > + AcpiTableInfo->TableGeneratorId, > + Status > + )); > + } > + > + // Return the first error status in case of failure > + if (!EFI_ERROR (Status)) { > + Status =3D Status1; > + } > + } > + > + return Status; > +} > + > +/** The function checks if the Configuration Manager has provided the > + mandatory ACPI tables for installation. > + > + @param [in] AcpiTableInfo Pointer to the ACPI Table Info list. > + @param [in] AcpiTableCount Count of ACPI Table Info. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_NOT_FOUND If mandatory table is not found. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +VerifyMandatoryTablesArePresent ( > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN UINT32 AcpiTableCount > + ) > +{ > + EFI_STATUS Status =3D EFI_SUCCESS; > + BOOLEAN FadtFound =3D FALSE; > + BOOLEAN MadtFound =3D FALSE; > + BOOLEAN GtdtFound =3D FALSE; > + BOOLEAN DsdtFound =3D FALSE; > + BOOLEAN Dbg2Found =3D FALSE; > + BOOLEAN SpcrFound =3D FALSE; > + > + ASSERT (AcpiTableInfo !=3D NULL); > + > + while (AcpiTableCount-- !=3D 0) { > + switch (AcpiTableInfo[AcpiTableCount].AcpiTableSignature) { > + case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: > + FadtFound =3D TRUE; > + break; > + case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: > + MadtFound =3D TRUE; > + break; > + case EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE: > + GtdtFound =3D TRUE; > + break; > + case > EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: > + DsdtFound =3D TRUE; > + break; > + case EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE: > + Dbg2Found =3D TRUE; > + break; > + case > EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE: > + SpcrFound =3D TRUE; > + break; > + default: > + break; > + } > + } > + > + // We need at least the FADT, MADT, GTDT and the DSDT tables to boot > + if (!FadtFound) { > + DEBUG ((DEBUG_ERROR,"ERROR: FADT Table not found\n")); > + Status =3D EFI_NOT_FOUND; > + } > + if (!MadtFound) { > + DEBUG ((DEBUG_ERROR, "ERROR: MADT Table not found.\n")); > + Status =3D EFI_NOT_FOUND; > + } > + if (!GtdtFound) { > + DEBUG ((DEBUG_ERROR, "ERROR: GTDT Table not found.\n")); > + Status =3D EFI_NOT_FOUND; > + } > + if (!DsdtFound) { > + DEBUG ((DEBUG_ERROR, "ERROR: DSDT Table not found.\n")); > + Status =3D EFI_NOT_FOUND; > + } > + if (!Dbg2Found) { > + DEBUG ((DEBUG_WARN, "WARNING: DBG2 Table not found.\n")); > + } > + if (!SpcrFound) { > + DEBUG ((DEBUG_WARN, "WARNING: SPCR Table not found.\n")); > + } > + return Status; > +} > + > +/** Generate and install ACPI tables. > + > + The function gathers the information necessary for installing the > + ACPI tables from the Configuration Manager, invokes the generators > + and installs them (via BuildAndInstallAcpiTable). > + > + @param [in] TableFactoryProtocol Pointer to the Table Factory Protoco= l > + interface. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_NOT_FOUND If a mandatory table or a generator is not > found. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +ProcessAcpiTables ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST > TableFactoryProtocol, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_TABLE_PROTOCOL * AcpiTableProtocol; > + CM_STD_OBJ_ACPI_TABLE_INFO * AcpiTableInfo; > + UINT32 AcpiTableCount; > + UINT32 idx; > + > + ASSERT (TableFactoryProtocol !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + > + // Find the AcpiTable protocol > + Status =3D gBS->LocateProtocol ( > + &gEfiAcpiTableProtocolGuid, > + NULL, > + (VOID**)&AcpiTableProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find AcpiTable protocol. Status =3D %r\n", > + Status > + )); > + return Status; > + } > + > + Status =3D GetEStdObjAcpiTableList ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &AcpiTableInfo, > + &AcpiTableCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to get ACPI Table List. Status =3D %r\n", > + Status > + )); > + return Status; > + } > + > + if (0 =3D=3D AcpiTableCount) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: EStdObjAcpiTableList: AcpiTableCount =3D %d\n", > + AcpiTableCount > + )); > + return EFI_NOT_FOUND; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: EStdObjAcpiTableList: AcpiTableCount =3D %d\n", > + AcpiTableCount > + )); > + > + // Check if mandatory ACPI tables are present. > + Status =3D VerifyMandatoryTablesArePresent ( > + AcpiTableInfo, > + AcpiTableCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find mandatory ACPI Table(s)." > + " Status =3D %r\n", > + Status > + )); > + return Status; > + } > + > + // Add the FADT Table first. > + for (idx =3D 0; idx < AcpiTableCount; idx++) { > + if (CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_FADT) =3D=3D > + AcpiTableInfo[idx].TableGeneratorId) { > + Status =3D BuildAndInstallAcpiTable ( > + TableFactoryProtocol, > + CfgMgrProtocol, > + AcpiTableProtocol, > + &AcpiTableInfo[idx] > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find build and install ACPI FADT Table." \ > + " Status =3D %r\n", > + Status > + )); > + return Status; > + } > + break; > + } > + } // for > + > + // Add remaining ACPI Tables > + for (idx =3D 0; idx < AcpiTableCount; idx++) { > + DEBUG (( > + DEBUG_INFO, > + "INFO: AcpiTableInfo[%d].TableGeneratorId =3D 0x%x\n", > + idx, > + AcpiTableInfo[idx].TableGeneratorId > + )); > + > + // Skip FADT Table since we have already added > + if (CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_FADT) =3D=3D > + AcpiTableInfo[idx].TableGeneratorId) { > + continue; > + } > + > + // Skip the Reserved table Generator ID > + if ((CREATE_STD_ACPI_TABLE_GEN_ID > (ESTD_ACPI_TABLE_ID_RESERVED) >=3D > + AcpiTableInfo[idx].TableGeneratorId) || > + (CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_MAX) > <=3D > + AcpiTableInfo[idx].TableGeneratorId)) { > + DEBUG (( > + DEBUG_WARN, > + "WARNING: Invalid ACPI Generator table ID =3D 0x%x, Skipping...\= n", > + AcpiTableInfo[idx].TableGeneratorId > + )); > + continue; > + } > + > + Status =3D BuildAndInstallAcpiTable ( > + TableFactoryProtocol, > + CfgMgrProtocol, > + AcpiTableProtocol, > + &AcpiTableInfo[idx] > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find, build, and install ACPI Table." \ > + " Status =3D %r\n", > + Status > + )); > + return Status; > + } > + } // for > + > + return Status; > +} > + > +/** Entrypoint of Dynamic Table Manager Dxe. > + > + The Dynamic Table Manager uses the Configuration Manager Protocol > + to get the list of ACPI and SMBIOS tables to install. For each table > + in the list it requests the corresponding ACPI/SMBIOS table factory fo= r > + a generator capable of building the ACPI/SMBIOS table. > + If a suitable table generator is found, it invokes the generator inter= face > + to build the table. The Dynamic Table Manager then installs the > + table and invokes another generator interface to free any resources > + allocated for building the table. > + > + @param ImageHandle > + @param SystemTable > + > + @retval EFI_SUCCESS Success. > + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. > + @retval EFI_NOT_FOUND Required interface/object was not found. > + @retval EFI_INVALID_PARAMETER Some parameter is incorrect/invalid. > +*/ > +EFI_STATUS > +EFIAPI > +DynamicTableManagerDxeInitialize ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status; > + EFI_CONFIGURATION_MANAGER_PROTOCOL * CfgMgrProtocol; > + CM_STD_OBJ_CONFIGURATION_MANAGER_INFO * CfgMfrInfo; > + EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * TableFactoryProtocol; > + > + // Locate the Dynamic Table Factory > + Status =3D gBS->LocateProtocol ( > + &gEfiDynamicTableFactoryProtocolGuid, > + NULL, > + (VOID**)&TableFactoryProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find Dynamic Table Factory protocol." \ > + " Status =3D %r\n", > + Status > + )); > + return Status; > + } > + > + // Locate the Configuration Manager for the Platform > + Status =3D gBS->LocateProtocol ( > + &gEfiConfigurationManagerProtocolGuid, > + NULL, > + (VOID**)&CfgMgrProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find Configuration Manager protocol. Status =3D = %r\n", > + Status > + )); > + return Status; > + } > + > + Status =3D GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to get Configuration Manager info. Status =3D %r\n"= , > + Status > + )); > + return Status; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: Configuration Manager Version =3D 0x%x, OemID > =3D %c%c%c%c%c%c\n", > + CfgMfrInfo->Revision, > + CfgMfrInfo->OemId[0], > + CfgMfrInfo->OemId[1], > + CfgMfrInfo->OemId[2], > + CfgMfrInfo->OemId[3], > + CfgMfrInfo->OemId[4], > + CfgMfrInfo->OemId[5] > + )); > + > + Status =3D ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: ACPI Table processing failure. Status =3D %r\n", > + Status > + )); > + } > + return Status; > +} > diff --git > a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableMan > agerDxe.inf > b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableMan > agerDxe.inf > new file mode 100644 > index > 0000000000000000000000000000000000000000..d006587a0119a8d5b4 > 33e3c651320d1c6e86f0f9 > --- /dev/null > +++ > b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableMan > agerDxe.inf > @@ -0,0 +1,48 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D DynamicTableManagerDxe > + FILE_GUID =3D 89122868-BCFD-49E8-88A3-06635CB7B3C= F > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + ENTRY_POINT =3D DynamicTableManagerDxeInitialize > + > +# > +# The following information is for reference only and not required by th= e > build tools. > +# > +# VALID_ARCHITECTURES =3D ARM AARCH64 > +# > + > +[Sources] > + DynamicTableManagerDxe.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + PrintLib > + TableHelperLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + > +[Protocols] > + gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUM= ED > + gEfiConfigurationManagerProtocolGuid > + gEfiDynamicTableFactoryProtocolGuid > + > +[Depex] > + TRUE > diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc > b/DynamicTablesPkg/DynamicTables.dsc.inc > new file mode 100644 > index > 0000000000000000000000000000000000000000..b89ea0c004710ebe98 > 34ac94a459bc98f9e1b5af > --- /dev/null > +++ b/DynamicTablesPkg/DynamicTables.dsc.inc > @@ -0,0 +1,46 @@ > +## @file > +# Dsc include file for Dynamic Tables Framework. > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
> +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +# > +## > + > +[Defines] > + > +[BuildOptions] > + *_*_*_ASL_FLAGS =3D -tc -li > + > +[LibraryClasses.common] > + > +[Components.common] > + # > + # Dynamic Table Factory Dxe > + # > + > DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory > Dxe.inf { > + > + > TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/Table > HelperLib.inf > + > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibAr > m.inf > + > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibAr > m.inf > + > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLib > Arm.inf > + > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibAr > m.inf > + > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibAr > m.inf > + > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibA > rm.inf > + > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibA > rm.inf > + > NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm > .inf > + } > + > + # > + # Dynamic Tables Manager Dxe > + # > + > DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManag > erDxe.inf { > + > + > TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/Table > HelperLib.inf > + } > diff --git a/DynamicTablesPkg/DynamicTables.fdf.inc > b/DynamicTablesPkg/DynamicTables.fdf.inc > new file mode 100644 > index > 0000000000000000000000000000000000000000..51229c1cbfecae3ba14 > 0f38a43fa67f11d716c58 > --- /dev/null > +++ b/DynamicTablesPkg/DynamicTables.fdf.inc > @@ -0,0 +1,35 @@ > +## @file > +# fdf include file for Dynamic Tables Framework. > +# > +# Copyright (c) 2017, ARM Limited. All rights reserved.
> +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +# > +## > + > +######################################################### > ####################### > +# > +# FV Section > +# > +# [FV] section is used to define what components or modules are placed > within a flash > +# device file. This section also defines order the components and modul= es > are positioned > +# within the image. The [FV] section consists of define statements, set > statements and > +# module statements. > +# > +######################################################### > ####################### > + > + # > + # Dynamic Table Factory Dxe > + # > + INF > DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory > Dxe.inf > + > + # > + # Dynamic Tables Dxe > + # > + INF > DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManag > erDxe.inf > diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec > b/DynamicTablesPkg/DynamicTablesPkg.dec > new file mode 100644 > index > 0000000000000000000000000000000000000000..4ac88d12aa47f6a22f2 > c2b0e2d8dc64e28cff1fd > --- /dev/null > +++ b/DynamicTablesPkg/DynamicTablesPkg.dec > @@ -0,0 +1,42 @@ > +## @file DynamicTablesPkg.dec > +# > +# Copyright (c) 2017, ARM Limited. All rights reserved.
> +# > +# This program and the accompanying materials are licensed and made > available under > +# the terms and conditions of the BSD License that accompanies this > distribution. > +# The full text of the license may be found at > +# http://opensource.org/licenses/bsd-license.php. > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +# > +## > + > +[Defines] > + DEC_SPECIFICATION =3D 0x00010005 > + PACKAGE_NAME =3D DynamicTablesPkg > + PACKAGE_GUID =3D 188EB346-8ABA-460E-A105-0F9D76F7324= A > + PACKAGE_VERSION =3D 1.0 > + > +[Includes] > + Include > + > +[Protocols] > + > + # Configuration Manager Protocol GUID > + gEfiConfigurationManagerProtocolGuid =3D { 0xd85a4835, 0x5a82, 0x4894, > { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } } > + > + # Dynamic Table Factory Protocol GUID > + gEfiDynamicTableFactoryProtocolGuid =3D { 0x91d1e327, 0xfe5a, 0x49b8, > { 0xab, 0x65, 0xe, 0xce, 0x2d, 0xdb, 0x45, 0xec } } > + > +[PcdsFixedAtBuild] > + > + # Maximum number of Custom ACPI Generators > + > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomACPIGenerators|1|UIN > T16|0xC0000001 > + > + # Maximum number of Custom SMBIOS Generators > + > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomSMBIOSGenerators|1| > UINT16|0xC0000002 > + > + # Maximum number of Custom DT Generators > + > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomDTGenerators|1|UINT1 > 6|0xC0000003 > + > diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h > b/DynamicTablesPkg/Include/AcpiTableGenerator.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..89fa713134857e2264 > 0b7a6f1f63a485048b7a72 > --- /dev/null > +++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h > @@ -0,0 +1,282 @@ > +/** @file > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > + - Std or STD - Standard > +**/ > + > +#ifndef ACPI_TABLE_GENERATOR_H_ > +#define ACPI_TABLE_GENERATOR_H_ > + > +#include > + > +// Module specific include files. > +#include > + > +#pragma pack(1) > + > +/** > +The Dynamic Tables Framework provisions two classes of ACPI table > +generators. > + - Standard generators: The ACPI table generators implemented by the > + Dynamic Tables Framework. > + - OEM generators: The ACPI table generators customized by the OEM. > + > +The Dynamic Tables Framework implements the following ACPI table > generators: > + - RAW : This is the simplest ACPI table generator. It simply install= s > + the ACPI table provided in the AcpiTableData member of the > + CM_STD_OBJ_ACPI_TABLE_INFO. The ACPI table data is provided > by > + the Configuration Manager and is generated using an > implementation > + defined mechanism. > + - DSDT : The DSDT generator is a clone of the RAW generator. The > difference > + is in the way the ACPI Table Data is generated from an AML f= ile. > + - SSDT : The SSDT generator is a clone of the RAW generator. The > difference > + is in the way the ACPI Table Data is generated from an AML f= ile. > + - FADT : The FADT generator collates the required platform informatio= n > from > + the Configuration Manager and builds the FADT table. > + - MADT : The MADT generator collates the GIC information from the > + Configuration Manager and builds the MADT table. > + - GTDT : The GTDT generator collates the Timer information from the > + Configuration Manager and builds the GTDT table. > + - DBG2 : The DBG2 generator collates the debug serial port informatio= n > from > + the Configuration Manager and builds the DBG2 table. > + - SPCR : The SPCR generator collates the serial port information from= the > + Configuration Manager and builds the SPCR table. > + - MCFG : The MCFG generator collates the PCI configuration space > information > + from the Configuration Manager and builds the MCFG table. > + - IORT : The IORT generator collates the IO Topology information from > the > + Configuration Manager and builds the IORT table. > +*/ > + > +/** The ACPI_TABLE_GENERATOR_ID type describes ACPI table generator > ID. > +*/ > +typedef TABLE_GENERATOR_ID ACPI_TABLE_GENERATOR_ID; > + > +/** The ESTD_ACPI_TABLE_ID enum describes the ACPI table IDs reserved > for > + the standard generators. > +*/ > +typedef enum StdAcpiTableId { > + ESTD_ACPI_TABLE_ID_RESERVED =3D 0x0000, ///< Reserved > + ESTD_ACPI_TABLE_ID_RAW, ///< RAW Generator > + ESTD_ACPI_TABLE_ID_DSDT =3D ESTD_ACPI_TABLE_ID_RAW, ///< DSDT > Generator > + ESTD_ACPI_TABLE_ID_SSDT =3D ESTD_ACPI_TABLE_ID_RAW, ///< SSDT > Generator > + ESTD_ACPI_TABLE_ID_FADT, ///< FADT Generator > + ESTD_ACPI_TABLE_ID_MADT, ///< MADT Generator > + ESTD_ACPI_TABLE_ID_GTDT, ///< GTDT Generator > + ESTD_ACPI_TABLE_ID_DBG2, ///< DBG2 Generator > + ESTD_ACPI_TABLE_ID_SPCR, ///< SPCR Generator > + ESTD_ACPI_TABLE_ID_MCFG, ///< MCFG Generator > + ESTD_ACPI_TABLE_ID_IORT, ///< IORT Generator > + ESTD_ACPI_TABLE_ID_MAX > +} ESTD_ACPI_TABLE_ID; > + > +/** This macro checks if the Table Generator ID is for an ACPI Table > Generator. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns TRUE if the table generator ID is for an ACPI Table > + Generator. > +*/ > +#define IS_GENERATOR_TYPE_ACPI(TableGeneratorId) \ > + (GET_TABLE_TYPE (TableGeneratorId) =3D=3D ETableGeneratorTypeA= cpi) > + > +/** This macro checks if the Table Generator ID is for a standard ACPI > + Table Generator. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns TRUE if the table generator ID is for a standard ACPI > + Table Generator. > +*/ > +#define IS_VALID_STD_ACPI_GENERATOR_ID(TableGeneratorId) \ > + ( \ > + IS_GENERATOR_NAMESPACE_STD (TableGeneratorId) && \ > + IS_GENERATOR_TYPE_ACPI (TableGeneratorId) && \ > + ((GET_TABLE_ID (GeneratorId) >=3D ESTD_ACPI_TABLE_ID_RAW) && = \ > + (GET_TABLE_ID (GeneratorId) < ESTD_ACPI_TABLE_ID_MAX)) \ > + ) > + > +/** This macro creates a standard ACPI Table Generator ID. > + > + @param [in] TableId The table generator ID. > + > + @returns a standard ACPI table generator ID. > +*/ > +#define CREATE_STD_ACPI_TABLE_GEN_ID(TableId) \ > + CREATE_TABLE_GEN_ID ( \ > + ETableGeneratorTypeAcpi, \ > + ETableGeneratorNameSpaceStd, \ > + TableId \ > + ) > + > +/** The Creator ID for the ACPI tables generated using > + the standard ACPI table generators. > +*/ > +#define TABLE_GENERATOR_CREATOR_ID_ARM SIGNATURE_32('A', 'R', > 'M', 'H') > + > +/** A macro to initialise the common header part of EFI ACPI tables as > + defined by the EFI_ACPI_DESCRIPTION_HEADER structure. > + > + @param [in] Signature The ACPI table signature. > + @param [in] Type The ACPI table structure. > + @param [in] Revision The ACPI table revision. > +*/ > +#define ACPI_HEADER(Signature, Type, Revision) { \ > + Signature, /* UINT32 Signature */ \ > + sizeof (Type), /* UINT32 Length */ \ > + Revision, /* UINT8 Revision */ \ > + 0, /* UINT8 Checksum */ \ > + { 0, 0, 0, 0, 0, 0 }, /* UINT8 OemId[6] */ \ > + 0, /* UINT64 OemTableId */ \ > + 0, /* UINT32 OemRevision */ \ > + 0, /* UINT32 CreatorId */ \ > + 0 /* UINT32 CreatorRevision */\ > + } > + > +/** A macro to dump the common header part of EFI ACPI tables as > + defined by the EFI_ACPI_DESCRIPTION_HEADER structure. > + > + @param [in] AcpiHeader The pointer to the ACPI table header. > +*/ > +#define DUMP_ACPI_TABLE_HEADER(AcpiHeader) \ > + DEBUG (( \ > + DEBUG_INFO, \ > + "ACPI TABLE %c%c%c%c : Rev 0x%x : Length : 0x%x\n", \ > + (AcpiHeader->Signature & 0xFF), \ > + ((AcpiHeader->Signature >> 8) & 0xFF), \ > + ((AcpiHeader->Signature >> 16) & 0xFF), \ > + ((AcpiHeader->Signature >> 24) & 0xFF), \ > + AcpiHeader->Revision, \ > + AcpiHeader->Length \ > + )); > + > +/** Forward declarations. > +*/ > +typedef struct ConfigurationManagerProtocol > EFI_CONFIGURATION_MANAGER_PROTOCOL; > +typedef struct CmAStdObjAcpiTableInfo > CM_STD_OBJ_ACPI_TABLE_INFO; > +typedef struct AcpiTableGenerator ACPI_TABLE_GENERATOR; > + > +/** This function pointer describes the interface to ACPI table build > + functions provided by the ACPI table generator and called by the > + Table Manager to build an ACPI table. > + > + @param [in] This Pointer to the ACPI table generator. > + @param [in] AcpiTableInfo Pointer to the ACPI table information. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol interface. > + @param [out] Table Pointer to the generated ACPI table. > + > + @returns EFI_SUCCESS If the table is generated successfully or other > + failure codes as returned by the generator. > +*/ > +typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLE) ( > + IN CONST ACPI_TABLE_GENERATOR * This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER ** Table > + ); > + > +/** This function pointer describes the interface used by the > + Table Manager to give the generator an opportunity to free > + any resources allocated for building the ACPI table. > + > + @param [in] This Pointer to the ACPI 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. > + > + @returns EFI_SUCCESS If freed successfully or other failure codes > + as returned by the generator. > +*/ > +typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_FREE_TABLE) ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST > AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ); > + > +/** The ACPI_TABLE_GENERATOR structure provides an interface that the > + Table Manager can use to invoke the functions to build ACPI tables. > +*/ > +typedef struct AcpiTableGenerator { > + /// The ACPI table generator ID. > + ACPI_TABLE_GENERATOR_ID GeneratorID; > + > + /// String describing the ACPI table generator. > + CONST CHAR16 * Description; > + > + /// The ACPI table signature. > + UINT32 AcpiTableSignature; > + > + /// The ACPI table revision. > + UINT32 AcpiTableRevision; > + > + /// The ACPI table creator ID. > + UINT32 CreatorId; > + > + /// The ACPI table creator revision. > + UINT32 CreatorRevision; > + > + /// ACPI table build function pointer. > + ACPI_TABLE_GENERATOR_BUILD_TABLE BuildAcpiTable; > + > + /** The function to free any resources > + allocated for building the ACPI table. > + */ > + ACPI_TABLE_GENERATOR_FREE_TABLE FreeTableResources; > +} ACPI_TABLE_GENERATOR; > + > +/** Register ACPI table factory generator. > + > + The ACPI table factory maintains a list of the Standard and OEM ACPI > + table generators. > + > + @param [in] Generator Pointer to the ACPI table generator. > + > + @retval EFI_SUCCESS The Generator was registered > + successfully. > + @retval EFI_INVALID_PARAMETER The Generator ID is invalid or > + the Generator pointer is NULL. > + @retval EFI_ALREADY_STARTED The Generator for the Table ID is > + already registered. > +*/ > +EFI_STATUS > +EFIAPI > +RegisterAcpiTableGenerator ( > + IN CONST ACPI_TABLE_GENERATOR * CONST Generator > + ); > + > +/** Deregister ACPI generator. > + > + This function is called by the ACPI table generator to deregister itse= lf > + from the ACPI table factory. > + > + @param [in] Generator Pointer to the ACPI table generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER The generator is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +DeregisterAcpiTableGenerator ( > + IN CONST ACPI_TABLE_GENERATOR * CONST Generator > + ); > + > +#pragma pack() > + > +#endif // ACPI_TABLE_GENERATOR_H_ > + > diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h > b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..abbd624eb026d14d22 > 80d766bf68633c60436829 > --- /dev/null > +++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h > @@ -0,0 +1,587 @@ > +/** @file > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > + - Std or STD - Standard > +**/ > + > +#ifndef ARM_NAMESPACE_OBJECTS_H_ > +#define ARM_NAMESPACE_OBJECTS_H_ > + > +#include > + > +#pragma pack(1) > + > +/** The EARM_OBJECT_ID enum describes the Object IDs > + in the ARM Namespace > +*/ > +typedef enum ArmObjectID { > + EArmObjReserved, ///< 0 - Reserved > + EArmObjBootArchInfo, ///< 1 - Boot Architecture Info > + EArmObjCpuInfo, ///< 2 - CPU Info > + EArmObjPowerManagementProfileInfo, ///< 3 - Power Management > Profile Info > + EArmObjGicCInfo, ///< 4 - GIC CPU Interface Info > + EArmObjGicDInfo, ///< 5 - GIC Distributor Info > + EArmObjGicMsiFrameInfo, ///< 6 - GIC MSI Frame Info > + EArmObjGicRedistributorInfo, ///< 7 - GIC Redistributor Info > + EArmObjGicItsInfo, ///< 8 - GIC ITS Info > + EArmObjSerialConsolePortInfo, ///< 9 - Serial Console Port Info > + EArmObjSerialDebugPortInfo, ///< 10 - Serial Debug Port Info > + EArmObjGenericTimerInfo, ///< 11 - Generic Timer Info > + EArmObjPlatformGTBlockInfo, ///< 12 - Platform GT Block Info > + EArmObjGTBlockTimerFrameInfo, ///< 13 - Generic Timer Block Fram= e > Info > + EArmObjPlatformGenericWatchdogInfo, ///< 14 - Platform Generic > Watchdog > + EArmObjPciConfigSpaceInfo, ///< 15 - PCI Configuration Space = Info > + EArmObjHypervisorVendorIdentity, ///< 16 - Hypervisor Vendor Id > + EArmObjFixedFeatureFlags, ///< 17 - Fixed feature flags for = FADT > + EArmObjItsGroup, ///< 18 - ITS Group > + EArmObjNamedComponent, ///< 19 - Named Component > + EArmObjRootComplex, ///< 20 - Root Complex > + EArmObjSmmuV1SmmuV2, ///< 21 - SMMUv1 or SMMUv2 > + EArmObjSmmuV3, ///< 22 - SMMUv3 > + EArmObjPmcg, ///< 23 - PMCG > + EArmObjGicItsIdentifierArray, ///< 24 - GIC ITS Identifier Array > + EArmObjIdMapping, ///< 25 - ID Mapping > + EArmObjSmmuInterruptArray, ///< 26 - SMMU Interrupt Array > + EArmObjMax > +} EARM_OBJECT_ID; > + > +/** A structure that describes the > + ARM Boot Architecture flags. > +*/ > +typedef struct CmArmBootArchInfo { > + /** This is the ARM_BOOT_ARCH flags field of the FADT Table > + described in the ACPI Table Specification. > + */ > + UINT32 BootArchFlags; > +} CM_ARM_BOOT_ARCH_INFO; > + > +typedef struct CmArmCpuInfo { > + // Reserved for use when SMBIOS tables are implemented > +} CM_ARM_CPU_INFO; > + > +typedef struct CmArmCpuInfoList { > + UINT32 CpuCount; > + CM_ARM_CPU_INFO * CpuInfo; > +} CM_ARM_CPU_INFO_LIST; > + > +/** A structure that describes the > + Power Management Profile Information for the Platform. > +*/ > +typedef struct CmArmPowerManagementProfileInfo { > + /** This is the Preferred_PM_Profile field of the FADT Table > + described in the ACPI Specification > + */ > + UINT8 PowerManagementProfile; > +} CM_ARM_POWER_MANAGEMENT_PROFILE_INFO; > + > +/** A structure that describes the > + GIC CPU Interface for the Platform. > +*/ > +typedef struct CmArmGicCInfo { > + /// The GIC CPU Interface number. > + UINT32 CPUInterfaceNumber; > + > + /** The ACPI Processor UID. This must match the > + _UID of the CPU Device object information described > + in the DSDT/SSDT for the CPU. > + */ > + UINT32 AcpiProcessorUid; > + > + /** The flags field as described by the GICC structure > + in the ACPI Specification. > + */ > + UINT32 Flags; > + > + /** The parking protocol version field as described by > + the GICC structure in the ACPI Specification. > + */ > + UINT32 ParkingProtocolVersion; > + > + /** The Performance Interrupt field as described by > + the GICC structure in the ACPI Specification. > + */ > + UINT32 PerformanceInterruptGsiv; > + > + /** The CPU Parked address field as described by > + the GICC structure in the ACPI Specification. > + */ > + UINT64 ParkedAddress; > + > + /** The base address for the GIC CPU Interface > + as described by the GICC structure in the > + ACPI Specification. > + */ > + UINT64 PhysicalBaseAddress; > + > + /** The base address for GICV interface > + as described by the GICC structure in the > + ACPI Specification. > + */ > + UINT64 GICV; > + > + /** The base address for GICH interface > + as described by the GICC structure in the > + ACPI Specification. > + */ > + UINT64 GICH; > + > + /** The GICV maintenance interrupt > + as described by the GICC structure in the > + ACPI Specification. > + */ > + UINT32 VGICMaintenanceInterrupt; > + > + /** The base address for GICR interface > + as described by the GICC structure in the > + ACPI Specification. > + */ > + UINT64 GICRBaseAddress; > + > + /** The MPIDR for the CPU > + as described by the GICC structure in the > + ACPI Specification. > + */ > + UINT64 MPIDR; > + > + /** The Processor Power Efficiency class > + as described by the GICC structure in the > + ACPI Specification. > + */ > + UINT8 ProcessorPowerEfficiencyClass; > +} CM_ARM_GICC_INFO; > + > +/** A structure that describes the > + GIC Distributor information for the Platform. > +*/ > +typedef struct CmArmGicDInfo { > + /// The GIC Distributor ID. > + UINT32 GicId; > + > + /// The Physical Base address for the GIC Distributor. > + UINT64 PhysicalBaseAddress; > + > + /** The global system interrupt > + number where this GIC Distributor's > + interrupt inputs start. > + */ > + UINT32 SystemVectorBase; > + > + /** The GIC version as described > + by the GICD structure in the > + ACPI Specification. > + */ > + UINT8 GicVersion; > +} CM_ARM_GICD_INFO; > + > +/** A structure that describes the > + GIC MSI Frame information for the Platform. > +*/ > +typedef struct CmArmGicMsiFrameInfo { > + /// The GIC MSI Frame ID > + UINT32 GicMsiFrameId; > + > + /// The Physical base address for the MSI Frame > + UINT64 PhysicalBaseAddress; > + > + /** The GIC MSI Frame flags > + as described by the GIC MSI frame > + structure in the ACPI Specification. > + */ > + UINT32 Flags; > + > + /// SPI Count used by this frame > + UINT16 SPICount; > + > + /// SPI Base used by this frame > + UINT16 SPIBase; > +} CM_ARM_GIC_MSI_FRAME_INFO; > + > +/** A structure that describes the > + GIC Redistributor information for the Platform. > +*/ > +typedef struct CmArmGicRedistInfo { > + /** The physical address of a page range > + containing all GIC Redistributors. > + */ > + UINT64 DiscoveryRangeBaseAddress; > + > + /// Length of the GIC Redistributor Discovery page range > + UINT32 DiscoveryRangeLength; > +} CM_ARM_GIC_REDIST_INFO; > + > +/** A structure that describes the > + GIC Interrupt Translation Service information for the Platform. > +*/ > +typedef struct CmArmGicItsInfo { > + /// The GIC ITS ID > + UINT32 GicItsId; > + > + /// The physical address for the Interrupt Translation Service > + UINT64 PhysicalBaseAddress; > +} CM_ARM_GIC_ITS_INFO; > + > +/** A structure that describes the > + Serial Port information for the Platform. > +*/ > +typedef struct CmArmSerialPortInfo { > + /// The physical base address for the serial port > + UINT64 BaseAddress; > + > + /// The serial port interrupt > + UINT32 Interrupt; > + > + /// The serial port baud rate > + UINT64 BaudRate; > + > + /// The serial port clock > + UINT32 Clock; > + > + /// Serial Port subtype > + UINT16 PortSubtype; > +} CM_ARM_SERIAL_PORT_INFO; > + > +/** A structure that describes the > + Generic Timer information for the Platform. > +*/ > +typedef struct CmArmGenericTimerInfo { > + /// The physical base address for the counter control frame > + UINT64 CounterControlBaseAddress; > + > + /// The physical base address for the counter read frame > + UINT64 CounterReadBaseAddress; > + > + /// The secure PL1 timer interrupt > + UINT32 SecurePL1TimerGSIV; > + > + /// The secure PL1 timer flags > + UINT32 SecurePL1TimerFlags; > + > + /// The non-secure PL1 timer interrupt > + UINT32 NonSecurePL1TimerGSIV; > + > + /// The non-secure PL1 timer flags > + UINT32 NonSecurePL1TimerFlags; > + > + /// The virtual timer interrupt > + UINT32 VirtualTimerGSIV; > + > + /// The virtual timer flags > + UINT32 VirtualTimerFlags; > + > + /// The non-secure PL2 timer interrupt > + UINT32 NonSecurePL2TimerGSIV; > + > + /// The non-secure PL2 timer flags > + UINT32 NonSecurePL2TimerFlags; > +} CM_ARM_GENERIC_TIMER_INFO; > + > +/** A structure that describes the > + Platform Generic Block Timer Frame information for the Platform. > +*/ > +typedef struct CmArmGTBlockTimerFrameInfo { > + /// The Generic Timer frame number > + UINT8 FrameNumber; > + > + /// The physical base address for the CntBase block > + UINT64 PhysicalAddressCntBase; > + > + /// The physical base address for the CntEL0Base block > + UINT64 PhysicalAddressCntEL0Base; > + > + /// The physical timer interrupt > + UINT32 PhysicalTimerGSIV; > + > + /** The physical timer flags as described by the GT Block > + Timer frame Structure in the ACPI Specification. > + */ > + UINT32 PhysicalTimerFlags; > + > + /// The virtual timer interrupt > + UINT32 VirtualTimerGSIV; > + > + /** The virtual timer flags as described by the GT Block > + Timer frame Structure in the ACPI Specification. > + */ > + UINT32 VirtualTimerFlags; > + > + /** The common timer flags as described by the GT Block > + Timer frame Structure in the ACPI Specification. > + */ > + UINT32 CommonFlags; > +} CM_ARM_GTBLOCK_TIMER_FRAME_INFO; > + > +/** A structure that describes the > + Platform Generic Block Timer information for the Platform. > +*/ > +typedef struct CmArmGTBlockInfo { > + /// The physical base address for the GT Block Timer structure > + UINT64 GTBlockPhysicalAddress; > + > + /// The number of timer frames implemented in the GT Block > + UINT32 GTBlockTimerFrameCount; > + > + /// Reference token for the GT Block timer frame list > + CM_OBJECT_TOKEN GTBlockTimerFrameToken; > +} CM_ARM_GTBLOCK_INFO; > + > +/** A structure that describes the > + SBSA Generic Watchdog information for the Platform. > +*/ > +typedef struct CmArmGenericWatchdogInfo { > + /// The physical base address of the SBSA Watchdog control frame > + UINT64 ControlFrameAddress; > + > + /// The physical base address of the SBSA Watchdog refresh frame > + UINT64 RefreshFrameAddress; > + > + /// The watchdog interrupt > + UINT32 TimerGSIV; > + > + /** The flags for the watchdog as described by the SBSA watchdog > + structure in the ACPI specification. > + */ > + UINT32 Flags; > +} CM_ARM_GENERIC_WATCHDOG_INFO; > + > +/** A structure that describes the > + PCI Configuration Space information for the Platform. > +*/ > +typedef struct CmArmPciConfigSpaceInfo { > + /// The physical base address for the PCI segment > + UINT64 BaseAddress; > + > + /// The PCI segment group number > + UINT16 PciSegmentGroupNumber; > + > + /// The start bus number > + UINT8 StartBusNumber; > + > + /// The end bus number > + UINT8 EndBusNumber; > +} CM_ARM_PCI_CONFIG_SPACE_INFO; > + > +/** A structure that describes the > + Hypervisor Vendor ID information for the Platform. > +*/ > +typedef struct CmArmHypervisorVendorId { > + /// The hypervisor Vendor ID > + UINT64 HypervisorVendorId; > +} CM_ARM_HYPERVISOR_VENDOR_ID; > + > +/** A structure that describes the > + Fixed feature flags for the Platform. > +*/ > +typedef struct CmArmFixedFeatureFlags { > + /// The Fixed feature flags > + UINT32 Flags; > +} CM_ARM_FIXED_FEATURE_FLAGS; > + > +/** A structure that describes the > + ITS Group node for the Platform. > +*/ > +typedef struct CmArmItsGroupNode { > + /// An unique token used to ideintify this object > + CM_OBJECT_TOKEN Token; > + /// The number of ITS identifiers in the ITS node > + UINT32 ItsIdCount; > + /// Reference token for the ITS identifier array > + CM_OBJECT_TOKEN ItsIdToken; > +} CM_ARM_ITS_GROUP_NODE; > + > +/** A structure that describes the > + GIC ITS Identifiers for an ITS Group node. > +*/ > +typedef struct CmArmGicItsIdentifier { > + /// The ITS Identifier > + UINT32 ItsId; > +} CM_ARM_ITS_IDENTIFIER; > + > +/** A structure that describes the > + Named component node for the Platform. > +*/ > +typedef struct CmArmNamedComponentNode { > + /// An unique token used to ideintify this object > + CM_OBJECT_TOKEN Token; > + /// Number of ID mappings > + UINT32 IdMappingCount; > + /// Reference token for the ID mapping array > + CM_OBJECT_TOKEN IdMappingToken; > + > + /// Flags for the named component > + UINT32 Flags; > + > + /// Memory access properties : Cache coherent attributes > + UINT32 CacheCoherent; > + /// Memory access properties : Allocation hints > + UINT8 AllocationHints; > + /// Memory access properties : Memory access flags > + UINT8 MemoryAccessFlags; > + > + /// Memory access properties : Address size limit > + UINT8 AddressSizeLimit; > + /** ASCII Null terminated string with the full path to > + the entry in the namespace for this object. > + */ > + CHAR8* ObjectName; > +} CM_ARM_NAMED_COMPONENT_NODE; > + > +/** A structure that describes the > + Root complex node for the Platform. > +*/ > +typedef struct CmArmRootComplexNode { > + /// An unique token used to ideintify this object > + CM_OBJECT_TOKEN Token; > + /// Number of ID mappings > + UINT32 IdMappingCount; > + /// Reference token for the ID mapping array > + CM_OBJECT_TOKEN IdMappingToken; > + > + /// Memory access properties : Cache coherent attributes > + UINT32 CacheCoherent; > + /// Memory access properties : Allocation hints > + UINT8 AllocationHints; > + /// Memory access properties : Memory access flags > + UINT8 MemoryAccessFlags; > + > + /// ATS attributes > + UINT32 AtsAttribute; > + /// PCI segment number > + UINT32 PciSegmentNumber; > +} CM_ARM_ROOT_COMPLEX_NODE; > + > +/** A structure that describes the > + SMMUv1 or SMMUv2 node for the Platform. > +*/ > +typedef struct CmArmSmmuV1SmmuV2Node { > + /// An unique token used to ideintify this object > + CM_OBJECT_TOKEN Token; > + /// Number of ID mappings > + UINT32 IdMappingCount; > + /// Reference token for the ID mapping array > + CM_OBJECT_TOKEN IdMappingToken; > + > + /// SMMU Base Address > + UINT64 BaseAddress; > + /// Length of the memory range covered by the SMMU > + UINT64 Span; > + /// SMMU Model > + UINT32 Model; > + /// SMMU flags > + UINT32 Flags; > + > + /// Number of context interrupts > + UINT32 ContextInterruptCount; > + /// Reference token for the context interrupt array > + CM_OBJECT_TOKEN ContextInterruptToken; > + > + /// Number of PMU interrupts > + UINT32 PmuInterruptCount; > + /// Reference token for the PMU interrupt array > + CM_OBJECT_TOKEN PmuInterruptToken; > + > + /// GSIV of the SMMU_NSgIrpt interrupt > + UINT32 SMMU_NSgIrpt; > + /// SMMU_NSgIrpt interrupt flags > + UINT32 SMMU_NSgIrptFlags; > + /// GSIV of the SMMU_NSgCfgIrpt interrupt > + UINT32 SMMU_NSgCfgIrpt; > + /// SMMU_NSgCfgIrpt interrupt flags > + UINT32 SMMU_NSgCfgIrptFlags; > +} CM_ARM_SMMUV1_SMMUV2_NODE; > + > +/** A structure that describes the > + SMMUv3 node for the Platform. > +*/ > +typedef struct CmArmSmmuV3Node { > + /// An unique token used to ideintify this object > + CM_OBJECT_TOKEN Token; > + /// Number of ID mappings > + UINT32 IdMappingCount; > + /// Reference token for the ID mapping array > + CM_OBJECT_TOKEN IdMappingToken; > + > + /// SMMU Base Address > + UINT64 BaseAddress; > + /// SMMU flags > + UINT32 Flags; > + /// VATOS address > + UINT64 VatosAddress; > + /// Model > + UINT32 Model; > + /// GSIV of the Event interrupt if SPI based > + UINT32 EventInterrupt; > + /// PRI Interrupt if SPI based > + UINT32 PriInterrupt; > + /// GERR interrupt if GSIV based > + UINT32 GerrInterrupt; > + /// Sync interrupt if GSIV based > + UINT32 SyncInterrupt; > + > + /// Proximity domain flag > + UINT8 ProximityDomain; > + /// Index into the array of ID mapping > + UINT32 DeviceIdMappingIndex; > +} CM_ARM_SMMUV3_NODE; > + > +/** A structure that describes the > + PMCG node for the Platform. > +*/ > +typedef struct CmArmPmcgNode { > + /// An unique token used to ideintify this object > + CM_OBJECT_TOKEN Token; > + /// Number of ID mappings > + UINT32 IdMappingCount; > + /// Reference token for the ID mapping array > + CM_OBJECT_TOKEN IdMappingToken; > + > + /// Base Address for performance monitor counter group > + UINT64 BaseAddress; > + /// GSIV for the Overflow interrupt > + UINT32 OverflowInterrupt; > + > + /// Reference token for the IORT node associated with this node > + CM_OBJECT_TOKEN ReferenceToken; > +} CM_ARM_PMCG_NODE; > + > +/** A structure that describes the > + ID Mappings for the Platform. > +*/ > +typedef struct CmArmIdMapping { > + /// Input base > + UINT32 InputBase; > + /// Number of input IDs > + UINT32 NumIds; > + /// Output Base > + UINT32 OutputBase; > + /// Reference token for the output node > + CM_OBJECT_TOKEN OutputReferenceToken; > + /// Flags > + UINT32 Flags; > +} CM_ARM_ID_MAPPING; > + > +/** A structure that describes the > + SMMU interrupts for the Platform. > +*/ > +typedef struct CmArmSmmuInterrupt { > + /// Interrupt number > + UINT32 Interrupt; > + > + /// Flags > + UINT32 Flags; > +} CM_ARM_SMMU_INTERRUPT; > + > +#pragma pack() > + > +#endif // ARM_NAMESPACE_OBJECTS_H_ > diff --git a/DynamicTablesPkg/Include/ConfigurationManagerHelper.h > b/DynamicTablesPkg/Include/ConfigurationManagerHelper.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..7f39e2167166e1ea0e > 895a535d85ddaf231bf394 > --- /dev/null > +++ b/DynamicTablesPkg/Include/ConfigurationManagerHelper.h > @@ -0,0 +1,119 @@ > +/** @file > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > +**/ > + > +#ifndef CONFIGURATION_MANAGER_HELPER_H_ > +#define CONFIGURATION_MANAGER_HELPER_H_ > + > +/** The GET_OBJECT_LIST macro expands to a function that is used to > retrieve > + an object or an object list from the Configuration Manager using the > + Configuration Manager Protocol interface. > + > + The macro expands to a function which has the following prototype: > + > + STATIC > + EFI_STATUS > + EFIAPI > + Get ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, > + OUT Type ** List, > + OUT UINT32 * Count OPTIONAL > + ); > + > + Generated function parameters: > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > protocol > + interface. > + @param [in] Token Reference token for the Object. > + @param [out] List Pointer to the Object list. > + @param [out] Count Count of the objects returned in the list. > + > + Macro Parameters: > + @param [in] CmObjectNameSpace The Object Namespace > + @param [in] CmObjectId Object Id. > + @param [in] Type Structure used to describe the Object. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object information is not > found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +#define GET_OBJECT_LIST(CmObjectNameSpace, CmObjectId, Type) > \ > +STATIC = \ > +EFI_STATUS = \ > +EFIAPI = \ > +Get##CmObjectId ( = \ > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, \ > + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, = \ > + OUT Type ** List, = \ > + OUT UINT32 * CONST Count OPTIONAL = \ > + ) = \ > +{ = \ > + EFI_STATUS Status; = \ > + CM_OBJ_DESCRIPTOR CmObjectDesc; = \ > + UINT32 ObjCount =3D 0; = \ > + if (List =3D=3D NULL) { = \ > + Status =3D EFI_INVALID_PARAMETER; = \ > + DEBUG (( = \ > + DEBUG_ERROR, = \ > + "ERROR: Get" #CmObjectId ": Invalid out parameter for" = \ > + " object list. Status =3D %r\n", = \ > + Status = \ > + )); = \ > + goto error_handler; = \ > + } = \ > + Status =3D CfgMgrProtocol->GetObject ( = \ > + CfgMgrProtocol, = \ > + CREATE_CM_OBJECT_ID ( = \ > + CmObjectNameSpace, = \ > + CmObjectId = \ > + ), = \ > + Token, = \ > + &CmObjectDesc = \ > + ); = \ > + if (EFI_ERROR (Status)) { = \ > + DEBUG (( = \ > + DEBUG_INFO, = \ > + "INFO: Get" #CmObjectId ": Platform does not implement " = \ > + #CmObjectId ". Status =3D %r\n", = \ > + Status = \ > + )); = \ > + *List =3D NULL; = \ > + goto error_handler; = \ > + } = \ > + if (CmObjectDesc.Size < sizeof (Type)) { = \ > + DEBUG (( = \ > + DEBUG_ERROR, = \ > + "ERROR: Get" #CmObjectId ": " #CmObjectId = \ > + ": Buffer too small, size =3D 0x%x\n", = \ > + CmObjectDesc.Size = \ > + )); = \ > + ASSERT (CmObjectDesc.Size >=3D sizeof (Type)); = \ > + Status =3D EFI_BAD_BUFFER_SIZE; = \ > + goto error_handler; = \ > + } = \ > + ObjCount =3D CmObjectDesc.Size / sizeof (Type); = \ > + *List =3D (Type*)CmObjectDesc.Data; = \ > +error_handler: = \ > + if (Count !=3D NULL) { = \ > + *Count =3D ObjCount; = \ > + } = \ > + return Status; = \ > +} > + > +#endif // CONFIGURATION_MANAGER_HELPER_H_ > diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h > b/DynamicTablesPkg/Include/ConfigurationManagerObject.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..98329133a67f6ba477 > 1ceb98c8cd30d1f470bd19 > --- /dev/null > +++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h > @@ -0,0 +1,176 @@ > +/** @file > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > +**/ > + > +#ifndef CONFIGURATION_MANAGER_OBJECT_H_ > +#define CONFIGURATION_MANAGER_OBJECT_H_ > + > +#include > +#include > + > +#pragma pack(1) > + > +/** The CM_OBJECT_ID type is used to identify the Configuration Manager > + objects. > + > + Description of Configuration Manager Object ID > +_________________________________________________________ > ______________________ > +|31 |30 |29 |28 || 27 | 26 | 25 | 24 || 23 | 22 | 21 | 20 || 19 | 18 | 1= 7 > | 16| > +------------------------------------------------------------------------= ------- > +| Name Space ID || 0 | 0 | 0 | 0 || 0 | 0 | 0 | 0 || 0 | 0 | = 0 | 0| > +_________________________________________________________ > ______________________ > + > +Bits: [31:28] - Name Space ID > + 0000 - Standard > + 0001 - ARM > + 1000 - Custom/OEM > + All other values are reserved. > + > +Bits: [27:16] - Reserved. > +_________________________________________________________ > ______________________ > +|15 |14 |13 |12 || 11 | 10 | 9 | 8 || 7 | 6 | 5 | 4 || 3 | 2 | = 1 | 0| > +------------------------------------------------------------------------= ------- > +| 0 | 0 | 0 | 0 || 0 | 0 | 0 | 0 || Object ID = | > +_________________________________________________________ > ______________________ > + > +Bits: [15:8] - Are reserved and must be zero. > + > +Bits: [7:0] - Object ID > + > +Object ID's in the Standard Namespace: > + 0 - Configuration Manager Revision > + 1 - ACPI Table List > + 2 - SMBIOS Table List > + > +Object ID's in the ARM Namespace: > + 0 - Reserved > + 1 - Boot Architecture Info > + 2 - CPU Info > + 3 - Power Management Profile Info > + 4 - GICC Info > + 5 - GICD Info > + 6 - GIC MSI Frame Info > + 7 - GIC Redistributor Info > + 8 - GIC ITS Info > + 9 - Serial Console Port Info > + 10 - Serial Debug Port Info > + 11 - Generic Timer Info > + 12 - Platform GT Block Info > + 13 - Platform Generic Watchdog > + 14 - PCI Configuration Space Info > + 15 - Hypervisor Vendor Id > + 16 - Fixed feature flags for FADT > +*/ > +typedef UINT32 CM_OBJECT_ID; > + > +/** A mask for Object ID > +*/ > +#define OBJECT_ID_MASK 0xFF > + > +/** A mask for Namespace ID > +*/ > +#define NAMESPACE_ID_MASK 0xF > + > +/** Starting bit position for Namespace ID > +*/ > +#define NAMESPACE_ID_BIT_SHIFT 28 > + > +/** The EOBJECT_NAMESPACE_ID enum describes the defined > namespaces > + for the Configuration Manager Objects. > +*/ > +typedef enum ObjectNameSpaceID { > + EObjNameSpaceStandard, ///< Standard Objects Namespace > + EObjNameSpaceArm, ///< ARM Objects Namespace > + EObjNameSpaceOem =3D 0x8, ///< OEM Objects Namespace > + EObjNameSpaceMax > +} EOBJECT_NAMESPACE_ID; > + > +/** A descriptor for Configuration Manager Objects. > + > + The Configuration Manager Protocol interface uses this descriptor > + to return the Configuration Manager Objects. > +*/ > +typedef struct CmObjDescriptor { > + /// sizeof the described Object or Object List. > + UINT32 Size; > + > + /// Pointer to the described Object or Object List. > + VOID * Data; > +} CM_OBJ_DESCRIPTOR; > + > +#pragma pack() > + > +/** This macro returns the namespace ID from the CmObjectID. > + > + @param [in] CmObjectId The Configuration Manager Object ID. > + > + @retval Returns the Namespace ID corresponding to the CmObjectID. > +*/ > +#define GET_CM_NAMESPACE_ID(CmObjectId) \ > + (((CmObjectId) >> NAMESPACE_ID_BIT_SHIFT) & \ > + NAMESPACE_ID_MASK) > + > +/** This macro returns the Object ID from the CmObjectID. > + > + @param [in] CmObjectId The Configuration Manager Object ID. > + > + @retval Returns the Object ID corresponding to the CmObjectID. > +*/ > +#define GET_CM_OBJECT_ID(CmObjectId) ((CmObjectId) & > OBJECT_ID_MASK) > + > +/** This macro returns a Configuration Manager Object ID > + from the NameSpace ID and the ObjectID. > + > + @param [in] NameSpaceId The namespace ID for the Object. > + @param [in] ObjectId The Object ID. > + > + @retval Returns the Configuration Manager Object ID. > +*/ > +#define CREATE_CM_OBJECT_ID(NameSpaceId, ObjectId) = \ > + ((((NameSpaceId) & NAMESPACE_ID_MASK) << > NAMESPACE_ID_BIT_SHIFT) | \ > + ((ObjectId) & OBJECT_ID_MASK)) > + > +/** This macro returns a Configuration Manager Object ID > + in the Standard Object Namespace. > + > + @param [in] ObjectId The Object ID. > + > + @retval Returns a Standard Configuration Manager Object ID. > +*/ > +#define CREATE_CM_STD_OBJECT_ID(ObjectId) \ > + (CREATE_CM_OBJECT_ID (EObjNameSpaceStandard, ObjectId)) > + > +/** This macro returns a Configuration Manager Object ID > + in the ARM Object Namespace. > + > + @param [in] ObjectId The Object ID. > + > + @retval Returns an ARM Configuration Manager Object ID. > +*/ > +#define CREATE_CM_ARM_OBJECT_ID(ObjectId) \ > + (CREATE_CM_OBJECT_ID (EObjNameSpaceArm, ObjectId)) > + > +/** This macro returns a Configuration Manager Object ID > + in the OEM Object Namespace. > + > + @param [in] ObjectId The Object ID. > + > + @retval Returns an OEM Configuration Manager Object ID. > +*/ > +#define CREATE_CM_OEM_OBJECT_ID(ObjectId) \ > + (CREATE_CM_OBJECT_ID (EObjNameSpaceOem, ObjectId)) > + > +#endif // CONFIGURATION_MANAGER_OBJECT_H_ > diff --git a/DynamicTablesPkg/Include/DeviceTreeTableGenerator.h > b/DynamicTablesPkg/Include/DeviceTreeTableGenerator.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..767a62d383e6d530e5 > 51b69a0a7146359f6fd093 > --- /dev/null > +++ b/DynamicTablesPkg/Include/DeviceTreeTableGenerator.h > @@ -0,0 +1,182 @@ > +/** @file > + > + Copyright (c) 2017, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > + - Std or STD - Standard > +**/ > + > +#ifndef DEVICETREE_TABLE_GENERATOR_H_ > +#define DEVICETREE_TABLE_GENERATOR_H_ > + > +#include > + > +#pragma pack(1) > + > +/** The DT_TABLE_GENERATOR_ID type describes Device Tree table > generator ID. > +*/ > +typedef TABLE_GENERATOR_ID DT_TABLE_GENERATOR_ID; > + > +/** The ESTD_DT_TABLE_ID enum describes the DT table IDs reserved for > + the standard generators. > +*/ > +typedef enum StdDtTableId { > + ESTD_DT_TABLE_ID_RESERVED =3D 0x0000, ///< Reserved. > + ESTD_DT_TABLE_ID_RAW, ///< RAW Generator. > + ESTD_DT_TABLE_ID_MAX > +} ESTD_DT_TABLE_ID; > + > +/** This macro checks if the Table Generator ID is for an DT Table > Generator. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns TRUE if the table generator ID is for an DT Table > + Generator. > +*/ > +#define IS_GENERATOR_TYPE_DT(TableGeneratorId) \ > + (GET_TABLE_TYPE(TableGeneratorId) =3D=3D ETableGeneratorTypeDt= ) > + > +/** This macro checks if the Table Generator ID is for a standard DT > + Table Generator. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns TRUE if the table generator ID is for a standard DT > + Table Generator. > +*/ > +#define IS_VALID_STD_DT_GENERATOR_ID(TableGeneratorId) \ > + ( \ > + IS_GENERATOR_NAMESPACE_STD(TableGeneratorId) && \ > + IS_GENERATOR_TYPE_DT(TableGeneratorId) && \ > + ((GET_TABLE_ID(GeneratorId) >=3D ESTD_DT_TABLE_ID_RAW) && \ > + (GET_TABLE_ID(GeneratorId) < ESTD_DT_TABLE_ID_MAX)) \ > + ) > + > +/** This macro creates a standard DT Table Generator ID. > + > + @param [in] TableId The table generator ID. > + > + @returns a standard DT table generator ID. > +*/ > +#define CREATE_STD_DT_TABLE_GEN_ID(TableId) \ > + CREATE_TABLE_GEN_ID ( \ > + ETableGeneratorTypeDt, \ > + ETableGeneratorNameSpaceStd, \ > + TableId \ > + ) > + > +/** Forward declarations. > +*/ > +typedef struct ConfigurationManagerProtocol > EFI_CONFIGURATION_MANAGER_PROTOCOL; > +typedef struct CmAStdObjDtTableInfo CM_STD_OBJ_DT_TABLE_INFO; > +typedef struct DtTableGenerator DT_TABLE_GENERATOR; > + > +/** This function pointer describes the interface to DT table build > + functions provided by the DT table generator and called by the > + Table Manager to build an DT table. > + > + @param [in] Generator Pointer to the DT table generator. > + @param [in] DtTableInfo Pointer to the DT table information. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol interface. > + @param [out] Table Pointer to the generated DT table. > + > + @returns EFI_SUCCESS If the table is generated successfully or other > + failure codes as returned by the generator. > +*/ > +typedef EFI_STATUS (*DT_TABLE_GENERATOR_BUILD_TABLE) ( > + IN CONST DT_TABLE_GENERATOR * Generator, > + IN CONST CM_STD_OBJ_DT_TABLE_INFO * CONST DtTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT VOID ** Table > + ); > + > +/** This function pointer describes the interface to used by the > + Table Manager to give the generator an opportunity to free > + any resources allocated for building the DT table. > + > + @param [in] Generator Pointer to the DT table generator. > + @param [in] DtTableInfo Pointer to the DT table information. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol interface. > + @param [in] Table Pointer to the generated DT table. > + > + @returns EFI_SUCCESS If freed successfully or other failure codes > + as returned by the generator. > +*/ > +typedef EFI_STATUS (*DT_TABLE_GENERATOR_FREE_TABLE) ( > + IN CONST DT_TABLE_GENERATOR * Generator, > + IN CONST CM_STD_OBJ_DT_TABLE_INFO * CONST DtTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN VOID ** Table > + ); > + > +/** The DT_TABLE_GENERATOR structure provides an interface that the > + Table Manager can use to invoke the functions to build DT tables. > +*/ > +typedef struct DtTableGenerator { > + /// The DT table generator ID. > + DT_TABLE_GENERATOR_ID GeneratorID; > + > + /// String describing the DT table generator. > + CONST CHAR16 * Description; > + > + /// DT table build function pointer. > + DT_TABLE_GENERATOR_BUILD_TABLE BuildDtTable; > + > + /// The function to free any resources allocated for building the DT t= able. > + DT_TABLE_GENERATOR_FREE_TABLE FreeTableResources; > +} DT_TABLE_GENERATOR; > + > +/** Register DT table factory generator. > + > + The DT table factory maintains a list of the Standard and OEM DT > + table generators. > + > + @param [in] Generator Pointer to the DT table generator. > + > + @retval EFI_SUCCESS The Generator was registered > + successfully. > + @retval EFI_INVALID_PARAMETER The Generator ID is invalid or > + the Generator pointer is NULL. > + @retval EFI_ALREADY_STARTED The Generator for the Table ID is > + already registered. > +*/ > +EFI_STATUS > +EFIAPI > +RegisterDtTableGenerator ( > + IN CONST DT_TABLE_GENERATOR * CONST Generator > + ); > + > +/** Deregister DT generator. > + > + This function is called by the DT table generator to deregister itself > + from the DT table factory. > + > + @param [in] Generator Pointer to the DT table generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER The generator is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +DeregisterDtTableGenerator ( > + IN CONST DT_TABLE_GENERATOR * CONST Generator > + ); > + > +#pragma pack() > + > +#endif // DEVICETREE_TABLE_GENERATOR_H_ > + > diff --git a/DynamicTablesPkg/Include/Library/TableHelperLib.h > b/DynamicTablesPkg/Include/Library/TableHelperLib.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..71efd2e7b94d072feeb > a39921e19a2460641e1d1 > --- /dev/null > +++ b/DynamicTablesPkg/Include/Library/TableHelperLib.h > @@ -0,0 +1,70 @@ > +/** @file > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#ifndef TABLE_HELPER_LIB_H_ > +#define TABLE_HELPER_LIB_H_ > + > +/** A helper macro to align a value to the 32-bit word boundary > +*/ > +#define ALIGN32(x) ((x) + (sizeof (UINT32) - 1)) & ~(sizeof (UINT32) - 1= ) > + > +/** The GetCgfMgrInfo function gets the > CM_STD_OBJ_CONFIGURATION_MANAGER_INFO > + object from the Configuration Manager. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > protocol > + interface. > + @param [out] CfgMfrInfo Pointer to the Configuration Manager Info > + object structure. > + > + @retval EFI_SUCCESS The object is returned. > + @retval EFI_INVALID_PARAMETER The Object ID is invalid. > + @retval EFI_NOT_FOUND The requested Object is not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size. > +*/ > +EFI_STATUS > +EFIAPI > +GetCgfMgrInfo ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT CM_STD_OBJ_CONFIGURATION_MANAGER_INFO ** > CfgMfrInfo > + ); > + > +/** The AddAcpiHeader function updates the ACPI header structure. It > uses the > + ACPI table Generator and the Configuration Manager protocol to obtai= n > the > + information required for constructing the header. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + protocol interface. > + @param [in] Generator Pointer to the ACPI table Generator. > + @param [in,out] AcpiHeader Pointer to the ACPI table header to be > + updated. > + @param [in] Length Length of the ACPI table. > + > + @retval EFI_SUCCESS The ACPI table is updated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object information is not > found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +EFI_STATUS > +EFIAPI > +AddAcpiHeader ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN CONST ACPI_TABLE_GENERATOR * CONST Generator, > + IN OUT EFI_ACPI_DESCRIPTION_HEADER * CONST AcpiHeader, > + IN CONST UINT32 Length > + ); > + > +#endif // TABLE_HELPER_LIB_H_ > diff --git > a/DynamicTablesPkg/Include/Protocol/ConfigurationManagerProtocol.h > b/DynamicTablesPkg/Include/Protocol/ConfigurationManagerProtocol.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..15ca0a22aac5129e5b > 291f1385f058113e186070 > --- /dev/null > +++ > b/DynamicTablesPkg/Include/Protocol/ConfigurationManagerProtocol.h > @@ -0,0 +1,128 @@ > +/** @file > + > + Copyright (c) 2017, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > +**/ > + > +#ifndef CONFIGURATION_MANAGER_PROTOCOL_H_ > +#define CONFIGURATION_MANAGER_PROTOCOL_H_ > + > +#include > + > +/** This macro defines the Configuration Manager Protocol GUID. > + > + GUID: {D85A4835-5A82-4894-AC02-706F43D5978E} > +*/ > +#define EFI_CONFIGURATION_MANAGER_PROTOCOL_GUID \ > + { 0xd85a4835, 0x5a82, 0x4894, \ > + { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } \ > + }; > + > +/** This macro defines the Configuration Manager Protocol Revision. > +*/ > +#define EFI_CONFIGURATION_MANAGER_PROTOCOL_REVISION > CREATE_REVISION (1, 0) > + > +#pragma pack(1) > + > +/** > + Forward declarations: > +*/ > +typedef struct ConfigurationManagerProtocol > EFI_CONFIGURATION_MANAGER_PROTOCOL; > +typedef struct PlatformRepositoryInfo > EFI_PLATFORM_REPOSITORY_INFO; > + > +/** The GetObject function defines the interface implemented by the > + Configuration Manager Protocol for returning the Configuration > + Manager Objects. > + > + @param [in] This Pointer to the Configuration Manager Protocol= . > + @param [in] CmObjectId The Configuration Manager Object ID. > + @param [in] Token An optional token identifying the object. If > + unused this must be CM_NULL_TOKEN. > + @param [out] CmObject Pointer to the Configuration Manager Object > + descriptor describing the requested Object. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object information is not > found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > Manager > + is less than the Object size for the req= uested > + object. > +*/ > +typedef > +EFI_STATUS > +(EFIAPI * EFI_CONFIGURATION_MANAGER_GET_OBJECT) ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST This, > + IN CONST CM_OBJECT_ID CmObjectId, > + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, > + IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject > + ); > + > +/** The SetObject function defines the interface implemented by the > + Configuration Manager Protocol for updating the Configuration > + Manager Objects. > + > + @param [in] This Pointer to the Configuration Manager Protocol= . > + @param [in] CmObjectId The Configuration Manager Object ID. > + @param [in] Token An optional token identifying the object. If > + unused this must be CM_NULL_TOKEN. > + @param [out] CmObject Pointer to the Configuration Manager Object > + descriptor describing the Object. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object information is not > found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > Manager > + is less than the Object size for the req= uested > + object. > + @retval EFI_UNSUPPORTED This operation is not supported. > +*/ > +typedef > +EFI_STATUS > +(EFIAPI * EFI_CONFIGURATION_MANAGER_SET_OBJECT) ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST This, > + IN CONST CM_OBJECT_ID CmObjectId, > + IN CONST CM_OBJECT_TOKEN Token OPTIONAL, > + IN CM_OBJ_DESCRIPTOR * CONST CmObject > + ); > + > +/** The EFI_CONFIGURATION_MANAGER_PROTOCOL structure describes > the > + Configuration Manager Protocol interface. > +*/ > +typedef struct ConfigurationManagerProtocol { > + /// The Configuration Manager Protocol revision. > + UINT32 Revision; > + > + /** The interface used to request information about > + the Configuration Manager Objects. > + */ > + EFI_CONFIGURATION_MANAGER_GET_OBJECT GetObject; > + > + /** The interface used to update the information stored > + in the Configuration Manager repository. > + */ > + EFI_CONFIGURATION_MANAGER_SET_OBJECT SetObject; > + > + /** Pointer to an implementation defined abstract repository > + provisioned by the Configuration Manager. > + */ > + EFI_PLATFORM_REPOSITORY_INFO * PlatRepoInfo; > +} EFI_CONFIGURATION_MANAGER_PROTOCOL; > + > +/** The Configuration Manager Protocol GUID. > +*/ > +extern EFI_GUID gEfiConfigurationManagerProtocolGuid; > + > +#pragma pack() > + > +#endif // CONFIGURATION_MANAGER_PROTOCOL_H_ > diff --git > a/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h > b/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..8688d0a40900c9dcd9 > 0c76bfb38911ccd6b4add6 > --- /dev/null > +++ b/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h > @@ -0,0 +1,140 @@ > +/** @file > + > + Copyright (c) 2017, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - ACPI - Advanced Configuration and Power Interface > + - SMBIOS - System Management BIOS > + - DT - Device Tree > +**/ > + > +#ifndef DYNAMIC_TABLE_FACTORY_PROTOCOL_H_ > +#define DYNAMIC_TABLE_FACTORY_PROTOCOL_H_ > + > +#include > +#include > +#include > + > +/** This macro defines the Dynamic Table Factory Protocol GUID. > + > + GUID: {91D1E327-FE5A-49B8-AB65-0ECE2DDB45EC} > +*/ > +#define EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL_GUID \ > + { 0x91d1e327, 0xfe5a, 0x49b8, \ > + { 0xab, 0x65, 0xe, 0xce, 0x2d, 0xdb, 0x45, 0xec } \ > + }; > + > +/** This macro defines the Configuration Manager Protocol Revision. > +*/ > +#define EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL_REVISION > CREATE_REVISION (1, 0) > + > +#pragma pack(1) > + > +/** > + Forward declarations: > +*/ > +typedef struct DynamicTableFactoryProtocol > EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL; > +typedef struct DynamicTableFactoryInfo > EFI_DYNAMIC_TABLE_FACTORY_INFO; > + > +/** Return a pointer to the ACPI table generator. > + > + @param [in] This Pointer to the Dynamic Table Factory Protocol. > + @param [in] TableId The ACPI table generator ID for the > + requested generator. > + @param [out] Generator Pointer to the requested ACPI table > + generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +typedef > +EFI_STATUS > +EFIAPI > +(EFIAPI * EFI_DYNAMIC_TABLE_FACTORY_GET_ACPI_TABLE_GENERATOR) ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This, > + IN CONST ACPI_TABLE_GENERATOR_ID GeneratorId, > + OUT CONST ACPI_TABLE_GENERATOR ** CONST Generator > + ); > + > +/** Return a pointer to the SMBIOS table generator. > + > + @param [in] This Pointer to the Dynamic Table Factory Protocol. > + @param [in] TableId The SMBIOS table generator ID for the > + requested generator. > + @param [out] Generator Pointer to the requested SMBIOS table > + generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +typedef > +EFI_STATUS > +EFIAPI > +(EFIAPI * > EFI_DYNAMIC_TABLE_FACTORY_GET_SMBIOS_TABLE_GENERATOR) ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This, > + IN CONST SMBIOS_TABLE_GENERATOR_ID GeneratorId, > + OUT CONST SMBIOS_TABLE_GENERATOR ** CONST Generator > + ); > + > +/** Return a pointer to the Device Tree table generator. > + > + @param [in] This Pointer to the Dynamic Table Factory Protocol. > + @param [in] TableId The Device Tree table generator ID for the > + requested generator. > + @param [out] Generator Pointer to the requested Device Tree table > + generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +typedef > +EFI_STATUS > +EFIAPI > +(EFIAPI * EFI_DYNAMIC_TABLE_FACTORY_GET_DT_TABLE_GENERATOR) ( > + IN CONST EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This, > + IN CONST DT_TABLE_GENERATOR_ID GeneratorId, > + OUT CONST DT_TABLE_GENERATOR ** CONST Generator > + ); > + > +/** A structure describing the Dynamic Table Factory Protocol interface. > +*/ > +typedef struct DynamicTableFactoryProtocol { > + /// The Dynamic Table Factory Protocol revision. > + UINT32 Revision; > + > + /// The interface used to request an ACPI Table Generator. > + EFI_DYNAMIC_TABLE_FACTORY_GET_ACPI_TABLE_GENERATOR > GetAcpiTableGenerator; > + > + /// The interface used to request a SMBIOS Table Generator. > + EFI_DYNAMIC_TABLE_FACTORY_GET_SMBIOS_TABLE_GENERATOR > GetSmbiosTableGenerator; > + > + /// The interface used to request a Device Tree Table Generator. > + EFI_DYNAMIC_TABLE_FACTORY_GET_DT_TABLE_GENERATOR > GetDtTableGenerator; > + > + /** Pointer to the data structure that holds the > + list of registered table generators > + */ > + EFI_DYNAMIC_TABLE_FACTORY_INFO * TableFactoryInfo; > +} EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL; > + > +/** The Dynamic Table Factory Protocol GUID. > +*/ > +extern EFI_GUID gEfiDynamicTableFactoryProtocolGuid; > + > +#pragma pack() > + > +#endif // DYNAMIC_TABLE_FACTORY_PROTOCOL_H_ > diff --git a/DynamicTablesPkg/Include/SmbiosTableGenerator.h > b/DynamicTablesPkg/Include/SmbiosTableGenerator.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..139d31464db473da9d > f427e1848835f3d693c41b > --- /dev/null > +++ b/DynamicTablesPkg/Include/SmbiosTableGenerator.h > @@ -0,0 +1,240 @@ > +/** @file > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#ifndef SMBIOS_TABLE_GENERATOR_H_ > +#define SMBIOS_TABLE_GENERATOR_H_ > + > +#include > + > +#include > + > +#pragma pack(1) > + > +/** The SMBIOS_TABLE_GENERATOR_ID type describes SMBIOS table > generator ID. > +*/ > +typedef TABLE_GENERATOR_ID SMBIOS_TABLE_GENERATOR_ID; > + > +/** The ESTD_SMBIOS_TABLE_ID enum describes the SMBIOS table IDs > reserved for > + the standard generators. > + > + NOTE: The SMBIOS Generator IDs do not match the table type numbers! > + This allows 0 to be used to catch invalid parameters. > +*/ > +typedef enum StdSmbiosTableGeneratorId { > + ESTD_SMBIOS_TABLE_ID_RESERVED =3D 0x0000, > + ESTD_SMBIOS_TABLE_ID_RAW, > + ESTD_SMBIOS_TABLE_ID_TYPE00, > + ESTD_SMBIOS_TABLE_ID_TYPE01, > + ESTD_SMBIOS_TABLE_ID_TYPE02, > + ESTD_SMBIOS_TABLE_ID_TYPE03, > + ESTD_SMBIOS_TABLE_ID_TYPE04, > + ESTD_SMBIOS_TABLE_ID_TYPE05, > + ESTD_SMBIOS_TABLE_ID_TYPE06, > + ESTD_SMBIOS_TABLE_ID_TYPE07, > + ESTD_SMBIOS_TABLE_ID_TYPE08, > + ESTD_SMBIOS_TABLE_ID_TYPE09, > + ESTD_SMBIOS_TABLE_ID_TYPE10, > + ESTD_SMBIOS_TABLE_ID_TYPE11, > + ESTD_SMBIOS_TABLE_ID_TYPE12, > + ESTD_SMBIOS_TABLE_ID_TYPE13, > + ESTD_SMBIOS_TABLE_ID_TYPE14, > + ESTD_SMBIOS_TABLE_ID_TYPE15, > + ESTD_SMBIOS_TABLE_ID_TYPE16, > + ESTD_SMBIOS_TABLE_ID_TYPE17, > + ESTD_SMBIOS_TABLE_ID_TYPE18, > + ESTD_SMBIOS_TABLE_ID_TYPE19, > + ESTD_SMBIOS_TABLE_ID_TYPE20, > + ESTD_SMBIOS_TABLE_ID_TYPE21, > + ESTD_SMBIOS_TABLE_ID_TYPE22, > + ESTD_SMBIOS_TABLE_ID_TYPE23, > + ESTD_SMBIOS_TABLE_ID_TYPE24, > + ESTD_SMBIOS_TABLE_ID_TYPE25, > + ESTD_SMBIOS_TABLE_ID_TYPE26, > + ESTD_SMBIOS_TABLE_ID_TYPE27, > + ESTD_SMBIOS_TABLE_ID_TYPE28, > + ESTD_SMBIOS_TABLE_ID_TYPE29, > + ESTD_SMBIOS_TABLE_ID_TYPE30, > + ESTD_SMBIOS_TABLE_ID_TYPE31, > + ESTD_SMBIOS_TABLE_ID_TYPE32, > + ESTD_SMBIOS_TABLE_ID_TYPE33, > + ESTD_SMBIOS_TABLE_ID_TYPE34, > + ESTD_SMBIOS_TABLE_ID_TYPE35, > + ESTD_SMBIOS_TABLE_ID_TYPE36, > + ESTD_SMBIOS_TABLE_ID_TYPE37, > + ESTD_SMBIOS_TABLE_ID_TYPE38, > + ESTD_SMBIOS_TABLE_ID_TYPE39, > + ESTD_SMBIOS_TABLE_ID_TYPE40, > + ESTD_SMBIOS_TABLE_ID_TYPE41, > + ESTD_SMBIOS_TABLE_ID_TYPE42, > + > + // IDs 43 - 125 are reserved > + > + ESTD_SMBIOS_TABLE_ID_TYPE126 =3D (ESTD_SMBIOS_TABLE_ID_TYPE00 + > 126), > + ESTD_SMBIOS_TABLE_ID_TYPE127, > + ESTD_SMBIOS_TABLE_ID_MAX > +} ESTD_SMBIOS_TABLE_ID; > + > +/** This macro checks if the Table Generator ID is for an SMBIOS Table > + Generator. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns TRUE if the table generator ID is for an SMBIOS Table > + Generator. > +*/ > +#define IS_GENERATOR_TYPE_SMBIOS(TableGeneratorId) \ > + ( \ > + GET_TABLE_TYPE (TableGeneratorId) =3D=3D \ > + ETableGeneratorTypeSmbios \ > + ) > + > +/** This macro checks if the Table Generator ID is for a standard SMBIOS > + Table Generator. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns TRUE if the table generator ID is for a standard SMBIOS > + Table Generator. > +*/ > +#define IS_VALID_STD_SMBIOS_GENERATOR_ID(TableGeneratorId) \ > + ( \ > + IS_GENERATOR_NAMESPACE_STD(TableGeneratorId) && \ > + IS_GENERATOR_TYPE_SMBIOS(TableGeneratorId) && \ > + ((GET_TABLE_ID(GeneratorId) >=3D ESTD_SMBIOS_TABLE_ID_RAW) && > \ > + (GET_TABLE_ID(GeneratorId) < ESTD_SMIOS_TABLE_ID_MAX)) \ > + ) > + > +/** This macro creates a standard SMBIOS Table Generator ID. > + > + @param [in] TableId The table generator ID. > + > + @returns a standard SMBIOS table generator ID. > +*/ > +#define CREATE_STD_SMBIOS_TABLE_GEN_ID(TableId) \ > + CREATE_TABLE_GEN_ID ( \ > + ETableGeneratorTypeSmbios, \ > + ETableGeneratorNameSpaceStd, \ > + TableId \ > + ) > + > +/** Forward declarations. > +*/ > +typedef struct ConfigurationManagerProtocol > EFI_CONFIGURATION_MANAGER_PROTOCOL; > +typedef struct CmStdObjSmbiosTableInfo > CM_STD_OBJ_SMBIOS_TABLE_INFO; > +typedef struct SmbiosTableGenerator SMBIOS_TABLE_GENERATOR; > + > +/** This function pointer describes the interface to SMBIOS table build > + functions provided by the SMBIOS table generator and called by the > + Table Manager to build an SMBIOS table. > + > + @param [in] Generator Pointer to the SMBIOS table generator. > + @param [in] SmbiosTableInfo Pointer to the SMBIOS table information. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol interface. > + @param [out] Table Pointer to the generated SMBIOS table. > + > + @returns EFI_SUCCESS If the table is generated successfully or other > + failure codes as returned by the generator. > +*/ > +typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_BUILD_TABLE) ( > + IN CONST SMBIOS_TABLE_GENERATOR * Generator, > + IN CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST SmbiosTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT SMBIOS_STRUCTURE ** Table > + ); > + > +/** This function pointer describes the interface to used by the > + Table Manager to give the generator an opportunity to free > + any resources allocated for building the SMBIOS table. > + > + @param [in] Generator Pointer to the SMBIOS table generator. > + @param [in] SmbiosTableInfo Pointer to the SMBIOS table information. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol interface. > + @param [in] Table Pointer to the generated SMBIOS table. > + > + @returns EFI_SUCCESS If freed successfully or other failure codes > + as returned by the generator. > +*/ > +typedef EFI_STATUS (*SMBIOS_TABLE_GENERATOR_FREE_TABLE) ( > + IN CONST SMBIOS_TABLE_GENERATOR * Generator, > + IN CONST CM_STD_OBJ_SMBIOS_TABLE_INFO * CONST > SmbiosTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN SMBIOS_STRUCTURE ** Table > + ); > + > +/** The SMBIOS_TABLE_GENERATOR structure provides an interface that > the > + Table Manager can use to invoke the functions to build SMBIOS tables= . > +*/ > +typedef struct SmbiosTableGenerator { > + /// The SMBIOS table generator ID. > + SMBIOS_TABLE_GENERATOR_ID GeneratorID; > + > + /// String describing the DT table > + /// generator. > + CONST CHAR16* Description; > + > + /// The SMBIOS table type. > + SMBIOS_TYPE Type; > + > + /// SMBIOS table build function pointer. > + SMBIOS_TABLE_GENERATOR_BUILD_TABLE BuildSmbiosTable; > + > + /** The function to free any resources > + allocated for building the SMBIOS table. > + */ > + SMBIOS_TABLE_GENERATOR_FREE_TABLE FreeTableResources; > +} SMBIOS_TABLE_GENERATOR; > + > +/** Register SMBIOS table factory generator. > + > + The SMBIOS table factory maintains a list of the Standard and OEM > SMBIOS > + table generators. > + > + @param [in] Generator Pointer to the SMBIOS table generator. > + > + @retval EFI_SUCCESS The Generator was registered > + successfully. > + @retval EFI_INVALID_PARAMETER The Generator ID is invalid or > + the Generator pointer is NULL. > + @retval EFI_ALREADY_STARTED The Generator for the Table ID is > + already registered. > +*/ > +EFI_STATUS > +EFIAPI > +RegisterSmbiosTableGenerator ( > + IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator > + ); > + > +/** Deregister SMBIOS generator. > + > + This function is called by the SMBIOS table generator to deregister it= self > + from the SMBIOS table factory. > + > + @param [in] Generator Pointer to the SMBIOS table generator. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER The generator is invalid. > + @retval EFI_NOT_FOUND The requested generator is not found > + in the list of registered generators. > +*/ > +EFI_STATUS > +EFIAPI > +DeregisterSmbiosTableGenerator ( > + IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator > + ); > +#pragma pack() > + > +#endif // SMBIOS_TABLE_GENERATOR_H_ > + > diff --git a/DynamicTablesPkg/Include/StandardNameSpaceObjects.h > b/DynamicTablesPkg/Include/StandardNameSpaceObjects.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..bcc9287527da4cdbc3 > 2a929ec6f68773a88a74f6 > --- /dev/null > +++ b/DynamicTablesPkg/Include/StandardNameSpaceObjects.h > @@ -0,0 +1,116 @@ > +/** @file > + > + Copyright (c) 2017, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > + - Std or STD - Standard > +**/ > + > +#ifndef STANDARD_NAMESPACE_OBJECTS_H_ > +#define STANDARD_NAMESPACE_OBJECTS_H_ > + > +#include > +#include > + > +#pragma pack(1) > + > +/** A macro defining a reserved zero/NULL token value that > + does not identify any object. > +*/ > +#define CM_NULL_TOKEN 0 > + > +/** A reference token that the Configuration Manager can use > + to identify a Configuration Manager object. > + > + This can be used to differentiate between instances of > + objects of the same types. The identification scheme is > + implementation defined and is defined by the Configuration > + Manager. > + > + Typically the token is used to identify a specific instance > + from a set of objects in a call to the GetObject()/SetObject(), > + implemented by the Configuration Manager protocol. > + > + Note: The token value 0 is reserved for a NULL token and does > + not identify any object. > +*/ > +typedef UINTN CM_OBJECT_TOKEN; > + > +/** The ESTD_OBJECT_ID enum describes the Object IDs > + in the Standard Namespace. > +*/ > +typedef enum StdObjectID { > + EStdObjCfgMgrInfo =3D 0x00000000, ///< 0 - Configuration Manager Info > + EStdObjAcpiTableList, ///< 1 - ACPI table Info List > + EStdObjSmbiosTableList, ///< 2 - SMBIOS table Info List > + EStdObjMax > +} ESTD_OBJECT_ID; > + > +/** A structure that describes the Configuration Manager Information. > +*/ > +typedef struct CmStdObjConfigurationManagerInfo { > + /// The Configuration Manager Revision. > + UINT32 Revision; > + > + /** The OEM ID. This information is used to > + populate the ACPI table header information. > + */ > + UINT8 OemId[6]; > +} CM_STD_OBJ_CONFIGURATION_MANAGER_INFO; > + > +/** A structure used to describe the ACPI table generators to be invoked= . > + > + The AcpiTableData member of this structure may be used to directly > provide > + the binary ACPI table data which is required by the following standard > + generators: > + - RAW > + - DSDT > + - SSDT > + > + Providing the ACPI table data is optional and depends on the generator > + that is being invoked. If unused, set AcpiTableData to NULL. > +*/ > +typedef struct CmAStdObjAcpiTableInfo { > + /// The signature of the ACPI Table to be installed. > + UINT32 AcpiTableSignature; > + > + /// The ACPI Table Generator ID. > + ACPI_TABLE_GENERATOR_ID TableGeneratorId; > + > + /// Optional pointer to the ACPI table data. > + EFI_ACPI_DESCRIPTION_HEADER * AcpiTableData; > + > +} CM_STD_OBJ_ACPI_TABLE_INFO; > + > +/** A structure used to describe the SMBIOS table generators to be > invoked. > + > + The SmbiosTableData member of this structure is used to provide > + the SMBIOS table data which is required by the following standard > + generator(s): > + - RAW > + > + Providing the SMBIOS table data is optional and depends on the > + generator that is being invoked. If unused, set the SmbiosTableData > + to NULL. > +*/ > +typedef struct CmStdObjSmbiosTableInfo { > + /// The SMBIOS Table Generator ID. > + SMBIOS_TABLE_GENERATOR_ID TableGeneratorId; > + > + /// Optional pointer to the SMBIOS table data. > + SMBIOS_STRUCTURE * SmbiosTableData; > +} CM_STD_OBJ_SMBIOS_TABLE_INFO; > + > +#pragma pack() > + > +#endif // STANDARD_NAMESPACE_OBJECTS_H_ > diff --git a/DynamicTablesPkg/Include/TableGenerator.h > b/DynamicTablesPkg/Include/TableGenerator.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..171609f1b73736596d > edff906ef8de275f2c8cca > --- /dev/null > +++ b/DynamicTablesPkg/Include/TableGenerator.h > @@ -0,0 +1,252 @@ > +/** @file > + > + Copyright (c) 2017, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - ACPI - Advanced Configuration and Power Interface > + - SMBIOS - System Management BIOS > + - DT - Device Tree > +**/ > + > +#ifndef TABLE_GENERATOR_H_ > +#define TABLE_GENERATOR_H_ > + > +/** The TABLE_GENERATOR_ID type describes the Table Generator ID > + > + Table Generator ID > + > +_________________________________________________________ > ______________________ > +| 31 | 30 |29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | = 17| > 16| > +------------------------------------------------------------------------= ------- > +|TNSID| 0 | TT | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | = 0| 0| > +_________________________________________________________ > ______________________ > +_________________________________________________________ > ______________________ > +|15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | = 1 | 0| > +------------------------------------------------------------------------= ------- > +| Table ID = | > +_________________________________________________________ > ______________________ > + > + Bit [31] - Table NameSpace ID (TNSID) > + 0 - Standard > + 1 - Custom/OEM > + > + Bit [30] - Reserved, Must be Zero > + > + Bit [29:28] - Table Type (TT) > + 0 - ACPI Table > + 1 - SMBIOS Table > + 2 - DT (Device Tree) Table > + 3 - Reserved (INVALID) > + > + Bit [27:16] - Reserved, Must Be Zero > + > + Bit [15:0] - Table ID > + > + Standard ACPI Table IDs: > + 0 - Reserved > + 1 - RAW > + 2 - FADT > + 3 - DSDT > + 4 - SSDT > + 5 - MADT > + 6 - GTDT > + 7 - DBG2 > + 8 - SPCR > + 9 - MCFG > + > + Standard SMBIOS Table IDs: > + 0 - Reserved > + 1 - RAW > + 2 - Table Type00 > + 3 - Table Type01 > + 4 - Table Type02 > + 5 - Table Type03 > + 6 - Table Type04 > + 7 - Table Type05 > + 8 - Table Type06 > + 9 - Table Type07 > + 10 - Table Type08 > + 11 - Table Type09 > + 12 - Table Type10 > + 13 - Table Type11 > + 14 - Table Type12 > + 15 - Table Type13 > + 16 - Table Type14 > + 17 - Table Type15 > + 18 - Table Type16 > + 19 - Table Type17 > + 20 - Table Type18 > + 21 - Table Type19 > + 22 - Table Type20 > + 23 - Table Type21 > + 24 - Table Type22 > + 25 - Table Type23 > + 26 - Table Type24 > + 27 - Table Type25 > + 28 - Table Type26 > + 29 - Table Type27 > + 30 - Table Type28 > + 31 - Table Type29 > + 32 - Table Type30 > + 33 - Table Type31 > + 34 - Table Type32 > + 35 - Table Type33 > + 36 - Table Type34 > + 37 - Table Type35 > + 38 - Table Type36 > + 39 - Table Type37 > + 40 - Table Type38 > + 41 - Table Type39 > + 42 - Table Type40 > + 43 - Table Type41 > + 44 - Table Type42 > + 45-127 - Reserved > + 128 - Table Type126 > + 129 - Table Type127 > +**/ > +typedef UINT32 TABLE_GENERATOR_ID; > + > +/** This enum lists the Table Generator Types. > +*/ > +typedef enum TableGeneratorType { > + ETableGeneratorTypeAcpi =3D 0, ///< ACPI Table Generator Type. > + ETableGeneratorTypeSmbios, ///< SMBIOS Table Generator Type. > + ETableGeneratorTypeDt, ///< Device Tree Table Generator Type. > + ETableGeneratorTypeReserved > +} ETABLE_GENERATOR_TYPE; > + > +/** This enum lists the namespaces for the Table Generators. > +*/ > +typedef enum TableGeneratorNameSpace { > + ETableGeneratorNameSpaceStd =3D 0, ///< Standard Namespace. > + ETableGeneratorNameSpaceOem ///< OEM Namespace. > +} ETABLE_GENERATOR_NAMESPACE; > + > +/** A mask for the Table ID bits of TABLE_GENERATOR_ID. > +*/ > +#define TABLE_ID_MASK 0xFF > + > +/** A mask for the Namespace ID bits of TABLE_GENERATOR_ID. > +*/ > +#define TABLE_NAMESPACEID_MASK (BIT31) > + > +/** A mask for the Table Type bits of TABLE_GENERATOR_ID. > +*/ > +#define TABLE_TYPE_MASK (BIT29 | BIT28) > + > +/** Starting bit position for the Table Type bits > +*/ > +#define TABLE_TYPE_BIT_SHIFT 28 > + > +/** Starting bit position for the Table Namespace ID bit > +*/ > +#define TABLE_NAMESPACE_ID_BIT_SHIFT 31 > + > +/** This macro returns the Table ID from the TableGeneratorId. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns the Table ID described by the TableGeneratorId. > +*/ > +#define GET_TABLE_ID(TableGeneratorId) \ > + ((TableGeneratorId) & TABLE_ID_MASK) > + > +/** This macro returns the Table type from the TableGeneratorId. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns the Table type described by the TableGeneratorId. > +*/ > +#define GET_TABLE_TYPE(TableGeneratorId) = \ > + (((TableGeneratorId) & TABLE_TYPE_MASK) >> > TABLE_TYPE_BIT_SHIFT) > + > +/** This macro returns the Namespace ID from the TableGeneratorId. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns the Namespace described by the TableGeneratorId. > +*/ > +#define GET_TABLE_NAMESPACEID(TableGeneratorId) \ > + (((TableGeneratorId) & TABLE_NAMESPACEID_MASK) >> \ > + TABLE_NAMESPACE_ID_BIT_SHIFT) > + > +/** This macro checks if the TableGeneratorId is in the Standard > Namespace. > + > + @param [in] TableGeneratorId The table generator ID. > + > + @returns TRUE if the TableGeneratorId is in the Standard Namespace. > +*/ > +#define IS_GENERATOR_NAMESPACE_STD(TableGeneratorId) \ > + ( \ > + GET_TABLE_NAMESPACEID(TableGeneratorId) =3D=3D \ > + ETableGeneratorNameSpaceStd \ > + ) > + > +/** This macro creates a TableGeneratorId > + > + @param [in] TableType The table type. > + @param [in] TableNameSpaceId The namespace ID for the table. > + @param [in] TableId The table ID. > + > + @returns a TableGeneratorId calculated from the inputs. > +*/ > +#define CREATE_TABLE_GEN_ID(TableType, TableNameSpaceId, TableId) > \ > + ((((TableType) << TABLE_TYPE_BIT_SHIFT) & TABLE_TYPE_MASK) | \ > + (((TableNameSpaceId) << TABLE_NAMESPACE_ID_BIT_SHIFT) & \ > + TABLE_NAMESPACEID_MASK) | ((TableId) & TABLE_ID_MASK)) > + > +/** Starting bit position for MAJOR revision > +*/ > +#define MAJOR_REVISION_BIT_SHIFT 16 > + > +/** A mask for Major revision. > +*/ > +#define MAJOR_REVISION_MASK 0xFFFF > + > +/** A mask for Minor revision. > +*/ > +#define MINOR_REVISION_MASK 0xFFFF > + > +/** This macro generates a Major.Minor version > + where the Major and Minor fields are 16 bit. > + > + @param [in] Major The Major revision. > + @param [in] Minor The Minor revision. > + > + @returns a 32 bit representation of the type Major.Minor. > +*/ > +#define CREATE_REVISION(Major, Minor) = \ > + ((((Major) & MAJOR_REVISION_MASK) << > MAJOR_REVISION_BIT_SHIFT) | \ > + ((Minor) & MINOR_REVISION_MASK)) > + > +/** This macro returns the Major revision > + > + Extracts Major from the 32 bit representation of the type Major.Minor > + > + @param [in] Revision The Revision value which is 32 bit. > + > + @returns the Major part of the revision. > +*/ > +#define GET_MAJOR_REVISION(Revision) = \ > + (((Revision) >> MAJOR_REVISION_BIT_SHIFT) & > MAJOR_REVISION_MASK) > + > +/** This macro returns the Minor revision > + > + Extracts Minor from the 32 bit representation of the type Major.Minor > + > + @param [in] Revision The Revision value which is 32 bit. > + > + @returns the Minor part of the revision. > +*/ > +#define GET_MINOR_REVISION(Revision) ((Revision) & > MINOR_REVISION_MASK) > + > +#endif // TABLE_GENERATOR_H_ > + > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.i > nf > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.i > nf > new file mode 100644 > index > 0000000000000000000000000000000000000000..e81ad7018334075758 > 441b1180a6a2d5e8565db3 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.i > nf > @@ -0,0 +1,47 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D AcpiDbg2LibArm > + FILE_GUID =3D A17BA4F0-3DEB-4FE5-BD27-EC008E541B22 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D NULL|DXE_DRIVER > + CONSTRUCTOR =3D AcpiDbg2LibConstructor > + DESTRUCTOR =3D AcpiDbg2LibDestructor > + > +[Sources] > + Dbg2Generator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + ArmPlatformPkg/ArmPlatformPkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + SerialPortLib > + > +[FixedPcd] > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits > + > +[Protocols] > + > +[Guids] > + > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..910b9b68f43b4a9e7d > 0d8e9a8c879abb172a9678 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c > @@ -0,0 +1,440 @@ > +/** @file > + DBG2 Table Generator > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Reference(s): > + - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 201= 5. > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard DBG2 Table Generator > + > + Constructs the DBG2 table for PL011 or SBSA UART peripherals. > + > +Requirements: > + The following Configuration Manager Object(s) are required by > + this Generator: > + - EArmObjSerialDebugPortInfo > +*/ > + > +#pragma pack(1) > + > +/** The number of debug ports represented by the Table. > +*/ > +#define DBG2_NUM_DEBUG_PORTS 1 > + > +/** The number of Generic Address Registers > + presented in the debug device information. > +*/ > +#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS 1 > + > +/** The index for the debug port 1 in the Debug port information list. > +*/ > +#define DBG_PORT_INDEX_PORT1 0 > + > +/** A string representing the name of the debug port 1. > +*/ > +#define NAME_STR_PORT1 "COM1" > + > +/** The length of the namespace string. > +*/ > +#define DBG2_NAMESPACESTRING_FIELD_SIZE sizeof > (NAME_STR_PORT1) > + > +/** The PL011 UART address range length. > +*/ > +#define PL011_UART_LENGTH 0x1000 > + > +/** A structure that provides the OS with the required information > + for initializing a debugger connection. > +*/ > +typedef struct { > + /// The debug device information for the platform > + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device; > + > + /// The base address register for the serial port > + EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister; > + > + /// The address size > + UINT32 AddressSize; > + > + /// The debug port name string > + UINT8 NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE]; > +} DBG2_DEBUG_DEVICE_INFORMATION; > + > +/** A structure representing the information about the debug port(s) > + available on the platform. > +*/ > +typedef struct { > + /// The DBG2 table header > + EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE Description; > + > + /// Debug port information list > + DBG2_DEBUG_DEVICE_INFORMATION > Dbg2DeviceInfo[DBG2_NUM_DEBUG_PORTS]; > +} DBG2_TABLE; > + > +/** A helper macro used for initializing the debug port device > + information structure. > + > + @param [in] NumReg The number of generic address registers. > + @param [in] SubType The DBG Port SubType. > + @param [in] UartBase The UART port base address. > + @param [in] UartAddrLen The UART port address range length. > + @param [in] UartNameStr The UART port name string. > +*/ > +#define DBG2_DEBUG_PORT_DDI( \ > + NumReg, \ > + SubType, \ > + UartBase, \ > + UartAddrLen, \ > + UartNameStr \ > + ) { \ > + { \ > + /* UINT8 Revision */ \ > + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, > \ > + /* UINT16 Length */ \ > + sizeof (DBG2_DEBUG_DEVICE_INFORMATION), \ > + /* UINT8 NumberofGenericAddressRegisters */ \ > + NumReg, \ > + /* UINT16 NameSpaceStringLength */ \ > + DBG2_NAMESPACESTRING_FIELD_SIZE, \ > + /* UINT16 NameSpaceStringOffset */ \ > + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString), > \ > + /* UINT16 OemDataLength */ \ > + 0, \ > + /* UINT16 OemDataOffset */ \ > + 0, \ > + /* UINT16 Port Type */ \ > + EFI_ACPI_DBG2_PORT_TYPE_SERIAL, \ > + /* UINT16 Port Subtype */ \ > + SubType, \ > + /* UINT8 Reserved[2] */ \ > + {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}, \ > + /* UINT16 BaseAddressRegister Offset */ \ > + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, > BaseAddressRegister), \ > + /* UINT16 AddressSize Offset */ \ > + OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize) > \ > + }, \ > + /* EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister > */ \ > + ARM_GAS32 (UartBase), \ > + /* UINT32 AddressSize */ \ > + UartAddrLen, \ > + /* UINT8 NameSpaceString[MAX_DBG2_NAME_LEN] */ \ > + UartNameStr \ > + } > + > +/** The DBG2 Table template definition. > + > + Note: fields marked with "{Template}" will be set dynamically > +*/ > +STATIC > +DBG2_TABLE AcpiDbg2 =3D { > + { > + ACPI_HEADER ( > + EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, > + DBG2_TABLE, > + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION > + ), > + OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo), > + DBG2_NUM_DEBUG_PORTS > + }, > + { > + /* > + * Debug port 1 > + */ > + DBG2_DEBUG_PORT_DDI ( > + DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS, > + 0, // {Template}: Serial Port Subtype > + 0, // {Template}: Serial Port Base Address > + PL011_UART_LENGTH, > + NAME_STR_PORT1 > + ) > + } > +}; > + > +#pragma pack() > + > +/** This macro expands to a function that retrieves the Serial > + debug port information from the Configuration Manager > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjSerialDebugPortInfo, > + CM_ARM_SERIAL_PORT_INFO > + ); > + > +/** Initialize the PL011 UART with the parameters obtained from > + the Configuration Manager. > + > + @param [in] SerialPortInfo Pointer to the Serial Port Information. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER The parameters for serial port > initialization > + are invalid. > +*/ > +STATIC > +EFI_STATUS > +SetupDebugUart ( > + IN CONST CM_ARM_SERIAL_PORT_INFO * CONST SerialPortInfo > + ) > +{ > + EFI_STATUS Status; > + UINT64 BaudRate; > + UINT32 ReceiveFifoDepth; > + EFI_PARITY_TYPE Parity; > + UINT8 DataBits; > + EFI_STOP_BITS_TYPE StopBits; > + > + ASSERT (SerialPortInfo !=3D NULL); > + > + // Initialize the Serial Debug UART > + DEBUG ((DEBUG_INFO, "Initializing Serial Debug UART...\n")); > + ReceiveFifoDepth =3D 0; // Use the default value for FIFO depth > + Parity =3D (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity); > + DataBits =3D FixedPcdGet8 (PcdUartDefaultDataBits); > + StopBits =3D (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits)= ; > + > + BaudRate =3D SerialPortInfo->BaudRate; > + Status =3D PL011UartInitializePort ( > + (UINTN)SerialPortInfo->BaseAddress, > + SerialPortInfo->Clock, > + &BaudRate, > + &ReceiveFifoDepth, > + &Parity, > + &DataBits, > + &StopBits > + ); > + > + DEBUG ((DEBUG_INFO, "Debug UART Configuration:\n")); > + DEBUG ((DEBUG_INFO, "UART Base =3D 0x%lx\n", SerialPortInfo- > >BaseAddress)); > + DEBUG ((DEBUG_INFO, "Clock =3D %d\n", SerialPortInfo->Clock)); > + DEBUG ((DEBUG_INFO, "Baudrate =3D %ld\n", BaudRate)); > + DEBUG ((DEBUG_INFO, "Configuring Debug UART. Status =3D %r\n", Status)= ); > + > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > +/** Construct the DBG2 ACPI table > + > + The BuildDbg2Table function is called by the Dynamic Table Manager > + to construct the DBG2 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 Info. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [out] Table Pointer to the constructed ACPI Table. > + > + @retval EFI_SUCCESS Table generated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +BuildDbg2Table ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + EFI_STATUS Status; > + CM_ARM_SERIAL_PORT_INFO * SerialPortInfo; > + > + ASSERT (This !=3D NULL); > + ASSERT (AcpiTableInfo !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Table !=3D NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTableSignat= ure); > + > + *Table =3D NULL; > + > + Status =3D GetEArmObjSerialDebugPortInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &SerialPortInfo, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: DBG2: Failed to get serial port information. Status =3D %r= \n", > + Status > + )); > + goto error_handler; > + } > + > + if (SerialPortInfo->BaseAddress =3D=3D 0) { > + Status =3D EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: DBG2: Uart port base address is invalid. BaseAddress =3D > 0x%lx\n", > + SerialPortInfo->BaseAddress > + )); > + goto error_handler; > + } > + > + if ((SerialPortInfo->PortSubtype !=3D > + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) && > + (SerialPortInfo->PortSubtype !=3D > + > EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) > && > + (SerialPortInfo->PortSubtype !=3D > + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART) > && > + (SerialPortInfo->PortSubtype !=3D > + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_DCC)) { > + Status =3D EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: DBG2: Uart port sybtype is invalid. PortSubtype =3D 0x%x\n= ", > + SerialPortInfo->PortSubtype > + )); > + goto error_handler; > + } > + > + Status =3D AddAcpiHeader ( > + CfgMgrProtocol, > + This, > + (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiDbg2, > + sizeof (DBG2_TABLE) > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: DBG2: Failed to add ACPI header. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Update the base address > + > AcpiDbg2.Dbg2DeviceInfo[DBG_PORT_INDEX_PORT1].BaseAddressRegister. > Address =3D > + SerialPortInfo->BaseAddress; > + > + // Update the serial port subtype > + > AcpiDbg2.Dbg2DeviceInfo[DBG_PORT_INDEX_PORT1].Dbg2Device.PortSubty > pe =3D > + SerialPortInfo->PortSubtype; > + > + // Initialize the serial port > + Status =3D SetupDebugUart (SerialPortInfo); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: DBG2: Failed to configure debug serial port. Status =3D %r= \n", > + Status > + )); > + goto error_handler; > + } > + > + *Table =3D (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiDbg2; > + > +error_handler: > + return Status; > +} > + > +/** This macro defines the DBG2 Table Generator revision. > +*/ > +#define DBG2_GENERATOR_REVISION CREATE_REVISION (1, 0) > + > +/** The interface for the DBG2 Table Generator. > +*/ > +STATIC > +CONST > +ACPI_TABLE_GENERATOR Dbg2Generator =3D { > + // Generator ID > + CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_DBG2), > + // Generator Description > + L"ACPI.STD.DBG2.GENERATOR", > + // ACPI Table Signature > + EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + DBG2_GENERATOR_REVISION, > + // Build Table function > + BuildDbg2Table, > + // No additional resources are allocated by the generator. > + // Hence the Free Resource function is not required. > + 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 > +AcpiDbg2LibConstructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D RegisterAcpiTableGenerator (&Dbg2Generator); > + DEBUG ((DEBUG_INFO, "DBG2: 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 > +AcpiDbg2LibDestructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D DeregisterAcpiTableGenerator (&Dbg2Generator); > + DEBUG ((DEBUG_INFO, "DBG2: Deregister Generator. Status =3D %r\n", > Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.in > f > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.in > f > new file mode 100644 > index > 0000000000000000000000000000000000000000..db8b04845434fd7d0c > db5230699b9279914b3900 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.in > f > @@ -0,0 +1,41 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D AcpiFadtLibArm > + FILE_GUID =3D 686FE5FE-B944-485F-8B1C-7D60E0056487 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D NULL|DXE_DRIVER > + CONSTRUCTOR =3D AcpiFadtLibConstructor > + DESTRUCTOR =3D AcpiFadtLibDestructor > + > +[Sources] > + FadtGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > +[Protocols] > + > +[Guids] > + > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..f33c3ef9a77cd980ff26 > 8a21c933026bdde7ccf7 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c > @@ -0,0 +1,666 @@ > +/** @file > + FADT Table Generator > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Reference(s): > + - ACPI 6.2 Specification - Errata A, September 2017 > + > +**/ > + > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard FADT Generator > + > +Requirements: > + The following Configuration Manager Object(s) are required by > + this Generator: > + - EArmObjPowerManagementProfileInfo > + - EArmObjBootArchInfo > + - EArmObjHypervisorVendorIdentity (OPTIONAL) > +*/ > + > +/** This macro defines the FADT flag options for ARM Platforms. > +*/ > +#define FADT_FLAGS (EFI_ACPI_6_2_HW_REDUCED_ACPI | \ > + EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE) > + > +/** This macro defines the valid mask for the FADT flag option > + if HW_REDUCED_ACPI flag in the table is set. > + > + Invalid bits are: 1, 2, 3,7, 8, 13, 14,16, 17 and > + 22-31 (reserved). > + > + Valid bits are: > + EFI_ACPI_6_2_WBINVD BIT0 > + EFI_ACPI_6_2_PWR_BUTTON BIT4 > + EFI_ACPI_6_2_SLP_BUTTON BIT5 > + EFI_ACPI_6_2_FIX_RTC BIT6 > + EFI_ACPI_6_2_DCK_CAP BIT9 > + EFI_ACPI_6_2_RESET_REG_SUP BIT10 > + EFI_ACPI_6_2_SEALED_CASE BIT11 > + EFI_ACPI_6_2_HEADLESS BIT12 > + EFI_ACPI_6_2_USE_PLATFORM_CLOCK BIT15 > + EFI_ACPI_6_2_FORCE_APIC_CLUSTER_MODEL BIT18 > + EFI_ACPI_6_2_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19 > + EFI_ACPI_6_2_HW_REDUCED_ACPI BIT20 > + EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE BIT21 > +*/ > +#define VALID_HARDWARE_REDUCED_FLAG_MASK ( \ > + EFI_ACPI_6_2_WBINVD | \ > + EFI_ACPI_6_2_PWR_BUTTON | \ > + EFI_ACPI_6_2_SLP_BUTTON | \ > + EFI_ACPI_6_2_FIX_RTC | \ > + EFI_ACPI_6_2_DCK_CAP | \ > + EFI_ACPI_6_2_RESET_REG_SUP | \ > + EFI_ACPI_6_2_SEALED_CASE | \ > + EFI_ACPI_6_2_HEADLESS | \ > + EFI_ACPI_6_2_USE_PLATFORM_CLOCK | \ > + EFI_ACPI_6_2_FORCE_APIC_CLUSTER_MODEL | \ > + EFI_ACPI_6_2_FORCE_APIC_PHYSICAL_DESTINATION_MODE | \ > + EFI_ACPI_6_2_HW_REDUCED_ACPI | \ > + EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE) > + > +#pragma pack(1) > + > +/** The AcpiFadt is a template > EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE > + structure used for generating the FADT Table. > + Note: fields marked with "{Template}" will be updated dynamically. > +*/ > +STATIC > +EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt =3D { > + ACPI_HEADER ( > + EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, > + EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE, > + EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION > + ), > + // UINT32 FirmwareCtrl > + 0, > + // UINT32 Dsdt > + 0, > + // UINT8 Reserved0 > + EFI_ACPI_RESERVED_BYTE, > + // UINT8 PreferredPmProfile > + EFI_ACPI_6_2_PM_PROFILE_UNSPECIFIED, // {Template}: Power > Management Profile > + // UINT16 SciInt > + 0, > + // UINT32 SmiCmd > + 0, > + // UINT8 AcpiEnable > + 0, > + // UINT8 AcpiDisable > + 0, > + // UINT8 S4BiosReq > + 0, > + // UINT8 PstateCnt > + 0, > + // UINT32 Pm1aEvtBlk > + 0, > + // UINT32 Pm1bEvtBlk > + 0, > + // UINT32 Pm1aCntBlk > + 0, > + // UINT32 Pm1bCntBlk > + 0, > + // UINT32 Pm2CntBlk > + 0, > + // UINT32 PmTmrBlk > + 0, > + // UINT32 Gpe0Blk > + 0, > + // UINT32 Gpe1Blk > + 0, > + // UINT8 Pm1EvtLen > + 0, > + // UINT8 Pm1CntLen > + 0, > + // UINT8 Pm2CntLen > + 0, > + // UINT8 PmTmrLen > + 0, > + // UINT8 Gpe0BlkLen > + 0, > + // UINT8 Gpe1BlkLen > + 0, > + // UINT8 Gpe1Base > + 0, > + // UINT8 CstCnt > + 0, > + // UINT16 PLvl2Lat > + 0, > + // UINT16 PLvl3Lat > + 0, > + // UINT16 FlushSize > + 0, > + // UINT16 FlushStride > + 0, > + // UINT8 DutyOffset > + 0, > + // UINT8 DutyWidth > + 0, > + // UINT8 DayAlrm > + 0, > + // UINT8 MonAlrm > + 0, > + // UINT8 Century > + 0, > + // UINT16 IaPcBootArch > + 0, > + // UINT8 Reserved1 > + 0, > + // UINT32 Flags > + FADT_FLAGS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE ResetReg > + NULL_GAS, > + // UINT8 ResetValue > + 0, > + // UINT16 ArmBootArch > + EFI_ACPI_6_2_ARM_PSCI_COMPLIANT, // {Template}: ARM Boot > Architecture Flags > + // UINT8 MinorRevision > + EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION, > + // UINT64 XFirmwareCtrl > + 0, > + // UINT64 XDsdt > + 0, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk > + NULL_GAS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk > + NULL_GAS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk > + NULL_GAS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk > + NULL_GAS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk > + NULL_GAS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk > + NULL_GAS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XGpe0Blk > + NULL_GAS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XGpe1Blk > + NULL_GAS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE SleepControlReg > + NULL_GAS, > + // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE SleepStatusReg > + NULL_GAS, > + // UINT64 HypervisorVendorIdentity > + EFI_ACPI_RESERVED_QWORD // {Template}: Hypervisor Vendor ID > +}; > + > +#pragma pack() > + > +/** This macro expands to a function that retrieves the Power > + Management Profile Information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjPowerManagementProfileInfo, > + CM_ARM_POWER_MANAGEMENT_PROFILE_INFO > + ); > + > +/** This macro expands to a function that retrieves the Boot > + Architecture Information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjBootArchInfo, > + CM_ARM_BOOT_ARCH_INFO > + ); > + > +/** This macro expands to a function that retrieves the Hypervisor > + Vendor ID from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjHypervisorVendorIdentity, > + CM_ARM_HYPERVISOR_VENDOR_ID > + ); > + > +/** This macro expands to a function that retrieves the Fixed > + feature flags for the platform from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjFixedFeatureFlags, > + CM_ARM_FIXED_FEATURE_FLAGS > + ); > + > +/** Update the Power Management Profile information in the FADT Table. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +FadtAddPmProfileInfo ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol > +) > +{ > + EFI_STATUS Status; > + CM_ARM_POWER_MANAGEMENT_PROFILE_INFO * PmProfile; > + > + ASSERT (CfgMgrProtocol !=3D NULL); > + > + // Get the Power Management Profile from the Platform Configuration > Manager > + Status =3D GetEArmObjPowerManagementProfileInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &PmProfile, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Failed to get Power Management Profile information."= \ > + " Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "FADT: PreferredPmProfile =3D 0x%x\n", > + PmProfile->PowerManagementProfile > + )); > + > + AcpiFadt.PreferredPmProfile =3D PmProfile->PowerManagementProfile; > + > +error_handler: > + return Status; > +} > + > +/** Updates the Boot Architecture information in the FADT Table. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +FadtAddBootArchInfo ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol > +) > +{ > + EFI_STATUS Status; > + CM_ARM_BOOT_ARCH_INFO * BootArchInfo; > + > + ASSERT (CfgMgrProtocol !=3D NULL); > + > + // Get the Boot Architecture flags from the Platform Configuration > Manager > + Status =3D GetEArmObjBootArchInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &BootArchInfo, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Failed to get Boot Architecture flags. Status =3D %r= \n", > + Status > + )); > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "FADT BootArchFlag =3D 0x%x\n", > + BootArchInfo->BootArchFlags > + )); > + > + AcpiFadt.ArmBootArch =3D BootArchInfo->BootArchFlags; > + > +error_handler: > + return Status; > +} > + > +/** Update the Hypervisor Vendor ID in the FADT Table. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +FadtAddHypervisorVendorId ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol > +) > +{ > + EFI_STATUS Status; > + CM_ARM_HYPERVISOR_VENDOR_ID * HypervisorVendorInfo; > + > + ASSERT (CfgMgrProtocol !=3D NULL); > + > + // Get the Hypervisor Vendor ID from the Platform Configuration > Manager > + Status =3D GetEArmObjHypervisorVendorIdentity ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &HypervisorVendorInfo, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + if (Status =3D=3D EFI_NOT_FOUND) { > + DEBUG (( > + DEBUG_INFO, > + "INFO: FADT: Platform does not have a Hypervisor Vendor ID." > + "Status =3D %r\n", > + Status > + )); > + } else { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Failed to get Hypervisor Vendor ID. Status =3D %r\= n", > + Status > + )); > + } > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "FADT: EArmObjHypervisorVendorIdentity =3D 0x%lx\n", > + HypervisorVendorInfo->HypervisorVendorId > + )); > + > + AcpiFadt.HypervisorVendorIdentity =3D HypervisorVendorInfo- > >HypervisorVendorId; > + > +error_handler: > + return Status; > +} > + > +/** Update the Fixed Feature Flags in the FADT Table. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +FadtAddFixedFeatureFlags ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol > +) > +{ > + EFI_STATUS Status; > + CM_ARM_FIXED_FEATURE_FLAGS * FixedFeatureFlags; > + > + ASSERT (CfgMgrProtocol !=3D NULL); > + > + // Get the Fixed feature flags from the Platform Configuration Manager > + Status =3D GetEArmObjFixedFeatureFlags ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &FixedFeatureFlags, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + if (Status =3D=3D EFI_NOT_FOUND) { > + DEBUG (( > + DEBUG_INFO, > + "INFO: FADT: Platform does not define additional Fixed feature f= lags." > + "Status =3D %r\n", > + Status > + )); > + } else { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Failed to get Fixed feature flags. Status =3D %r\n= ", > + Status > + )); > + } > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "FADT: EArmObjFixedFeatureFlags =3D 0x%x\n", > + FixedFeatureFlags->Flags > + )); > + > + if ((FixedFeatureFlags->Flags & > ~(VALID_HARDWARE_REDUCED_FLAG_MASK)) !=3D 0) { > + DEBUG (( > + DEBUG_WARN, > + "FADT: Invalid Fixed feature flags defined by platform," > + "Invalid Flags bits are =3D 0x%x\n", > + (FixedFeatureFlags->Flags & > ~(VALID_HARDWARE_REDUCED_FLAG_MASK)) > + )); > + } > + > + AcpiFadt.Flags |=3D (FixedFeatureFlags->Flags & > + VALID_HARDWARE_REDUCED_FLAG_MASK); > + > +error_handler: > + return Status; > +} > + > +/** Construct the FADT 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 Info. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [out] Table Pointer to the constructed ACPI Table. > + > + @retval EFI_SUCCESS Table generated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +BuildFadtTable ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + EFI_STATUS Status; > + > + ASSERT (This !=3D NULL); > + ASSERT (AcpiTableInfo !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Table !=3D NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTableSignat= ure); > + > + *Table =3D NULL; > + > + Status =3D AddAcpiHeader ( > + CfgMgrProtocol, > + This, > + (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiFadt, > + sizeof (EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE) > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Failed to add ACPI header. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Update PmProfile Info > + Status =3D FadtAddPmProfileInfo (CfgMgrProtocol); > + if (EFI_ERROR (Status)) { > + goto error_handler; > + } > + > + // Update BootArch Info > + Status =3D FadtAddBootArchInfo (CfgMgrProtocol); > + if (EFI_ERROR (Status)) { > + goto error_handler; > + } > + > + // Add the Hypervisor Vendor Id if present > + // Note if no hypervisor is present the zero bytes > + // will be placed in this field. > + Status =3D FadtAddHypervisorVendorId (CfgMgrProtocol); > + if (EFI_ERROR (Status)) { > + if (Status =3D=3D EFI_NOT_FOUND) { > + DEBUG (( > + DEBUG_INFO, > + "INFO: FADT: No Hypervisor Vendor ID found," \ > + " assuming no Hypervisor is present in the firmware.\n" > + )); > + } else { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Error reading Hypervisor Vendor ID, Status =3D %r"= , > + Status > + )); > + goto error_handler; > + } > + } > + > + Status =3D FadtAddFixedFeatureFlags (CfgMgrProtocol); > + if (EFI_ERROR (Status)) { > + if (Status =3D=3D EFI_NOT_FOUND) { > + DEBUG (( > + DEBUG_INFO, > + "INFO: FADT: No Fixed feature flags found," \ > + " assuming no additional flags are defined for the platform.\n" > + )); > + Status =3D EFI_SUCCESS; > + } else { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Error reading Fixed feature flags, Status =3D %r", > + Status > + )); > + goto error_handler; > + } > + } > + > + *Table =3D (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiFadt; > +error_handler: > + return Status; > +} > + > +/** This macro defines the FADT Table Generator revision. > +*/ > +#define FADT_GENERATOR_REVISION CREATE_REVISION (1, 0) > + > +/** The interface for the FADT Table Generator. > +*/ > +STATIC > +CONST > +ACPI_TABLE_GENERATOR FadtGenerator =3D { > + // Generator ID > + CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_FADT), > + // Generator Description > + L"ACPI.STD.FADT.GENERATOR", > + // ACPI Table Signature > + EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + FADT_GENERATOR_REVISION, > + // Build Table function > + BuildFadtTable, > + // No additional resources are allocated by the generator. > + // Hence the Free Resource function is not required. > + 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 > +AcpiFadtLibConstructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D RegisterAcpiTableGenerator (&FadtGenerator); > + DEBUG ((DEBUG_INFO, "FADT: 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 > +AcpiFadtLibDestructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D DeregisterAcpiTableGenerator (&FadtGenerator); > + DEBUG ((DEBUG_INFO, "FADT: Deregister Generator. Status =3D %r\n", > Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.in > f > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.in > f > new file mode 100644 > index > 0000000000000000000000000000000000000000..701cc8b019f564469fc > 1ec411ed11b367c48ff01 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.in > f > @@ -0,0 +1,41 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D AcpiGtdtLibArm > + FILE_GUID =3D 26490F7A-7FA2-423C-8939-C6206329BC37 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D NULL|DXE_DRIVER > + CONSTRUCTOR =3D AcpiGtdtLibConstructor > + DESTRUCTOR =3D AcpiGtdtLibDestructor > + > +[Sources] > + GtdtGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[FixedPcd] > + > +[Protocols] > + > +[Guids] > + > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..3bc34769346eeedb9c > 75ce76148d187b61b6fac1 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c > @@ -0,0 +1,670 @@ > +/** @file > + GTDT Table Generator > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Reference(s): > + - ACPI 6.2 Specification - Errata A, September 2017 > + > +**/ > + > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard GTDT Generator > + > +Requirements: > + The following Configuration Manager Object(s) are required by > + this Generator: > + - EArmObjGenericTimerInfo > + - EArmObjPlatformGenericWatchdogInfo (OPTIONAL) > + - EArmObjPlatformGTBlockInfo (OPTIONAL) > + - EArmObjGTBlockTimerFrameInfo (OPTIONAL) > +*/ > + > +/** This macro expands to a function that retrieves the Generic > + Timer Information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjGenericTimerInfo, > + CM_ARM_GENERIC_TIMER_INFO > + ); > + > +/** This macro expands to a function that retrieves the SBSA Generic > + Watchdog Timer Information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjPlatformGenericWatchdogInfo, > + CM_ARM_GENERIC_WATCHDOG_INFO > + ); > + > +/** This macro expands to a function that retrieves the Platform Generic > + Timer Block Information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjPlatformGTBlockInfo, > + CM_ARM_GTBLOCK_INFO > + ); > + > +/** This macro expands to a function that retrieves the Generic > + Timer Block Timer Frame Information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjGTBlockTimerFrameInfo, > + CM_ARM_GTBLOCK_TIMER_FRAME_INFO > + ); > + > +/** Add the Generic Timer Information to the GTDT table. > + > + Also update the Platform Timer offset information if the platform > + implements platform timers. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [in] Gtdt Pointer to the GTDT Table. > + @param [in] PlatformTimerCount Platform timer count. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +AddGenericTimerInfo ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE * CONST > Gtdt, > + IN CONST UINT32 PlatformTimerCount > +) > +{ > + EFI_STATUS Status; > + CM_ARM_GENERIC_TIMER_INFO * GenericTimerInfo; > + > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Gtdt !=3D NULL); > + > + Status =3D GetEArmObjGenericTimerInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &GenericTimerInfo, > + NULL > + ); > + > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to get GenericTimerInfo. Status =3D %r\n", > + Status > + )); > + return Status; > + } > + > + Gtdt->CntControlBasePhysicalAddress =3D > + GenericTimerInfo->CounterControlBaseAddress; > + Gtdt->Reserved =3D EFI_ACPI_RESERVED_DWORD; > + Gtdt->SecurePL1TimerGSIV =3D GenericTimerInfo->SecurePL1TimerGSIV; > + Gtdt->SecurePL1TimerFlags =3D GenericTimerInfo->SecurePL1TimerFlags; > + Gtdt->NonSecurePL1TimerGSIV =3D GenericTimerInfo- > >NonSecurePL1TimerGSIV; > + Gtdt->NonSecurePL1TimerFlags =3D GenericTimerInfo- > >NonSecurePL1TimerFlags; > + Gtdt->VirtualTimerGSIV =3D GenericTimerInfo->VirtualTimerGSIV; > + Gtdt->VirtualTimerFlags =3D GenericTimerInfo->VirtualTimerFlags; > + Gtdt->NonSecurePL2TimerGSIV =3D GenericTimerInfo- > >NonSecurePL2TimerGSIV; > + Gtdt->NonSecurePL2TimerFlags =3D GenericTimerInfo- > >NonSecurePL2TimerFlags; > + Gtdt->CntReadBasePhysicalAddress =3D > + GenericTimerInfo->CounterReadBaseAddress; > + Gtdt->PlatformTimerCount =3D PlatformTimerCount; > + Gtdt->PlatformTimerOffset =3D (PlatformTimerCount =3D=3D 0) ? 0 : > + sizeof (EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE); > + > + return EFI_SUCCESS; > +} > + > +/** Add the SBSA Generic Watchdog Timers to the GTDT table. > + > + @param [in] Gtdt Pointer to the GTDT Table. > + @param [in] WatchdogOffset Offset to the watchdog information in th= e > + GTDT Table. > + @param [in] WatchdogInfoList Pointer to the watchdog information list= . > + @param [in] WatchdogCount Platform timer count. > +*/ > +STATIC > +VOID > +AddGenericWatchdogList ( > + IN EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE * CONST Gtdt, > + IN CONST UINT32 WatchdogOffse= t, > + IN CONST CM_ARM_GENERIC_WATCHDOG_INFO * > WatchdogInfoList, > + IN UINT32 WatchdogCount > + ) > +{ > + EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE * > Watchdog; > + > + ASSERT (Gtdt !=3D NULL); > + ASSERT (WatchdogInfoList !=3D NULL); > + > + Watchdog =3D > (EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE *) > + ((UINT8*)Gtdt + WatchdogOffset); > + > + while (WatchdogCount-- !=3D 0) { > + // Add watchdog entry > + DEBUG ((DEBUG_INFO, "GTDT: Watchdog =3D 0x%p\n", Watchdog)); > + Watchdog->Type =3D EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG; > + Watchdog->Length =3D > + sizeof (EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE); > + Watchdog->Reserved =3D EFI_ACPI_RESERVED_BYTE; > + Watchdog->RefreshFramePhysicalAddress =3D > + WatchdogInfoList->RefreshFrameAddress; > + Watchdog->WatchdogControlFramePhysicalAddress =3D > + WatchdogInfoList->ControlFrameAddress; > + Watchdog->WatchdogTimerGSIV =3D WatchdogInfoList->TimerGSIV; > + Watchdog->WatchdogTimerFlags =3D WatchdogInfoList->Flags; > + Watchdog++; > + WatchdogInfoList++; > + } // for > +} > + > +/** Update the GT Block Timer Frame lists in the GTDT Table. > + > + @param [in] GtBlockFrame Pointer to the GT Block Frames > + list to be updated. > + @param [in] GTBlockTimerFrameList Pointer to the GT Block Frame > + Information List. > + @param [in] GTBlockFrameCount Number of GT Block Frames. > + > + @retval EFI_SUCCESS Table generated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > +*/ > +STATIC > +EFI_STATUS > +AddGTBlockTimerFrames ( > + IN EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCTURE * > GtBlockFrame, > + IN CONST CM_ARM_GTBLOCK_TIMER_FRAME_INFO * > GTBlockTimerFrameList, > + IN UINT32 GTBlockFra= meCount > +) > +{ > + ASSERT (GtBlockFrame !=3D NULL); > + ASSERT (GTBlockTimerFrameList !=3D NULL); > + > + if (GTBlockFrameCount > 8) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: GT Block Frame Count %d is greater than 8\n", > + GTBlockFrameCount > + )); > + ASSERT (GTBlockFrameCount <=3D 8); > + return EFI_INVALID_PARAMETER; > + } > + > + while (GTBlockFrameCount-- !=3D 0) { > + DEBUG (( > + DEBUG_INFO, > + "GTDT: GtBlockFrame =3D 0x%p\n", > + GtBlockFrame > + )); > + > + GtBlockFrame->GTFrameNumber =3D GTBlockTimerFrameList- > >FrameNumber; > + GtBlockFrame->Reserved[0] =3D EFI_ACPI_RESERVED_BYTE; > + GtBlockFrame->Reserved[1] =3D EFI_ACPI_RESERVED_BYTE; > + GtBlockFrame->Reserved[2] =3D EFI_ACPI_RESERVED_BYTE; > + > + GtBlockFrame->CntBaseX =3D GTBlockTimerFrameList- > >PhysicalAddressCntBase; > + GtBlockFrame->CntEL0BaseX =3D > + GTBlockTimerFrameList->PhysicalAddressCntEL0Base; > + > + GtBlockFrame->GTxPhysicalTimerGSIV =3D > + GTBlockTimerFrameList->PhysicalTimerGSIV; > + GtBlockFrame->GTxPhysicalTimerFlags =3D > + GTBlockTimerFrameList->PhysicalTimerFlags; > + > + GtBlockFrame->GTxVirtualTimerGSIV =3D GTBlockTimerFrameList- > >VirtualTimerGSIV; > + GtBlockFrame->GTxVirtualTimerFlags =3D > + GTBlockTimerFrameList->VirtualTimerFlags; > + > + GtBlockFrame->GTxCommonFlags =3D GTBlockTimerFrameList- > >CommonFlags; > + GtBlockFrame++; > + GTBlockTimerFrameList++; > + } // for > + return EFI_SUCCESS; > +} > + > +/** Add the GT Block Timers in the GTDT Table. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [in] Gtdt Pointer to the GTDT Table. > + @param [in] GTBlockOffset Offset of the GT Block > + information in the GTDT Table. > + @param [in] GTBlockInfo Pointer to the GT Block > + Information List. > + @param [in] BlockTimerCount Number of GT Block Timers. > + > + @retval EFI_SUCCESS Table generated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > +*/ > +STATIC > +EFI_STATUS > +AddGTBlockList ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE * CONST Gtdt, > + IN CONST UINT32 GTBlockOffset= , > + IN CONST CM_ARM_GTBLOCK_INFO * GTBlockInfo, > + IN UINT32 BlockTimerCou= nt > +) > +{ > + EFI_STATUS Status; > + EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE * GTBlock; > + EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCTURE * GtBlockFrame; > + CM_ARM_GTBLOCK_TIMER_FRAME_INFO * > GTBlockTimerFrameList; > + UINT32 GTBlockTimerFrameCount; > + > + ASSERT (Gtdt !=3D NULL); > + ASSERT (GTBlockInfo !=3D NULL); > + > + GTBlock =3D (EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE *)((UINT8*)Gtdt > + > + GTBlockOffset); > + > + while (BlockTimerCount-- !=3D 0) { > + DEBUG ((DEBUG_INFO, "GTDT: GTBlock =3D 0x%p\n", GTBlock)); > + > + Status =3D GetEArmObjGTBlockTimerFrameInfo ( > + CfgMgrProtocol, > + GTBlockInfo->GTBlockTimerFrameToken, > + >BlockTimerFrameList, > + >BlockTimerFrameCount > + ); > + if (EFI_ERROR (Status) || > + (GTBlockTimerFrameCount !=3D GTBlockInfo- > >GTBlockTimerFrameCount)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to get Generic Timer Frames. Status =3D %r\= n", > + Status > + )); > + return Status; > + } > + > + GTBlock->Type =3D EFI_ACPI_6_2_GTDT_GT_BLOCK; > + GTBlock->Length =3D sizeof (EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE) > + > + (sizeof (EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCT= URE) > * > + GTBlockInfo->GTBlockTimerFrameCount); > + > + GTBlock->Reserved =3D EFI_ACPI_RESERVED_BYTE; > + GTBlock->CntCtlBase =3D GTBlockInfo->GTBlockPhysicalAddress; > + GTBlock->GTBlockTimerCount =3D GTBlockInfo->GTBlockTimerFrameCount; > + GTBlock->GTBlockTimerOffset =3D > + sizeof (EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE); > + > + GtBlockFrame =3D (EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCTURE*) > + ((UINT8*)GTBlock + GTBlock->GTBlockTimerOffset); > + > + // Add GT Block Timer frames > + Status =3D AddGTBlockTimerFrames ( > + GtBlockFrame, > + GTBlockTimerFrameList, > + GTBlockTimerFrameCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to add Generic Timer Frames. Status =3D %r\= n", > + Status > + )); > + return Status; > + } > + > + // Next GTBlock > + GTBlock =3D (EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE > *)((UINT8*)GTBlock + > + GTBlock->Length); > + GTBlockInfo++; > + }// for > + return EFI_SUCCESS; > +} > + > +/** Construct the GTDT ACPI table. > + > + Called by the Dynamic Table Manager, 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 Info. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [out] Table Pointer to the constructed ACPI Table. > + > + @retval EFI_SUCCESS Table generated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +BuildGtdtTable ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + EFI_STATUS Status; > + UINT32 TableSize; > + UINT32 PlatformTimerCount =3D= 0; > + UINT32 WatchdogCount; > + UINT32 BlockTimerCount; > + CM_ARM_GENERIC_WATCHDOG_INFO * WatchdogInfoList; > + CM_ARM_GTBLOCK_INFO * GTBlockInfo; > + EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE * Gtdt; > + UINT32 idx; > + UINT32 GTBlockOffset; > + UINT32 WatchdogOffset =3D 0; > + > + ASSERT (This !=3D NULL); > + ASSERT (AcpiTableInfo !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Table !=3D NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTableSignat= ure); > + > + *Table =3D NULL; > + Status =3D GetEArmObjPlatformGTBlockInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + >BlockInfo, > + &BlockTimerCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to Get Platform GT Block Information." \ > + " Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Status =3D GetEArmObjPlatformGenericWatchdogInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &WatchdogInfoList, > + &WatchdogCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to Get Platform Generic Watchdog Information.= " > \ > + " Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "GTDT: BlockTimerCount =3D %d, WatchdogCount =3D %d\n", > + BlockTimerCount, > + WatchdogCount > + )); > + > + // Calculate the GTDT Table Size > + TableSize =3D sizeof (EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE); > + if (BlockTimerCount !=3D 0) { > + GTBlockOffset =3D TableSize; > + PlatformTimerCount +=3D BlockTimerCount; > + TableSize +=3D (sizeof (EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE) * > + BlockTimerCount); > + > + for (idx =3D 0; idx < BlockTimerCount; idx++) { > + if (GTBlockInfo[idx].GTBlockTimerFrameCount > 8) { > + Status =3D EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "GTDT: GTBockFrameCount cannot be more than 8." \ > + " GTBockFrameCount =3D %d, Status =3D %r\n", > + GTBlockInfo[idx].GTBlockTimerFrameCount, > + Status > + )); > + goto error_handler; > + } > + TableSize +=3D (sizeof > (EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCTURE) * > + GTBlockInfo[idx].GTBlockTimerFrameCount); > + } > + > + DEBUG (( > + DEBUG_INFO, > + "GTDT: GTBockOffset =3D 0x%x, PLATFORM_TIMER_COUNT =3D %d\n", > + GTBlockOffset, > + PlatformTimerCount > + )); > + } > + > + if (WatchdogCount !=3D 0) { > + WatchdogOffset =3D TableSize; > + PlatformTimerCount +=3D WatchdogCount; > + TableSize +=3D (sizeof > (EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE) * > + WatchdogCount); > + DEBUG (( > + DEBUG_INFO, > + "GTDT: WatchdogOffset =3D 0x%x, PLATFORM_TIMER_COUNT =3D %d\n", > + WatchdogOffset, > + PlatformTimerCount > + )); > + } > + > + *Table =3D (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize); > + if (*Table =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to allocate memory for GTDT Table, Size =3D %= d," \ > + " Status =3D %r\n", > + TableSize, > + Status > + )); > + goto error_handler; > + } > + > + Gtdt =3D (EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE*)*Table; > + DEBUG (( > + DEBUG_INFO, > + "GTDT: Gtdt =3D 0x%p TableSize =3D 0x%x\n", > + Gtdt, > + TableSize > + )); > + > + Status =3D AddAcpiHeader (CfgMgrProtocol, This, &Gtdt->Header, > TableSize); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to add ACPI header. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Status =3D AddGenericTimerInfo ( > + CfgMgrProtocol, > + Gtdt, > + PlatformTimerCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to add Generic Timer Info. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + if (BlockTimerCount !=3D 0) { > + Status =3D AddGTBlockList ( > + CfgMgrProtocol, > + Gtdt, > + GTBlockOffset, > + GTBlockInfo, > + BlockTimerCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to add GT Block timers. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + } > + > + if (WatchdogCount !=3D 0) { > + AddGenericWatchdogList ( > + Gtdt, > + WatchdogOffset, > + WatchdogInfoList, > + WatchdogCount > + ); > + } > + > + return Status; > + > +error_handler: > + if (*Table !=3D NULL) { > + FreePool (*Table); > + *Table =3D NULL; > + } > + return Status; > +} > + > +/** Free any resources allocated for constructing the GTDT. > + > + @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 > +FreeGtdtTableResources ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST > AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > +) > +{ > + 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->AcpiTableSignat= ure); > + > + if ((Table =3D=3D NULL) || (*Table =3D=3D NULL)) { > + DEBUG ((DEBUG_ERROR, "ERROR: GTDT: Invalid Table Pointer\n")); > + ASSERT ((Table !=3D NULL) && (*Table !=3D NULL)); > + return EFI_INVALID_PARAMETER; > + } > + > + FreePool (*Table); > + *Table =3D NULL; > + return EFI_SUCCESS; > +} > + > +/** This macro defines the GTDT Table Generator revision. > +*/ > +#define GTDT_GENERATOR_REVISION CREATE_REVISION (1, 0) > + > +/** The interface for the GTDT Table Generator. > +*/ > +STATIC > +CONST > +ACPI_TABLE_GENERATOR GtdtGenerator =3D { > + // Generator ID > + CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_GTDT), > + // Generator Description > + L"ACPI.STD.GTDT.GENERATOR", > + // ACPI Table Signature > + EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + GTDT_GENERATOR_REVISION, > + // Build Table function > + BuildGtdtTable, > + // Free Resource function > + FreeGtdtTableResources > +}; > + > +/** 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 > +AcpiGtdtLibConstructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D RegisterAcpiTableGenerator (&GtdtGenerator); > + DEBUG ((DEBUG_INFO, "GTDT: 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 > +AcpiGtdtLibDestructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D DeregisterAcpiTableGenerator (&GtdtGenerator); > + DEBUG ((DEBUG_INFO, "GTDT: Deregister Generator. Status =3D %r\n", > Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf > new file mode 100644 > index > 0000000000000000000000000000000000000000..1d77a3bb58cfa9643b > 4c1b47b83e1ab4e53d26cb > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf > @@ -0,0 +1,41 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D AcpiIortLibArm > + FILE_GUID =3D 25682BA8-B41D-4403-B034-253769E0DAD5 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D NULL|DXE_DRIVER > + CONSTRUCTOR =3D AcpiIortLibConstructor > + DESTRUCTOR =3D AcpiIortLibDestructor > + > +[Sources] > + IortGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > +[Protocols] > + > +[Guids] > + > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..cee960fba4e4c19a9c5 > 2f2c38e887741a074e2a9 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c > @@ -0,0 +1,2046 @@ > +/** @file > + IORT Table Generator > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Reference(s): > + - IO Remapping Table, Platform Design Document, > + Document number: ARM DEN 0049C, Issue C, 15 May 2017 > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > + > +#include "IortGenerator.h" > + > +/** ARM standard IORT Generator > + > +Requirements: > + The following Configuration Manager Object(s) are required by > + this Generator: > + - EArmObjItsGroup > + - EArmObjNamedComponent > + - EArmObjRootComplex > + - EArmObjSmmuV1SmmuV2 > + - EArmObjSmmuV3 > + - EArmObjPmcg > + - EArmObjGicItsIdentifierArray > + - EArmObjIdMapping > + - EArmObjGicItsIdentifierArray > +*/ > + > +/** This macro expands to a function that retrieves the ITS > + Group node information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjItsGroup, > + CM_ARM_ITS_GROUP_NODE > + ); > + > +/** This macro expands to a function that retrieves the > + Named Component node information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjNamedComponent, > + CM_ARM_NAMED_COMPONENT_NODE > + ); > + > +/** This macro expands to a function that retrieves the > + Root Complex node information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjRootComplex, > + CM_ARM_ROOT_COMPLEX_NODE > + ); > + > +/** This macro expands to a function that retrieves the > + SMMU v1/v2 node information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjSmmuV1SmmuV2, > + CM_ARM_SMMUV1_SMMUV2_NODE > + ); > + > +/** This macro expands to a function that retrieves the > + SMMU v3 node information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjSmmuV3, > + CM_ARM_SMMUV3_NODE > + ); > + > +/** This macro expands to a function that retrieves the > + PMCG node information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjPmcg, > + CM_ARM_PMCG_NODE > + ); > + > +/** This macro expands to a function that retrieves the > + ITS Identifier Array information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjGicItsIdentifierArray, > + CM_ARM_ITS_IDENTIFIER > + ); > + > +/** This macro expands to a function that retrieves the > + Id Mapping Array information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjIdMapping, > + CM_ARM_ID_MAPPING > + ); > + > +/** This macro expands to a function that retrieves the > + SMMU Interrupt Array information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjSmmuInterruptArray, > + CM_ARM_SMMU_INTERRUPT > + ); > + > +/** Returns the size of the ITS Group node. > + > + @param [in] Node Pointer to ITS Group node. > + > + @retval Size of the ITS Group Node. > +*/ > +STATIC > +UINT32 > +GetItsGroupNodeSize ( > + IN CONST CM_ARM_ITS_GROUP_NODE * Node > + ) > +{ > + ASSERT (Node !=3D NULL); > + > + // Size of ITS Group Node > + UINT32 Size =3D sizeof (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE); > + > + // Size of ITS Identifier array > + Size +=3D (Node->ItsIdCount * sizeof (UINT32)); > + return Size; > +} > + > +/** Returns the total size required for the ITS Group 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 ITS Group node list. > + @param [in] NodeCount Count of the ITS Group nodes. > + @param [in, out] NodeIndexer Pointer to the next Node Indexer. > + > + @retval Total size of the ITS Group Nodes. > +*/ > +STATIC > +UINT32 > +GetSizeofItsGroupNodes ( > + IN CONST UINT32 NodeStartOffset, > + IN CONST CM_ARM_ITS_GROUP_NODE * NodeList, > + IN UINT32 NodeCount, > + IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer > + ) > +{ > + UINT32 Size =3D 0; > + > + ASSERT (NodeList !=3D NULL); > + > + while (NodeCount-- !=3D 0) { > + (*NodeIndexer)->Token =3D NodeList->Token; > + (*NodeIndexer)->Object =3D (VOID*)NodeList; > + (*NodeIndexer)->Offset =3D Size + NodeStartOffset; > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset = =3D 0x%x\n", > + *NodeIndexer, > + (*NodeIndexer)->Token, > + (*NodeIndexer)->Object, > + (*NodeIndexer)->Offset > + )); > + > + Size +=3D GetItsGroupNodeSize (NodeList); > + (*NodeIndexer)++; > + NodeList++; > + } > + return Size; > +} > + > +/** Returns the size of the Named Component node. > + > + @param [in] Node Pointer to Named Component node. > + > + @retval Size of the Named Component node. > +*/ > +STATIC > +UINT32 > +GetNamedComponentNodeSize ( > + IN CONST CM_ARM_NAMED_COMPONENT_NODE * Node > + ) > +{ > + ASSERT (Node !=3D NULL); > + > + // Size of Named Component node > + UINT32 Size =3D sizeof > (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE); > + > + // Size of ID mapping array > + Size +=3D (Node->IdMappingCount * sizeof > (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE)); > + > + /* Size of ASCII string + NULL termination + 'padding to > + 32-bit word aligned'. > + */ > + Size +=3D ALIGN32 (AsciiStrLen (Node->ObjectName) + 1); > + return Size; > +} > + > +/** Returns the total size required for the Named Component 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 Named Component node li= st. > + @param [in] NodeCount Count of the Named Component nodes= . > + @param [in, out] NodeIndexer Pointer to the next Node Indexer. > + > + @retval Total size of the Named Component nodes. > +*/ > +STATIC > +UINT32 > +GetSizeofNamedComponentNodes ( > + IN CONST UINT32 NodeStartOffset, > + IN CONST CM_ARM_NAMED_COMPONENT_NODE * NodeList, > + IN UINT32 NodeCount, > + IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer > + ) > +{ > + UINT32 Size =3D 0; > + > + ASSERT (NodeList !=3D NULL); > + > + while (NodeCount-- !=3D 0) { > + (*NodeIndexer)->Token =3D NodeList->Token; > + (*NodeIndexer)->Object =3D (VOID*)NodeList; > + (*NodeIndexer)->Offset =3D Size + NodeStartOffset; > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset = =3D 0x%x\n", > + *NodeIndexer, > + (*NodeIndexer)->Token, > + (*NodeIndexer)->Object, > + (*NodeIndexer)->Offset > + )); > + > + Size +=3D GetNamedComponentNodeSize (NodeList); > + (*NodeIndexer)++; > + NodeList++; > + } > + > + return Size; > +} > + > +/** Returns the size of the Root Complex node. > + > + @param [in] Node Pointer to Root Complex node. > + > + @retval Size of the Root Complex node. > +*/ > +STATIC > +UINT32 > +GetRootComplexNodeSize ( > + IN CONST CM_ARM_ROOT_COMPLEX_NODE * Node > + ) > +{ > + ASSERT (Node !=3D NULL); > + > + // Size of Root Complex node > + UINT32 Size =3D sizeof (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE); > + > + // Size of ID mapping array > + Size +=3D (Node->IdMappingCount * > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE)); > + return Size; > +} > + > +/** Returns the total size required for the Root Complex 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 Root Complex node list. > + @param [in] NodeCount Count of the Root Complex nodes. > + @param [in, out] NodeIndexer Pointer to the next Node Indexer. > + > + @retval Total size of the Root Complex nodes. > +*/ > +STATIC > +UINT32 > +GetSizeofRootComplexNodes ( > + IN CONST UINT32 NodeStartOffset, > + IN CONST CM_ARM_ROOT_COMPLEX_NODE * NodeList, > + IN UINT32 NodeCount, > + IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer > + ) > +{ > + UINT32 Size =3D 0; > + > + ASSERT (NodeList !=3D NULL); > + > + while (NodeCount-- !=3D 0) { > + (*NodeIndexer)->Token =3D NodeList->Token; > + (*NodeIndexer)->Object =3D (VOID*)NodeList; > + (*NodeIndexer)->Offset =3D Size + NodeStartOffset; > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset = =3D 0x%x\n", > + *NodeIndexer, > + (*NodeIndexer)->Token, > + (*NodeIndexer)->Object, > + (*NodeIndexer)->Offset > + )); > + > + Size +=3D GetRootComplexNodeSize (NodeList); > + (*NodeIndexer)++; > + NodeList++; > + } > + > + return Size; > +} > + > +/** Returns the size of the SMMUv1/SMMUv2 node. > + > + @param [in] Node Pointer to SMMUv1/SMMUv2 node list. > + > + @retval Size of the SMMUv1/SMMUv2 node. > +*/ > +STATIC > +UINT32 > +GetSmmuV1V2NodeSize ( > + IN CONST CM_ARM_SMMUV1_SMMUV2_NODE * Node > + ) > +{ > + ASSERT (Node !=3D NULL); > + > + // Size of SMMU v1/SMMU v2 node > + UINT32 Size =3D sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE); > + > + // Size of ID mapping array > + Size +=3D (Node->IdMappingCount * > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE)); > + > + // Size of context interrupt array > + Size +=3D (Node->ContextInterruptCount * > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT)); > + > + // Size of PMU interrupt array > + Size +=3D (Node->PmuInterruptCount * > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT)); > + return Size; > +} > + > +/** Returns the total size required for the SMMUv1/SMMUv2 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 SMMUv1/SMMUv2 node list= . > + @param [in] NodeCount Count of the SMMUv1/SMMUv2 nodes. > + @param [in, out] NodeIndexer Pointer to the next Node Indexer. > + > + @retval Total size of the SMMUv1/SMMUv2 nodes. > +*/ > +STATIC > +UINT32 > +GetSizeofSmmuV1V2Nodes ( > + IN CONST UINT32 NodeStartOffset, > + IN CONST CM_ARM_SMMUV1_SMMUV2_NODE * NodeList, > + IN UINT32 NodeCount, > + IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer > + ) > +{ > + UINT32 Size =3D 0; > + > + ASSERT (NodeList !=3D NULL); > + > + while (NodeCount-- !=3D 0) { > + (*NodeIndexer)->Token =3D NodeList->Token; > + (*NodeIndexer)->Object =3D (VOID*)NodeList; > + (*NodeIndexer)->Offset =3D Size + NodeStartOffset; > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset = =3D 0x%x\n", > + *NodeIndexer, > + (*NodeIndexer)->Token, > + (*NodeIndexer)->Object, > + (*NodeIndexer)->Offset > + )); > + > + Size +=3D GetSmmuV1V2NodeSize (NodeList); > + (*NodeIndexer)++; > + NodeList++; > + } > + return Size; > +} > + > +/** Returns the size of the SMMUv3 node. > + > + @param [in] Node Pointer to SMMUv3 node list. > + > + @retval Total size of the SMMUv3 nodes. > +*/ > +STATIC > +UINT32 > +GetSmmuV3NodeSize ( > + IN CONST CM_ARM_SMMUV3_NODE * Node > + ) > +{ > + ASSERT (Node !=3D NULL); > + > + // Size of SMMU v1/SMMU v2 node > + UINT32 Size =3D sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE); > + > + // Size of ID mapping array > + Size +=3D (Node->IdMappingCount * > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE)); > + return Size; > +} > + > +/** Returns the total size required for the SMMUv3 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 SMMUv3 node list. > + @param [in] NodeCount Count of the SMMUv3 nodes. > + @param [in, out] NodeIndexer Pointer to the next Node Indexer. > + > + @retval Total size of the SMMUv3 nodes. > +*/ > +STATIC > +UINT32 > +GetSizeofSmmuV3Nodes ( > + IN CONST UINT32 NodeStartOffset, > + IN CONST CM_ARM_SMMUV3_NODE * NodeList, > + IN UINT32 NodeCount, > + IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer > + ) > +{ > + UINT32 Size =3D 0; > + > + ASSERT (NodeList !=3D NULL); > + > + while (NodeCount-- !=3D 0) { > + (*NodeIndexer)->Token =3D NodeList->Token; > + (*NodeIndexer)->Object =3D (VOID*)NodeList; > + (*NodeIndexer)->Offset =3D Size + NodeStartOffset; > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset = =3D 0x%x\n", > + *NodeIndexer, > + (*NodeIndexer)->Token, > + (*NodeIndexer)->Object, > + (*NodeIndexer)->Offset > + )); > + > + Size +=3D GetSmmuV3NodeSize (NodeList); > + (*NodeIndexer)++; > + NodeList++; > + } > + return Size; > +} > + > +/** Returns the size of the PMCG node. > + > + @param [in] Node Pointer to PMCG node. > + > + @retval Size of the PMCG node. > +*/ > +STATIC > +UINT32 > +GetPmcgNodeSize ( > + IN CONST CM_ARM_PMCG_NODE * Node > + ) > +{ > + ASSERT (Node !=3D NULL); > + > + // Size of PMCG node > + UINT32 Size =3D sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE); > + > + // Size of ID mapping array > + Size +=3D (Node->IdMappingCount * > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE)); > + return Size; > +} > + > +/** Returns the total size required for the PMCG 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 PMCG node list. > + @param [in] NodeCount Count of the PMCG nodes. > + @param [in, out] NodeIndexer Pointer to the next Node Indexer. > + > + @retval Total size of the PMCG nodes. > +*/ > +STATIC > +UINT32 > +GetSizeofPmcgNodes ( > + IN CONST UINT32 NodeStartOffset, > + IN CONST CM_ARM_PMCG_NODE * NodeList, > + IN UINT32 NodeCount, > + IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer > + ) > +{ > + UINT32 Size =3D 0; > + > + ASSERT (NodeList !=3D NULL); > + > + while (NodeCount-- !=3D 0) { > + (*NodeIndexer)->Token =3D NodeList->Token; > + (*NodeIndexer)->Object =3D (VOID*)NodeList; > + (*NodeIndexer)->Offset =3D Size + NodeStartOffset; > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer =3D %p, Token =3D %p, Object =3D %p, Offset = =3D 0x%x\n", > + *NodeIndexer, > + (*NodeIndexer)->Token, > + (*NodeIndexer)->Object, > + (*NodeIndexer)->Offset > + )); > + > + Size +=3D GetPmcgNodeSize (NodeList); > + (*NodeIndexer)++; > + NodeList++; > + } > + return Size; > +} > + > +/** Returns the offset of the Node referenced by the Token. > + > + @param [in] NodeIndexer Pointer to node indexer array. > + @param [in] NodeCount Count of the nodes. > + @param [in] Token Reference token for the node. > + @param [out] NodeOffset Offset of the node from the > + start of the IORT table. > + > + @retval EFI_SUCCESS Success. > + @retval EFI_NOT_FOUND No matching token reference > + found in node indexer array. > +*/ > +STATIC > +EFI_STATUS > +GetNodeOffsetReferencedByToken ( > + IN IORT_NODE_INDEXER * NodeIndexer, > + IN UINT32 NodeCount, > + IN CM_OBJECT_TOKEN Token, > + OUT UINT32 * NodeOffset > + ) > +{ > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer: Search Token =3D %p\n", > + Token > + )); > + while (NodeCount-- !=3D 0) { > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer: NodeIndexer->Token =3D %p, Offset =3D %d\n", > + NodeIndexer->Token, > + NodeIndexer->Offset > + )); > + if (NodeIndexer->Token =3D=3D Token) { > + *NodeOffset =3D NodeIndexer->Offset; > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer: Token =3D %p, Found\n", > + Token > + )); > + return EFI_SUCCESS; > + } > + NodeIndexer++; > + } > + DEBUG (( > + DEBUG_INFO, > + "IORT: Node Indexer: Token =3D %p, Not Found\n", > + Token > + )); > + return EFI_NOT_FOUND; > +} > + > +/** Update the Id Mapping Array. > + > + This function retrieves the Id Mapping Array object referenced by th= e > + IdMappingToken and updates the IdMapArray. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manage= r > + Protocol Interface. > + @param [in] IdMapArray Pointer to an array of Id Mappings. > + @param [in] IdCount Number of Id Mappings. > + @param [in] IdMappingToken Reference Token for retrieving the > + Id Mapping Array object. > + > + @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 > +AddIdMappingArray ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray, > + IN UINT32 IdCount, > + IN CONST CM_OBJECT_TOKEN IdMappingTo= ken > + ) > +{ > + EFI_STATUS Status; > + CM_ARM_ID_MAPPING * IdMappings; > + UINT32 IdMappingCount; > + ACPI_IORT_GENERATOR * Generator =3D (ACPI_IORT_GENERATOR*)This; > + > + ASSERT (IdMapArray !=3D NULL); > + > + // Get the Id Mapping Array > + Status =3D GetEArmObjIdMapping ( > + CfgMgrProtocol, > + IdMappingToken, > + &IdMappings, > + &IdMappingCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get Id Mapping array. Status =3D %r\n", > + Status > + )); > + return Status; > + } > + > + if (IdMappingCount < IdCount) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get the required number of Id Mappings.\n" > + )); > + return EFI_NOT_FOUND; > + } > + > + // Populate the Id Mapping array > + while (IdCount-- !=3D 0) { > + Status =3D GetNodeOffsetReferencedByToken ( > + Generator->NodeIndexer, > + Generator->IortNodeCount, > + IdMappings->OutputReferenceToken, > + &IdMapArray->OutputReference > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get Output Reference for ITS Identifier = array." > + "Reference Token =3D %p" > + " Status =3D %r\n", > + IdMappings->OutputReferenceToken, > + Status > + )); > + return Status; > + } > + > + IdMapArray->InputBase =3D IdMappings->InputBase; > + IdMapArray->NumIds =3D IdMappings->NumIds; > + IdMapArray->OutputBase =3D IdMappings->OutputBase; > + IdMapArray->Flags =3D IdMappings->Flags; > + > + IdMapArray++; > + IdMappings++; > + } // Id Mapping array > + > + return EFI_SUCCESS; > +} > + > +/** Update the ITS Group Node Information. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manage= r > + Protocol Interface. > + @param [in] Iort Pointer to IORT table structure. > + @param [in] NodesStartOffset Offset for the start of the ITS Gro= up > + Nodes. > + @param [in] NodeList Pointer to an array of ITS Group No= de > + Objects. > + @param [in] NodeCount Number of ITS 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 > +AddItsGroupNodes ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, > + IN CONST UINT32 NodesStartOffset= , > + IN CONST CM_ARM_ITS_GROUP_NODE * NodeList, > + IN UINT32 NodeCount > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE * ItsGroupNode; > + UINT32 * ItsIds; > + CM_ARM_ITS_IDENTIFIER * ItsIdentifier; > + UINT32 ItsIdentifierCount; > + UINT32 IdIndex; > + > + ASSERT (Iort !=3D NULL); > + > + ItsGroupNode =3D > (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE*)((UINT8*)Iort + > + NodesStartOffset); > + > + while (NodeCount-- !=3D 0) { > + // Populate the node header > + ItsGroupNode->Node.Type =3D EFI_ACPI_IORT_TYPE_ITS_GROUP; > + ItsGroupNode->Node.Length =3D GetItsGroupNodeSize (NodeList); > + ItsGroupNode->Node.Revision =3D 0; > + ItsGroupNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; > + ItsGroupNode->Node.NumIdMappings =3D 0; > + ItsGroupNode->Node.IdReference =3D 0; > + > + // IORT specific data > + ItsGroupNode->NumItsIdentifiers =3D NodeList->ItsIdCount; > + ItsIds =3D (UINT32*)((UINT8*)ItsGroupNode + > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE)); > + > + Status =3D GetEArmObjGicItsIdentifierArray ( > + CfgMgrProtocol, > + NodeList->ItsIdToken, > + &ItsIdentifier, > + &ItsIdentifierCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get ITS Identifier array. Status =3D %r\= n", > + Status > + )); > + return Status; > + } > + > + if (ItsIdentifierCount < ItsGroupNode->NumItsIdentifiers) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get the required number of ITS Identifie= rs.\n" > + )); > + return EFI_NOT_FOUND; > + } > + > + // Populate the ITS identifier array > + for (IdIndex =3D 0; IdIndex < ItsGroupNode->NumItsIdentifiers; IdInd= ex++) > { > + ItsIds[IdIndex] =3D ItsIdentifier[IdIndex].ItsId; > + } // ITS identifier array > + > + // Next IORT Group Node > + ItsGroupNode =3D > (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE*)((UINT8*)ItsGroupNode + > + ItsGroupNode->Node.Length); > + NodeList++; > + } // IORT Group Node > + > + return EFI_SUCCESS; > +} > + > +/** Update the Named Component Node Information. > + > + This function updates the Named Component node information in the > IORT > + table. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manage= r > + Protocol Interface. > + @param [in] Iort Pointer to IORT table structure. > + @param [in] NodesStartOffset Offset for the start of the Named > + Component Nodes. > + @param [in] NodeList Pointer to an array of Named Compon= ent > + Node Objects. > + @param [in] NodeCount Number of Named Component 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 > +AddNamedComponentNodes ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, > + IN CONST UINT32 NodesStartO= ffset, > + IN CONST CM_ARM_NAMED_COMPONENT_NODE * NodeList, > + IN UINT32 NodeCount > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE * NcNode; > + EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray; > + UINT32 ObjectNameLenght; > + CHAR8 * ObjectName; > + > + ASSERT (Iort !=3D NULL); > + > + NcNode =3D > (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE*)((UINT8*)Iort + > + NodesStartOffset); > + > + while (NodeCount-- !=3D 0) { > + // Populate the node header > + NcNode->Node.Type =3D EFI_ACPI_IORT_TYPE_NAMED_COMP; > + NcNode->Node.Length =3D > + GetNamedComponentNodeSize (NodeList); > + NcNode->Node.Revision =3D 1; > + NcNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; > + NcNode->Node.NumIdMappings =3D NodeList->IdMappingCount; > + > + ObjectNameLenght =3D AsciiStrLen (NodeList->ObjectName) + 1; > + NcNode->Node.IdReference =3D > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE) + > + (ALIGN32 (ObjectNameLenght)); > + > + // Named Component specific data > + NcNode->Flags =3D NodeList->Flags; > + NcNode->CacheCoherent =3D NodeList->CacheCoherent; > + NcNode->AllocationHints =3D NodeList->AllocationHints; > + NcNode->Reserved =3D EFI_ACPI_RESERVED_WORD; > + NcNode->MemoryAccessFlags =3D NodeList->MemoryAccessFlags; > + NcNode->AddressSizeLimit =3D NodeList->AddressSizeLimit; > + > + // Copy the object name > + ObjectName =3D (CHAR8*)((UINT8*)NcNode + > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE)); > + Status =3D AsciiStrCpyS ( > + ObjectName, > + ObjectNameLenght, > + NodeList->ObjectName > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to copy Object Name. Status =3D %r\n", > + Status > + )); > + return Status; > + } > + > + if ((NodeList->IdMappingCount > 0) && > + (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { > + // Ids for Named Component > + IdMapArray =3D > (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)NcNode + > + NcNode->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; > + } > + } > + > + // Next Named Component Node > + NcNode =3D > (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE*)((UINT8*)NcNode > + > + NcNode->Node.Length); > + NodeList++; > + } // Named Component Node > + > + return EFI_SUCCESS; > +} > + > +/** Update the Root Complex Node Information. > + > + This function updates the Root Complex node information in the IORT > table. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manage= r > + Protocol Interface. > + @param [in] Iort Pointer to IORT table structure. > + @param [in] NodesStartOffset Offset for the start of the Root > Complex > + Nodes. > + @param [in] NodeList Pointer to an array of Root Complex= Node > + Objects. > + @param [in] NodeCount Number of Root Complex 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 > +AddRootComplexNodes ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, > + IN CONST UINT32 NodesStartO= ffset, > + IN CONST CM_ARM_ROOT_COMPLEX_NODE * NodeList, > + IN UINT32 NodeCount > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_6_0_IO_REMAPPING_RC_NODE * RcNode; > + EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray; > + > + ASSERT (Iort !=3D NULL); > + > + RcNode =3D (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE*)((UINT8*)Iort + > + NodesStartOffset); > + > + while (NodeCount-- !=3D 0) { > + // Populate the node header > + RcNode->Node.Type =3D EFI_ACPI_IORT_TYPE_ROOT_COMPLEX; > + RcNode->Node.Length =3D GetRootComplexNodeSize (NodeList); > + RcNode->Node.Revision =3D 0; > + RcNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; > + RcNode->Node.NumIdMappings =3D NodeList->IdMappingCount; > + RcNode->Node.IdReference =3D sizeof > (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE); > + > + // Root Complex specific data > + RcNode->CacheCoherent =3D NodeList->CacheCoherent; > + RcNode->AllocationHints =3D NodeList->AllocationHints; > + RcNode->Reserved =3D EFI_ACPI_RESERVED_WORD; > + RcNode->MemoryAccessFlags =3D NodeList->MemoryAccessFlags; > + RcNode->AtsAttribute =3D NodeList->AtsAttribute; > + RcNode->PciSegmentNumber =3D NodeList->PciSegmentNumber; > + > + if ((NodeList->IdMappingCount > 0) && > + (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { > + // Ids for Root Complex > + IdMapArray =3D > (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)RcNode + > + RcNode->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; > + } > + } > + > + // Next Root Complex Node > + RcNode =3D (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE*)((UINT8*)RcNode > + > + RcNode->Node.Length); > + NodeList++; > + } // Root Complex Node > + > + return EFI_SUCCESS; > +} > + > +/** Update the SMMU Interrupt Array. > + > + This function retrieves the InterruptArray object referenced by the > + InterruptToken and updates the SMMU InterruptArray. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manage= r > + Protocol Interface. > + @param [in] InterruptArray Pointer to an array of Interrupts. > + @param [in] InterruptCount Number of entries in the InterruptA= rray. > + @param [in] InterruptToken Reference Token for retrieving the > SMMU > + InterruptArray object. > + > + @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 > +AddSmmuInterrruptArray ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN OUT EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT * > InterruptArray, > + IN UINT32 InterruptCount, > + IN CONST CM_OBJECT_TOKEN InterruptToken > + ) > +{ > + EFI_STATUS Status; > + CM_ARM_SMMU_INTERRUPT * SmmuInterrupt; > + UINT32 SmmuInterruptCount; > + > + ASSERT (InterruptArray !=3D NULL); > + > + // Get the SMMU Interrupt Array > + Status =3D GetEArmObjSmmuInterruptArray ( > + CfgMgrProtocol, > + InterruptToken, > + &SmmuInterrupt, > + &SmmuInterruptCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get SMMU Interrupt array. Status =3D %r\n"= , > + Status > + )); > + return Status; > + } > + > + if (SmmuInterruptCount < InterruptCount) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get the required number of SMMU > Interrupts.\n" > + )); > + return EFI_NOT_FOUND; > + } > + > + // Populate the Id Mapping array > + while (InterruptCount-- !=3D 0) { > + InterruptArray->Interrupt =3D SmmuInterrupt->Interrupt; > + InterruptArray->InterruptFlags =3D SmmuInterrupt->Flags; > + InterruptArray++; > + SmmuInterrupt++; > + } // Id Mapping array > + > + return EFI_SUCCESS; > +} > + > +/** Update the SMMU v1/v2 Node Information. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manage= r > + Protocol Interface. > + @param [in] Iort Pointer to IORT table structure. > + @param [in] NodesStartOffset Offset for the start of the SMMU v1= /v2 > + Nodes. > + @param [in] NodeList Pointer to an array of SMMU v1/v2 N= ode > + Objects. > + @param [in] NodeCount Number of SMMU v1/v2 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 > +AddSmmuV1V2Nodes ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, > + IN CONST UINT32 NodesStartOffset, > + IN CONST CM_ARM_SMMUV1_SMMUV2_NODE * NodeList, > + IN UINT32 NodeCount > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE * SmmuNode; > + EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray; > + > + EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT * ContextInterruptArray; > + EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT * PmuInterruptArray; > + > + ASSERT (Iort !=3D NULL); > + > + SmmuNode =3D > (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE*)((UINT8*)Iort + > + NodesStartOffset); > + > + while (NodeCount-- !=3D 0) { > + // Populate the node header > + SmmuNode->Node.Type =3D EFI_ACPI_IORT_TYPE_SMMUv1v2; > + SmmuNode->Node.Length =3D GetSmmuV1V2NodeSize (NodeList); > + SmmuNode->Node.Revision =3D 0; > + SmmuNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; > + SmmuNode->Node.NumIdMappings =3D NodeList->IdMappingCount; > + SmmuNode->Node.IdReference =3D sizeof > (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE) + > + (NodeList->ContextInterruptCount * > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT)) + > + (NodeList->PmuInterruptCount * > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT)); > + > + // SMMU v1/v2 specific data > + SmmuNode->Base =3D NodeList->BaseAddress; > + SmmuNode->Span =3D NodeList->Span; > + SmmuNode->Model =3D NodeList->Model; > + SmmuNode->Flags =3D NodeList->Flags; > + > + // Reference to Global Interrupt Array > + SmmuNode->GlobalInterruptArrayRef =3D > + OFFSET_OF (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE, > SMMU_NSgIrpt); > + > + // Context Interrupt > + SmmuNode->NumContextInterrupts =3D NodeList- > >ContextInterruptCount; > + SmmuNode->ContextInterruptArrayRef =3D > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE); > + ContextInterruptArray =3D > + (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT*)((UINT8*)SmmuNode + > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE)); > + > + // PMU Interrupt > + SmmuNode->NumPmuInterrupts =3D NodeList->PmuInterruptCount; > + SmmuNode->PmuInterruptArrayRef =3D SmmuNode- > >ContextInterruptArrayRef + > + (NodeList->ContextInterruptCount * > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT)); > + PmuInterruptArray =3D > + (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT*)((UINT8*)SmmuNode + > + SmmuNode->PmuInterruptArrayRef); > + > + SmmuNode->SMMU_NSgIrpt =3D NodeList->SMMU_NSgIrpt; > + SmmuNode->SMMU_NSgIrptFlags =3D NodeList->SMMU_NSgIrptFlags; > + SmmuNode->SMMU_NSgCfgIrpt =3D NodeList->SMMU_NSgCfgIrpt; > + SmmuNode->SMMU_NSgCfgIrptFlags =3D NodeList- > >SMMU_NSgCfgIrptFlags; > + > + // Add Context Interrupt Array > + Status =3D AddSmmuInterrruptArray ( > + CfgMgrProtocol, > + ContextInterruptArray, > + SmmuNode->NumContextInterrupts, > + NodeList->ContextInterruptToken > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to Context Interrupt Array. Status =3D %r\n= ", > + Status > + )); > + return Status; > + } > + > + // Add PMU Interrupt Array > + if ((SmmuNode->NumPmuInterrupts > 0) && > + (NodeList->PmuInterruptToken !=3D CM_NULL_TOKEN)) { > + Status =3D AddSmmuInterrruptArray ( > + CfgMgrProtocol, > + PmuInterruptArray, > + SmmuNode->NumPmuInterrupts, > + NodeList->PmuInterruptToken > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to PMU Interrupt Array. Status =3D %r\n", > + Status > + )); > + return Status; > + } > + } > + > + if ((NodeList->IdMappingCount > 0) && > + (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { > + // Ids for SMMU v1/v2 Node > + IdMapArray =3D > (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)SmmuNode + > + SmmuNode->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; > + } > + } > + // Next SMMU v1/v2 Node > + SmmuNode =3D > (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE*)((UINT8*)SmmuNode + > + SmmuNode->Node.Length); > + NodeList++; > + } // SMMU v1/v2 Node > + > + return EFI_SUCCESS; > +} > + > +/** Update the SMMUv3 Node Information. > + > + This function updates the SMMUv3 node information in the IORT table. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manage= r > + Protocol Interface. > + @param [in] Iort Pointer to IORT table structure. > + @param [in] NodesStartOffset Offset for the start of the SMMUv3 > Nodes. > + @param [in] NodeList Pointer to an array of SMMUv3 Node > Objects. > + @param [in] NodeCount Number of SMMUv3 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 > +AddSmmuV3Nodes ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, > + IN CONST UINT32 NodesStartO= ffset, > + IN CONST CM_ARM_SMMUV3_NODE * NodeList, > + IN UINT32 NodeCount > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE * SmmuV3Node; > + EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray; > + > + ASSERT (Iort !=3D NULL); > + > + SmmuV3Node =3D > (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE*)((UINT8*)Iort + > + NodesStartOffset); > + > + while (NodeCount-- !=3D 0) { > + // Populate the node header > + SmmuV3Node->Node.Type =3D EFI_ACPI_IORT_TYPE_SMMUv3; > + SmmuV3Node->Node.Length =3D GetSmmuV3NodeSize (NodeList); > + SmmuV3Node->Node.Revision =3D 1; > + SmmuV3Node->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; > + SmmuV3Node->Node.NumIdMappings =3D NodeList->IdMappingCount; > + SmmuV3Node->Node.IdReference =3D > + sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE); > + > + // SMMUv3 specific data > + SmmuV3Node->Base =3D NodeList->BaseAddress; > + SmmuV3Node->Flags =3D NodeList->Flags; > + SmmuV3Node->Reserved =3D EFI_ACPI_RESERVED_WORD; > + SmmuV3Node->VatosAddress =3D NodeList->VatosAddress; > + SmmuV3Node->Model =3D NodeList->Model; > + SmmuV3Node->Event =3D NodeList->EventInterrupt; > + SmmuV3Node->Pri =3D NodeList->PriInterrupt; > + SmmuV3Node->Gerr =3D NodeList->GerrInterrupt; > + SmmuV3Node->Sync =3D NodeList->SyncInterrupt; > + > + if ((SmmuV3Node->Flags & > EFI_ACPI_IORT_SMMUv3_FLAG_PROXIMITY_DOMAIN) !=3D 0) { > + // The Proximity Domain Valid flag is set to 1 > + SmmuV3Node->ProximityDomain =3D NodeList->ProximityDomain; > + } else { > + SmmuV3Node->ProximityDomain =3D 0; > + } > + > + SmmuV3Node->Reserved1[0] =3D EFI_ACPI_RESERVED_BYTE; > + SmmuV3Node->Reserved1[1] =3D EFI_ACPI_RESERVED_BYTE; > + SmmuV3Node->Reserved1[2] =3D EFI_ACPI_RESERVED_BYTE; > + > + if ((SmmuV3Node->Event !=3D 0) && (SmmuV3Node->Pri !=3D 0) && > + (SmmuV3Node->Gerr !=3D 0) && (SmmuV3Node->Sync !=3D 0)) { > + // If all the SMMU control interrupts are GSIV based, > + // the DeviceID mapping index field is ignored. > + SmmuV3Node->DeviceIdMappingIndex =3D 0; > + } else { > + SmmuV3Node->DeviceIdMappingIndex =3D NodeList- > >DeviceIdMappingIndex; > + } > + > + if ((NodeList->IdMappingCount > 0) && > + (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { > + // Ids for SMMUv3 node > + IdMapArray =3D > (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)SmmuV3Node + > + SmmuV3Node->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; > + } > + } > + > + // Next SMMUv3 Node > + SmmuV3Node =3D > (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE*)((UINT8*)SmmuV3Node > + > + SmmuV3Node->Node.Length); > + NodeList++; > + } // SMMUv3 Node > + > + return EFI_SUCCESS; > +} > + > +/** Update the PMCG Node Information. > + > + This function updates the PMCG node information in the IORT table. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manage= r > + Protocol Interface. > + @param [in] Iort Pointer to IORT table structure. > + @param [in] NodesStartOffset Offset for the start of the PMCG No= des. > + @param [in] NodeList Pointer to an array of PMCG Node Ob= jects. > + @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 > +AddPmcgNodes ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort, > + IN CONST UINT32 NodesStartO= ffset, > + IN CONST CM_ARM_PMCG_NODE * NodeList, > + IN UINT32 NodeCount > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE * PmcgNode; > + EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray; > + ACPI_IORT_GENERATOR * Generator =3D > (ACPI_IORT_GENERATOR*)This; > + > + ASSERT (Iort !=3D NULL); > + > + PmcgNode =3D > (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE*)((UINT8*)Iort + > + NodesStartOffset); > + > + while (NodeCount-- !=3D 0) { > + // Populate the node header > + PmcgNode->Node.Type =3D EFI_ACPI_IORT_TYPE_PMCG; > + PmcgNode->Node.Length =3D GetPmcgNodeSize (NodeList); > + PmcgNode->Node.Revision =3D 0; > + PmcgNode->Node.Reserved =3D EFI_ACPI_RESERVED_DWORD; > + PmcgNode->Node.NumIdMappings =3D NodeList->IdMappingCount; > + PmcgNode->Node.IdReference =3D sizeof > (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE); > + > + // PMCG specific data > + PmcgNode->Base =3D NodeList->BaseAddress; > + PmcgNode->OverflowInterruptGsiv =3D NodeList->OverflowInterrupt; > + > + Status =3D GetNodeOffsetReferencedByToken ( > + Generator->NodeIndexer, > + Generator->IortNodeCount, > + NodeList->ReferenceToken, > + &PmcgNode->NodeReference > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get Output Reference for PMCG Node." > + "Reference Token =3D %p" > + " Status =3D %r\n", > + NodeList->ReferenceToken, > + Status > + )); > + return Status; > + } > + > + if ((NodeList->IdMappingCount > 0) && > + (NodeList->IdMappingToken !=3D CM_NULL_TOKEN)) { > + // Ids for PMCG node > + IdMapArray =3D > (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)PmcgNode + > + PmcgNode->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; > + } > + } > + > + // Next PMCG Node > + PmcgNode =3D > (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE*)((UINT8*)PmcgNode + > + PmcgNode->Node.Length); > + NodeList++; > + } // PMCG Node > + > + return EFI_SUCCESS; > +} > + > +/** Construct the IORT 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 Info. > + @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 > +BuildIortTable ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + EFI_STATUS Status; > + UINT32 TableSize; > + UINT32 IortNodeCount; > + > + UINT32 ItsGroupNodeCount; > + UINT32 NamedComponentNodeCount; > + UINT32 RootComplexNodeCount; > + UINT32 SmmuV1V2NodeCount; > + UINT32 SmmuV3NodeCount; > + UINT32 PmcgNodeCount; > + > + UINT32 ItsGroupOffset; > + UINT32 NamedComponentOffset; > + UINT32 RootComplexOffset; > + UINT32 SmmuV1V2Offset; > + UINT32 SmmuV3Offset; > + UINT32 PmcgOffset; > + > + CM_ARM_ITS_GROUP_NODE * ItsGroupNodeList; > + CM_ARM_NAMED_COMPONENT_NODE * > NamedComponentNodeList; > + CM_ARM_ROOT_COMPLEX_NODE * RootComplexNodeList; > + CM_ARM_SMMUV1_SMMUV2_NODE * SmmuV1V2NodeList; > + CM_ARM_SMMUV3_NODE * SmmuV3NodeList; > + CM_ARM_PMCG_NODE * PmcgNodeList; > + > + EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort; > + IORT_NODE_INDEXER * NodeIndexer; > + ACPI_IORT_GENERATOR * Generator; > + > + ASSERT (This !=3D NULL); > + ASSERT (AcpiTableInfo !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Table !=3D NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTableSignat= ure); > + > + Generator =3D (ACPI_IORT_GENERATOR*)This; > + *Table =3D NULL; > + > + // Get the ITS group node info > + Status =3D GetEArmObjItsGroup ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &ItsGroupNodeList, > + &ItsGroupNodeCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get ITS Group Node Info. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Add the ITS group node count > + IortNodeCount =3D ItsGroupNodeCount; > + > + // Get the Named component node info > + Status =3D GetEArmObjNamedComponent ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &NamedComponentNodeList, > + &NamedComponentNodeCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get Named Component Node Info. Status > =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Add the Named Component group count > + IortNodeCount +=3D NamedComponentNodeCount; > + > + // Get the Root complex node info > + Status =3D GetEArmObjRootComplex ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &RootComplexNodeList, > + &RootComplexNodeCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get Root Complex Node Info. Status =3D %r\= n", > + Status > + )); > + goto error_handler; > + } > + > + // Add the Root Complex node count > + IortNodeCount +=3D RootComplexNodeCount; > + > + // Get the SMMU v1/v2 node info > + Status =3D GetEArmObjSmmuV1SmmuV2 ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &SmmuV1V2NodeList, > + &SmmuV1V2NodeCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get SMMUv1/SMMUv2 Node Info. Status > =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Add the SMMU v1/v2 node count > + IortNodeCount +=3D SmmuV1V2NodeCount; > + > + // Get the SMMUv3 node info > + Status =3D GetEArmObjSmmuV3 ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &SmmuV3NodeList, > + &SmmuV3NodeCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get SMMUv3 Node Info. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Add the SMMUv3 node count > + IortNodeCount +=3D SmmuV3NodeCount; > + > + // Get the PMCG node info > + Status =3D GetEArmObjPmcg ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &PmcgNodeList, > + &PmcgNodeCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to get PMCG Node Info. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Add the PMCG node count > + IortNodeCount +=3D PmcgNodeCount; > + > + // Allocate Node Indexer array > + NodeIndexer =3D (IORT_NODE_INDEXER*)AllocateZeroPool ( > + (sizeof (IORT_NODE_INDEXER) * > + IortNodeCount) > + ); > + if (NodeIndexer =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to allocate memory for Node Indexer" \ > + " Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + DEBUG ((DEBUG_INFO, "INFO: NodeIndexer =3D %p\n", NodeIndexer)); > + Generator->IortNodeCount =3D IortNodeCount; > + Generator->NodeIndexer =3D NodeIndexer; > + > + // Calculate the size of the IORT table > + TableSize =3D sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE); > + > + // ITS Group Nodes > + if (ItsGroupNodeCount > 0) { > + ItsGroupOffset =3D TableSize; > + // Size of ITS Group node list. > + TableSize +=3D GetSizeofItsGroupNodes ( > + ItsGroupOffset, > + ItsGroupNodeList, > + ItsGroupNodeCount, > + &NodeIndexer > + ); > + } > + > + // Named Component Nodes > + if (NamedComponentNodeCount > 0) { > + NamedComponentOffset =3D TableSize; > + // Size of Named Component node list. > + TableSize +=3D GetSizeofNamedComponentNodes ( > + NamedComponentOffset, > + NamedComponentNodeList, > + NamedComponentNodeCount, > + &NodeIndexer > + ); > + } > + > + // Root Complex Nodes > + if (RootComplexNodeCount > 0) { > + RootComplexOffset =3D TableSize; > + // Size of Root Complex node list. > + TableSize +=3D GetSizeofRootComplexNodes ( > + RootComplexOffset, > + RootComplexNodeList, > + RootComplexNodeCount, > + &NodeIndexer > + ); > + } > + > + // SMMUv1/SMMUv2 Nodes > + if (SmmuV1V2NodeCount > 0) { > + SmmuV1V2Offset =3D TableSize; > + // Size of SMMUv1/SMMUv2 node list. > + TableSize +=3D GetSizeofSmmuV1V2Nodes ( > + SmmuV1V2Offset, > + SmmuV1V2NodeList, > + SmmuV1V2NodeCount, > + &NodeIndexer > + ); > + } > + > + // SMMUv3 Nodes > + if (SmmuV3NodeCount > 0) { > + SmmuV3Offset =3D TableSize; > + // Size of SMMUv3 node list. > + TableSize +=3D GetSizeofSmmuV3Nodes ( > + SmmuV3Offset, > + SmmuV3NodeList, > + SmmuV3NodeCount, > + &NodeIndexer > + ); > + } > + > + // PMCG Nodes > + if (PmcgNodeCount > 0) { > + PmcgOffset =3D TableSize; > + // Size of PMCG node list. > + TableSize +=3D GetSizeofPmcgNodes ( > + PmcgOffset, > + PmcgNodeList, > + PmcgNodeCount, > + &NodeIndexer > + ); > + } > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: IORT:\n" \ > + " IortNodeCount =3D %d\n" \ > + " TableSize =3D %d\n", > + IortNodeCount, > + TableSize > + )); > + > + DEBUG (( > + DEBUG_INFO, > + " ItsGroupNodeCount =3D %d\n" \ > + " ItsGroupOffset =3D %d\n", > + ItsGroupNodeCount, > + ItsGroupOffset > + )); > + > + DEBUG (( > + DEBUG_INFO, > + " NamedComponentNodeCount =3D %d\n" \ > + " NamedComponentOffset =3D %d\n", > + NamedComponentNodeCount, > + NamedComponentOffset > + )); > + > + DEBUG (( > + DEBUG_INFO, > + " RootComplexNodeCount =3D %d\n" \ > + " RootComplexOffset =3D %d\n", > + RootComplexNodeCount, > + RootComplexOffset > + )); > + > + DEBUG (( > + DEBUG_INFO, > + " SmmuV1V2NodeCount =3D %d\n" \ > + " SmmuV1V2Offset =3D %d\n", > + SmmuV1V2NodeCount, > + SmmuV1V2Offset > + )); > + > + DEBUG (( > + DEBUG_INFO, > + " SmmuV3NodeCount =3D %d\n" \ > + " SmmuV3Offset =3D %d\n", > + SmmuV3NodeCount, > + SmmuV3Offset > + )); > + > + DEBUG (( > + DEBUG_INFO, > + " PmcgNodeCount =3D %d\n" \ > + " PmcgOffset =3D %d\n", > + PmcgNodeCount, > + PmcgOffset > + )); > + > + // Allocate the Buffer for IORT table > + *Table =3D (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize); > + if (*Table =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to allocate memory for IORT Table, Size =3D %= d," \ > + " Status =3D %r\n", > + TableSize, > + Status > + )); > + goto error_handler; > + } > + > + Iort =3D (EFI_ACPI_6_0_IO_REMAPPING_TABLE*)*Table; > + > + DEBUG (( > + DEBUG_INFO, > + "IORT: Iort =3D 0x%p TableSize =3D 0x%x\n", > + Iort, > + TableSize > + )); > + > + Status =3D AddAcpiHeader (CfgMgrProtocol, This, &Iort->Header, TableSi= ze); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to add ACPI header. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Update IORT table > + Iort->NumNodes =3D IortNodeCount; > + Iort->NodeOffset =3D sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE); > + Iort->Reserved =3D EFI_ACPI_RESERVED_DWORD; > + > + if (ItsGroupNodeCount > 0) { > + Status =3D AddItsGroupNodes ( > + This, > + CfgMgrProtocol, > + Iort, > + ItsGroupOffset, > + ItsGroupNodeList, > + ItsGroupNodeCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to add ITS Group Node. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + } > + > + if (NamedComponentNodeCount > 0) { > + Status =3D AddNamedComponentNodes ( > + This, > + CfgMgrProtocol, > + Iort, > + NamedComponentOffset, > + NamedComponentNodeList, > + NamedComponentNodeCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to add Named Component Node. Status =3D %r\= n", > + Status > + )); > + goto error_handler; > + } > + } > + > + if (RootComplexNodeCount > 0) { > + Status =3D AddRootComplexNodes ( > + This, > + CfgMgrProtocol, > + Iort, > + RootComplexOffset, > + RootComplexNodeList, > + RootComplexNodeCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to add Root Complex Node. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + } > + > + if (SmmuV1V2NodeCount > 0) { > + Status =3D AddSmmuV1V2Nodes ( > + This, > + CfgMgrProtocol, > + Iort, > + SmmuV1V2Offset, > + SmmuV1V2NodeList, > + SmmuV1V2NodeCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to add SMMU v1/v2 Node. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + } > + > + if (SmmuV3NodeCount > 0) { > + Status =3D AddSmmuV3Nodes ( > + This, > + CfgMgrProtocol, > + Iort, > + SmmuV3Offset, > + SmmuV3NodeList, > + SmmuV3NodeCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to add SMMUv3 Node. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + } > + > + if (PmcgNodeCount > 0) { > + Status =3D AddPmcgNodes ( > + This, > + CfgMgrProtocol, > + Iort, > + PmcgOffset, > + PmcgNodeList, > + PmcgNodeCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: IORT: Failed to add SMMUv3 Node. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + } > + > + return EFI_SUCCESS; > + > +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 IORT > + > + @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 > +FreeIortTableResources ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST > AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + ACPI_IORT_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->AcpiTableSignat= ure); > + > + Generator =3D (ACPI_IORT_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: IORT: Invalid Table Pointer\n")); > + ASSERT ((Table !=3D NULL) && (*Table !=3D NULL)); > + return EFI_INVALID_PARAMETER; > + } > + > + FreePool (*Table); > + *Table =3D NULL; > + return EFI_SUCCESS; > +} > + > +/** The IORT Table Generator revision. > +*/ > +#define IORT_GENERATOR_REVISION CREATE_REVISION (1, 0) > + > +/** The interface for the MADT Table Generator. > +*/ > +STATIC > +ACPI_IORT_GENERATOR IortGenerator =3D { > + // ACPI table generator header > + { > + // Generator ID > + CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_IORT), > + // Generator Description > + L"ACPI.STD.IORT.GENERATOR", > + // ACPI Table Signature > + EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_IO_REMAPPING_TABLE_REVISION, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + IORT_GENERATOR_REVISION, > + // Build Table function > + BuildIortTable, > + // Free Resource function > + FreeIortTableResources > + }, > + > + // IORT Generator private data > + > + // Iort Node count > + 0, > + // Pointer to Iort 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 > +AcpiIortLibConstructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D RegisterAcpiTableGenerator > (&IortGenerator.Header); > + DEBUG ((DEBUG_INFO, "IORT: 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 > +AcpiIortLibDestructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D DeregisterAcpiTableGenerator > (&IortGenerator.Header); > + DEBUG ((DEBUG_INFO, "Iort: Deregister Generator. Status =3D %r\n", > Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h > new file mode 100644 > index > 0000000000000000000000000000000000000000..44c89042e23d50ca73 > 70ee6cae0761e692b78d31 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h > @@ -0,0 +1,50 @@ > +/** @file > + > + Copyright (c) 2018, ARM Limited. All rights reserved. > + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Glossary: > + - Cm or CM - Configuration Manager > + - Obj or OBJ - Object > + - Std or STD - Standard > +**/ > + > +#ifndef IORT_GENERATOR_H_ > +#define IORT_GENERATOR_H_ > + > +#pragma pack(1) > + > +/** A structure that describes the Node indexer > + used for indexing the IORT nodes. > +*/ > +typedef struct IortNodeIndexer { > + /// Index token for the Node > + CM_OBJECT_TOKEN Token; > + /// Pointer to the node > + VOID * Object; > + /// Node offset from the start of the IORT table > + UINT32 Offset; > +} IORT_NODE_INDEXER; > + > +typedef struct AcpiIortGenerator { > + /// ACPI Table generator header > + ACPI_TABLE_GENERATOR Header; > + > + // IORT Generator private data > + > + /// IORT node count > + UINT32 IortNodeCount; > + /// Pointer to the node indexer array > + IORT_NODE_INDEXER * NodeIndexer; > +} ACPI_IORT_GENERATOR; > + > +#pragma pack() > + > +#endif // IORT_GENERATOR_H_ > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm. > inf > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm. > inf > new file mode 100644 > index > 0000000000000000000000000000000000000000..03be5a2ab6e8df5029 > d1c823f51ff01a4293f694 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm. > inf > @@ -0,0 +1,41 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D AcpiMadtLibArm > + FILE_GUID =3D AF76C93B-41B5-454D-83CD-D2A80A1C1E38 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D NULL|DXE_DRIVER > + CONSTRUCTOR =3D AcpiMadtLibConstructor > + DESTRUCTOR =3D AcpiMadtLibDestructor > + > +[Sources] > + MadtGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > +[Protocols] > + > +[Guids] > + > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..a08832aa813a6df0df5 > 1f82741084f81d511b30a > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c > @@ -0,0 +1,717 @@ > +/** @file > + MADT Table Generator > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Reference(s): > + - ACPI 6.2 Specification - Errata A, September 2017 > + > +**/ > + > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard MADT Generator > + > +Requirements: > + The following Configuration Manager Object(s) are required by > + this Generator: > + - EArmObjGicCInfo > + - EArmObjGicDInfo > + - EArmObjGicMsiFrameInfo (OPTIONAL) > + - EArmObjGicRedistributorInfo (OPTIONAL) > + - EArmObjGicItsInfo (OPTIONAL) > +*/ > + > +/** This macro expands to a function that retrieves the GIC > + CPU interface Information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjGicCInfo, > + CM_ARM_GICC_INFO > + ); > + > +/** This macro expands to a function that retrieves the GIC > + Distributor Information from the Configuration Manager. > +*/ > + > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjGicDInfo, > + CM_ARM_GICD_INFO > + ); > + > +/** This macro expands to a function that retrieves the GIC > + MSI Frame Information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjGicMsiFrameInfo, > + CM_ARM_GIC_MSI_FRAME_INFO > + ); > + > +/** This macro expands to a function that retrieves the GIC > + Redistributor Information from the Configuration Manager. > +*/ > + > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjGicRedistributorInfo, > + CM_ARM_GIC_REDIST_INFO > + ); > + > +/** This macro expands to a function that retrieves the GIC > + Interrupt Translation Service Information from the > + Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjGicItsInfo, > + CM_ARM_GIC_ITS_INFO > + ); > + > +/** This function updates the GIC CPU Interface Information in the > + EFI_ACPI_6_2_GIC_STRUCTURE structure. > + > + @param [in] Gicc Pointer to GIC CPU Interface structure. > + @param [in] GicCInfo Pointer to the GIC CPU Interface Information. > +*/ > +STATIC > +VOID > +AddGICC ( > + IN EFI_ACPI_6_2_GIC_STRUCTURE * CONST Gicc, > + IN CONST CM_ARM_GICC_INFO * CONST GicCInfo > + ) > +{ > + ASSERT (Gicc !=3D NULL); > + ASSERT (GicCInfo !=3D NULL); > + > + // UINT8 Type > + Gicc->Type =3D EFI_ACPI_6_2_GIC; > + // UINT8 Length > + Gicc->Length =3D sizeof (EFI_ACPI_6_2_GIC_STRUCTURE); > + // UINT16 Reserved > + Gicc->Reserved =3D EFI_ACPI_RESERVED_WORD; > + > + // UINT32 CPUInterfaceNumber > + Gicc->CPUInterfaceNumber =3D GicCInfo->CPUInterfaceNumber; > + // UINT32 AcpiProcessorUid > + Gicc->AcpiProcessorUid =3D GicCInfo->AcpiProcessorUid; > + // UINT32 Flags > + Gicc->Flags =3D GicCInfo->Flags; > + // UINT32 ParkingProtocolVersion > + Gicc->ParkingProtocolVersion =3D GicCInfo->ParkingProtocolVersion; > + // UINT32 PerformanceInterruptGsiv > + Gicc->PerformanceInterruptGsiv =3D GicCInfo->PerformanceInterruptGsiv; > + // UINT64 ParkedAddress > + Gicc->ParkedAddress =3D GicCInfo->ParkedAddress; > + > + // UINT64 PhysicalBaseAddress > + Gicc->PhysicalBaseAddress =3D GicCInfo->PhysicalBaseAddress; > + // UINT64 GICV > + Gicc->GICV =3D GicCInfo->GICV; > + // UINT64 GICH > + Gicc->GICH =3D GicCInfo->GICH; > + > + // UINT32 VGICMaintenanceInterrupt > + Gicc->VGICMaintenanceInterrupt =3D GicCInfo->VGICMaintenanceInterrupt; > + // UINT64 GICRBaseAddress > + Gicc->GICRBaseAddress =3D GicCInfo->GICRBaseAddress; > + > + // UINT64 MPIDR > + Gicc->MPIDR =3D GicCInfo->MPIDR; > + // UINT8 ProcessorPowerEfficiencyClass > + Gicc->ProcessorPowerEfficiencyClass =3D > + GicCInfo->ProcessorPowerEfficiencyClass; > + // UINT8 Reserved2[3] > + Gicc->Reserved2[0] =3D EFI_ACPI_RESERVED_BYTE; > + Gicc->Reserved2[1] =3D EFI_ACPI_RESERVED_BYTE; > + Gicc->Reserved2[2] =3D EFI_ACPI_RESERVED_BYTE; > +} > + > +/** Add the GIC CPU Interface Information to the MADT Table. > + > + @param [in] Gicc Pointer to GIC CPU Interface > + structure list. > + @param [in] GicCInfo Pointer to the GIC CPU > + Information list. > + @param [in] GicCCount Count of GIC CPU Interfaces. > +*/ > +STATIC > +VOID > +AddGICCList ( > + IN EFI_ACPI_6_2_GIC_STRUCTURE * Gicc, > + IN CONST CM_ARM_GICC_INFO * GicCInfo, > + IN UINT32 GicCCount > + ) > +{ > + ASSERT (Gicc !=3D NULL); > + ASSERT (GicCInfo !=3D NULL); > + > + while (GicCCount-- !=3D 0) { > + AddGICC (Gicc++, GicCInfo++); > + } > +} > + > +/** Update the GIC Distributor Information in the MADT Table. > + > + @param [in] Gicd Pointer to GIC Distributor structure. > + @param [in] GicDInfo Pointer to the GIC Distributor Information. > +*/ > +STATIC > +VOID > +AddGICD ( > + EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE * CONST Gicd, > + CONST CM_ARM_GICD_INFO * CONST GicDInfo > +) > +{ > + ASSERT (Gicd !=3D NULL); > + ASSERT (GicDInfo !=3D NULL); > + > + // UINT8 Type > + Gicd->Type =3D EFI_ACPI_6_2_GICD; > + // UINT8 Length > + Gicd->Length =3D sizeof (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE); > + // UINT16 Reserved > + Gicd->Reserved1 =3D EFI_ACPI_RESERVED_WORD; > + // UINT32 Identifier > + Gicd->GicId =3D GicDInfo->GicId; > + // UINT64 PhysicalBaseAddress > + Gicd->PhysicalBaseAddress =3D GicDInfo->PhysicalBaseAddress; > + // UINT32 VectorBase > + Gicd->SystemVectorBase =3D EFI_ACPI_RESERVED_DWORD; > + // UINT8 GicVersion > + Gicd->GicVersion =3D GicDInfo->GicVersion; > + // UINT8 Reserved2[3] > + Gicd->Reserved2[0] =3D EFI_ACPI_RESERVED_BYTE; > + Gicd->Reserved2[1] =3D EFI_ACPI_RESERVED_BYTE; > + Gicd->Reserved2[2] =3D EFI_ACPI_RESERVED_BYTE; > +} > + > +/** Update the GIC MSI Frame Information. > + > + @param [in] GicMsiFrame Pointer to GIC MSI Frame structure. > + @param [in] GicMsiFrameInfo Pointer to the GIC MSI Frame > Information. > +*/ > +STATIC > +VOID > +AddGICMsiFrame ( > + IN EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE * CONST GicMsiFrame, > + IN CONST CM_ARM_GIC_MSI_FRAME_INFO * CONST > GicMsiFrameInfo > +) > +{ > + ASSERT (GicMsiFrame !=3D NULL); > + ASSERT (GicMsiFrameInfo !=3D NULL); > + > + GicMsiFrame->Type =3D EFI_ACPI_6_2_GIC_MSI_FRAME; > + GicMsiFrame->Length =3D sizeof > (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE); > + GicMsiFrame->Reserved1 =3D EFI_ACPI_RESERVED_WORD; > + GicMsiFrame->GicMsiFrameId =3D GicMsiFrameInfo->GicMsiFrameId; > + GicMsiFrame->PhysicalBaseAddress =3D GicMsiFrameInfo- > >PhysicalBaseAddress; > + > + GicMsiFrame->Flags =3D GicMsiFrameInfo->Flags; > + GicMsiFrame->SPICount =3D GicMsiFrameInfo->SPICount; > + GicMsiFrame->SPIBase =3D GicMsiFrameInfo->SPIBase; > +} > + > +/** Add the GIC MSI Frame Information to the MADT Table. > + > + @param [in] GicMsiFrame Pointer to GIC MSI Frame structure list. > + @param [in] GicMsiFrameInfo Pointer to the GIC MSI Frame info list. > + @param [in] GicMsiFrameCount Count of GIC MSI Frames. > +*/ > +STATIC > +VOID > +AddGICMsiFrameInfoList ( > + IN EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE * GicMsiFrame, > + IN CONST CM_ARM_GIC_MSI_FRAME_INFO * GicMsiFrameInfo, > + IN UINT32 GicMsiFrameCount > +) > +{ > + ASSERT (GicMsiFrame !=3D NULL); > + ASSERT (GicMsiFrameInfo !=3D NULL); > + > + while (GicMsiFrameCount-- !=3D 0) { > + AddGICMsiFrame (GicMsiFrame++, GicMsiFrameInfo++); > + } > +} > + > +/** Update the GIC Redistributor Information. > + > + @param [in] Gicr Pointer to GIC Redistributor structu= re. > + @param [in] GicRedisributorInfo Pointer to the GIC Redistributor Inf= o. > +*/ > +STATIC > +VOID > +AddGICRedistributor ( > + IN EFI_ACPI_6_2_GICR_STRUCTURE * CONST Gicr, > + IN CONST CM_ARM_GIC_REDIST_INFO * CONST GicRedisributorInfo > + ) > +{ > + ASSERT (Gicr !=3D NULL); > + ASSERT (GicRedisributorInfo !=3D NULL); > + > + Gicr->Type =3D EFI_ACPI_6_2_GICR; > + Gicr->Length =3D sizeof (EFI_ACPI_6_2_GICR_STRUCTURE); > + Gicr->Reserved =3D EFI_ACPI_RESERVED_WORD; > + Gicr->DiscoveryRangeBaseAddress =3D > + GicRedisributorInfo->DiscoveryRangeBaseAddress; > + Gicr->DiscoveryRangeLength =3D GicRedisributorInfo- > >DiscoveryRangeLength; > +} > + > +/** Add the GIC Redistributor Information to the MADT Table. > + > + @param [in] Gicr Pointer to GIC Redistributor structure list. > + @param [in] GicRInfo Pointer to the GIC Distributor info list. > + @param [in] GicRCount Count of GIC Distributors. > +*/ > +STATIC > +VOID > +AddGICRedistributorList ( > + IN EFI_ACPI_6_2_GICR_STRUCTURE * Gicr, > + IN CONST CM_ARM_GIC_REDIST_INFO * GicRInfo, > + IN UINT32 GicRCount > +) > +{ > + ASSERT (Gicr !=3D NULL); > + ASSERT (GicRInfo !=3D NULL); > + > + while (GicRCount-- !=3D 0) { > + AddGICRedistributor (Gicr++, GicRInfo++); > + } > +} > + > +/** Update the GIC Interrupt Translation Service Information > + > + @param [in] GicIts Pointer to GIC ITS structure. > + @param [in] GicItsInfo Pointer to the GIC ITS Information. > +*/ > +STATIC > +VOID > +AddGICInterruptTranslationService ( > + IN EFI_ACPI_6_2_GIC_ITS_STRUCTURE * CONST GicIts, > + IN CONST CM_ARM_GIC_ITS_INFO * CONST GicItsInfo > +) > +{ > + ASSERT (GicIts !=3D NULL); > + ASSERT (GicItsInfo !=3D NULL); > + > + GicIts->Type =3D EFI_ACPI_6_2_GIC_ITS; > + GicIts->Length =3D sizeof (EFI_ACPI_6_2_GIC_ITS_STRUCTURE); > + GicIts->Reserved =3D EFI_ACPI_RESERVED_WORD; > + GicIts->GicItsId =3D GicItsInfo->GicItsId; > + GicIts->PhysicalBaseAddress =3D GicItsInfo->PhysicalBaseAddress; > + GicIts->Reserved2 =3D EFI_ACPI_RESERVED_DWORD; > +} > + > +/** Add the GIC Interrupt Translation Service Information > + to the MADT Table. > + > + @param [in] GicIts Pointer to GIC ITS structure list. > + @param [in] GicItsInfo Pointer to the GIC ITS list. > + @param [in] GicItsCount Count of GIC ITS. > +*/ > +STATIC > +VOID > +AddGICItsList ( > + IN EFI_ACPI_6_2_GIC_ITS_STRUCTURE * GicIts, > + IN CONST CM_ARM_GIC_ITS_INFO * GicItsInfo, > + IN UINT32 GicItsCount > +) > +{ > + ASSERT (GicIts !=3D NULL); > + ASSERT (GicItsInfo !=3D NULL); > + > + while (GicItsCount-- !=3D 0) { > + AddGICInterruptTranslationService (GicIts++, GicItsInfo++); > + } > +} > + > +/** Construct the MADT 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 Info. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [out] Table Pointer to the constructed ACPI Table. > + > + @retval EFI_SUCCESS Table generated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +BuildMadtTable ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + EFI_STATUS Status; > + UINT32 TableSize; > + UINT32 GicCCount; > + UINT32 GicDCount; > + UINT32 GicMSICount; > + UINT32 GicRedistCount; > + UINT32 GicItsCount; > + CM_ARM_GICC_INFO * GicCInfo; > + CM_ARM_GICD_INFO * GicDInfo; > + CM_ARM_GIC_MSI_FRAME_INFO * GicMSIInfo; > + CM_ARM_GIC_REDIST_INFO * GicRedistInfo; > + CM_ARM_GIC_ITS_INFO * GicItsInfo; > + UINT32 GicCOffset; > + UINT32 GicDOffset; > + UINT32 GicMSIOffset; > + UINT32 GicRedistOffset; > + UINT32 GicItsOffset; > + > + EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER * Madt; > + > + ASSERT (This !=3D NULL); > + ASSERT (AcpiTableInfo !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Table !=3D NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTableSignat= ure); > + > + *Table =3D NULL; > + > + Status =3D GetEArmObjGicCInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &GicCInfo, > + &GicCCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GICC Info. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + if (GicCCount =3D=3D 0) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: GIC CPU Interface information not provided.\n" > + )); > + ASSERT (GicCCount !=3D 0); > + Status =3D EFI_INVALID_PARAMETER; > + goto error_handler; > + } > + > + Status =3D GetEArmObjGicDInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &GicDInfo, > + &GicDCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GICD Info. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + if (GicDCount =3D=3D 0) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: GIC Distributor information not provided.\n" > + )); > + ASSERT (GicDCount !=3D 0); > + Status =3D EFI_INVALID_PARAMETER; > + goto error_handler; > + } > + > + if (GicDCount > 1) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: One, and only one, GIC distributor must be present." > + "GicDCount =3D %d\n", > + GicDCount > + )); > + ASSERT (GicDCount <=3D 1); > + Status =3D EFI_INVALID_PARAMETER; > + goto error_handler; > + } > + > + Status =3D GetEArmObjGicMsiFrameInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &GicMSIInfo, > + &GicMSICount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GIC MSI Info. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Status =3D GetEArmObjGicRedistributorInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &GicRedistInfo, > + &GicRedistCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GIC Redistributor Info. Status =3D %r\= n", > + Status > + )); > + goto error_handler; > + } > + > + Status =3D GetEArmObjGicItsInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &GicItsInfo, > + &GicItsCount > + ); > + if (EFI_ERROR (Status) && (Status !=3D EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GIC ITS Info. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + TableSize =3D sizeof > (EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER); > + > + GicCOffset =3D TableSize; > + TableSize +=3D (sizeof (EFI_ACPI_6_2_GIC_STRUCTURE) * GicCCount); > + > + GicDOffset =3D TableSize; > + TableSize +=3D (sizeof (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE) * > GicDCount); > + > + GicMSIOffset =3D TableSize; > + TableSize +=3D (sizeof (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE) * > GicMSICount); > + > + GicRedistOffset =3D TableSize; > + TableSize +=3D (sizeof (EFI_ACPI_6_2_GICR_STRUCTURE) * GicRedistCount)= ; > + > + GicItsOffset =3D TableSize; > + TableSize +=3D (sizeof (EFI_ACPI_6_2_GIC_ITS_STRUCTURE) * GicItsCount)= ; > + > + // Allocate the Buffer for MADT table > + *Table =3D (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize); > + if (*Table =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to allocate memory for MADT Table, Size =3D %= d," > \ > + " Status =3D %r\n", > + TableSize, > + Status > + )); > + goto error_handler; > + } > + > + Madt =3D > (EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER*)*Table; > + > + DEBUG (( > + DEBUG_INFO, > + "MADT: Madt =3D 0x%p TableSize =3D 0x%x\n", > + Madt, > + TableSize > + )); > + > + Status =3D AddAcpiHeader (CfgMgrProtocol, This, &Madt->Header, > TableSize); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to add ACPI header. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + AddGICCList ( > + (EFI_ACPI_6_2_GIC_STRUCTURE*)((UINT8*)Madt + GicCOffset), > + GicCInfo, > + GicCCount > + ); > + > + AddGICD ( > + (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE*)((UINT8*)Madt + > GicDOffset), > + GicDInfo > + ); > + > + if (GicMSICount !=3D 0) { > + AddGICMsiFrameInfoList ( > + (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE*)((UINT8*)Madt + > GicMSIOffset), > + GicMSIInfo, > + GicMSICount > + ); > + } > + > + if (GicRedistCount !=3D 0) { > + AddGICRedistributorList ( > + (EFI_ACPI_6_2_GICR_STRUCTURE*)((UINT8*)Madt + GicRedistOffset), > + GicRedistInfo, > + GicRedistCount > + ); > + } > + > + if (GicItsCount !=3D 0) { > + AddGICItsList ( > + (EFI_ACPI_6_2_GIC_ITS_STRUCTURE*)((UINT8*)Madt + GicItsOffset), > + GicItsInfo, > + GicItsCount > + ); > + } > + > + return EFI_SUCCESS; > + > +error_handler: > + if (*Table !=3D NULL) { > + FreePool (*Table); > + *Table =3D NULL; > + } > + return Status; > +} > + > +/** Free any resources allocated for constructing the MADT > + > + @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 > +FreeMadtTableResources ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST > AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + 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->AcpiTableSignat= ure); > + > + if ((Table =3D=3D NULL) || (*Table =3D=3D NULL)) { > + DEBUG ((DEBUG_ERROR, "ERROR: MADT: Invalid Table Pointer\n")); > + ASSERT ((Table !=3D NULL) && (*Table !=3D NULL)); > + return EFI_INVALID_PARAMETER; > + } > + > + FreePool (*Table); > + *Table =3D NULL; > + return EFI_SUCCESS; > +} > + > +/** The MADT Table Generator revision. > +*/ > +#define MADT_GENERATOR_REVISION CREATE_REVISION (1, 0) > + > +/** The interface for the MADT Table Generator. > +*/ > +STATIC > +CONST > +ACPI_TABLE_GENERATOR MadtGenerator =3D { > + // Generator ID > + CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_MADT), > + // Generator Description > + L"ACPI.STD.MADT.GENERATOR", > + // ACPI Table Signature > + EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + MADT_GENERATOR_REVISION, > + // Build Table function > + BuildMadtTable, > + // Free Resource function > + FreeMadtTableResources > +}; > + > +/** 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 > +AcpiMadtLibConstructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D RegisterAcpiTableGenerator (&MadtGenerator); > + DEBUG ((DEBUG_INFO, "MADT: 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 > +AcpiMadtLibDestructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D DeregisterAcpiTableGenerator (&MadtGenerator); > + DEBUG ((DEBUG_INFO, "MADT: Deregister Generator. Status =3D %r\n", > Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.i > nf > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.i > nf > new file mode 100644 > index > 0000000000000000000000000000000000000000..dfd20dbb86ff1cf9150e > 8f6a219b2d1008f2116f > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.i > nf > @@ -0,0 +1,41 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D AcpiMcfgLibArm > + FILE_GUID =3D 8C9BDCB2-72D4-4F30-A12D-1145C3807FF7 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D NULL|DXE_DRIVER > + CONSTRUCTOR =3D AcpiMcfgLibConstructor > + DESTRUCTOR =3D AcpiMcfgLibDestructor > + > +[Sources] > + McfgGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > +[Protocols] > + > +[Guids] > + > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..8b95fd3d5c7f97e9cf7c > cd956fcba56d46fc6cf1 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c > @@ -0,0 +1,342 @@ > +/** @file > + MCFG Table Generator > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Reference(s): > + - PCI Firmware Specification - Revision 3.2, January 26, 2015. > + > +**/ > + > +#include > > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard MCFG Generator > + > +Requirements: > + The following Configuration Manager Object(s) are required by > + this Generator: > + - EArmObjPciConfigSpaceInfo > +*/ > + > +#pragma pack(1) > + > +/** This typedef is used to shorten the name of the MCFG Table > + header structure. > +*/ > +typedef > + > EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_HE > ADER > + MCFG_TABLE; > + > +/** This typedef is used to shorten the name of the Enhanced > + Configuration Space address structure. > +*/ > +typedef > + > EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ > ADDRESS_ALLOCATION_STRUCTURE > + MCFG_CFG_SPACE_ADDR; > + > +#pragma pack() > + > +/** Retrieve the PCI Configuration Space Information. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjPciConfigSpaceInfo, > + CM_ARM_PCI_CONFIG_SPACE_INFO > + ); > + > +/** Add the PCI Enhanced Configuration Space Information to the MCFG > Table. > + > + @param [in] Mcfg Pointer to MCFG Table. > + @param [in] PciCfgSpaceOffset Offset for the PCI Configuration Spac= e > + Info structure in the MCFG Table. > + @param [in] PciCfgSpaceInfoList Pointer to the PCI Configuration Spac= e > + Info List. > + @param [in] PciCfgSpaceCount Count of PCI Configuration Space Info= . > +*/ > +STATIC > +VOID > +AddPciConfigurationSpaceList ( > + IN MCFG_TABLE * CONST Mcfg, > + IN CONST UINT32 PciCfgSpaceOffset, > + IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO * PciCfgSpaceInfoList, > + IN UINT32 PciCfgSpaceCount > +) > +{ > + MCFG_CFG_SPACE_ADDR * PciCfgSpace; > + > + ASSERT (Mcfg !=3D NULL); > + ASSERT (PciCfgSpaceInfoList !=3D NULL); > + > + PciCfgSpace =3D (MCFG_CFG_SPACE_ADDR *)((UINT8*)Mcfg + > PciCfgSpaceOffset); > + > + while (PciCfgSpaceCount-- !=3D 0) { > + // Add PCI Configuration Space entry > + PciCfgSpace->BaseAddress =3D PciCfgSpaceInfoList->BaseAddress; > + PciCfgSpace->PciSegmentGroupNumber =3D > + PciCfgSpaceInfoList->PciSegmentGroupNumber; > + PciCfgSpace->StartBusNumber =3D PciCfgSpaceInfoList->StartBusNumber; > + PciCfgSpace->EndBusNumber =3D PciCfgSpaceInfoList->EndBusNumber; > + PciCfgSpace->Reserved =3D EFI_ACPI_RESERVED_DWORD; > + PciCfgSpace++; > + PciCfgSpaceInfoList++; > + } > +} > + > +/** Construct the MCFG 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 Info. > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + Protocol Interface. > + @param [out] Table Pointer to the constructed ACPI Table. > + > + @retval EFI_SUCCESS Table generated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object was not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +BuildMcfgTable ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + EFI_STATUS Status; > + UINT32 TableSize; > + UINT32 ConfigurationSpaceCount; > + CM_ARM_PCI_CONFIG_SPACE_INFO * PciConfigSpaceInfoList; > + MCFG_TABLE * Mcfg; > + > + ASSERT (This !=3D NULL); > + ASSERT (AcpiTableInfo !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Table !=3D NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTableSignat= ure); > + > + *Table =3D NULL; > + Status =3D GetEArmObjPciConfigSpaceInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &PciConfigSpaceInfoList, > + &ConfigurationSpaceCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, > + "ERROR: MCFG: Failed to get PCI Configuration Space Information." = \ > + " Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + if (ConfigurationSpaceCount =3D=3D 0) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MCFG: Configuration Space Count =3D %d\n", > + ConfigurationSpaceCount > + )); > + Status =3D EFI_INVALID_PARAMETER; > + ASSERT (ConfigurationSpaceCount !=3D 0); > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "MCFG: Configuration Space Count =3D %d\n", > + ConfigurationSpaceCount > + )); > + > + // Calculate the MCFG Table Size > + TableSize =3D sizeof (MCFG_TABLE) + > + ((sizeof (MCFG_CFG_SPACE_ADDR) * ConfigurationSpaceCount)); > + > + *Table =3D (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize); > + if (*Table =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MCFG: Failed to allocate memory for MCFG Table, Size =3D %= d," > \ > + " Status =3D %r\n", > + TableSize, > + Status > + )); > + goto error_handler; > + } > + > + Mcfg =3D (MCFG_TABLE*)*Table; > + DEBUG (( > + DEBUG_INFO, > + "MCFG: Mcfg =3D 0x%p TableSize =3D 0x%x\n", > + Mcfg, > + TableSize > + )); > + > + Status =3D AddAcpiHeader (CfgMgrProtocol, This, &Mcfg->Header, > TableSize); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MCFG: Failed to add ACPI header. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Mcfg->Reserved =3D EFI_ACPI_RESERVED_QWORD; > + > + AddPciConfigurationSpaceList ( > + Mcfg, > + sizeof (MCFG_TABLE), > + PciConfigSpaceInfoList, > + ConfigurationSpaceCount > + ); > + > + return EFI_SUCCESS; > + > +error_handler: > + if (*Table !=3D NULL) { > + FreePool (*Table); > + *Table =3D NULL; > + } > + return Status; > +} > + > +/** Free any resources allocated for constructing the MCFG > + > + @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 > +FreeMcfgTableResources ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST > AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + 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->AcpiTableSignat= ure); > + > + if ((Table =3D=3D NULL) || (*Table =3D=3D NULL)) { > + DEBUG ((DEBUG_ERROR, "ERROR: MCFG: Invalid Table Pointer\n")); > + ASSERT ((Table !=3D NULL) && (*Table !=3D NULL)); > + return EFI_INVALID_PARAMETER; > + } > + > + FreePool (*Table); > + *Table =3D NULL; > + return EFI_SUCCESS; > +} > + > +/** This macro defines the MCFG Table Generator revision. > +*/ > +#define MCFG_GENERATOR_REVISION CREATE_REVISION (1, 0) > + > +/** The interface for the MCFG Table Generator. > +*/ > +STATIC > +CONST > +ACPI_TABLE_GENERATOR McfgGenerator =3D { > + // Generator ID > + CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_MCFG), > + // Generator Description > + L"ACPI.STD.MCFG.GENERATOR", > + // ACPI Table Signature > + > EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE > _BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, > + // ACPI Table Revision > + > EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_RE > VISION, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + MCFG_GENERATOR_REVISION, > + // Build Table function > + BuildMcfgTable, > + // Free Resource function > + FreeMcfgTableResources > +}; > + > +/** 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 > +AcpiMcfgLibConstructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D RegisterAcpiTableGenerator (&McfgGenerator); > + DEBUG ((DEBUG_INFO, "MCFG: 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 > +AcpiMcfgLibDestructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D DeregisterAcpiTableGenerator (&McfgGenerator); > + DEBUG ((DEBUG_INFO, "MCFG: Deregister Generator. Status =3D %r\n", > Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf > new file mode 100644 > index > 0000000000000000000000000000000000000000..cbb53ecef6b5b16405b > 03bebf28a664259928518 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf > @@ -0,0 +1,41 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D AcpiRawLibArm > + FILE_GUID =3D 20F31568-D687-49BA-B326-CCD9D38EDE16 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D NULL|DXE_DRIVER > + CONSTRUCTOR =3D AcpiRawLibConstructor > + DESTRUCTOR =3D AcpiRawLibDestructor > + > +[Sources] > + RawGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > +[Protocols] > + > +[Guids] > + > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..974b2993c24ae148ee > b88342c5e32fa997a31c0e > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c > @@ -0,0 +1,142 @@ > +/** @file > + MCFG Table Generator > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +**/ > + > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > + > +/** Construct the ACPI table using the ACPI table data provided. > + > + 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 Info. > + @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. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +BuildRawTable ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + ASSERT (This !=3D NULL); > + ASSERT (AcpiTableInfo !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Table !=3D NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableData !=3D NULL); > + > + if (AcpiTableInfo->AcpiTableData =3D=3D NULL) { > + *Table =3D NULL; > + return EFI_INVALID_PARAMETER; > + } > + > + *Table =3D AcpiTableInfo->AcpiTableData; > + > + return EFI_SUCCESS; > +} > + > +/** This macro defines the Raw Generator revision. > +*/ > +#define RAW_GENERATOR_REVISION CREATE_REVISION (1, 0) > + > +/** The interface for the Raw Table Generator. > +*/ > +STATIC > +CONST > +ACPI_TABLE_GENERATOR RawGenerator =3D { > + // Generator ID > + CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_RAW), > + // Generator Description > + L"ACPI.STD.RAW.GENERATOR", > + // ACPI Table Signature - Unused > + 0, > + // ACPI Table Revision - Unused > + 0, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + RAW_GENERATOR_REVISION, > + // Build Table function > + BuildRawTable, > + // No additional resources are allocated by the generator. > + // Hence the Free Resource function is not required. > + 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 > +AcpiRawLibConstructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D RegisterAcpiTableGenerator (&RawGenerator); > + DEBUG ((DEBUG_INFO, "RAW: 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 > +AcpiRawLibDestructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D DeregisterAcpiTableGenerator (&RawGenerator); > + DEBUG ((DEBUG_INFO, "RAW: Deregister Generator. Status =3D %r\n", > Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.in > f > new file mode 100644 > index > 0000000000000000000000000000000000000000..35c17089986f728a55 > 3d73849744e3f904f28b24 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.in > f > @@ -0,0 +1,41 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D AcpiSpcrLibArm > + FILE_GUID =3D 55088136-7B78-4974-B1EE-F630150D0DE7 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D NULL|DXE_DRIVER > + CONSTRUCTOR =3D AcpiSpcrLibConstructor > + DESTRUCTOR =3D AcpiSpcrLibDestructor > + > +[Sources] > + SpcrGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > +[Protocols] > + > +[Guids] > + > diff --git > a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..04b64b2c91951d3047 > a01bb5a807a3adb321ca50 > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c > @@ -0,0 +1,324 @@ > +/** @file > + SPCR Table Generator > + > + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > + This program and the accompanying materials > + are licensed and made available under the terms and conditions of the > BSD License > + which accompanies this distribution. The full text of the license may= be > found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > + @par Reference(s): > + - Microsoft Serial Port Console Redirection Table > + Specification - Version 1.03 - August 10, 2015. > + > +**/ > + > +#include > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard SPCR Table Generator > + > + Constructs the SPCR table for PL011 or SBSA UART peripherals. > + > +Requirements: > + The following Configuration Manager Object(s) are required by > + this Generator: > + - EArmObjSerialConsolePortInfo > + > +NOTE: This implementation ignores the possibility that the Serial settin= gs > may > + be modified from the UEFI Shell. A more complex handler would be > needed > + to (e.g.) recover serial port settings from the UART, or non-volat= ile > + storage. > +*/ > + > +#pragma pack(1) > + > +/** This macro defines the no flow control option. > +*/ > +#define SPCR_FLOW_CONTROL_NONE 0 > + > +/**A template for generating the SPCR Table. > + > + Note: fields marked "{Template}" will be updated dynamically. > +*/ > +STATIC > +EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE AcpiSpcr =3D { > + ACPI_HEADER ( > + > EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE, > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION > + ), > + 0, // {Template}: Serial Port Subtype > + { > + EFI_ACPI_RESERVED_BYTE, > + EFI_ACPI_RESERVED_BYTE, > + EFI_ACPI_RESERVED_BYTE > + }, > + ARM_GAS32 (0), // {Template}: Serial Port Base Address > + > EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_ > GIC, > + 0, // Not used on ARM > + 0, // {Template}: Serial Port Interrupt > + 0, // {Template}: Serial Port Baudrate > + > EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARIT > Y, > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1, > + SPCR_FLOW_CONTROL_NONE, > + > EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_A > NSI, > + EFI_ACPI_RESERVED_BYTE, > + 0xFFFF, > + 0xFFFF, > + 0x00, > + 0x00, > + 0x00, > + 0x00000000, > + 0x00, > + EFI_ACPI_RESERVED_DWORD > +}; > + > +#pragma pack() > + > +/** This macro expands to a function that retrieves the Serial > + Port Information from the Configuration Manager. > +*/ > +GET_OBJECT_LIST ( > + EObjNameSpaceArm, > + EArmObjSerialConsolePortInfo, > + CM_ARM_SERIAL_PORT_INFO > + ) > + > +/** Construct the SPCR 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 Info. > + @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_UNSUPPORTED An unsupported baudrate was specified > by the > + Configuration Manager. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +STATIC > +EFI_STATUS > +EFIAPI > +BuildSpcrTable ( > + IN CONST ACPI_TABLE_GENERATOR * CONST This, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + EFI_STATUS Status; > + CM_ARM_SERIAL_PORT_INFO * SerialPortInfo; > + > + ASSERT (This !=3D NULL); > + ASSERT (AcpiTableInfo !=3D NULL); > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Table !=3D NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId =3D=3D This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature =3D=3D This->AcpiTableSignat= ure); > + > + *Table =3D NULL; > + > + Status =3D GetEArmObjSerialConsolePortInfo ( > + CfgMgrProtocol, > + CM_NULL_TOKEN, > + &SerialPortInfo, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SPCR: Failed to get serial port information. Status =3D %r= \n", > + Status > + )); > + goto error_handler; > + } > + > + if (SerialPortInfo->BaseAddress =3D=3D 0) { > + Status =3D EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SPCR: Uart port base address is invalid. BaseAddress =3D > 0x%lx\n", > + SerialPortInfo->BaseAddress > + )); > + goto error_handler; > + } > + > + if ((SerialPortInfo->PortSubtype !=3D > + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) && > + (SerialPortInfo->PortSubtype !=3D > + > EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) > && > + (SerialPortInfo->PortSubtype !=3D > + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART) > && > + (SerialPortInfo->PortSubtype !=3D > + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_DCC)) { > + Status =3D EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SPCR: Uart port sybtype is invalid. PortSubtype =3D 0x%x\n= ", > + SerialPortInfo->PortSubtype > + )); > + goto error_handler; > + } > + > + DEBUG ((DEBUG_INFO, "SPCR UART Configuration:\n")); > + DEBUG ((DEBUG_INFO, " UART Base =3D 0x%lx\n", SerialPortInfo- > >BaseAddress)); > + DEBUG ((DEBUG_INFO, " Clock =3D %d\n", SerialPortInfo->Clock)); > + DEBUG ((DEBUG_INFO, " Baudrate =3D %ld\n", SerialPortInfo->BaudRate= )); > + DEBUG ((DEBUG_INFO, " Interrupt =3D %d\n", SerialPortInfo->Interrupt= )); > + > + Status =3D AddAcpiHeader ( > + CfgMgrProtocol, > + This, > + (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiSpcr, > + sizeof (EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE) > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SPCR: Failed to add ACPI header. Status =3D %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Update the serial port subtype > + AcpiSpcr.InterfaceType =3D SerialPortInfo->PortSubtype; > + > + // Update the base address > + AcpiSpcr.BaseAddress.Address =3D SerialPortInfo->BaseAddress; > + > + // Update the UART interrupt > + AcpiSpcr.GlobalSystemInterrupt =3D SerialPortInfo->Interrupt; > + > + switch (SerialPortInfo->BaudRate) { > + case 9600: > + AcpiSpcr.BaudRate =3D > + > EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600; > + break; > + case 19200: > + AcpiSpcr.BaudRate =3D > + > EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_1920 > 0; > + break; > + case 57600: > + AcpiSpcr.BaudRate =3D > + > EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_5760 > 0; > + break; > + case 115200: > + AcpiSpcr.BaudRate =3D > + > EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_1152 > 00; > + break; > + default: > + Status =3D EFI_UNSUPPORTED; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SPCR: Invalid Baud Rate %ld, Status =3D %r\n", > + SerialPortInfo->BaudRate, > + Status > + )); > + goto error_handler; > + } // switch > + > + *Table =3D (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiSpcr; > + > +error_handler: > + return Status; > +} > + > +/** This macro defines the SPCR Table Generator revision. > +*/ > +#define SPCR_GENERATOR_REVISION CREATE_REVISION (1, 0) > + > +/** The interface for the SPCR Table Generator. > +*/ > +STATIC > +CONST > +ACPI_TABLE_GENERATOR SpcrGenerator =3D { > + // Generator ID > + CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_SPCR), > + // Generator Description > + L"ACPI.STD.SPCR.GENERATOR", > + // ACPI Table Signature > + EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + SPCR_GENERATOR_REVISION, > + // Build Table function > + BuildSpcrTable, > + // No additional resources are allocated by the generator. > + // Hence the Free Resource function is not required. > + 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 > +AcpiSpcrLibConstructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D RegisterAcpiTableGenerator (&SpcrGenerator); > + DEBUG ((DEBUG_INFO, "SPCR: 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 > +AcpiSpcrLibDestructor ( > + IN CONST EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE * CONST SystemTable > + ) > +{ > + EFI_STATUS Status =3D DeregisterAcpiTableGenerator (&SpcrGenerator); > + DEBUG ((DEBUG_INFO, "SPCR: Deregister Generator. Status =3D %r\n", > Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c > b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..16bce37e4c0cb2666e > 8f2d0895c4fa55f350f2f1 > --- /dev/null > +++ b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c > @@ -0,0 +1,164 @@ > +/** @file > + Table Helper > + > +Copyright (c) 2017, ARM Limited. All rights reserved. > +This program and the accompanying materials > +are licensed and made available under the terms and conditions of the BS= D > License > +which accompanies this distribution. The full text of the license may b= e > found at > +http://opensource.org/licenses/bsd-license.php > + > +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +**/ > + > +#include > +#include > +#include > +#include > + > +// Module specific include files. > +#include > +#include > +#include > + > +/** The GetCgfMgrInfo function gets the > CM_STD_OBJ_CONFIGURATION_MANAGER_INFO > + object from the Configuration Manager. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > protocol > + interface. > + @param [out] CfgMfrInfo Pointer to the Configuration Manager Info > + object structure. > + > + @retval EFI_SUCCESS The object is returned. > + @retval EFI_INVALID_PARAMETER The Object ID is invalid. > + @retval EFI_NOT_FOUND The requested Object is not found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size. > +*/ > +EFI_STATUS > +EFIAPI > +GetCgfMgrInfo ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + OUT CM_STD_OBJ_CONFIGURATION_MANAGER_INFO ** > CfgMfrInfo > + ) > +{ > + EFI_STATUS Status; > + CM_OBJ_DESCRIPTOR CmObjectDesc; > + > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (CfgMfrInfo !=3D NULL); > + > + *CfgMfrInfo =3D NULL; > + Status =3D CfgMgrProtocol->GetObject ( > + CfgMgrProtocol, > + CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo)= , > + CM_NULL_TOKEN, > + &CmObjectDesc > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to Get Configuration Manager Info. Status =3D %r\n"= , > + Status > + )); > + return Status; > + } > + > + if (CmObjectDesc.Size < sizeof > (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: EStdObjCfgMgrInfo: Buffer too small, size =3D 0x%x\n", > + CmObjectDesc.Size > + )); > + ASSERT ( > + CmObjectDesc.Size >=3D sizeof > (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO) > + ); > + return EFI_BAD_BUFFER_SIZE; > + } > + > + *CfgMfrInfo =3D > (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO*)CmObjectDesc.Data; > + return Status; > +} > + > +/** The AddAcpiHeader function updates the ACPI header structure > pointed by > + the AcpiHeader. It utilizes the ACPI table Generator and the > Configuration > + Manager protocol to obtain any information required for constructing > the > + header. > + > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager > + protocol interface. > + @param [in] Generator Pointer to the ACPI table Generator. > + @param [in,out] AcpiHeader Pointer to the ACPI table header to be > + updated. > + @param [in] Length Length of the ACPI table. > + > + @retval EFI_SUCCESS The ACPI table is updated successfully. > + @retval EFI_INVALID_PARAMETER A parameter is invalid. > + @retval EFI_NOT_FOUND The required object information is not > found. > + @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration > + Manager is less than the Object size for= the > + requested object. > +*/ > +EFI_STATUS > +EFIAPI > +AddAcpiHeader ( > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST > CfgMgrProtocol, > + IN CONST ACPI_TABLE_GENERATOR * CONST Generator, > + IN OUT EFI_ACPI_DESCRIPTION_HEADER * CONST AcpiHeader, > + IN CONST UINT32 Length > + ) > +{ > + EFI_STATUS Status; > + CM_STD_OBJ_CONFIGURATION_MANAGER_INFO * CfgMfrInfo; > + > + ASSERT (CfgMgrProtocol !=3D NULL); > + ASSERT (Generator !=3D NULL); > + ASSERT (AcpiHeader !=3D NULL); > + ASSERT (Length >=3D sizeof (EFI_ACPI_DESCRIPTION_HEADER)); > + > + if ((CfgMgrProtocol =3D=3D NULL) || > + (Generator =3D=3D NULL) || > + (AcpiHeader =3D=3D NULL) || > + (Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) > + ) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status =3D GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to get Configuration Manager info. Status =3D %r\n"= , > + Status > + )); > + goto error_handler; > + } > + > + // UINT32 Signature > + AcpiHeader->Signature =3D Generator->AcpiTableSignature; > + // UINT32 Length > + AcpiHeader->Length =3D Length; > + // UINT8 Revision > + AcpiHeader->Revision =3D Generator->AcpiTableRevision; > + // UINT8 Checksum > + AcpiHeader->Checksum =3D 0; > + > + // UINT8 OemId[6] > + CopyMem (AcpiHeader->OemId, CfgMfrInfo->OemId, sizeof (AcpiHeader- > >OemId)); > + > + // UINT64 OemTableId > + AcpiHeader->OemTableId =3D Generator->CreatorId; > + AcpiHeader->OemTableId <<=3D 32; > + AcpiHeader->OemTableId |=3D Generator->AcpiTableSignature; > + > + // UINT32 OemRevision > + AcpiHeader->OemRevision =3D CfgMfrInfo->Revision; > + > + // UINT32 CreatorId > + AcpiHeader->CreatorId =3D Generator->CreatorId; > + // UINT32 CreatorRevision > + AcpiHeader->CreatorRevision =3D Generator->CreatorRevision; > + > +error_handler: > + return Status; > +} > diff --git > a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf > b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf > new file mode 100644 > index > 0000000000000000000000000000000000000000..5faadd198f053d3f628 > 1019aff97466932917b8d > --- /dev/null > +++ > b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf > @@ -0,0 +1,35 @@ > +## @file > +# > +# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. > +# > +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the > BSD License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +## > + > +[Defines] > + INF_VERSION =3D 0x00010019 > + BASE_NAME =3D DynamicTableHelperLib > + FILE_GUID =3D E315C738-3A39-4D0D-A0AF-8EDFA770AB39 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D TableHelperLib > + > +[Sources] > + TableHelper.c > + > +[Packages] > + MdePkg/MdePkg.dec > + DynamicTablesPkg/DynamicTablesPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Protocols] > + > +[Guids] > + > -- > 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' >=20