From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2a00:1450:400c:c09::22f; helo=mail-wm0-x22f.google.com; envelope-from=leif.lindholm@linaro.org; receiver=edk2-devel@lists.01.org Received: from mail-wm0-x22f.google.com (mail-wm0-x22f.google.com [IPv6:2a00:1450:400c:c09::22f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 05FBE20945BDA for ; Tue, 3 Oct 2017 09:00:17 -0700 (PDT) Received: by mail-wm0-x22f.google.com with SMTP id f4so9891382wme.0 for ; Tue, 03 Oct 2017 09:03:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=mK5NFOlmr+ewLnRRAME15q8/VvLgUhJrPwtlfYkTbwY=; b=Qa8h154y5F/uChbcB7+E1KIFZf85CEQN7eliNQ0n3woj7ZQQHA4ONFk4kyARH2xzQd HvCoIe0md9+75YPAsglsdwxtvwCGu2RlqLl3kCuRax4OSjuhcxsK7XLsAjL/EVm/zSwK 1mjzQX5sq7lEq/NMd330GP6egbIVUT0e7LA5A= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=mK5NFOlmr+ewLnRRAME15q8/VvLgUhJrPwtlfYkTbwY=; b=cZ8W5jsSc8msdOUtwpefjf4+YDO5InAku6bhwf0ob40efLtEsoy3MYyRATj9J4ggjf +WngRKk/ODqSYcTosDEKb0EwsOLaBFfQvscG+HFakUNVBSBC5vbnDjEejAVB0+ov7PkN kpZHaz8PGxTidGflLjibNaEK/DyIPgjb1gHsZUTjYpr9w8emlvY+6byqdJC1E5p/cdn1 exN9wKFafpF51vw61oCv3SOGFKDrVmsilnnTwVqiXw5qo1pFUIBwh7QmItpF3EK++PZ9 JEPHKyf1zsyuGdx1x4IpPkvOaa5y2SI/c0vugUpjWNcVrKplHzCVCuH7oujCWqvvYo9j DABw== X-Gm-Message-State: AHPjjUgrYuulzExei6QcdLDtEclhX1Xn8h2aS73dj1+ud/YWvFyM+FAI zUWSWsEfgDJwi4eZFsNgwNR0nA== X-Google-Smtp-Source: AOwi7QCe/HxUgIItdujR1b8gSATXEvLhngNkA46ZzCYVdeD/iuLQL1AXe2DV/kRVv3oj3Uqx/1lv3A== X-Received: by 10.28.214.212 with SMTP id n203mr12037225wmg.10.1507046616160; Tue, 03 Oct 2017 09:03:36 -0700 (PDT) Received: from bivouac.eciton.net (bivouac.eciton.net. [2a00:1098:0:86:1000:23:0:2]) by smtp.gmail.com with ESMTPSA id j5sm11010375wmg.8.2017.10.03.09.03.32 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 03 Oct 2017 09:03:33 -0700 (PDT) Date: Tue, 3 Oct 2017 17:03:30 +0100 From: Leif Lindholm To: "Zeng, Star" Cc: "evan.lloyd@arm.com" , "edk2-devel@lists.01.org" , Matteo.Carlini@arm.com, ard.biesheuvel@linaro.org, "Kinney, Michael D" , thomas.abraham@arm.com, Arvind.Chauhan@arm.com, "Yao, Jiewen" , leif.lindholm@linaro.org, Daniil.Egranov@arm.com Message-ID: <20171003153117.rrs4im264tgi2bkw@bivouac.eciton.net> References: <20171002194753.4316-1-evan.lloyd@arm.com> <20171002194753.4316-2-evan.lloyd@arm.com> <0C09AFA07DD0434D9E2A0C6AEB0483103B97E09A@shsmsx102.ccr.corp.intel.com> MIME-Version: 1.0 In-Reply-To: <0C09AFA07DD0434D9E2A0C6AEB0483103B97E09A@shsmsx102.ccr.corp.intel.com> User-Agent: NeoMutt/20170113 (1.7.2) Subject: Re: [PATCH 1/2] MdeModulePkg: Dynamic Tables Framework X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Oct 2017 16:00:19 -0000 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline (something funky going on with email addresses on cc, I've adjusted here) On Tue, Oct 03, 2017 at 02:34:52PM +0000, Zeng, Star wrote: > May I ask you are proposing > edk2-platforms(https://github.com/tianocore/edk2-platforms) change > or edk2 master(https://github.com/tianocore/edk2) change? MdeModulePkg exists only in edk2, so that is the intended target. (I expect to be back to patch reviewing again tomorrow.) Best Regards, Leif > Please note, we may have no/occasional email response during PRC holiday (10/1 - 10/8). > > Thanks, > Star > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of evan.lloyd@arm.com > Sent: Tuesday, October 3, 2017 3:48 AM > To: edk2-devel@lists.01.org > Cc: "Matteo.Carlini@arm.com"@arm.com; "nd@arm.com"@arm.com; "ard.biesheuvel@linaro.org"@arm.com; "thomas.abraham@arm.com"@arm.com; "Arvind.Chauhan@arm.com"@arm.com; "leif.lindholm@linaro.org"@arm.com; "Daniil.Egranov@arm.com"@arm.com > Subject: [edk2] [PATCH 1/2] MdeModulePkg: Dynamic Tables Framework > > From: Sami Mujawar > > 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. > > Traditionally the firmware tables are handcrafted using ACPI > Machine Language (AML), 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. > > 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. > > The framework also provisions 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. > > 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 implements the functionality required for ARM > architecture; the framework is extensible, and support for other > architectures can be easily added. > > Contributions from the community are invited. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Sami Mujawar > Signed-off-by: Evan Lloyd > --- > MdeModulePkg/MdeModulePkg.dec | 13 + > MdeModulePkg/Universal/DynamicTables/DynamicTables.dsc.inc | 45 ++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf | 49 ++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf | 47 ++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf | 46 ++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf | 47 ++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf | 47 ++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf | 44 ++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf | 44 ++ > MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelperLib.inf | 39 ++ > MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf | 57 ++ > MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.inf | 47 ++ > MdeModulePkg/Include/DynamicTables/AcpiTableGenerator.h | 280 ++++++++ > MdeModulePkg/Include/DynamicTables/ArmNameSpaceObjects.h | 367 ++++++++++ > MdeModulePkg/Include/DynamicTables/ConfigurationManagerHelper.h | 112 +++ > MdeModulePkg/Include/DynamicTables/ConfigurationManagerObject.h | 158 +++++ > MdeModulePkg/Include/DynamicTables/SmbiosTableGenerator.h | 235 +++++++ > MdeModulePkg/Include/DynamicTables/StandardNameSpaceObjects.h | 93 +++ > MdeModulePkg/Include/DynamicTables/TableGenerator.h | 235 +++++++ > MdeModulePkg/Include/Library/TableHelperLib.h | 67 ++ > MdeModulePkg/Include/Protocol/ConfigurationManagerProtocol.h | 121 ++++ > MdeModulePkg/Include/Protocol/DynamicTableFactoryProtocol.h | 113 +++ > MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactory.h | 91 +++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c | 440 ++++++++++++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c | 562 +++++++++++++++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c | 652 +++++++++++++++++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c | 732 ++++++++++++++++++++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c | 336 +++++++++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiRawLibArm/RawGenerator.c | 177 +++++ > MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c | 323 +++++++++ > MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelper.c | 165 +++++ > MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c | 227 ++++++ > MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c | 84 +++ > MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c | 227 ++++++ > MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.c | 531 ++++++++++++++ > MdeModulePkg/Universal/DynamicTables/DynamicTables.fdf.inc | 35 + > 36 files changed, 6888 insertions(+) > > diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec > index a3c0633ee1ec6ab7540a1b7221850e975f95ad80..de8a658c21d11ab1396bb543b026f94a396a0710 100644 > --- a/MdeModulePkg/MdeModulePkg.dec > +++ b/MdeModulePkg/MdeModulePkg.dec > @@ -7,6 +7,7 @@ > # Copyright (c) 2016, Linaro Ltd. All rights reserved.
> # (C) Copyright 2016 Hewlett Packard Enterprise Development LP
> # Copyright (c) 2017, AMD Incorporated. All rights reserved.
> +# 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. > @@ -556,6 +557,12 @@ [Protocols] > ## Include/Protocol/IoMmu.h > gEdkiiIoMmuProtocolGuid = { 0x4e939de9, 0xd948, 0x4b0f, { 0x88, 0xed, 0xe6, 0xe1, 0xce, 0x51, 0x7c, 0x1e } } > > + # Configuration Manager Protocol GUID > + gEfiConfigurationManagerProtocolGuid = { 0xd85a4835, 0x5a82, 0x4894, { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } } > + > + # Dynamic Table Factory Protocol GUID > + gEfiDynamicTableFactoryProtocolGuid = { 0x91d1e327, 0xfe5a, 0x49b8, { 0xab, 0x65, 0xe, 0xce, 0x2d, 0xdb, 0x45, 0xec } } > + > # > # [Error.gEfiMdeModulePkgTokenSpaceGuid] > # 0x80000001 | Invalid value provided. > @@ -867,6 +874,12 @@ [PcdsFixedAtBuild] > # @ValidList 0x80000006 | 0x03058002 > gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable|0x03058002|UINT32|0x30001040 > > + # Maximum number of Custom ACPI Generators > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomACPIGenerators|1|UINT16|0xC0000001 > + > + # Maximum number of Custom SMBIOS Generators > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomSMBIOSGenerators|1|UINT16|0xC0000002 > + > [PcdsFixedAtBuild, PcdsPatchableInModule] > ## Dynamic type PCD can be registered callback function for Pcd setting action. > # PcdMaxPeiPcdCallBackNumberPerPcdEntry indicates the maximum number of callback function > diff --git a/MdeModulePkg/Universal/DynamicTables/DynamicTables.dsc.inc b/MdeModulePkg/Universal/DynamicTables/DynamicTables.dsc.inc > new file mode 100644 > index 0000000000000000000000000000000000000000..548c77ad971f97c43da8f7ba1b69fa6948430c17 > --- /dev/null > +++ b/MdeModulePkg/Universal/DynamicTables/DynamicTables.dsc.inc > @@ -0,0 +1,45 @@ > +## @file > +# Dsc 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 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] > + > +[BuildOptions] > + *_*_*_ASL_FLAGS = -th -li > + > +[LibraryClasses.common] > + > +[Components.common] > + # > + # Dynamic Table Factory Dxe > + # > + MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf { > + > + TableHelperLib|MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelperLib.inf > + NULL|MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf > + NULL|MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf > + NULL|MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf > + NULL|MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf > + NULL|MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf > + NULL|MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf > + NULL|MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf > + } > + > + # > + # Dynamic Tables Manager Dxe > + # > + MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.inf { > + > + TableHelperLib|MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelperLib.inf > + } > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..591b6364ae86c885ca4768599d3eadf6d2842eff > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf > @@ -0,0 +1,49 @@ > +## @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. > +## > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = AcpiDbg2LibArm > + FILE_GUID = A17BA4F0-3DEB-4FE5-BD27-EC008E541B22 > + VERSION_STRING = 1.0 > + MODULE_TYPE = DXE_DRIVER > + LIBRARY_CLASS = NULL|DXE_DRIVER > + CONSTRUCTOR = AcpiDbg2LibConstructor > + DESTRUCTOR = AcpiDbg2LibDestructor > + > + > +[Sources] > + Dbg2Generator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + ArmPlatformPkg/ArmPlatformPkg.dec > + > +[LibraryClasses] > + BaseLib > + SerialPortLib > + > +[FixedPcd] > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits > + > +[Protocols] > + > + > +[Guids] > + > + > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..ae5239fd2a3e6f00574cf5f3bb4a561031e122be > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf > @@ -0,0 +1,47 @@ > +## @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. > +## > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = AcpiFadtLibArm > + FILE_GUID = 686FE5FE-B944-485F-8B1C-7D60E0056487 > + VERSION_STRING = 1.0 > + MODULE_TYPE = DXE_DRIVER > + LIBRARY_CLASS = NULL|DXE_DRIVER > + CONSTRUCTOR = AcpiFadtLibConstructor > + DESTRUCTOR = AcpiFadtLibDestructor > + > + > +[Sources] > + FadtGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > + > +[Protocols] > + > + > +[Guids] > + > + > + > + > + > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..be38489c2987a81d68effd9c05b731b17cb2819c > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf > @@ -0,0 +1,46 @@ > +## @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. > +## > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = AcpiGtdtLibArm > + FILE_GUID = 26490F7A-7FA2-423C-8939-C6206329BC37 > + VERSION_STRING = 1.0 > + MODULE_TYPE = DXE_DRIVER > + LIBRARY_CLASS = NULL|DXE_DRIVER > + CONSTRUCTOR = AcpiGtdtLibConstructor > + DESTRUCTOR = AcpiGtdtLibDestructor > + > + > +[Sources] > + GtdtGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[FixedPcd] > + > +[Protocols] > + > + > +[Guids] > + > + > + > + > + > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..9807e3fe75bb785c3b400410248e6434532f2147 > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf > @@ -0,0 +1,47 @@ > +## @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. > +## > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = AcpiMadtLibArm > + FILE_GUID = AF76C93B-41B5-454D-83CD-D2A80A1C1E38 > + VERSION_STRING = 1.0 > + MODULE_TYPE = DXE_DRIVER > + LIBRARY_CLASS = NULL|DXE_DRIVER > + CONSTRUCTOR = AcpiMadtLibConstructor > + DESTRUCTOR = AcpiMadtLibDestructor > + > + > +[Sources] > + MadtGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > + > +[Protocols] > + > + > +[Guids] > + > + > + > + > + > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..2f879dfee4b93a56a923340c4b416c6df9656618 > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf > @@ -0,0 +1,47 @@ > +## @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. > +## > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = AcpiMcfgLibArm > + FILE_GUID = 8C9BDCB2-72D4-4F30-A12D-1145C3807FF7 > + VERSION_STRING = 1.0 > + MODULE_TYPE = DXE_DRIVER > + LIBRARY_CLASS = NULL|DXE_DRIVER > + CONSTRUCTOR = AcpiMcfgLibConstructor > + DESTRUCTOR = AcpiMcfgLibDestructor > + > + > +[Sources] > + McfgGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > + > +[Protocols] > + > + > +[Guids] > + > + > + > + > + > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..db208bdeb8ffce085367ee865766a0a1bd90cb28 > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf > @@ -0,0 +1,44 @@ > +## @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. > +## > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = AcpiRawLibArm > + FILE_GUID = 20F31568-D687-49BA-B326-CCD9D38EDE16 > + VERSION_STRING = 1.0 > + MODULE_TYPE = DXE_DRIVER > + LIBRARY_CLASS = NULL|DXE_DRIVER > + CONSTRUCTOR = AcpiRawLibConstructor > + DESTRUCTOR = AcpiRawLibDestructor > + > + > +[Sources] > + RawGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > + > +[Protocols] > + > + > +[Guids] > + > + > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..3d47e6ae1f7995f76fe3e93093b0185e48ecae79 > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf > @@ -0,0 +1,44 @@ > +## @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. > +## > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = AcpiSpcrLibArm > + FILE_GUID = 55088136-7B78-4974-B1EE-F630150D0DE7 > + VERSION_STRING = 1.0 > + MODULE_TYPE = DXE_DRIVER > + LIBRARY_CLASS = NULL|DXE_DRIVER > + CONSTRUCTOR = AcpiSpcrLibConstructor > + DESTRUCTOR = AcpiSpcrLibDestructor > + > + > +[Sources] > + SpcrGenerator.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Pcd] > + > + > +[Protocols] > + > + > +[Guids] > + > + > diff --git a/MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelperLib.inf b/MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelperLib.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..38952fba1c8056bf0c581975ca974abbef1e8096 > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelperLib.inf > @@ -0,0 +1,39 @@ > +## @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. > +## > + > +[Defines] > + INF_VERSION = 0x00010019 > + BASE_NAME = DynamicTableHelperLib > + FILE_GUID = E315C738-3A39-4D0D-A0AF-8EDFA770AB39 > + VERSION_STRING = 1.0 > + MODULE_TYPE = DXE_DRIVER > + LIBRARY_CLASS = TableHelperLib > + > + > +[Sources] > + TableHelper.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + EmbeddedPkg/EmbeddedPkg.dec > + > +[LibraryClasses] > + BaseLib > + > +[Protocols] > + > + > +[Guids] > + > + > diff --git a/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..c58ac3a8d6d655e38cb8460a35ce256fc4e5ada6 > --- /dev/null > +++ b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf > @@ -0,0 +1,57 @@ > +## @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. > +## > + > + > +[Defines] > + INF_VERSION = 0x00010016 > + BASE_NAME = DynamicTableFactoryDxe > + FILE_GUID = FE846898-7403-4932-B8AD-A0491F0C2CBA > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + ENTRY_POINT = DynamicTableFactoryDxeInitialize > + > +# > +# The following information is for reference only and not required by the build tools. > +# > +# VALID_ARCHITECTURES = ARM AARCH64 > +# > + > +[Sources] > + DynamicTableFactoryDxe.c > + AcpiTableFactory/AcpiTableFactory.c > + SmbiosTableFactory/SmbiosTableFactory.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + > +[LibraryClasses] > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + PrintLib > + BaseLib > + MemoryAllocationLib > + TableHelperLib > + > +[FixedPcd] > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomACPIGenerators > + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomSMBIOSGenerators > + > +[Protocols] > + gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED > + gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED > + gEfiConfigurationManagerProtocolGuid > + gEfiDynamicTableFactoryProtocolGuid > + > +[Depex] > + TRUE > diff --git a/MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.inf > new file mode 100644 > index 0000000000000000000000000000000000000000..9c5a5f6207687ca90fa11188340d09c304fc34c0 > --- /dev/null > +++ b/MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.inf > @@ -0,0 +1,47 @@ > +## @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. > +## > + > +[Defines] > + INF_VERSION = 0x00010016 > + BASE_NAME = DynamicTableManagerDxe > + FILE_GUID = 89122868-BCFD-49E8-88A3-06635CB7B3CF > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + ENTRY_POINT = DynamicTableManagerDxeInitialize > + > +# > +# The following information is for reference only and not required by the build tools. > +# > +# VALID_ARCHITECTURES = ARM AARCH64 > +# > + > +[Sources] > + DynamicTableManagerDxe.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + > +[LibraryClasses] > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + PrintLib > + TableHelperLib > + > +[Protocols] > + gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED > + gEfiConfigurationManagerProtocolGuid > + gEfiDynamicTableFactoryProtocolGuid > + > +[Depex] > + TRUE > diff --git a/MdeModulePkg/Include/DynamicTables/AcpiTableGenerator.h b/MdeModulePkg/Include/DynamicTables/AcpiTableGenerator.h > new file mode 100644 > index 0000000000000000000000000000000000000000..3a07cd6e10217958d22a93060a0f9aa48947f264 > --- /dev/null > +++ b/MdeModulePkg/Include/DynamicTables/AcpiTableGenerator.h > @@ -0,0 +1,280 @@ > +/** @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 ACPI_TABLE_GENERATOR_H_ > +#define ACPI_TABLE_GENERATOR_H_ > + > +#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 generatos customized by the OEM. > + > +The Dynamic Tables Framework implements the following ACPI table generators: > + - RAW : This is the simplest ACPI table generator. It simply installs > + 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 clone of the RAW generator. The difference > + is in the way the ACPI Table Data is generated from an AML file. > + - SSDT : The SSDT generator is clone of the RAW generator. The difference > + is in the way the ACPI Table Data is generated from an AML file. > + - FADT : The FADT generator collates the required platform information for > + building the ACPI FADT table from the Configuration Manager and > + generates the FADT table. > + - MADT : The MADT generator collates the GIC information for building the > + ACPI MADT table from the Configuration Manager and generates the > + MADT table. > + - GTDT : The GTDT generator collates the Timer information for building the > + ACPI GTDT table from the Configuration Manager and generates the > + GTDT table. > + - DBG2 : The DBG2 generator collates the debug serial port information for > + building the DBG2 table from the Configuration Manager and > + generates the GTDT table. > + - SPCR : The SPCR generator collates the serial port information for > + building the SPCR table from the Configuration Manager and > + generates the SPCR table. > + - MCFG : The MCFG generator collates the PCI configuration space information > + for building the MCFG table from the Configuration Manager and > + generates the MCFG 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 = 0x0000, ///< Reserved. > + ESTD_ACPI_TABLE_ID_RAW, ///< RAW Generator. > + ESTD_ACPI_TABLE_ID_DSDT = ESTD_ACPI_TABLE_ID_RAW, ///< DSDT Generator. > + ESTD_ACPI_TABLE_ID_SSDT = 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_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) == ETableGeneratorTypeAcpi) > + > +/** 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) >= 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] Generator 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 * Generator, > + 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 to used by the > + Table Manager to give the generator an opportunity to free > + any resources allocated for building the ACPI table. > + > + @param [in] Generator 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 [in] Table Pointer to the generated 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 * Generator, > + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo, > + IN CONST EFI_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, > + IN EFI_ACPI_DESCRIPTION_HEADER ** 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 > + ); > + > +/** Unregister ACPI generator. > + > + This function is called by the ACPI table generator to unregister itself > + 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 > +UnRegisterAcpiTableGenerator ( > + IN CONST ACPI_TABLE_GENERATOR * CONST Generator > + ); > + > +#pragma pack() > + > +#endif // ACPI_TABLE_GENERATOR_H_ > + > diff --git a/MdeModulePkg/Include/DynamicTables/ArmNameSpaceObjects.h b/MdeModulePkg/Include/DynamicTables/ArmNameSpaceObjects.h > new file mode 100644 > index 0000000000000000000000000000000000000000..dbc909894d17ba9df7a78c2d8be797adabb49a34 > --- /dev/null > +++ b/MdeModulePkg/Include/DynamicTables/ArmNameSpaceObjects.h > @@ -0,0 +1,367 @@ > +/** @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 ARM_NAMESPACE_OBJECTS_H_ > +#define ARM_NAMESPACE_OBJECTS_H_ > +#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 > + EArmObjPlatformGenericWatchdogInfo, ///< 13 - Platform Generic Watchdog > + EArmObjPciConfigSpaceInfo, ///< 14 - PCI Configuration Space Info > + EArmObjHypervisorVendorIdentity, ///< 15 - Hypervisor Vendor Id > + 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 maintainence 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; > +} 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; > + > + /// Pointer to the GT Block timer > + /// frame list. > + CM_ARM_GTBLOCK_TIMER_FRAME_INFO * GTBlockTimerFrameList; > +} 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; > + > +#pragma pack() > + > +#endif // ARM_NAMESPACE_OBJECTS_H_ > diff --git a/MdeModulePkg/Include/DynamicTables/ConfigurationManagerHelper.h b/MdeModulePkg/Include/DynamicTables/ConfigurationManagerHelper.h > new file mode 100644 > index 0000000000000000000000000000000000000000..23edd7c343bd09476692d2fb8af088d95b8ff28d > --- /dev/null > +++ b/MdeModulePkg/Include/DynamicTables/ConfigurationManagerHelper.h > @@ -0,0 +1,112 @@ > +/** @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_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, > + OUT Type ** List, > + OUT UINTN * Count OPTIONAL > + ); > + > + Generated function parameters: > + @param [in] CfgMgrProtocol Pointer to the Configuration Manager protocol > + interface. > + @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, \ > + OUT Type ** List, \ > + OUT UINTN * CONST Count OPTIONAL \ > + ) \ > +{ \ > + EFI_STATUS Status; \ > + CM_OBJ_DESCRIPTOR CmObjectDesc; \ > + UINTN ObjCount = 0; \ > + if (List == NULL) { \ > + Status = EFI_INVALID_PARAMETER; \ > + DEBUG (( \ > + DEBUG_ERROR, \ > + "ERROR: Get" #CmObjectId ": Invalid out parameter for" \ > + " object list. Status = %r\n", \ > + Status \ > + )); \ > + goto error_handler; \ > + } \ > + Status = CfgMgrProtocol->GetObject ( \ > + CfgMgrProtocol, \ > + CREATE_CM_OBJECT_ID (CmObjectNameSpace, CmObjectId), \ > + &CmObjectDesc \ > + ); \ > + if (EFI_ERROR (Status)) { \ > + DEBUG (( \ > + DEBUG_WARN, \ > + "WARNING: Get" #CmObjectId ": Platform does not implement " \ > + #CmObjectId ". Status = %r\n", \ > + Status \ > + )); \ > + *List = NULL; \ > + goto error_handler; \ > + } \ > + if (CmObjectDesc.Size < sizeof (Type)) { \ > + DEBUG (( \ > + DEBUG_ERROR, \ > + "ERROR: Get" #CmObjectId ": " #CmObjectId \ > + ": Buffer too small, size = 0x%x\n", \ > + CmObjectDesc.Size \ > + )); \ > + ASSERT (CmObjectDesc.Size >= sizeof (Type)); \ > + Status = EFI_BAD_BUFFER_SIZE; \ > + goto error_handler; \ > + } \ > + ObjCount = CmObjectDesc.Size / sizeof (Type); \ > + *List = (Type*)CmObjectDesc.Data; \ > +error_handler: \ > + if (Count != NULL) { \ > + *Count = ObjCount; \ > + } \ > + return Status; \ > +} > + > +#endif // CONFIGURATION_MANAGER_HELPER_H_ > diff --git a/MdeModulePkg/Include/DynamicTables/ConfigurationManagerObject.h b/MdeModulePkg/Include/DynamicTables/ConfigurationManagerObject.h > new file mode 100644 > index 0000000000000000000000000000000000000000..99afab094328cf830831899011a7f6fca1d6e5f2 > --- /dev/null > +++ b/MdeModulePkg/Include/DynamicTables/ConfigurationManagerObject.h > @@ -0,0 +1,158 @@ > +/** @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_OBJECT_H_ > +#define CONFIGURATION_MANAGER_OBJECT_H_ > + > +#pragma pack(1) > + > +/** The CM_OBJECT_ID type is used to identify the Configration Manager objects. > + > + Description of Configuration Manager Object ID > +________________________________________________________________________________ > +|31 |30 |29 |28 || 27 | 26 | 25 | 24 || 23 | 22 | 21 | 20 || 19 | 18 | 17 | 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 > + 12 - Generic Timer Info > + 13 - Platform GT Block Info > + 14 - Platform Generic Watchdog > + 15 - PCI Configuration Space Info > + 16 - Hypervisor Vendor Id > +*/ > +typedef UINT32 CM_OBJECT_ID; > + > +/** The EOBJECT_NAMESPACE_ID enum describes the defined namespaces > + for the Confguration Manager Objects. > +*/ > +typedef enum ObjectNameSpaceID { > + EObjNameSpaceStandard, ///< Standard Objects Namespace > + EObjNameSpaceArm, ///< ARM Objects Namespace > + EObjNameSpaceOem = 0x8, ///< OEM Objects Namespace > + EObjNameSpaceMax > +} EOBJECT_NAMESPACE_ID; > + > +/** The CM_OBJ_DESCRIPTOR structure describes the Configuration > + Manager Object descriptor. The Configuration Manager Protocol > + interface uses this descriptor to return the Configuration > + Manager Objects. > +*/ > +typedef struct CmObjDescriptor { > + /// Size of the Object or Object List > + /// described by this descriptor. > + UINT32 Size; > + > + /// Pointer to the Object or Object List > + /// described by this descriptor. > + UINTN * 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) >> 28) & 0xF) > + > +/** 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) & 0xFF) > + > +/** 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) & 0xF) << 28) | ((ObjectId) & 0xF)) > + > +/** 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/MdeModulePkg/Include/DynamicTables/SmbiosTableGenerator.h b/MdeModulePkg/Include/DynamicTables/SmbiosTableGenerator.h > new file mode 100644 > index 0000000000000000000000000000000000000000..10d29be800a0c126ed32dcfa070f1473a8aee7a9 > --- /dev/null > +++ b/MdeModulePkg/Include/DynamicTables/SmbiosTableGenerator.h > @@ -0,0 +1,235 @@ > +/** @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. > + > +**/ > + > +#ifndef SMBIOS_TABLE_GENERATOR_H_ > +#define SMBIOS_TABLE_GENERATOR_H_ > + > +#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 = 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 = (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) == \ > + 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) >= 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 > + ); > + > +/** Unregister SMBIOS generator. > + > + This function is called by the SMBIOS table generator to unregister itself > + 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 > +UnRegisterSmbiosTableGenerator ( > + IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator > + ); > +#pragma pack() > + > +#endif // SMBIOS_TABLE_GENERATOR_H_ > + > diff --git a/MdeModulePkg/Include/DynamicTables/StandardNameSpaceObjects.h b/MdeModulePkg/Include/DynamicTables/StandardNameSpaceObjects.h > new file mode 100644 > index 0000000000000000000000000000000000000000..76ae3f2208a5c80f0ca10b75e5df94cbb43e4688 > --- /dev/null > +++ b/MdeModulePkg/Include/DynamicTables/StandardNameSpaceObjects.h > @@ -0,0 +1,93 @@ > +/** @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) > + > +/** The ESTD_OBJECT_ID enum describes the Object IDs > + in the Standard Namespace. > +*/ > +typedef enum StdObjectID { > + EStdObjCfgMgrInfo = 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/MdeModulePkg/Include/DynamicTables/TableGenerator.h b/MdeModulePkg/Include/DynamicTables/TableGenerator.h > new file mode 100644 > index 0000000000000000000000000000000000000000..93d557273459948f5211e1c26a6028fc12b181fb > --- /dev/null > +++ b/MdeModulePkg/Include/DynamicTables/TableGenerator.h > @@ -0,0 +1,235 @@ > +/** @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 = 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 = 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) > + > +/** 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) >> 28) > + > +/** 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) >> 31) > + > +/** 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) == \ > + 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) << 28) & TABLE_TYPE_MASK) | \ > + (((TableNameSpaceId) << 31) & TABLE_NAMESPACEID_MASK) | \ > + ((TableId) & TABLE_ID_MASK) \ > + ) > + > +/** 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) & 0xFFFF) << 16) | ((Minor) & 0xFFFF)) > + > +/** This macro returns the Major revison > + > + 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) >> 16) & 0xFFFF) > + > +/** This macro returns the Minor revison > + > + 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) & 0xFFFF) > + > +#endif // TABLE_GENERATOR_H_ > + > diff --git a/MdeModulePkg/Include/Library/TableHelperLib.h b/MdeModulePkg/Include/Library/TableHelperLib.h > new file mode 100644 > index 0000000000000000000000000000000000000000..4b22e024dee1a311e4e4b532371ccef94bc02be3 > --- /dev/null > +++ b/MdeModulePkg/Include/Library/TableHelperLib.h > @@ -0,0 +1,67 @@ > +/** @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. > + > +**/ > + > +#ifndef TABLE_HELPER_LIB_H_ > +#define TABLE_HELPER_LIB_H_ > + > +/** 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 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 > + ); > + > +#endif // TABLE_HELPER_LIB_H_ > diff --git a/MdeModulePkg/Include/Protocol/ConfigurationManagerProtocol.h b/MdeModulePkg/Include/Protocol/ConfigurationManagerProtocol.h > new file mode 100644 > index 0000000000000000000000000000000000000000..387935943648654ef095720dec452d1c15b8fc11 > --- /dev/null > +++ b/MdeModulePkg/Include/Protocol/ConfigurationManagerProtocol.h > @@ -0,0 +1,121 @@ > +/** @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_ > + > +/** 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 Poiner to the Configuration Manager Protocol. > + @param [in] CmObjectId The Configuration Manager Object ID. > + @param [out] CmObject Pointer to the Configuration Manager Object > + descrptor describing the requested Object. > + > + @retval Returns: > + EFI_SUCCESS Success. > + EFI_INVALID_PARAMETER A parameter is invalid. > + EFI_NOT_FOUND The required object information is not found. > + EFI_BAD_BUFFER_SIZE The size returned by the Configuration Manager > + is less than the Object size for the requested > + 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 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 Poiner to the Configuration Manager Protocol. > + @param [in] CmObjectId The Configuration Manager Object ID. > + @param [out] CmObject Pointer to the Configuration Manager Object > + descrptor describing the Object. > + > + @retval Returns: > + EFI_SUCCESS The operation completed successfully. > + EFI_INVALID_PARAMETER A parameter is invalid. > + EFI_NOT_FOUND The required object information is not found. > + EFI_BAD_BUFFER_SIZE The size returned by the Configuration Manager > + is less than the Object size for the requested > + object. > + 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 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; > + > +/** A global GUID defined in the protocol section of the > + MdeModulePkg.dec file. > +*/ > +extern EFI_GUID gEfiConfigurationManagerProtocolGuid; > + > +#pragma pack() > + > +#endif // CONFIGURATION_MANAGER_PROTOCOL_H_ > diff --git a/MdeModulePkg/Include/Protocol/DynamicTableFactoryProtocol.h b/MdeModulePkg/Include/Protocol/DynamicTableFactoryProtocol.h > new file mode 100644 > index 0000000000000000000000000000000000000000..5ece83bb44ec2d88fbd3b49b0e7bdc6314c332c7 > --- /dev/null > +++ b/MdeModulePkg/Include/Protocol/DynamicTableFactoryProtocol.h > @@ -0,0 +1,113 @@ > +/** @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 > +**/ > + > +#ifndef DYNAMIC_TABLE_FACTORY_PROTOCOL_H_ > +#define DYNAMIC_TABLE_FACTORY_PROTOCOL_H_ > + > +#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 Poiner 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 paramter 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 Poiner 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 > + ); > + > +/** 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; > + > + /// Pointer to the data structure that holds the > + /// list of registered table generators > + EFI_DYNAMIC_TABLE_FACTORY_INFO * TableFactoryInfo; > +} EFI_DYNAMIC_TABLE_FACTORY_PROTOCOL; > + > +/** A global GUID defined in the protocol section of the > + MdeModulePkg.dec file. > +*/ > +extern EFI_GUID gEfiDynamicTableFactoryProtocolGuid; > + > +#pragma pack() > + > +#endif // DYNAMIC_TABLE_FACTORY_PROTOCOL_H_ > diff --git a/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactory.h b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactory.h > new file mode 100644 > index 0000000000000000000000000000000000000000..88d9e5a4a58307ea26ddbe75579cddc3333ccc34 > --- /dev/null > +++ b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactory.h > @@ -0,0 +1,91 @@ > +/** @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 > +**/ > + > +#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)]; > +} EFI_DYNAMIC_TABLE_FACTORY_INFO; > + > +/** Return a pointer to the ACPI table generator. > + > + @param [in] This Poiner to the Dynamic Table Factory Protocol. > + @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 Poiner to the Dynamic Table Factory Protocol. > + @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 > + ); > + > +#pragma pack() > + > +#endif // DYNAMIC_TABLE_FACTORY_H_ > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c > new file mode 100644 > index 0000000000000000000000000000000000000000..1bf20424b942ac08fe93d157f3869de53577cf0e > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c > @@ -0,0 +1,440 @@ > +/** @file > + DBG2 Table Generator > + > + 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 > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard DBG2 Table Generator > + > + Generates the ACPI DBG2 Port Table for ARM UARTs > + as specified by the Microsoft Debug Port Table 2 (DBG2) > + Specification - December 10, 2015. > + > + 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) > + > +/** Define the number of debug ports represented by the Table. > +*/ > +#define DBG2_NUM_DEBUG_PORTS 1 > + > +/** Define the number of Generic Address Registers > + presented in the debug device information. > +*/ > +#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS 1 > + > +/** Define the index for the debug port 1. > +*/ > +#define DBG_PORT_INDEX_PORT1 0 > + > +/** Define the string representing the debug port 1 name. > +*/ > +#define NAME_STR_PORT1 "COM1" > + > +/** Define the length of the namespace string. > +*/ > +#define DBG2_NAMESPACESTRING_FIELD_SIZE sizeof (NAME_STR_PORT1) > + > +/** Define the PL011 UART address range length. > +*/ > +#define PL011_UART_LENGTH 0x1000 > + > +/** This structure provides the OS with the information required 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_1_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister; > + > + /// The address size > + UINT32 AddressSize; > + > + /// The debug port name string > + UINT8 NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE]; > +} DBG2_DEBUG_DEVICE_INFORMATION; > + > +/** This structure represents 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 initalizing 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_1_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 = { > + { > + ACPI_HEADER ( > + EFI_ACPI_6_1_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, > + EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART, > + 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 != NULL); > + > + // Initialize the Serial Debug UART > + DEBUG ((DEBUG_INFO, "Initializing Serial Debug UART...\n")); > + ReceiveFifoDepth = 0; // Use the default value for FIFO depth > + Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity); > + DataBits = FixedPcdGet8 (PcdUartDefaultDataBits); > + StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits); > + > + BaudRate = SerialPortInfo->BaudRate; > + Status = PL011UartInitializePort ( > + (UINTN)SerialPortInfo->BaseAddress, > + SerialPortInfo->Clock, > + &BaudRate, > + &ReceiveFifoDepth, > + &Parity, > + &DataBits, > + &StopBits > + ); > + > + DEBUG ((DEBUG_INFO, "Debug UART Configuration:\n")); > + DEBUG ((DEBUG_INFO, "UART Base = 0x%lx\n", SerialPortInfo->BaseAddress)); > + DEBUG ((DEBUG_INFO, "Clock = %d\n", SerialPortInfo->Clock)); > + DEBUG ((DEBUG_INFO, "Baudrate = %ld\n", BaudRate)); > + DEBUG ((DEBUG_INFO, "Configuring Debug UART. Status = %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 Confguration 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 = NULL; > + > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (Table != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + *Table = NULL; > + > + Status = GetEArmObjSerialDebugPortInfo ( > + CfgMgrProtocol, > + &SerialPortInfo, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: DBG2: Failed to get serial port information. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Status = 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 = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + AcpiDbg2.Dbg2DeviceInfo[DBG_PORT_INDEX_PORT1].BaseAddressRegister.Address = > + SerialPortInfo->BaseAddress; > + > + Status = SetupDebugUart (SerialPortInfo); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: DBG2: Failed to configure debug serial port. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + *Table = (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiDbg2; > + > +error_handler: > + return Status; > +} > + > +/** Free any resources allocated for constructing the DBG2. > + > + @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] Table Pointer to the ACPI Table. > + > + @retval EFI_SUCCESS The resources were freed successfully. > +*/ > +STATIC > +EFI_STATUS > +FreeDbg2TableResources ( > + 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 EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + return EFI_SUCCESS; > +} > + > +/** 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 = { > + // 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_1_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, > + // Free Resource function > + FreeDbg2TableResources > +}; > + > +/** 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; > + > + Status = RegisterAcpiTableGenerator (&Dbg2Generator); > + DEBUG ((DEBUG_INFO, "DBG2: Register Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + > + return Status; > +} > + > +/** Un-register 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 un-registered. > + @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; > + > + Status = UnRegisterAcpiTableGenerator (&Dbg2Generator); > + DEBUG ((DEBUG_INFO, "DBG2: Unregister Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c > new file mode 100644 > index 0000000000000000000000000000000000000000..75e0b7b50ef34a71cc091db50667a19b40b3f1c9 > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c > @@ -0,0 +1,562 @@ > +/** @file > + FADT Table Generator > + > + 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 > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard FADT Generator > + > + Generates the ACPI FADT Table as specified by the > + ACPI 6.1 Specification - January, 2016. > + > +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_1_HW_REDUCED_ACPI | \ > + EFI_ACPI_6_1_LOW_POWER_S0_IDLE_CAPABLE) > + > +#pragma pack(1) > + > +/** The AcpiFadt is a template EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE > + structure used for generating the FADT Table. > + Note: fields marked with "{Template}" will be updated dynamically. > +*/ > +STATIC > +EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt = { > + ACPI_HEADER ( > + EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, > + EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE, > + EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_REVISION > + ), > + // UINT32 FirmwareCtrl > + 0, > + // UINT32 Dsdt > + 0, > + // UINT8 Reserved0 > + EFI_ACPI_RESERVED_BYTE, > + // UINT8 PreferredPmProfile > + EFI_ACPI_6_1_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_1_GENERIC_ADDRESS_STRUCTURE ResetReg > + NULL_GAS, > + // UINT8 ResetValue > + 0, > + // UINT16 ArmBootArch > + EFI_ACPI_6_1_ARM_PSCI_COMPLIANT, // {Template}: ARM Boot Architecture Flags > + // UINT8 MinorRevision > + EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION, > + // UINT64 XFirmwareCtrl > + 0, > + // UINT64 XDsdt > + 0, > + // EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk > + NULL_GAS, > + // EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk > + NULL_GAS, > + // EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk > + NULL_GAS, > + // EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk > + NULL_GAS, > + // EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk > + NULL_GAS, > + // EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk > + NULL_GAS, > + // EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XGpe0Blk > + NULL_GAS, > + // EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE XGpe1Blk > + NULL_GAS, > + // EFI_ACPI_6_1_GENERIC_ADDRESS_STRUCTURE SleepControlReg > + NULL_GAS, > + // EFI_ACPI_6_1_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 > + ); > + > +/** 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 = NULL; > + > + ASSERT (CfgMgrProtocol != NULL); > + > + // Get the Power Management Profile from the Platform Configuration Manager > + Status = GetEArmObjPowerManagementProfileInfo ( > + CfgMgrProtocol, > + &PmProfile, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Failed to get Power Management Profile information." \ > + " Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "FADT: PreferredPmProfile = 0x%x\n", > + PmProfile->PowerManagementProfile > + )); > + > + AcpiFadt.PreferredPmProfile = 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 = NULL; > + > + ASSERT (CfgMgrProtocol != NULL); > + > + // Get the Boot Architecture flags from the Platform Configuration Manager > + Status = GetEArmObjBootArchInfo ( > + CfgMgrProtocol, > + &BootArchInfo, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Failed to get Boot Architecture flags. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "FADT BootArchFlag = 0x%x\n", > + BootArchInfo->BootArchFlags > + )); > + > + AcpiFadt.ArmBootArch = 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 = NULL; > + > + ASSERT (CfgMgrProtocol != NULL); > + > + // Get the Hypervisor Vendor ID from the Platform Configuration Manager > + Status = GetEArmObjHypervisorVendorIdentity ( > + CfgMgrProtocol, > + &HypervisorVendorInfo, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + if (Status == EFI_NOT_FOUND) { > + DEBUG (( > + DEBUG_INFO, > + "INFO: FADT: Platform does not have a Hypervisor Vendor ID. Status = %r\n", > + Status > + )); > + } else { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Failed to get Hypervisor Vendor ID. Status = %r\n", > + Status > + )); > + } > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "FADT: EArmObjHypervisorVendorIdentity = 0x%lx\n", > + HypervisorVendorInfo->HypervisorVendorId > + )); > + > + AcpiFadt.HypervisorVendorIdentity = HypervisorVendorInfo->HypervisorVendorId; > + > +error_handler: > + return Status; > +} > + > +/** Construct the FADT table. > + > + This function invokes the Confguration 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 != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (Table != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + *Table = NULL; > + > + Status = AddAcpiHeader ( > + CfgMgrProtocol, > + This, > + (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiFadt, > + sizeof (EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE) > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: FADT: Failed to add ACPI header. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + // Update PmProfile Info > + Status = FadtAddPmProfileInfo (CfgMgrProtocol); > + if (EFI_ERROR (Status)) { > + goto error_handler; > + } > + > + // Update BootArch Info > + Status = 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 = FadtAddHypervisorVendorId (CfgMgrProtocol); > + if (EFI_ERROR (Status)) { > + if (Status == 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 = %r", > + Status > + )); > + goto error_handler; > + } > + } > + > + *Table = (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiFadt; > + Status = EFI_SUCCESS; > +error_handler: > + return Status; > +} > + > +/** Free any resources allocated for constructing the FADT. > + > + @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] Table Pointer to the ACPI Table. > + > + @retval EFI_SUCCESS The resources were freed successfully. > +*/ > +STATIC > +EFI_STATUS > +FreeFadtTableResources ( > + 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 EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + return EFI_SUCCESS; > +} > + > +/** 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 = { > + // 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_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_REVISION, > + // Creator ID > + TABLE_GENERATOR_CREATOR_ID_ARM, > + // Creator Revision > + FADT_GENERATOR_REVISION, > + // Build Table function > + BuildFadtTable, > + // Free Resource function > + FreeFadtTableResources > +}; > + > +/** 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; > + > + Status = RegisterAcpiTableGenerator (&FadtGenerator); > + DEBUG ((DEBUG_INFO, "FADT: Register Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > +/** Un-register 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 un-registered. > + @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; > + > + Status = UnRegisterAcpiTableGenerator (&FadtGenerator); > + DEBUG ((DEBUG_INFO, "FADT: Unregister Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c > new file mode 100644 > index 0000000000000000000000000000000000000000..8a243e7d2ef2fa5806116030c74337f1f8e72e8b > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c > @@ -0,0 +1,652 @@ > +/** @file > + GTDT Table Generator > + > + 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 > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard GTDT Generator > + > + Generates the ACPI GTDT Table as specified by the > + ACPI 6.1 Specification - January, 2016. > + > +Requirements: > + The following Configuration Manager Object(s) are required by > + this Generator: > + - EArmObjGenericTimerInfo > + - EArmObjPlatformGenericWatchdogInfo (OPTIONAL) > + - EArmObjPlatformGTBlockInfo (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 > + ); > + > +/** 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_1_GENERIC_TIMER_DESCRIPTION_TABLE * CONST Gtdt, > + IN CONST UINT32 PlatformTimerCount > +) > +{ > + EFI_STATUS Status; > + CM_ARM_GENERIC_TIMER_INFO * GenericTimerInfo = NULL; > + > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (Gtdt != NULL); > + > + Status = GetEArmObjGenericTimerInfo ( > + CfgMgrProtocol, > + &GenericTimerInfo, > + NULL > + ); > + > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to get GenericTimerInfo. Status = %r\n", > + Status > + )); > + return Status; > + } > + > + Gtdt->CntControlBasePhysicalAddress = > + GenericTimerInfo->CounterControlBaseAddress; > + Gtdt->Reserved = EFI_ACPI_RESERVED_DWORD; > + Gtdt->CntReadBasePhysicalAddress = > + GenericTimerInfo->CounterReadBaseAddress; > + Gtdt->PlatformTimerCount = PlatformTimerCount; > + Gtdt->PlatformTimerOffset = (PlatformTimerCount == 0) ? 0 : > + sizeof (EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE); > + > + Gtdt->SecurePL1TimerGSIV = GenericTimerInfo->SecurePL1TimerGSIV; > + Gtdt->SecurePL1TimerFlags = GenericTimerInfo->SecurePL1TimerFlags; > + Gtdt->NonSecurePL1TimerGSIV = GenericTimerInfo->NonSecurePL1TimerGSIV; > + Gtdt->NonSecurePL1TimerFlags = GenericTimerInfo->NonSecurePL1TimerFlags; > + Gtdt->VirtualTimerGSIV = GenericTimerInfo->VirtualTimerGSIV; > + Gtdt->VirtualTimerFlags = GenericTimerInfo->VirtualTimerFlags; > + Gtdt->NonSecurePL2TimerGSIV = GenericTimerInfo->NonSecurePL2TimerGSIV; > + Gtdt->NonSecurePL2TimerFlags = GenericTimerInfo->NonSecurePL2TimerFlags; > + > + 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 the > + GTDT Table. > + @param [in] WatchdogInfoList Pointer to the watchdog information list. > + @param [in] WatchdogCount Platform timer count. > +*/ > +STATIC > +VOID > +AddGenericWatchdogList ( > + IN EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE * CONST Gtdt, > + IN CONST UINTN WatchdogOffset, > + IN CONST CM_ARM_GENERIC_WATCHDOG_INFO * CONST WatchdogInfoList, > + IN CONST UINTN WatchdogCount > + ) > +{ > + UINTN idx; > + EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE * Watchdog; > + > + ASSERT (Gtdt != NULL); > + ASSERT (WatchdogInfoList != NULL); > + > + Watchdog = (EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE *) > + ((UINT8*)Gtdt + WatchdogOffset); > + > + for (idx = 0; idx < WatchdogCount; idx++) { > + // Add watchdog entry > + DEBUG ((DEBUG_INFO, "GTDT: Watchdog[%d] = 0x%p\n", idx, &Watchdog[idx])); > + Watchdog[idx].Type = EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG; > + Watchdog[idx].Length = > + sizeof (EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE); > + Watchdog[idx].Reserved = EFI_ACPI_RESERVED_BYTE; > + Watchdog[idx].RefreshFramePhysicalAddress = > + WatchdogInfoList[idx].RefreshFrameAddress; > + Watchdog[idx].WatchdogControlFramePhysicalAddress = > + WatchdogInfoList[idx].ControlFrameAddress; > + Watchdog[idx].WatchdogTimerGSIV = WatchdogInfoList[idx].TimerGSIV; > + Watchdog[idx].WatchdogTimerFlags = WatchdogInfoList[idx].Flags; > + > + } // 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_1_GTDT_GT_BLOCK_TIMER_STRUCTURE * CONST GtBlockFrame, > + IN CONST CM_ARM_GTBLOCK_TIMER_FRAME_INFO * CONST GTBlockTimerFrameList, > + IN CONST UINTN GTBlockFrameCount > +) > +{ > + UINTN idx; > + > + ASSERT (GtBlockFrame != NULL); > + ASSERT (GTBlockTimerFrameList != NULL); > + > + if (GTBlockFrameCount > 8) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: GT Block Frame Count %d is greater than 8\n", > + GTBlockFrameCount > + )); > + ASSERT (GTBlockFrameCount <= 8); > + return EFI_INVALID_PARAMETER; > + } > + > + for (idx = 0; idx < GTBlockFrameCount; idx++) { > + DEBUG (( > + DEBUG_INFO, > + "GTDT: GtBlockFrame[%d] = 0x%p\n", > + idx, > + GtBlockFrame[idx] > + )); > + > + GtBlockFrame[idx].GTFrameNumber = GTBlockTimerFrameList[idx].FrameNumber; > + GtBlockFrame[idx].Reserved[0] = EFI_ACPI_RESERVED_BYTE; > + GtBlockFrame[idx].Reserved[1] = EFI_ACPI_RESERVED_BYTE; > + GtBlockFrame[idx].Reserved[2] = EFI_ACPI_RESERVED_BYTE; > + > + GtBlockFrame[idx].CntBaseX = > + GTBlockTimerFrameList[idx].PhysicalAddressCntBase; > + GtBlockFrame[idx].CntEL0BaseX = > + GTBlockTimerFrameList[idx].PhysicalAddressCntEL0Base; > + > + GtBlockFrame[idx].GTxPhysicalTimerGSIV = > + GTBlockTimerFrameList[idx].PhysicalTimerGSIV; > + GtBlockFrame[idx].GTxPhysicalTimerFlags = > + GTBlockTimerFrameList[idx].PhysicalTimerFlags; > + > + GtBlockFrame[idx].GTxVirtualTimerGSIV = > + GTBlockTimerFrameList[idx].VirtualTimerGSIV; > + GtBlockFrame[idx].GTxVirtualTimerFlags = > + GTBlockTimerFrameList[idx].VirtualTimerFlags; > + > + GtBlockFrame[idx].GTxCommonFlags = GTBlockTimerFrameList[idx].CommonFlags; > + > + } // for > + return EFI_SUCCESS; > +} > + > +/** Add the GT Block Timers in the GTDT Table. > + > + @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 EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE * CONST Gtdt, > + IN CONST UINTN GTBlockOffset, > + IN CONST CM_ARM_GTBLOCK_INFO * CONST GTBlockInfo, > + IN CONST UINTN BlockTimerCount > +) > +{ > + EFI_STATUS Status; > + UINTN idx; > + EFI_ACPI_6_1_GTDT_GT_BLOCK_STRUCTURE * GTBlock; > + EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_STRUCTURE * GtBlockFrame; > + > + ASSERT (Gtdt != NULL); > + ASSERT (GTBlockInfo != NULL); > + > + GTBlock = (EFI_ACPI_6_1_GTDT_GT_BLOCK_STRUCTURE *)((UINT8*)Gtdt + > + GTBlockOffset); > + > + for (idx = 0; idx < BlockTimerCount; idx++) { > + DEBUG ((DEBUG_INFO, "GTDT: GTBlock[%d] = 0x%p\n", > + idx, > + GTBlock > + )); > + > + GTBlock->Type = EFI_ACPI_6_1_GTDT_GT_BLOCK; > + GTBlock->Length = sizeof (EFI_ACPI_6_1_GTDT_GT_BLOCK_STRUCTURE) + > + (sizeof (EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_STRUCTURE) * > + GTBlockInfo[idx].GTBlockTimerFrameCount); > + > + GTBlock->Reserved = EFI_ACPI_RESERVED_BYTE; > + GTBlock->CntCtlBase = GTBlockInfo[idx].GTBlockPhysicalAddress; > + GTBlock->GTBlockTimerCount = GTBlockInfo[idx].GTBlockTimerFrameCount; > + GTBlock->GTBlockTimerOffset = > + sizeof (EFI_ACPI_6_1_GTDT_GT_BLOCK_STRUCTURE); > + > + GtBlockFrame = (EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_STRUCTURE*) > + ((UINT8*)GTBlock + GTBlock->GTBlockTimerOffset); > + > + // Add GT Block Timer frames > + Status = AddGTBlockTimerFrames ( > + GtBlockFrame, > + GTBlockInfo[idx].GTBlockTimerFrameList, > + GTBlockInfo[idx].GTBlockTimerFrameCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to add Generic Timer Frames. Status = %r\n", > + Status > + )); > + return Status; > + } > + > + // Next GTBlock > + GTBlock = (EFI_ACPI_6_1_GTDT_GT_BLOCK_STRUCTURE *)((UINT8*)GTBlock + > + GTBlock->Length); > + }// for > + return EFI_SUCCESS; > +} > + > +/** Construct the GTDT ACPI table. > + > + Called by the Dynamic Table Manager, this function invokes the > + Confguration 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; > + UINTN TableSize; > + UINTN PlatformTimerCount = 0; > + UINTN WatchdogCount; > + UINTN BlockTimerCount; > + CM_ARM_GENERIC_WATCHDOG_INFO * WatchdogInfoList = NULL; > + CM_ARM_GTBLOCK_INFO * GTBlockInfo = NULL; > + EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE * Gtdt; > + UINTN idx; > + UINTN GTBlockOffset; > + UINTN WatchdogOffset = 0; > + > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (Table != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + *Table = NULL; > + Status = GetEArmObjPlatformGTBlockInfo ( > + CfgMgrProtocol, > + >BlockInfo, > + &BlockTimerCount > + ); > + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to Get Platform GT Block Information." \ > + " Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Status = GetEArmObjPlatformGenericWatchdogInfo ( > + CfgMgrProtocol, > + &WatchdogInfoList, > + &WatchdogCount > + ); > + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to Get Platform Generic Watchdog Information." \ > + " Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "GTDT: BlockTimerCount = %d, WatchdogCount = %d\n", > + BlockTimerCount, > + WatchdogCount > + )); > + > + // Calculate the GTDT Table Size > + TableSize = sizeof (EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE); > + if (BlockTimerCount != 0) { > + GTBlockOffset = TableSize; > + PlatformTimerCount += BlockTimerCount; > + TableSize += (sizeof (EFI_ACPI_6_1_GTDT_GT_BLOCK_STRUCTURE) * > + BlockTimerCount); > + > + for (idx = 0; idx < BlockTimerCount; idx++) { > + if (GTBlockInfo[idx].GTBlockTimerFrameCount > 8) { > + Status = EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "GTDT: GTBockFrameCount cannot be more than 8." \ > + " GTBockFrameCount = %d, Status = %r\n", > + GTBlockInfo[idx].GTBlockTimerFrameCount, > + Status > + )); > + goto error_handler; > + } > + TableSize += (sizeof (EFI_ACPI_6_1_GTDT_GT_BLOCK_TIMER_STRUCTURE) * > + GTBlockInfo[idx].GTBlockTimerFrameCount); > + } > + > + DEBUG (( > + DEBUG_INFO, > + "GTDT: GTBockOffset = 0x%x, PLATFORM_TIMER_COUNT = %d\n", > + GTBlockOffset, > + PlatformTimerCount > + )); > + } > + > + if (WatchdogCount != 0) { > + WatchdogOffset = TableSize; > + PlatformTimerCount += WatchdogCount; > + TableSize += (sizeof (EFI_ACPI_6_1_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE) * > + WatchdogCount); > + DEBUG (( > + DEBUG_INFO, > + "GTDT: WatchdogOffset = 0x%x, PLATFORM_TIMER_COUNT = %d\n", > + WatchdogOffset, > + PlatformTimerCount > + )); > + } > + > + *Table = (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize); > + if (*Table == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to allocate memory for GTDT Table, Size = %d," \ > + " Status = %r\n", > + TableSize, > + Status > + )); > + goto error_handler; > + } > + > + Gtdt = (EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE*)*Table; > + DEBUG (( > + DEBUG_INFO, > + "GTDT: Gtdt = 0x%p TableSize = 0x%x\n", > + Gtdt, > + TableSize > + )); > + > + Status = AddAcpiHeader (CfgMgrProtocol, This, &Gtdt->Header, TableSize); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to add ACPI header. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Status = AddGenericTimerInfo ( > + CfgMgrProtocol, > + Gtdt, > + PlatformTimerCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to add Generic Timer Info. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + if (BlockTimerCount != 0) { > + Status = AddGTBlockList ( > + Gtdt, > + GTBlockOffset, > + GTBlockInfo, > + BlockTimerCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: GTDT: Failed to add GT Block timers. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + } > + > + if (WatchdogCount != 0) { > + AddGenericWatchdogList ( > + Gtdt, > + WatchdogOffset, > + WatchdogInfoList, > + WatchdogCount > + ); > + } > + > + return Status; > + > +error_handler: > + if (*Table != NULL) { > + FreePool (*Table); > + *Table = 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] 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 EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > +) > +{ > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + if ((Table == NULL) || (*Table == NULL)) { > + DEBUG ((DEBUG_ERROR, "ERROR: GTDT: Invalid Table Pointer\n")); > + ASSERT ((Table != NULL) && (*Table != NULL)); > + return EFI_INVALID_PARAMETER; > + } > + > + FreePool (*Table); > + *Table = 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 = { > + // 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_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_6_1_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; > + > + Status = RegisterAcpiTableGenerator (&GtdtGenerator); > + DEBUG ((DEBUG_INFO, "GTDT: Register Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > +/** Un-register 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 un-registered. > + @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; > + > + Status = UnRegisterAcpiTableGenerator (&GtdtGenerator); > + DEBUG ((DEBUG_INFO, "GTDT: Unregister Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c > new file mode 100644 > index 0000000000000000000000000000000000000000..cce440d91f50d8a7ac429acb6be40d4a6ac4e230 > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c > @@ -0,0 +1,732 @@ > +/** @file > + MADT Table Generator > + > + 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 > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard MADT Generator > + > + Generates the ACPI MADT Table as specified by the > + ACPI 6.1 Specification - January, 2016. > + > +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 Serice 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_1_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_1_GIC_STRUCTURE * CONST Gicc, > + IN CONST CM_ARM_GICC_INFO * CONST GicCInfo > + ) > +{ > + ASSERT (Gicc != NULL); > + ASSERT (GicCInfo != NULL); > + > + /* UINT8 Type */ > + Gicc->Type = EFI_ACPI_6_1_GIC; > + /* UINT8 Length */ > + Gicc->Length = sizeof (EFI_ACPI_6_1_GIC_STRUCTURE); > + /* UINT16 Reserved */ > + Gicc->Reserved = EFI_ACPI_RESERVED_WORD; > + > + /* UINT32 CPUInterfaceNumber */ > + Gicc->CPUInterfaceNumber = GicCInfo->CPUInterfaceNumber; > + /* UINT32 AcpiProcessorUid */ > + Gicc->AcpiProcessorUid = GicCInfo->AcpiProcessorUid; > + /* UINT32 Flags */ > + Gicc->Flags = GicCInfo->Flags; > + /* UINT32 ParkingProtocolVersion */ > + Gicc->ParkingProtocolVersion = GicCInfo->ParkingProtocolVersion; > + /* UINT32 PerformanceInterruptGsiv */ > + Gicc->PerformanceInterruptGsiv = GicCInfo->PerformanceInterruptGsiv; > + /* UINT64 ParkedAddress */ > + Gicc->ParkedAddress = GicCInfo->ParkedAddress; > + > + /* UINT64 PhysicalBaseAddress */ > + Gicc->PhysicalBaseAddress = GicCInfo->PhysicalBaseAddress; > + /* UINT64 GICV */ > + Gicc->GICV = GicCInfo->GICV; > + /* UINT64 GICH */ > + Gicc->GICH = GicCInfo->GICH; > + > + /* UINT32 VGICMaintenanceInterrupt */ > + Gicc->VGICMaintenanceInterrupt = GicCInfo->VGICMaintenanceInterrupt; > + /* UINT64 GICRBaseAddress */ > + Gicc->GICRBaseAddress = GicCInfo->GICRBaseAddress; > + > + /* UINT64 MPIDR */ > + Gicc->MPIDR = GicCInfo->MPIDR; > + /* UINT8 ProcessorPowerEfficiencyClass */ > + Gicc->ProcessorPowerEfficiencyClass = > + GicCInfo->ProcessorPowerEfficiencyClass; > + /* UINT8 Reserved2[3] */ > + Gicc->Reserved2[0] = EFI_ACPI_RESERVED_BYTE; > + Gicc->Reserved2[1] = EFI_ACPI_RESERVED_BYTE; > + Gicc->Reserved2[2] = 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_1_GIC_STRUCTURE * Gicc, > + IN CONST CM_ARM_GICC_INFO * GicCInfo, > + IN CONST UINTN GicCCount > + ) > +{ > + UINTN idx; > + > + ASSERT (Gicc != NULL); > + ASSERT (GicCInfo != NULL); > + > + for (idx = 0; idx < GicCCount; idx++) { > + 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_1_GIC_DISTRIBUTOR_STRUCTURE * CONST Gicd, > + CONST CM_ARM_GICD_INFO * CONST GicDInfo > +) > +{ > + ASSERT (Gicd != NULL); > + ASSERT (GicDInfo != NULL); > + > + /* UINT8 Type */ > + Gicd->Type = EFI_ACPI_6_1_GICD; > + /* UINT8 Length */ > + Gicd->Length = sizeof (EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE); > + /* UINT16 Reserved */ > + Gicd->Reserved1 = EFI_ACPI_RESERVED_WORD; > + /* UINT32 Identifier */ > + Gicd->GicId = GicDInfo->GicId; > + /* UINT64 PhysicalBaseAddress */ > + Gicd->PhysicalBaseAddress = GicDInfo->PhysicalBaseAddress; > + /* UINT32 VectorBase */ > + Gicd->SystemVectorBase = GicDInfo->SystemVectorBase; > + /* UINT8 GicVersion */ > + Gicd->GicVersion = GicDInfo->GicVersion; > + /* UINT8 Reserved2[3] */ > + Gicd->Reserved2[0] = EFI_ACPI_RESERVED_BYTE; > + Gicd->Reserved2[1] = EFI_ACPI_RESERVED_BYTE; > + Gicd->Reserved2[2] = EFI_ACPI_RESERVED_BYTE; > +} > + > +/** Add the GIC Distributor Information to the MADT Table. > + > + @param [in] Gicd Pointer to GIC Distributor structure list. > + @param [in] GicDInfo Pointer to the GIC Distributor Information list. > + @param [in] GicDCount Count of GIC Distributors. > +*/ > +STATIC > +VOID > +AddGICDList ( > + IN EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE * Gicd, > + IN CONST CM_ARM_GICD_INFO * GicDInfo, > + IN CONST UINTN GicDCount > + ) > +{ > + UINTN idx; > + > + ASSERT (Gicd != NULL); > + ASSERT (GicDInfo != NULL); > + > + for (idx = 0; idx < GicDCount; idx++) { > + AddGICD (Gicd++, GicDInfo++); > + } > +} > + > +/** 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_1_GIC_MSI_FRAME_STRUCTURE * CONST GicMsiFrame, > + IN CONST CM_ARM_GIC_MSI_FRAME_INFO * CONST GicMsiFrameInfo > +) > +{ > + ASSERT (GicMsiFrame != NULL); > + ASSERT (GicMsiFrameInfo != NULL); > + > + GicMsiFrame->Type = EFI_ACPI_6_1_GIC_MSI_FRAME; > + GicMsiFrame->Length = sizeof (EFI_ACPI_6_1_GIC_MSI_FRAME_STRUCTURE); > + GicMsiFrame->Reserved1 = EFI_ACPI_RESERVED_WORD; > + GicMsiFrame->GicMsiFrameId = GicMsiFrameInfo->GicMsiFrameId; > + GicMsiFrame->PhysicalBaseAddress = GicMsiFrameInfo->PhysicalBaseAddress; > + > + GicMsiFrame->Flags = GicMsiFrameInfo->Flags; > + GicMsiFrame->SPICount = GicMsiFrameInfo->SPICount; > + GicMsiFrame->SPIBase = 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_1_GIC_MSI_FRAME_STRUCTURE * GicMsiFrame, > + IN CONST CM_ARM_GIC_MSI_FRAME_INFO * GicMsiFrameInfo, > + IN CONST UINTN GicMsiFrameCount > +) > +{ > + UINTN idx; > + > + ASSERT (GicMsiFrame != NULL); > + ASSERT (GicMsiFrameInfo != NULL); > + > + for (idx = 0; idx < GicMsiFrameCount; idx++) { > + AddGICMsiFrame (GicMsiFrame++, GicMsiFrameInfo++); > + } > +} > + > +/** Update the GIC Redistributor Information. > + > + @param [in] Gicr Pointer to GIC Redistributor structure. > + @param [in] GicRedisributorInfo Pointer to the GIC Redistributor Info. > +*/ > +STATIC > +VOID > +AddGICRedistributor ( > + IN EFI_ACPI_6_1_GICR_STRUCTURE * CONST Gicr, > + IN CONST CM_ARM_GIC_REDIST_INFO * CONST GicRedisributorInfo > + ) > +{ > + ASSERT (Gicr != NULL); > + ASSERT (GicRedisributorInfo != NULL); > + > + Gicr->Type = EFI_ACPI_6_1_GICR; > + Gicr->Length = sizeof (EFI_ACPI_6_1_GICR_STRUCTURE); > + Gicr->Reserved = EFI_ACPI_RESERVED_WORD; > + Gicr->DiscoveryRangeBaseAddress = > + GicRedisributorInfo->DiscoveryRangeBaseAddress; > + Gicr->DiscoveryRangeLength = 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_1_GICR_STRUCTURE * Gicr, > + IN CONST CM_ARM_GIC_REDIST_INFO * GicRInfo, > + IN CONST UINTN GicRCount > +) > +{ > + UINTN idx; > + > + ASSERT (Gicr != NULL); > + ASSERT (GicRInfo != NULL); > + > + for (idx = 0; idx < GicRCount; idx++) { > + 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_1_GIC_ITS_STRUCTURE * CONST GicIts, > + IN CONST CM_ARM_GIC_ITS_INFO * CONST GicItsInfo > +) > +{ > + ASSERT (GicIts != NULL); > + ASSERT (GicItsInfo != NULL); > + > + GicIts->Type = EFI_ACPI_6_1_GIC_ITS; > + GicIts->Length = sizeof (EFI_ACPI_6_1_GIC_ITS_STRUCTURE); > + GicIts->Reserved = EFI_ACPI_RESERVED_WORD; > + GicIts->GicItsId = GicItsInfo->GicItsId; > + GicIts->PhysicalBaseAddress = GicItsInfo->PhysicalBaseAddress; > + GicIts->Reserved2 = 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_1_GIC_ITS_STRUCTURE * GicIts, > + IN CONST CM_ARM_GIC_ITS_INFO * GicItsInfo, > + IN CONST UINTN GicItsCount > +) > +{ > + UINTN idx; > + > + ASSERT (GicIts != NULL); > + ASSERT (GicItsInfo != NULL); > + > + for (idx = 0; idx < GicItsCount; idx++) { > + AddGICInterruptTranslationService (GicIts++, GicItsInfo++); > + } > +} > + > +/** Construct the MADT ACPI table. > + > + This function invokes the Confguration 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; > + UINTN TableSize; > + UINTN GicCCount; > + UINTN GicDCount; > + UINTN GicMSICount; > + UINTN GicRedistCount; > + UINTN GicItsCount; > + CM_ARM_GICC_INFO * GicCInfo = NULL; > + CM_ARM_GICD_INFO * GicDInfo = NULL; > + CM_ARM_GIC_MSI_FRAME_INFO * GicMSIInfo = NULL; > + CM_ARM_GIC_REDIST_INFO * GicRedistInfo = NULL; > + CM_ARM_GIC_ITS_INFO * GicItsInfo = NULL; > + UINTN GicCOffset; > + UINTN GicDOffset; > + UINTN GicMSIOffset; > + UINTN GicRedistOffset; > + UINTN GicItsOffset; > + > + EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER * Madt; > + > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (Table != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + *Table = NULL; > + > + Status = GetEArmObjGicCInfo (CfgMgrProtocol, &GicCInfo, &GicCCount); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GICC Info. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + if (GicCCount == 0) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: GIC CPU Interface information not provided.\n" > + )); > + ASSERT (GicCCount != 0); > + Status = EFI_INVALID_PARAMETER; > + goto error_handler; > + } > + > + Status = GetEArmObjGicDInfo (CfgMgrProtocol, &GicDInfo, &GicDCount); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GICD Info. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + if (GicDCount == 0) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: GIC Distributor information not provided.\n" > + )); > + ASSERT (GicDCount != 0); > + Status = EFI_INVALID_PARAMETER; > + goto error_handler; > + } > + > + Status = GetEArmObjGicMsiFrameInfo ( > + CfgMgrProtocol, > + &GicMSIInfo, > + &GicMSICount > + ); > + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GIC MSI Info. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Status = GetEArmObjGicRedistributorInfo ( > + CfgMgrProtocol, > + &GicRedistInfo, > + &GicRedistCount > + ); > + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GIC Redistributor Info. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Status = GetEArmObjGicItsInfo ( > + CfgMgrProtocol, > + &GicItsInfo, > + &GicItsCount > + ); > + if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to get GIC ITS Info. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + TableSize = sizeof (EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER); > + > + GicCOffset = TableSize; > + TableSize += (sizeof (EFI_ACPI_6_1_GIC_STRUCTURE) * GicCCount); > + > + GicDOffset = TableSize; > + TableSize += (sizeof (EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE) * GicDCount); > + > + GicMSIOffset = TableSize; > + TableSize += (sizeof (EFI_ACPI_6_1_GIC_MSI_FRAME_STRUCTURE) * GicMSICount); > + > + GicRedistOffset = TableSize; > + TableSize += (sizeof (EFI_ACPI_6_1_GICR_STRUCTURE) * GicRedistCount); > + > + GicItsOffset = TableSize; > + TableSize += (sizeof (EFI_ACPI_6_1_GIC_ITS_STRUCTURE) * GicItsCount); > + > + // Allocate the Buffer for MADT table > + *Table = (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize); > + if (*Table == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to allocate memory for MADT Table, Size = %d," \ > + " Status = %r\n", > + TableSize, > + Status > + )); > + goto error_handler; > + } > + > + Madt = (EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER*)*Table; > + > + DEBUG (( > + DEBUG_INFO, > + "MADT: Madt = 0x%p TableSize = 0x%x\n", > + Madt, > + TableSize > + )); > + > + Status = AddAcpiHeader (CfgMgrProtocol, This, &Madt->Header, TableSize); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MADT: Failed to add ACPI header. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + AddGICCList ( > + (EFI_ACPI_6_1_GIC_STRUCTURE*)((UINT8*)Madt + GicCOffset), > + GicCInfo, > + GicCCount > + ); > + > + AddGICDList ( > + (EFI_ACPI_6_1_GIC_DISTRIBUTOR_STRUCTURE*)((UINT8*)Madt + GicDOffset), > + GicDInfo, > + GicDCount > + ); > + > + if (GicMSICount != 0) { > + AddGICMsiFrameInfoList ( > + (EFI_ACPI_6_1_GIC_MSI_FRAME_STRUCTURE*)((UINT8*)Madt + GicMSIOffset), > + GicMSIInfo, > + GicMSICount > + ); > + } > + > + if (GicRedistCount != 0) { > + AddGICRedistributorList ( > + (EFI_ACPI_6_1_GICR_STRUCTURE*)((UINT8*)Madt + GicRedistOffset), > + GicRedistInfo, > + GicRedistCount > + ); > + } > + > + if (GicItsCount != 0) { > + AddGICItsList ( > + (EFI_ACPI_6_1_GIC_ITS_STRUCTURE*)((UINT8*)Madt + GicItsOffset), > + GicItsInfo, > + GicItsCount > + ); > + } > + > + return EFI_SUCCESS; > + > +error_handler: > + if (*Table != NULL) { > + FreePool (*Table); > + *Table = 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] 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 EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + if ((Table == NULL) || (*Table == NULL)) { > + DEBUG ((DEBUG_ERROR, "ERROR: MADT: Invalid Table Pointer\n")); > + ASSERT ((Table != NULL) && (*Table != NULL)); > + return EFI_INVALID_PARAMETER; > + } > + > + FreePool (*Table); > + *Table = 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 = { > + // 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_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_6_1_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; > + > + Status = RegisterAcpiTableGenerator (&MadtGenerator); > + DEBUG ((DEBUG_INFO, "MADT: Register Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > +/** Un-register 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 un-registered. > + @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; > + > + Status = UnRegisterAcpiTableGenerator (&MadtGenerator); > + DEBUG ((DEBUG_INFO, "MADT: Unregister Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c > new file mode 100644 > index 0000000000000000000000000000000000000000..c023b413797379562f20ae97db9e2f2ca6d8758c > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c > @@ -0,0 +1,336 @@ > +/** @file > + MCFG Table Generator > + > + 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 > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard MCFG Generator > + > + Generates the MCFG Table as specified by the PCI Firmware > + Specification - Revision 3.2, January 26, 2015. > + > +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_HEADER > + 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 Space > + Info structure in the MCFG Table. > + @param [in] PciCfgSpaceInfoList Pointer to the PCI Configuration Space > + Info List. > + @param [in] PciCfgSpaceCount Count of PCI Configuration Space Info. > +*/ > +STATIC > +VOID > +AddPciConfigurationSpaceList ( > + IN MCFG_TABLE * CONST Mcfg, > + IN CONST UINTN PciCfgSpaceOffset, > + IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO * CONST PciCfgSpaceInfoList, > + IN CONST UINTN PciCfgSpaceCount > +) > +{ > + UINTN idx; > + MCFG_CFG_SPACE_ADDR * PciCfgSpace; > + > + ASSERT (Mcfg != NULL); > + ASSERT (PciCfgSpaceInfoList != NULL); > + > + PciCfgSpace = (MCFG_CFG_SPACE_ADDR *)((UINT8*)Mcfg + PciCfgSpaceOffset); > + for (idx = 0; idx < PciCfgSpaceCount; idx++) { > + // Add PCI Configuration Space entry > + PciCfgSpace[idx].BaseAddress = PciCfgSpaceInfoList[idx].BaseAddress; > + PciCfgSpace[idx].PciSegmentGroupNumber = > + PciCfgSpaceInfoList[idx].PciSegmentGroupNumber; > + PciCfgSpace[idx].StartBusNumber = PciCfgSpaceInfoList[idx].StartBusNumber; > + PciCfgSpace[idx].EndBusNumber = PciCfgSpaceInfoList[idx].EndBusNumber; > + PciCfgSpace[idx].Reserved = EFI_ACPI_RESERVED_DWORD; > + } > +} > + > +/** Construct the MCFG ACPI table. > + > + This function invokes the Confguration 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; > + UINTN TableSize; > + UINTN ConfigurationSpaceCount; > + CM_ARM_PCI_CONFIG_SPACE_INFO * PciConfigSpaceInfoList = NULL; > + MCFG_TABLE * Mcfg; > + > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (Table != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + *Table = NULL; > + Status = GetEArmObjPciConfigSpaceInfo ( > + CfgMgrProtocol, > + &PciConfigSpaceInfoList, > + &ConfigurationSpaceCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, > + "ERROR: MCFG: Failed to get PCI Configuration Space Information." \ > + " Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + ASSERT (ConfigurationSpaceCount != 0); > + > + DEBUG (( > + DEBUG_INFO, > + "MCFG: Configuration Space Count = %d\n", > + ConfigurationSpaceCount > + )); > + > + // Calculate the MCFG Table Size > + TableSize = sizeof (MCFG_TABLE) + > + ((sizeof (MCFG_CFG_SPACE_ADDR) * ConfigurationSpaceCount)); > + > + *Table = (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize); > + if (*Table == NULL) { > + Status = EFI_OUT_OF_RESOURCES; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MCFG: Failed to allocate memory for MCFG Table, Size = %d," \ > + " Status = %r\n", > + TableSize, > + Status > + )); > + goto error_handler; > + } > + > + Mcfg = (MCFG_TABLE*)*Table; > + DEBUG (( > + DEBUG_INFO, > + "MCFG: Mcfg = 0x%p TableSize = 0x%x\n", > + Mcfg, > + TableSize > + )); > + > + Status = AddAcpiHeader (CfgMgrProtocol, This, &Mcfg->Header, TableSize); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: MCFG: Failed to add ACPI header. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + Mcfg->Reserved = EFI_ACPI_RESERVED_QWORD; > + > + AddPciConfigurationSpaceList ( > + Mcfg, > + sizeof (MCFG_TABLE), > + PciConfigSpaceInfoList, > + ConfigurationSpaceCount > + ); > + > + return EFI_SUCCESS; > + > +error_handler: > + if (*Table != NULL) { > + FreePool (*Table); > + *Table = 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] 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 EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + if ((Table == NULL) || (*Table == NULL)) { > + DEBUG ((DEBUG_ERROR, "ERROR: MCFG: Invalid Table Pointer\n")); > + ASSERT ((Table != NULL) && (*Table != NULL)); > + return EFI_INVALID_PARAMETER; > + } > + > + FreePool (*Table); > + *Table = 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 = { > + // 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_1_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, > + // ACPI Table Revision > + EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION, > + // 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; > + > + Status = RegisterAcpiTableGenerator (&McfgGenerator); > + DEBUG ((DEBUG_INFO, "MCFG: Register Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > +/** Un-register 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 un-registered. > + @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; > + > + Status = UnRegisterAcpiTableGenerator (&McfgGenerator); > + DEBUG ((DEBUG_INFO, "MCFG: Unregister Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiRawLibArm/RawGenerator.c b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiRawLibArm/RawGenerator.c > new file mode 100644 > index 0000000000000000000000000000000000000000..aaca70cba0a1a08c0730bd84134c1b8722edd7af > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiRawLibArm/RawGenerator.c > @@ -0,0 +1,177 @@ > +/** @file > + MCFG Table Generator > + > + 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 > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** Construct the ACPI table using the ACPI table data provided. > + > + This function invokes the Confguration 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 != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (Table != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableData != NULL); > + > + if (AcpiTableInfo->AcpiTableData == NULL) { > + *Table = NULL; > + return EFI_INVALID_PARAMETER; > + } > + > + *Table = AcpiTableInfo->AcpiTableData; > + > + return EFI_SUCCESS; > +} > + > +/** Free any resources allocated for constructing the ACPI table. > + > + @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] Table Pointer to the ACPI Table. > + > + @retval EFI_SUCCESS The resources were freed successfully. > + > +*/ > +STATIC > +EFI_STATUS > +FreeRawTableResources ( > + 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 EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + > + 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 = { > + // 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, > + // Free Resource function > + FreeRawTableResources > +}; > + > +/** 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; > + > + Status = RegisterAcpiTableGenerator (&RawGenerator); > + DEBUG ((DEBUG_INFO, "RAW: Register Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > +/** Un-register 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 un-registered. > + @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; > + > + Status = UnRegisterAcpiTableGenerator (&RawGenerator); > + DEBUG ((DEBUG_INFO, "RAW: UnRegister Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git a/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c > new file mode 100644 > index 0000000000000000000000000000000000000000..ccfbcf088cfaec1e4f9f3738f5fe09a65c93bc9e > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c > @@ -0,0 +1,323 @@ > +/** @file > + SPCR Table Generator > + > + 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 > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** ARM standard SPCR Table Generator > + > + Generates the ACPI SPCR Table for ARM UARTs as specified by > + the Microsoft Serial Port Console Redirection Table > + Specification - Version 1.03 - August 10, 2015. > + > + 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 settings 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-volatile > + 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 = { > + ACPI_HEADER ( > + EFI_ACPI_6_1_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE, > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION > + ), > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_ARM_PL011_UART, > + { > + 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_PARITY, > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1, > + SPCR_FLOW_CONTROL_NONE, > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_ANSI, > + 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 Confguration 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 > + Confguration 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 = NULL; > + > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (Table != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + *Table = NULL; > + > + Status = GetEArmObjSerialConsolePortInfo ( > + CfgMgrProtocol, > + &SerialPortInfo, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SPCR: Failed to get serial port information. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + DEBUG ((DEBUG_INFO, "SPCR UART Configuration:\n")); > + DEBUG ((DEBUG_INFO, " UART Base = 0x%lx\n", SerialPortInfo->BaseAddress)); > + DEBUG ((DEBUG_INFO, " Clock = %d\n", SerialPortInfo->Clock)); > + DEBUG ((DEBUG_INFO, " Baudrate = %ld\n", SerialPortInfo->BaudRate)); > + DEBUG ((DEBUG_INFO, " Interrupt = %d\n", SerialPortInfo->Interrupt)); > + > + Status = 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 = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + AcpiSpcr.BaseAddress.Address = SerialPortInfo->BaseAddress; > + AcpiSpcr.GlobalSystemInterrupt = SerialPortInfo->Interrupt; > + > + switch (SerialPortInfo->BaudRate) { > + case 9600: > + AcpiSpcr.BaudRate = > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600; > + break; > + case 19200: > + AcpiSpcr.BaudRate = > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200; > + break; > + case 57600: > + AcpiSpcr.BaudRate = > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600; > + break; > + case 115200: > + AcpiSpcr.BaudRate = > + EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200; > + break; > + default: > + Status = EFI_UNSUPPORTED; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SPCR: Invalid Baud Rate %ld, Status = %r\n", > + SerialPortInfo->BaudRate, > + Status > + )); > + goto error_handler; > + } // switch > + > + *Table = (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiSpcr; > + > +error_handler: > + return Status; > +} > + > +/** Free any resources allocated for constructing the SPCR. > + > + @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] Table Pointer to the ACPI Table. > + > + @retval EFI_SUCCESS The resources were freed successfully. > +*/ > +STATIC > +EFI_STATUS > +FreeSpcrTableResources ( > + 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 EFI_ACPI_DESCRIPTION_HEADER ** CONST Table > + ) > +{ > + ASSERT (This != NULL); > + ASSERT (AcpiTableInfo != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID); > + ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature); > + > + return EFI_SUCCESS; > +} > + > +/** 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 = { > + // 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_1_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, > + // Free Resource function > + FreeSpcrTableResources > +}; > + > +/** 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; > + > + Status = RegisterAcpiTableGenerator (&SpcrGenerator); > + DEBUG ((DEBUG_INFO, "SPCR: Register Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > + > +/** Un-register 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 un-registered. > + @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; > + > + Status = UnRegisterAcpiTableGenerator (&SpcrGenerator); > + DEBUG ((DEBUG_INFO, "SPCR: Unregister Generator. Status = %r\n", Status)); > + ASSERT_EFI_ERROR (Status); > + return Status; > +} > diff --git a/MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelper.c b/MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelper.c > new file mode 100644 > index 0000000000000000000000000000000000000000..8dc1d6b6f7c6eb71bd0ab16b690a9f5b4855dc3d > --- /dev/null > +++ b/MdeModulePkg/Library/DynamicTables/Common/TableHelperLib/TableHelper.c > @@ -0,0 +1,165 @@ > +/** @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 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 > +#include > +#include > + > +#include > +#include > +#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 != NULL); > + ASSERT (CfgMfrInfo != NULL); > + > + *CfgMfrInfo = NULL; > + Status = CfgMgrProtocol->GetObject ( > + CfgMgrProtocol, > + CREATE_CM_STD_OBJECT_ID (EStdObjCfgMgrInfo), > + &CmObjectDesc > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to Get Configuration Manager Info. Status = %r\n", > + Status > + )); > + return Status; > + } > + > + ASSERT (CmObjectDesc.Size >= sizeof (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO)); > + if (CmObjectDesc.Size < sizeof (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: EStdObjCfgMgrInfo: Buffer too small, size = 0x%x\n", > + CmObjectDesc.Size > + )); > + return EFI_BAD_BUFFER_SIZE; > + } > + > + *CfgMfrInfo = (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 != NULL); > + ASSERT (Generator != NULL); > + ASSERT (AcpiHeader != NULL); > + ASSERT (Length >= sizeof (EFI_ACPI_DESCRIPTION_HEADER)); > + > + if ((CfgMgrProtocol == NULL) || > + (Generator == NULL) || > + (AcpiHeader == NULL) || > + (Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) > + ) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to get Configuration Manager info. Status = %r\n", > + Status > + )); > + goto error_handler; > + } > + > + /* UINT32 Signature */ > + AcpiHeader->Signature = Generator->AcpiTableSignature; > + /* UINT32 Length */ > + AcpiHeader->Length = Length; > + /* UINT8 Revision */ > + AcpiHeader->Revision = Generator->AcpiTableRevision; > + /* UINT8 Checksum */ > + AcpiHeader->Checksum = 0; > + > + /* UINT8 OemId[6] */ > + CopyMem (AcpiHeader->OemId, CfgMfrInfo->OemId, sizeof (AcpiHeader->OemId)); > + > + /* UINT64 OemTableId */ > + AcpiHeader->OemTableId = Generator->CreatorId; // Generator->GeneratorID; > + AcpiHeader->OemTableId <<= 32; > + AcpiHeader->OemTableId |= Generator->AcpiTableSignature; > + > + /* UINT32 OemRevision */ > + AcpiHeader->OemRevision = CfgMfrInfo->Revision; > + > + /* UINT32 CreatorId */ > + AcpiHeader->CreatorId = Generator->CreatorId; > + /* UINT32 CreatorRevision */ > + AcpiHeader->CreatorRevision = Generator->CreatorRevision; > + > + Status = EFI_SUCCESS; > +error_handler: > + return Status; > +} > diff --git a/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c > new file mode 100644 > index 0000000000000000000000000000000000000000..79cf0f290ddb79499c71d6c553b420418dec50f1 > --- /dev/null > +++ b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c > @@ -0,0 +1,227 @@ > +/** @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 > +#include > +#include > + > +#include > +#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 Poiner to the Dynamic Table Factory Protocol. > + @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 != NULL); > + > + FactoryInfo = This->TableFactoryInfo; > + > + if (Generator == 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 = NULL; > + TableId = GET_TABLE_ID (GeneratorId); > + if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) { > + if (TableId >= (ESTD_ACPI_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_ACPI_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->StdAcpiTableGeneratorList[TableId] != NULL) { > + *Generator = FactoryInfo->StdAcpiTableGeneratorList[TableId]; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >= FixedPcdGet16 (PcdMaxCustomACPIGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomACPIGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->CustomAcpiTableGeneratorList[TableId] != NULL) { > + *Generator = 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 == 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 = GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >= (ESTD_ACPI_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_ACPI_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdAcpiTableGeneratorList[TableId] == NULL) { > + TableFactoryInfo.StdAcpiTableGeneratorList[TableId] = Generator; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } else { > + if (TableId >= FixedPcdGet16 (PcdMaxCustomACPIGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomACPIGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] == NULL) { > + TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] = Generator; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** Unregister ACPI generator. > + > + This function is called by the ACPI table generator to unregister itself > + 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 > +UnRegisterAcpiTableGenerator ( > + IN CONST ACPI_TABLE_GENERATOR * CONST Generator > + ) > +{ > + UINT16 TableId; > + > + if (Generator == NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: ACPI un-register - Invalid Generator\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_ACPI (Generator->GeneratorID)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: ACPI un-register - Generator" \ > + " Type is not ACPI\n" > + )); > + return EFI_INVALID_PARAMETER; > + } > + > + TableId = GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >= (ESTD_ACPI_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_ACPI_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdAcpiTableGeneratorList[TableId] != NULL) { > + if (Generator != TableFactoryInfo.StdAcpiTableGeneratorList[TableId]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.StdAcpiTableGeneratorList[TableId] = NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >= FixedPcdGet16 (PcdMaxCustomACPIGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomACPIGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] != NULL) { > + if (Generator != > + TableFactoryInfo.CustomAcpiTableGeneratorList[TableId]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.CustomAcpiTableGeneratorList[TableId] = NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } > + > + DEBUG ((DEBUG_INFO, "Unregistering %s\n", Generator->Description)); > + return EFI_SUCCESS; > +} > diff --git a/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c > new file mode 100644 > index 0000000000000000000000000000000000000000..64a0390cdd006d8e3222ff19b269d1b4326736c3 > --- /dev/null > +++ b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.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 > +#include > +#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 = { > + CREATE_REVISION (1, 0), > + GetAcpiTableGenerator, > + GetSmbiosTableGenerator, > + &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 = 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 = %r\n", > + Status > + )); > + } > + return Status; > +} > diff --git a/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c > new file mode 100644 > index 0000000000000000000000000000000000000000..64b578f30a3413ac2b22ccef4f09368c1af38b67 > --- /dev/null > +++ b/MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c > @@ -0,0 +1,227 @@ > +/** @file > + SMBIOS 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 > +#include > +#include > + > +#include > +#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 Poiner to the Dynamic Table Factory Protocol. > + @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 != NULL); > + > + FactoryInfo = This->TableFactoryInfo; > + > + if (Generator == 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 = NULL; > + TableId = GET_TABLE_ID (GeneratorId); > + if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) { > + if (TableId >= (ESTD_SMBIOS_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_SMBIOS_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->StdSmbiosTableGeneratorList[TableId] != NULL) { > + *Generator = FactoryInfo->StdSmbiosTableGeneratorList[TableId]; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >= FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (FactoryInfo->CustomSmbiosTableGeneratorList[TableId] != NULL) { > + *Generator = 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 == 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 = GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >= (ESTD_SMBIOS_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_SMBIOS_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] == NULL) { > + TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] = Generator; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } else { > + if (TableId >= FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] == NULL) { > + TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] = Generator; > + } else { > + return EFI_ALREADY_STARTED; > + } > + } > + return EFI_SUCCESS; > +} > + > +/** Unregister SMBIOS generator. > + > + This function is called by the SMBIOS table generator to unregister itself > + 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 > +UnRegisterSmbiosTableGenerator ( > + IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator > + ) > +{ > + UINT16 TableId; > + > + if (Generator == NULL) { > + DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS un-register - Invalid Generator\n")); > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IS_GENERATOR_TYPE_SMBIOS (Generator->GeneratorID)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: SMBIOS un-register - Generator" \ > + " Type is not SMBIOS\n" > + )); > + return EFI_INVALID_PARAMETER; > + } > + > + TableId = GET_TABLE_ID (Generator->GeneratorID); > + if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) { > + if (TableId >= (ESTD_SMBIOS_TABLE_ID_MAX)) { > + ASSERT (TableId < (ESTD_SMBIOS_TABLE_ID_MAX)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] != NULL) { > + if (Generator != TableFactoryInfo.StdSmbiosTableGeneratorList[TableId]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.StdSmbiosTableGeneratorList[TableId] = NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } else { > + if (TableId >= FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)) { > + ASSERT (TableId < FixedPcdGet16 (PcdMaxCustomSMBIOSGenerators)); > + return EFI_INVALID_PARAMETER; > + } > + if (TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] != NULL) { > + if (Generator != > + TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId]) { > + return EFI_INVALID_PARAMETER; > + } > + TableFactoryInfo.CustomSmbiosTableGeneratorList[TableId] = NULL; > + } else { > + return EFI_NOT_FOUND; > + } > + } > + > + DEBUG ((DEBUG_INFO, "Unregistering %s\n", Generator->Description)); > + return EFI_SUCCESS; > +} > diff --git a/MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.c b/MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.c > new file mode 100644 > index 0000000000000000000000000000000000000000..f84bf3bef910ddf86629062d6d1ca1dffafa5a28 > --- /dev/null > +++ b/MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.c > @@ -0,0 +1,531 @@ > +/** @file > + Dynamic Table Manager 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 > +#include > +#include > + > +#include > +#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 the > + table, then frees the resources allocated for generating it. > + > + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol > + 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; > + CONST ACPI_TABLE_GENERATOR * Generator = NULL; > + EFI_ACPI_DESCRIPTION_HEADER * AcpiTable; > + UINTN TableHandle; > + > + ASSERT (TableFactoryProtocol != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + ASSERT (AcpiTableProtocol != NULL); > + ASSERT (AcpiTableInfo != NULL); > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: EStdObjAcpiTableList: Address = 0x%p," \ > + " TableGeneratorId = 0x%x\n", > + AcpiTableInfo, > + AcpiTableInfo->TableGeneratorId > + )); > + > + Status = TableFactoryProtocol->GetAcpiTableGenerator ( > + TableFactoryProtocol, > + AcpiTableInfo->TableGeneratorId, > + &Generator > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Table Generator not found." \ > + " TableGeneratorId = 0x%x. Status = %r\n", > + AcpiTableInfo->TableGeneratorId, > + Status > + )); > + return Status; > + } > + > + ASSERT (Generator != NULL); > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: Generator found : %s\n", > + Generator->Description > + )); > + > + if (Generator->BuildAcpiTable == NULL) { > + Status = EFI_INVALID_PARAMETER; > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Table Generator does not implement the" \ > + " ACPI_TABLE_GENERATOR_BUILD_TABLE interface." \ > + " TableGeneratorId = 0x%x. Status = %r\n", > + AcpiTableInfo->TableGeneratorId, > + Status > + )); > + return Status; > + } > + > + AcpiTable = NULL; > + Status = Generator->BuildAcpiTable ( > + Generator, > + AcpiTableInfo, > + CfgMgrProtocol, > + &AcpiTable > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to Build Table." \ > + " TableGeneratorId = 0x%x. Status = %r\n", > + AcpiTableInfo->TableGeneratorId, > + Status > + )); > + // Free any allocated resources. > + goto error_handler; > + } > + > + ASSERT (AcpiTable != NULL); > + > + // Dump ACPI Table Header > + DUMP_ACPI_TABLE_HEADER (AcpiTable); > + > + // Install ACPI table > + Status = AcpiTableProtocol->InstallAcpiTable ( > + AcpiTableProtocol, > + AcpiTable, > + AcpiTable->Length, > + &TableHandle > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to Install ACPI Table. Status = %r\n", > + Status > + )); > + // Free any allocated resources. > + goto error_handler; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: ACPI Table installed. Status = %r\n", > + Status > + )); > + > +error_handler: > + // Free any resources allocated for generating the tables. > + if ((AcpiTable != NULL) && (Generator->FreeTableResources != NULL)) { > + Status = Generator->FreeTableResources ( > + Generator, > + AcpiTableInfo, > + CfgMgrProtocol, > + &AcpiTable > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to Free Table Resources." \ > + "TableGeneratorId = 0x%x. Status = %r\n", > + AcpiTableInfo->TableGeneratorId, > + Status > + )); > + } > + } > + 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 CONST UINTN AcpiTableCount > + ) > +{ > + EFI_STATUS Status = EFI_SUCCESS; > + BOOLEAN FadtFound = FALSE; > + BOOLEAN MadtFound = FALSE; > + BOOLEAN GtdtFound = FALSE; > + BOOLEAN DsdtFound = FALSE; > + BOOLEAN Dbg2Found = FALSE; > + BOOLEAN SpcrFound = FALSE; > + UINTN idx; > + > + ASSERT (AcpiTableInfo != NULL); > + > + for (idx = 0; idx < AcpiTableCount; idx++) { > + switch (AcpiTableInfo[idx].AcpiTableSignature) { > + case EFI_ACPI_6_1_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: > + FadtFound = TRUE; > + break; > + case EFI_ACPI_6_1_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: > + MadtFound = TRUE; > + break; > + case EFI_ACPI_6_1_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE: > + GtdtFound = TRUE; > + break; > + case EFI_ACPI_6_1_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: > + DsdtFound = TRUE; > + break; > + case EFI_ACPI_6_1_DEBUG_PORT_2_TABLE_SIGNATURE: > + Dbg2Found = TRUE; > + break; > + case EFI_ACPI_6_1_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE: > + SpcrFound = 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 = EFI_NOT_FOUND; > + } > + if (!MadtFound) { > + DEBUG ((DEBUG_ERROR, "ERROR: MADT Table not found.\n")); > + Status = EFI_NOT_FOUND; > + } > + if (!GtdtFound) { > + DEBUG ((DEBUG_ERROR, "ERROR: GTDT Table not found.\n")); > + Status = EFI_NOT_FOUND; > + } > + if (!DsdtFound) { > + DEBUG ((DEBUG_ERROR, "ERROR: DSDT Table not found.\n")); > + Status = 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 Protocol > + 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; > + UINTN AcpiTableCount; > + CM_STD_OBJ_ACPI_TABLE_INFO * AcpiTableInfo; > + UINTN idx; > + > + ASSERT (TableFactoryProtocol != NULL); > + ASSERT (CfgMgrProtocol != NULL); > + > + // Find the AcpiTable protocol > + Status = gBS->LocateProtocol ( > + &gEfiAcpiTableProtocolGuid, > + NULL, > + (VOID**)&AcpiTableProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find AcpiTable protocol. Status = %r\n", > + Status > + )); > + return Status; > + } > + > + Status = GetEStdObjAcpiTableList ( > + CfgMgrProtocol, > + &AcpiTableInfo, > + &AcpiTableCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to get ACPI Table List. Status = %r\n", > + Status > + )); > + return Status; > + } > + > + if (0 == AcpiTableCount) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: EStdObjAcpiTableList: AcpiTableCount = %d\n", > + AcpiTableCount > + )); > + return EFI_NOT_FOUND; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: EStdObjAcpiTableList: AcpiTableCount = %d\n", > + AcpiTableCount > + )); > + > + // Check if mandatory ACPI tables are present. > + Status = VerifyMandatoryTablesArePresent ( > + AcpiTableInfo, > + AcpiTableCount > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find mandatory ACPI Table(s)." > + " Status = %r\n", > + Status > + )); > + return Status; > + } > + > + // Add the FADT Table first. > + for (idx = 0; idx < AcpiTableCount; idx++) { > + if (CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_FADT) == > + AcpiTableInfo[idx].TableGeneratorId) { > + Status = BuildAndInstallAcpiTable ( > + TableFactoryProtocol, > + CfgMgrProtocol, > + AcpiTableProtocol, > + &AcpiTableInfo[idx] > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find build and install ACPI FADT Table." \ > + " Status = %r\n", > + Status > + )); > + return Status; > + } > + break; > + } > + } // for > + > + // Add remaining ACPI Tables > + for (idx = 0; idx < AcpiTableCount; idx++) { > + DEBUG (( > + DEBUG_INFO, > + "INFO: AcpiTableInfo[%d].TableGeneratorId = 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) == > + AcpiTableInfo[idx].TableGeneratorId) { > + continue; > + } > + > + // Skip the Reserved table Generator ID > + if ((CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_RESERVED) >= > + AcpiTableInfo[idx].TableGeneratorId) || > + (CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_MAX) <= > + AcpiTableInfo[idx].TableGeneratorId)) { > + DEBUG (( > + DEBUG_WARN, > + "WARNING: Invalid ACPI Generator table ID = 0x%x, Skipping...\n", > + AcpiTableInfo[idx].TableGeneratorId > + )); > + continue; > + } > + > + Status = BuildAndInstallAcpiTable ( > + TableFactoryProtocol, > + CfgMgrProtocol, > + AcpiTableProtocol, > + &AcpiTableInfo[idx] > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find, build, and install ACPI Table." \ > + " Status = %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 for > + a generator capable of building the ACPI/SMBIOS table. > + If a suitable table generator is found, it invokes the generator interface > + 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 = gBS->LocateProtocol ( > + &gEfiDynamicTableFactoryProtocolGuid, > + NULL, > + (VOID**)&TableFactoryProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find Dynamic Table Factory protocol." \ > + " Status = %r\n", > + Status > + )); > + return Status; > + } > + > + // Locate the Configuration Manager for the Platform > + Status = gBS->LocateProtocol ( > + &gEfiConfigurationManagerProtocolGuid, > + NULL, > + (VOID**)&CfgMgrProtocol > + ); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to find Configuration Manager protocol. Status = %r\n", > + Status > + )); > + return Status; > + } > + > + Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: Failed to get Configuration Manager info. Status = %r\n", > + Status > + )); > + return Status; > + } > + > + DEBUG (( > + DEBUG_INFO, > + "INFO: Configuration Manager Version = 0x%x, OemID = %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 = ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "ERROR: ACPI Table processing failure. Status = %r\n", > + Status > + )); > + } > + return Status; > +} > diff --git a/MdeModulePkg/Universal/DynamicTables/DynamicTables.fdf.inc b/MdeModulePkg/Universal/DynamicTables/DynamicTables.fdf.inc > new file mode 100644 > index 0000000000000000000000000000000000000000..69012cf8242c8ddd13ac4033293ac8a7053dfbd8 > --- /dev/null > +++ b/MdeModulePkg/Universal/DynamicTables/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 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. > +# > +## > + > +################################################################################ > +# > +# 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 modules are positioned > +# within the image. The [FV] section consists of define statements, set statements and > +# module statements. > +# > +################################################################################ > + > + # > + # Dynamic Table Factory Dxe > + # > + INF MdeModulePkg/Universal/DynamicTables/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf > + > + # > + # Dynamic Tables Dxe > + # > + INF MdeModulePkg/Universal/DynamicTables/DynamicTableManagerDxe/DynamicTableManagerDxe.inf > -- > Guid("CE165669-3EF3-493F-B85D-6190EE5B9759") > > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel > _______________________________________________ > edk2-devel mailing list > edk2-devel@lists.01.org > https://lists.01.org/mailman/listinfo/edk2-devel