From: Sean Brogan <sean.brogan@microsoft.com>
To: Leif Lindholm <leif.lindholm@linaro.org>,
"Zeng, Star" <star.zeng@intel.com>
Cc: "thomas.abraham@arm.com" <thomas.abraham@arm.com>,
"ard.biesheuvel@linaro.org" <ard.biesheuvel@linaro.org>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
"Arvind.Chauhan@arm.com" <Arvind.Chauhan@arm.com>,
"Yao, Jiewen" <jiewen.yao@intel.com>,
"Kinney, Michael D" <michael.d.kinney@intel.com>
Subject: Re: [PATCH 1/2] MdeModulePkg: Dynamic Tables Framework
Date: Tue, 3 Oct 2017 18:44:58 +0000 [thread overview]
Message-ID: <MWHPR21MB0479120C3CBD548C5246038DE1720@MWHPR21MB0479.namprd21.prod.outlook.com> (raw)
In-Reply-To: <20171003153117.rrs4im264tgi2bkw@bivouac.eciton.net>
This looks like an interesting proposal but I would like to see it created in a new package rather than continuing to encourage the monolithic MdeModulePkg. Could this be a candidate for a new "feature" package? It seems to have enough content and growth potential to warrant a package of its own.
Thanks
Sean
-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Leif Lindholm
Sent: Tuesday, October 3, 2017 9:04 AM
To: Zeng, Star <star.zeng@intel.com>
Cc: thomas.abraham@arm.com; ard.biesheuvel@linaro.org; edk2-devel@lists.01.org; leif.lindholm@linaro.org; Arvind.Chauhan@arm.com; Yao, Jiewen <jiewen.yao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: Re: [edk2] [PATCH 1/2] MdeModulePkg: Dynamic Tables Framework
(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://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2-platforms&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347135677&sdata=7e3uXgai8UowRlEh8eakX%2FJvo35fO6q5z5n31qgr1X0%3D&reserved=0) change
> or edk2 master(https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ftianocore%2Fedk2&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347135677&sdata=EIpLHlZrsJpCZOBMhVDqz9Tf739WyAHc8NqwaTOHZRM%3D&reserved=0) 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 <sami.mujawar@arm.com>
>
> 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 <sami.mujawar@arm.com>
> Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
> ---
> 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.<BR>
> # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> # Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
> +# Copyright (c) 2017, ARM Limited. All rights reserved.<BR>
> #
> # 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.<BR>
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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 {
> + <LibraryClasses>
> + 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 {
> + <LibraryClasses>
> + 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +#
> +# 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +
> + 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<CmObjectId> (
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347145681&sdata=K9HVTSZ3%2BqOcifbd30%2BzzcZScxiQpjLjxwz5caD25z4%3D&reserved=0
> +
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/SmbiosTableGenerator.h>
> +
> +#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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/SmbiosTableGenerator.h>
> +
> +/** 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/AcpiLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +#include <IndustryStandard/DebugPort2Table.h>
> +#include <Drivers/PL011Uart.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <DynamicTables/ConfigurationManagerHelper.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <DynamicTables/ArmNameSpaceObjects.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Library/TableHelperLib.h>
> +
> +/** 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/AcpiLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <DynamicTables/ConfigurationManagerHelper.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <DynamicTables/ArmNameSpaceObjects.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Library/TableHelperLib.h>
> +
> +/** 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/AcpiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <DynamicTables/ConfigurationManagerHelper.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <DynamicTables/ArmNameSpaceObjects.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Library/TableHelperLib.h>
> +
> +/** 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/AcpiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <DynamicTables/ConfigurationManagerHelper.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <DynamicTables/ArmNameSpaceObjects.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Library/TableHelperLib.h>
> +
> +/** 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/AcpiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <DynamicTables/ConfigurationManagerHelper.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <DynamicTables/ArmNameSpaceObjects.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Library/TableHelperLib.h>
> +
> +/** 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/AcpiLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <DynamicTables/ArmNameSpaceObjects.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Library/TableHelperLib.h>
> +
> +/** 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/DebugLib.h>
> +#include <Library/AcpiLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <DynamicTables/ConfigurationManagerHelper.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <DynamicTables/ArmNameSpaceObjects.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Library/TableHelperLib.h>
> +
> +/** 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
> +https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> +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 <Protocol/AcpiTable.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <Protocol/ConfigurationManagerProtocol.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
> + )
> +{
> + 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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347155694&sdata=Vbi5fMjtzoPlo8V336zBbedbol0iV538QsEJCuyssSU%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Protocol/DynamicTableFactoryProtocol.h>
> +#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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347165698&sdata=QltD7gCgjwkiQSrrD6ZFKjuKJJjoNXfncV%2Fbs4sJkPc%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/SmbiosTableGenerator.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Protocol/DynamicTableFactoryProtocol.h>
> +#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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347165698&sdata=QltD7gCgjwkiQSrrD6ZFKjuKJJjoNXfncV%2Fbs4sJkPc%3D&reserved=0
> +
> + 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 <Protocol/Smbios.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/SmbiosTableGenerator.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Protocol/DynamicTableFactoryProtocol.h>
> +#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
> + https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347165698&sdata=QltD7gCgjwkiQSrrD6ZFKjuKJJjoNXfncV%2Fbs4sJkPc%3D&reserved=0
> +
> + 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 <Protocol/AcpiTable.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Smbios.h>
> +
> +#include <DynamicTables/TableGenerator.h>
> +#include <DynamicTables/AcpiTableGenerator.h>
> +#include <DynamicTables/SmbiosTableGenerator.h>
> +#include <DynamicTables/StandardNameSpaceObjects.h>
> +#include <DynamicTables/ConfigurationManagerObject.h>
> +#include <DynamicTables/ConfigurationManagerHelper.h>
> +#include <Protocol/ConfigurationManagerProtocol.h>
> +#include <Protocol/DynamicTableFactoryProtocol.h>
> +#include <Library/TableHelperLib.h>
> +
> +/** 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.<BR>
> +#
> +# 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
> +# https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fopensource.org%2Flicenses%2Fbsd-license.php&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347165698&sdata=QltD7gCgjwkiQSrrD6ZFKjuKJJjoNXfncV%2Fbs4sJkPc%3D&reserved=0
> +#
> +# 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://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347165698&sdata=DOHnkhWF%2FPMDziy4%2FYIMOB439O0IvZaHuB1QL0CmdI8%3D&reserved=0
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347165698&sdata=DOHnkhWF%2FPMDziy4%2FYIMOB439O0IvZaHuB1QL0CmdI8%3D&reserved=0
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=02%7C01%7Csean.brogan%40microsoft.com%7C2ac4d526c9b240a1fa4308d50a7851cc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636426434347165698&sdata=DOHnkhWF%2FPMDziy4%2FYIMOB439O0IvZaHuB1QL0CmdI8%3D&reserved=0
next prev parent reply other threads:[~2017-10-03 18:41 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-02 19:47 [PATCH 0/2] Dynamic Tables evan.lloyd
2017-10-02 19:47 ` [PATCH 1/2] MdeModulePkg: Dynamic Tables Framework evan.lloyd
2017-10-03 14:34 ` Zeng, Star
2017-10-03 16:03 ` Leif Lindholm
2017-10-03 18:44 ` Sean Brogan [this message]
2017-10-03 17:03 ` Evan Lloyd
2017-10-02 19:47 ` [PATCH 2/2] [edk2-platforms] Platform/ARM: Dynamic Tables support for FVP evan.lloyd
2017-10-03 17:12 ` [PATCH 0/2] Dynamic Tables Evan Lloyd
2017-10-10 2:29 ` Yao, Jiewen
2017-10-10 18:52 ` Evan Lloyd
2017-10-10 19:57 ` Laszlo Ersek
2017-10-11 1:25 ` Yao, Jiewen
2017-10-12 15:43 ` Leif Lindholm
2017-10-12 15:46 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=MWHPR21MB0479120C3CBD548C5246038DE1720@MWHPR21MB0479.namprd21.prod.outlook.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox