* [PATCH v1 01/22] DynamicTablesPkg: Dynamic Tables Framework
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
@ 2018-12-21 16:56 ` Sami Mujawar
2018-12-21 16:56 ` [PATCH v1 02/22] DynamicTablesPkg: Table Generator definition Sami Mujawar
` (20 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:56 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
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
Source Language (ASL), Table Definition Language (TDL) and
C-code. This approach can be error prone and involves time
consuming debugging.
In addition, it may be desirable to configure platform hardware
at runtime such as: configuring the number of cores available
for use by the OS, or turning SoC features ON or OFF.
This patch introduces Dynamic Tables Framework which also provides
mechanisms to reduce the amount of effort required in porting
firmware to new platforms. A more detailed description is in
the Readme.md file.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Readme.md | 139 ++++++++++++++++++++
1 file changed, 139 insertions(+)
diff --git a/DynamicTablesPkg/Readme.md b/DynamicTablesPkg/Readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..93fd1f313aa5227df5c1ccc82dfe17cb4c8f9e0a
--- /dev/null
+++ b/DynamicTablesPkg/Readme.md
@@ -0,0 +1,139 @@
+Dynamic Tables Framework
+------------------------
+
+Dynamic Tables Framework provides mechanisms to reduce the amount
+of effort required in porting firmware to new platforms. The aim is
+to provide an implementation capable of generating the firmware
+tables from an external source. This is potentially a management
+node, either local or remote, or, where suitable, a file that might
+be generated from the system construction. This initial release
+does not fully implement that - the configuration is held in local
+UEFI modules.
+
+Feature Summary
+---------------
+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
+Source Language (ASL), Table Definition Language (TDL) and
+C-code. This approach can be error prone and involves time
+consuming debugging. In addition, it may be desirable to configure
+platform hardware at runtime such as: configuring the number of
+cores available for use by the OS, or turning SoC features ON or
+OFF.
+
+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 provides the ability to implement custom/OEM
+generators; thereby facilitating support for custom tables. The
+custom generators can also utilize the existing standard generators
+and override any functionality if needed.
+
+The framework currently implements a set of standard ACPI table
+generators for ARM architecture, that can generate Server Base Boot
+Requirement (SBBR) compliant tables. Although, the set of standard
+generators implement the functionality required for ARM architecture;
+the framework is extensible, and support for other architectures can
+be added easily.
+
+The framework currently supports the following table generators for ARM:
+* DBG2 - Debug Port Table 2
+* DSDT - Differentiated system description table. This is essentially
+ a RAW table generator.
+* FADT - Fixed ACPI Description Table
+* GTDT - Generic Timer Description Table
+* IORT - IO Remapping Table
+* MADT - Multiple APIC Description Table
+* MCFG - PCI Express memory mapped configuration space base address
+ Description Table
+* SPCR - Serial Port Console Redirection Table
+* SSDT - Secondary System Description Table. This is essentially
+ a RAW table generator.
+
+Roadmap
+-------
+The current implementation of the Configuration Manager populates the
+platform information statically as a C structure. Further enhancements
+to introduce runtime loading of platform information from a platform
+information file is planned.
+
+Also support for generating SMBIOS tables is planned and will be added
+subsequently.
+
+Related Modules
+---------------
+
+### ACPICA iASL compiler
+The RAW table generator, used to process the DSDT/SSDT files depends on
+the iASL compiler to convert the DSDT/SSDT ASL files to a C array containing
+the hex AML code. The "-tc" option of the iASL compiler has been enhanced to
+support generation of an AML hex file (C header) with a unique symbol name
+so that it is suitable for inclusion from a C source file.
+
+Related Links
+--------------
+
+<https://github.com/acpica/acpica.git>
+
+
+Supported Platforms
+-------------------
+1. Juno
+2. FVP Models
+
+Build Instructions
+------------------
+1. Set path for the iASL compiler with support for generating a C header
+ file as output.
+
+2. Set PACKAGES_PATH to point to the locations of the following repositories:
+
+Example:
+
+> set PACKAGES_PATH=%CD%\edk2;%CD%\edk2-platforms;
+
+ or
+
+> export PACKAGES_PATH=$PWD/edk2:$PWD/edk2-platforms
+
+3. To enable Dynamic tables framework the *'DYNAMIC_TABLES_FRAMEWORK'*
+option must be defined. This can be passed as a command line
+parameter to the edk2 build system.
+
+Example:
+
+>build -a AARCH64 -p Platform\ARM\JunoPkg\ArmJuno.dsc
+ -t GCC5 **-D DYNAMIC_TABLES_FRAMEWORK**
+
+or
+
+>build -a AARCH64 -p Platform\ARM\VExpressPkg\ArmVExpress-FVP-AArch64.dsc
+ -t GCC5 **-D DYNAMIC_TABLES_FRAMEWORK**
+
+Prerequisites
+-------------
+ACPICA iASL compiler with the enhanced "-tc" option to support generation of
+AML hex (C header) files with unique symbol names.
+
+A patch *'[iASL: Enhance the -tc option (create AML hex file in C)](https://github.com/acpica/acpica/commit/f9a88a4c1cd020b6a5475d63b29626852a0b5f37)'*, dated 16 March 2018 (2018-03-16),
+to enable this support has been integrated to the ACPICA source repository.
+
+Ensure that the iASL compiler used for building *Dynamic Tables Framework* has this feature enabled.
+
+This feature was made available in the *ACPICA Compiler update
+[Version 20180508](https://www.acpica.org/node/156)*, dated 8 May 2018 (2018-05-08).
+
+Documentation
+-------------
+
+Refer to the following presentation from *UEFI Plugfest Seattle 2018*:
+
+[Dynamic Tables Framework: A Step Towards Automatic Generation of Advanced Configuration and Power Interface (ACPI) & System Management BIOS (SMBIOS) Tables – Sami Mujawar (Arm).](http://www.uefi.org/sites/default/files/resources/Arm_Dynamic%20Tables%20Framework%20A%20Step%20Towards%20Automatic%20Generation%20of%20Advanced%20Configuration%20and%20Power%20Interface%20%28ACPI%29%20%26%20System%20Management%20BIOS%20%28SMBIOS%29%20Tables%20_0.pdf)
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 02/22] DynamicTablesPkg: Table Generator definition
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
2018-12-21 16:56 ` [PATCH v1 01/22] DynamicTablesPkg: " Sami Mujawar
@ 2018-12-21 16:56 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 03/22] DynamicTablesPkg: Acpi Table Generator Sami Mujawar
` (19 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:56 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
A Table generator is a component that implements the logic
for building a firmware table. This is typically implemented
as a library and registers itself with a table factory.
Table generators are further classified based on type of table
it generates, a namespace that signifies if the implementation
is standard or an OEM specific implementation and a table Id.
This patch introduces the definitions used for describing a
table generator.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTablesPkg.dec | 24 ++
DynamicTablesPkg/Include/TableGenerator.h | 252 ++++++++++++++++++++
2 files changed, 276 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec b/DynamicTablesPkg/DynamicTablesPkg.dec
new file mode 100644
index 0000000000000000000000000000000000000000..b1a6c64948d01426fc95b8599fc17adaa8c35f3d
--- /dev/null
+++ b/DynamicTablesPkg/DynamicTablesPkg.dec
@@ -0,0 +1,24 @@
+## @file
+# dec file for Dynamic Tables Framework.
+#
+# Copyright (c) 2017 - 2018, 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.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = DynamicTablesPkg
+ PACKAGE_GUID = 188EB346-8ABA-460E-A105-0F9D76F7324A
+ PACKAGE_VERSION = 1.0
+
+[Includes]
+ Include
+
diff --git a/DynamicTablesPkg/Include/TableGenerator.h b/DynamicTablesPkg/Include/TableGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea996085683ff6a783ec9a676efce6604b956d8e
--- /dev/null
+++ b/DynamicTablesPkg/Include/TableGenerator.h
@@ -0,0 +1,252 @@
+/** @file
+
+ Copyright (c) 2017, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - ACPI - Advanced Configuration and Power Interface
+ - SMBIOS - System Management BIOS
+ - DT - Device Tree
+**/
+
+#ifndef TABLE_GENERATOR_H_
+#define TABLE_GENERATOR_H_
+
+/** The TABLE_GENERATOR_ID type describes the Table Generator ID
+
+ Table Generator ID
+
+_______________________________________________________________________________
+| 31 | 30 |29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17| 16|
+-------------------------------------------------------------------------------
+|TNSID| 0 | TT | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0| 0|
+_______________________________________________________________________________
+_______________________________________________________________________________
+|15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0|
+-------------------------------------------------------------------------------
+| Table ID |
+_______________________________________________________________________________
+
+ Bit [31] - Table NameSpace ID (TNSID)
+ 0 - Standard
+ 1 - Custom/OEM
+
+ Bit [30] - Reserved, Must be Zero
+
+ Bit [29:28] - Table Type (TT)
+ 0 - ACPI Table
+ 1 - SMBIOS Table
+ 2 - DT (Device Tree) Table
+ 3 - Reserved (INVALID)
+
+ Bit [27:16] - Reserved, Must Be Zero
+
+ Bit [15:0] - Table ID
+
+ Standard ACPI Table IDs:
+ 0 - Reserved
+ 1 - RAW
+ 2 - FADT
+ 3 - DSDT
+ 4 - SSDT
+ 5 - MADT
+ 6 - GTDT
+ 7 - DBG2
+ 8 - SPCR
+ 9 - MCFG
+
+ Standard SMBIOS Table IDs:
+ 0 - Reserved
+ 1 - RAW
+ 2 - Table Type00
+ 3 - Table Type01
+ 4 - Table Type02
+ 5 - Table Type03
+ 6 - Table Type04
+ 7 - Table Type05
+ 8 - Table Type06
+ 9 - Table Type07
+ 10 - Table Type08
+ 11 - Table Type09
+ 12 - Table Type10
+ 13 - Table Type11
+ 14 - Table Type12
+ 15 - Table Type13
+ 16 - Table Type14
+ 17 - Table Type15
+ 18 - Table Type16
+ 19 - Table Type17
+ 20 - Table Type18
+ 21 - Table Type19
+ 22 - Table Type20
+ 23 - Table Type21
+ 24 - Table Type22
+ 25 - Table Type23
+ 26 - Table Type24
+ 27 - Table Type25
+ 28 - Table Type26
+ 29 - Table Type27
+ 30 - Table Type28
+ 31 - Table Type29
+ 32 - Table Type30
+ 33 - Table Type31
+ 34 - Table Type32
+ 35 - Table Type33
+ 36 - Table Type34
+ 37 - Table Type35
+ 38 - Table Type36
+ 39 - Table Type37
+ 40 - Table Type38
+ 41 - Table Type39
+ 42 - Table Type40
+ 43 - Table Type41
+ 44 - Table Type42
+ 45-127 - Reserved
+ 128 - Table Type126
+ 129 - Table Type127
+**/
+typedef UINT32 TABLE_GENERATOR_ID;
+
+/** This enum lists the Table Generator Types.
+*/
+typedef enum TableGeneratorType {
+ ETableGeneratorTypeAcpi = 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)
+
+/** Starting bit position for the Table Type bits
+*/
+#define TABLE_TYPE_BIT_SHIFT 28
+
+/** Starting bit position for the Table Namespace ID bit
+*/
+#define TABLE_NAMESPACE_ID_BIT_SHIFT 31
+
+/** This macro returns the Table ID from the TableGeneratorId.
+
+ @param [in] TableGeneratorId The table generator ID.
+
+ @return 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.
+
+ @return the Table type described by the TableGeneratorId.
+**/
+#define GET_TABLE_TYPE(TableGeneratorId) \
+ (((TableGeneratorId) & TABLE_TYPE_MASK) >> TABLE_TYPE_BIT_SHIFT)
+
+/** This macro returns the Namespace ID from the TableGeneratorId.
+
+ @param [in] TableGeneratorId The table generator ID.
+
+ @return the Namespace described by the TableGeneratorId.
+**/
+#define GET_TABLE_NAMESPACEID(TableGeneratorId) \
+ (((TableGeneratorId) & TABLE_NAMESPACEID_MASK) >> \
+ TABLE_NAMESPACE_ID_BIT_SHIFT)
+
+/** This macro checks if the TableGeneratorId is in the Standard Namespace.
+
+ @param [in] TableGeneratorId The table generator ID.
+
+ @return 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.
+
+ @return a TableGeneratorId calculated from the inputs.
+**/
+#define CREATE_TABLE_GEN_ID(TableType, TableNameSpaceId, TableId) \
+ ((((TableType) << TABLE_TYPE_BIT_SHIFT) & TABLE_TYPE_MASK) | \
+ (((TableNameSpaceId) << TABLE_NAMESPACE_ID_BIT_SHIFT) & \
+ TABLE_NAMESPACEID_MASK) | ((TableId) & TABLE_ID_MASK))
+
+/** Starting bit position for MAJOR revision
+*/
+#define MAJOR_REVISION_BIT_SHIFT 16
+
+/** A mask for Major revision.
+*/
+#define MAJOR_REVISION_MASK 0xFFFF
+
+/** A mask for Minor revision.
+*/
+#define MINOR_REVISION_MASK 0xFFFF
+
+/** This macro generates a Major.Minor version
+ where the Major and Minor fields are 16 bit.
+
+ @param [in] Major The Major revision.
+ @param [in] Minor The Minor revision.
+
+ @return a 32 bit representation of the type Major.Minor.
+**/
+#define CREATE_REVISION(Major, Minor) \
+ ((((Major) & MAJOR_REVISION_MASK) << MAJOR_REVISION_BIT_SHIFT) | \
+ ((Minor) & MINOR_REVISION_MASK))
+
+/** This macro returns the Major revision
+
+ Extracts Major from the 32 bit representation of the type Major.Minor
+
+ @param [in] Revision The Revision value which is 32 bit.
+
+ @return the Major part of the revision.
+**/
+#define GET_MAJOR_REVISION(Revision) \
+ (((Revision) >> MAJOR_REVISION_BIT_SHIFT) & MAJOR_REVISION_MASK)
+
+/** This macro returns the Minor revision
+
+ Extracts Minor from the 32 bit representation of the type Major.Minor
+
+ @param [in] Revision The Revision value which is 32 bit.
+
+ @return the Minor part of the revision.
+**/
+#define GET_MINOR_REVISION(Revision) ((Revision) & MINOR_REVISION_MASK)
+
+#endif // TABLE_GENERATOR_H_
+
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 03/22] DynamicTablesPkg: Acpi Table Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
2018-12-21 16:56 ` [PATCH v1 01/22] DynamicTablesPkg: " Sami Mujawar
2018-12-21 16:56 ` [PATCH v1 02/22] DynamicTablesPkg: Table Generator definition Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 04/22] DynamicTablesPkg: SMBIOS " Sami Mujawar
` (18 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
This patch introduces the required interfaces and definitions
for implementing an ACPI table generator.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Include/AcpiTableGenerator.h | 357 ++++++++++++++++++++
1 file changed, 357 insertions(+)
diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad4d0732197f25bf43f3fb3cdf0cc9321e9d2030
--- /dev/null
+++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h
@@ -0,0 +1,357 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+ - Std or STD - Standard
+**/
+
+#ifndef ACPI_TABLE_GENERATOR_H_
+#define ACPI_TABLE_GENERATOR_H_
+
+#include <IndustryStandard/Acpi.h>
+
+// Module specific include files.
+#include <TableGenerator.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 generators customized by the OEM.
+
+The Dynamic Tables Framework implements the following ACPI table generators:
+ - RAW : This is the simplest ACPI table generator. It simply 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 a 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 a 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 from
+ the Configuration Manager and builds the FADT table.
+ - MADT : The MADT generator collates the GIC information from the
+ Configuration Manager and builds the MADT table.
+ - GTDT : The GTDT generator collates the Timer information from the
+ Configuration Manager and builds the GTDT table.
+ - DBG2 : The DBG2 generator collates the debug serial port information from
+ the Configuration Manager and builds the DBG2 table.
+ - SPCR : The SPCR generator collates the serial port information from the
+ Configuration Manager and builds the SPCR table.
+ - MCFG : The MCFG generator collates the PCI configuration space information
+ from the Configuration Manager and builds the MCFG table.
+ - IORT : The IORT generator collates the IO Topology information from the
+ Configuration Manager and builds the IORT table.
+*/
+
+/** The ACPI_TABLE_GENERATOR_ID type describes ACPI table generator ID.
+*/
+typedef TABLE_GENERATOR_ID ACPI_TABLE_GENERATOR_ID;
+
+/** The ESTD_ACPI_TABLE_ID enum describes the ACPI table IDs reserved for
+ the standard generators.
+*/
+typedef enum StdAcpiTableId {
+ ESTD_ACPI_TABLE_ID_RESERVED = 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_IORT, ///< IORT Generator
+ ESTD_ACPI_TABLE_ID_MAX
+} ESTD_ACPI_TABLE_ID;
+
+/** This macro checks if the Table Generator ID is for an ACPI Table Generator.
+
+ @param [in] TableGeneratorId The table generator ID.
+
+ @return 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.
+
+ @return 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.
+
+ @return a standard ACPI table generator ID.
+**/
+#define CREATE_STD_ACPI_TABLE_GEN_ID(TableId) \
+ CREATE_TABLE_GEN_ID ( \
+ ETableGeneratorTypeAcpi, \
+ ETableGeneratorNameSpaceStd, \
+ TableId \
+ )
+
+/** This macro creates an OEM ACPI Table Generator ID.
+
+ @param [in] TableId The table generator ID.
+
+ @return an OEM ACPI table generator ID.
+**/
+#define CREATE_OEM_ACPI_TABLE_GEN_ID(TableId) \
+ CREATE_TABLE_GEN_ID ( \
+ ETableGeneratorTypeAcpi, \
+ ETableGeneratorNameSpaceOem, \
+ 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 EDKII_CONFIGURATION_MANAGER_PROTOCOL;
+typedef struct CmAStdObjAcpiTableInfo CM_STD_OBJ_ACPI_TABLE_INFO;
+typedef struct AcpiTableGenerator ACPI_TABLE_GENERATOR;
+
+/** This function pointer describes the interface to ACPI table build
+ functions provided by the ACPI table generator and called by the
+ Table Manager to build an ACPI table.
+
+ @param [in] This Pointer to the ACPI table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI table information.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol interface.
+ @param [out] Table Pointer to the generated ACPI table.
+
+ @return EFI_SUCCESS If the table is generated successfully or other
+ failure codes as returned by the generator.
+**/
+typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLE) (
+ IN CONST ACPI_TABLE_GENERATOR * This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** Table
+ );
+
+/** This function pointer describes the interface used by the
+ Table Manager to give the generator an opportunity to free
+ any resources allocated for building the ACPI table.
+
+ @param [in] This Pointer to the ACPI table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Table Pointer to the ACPI Table.
+
+ @return EFI_SUCCESS If freed successfully or other failure codes
+ as returned by the generator.
+**/
+typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_FREE_TABLE) (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table
+ );
+
+/** This function pointer describes an extended interface to build
+ ACPI Tables. The ACPI table generator can generate multiple
+ ACPI Tables and return a pointer to the list of ACPI tables.
+ The FreeTableResourcesEx() must be called to free any resources
+ that may have been allocated using this interface.
+
+ @param [in] This Pointer to the ACPI table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI table information.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol interface.
+ @param [out] Table Pointer to a list of generated ACPI table(s).
+ @param [out] TableCount Number of generated ACPI table(s).
+
+ @return EFI_SUCCESS If the table is generated successfully or other
+ failure codes as returned by the generator.
+**/
+typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_BUILD_TABLEEX) (
+ IN CONST ACPI_TABLE_GENERATOR * This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER *** Table,
+ OUT UINTN * CONST TableCount
+ );
+
+/** This function pointer describes an extended interface used by the
+ Table Manager to give the generator an opportunity to free
+ any resources allocated for building the ACPI table. This interface
+ must be used in conjunction with the BuildAcpiTableEx interface.
+
+ @param [in] This Pointer to the ACPI table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Table Pointer to the list of ACPI Table(s).
+ @param [in] TableCount Number of ACPI table(s).
+
+ @return EFI_SUCCESS If freed successfully or other failure codes
+ as returned by the generator.
+**/
+typedef EFI_STATUS (*ACPI_TABLE_GENERATOR_FREE_TABLEEX) (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER *** CONST Table,
+ IN CONST UINTN TableCount
+ );
+
+/** The ACPI_TABLE_GENERATOR structure provides an interface that the
+ Table Manager can use to invoke the functions to build ACPI tables.
+
+ Note: Although the Generator is required to implement at least
+ one pair of interfaces (BuildAcpiTable & FreeTableResources or
+ BuildAcpiTableEx & FreeTableResourcesEx) for generating the ACPI
+ table(s), if both pair of interfaces are implemented the extended
+ version will take precedence.
+**/
+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 extended build function pointer.
+ ACPI_TABLE_GENERATOR_BUILD_TABLEEX BuildAcpiTableEx;
+
+ /** The function to free any resources
+ allocated for building the ACPI table
+ using the extended interface.
+ */
+ ACPI_TABLE_GENERATOR_FREE_TABLEEX FreeTableResourcesEx;
+} ACPI_TABLE_GENERATOR;
+
+/** Register ACPI table factory generator.
+
+ The ACPI table factory maintains a list of the Standard and OEM ACPI
+ table generators.
+
+ @param [in] Generator Pointer to the ACPI table generator.
+
+ @retval EFI_SUCCESS The Generator was registered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The Generator ID is invalid or
+ the Generator pointer is NULL.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID is
+ already registered.
+**/
+EFI_STATUS
+EFIAPI
+RegisterAcpiTableGenerator (
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator
+ );
+
+/** Deregister ACPI generator.
+
+ This function is called by the ACPI table generator to deregister 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
+DeregisterAcpiTableGenerator (
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator
+ );
+
+#pragma pack()
+
+#endif // ACPI_TABLE_GENERATOR_H_
+
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 04/22] DynamicTablesPkg: SMBIOS Table Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (2 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 03/22] DynamicTablesPkg: Acpi Table Generator Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 05/22] DynamicTablesPkg: DT " Sami Mujawar
` (17 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
This patch introduces the required interfaces and definitions
for implementing a SMBIOS table generator.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Include/SmbiosTableGenerator.h | 240 ++++++++++++++++++++
1 file changed, 240 insertions(+)
diff --git a/DynamicTablesPkg/Include/SmbiosTableGenerator.h b/DynamicTablesPkg/Include/SmbiosTableGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e9193e381d051f60689e27daf84c382835d2c9f
--- /dev/null
+++ b/DynamicTablesPkg/Include/SmbiosTableGenerator.h
@@ -0,0 +1,240 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef SMBIOS_TABLE_GENERATOR_H_
+#define SMBIOS_TABLE_GENERATOR_H_
+
+#include <IndustryStandard/SmBios.h>
+
+#include <TableGenerator.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.
+
+ @return 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.
+
+ @return 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.
+
+ @return 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 EDKII_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.
+
+ @return 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 EDKII_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.
+
+ @return 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 EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN SMBIOS_STRUCTURE ** Table
+ );
+
+/** The SMBIOS_TABLE_GENERATOR structure provides an interface that the
+ Table Manager can use to invoke the functions to build SMBIOS tables.
+*/
+typedef struct SmbiosTableGenerator {
+ /// The SMBIOS table generator ID.
+ SMBIOS_TABLE_GENERATOR_ID GeneratorID;
+
+ /// String describing the DT table
+ /// generator.
+ CONST CHAR16* Description;
+
+ /// The SMBIOS table type.
+ SMBIOS_TYPE Type;
+
+ /// SMBIOS table build function pointer.
+ SMBIOS_TABLE_GENERATOR_BUILD_TABLE BuildSmbiosTable;
+
+ /** The function to free any resources
+ allocated for building the SMBIOS table.
+ */
+ SMBIOS_TABLE_GENERATOR_FREE_TABLE FreeTableResources;
+} SMBIOS_TABLE_GENERATOR;
+
+/** Register SMBIOS table factory generator.
+
+ The SMBIOS table factory maintains a list of the Standard and OEM SMBIOS
+ table generators.
+
+ @param [in] Generator Pointer to the SMBIOS table generator.
+
+ @retval EFI_SUCCESS The Generator was registered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The Generator ID is invalid or
+ the Generator pointer is NULL.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID is
+ already registered.
+**/
+EFI_STATUS
+EFIAPI
+RegisterSmbiosTableGenerator (
+ IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator
+ );
+
+/** Deregister SMBIOS generator.
+
+ This function is called by the SMBIOS table generator to deregister 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
+DeregisterSmbiosTableGenerator (
+ IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator
+ );
+#pragma pack()
+
+#endif // SMBIOS_TABLE_GENERATOR_H_
+
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 05/22] DynamicTablesPkg: DT Table Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (3 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 04/22] DynamicTablesPkg: SMBIOS " Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 06/22] DynamicTablesPkg: Standard NameSpace Objects Sami Mujawar
` (16 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
This patch introduces the interfaces and definitions for
implementing a Device Tree table generator.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Include/DeviceTreeTableGenerator.h | 182 ++++++++++++++++++++
1 file changed, 182 insertions(+)
diff --git a/DynamicTablesPkg/Include/DeviceTreeTableGenerator.h b/DynamicTablesPkg/Include/DeviceTreeTableGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..458b0578e7e872ac61aef792f220db4b3fea0384
--- /dev/null
+++ b/DynamicTablesPkg/Include/DeviceTreeTableGenerator.h
@@ -0,0 +1,182 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+ - Std or STD - Standard
+**/
+
+#ifndef DEVICETREE_TABLE_GENERATOR_H_
+#define DEVICETREE_TABLE_GENERATOR_H_
+
+#include <TableGenerator.h>
+
+#pragma pack(1)
+
+/** The DT_TABLE_GENERATOR_ID type describes Device Tree table generator ID.
+*/
+typedef TABLE_GENERATOR_ID DT_TABLE_GENERATOR_ID;
+
+/** The ESTD_DT_TABLE_ID enum describes the DT table IDs reserved for
+ the standard generators.
+*/
+typedef enum StdDtTableId {
+ ESTD_DT_TABLE_ID_RESERVED = 0x0000, ///< Reserved.
+ ESTD_DT_TABLE_ID_RAW, ///< RAW Generator.
+ ESTD_DT_TABLE_ID_MAX
+} ESTD_DT_TABLE_ID;
+
+/** This macro checks if the Table Generator ID is for an DT Table Generator.
+
+ @param [in] TableGeneratorId The table generator ID.
+
+ @return TRUE if the table generator ID is for an DT Table
+ Generator.
+**/
+#define IS_GENERATOR_TYPE_DT(TableGeneratorId) \
+ (GET_TABLE_TYPE(TableGeneratorId) == ETableGeneratorTypeDt)
+
+/** This macro checks if the Table Generator ID is for a standard DT
+ Table Generator.
+
+ @param [in] TableGeneratorId The table generator ID.
+
+ @return TRUE if the table generator ID is for a standard DT
+ Table Generator.
+**/
+#define IS_VALID_STD_DT_GENERATOR_ID(TableGeneratorId) \
+ ( \
+ IS_GENERATOR_NAMESPACE_STD(TableGeneratorId) && \
+ IS_GENERATOR_TYPE_DT(TableGeneratorId) && \
+ ((GET_TABLE_ID(GeneratorId) >= ESTD_DT_TABLE_ID_RAW) && \
+ (GET_TABLE_ID(GeneratorId) < ESTD_DT_TABLE_ID_MAX)) \
+ )
+
+/** This macro creates a standard DT Table Generator ID.
+
+ @param [in] TableId The table generator ID.
+
+ @return a standard DT table generator ID.
+**/
+#define CREATE_STD_DT_TABLE_GEN_ID(TableId) \
+ CREATE_TABLE_GEN_ID ( \
+ ETableGeneratorTypeDt, \
+ ETableGeneratorNameSpaceStd, \
+ TableId \
+ )
+
+/** Forward declarations.
+*/
+typedef struct ConfigurationManagerProtocol EDKII_CONFIGURATION_MANAGER_PROTOCOL;
+typedef struct CmAStdObjDtTableInfo CM_STD_OBJ_DT_TABLE_INFO;
+typedef struct DtTableGenerator DT_TABLE_GENERATOR;
+
+/** This function pointer describes the interface to DT table build
+ functions provided by the DT table generator and called by the
+ Table Manager to build an DT table.
+
+ @param [in] Generator Pointer to the DT table generator.
+ @param [in] DtTableInfo Pointer to the DT table information.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol interface.
+ @param [out] Table Pointer to the generated DT table.
+
+ @return EFI_SUCCESS If the table is generated successfully or other
+ failure codes as returned by the generator.
+**/
+typedef EFI_STATUS (*DT_TABLE_GENERATOR_BUILD_TABLE) (
+ IN CONST DT_TABLE_GENERATOR * Generator,
+ IN CONST CM_STD_OBJ_DT_TABLE_INFO * CONST DtTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT VOID ** Table
+ );
+
+/** This function pointer describes the interface to used by the
+ Table Manager to give the generator an opportunity to free
+ any resources allocated for building the DT table.
+
+ @param [in] Generator Pointer to the DT table generator.
+ @param [in] DtTableInfo Pointer to the DT table information.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol interface.
+ @param [in] Table Pointer to the generated DT table.
+
+ @return EFI_SUCCESS If freed successfully or other failure codes
+ as returned by the generator.
+**/
+typedef EFI_STATUS (*DT_TABLE_GENERATOR_FREE_TABLE) (
+ IN CONST DT_TABLE_GENERATOR * Generator,
+ IN CONST CM_STD_OBJ_DT_TABLE_INFO * CONST DtTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN VOID ** Table
+ );
+
+/** The DT_TABLE_GENERATOR structure provides an interface that the
+ Table Manager can use to invoke the functions to build DT tables.
+*/
+typedef struct DtTableGenerator {
+ /// The DT table generator ID.
+ DT_TABLE_GENERATOR_ID GeneratorID;
+
+ /// String describing the DT table generator.
+ CONST CHAR16 * Description;
+
+ /// DT table build function pointer.
+ DT_TABLE_GENERATOR_BUILD_TABLE BuildDtTable;
+
+ /// The function to free any resources allocated for building the DT table.
+ DT_TABLE_GENERATOR_FREE_TABLE FreeTableResources;
+} DT_TABLE_GENERATOR;
+
+/** Register DT table factory generator.
+
+ The DT table factory maintains a list of the Standard and OEM DT
+ table generators.
+
+ @param [in] Generator Pointer to the DT table generator.
+
+ @retval EFI_SUCCESS The Generator was registered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The Generator ID is invalid or
+ the Generator pointer is NULL.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID is
+ already registered.
+**/
+EFI_STATUS
+EFIAPI
+RegisterDtTableGenerator (
+ IN CONST DT_TABLE_GENERATOR * CONST Generator
+ );
+
+/** Deregister DT generator.
+
+ This function is called by the DT table generator to deregister itself
+ from the DT table factory.
+
+ @param [in] Generator Pointer to the DT table generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER The generator is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+DeregisterDtTableGenerator (
+ IN CONST DT_TABLE_GENERATOR * CONST Generator
+ );
+
+#pragma pack()
+
+#endif // DEVICETREE_TABLE_GENERATOR_H_
+
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 06/22] DynamicTablesPkg: Standard NameSpace Objects
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (4 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 05/22] DynamicTablesPkg: DT " Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 07/22] DynamicTablesPkg: Arm " Sami Mujawar
` (15 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The dynamic tables frameworks core communicates with the
platform specific implementation using the configuration
manager protocol interface. The dynamic tables framework
core uses this interface to retrieve information required
for generating the firmware tables. This information is
represented in the form of objects, which are classified
as standard namespace objects, Arm namespace objects or
as Custom/OEM namespace objects.
This patch introduces the definitions for standard
namespace objects.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Include/StandardNameSpaceObjects.h | 116 ++++++++++++++++++++
1 file changed, 116 insertions(+)
diff --git a/DynamicTablesPkg/Include/StandardNameSpaceObjects.h b/DynamicTablesPkg/Include/StandardNameSpaceObjects.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f682a52dad4059b0d768d7765c4dbd875cc5d53
--- /dev/null
+++ b/DynamicTablesPkg/Include/StandardNameSpaceObjects.h
@@ -0,0 +1,116 @@
+/** @file
+
+ Copyright (c) 2017, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+ - Std or STD - Standard
+**/
+
+#ifndef STANDARD_NAMESPACE_OBJECTS_H_
+#define STANDARD_NAMESPACE_OBJECTS_H_
+
+#include <AcpiTableGenerator.h>
+#include <SmbiosTableGenerator.h>
+
+#pragma pack(1)
+
+/** A macro defining a reserved zero/NULL token value that
+ does not identify any object.
+*/
+#define CM_NULL_TOKEN 0
+
+/** A reference token that the Configuration Manager can use
+ to identify a Configuration Manager object.
+
+ This can be used to differentiate between instances of
+ objects of the same types. The identification scheme is
+ implementation defined and is defined by the Configuration
+ Manager.
+
+ Typically the token is used to identify a specific instance
+ from a set of objects in a call to the GetObject()/SetObject(),
+ implemented by the Configuration Manager protocol.
+
+ Note: The token value 0 is reserved for a NULL token and does
+ not identify any object.
+**/
+typedef UINTN CM_OBJECT_TOKEN;
+
+/** The ESTD_OBJECT_ID enum describes the Object IDs
+ in the Standard Namespace.
+*/
+typedef enum StdObjectID {
+ EStdObjCfgMgrInfo = 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_
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 07/22] DynamicTablesPkg: Arm NameSpace Objects
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (5 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 06/22] DynamicTablesPkg: Standard NameSpace Objects Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 08/22] DynamicTablesPkg: Configuration Manager Objects Sami Mujawar
` (14 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The dynamic tables frameworks core communicates with the
platform specific implementation using the configuration
manager protocol interface. The dynamic tables framework
core uses this interface to retrieve information required
for generating the firmware tables. This information is
represented in the form of objects, which are classified
as standard namespace objects, Arm namespace objects or
as Custom/OEM namespace objects.
This patch introduces the definitions for the Arm namespace
objects.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Include/ArmNameSpaceObjects.h | 591 ++++++++++++++++++++
1 file changed, 591 insertions(+)
diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
new file mode 100644
index 0000000000000000000000000000000000000000..93cb6949f0eb2ac2ad3524494e4a14c7a6fab4b8
--- /dev/null
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -0,0 +1,591 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+ - Std or STD - Standard
+**/
+
+#ifndef ARM_NAMESPACE_OBJECTS_H_
+#define ARM_NAMESPACE_OBJECTS_H_
+
+#include <StandardNameSpaceObjects.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
+ EArmObjGTBlockTimerFrameInfo, ///< 13 - Generic Timer Block Frame Info
+ EArmObjPlatformGenericWatchdogInfo, ///< 14 - Platform Generic Watchdog
+ EArmObjPciConfigSpaceInfo, ///< 15 - PCI Configuration Space Info
+ EArmObjHypervisorVendorIdentity, ///< 16 - Hypervisor Vendor Id
+ EArmObjFixedFeatureFlags, ///< 17 - Fixed feature flags for FADT
+ EArmObjItsGroup, ///< 18 - ITS Group
+ EArmObjNamedComponent, ///< 19 - Named Component
+ EArmObjRootComplex, ///< 20 - Root Complex
+ EArmObjSmmuV1SmmuV2, ///< 21 - SMMUv1 or SMMUv2
+ EArmObjSmmuV3, ///< 22 - SMMUv3
+ EArmObjPmcg, ///< 23 - PMCG
+ EArmObjGicItsIdentifierArray, ///< 24 - GIC ITS Identifier Array
+ EArmObjIdMapping, ///< 25 - ID Mapping
+ EArmObjSmmuInterruptArray, ///< 26 - SMMU Interrupt Array
+ EArmObjMax
+} EARM_OBJECT_ID;
+
+/** A structure that describes the
+ ARM Boot Architecture flags.
+*/
+typedef struct CmArmBootArchInfo {
+ /** This is the ARM_BOOT_ARCH flags field of the FADT Table
+ described in the ACPI Table Specification.
+ */
+ UINT32 BootArchFlags;
+} CM_ARM_BOOT_ARCH_INFO;
+
+typedef struct CmArmCpuInfo {
+ // Reserved for use when SMBIOS tables are implemented
+} CM_ARM_CPU_INFO;
+
+typedef struct CmArmCpuInfoList {
+ UINT32 CpuCount;
+ CM_ARM_CPU_INFO * CpuInfo;
+} CM_ARM_CPU_INFO_LIST;
+
+/** A structure that describes the
+ Power Management Profile Information for the Platform.
+*/
+typedef struct CmArmPowerManagementProfileInfo {
+ /** This is the Preferred_PM_Profile field of the FADT Table
+ described in the ACPI Specification
+ */
+ UINT8 PowerManagementProfile;
+} CM_ARM_POWER_MANAGEMENT_PROFILE_INFO;
+
+/** A structure that describes the
+ GIC CPU Interface for the Platform.
+*/
+typedef struct CmArmGicCInfo {
+ /// The GIC CPU Interface number.
+ UINT32 CPUInterfaceNumber;
+
+ /** The ACPI Processor UID. This must match the
+ _UID of the CPU Device object information described
+ in the DSDT/SSDT for the CPU.
+ */
+ UINT32 AcpiProcessorUid;
+
+ /** The flags field as described by the GICC structure
+ in the ACPI Specification.
+ */
+ UINT32 Flags;
+
+ /** The parking protocol version field as described by
+ the GICC structure in the ACPI Specification.
+ */
+ UINT32 ParkingProtocolVersion;
+
+ /** The Performance Interrupt field as described by
+ the GICC structure in the ACPI Specification.
+ */
+ UINT32 PerformanceInterruptGsiv;
+
+ /** The CPU Parked address field as described by
+ the GICC structure in the ACPI Specification.
+ */
+ UINT64 ParkedAddress;
+
+ /** The base address for the GIC CPU Interface
+ as described by the GICC structure in the
+ ACPI Specification.
+ */
+ UINT64 PhysicalBaseAddress;
+
+ /** The base address for GICV interface
+ as described by the GICC structure in the
+ ACPI Specification.
+ */
+ UINT64 GICV;
+
+ /** The base address for GICH interface
+ as described by the GICC structure in the
+ ACPI Specification.
+ */
+ UINT64 GICH;
+
+ /** The GICV maintenance interrupt
+ as described by the GICC structure in the
+ ACPI Specification.
+ */
+ UINT32 VGICMaintenanceInterrupt;
+
+ /** The base address for GICR interface
+ as described by the GICC structure in the
+ ACPI Specification.
+ */
+ UINT64 GICRBaseAddress;
+
+ /** The MPIDR for the CPU
+ as described by the GICC structure in the
+ ACPI Specification.
+ */
+ UINT64 MPIDR;
+
+ /** The Processor Power Efficiency class
+ as described by the GICC structure in the
+ ACPI Specification.
+ */
+ UINT8 ProcessorPowerEfficiencyClass;
+} CM_ARM_GICC_INFO;
+
+/** A structure that describes the
+ GIC Distributor information for the Platform.
+*/
+typedef struct CmArmGicDInfo {
+ /// The GIC Distributor ID.
+ UINT32 GicId;
+
+ /// The Physical Base address for the GIC Distributor.
+ UINT64 PhysicalBaseAddress;
+
+ /** The global system interrupt
+ number where this GIC Distributor's
+ interrupt inputs start.
+ */
+ UINT32 SystemVectorBase;
+
+ /** The GIC version as described
+ by the GICD structure in the
+ ACPI Specification.
+ */
+ UINT8 GicVersion;
+} CM_ARM_GICD_INFO;
+
+/** A structure that describes the
+ GIC MSI Frame information for the Platform.
+*/
+typedef struct CmArmGicMsiFrameInfo {
+ /// The GIC MSI Frame ID
+ UINT32 GicMsiFrameId;
+
+ /// The Physical base address for the MSI Frame
+ UINT64 PhysicalBaseAddress;
+
+ /** The GIC MSI Frame flags
+ as described by the GIC MSI frame
+ structure in the ACPI Specification.
+ */
+ UINT32 Flags;
+
+ /// SPI Count used by this frame
+ UINT16 SPICount;
+
+ /// SPI Base used by this frame
+ UINT16 SPIBase;
+} CM_ARM_GIC_MSI_FRAME_INFO;
+
+/** A structure that describes the
+ GIC Redistributor information for the Platform.
+*/
+typedef struct CmArmGicRedistInfo {
+ /** The physical address of a page range
+ containing all GIC Redistributors.
+ */
+ UINT64 DiscoveryRangeBaseAddress;
+
+ /// Length of the GIC Redistributor Discovery page range
+ UINT32 DiscoveryRangeLength;
+} CM_ARM_GIC_REDIST_INFO;
+
+/** A structure that describes the
+ GIC Interrupt Translation Service information for the Platform.
+*/
+typedef struct CmArmGicItsInfo {
+ /// The GIC ITS ID
+ UINT32 GicItsId;
+
+ /// The physical address for the Interrupt Translation Service
+ UINT64 PhysicalBaseAddress;
+} CM_ARM_GIC_ITS_INFO;
+
+/** A structure that describes the
+ Serial Port information for the Platform.
+*/
+typedef struct CmArmSerialPortInfo {
+ /// The physical base address for the serial port
+ UINT64 BaseAddress;
+
+ /// The serial port interrupt
+ UINT32 Interrupt;
+
+ /// The serial port baud rate
+ UINT64 BaudRate;
+
+ /// The serial port clock
+ UINT32 Clock;
+
+ /// Serial Port subtype
+ UINT16 PortSubtype;
+} CM_ARM_SERIAL_PORT_INFO;
+
+/** A structure that describes the
+ Generic Timer information for the Platform.
+*/
+typedef struct CmArmGenericTimerInfo {
+ /// The physical base address for the counter control frame
+ UINT64 CounterControlBaseAddress;
+
+ /// The physical base address for the counter read frame
+ UINT64 CounterReadBaseAddress;
+
+ /// The secure PL1 timer interrupt
+ UINT32 SecurePL1TimerGSIV;
+
+ /// The secure PL1 timer flags
+ UINT32 SecurePL1TimerFlags;
+
+ /// The non-secure PL1 timer interrupt
+ UINT32 NonSecurePL1TimerGSIV;
+
+ /// The non-secure PL1 timer flags
+ UINT32 NonSecurePL1TimerFlags;
+
+ /// The virtual timer interrupt
+ UINT32 VirtualTimerGSIV;
+
+ /// The virtual timer flags
+ UINT32 VirtualTimerFlags;
+
+ /// The non-secure PL2 timer interrupt
+ UINT32 NonSecurePL2TimerGSIV;
+
+ /// The non-secure PL2 timer flags
+ UINT32 NonSecurePL2TimerFlags;
+} CM_ARM_GENERIC_TIMER_INFO;
+
+/** A structure that describes the
+ Platform Generic Block Timer Frame information for the Platform.
+*/
+typedef struct CmArmGTBlockTimerFrameInfo {
+ /// The Generic Timer frame number
+ UINT8 FrameNumber;
+
+ /// The physical base address for the CntBase block
+ UINT64 PhysicalAddressCntBase;
+
+ /// The physical base address for the CntEL0Base block
+ UINT64 PhysicalAddressCntEL0Base;
+
+ /// The physical timer interrupt
+ UINT32 PhysicalTimerGSIV;
+
+ /** The physical timer flags as described by the GT Block
+ Timer frame Structure in the ACPI Specification.
+ */
+ UINT32 PhysicalTimerFlags;
+
+ /// The virtual timer interrupt
+ UINT32 VirtualTimerGSIV;
+
+ /** The virtual timer flags as described by the GT Block
+ Timer frame Structure in the ACPI Specification.
+ */
+ UINT32 VirtualTimerFlags;
+
+ /** The common timer flags as described by the GT Block
+ Timer frame Structure in the ACPI Specification.
+ */
+ UINT32 CommonFlags;
+} CM_ARM_GTBLOCK_TIMER_FRAME_INFO;
+
+/** A structure that describes the
+ Platform Generic Block Timer information for the Platform.
+*/
+typedef struct CmArmGTBlockInfo {
+ /// The physical base address for the GT Block Timer structure
+ UINT64 GTBlockPhysicalAddress;
+
+ /// The number of timer frames implemented in the GT Block
+ UINT32 GTBlockTimerFrameCount;
+
+ /// Reference token for the GT Block timer frame list
+ CM_OBJECT_TOKEN GTBlockTimerFrameToken;
+} CM_ARM_GTBLOCK_INFO;
+
+/** A structure that describes the
+ SBSA Generic Watchdog information for the Platform.
+*/
+typedef struct CmArmGenericWatchdogInfo {
+ /// The physical base address of the SBSA Watchdog control frame
+ UINT64 ControlFrameAddress;
+
+ /// The physical base address of the SBSA Watchdog refresh frame
+ UINT64 RefreshFrameAddress;
+
+ /// The watchdog interrupt
+ UINT32 TimerGSIV;
+
+ /** The flags for the watchdog as described by the SBSA watchdog
+ structure in the ACPI specification.
+ */
+ UINT32 Flags;
+} CM_ARM_GENERIC_WATCHDOG_INFO;
+
+/** A structure that describes the
+ PCI Configuration Space information for the Platform.
+*/
+typedef struct CmArmPciConfigSpaceInfo {
+ /// The physical base address for the PCI segment
+ UINT64 BaseAddress;
+
+ /// The PCI segment group number
+ UINT16 PciSegmentGroupNumber;
+
+ /// The start bus number
+ UINT8 StartBusNumber;
+
+ /// The end bus number
+ UINT8 EndBusNumber;
+} CM_ARM_PCI_CONFIG_SPACE_INFO;
+
+/** A structure that describes the
+ Hypervisor Vendor ID information for the Platform.
+*/
+typedef struct CmArmHypervisorVendorId {
+ /// The hypervisor Vendor ID
+ UINT64 HypervisorVendorId;
+} CM_ARM_HYPERVISOR_VENDOR_ID;
+
+/** A structure that describes the
+ Fixed feature flags for the Platform.
+*/
+typedef struct CmArmFixedFeatureFlags {
+ /// The Fixed feature flags
+ UINT32 Flags;
+} CM_ARM_FIXED_FEATURE_FLAGS;
+
+/** A structure that describes the
+ ITS Group node for the Platform.
+*/
+typedef struct CmArmItsGroupNode {
+ /// An unique token used to ideintify this object
+ CM_OBJECT_TOKEN Token;
+ /// The number of ITS identifiers in the ITS node
+ UINT32 ItsIdCount;
+ /// Reference token for the ITS identifier array
+ CM_OBJECT_TOKEN ItsIdToken;
+} CM_ARM_ITS_GROUP_NODE;
+
+/** A structure that describes the
+ GIC ITS Identifiers for an ITS Group node.
+*/
+typedef struct CmArmGicItsIdentifier {
+ /// The ITS Identifier
+ UINT32 ItsId;
+} CM_ARM_ITS_IDENTIFIER;
+
+/** A structure that describes the
+ Named component node for the Platform.
+*/
+typedef struct CmArmNamedComponentNode {
+ /// An unique token used to ideintify this object
+ CM_OBJECT_TOKEN Token;
+ /// Number of ID mappings
+ UINT32 IdMappingCount;
+ /// Reference token for the ID mapping array
+ CM_OBJECT_TOKEN IdMappingToken;
+
+ /// Flags for the named component
+ UINT32 Flags;
+
+ /// Memory access properties : Cache coherent attributes
+ UINT32 CacheCoherent;
+ /// Memory access properties : Allocation hints
+ UINT8 AllocationHints;
+ /// Memory access properties : Memory access flags
+ UINT8 MemoryAccessFlags;
+
+ /// Memory access properties : Address size limit
+ UINT8 AddressSizeLimit;
+ /** ASCII Null terminated string with the full path to
+ the entry in the namespace for this object.
+ */
+ CHAR8* ObjectName;
+} CM_ARM_NAMED_COMPONENT_NODE;
+
+/** A structure that describes the
+ Root complex node for the Platform.
+*/
+typedef struct CmArmRootComplexNode {
+ /// An unique token used to ideintify this object
+ CM_OBJECT_TOKEN Token;
+ /// Number of ID mappings
+ UINT32 IdMappingCount;
+ /// Reference token for the ID mapping array
+ CM_OBJECT_TOKEN IdMappingToken;
+
+ /// Memory access properties : Cache coherent attributes
+ UINT32 CacheCoherent;
+ /// Memory access properties : Allocation hints
+ UINT8 AllocationHints;
+ /// Memory access properties : Memory access flags
+ UINT8 MemoryAccessFlags;
+
+ /// ATS attributes
+ UINT32 AtsAttribute;
+ /// PCI segment number
+ UINT32 PciSegmentNumber;
+ /// Memory address size limit
+ UINT8 MemoryAddressSize;
+} CM_ARM_ROOT_COMPLEX_NODE;
+
+/** A structure that describes the
+ SMMUv1 or SMMUv2 node for the Platform.
+*/
+typedef struct CmArmSmmuV1SmmuV2Node {
+ /// An unique token used to ideintify this object
+ CM_OBJECT_TOKEN Token;
+ /// Number of ID mappings
+ UINT32 IdMappingCount;
+ /// Reference token for the ID mapping array
+ CM_OBJECT_TOKEN IdMappingToken;
+
+ /// SMMU Base Address
+ UINT64 BaseAddress;
+ /// Length of the memory range covered by the SMMU
+ UINT64 Span;
+ /// SMMU Model
+ UINT32 Model;
+ /// SMMU flags
+ UINT32 Flags;
+
+ /// Number of context interrupts
+ UINT32 ContextInterruptCount;
+ /// Reference token for the context interrupt array
+ CM_OBJECT_TOKEN ContextInterruptToken;
+
+ /// Number of PMU interrupts
+ UINT32 PmuInterruptCount;
+ /// Reference token for the PMU interrupt array
+ CM_OBJECT_TOKEN PmuInterruptToken;
+
+ /// GSIV of the SMMU_NSgIrpt interrupt
+ UINT32 SMMU_NSgIrpt;
+ /// SMMU_NSgIrpt interrupt flags
+ UINT32 SMMU_NSgIrptFlags;
+ /// GSIV of the SMMU_NSgCfgIrpt interrupt
+ UINT32 SMMU_NSgCfgIrpt;
+ /// SMMU_NSgCfgIrpt interrupt flags
+ UINT32 SMMU_NSgCfgIrptFlags;
+} CM_ARM_SMMUV1_SMMUV2_NODE;
+
+/** A structure that describes the
+ SMMUv3 node for the Platform.
+*/
+typedef struct CmArmSmmuV3Node {
+ /// An unique token used to ideintify this object
+ CM_OBJECT_TOKEN Token;
+ /// Number of ID mappings
+ UINT32 IdMappingCount;
+ /// Reference token for the ID mapping array
+ CM_OBJECT_TOKEN IdMappingToken;
+
+ /// SMMU Base Address
+ UINT64 BaseAddress;
+ /// SMMU flags
+ UINT32 Flags;
+ /// VATOS address
+ UINT64 VatosAddress;
+ /// Model
+ UINT32 Model;
+ /// GSIV of the Event interrupt if SPI based
+ UINT32 EventInterrupt;
+ /// PRI Interrupt if SPI based
+ UINT32 PriInterrupt;
+ /// GERR interrupt if GSIV based
+ UINT32 GerrInterrupt;
+ /// Sync interrupt if GSIV based
+ UINT32 SyncInterrupt;
+
+ /// Proximity domain flag
+ UINT32 ProximityDomain;
+ /// Index into the array of ID mapping
+ UINT32 DeviceIdMappingIndex;
+} CM_ARM_SMMUV3_NODE;
+
+/** A structure that describes the
+ PMCG node for the Platform.
+*/
+typedef struct CmArmPmcgNode {
+ /// An unique token used to ideintify this object
+ CM_OBJECT_TOKEN Token;
+ /// Number of ID mappings
+ UINT32 IdMappingCount;
+ /// Reference token for the ID mapping array
+ CM_OBJECT_TOKEN IdMappingToken;
+
+ /// Base Address for performance monitor counter group
+ UINT64 BaseAddress;
+ /// GSIV for the Overflow interrupt
+ UINT32 OverflowInterrupt;
+ /// Page 1 Base address
+ UINT64 Page1BaseAddress;
+
+ /// Reference token for the IORT node associated with this node
+ CM_OBJECT_TOKEN ReferenceToken;
+} CM_ARM_PMCG_NODE;
+
+/** A structure that describes the
+ ID Mappings for the Platform.
+*/
+typedef struct CmArmIdMapping {
+ /// Input base
+ UINT32 InputBase;
+ /// Number of input IDs
+ UINT32 NumIds;
+ /// Output Base
+ UINT32 OutputBase;
+ /// Reference token for the output node
+ CM_OBJECT_TOKEN OutputReferenceToken;
+ /// Flags
+ UINT32 Flags;
+} CM_ARM_ID_MAPPING;
+
+/** A structure that describes the
+ SMMU interrupts for the Platform.
+*/
+typedef struct CmArmSmmuInterrupt {
+ /// Interrupt number
+ UINT32 Interrupt;
+
+ /// Flags
+ UINT32 Flags;
+} CM_ARM_SMMU_INTERRUPT;
+
+#pragma pack()
+
+#endif // ARM_NAMESPACE_OBJECTS_H_
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 08/22] DynamicTablesPkg: Configuration Manager Objects
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (6 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 07/22] DynamicTablesPkg: Arm " Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 09/22] DynamicTablesPkg: Configuration Manager Protocol Sami Mujawar
` (13 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The dynamic tables frameworks core communicates with the
platform specific implementation using the configuration
manager protocol interface. The dynamic tables framework
core uses this interface to retrieve information required
for generating the firmware tables. This information is
represented in the form of objects, which are classified
as standard namespace objects, Arm namespace objects or
as Custom/OEM namespace objects.
The configuration manager objects provides a convenient
way for wrapping up the namespaces using a well defined
configuration manager object Id.
The configuration manager is a platform specific component
that collates the platform information required for generating
firmware tables and represents them as configuration manager
objects.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Include/ConfigurationManagerObject.h | 176 ++++++++++++++++++++
1 file changed, 176 insertions(+)
diff --git a/DynamicTablesPkg/Include/ConfigurationManagerObject.h b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..d1682c7066365bee6206f7de2b801be53a971750
--- /dev/null
+++ b/DynamicTablesPkg/Include/ConfigurationManagerObject.h
@@ -0,0 +1,176 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef CONFIGURATION_MANAGER_OBJECT_H_
+#define CONFIGURATION_MANAGER_OBJECT_H_
+
+#include <ArmNameSpaceObjects.h>
+#include <StandardNameSpaceObjects.h>
+
+#pragma pack(1)
+
+/** The CM_OBJECT_ID type is used to identify the Configuration Manager
+ objects.
+
+ Description of Configuration Manager Object ID
+_______________________________________________________________________________
+|31 |30 |29 |28 || 27 | 26 | 25 | 24 || 23 | 22 | 21 | 20 || 19 | 18 | 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
+ 11 - Generic Timer Info
+ 12 - Platform GT Block Info
+ 13 - Platform Generic Watchdog
+ 14 - PCI Configuration Space Info
+ 15 - Hypervisor Vendor Id
+ 16 - Fixed feature flags for FADT
+*/
+typedef UINT32 CM_OBJECT_ID;
+
+/** A mask for Object ID
+*/
+#define OBJECT_ID_MASK 0xFF
+
+/** A mask for Namespace ID
+*/
+#define NAMESPACE_ID_MASK 0xF
+
+/** Starting bit position for Namespace ID
+*/
+#define NAMESPACE_ID_BIT_SHIFT 28
+
+/** The EOBJECT_NAMESPACE_ID enum describes the defined namespaces
+ for the Configuration Manager Objects.
+*/
+typedef enum ObjectNameSpaceID {
+ EObjNameSpaceStandard, ///< Standard Objects Namespace
+ EObjNameSpaceArm, ///< ARM Objects Namespace
+ EObjNameSpaceOem = 0x8, ///< OEM Objects Namespace
+ EObjNameSpaceMax
+} EOBJECT_NAMESPACE_ID;
+
+/** A descriptor for Configuration Manager Objects.
+
+ The Configuration Manager Protocol interface uses this descriptor
+ to return the Configuration Manager Objects.
+*/
+typedef struct CmObjDescriptor {
+ /// sizeof the described Object or Object List.
+ UINT32 Size;
+
+ /// Pointer to the described Object or Object List.
+ VOID * Data;
+} CM_OBJ_DESCRIPTOR;
+
+#pragma pack()
+
+/** This macro returns the namespace ID from the CmObjectID.
+
+ @param [in] CmObjectId The Configuration Manager Object ID.
+
+ @retval Returns the Namespace ID corresponding to the CmObjectID.
+**/
+#define GET_CM_NAMESPACE_ID(CmObjectId) \
+ (((CmObjectId) >> NAMESPACE_ID_BIT_SHIFT) & \
+ NAMESPACE_ID_MASK)
+
+/** This macro returns the Object ID from the CmObjectID.
+
+ @param [in] CmObjectId The Configuration Manager Object ID.
+
+ @retval Returns the Object ID corresponding to the CmObjectID.
+**/
+#define GET_CM_OBJECT_ID(CmObjectId) ((CmObjectId) & OBJECT_ID_MASK)
+
+/** This macro returns a Configuration Manager Object ID
+ from the NameSpace ID and the ObjectID.
+
+ @param [in] NameSpaceId The namespace ID for the Object.
+ @param [in] ObjectId The Object ID.
+
+ @retval Returns the Configuration Manager Object ID.
+**/
+#define CREATE_CM_OBJECT_ID(NameSpaceId, ObjectId) \
+ ((((NameSpaceId) & NAMESPACE_ID_MASK) << NAMESPACE_ID_BIT_SHIFT) | \
+ ((ObjectId) & OBJECT_ID_MASK))
+
+/** This macro returns a Configuration Manager Object ID
+ in the Standard Object Namespace.
+
+ @param [in] ObjectId The Object ID.
+
+ @retval Returns a Standard Configuration Manager Object ID.
+**/
+#define CREATE_CM_STD_OBJECT_ID(ObjectId) \
+ (CREATE_CM_OBJECT_ID (EObjNameSpaceStandard, ObjectId))
+
+/** This macro returns a Configuration Manager Object ID
+ in the ARM Object Namespace.
+
+ @param [in] ObjectId The Object ID.
+
+ @retval Returns an ARM Configuration Manager Object ID.
+**/
+#define CREATE_CM_ARM_OBJECT_ID(ObjectId) \
+ (CREATE_CM_OBJECT_ID (EObjNameSpaceArm, ObjectId))
+
+/** This macro returns a Configuration Manager Object ID
+ in the OEM Object Namespace.
+
+ @param [in] ObjectId The Object ID.
+
+ @retval Returns an OEM Configuration Manager Object ID.
+**/
+#define CREATE_CM_OEM_OBJECT_ID(ObjectId) \
+ (CREATE_CM_OBJECT_ID (EObjNameSpaceOem, ObjectId))
+
+#endif // CONFIGURATION_MANAGER_OBJECT_H_
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 09/22] DynamicTablesPkg: Configuration Manager Protocol
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (7 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 08/22] DynamicTablesPkg: Configuration Manager Objects Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 10/22] DynamicTablesPkg: Configuration Manager Helper Sami Mujawar
` (12 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
Introduce configuration manager protocol interface
that is used by the dynamic tables framework core
to communicate with configuration manager.
Configuration manager is a platform specific module
that implements the configuration manager protocol.
Table generators use this interface to retrieve the
hardware information from the configuration manager.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTablesPkg.dec | 5 +
DynamicTablesPkg/Include/Protocol/ConfigurationManagerProtocol.h | 128 ++++++++++++++++++++
2 files changed, 133 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec b/DynamicTablesPkg/DynamicTablesPkg.dec
index b1a6c64948d01426fc95b8599fc17adaa8c35f3d..e5e731085a721f5f2a0129b4678dedbb0c7b985a 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dec
+++ b/DynamicTablesPkg/DynamicTablesPkg.dec
@@ -22,3 +22,8 @@ [Defines]
[Includes]
Include
+[Protocols]
+
+ # Configuration Manager Protocol GUID
+ gEdkiiConfigurationManagerProtocolGuid = { 0xd85a4835, 0x5a82, 0x4894, { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } }
+
diff --git a/DynamicTablesPkg/Include/Protocol/ConfigurationManagerProtocol.h b/DynamicTablesPkg/Include/Protocol/ConfigurationManagerProtocol.h
new file mode 100644
index 0000000000000000000000000000000000000000..02c3d22ca7e961058c2c157e7f5a981e1418535e
--- /dev/null
+++ b/DynamicTablesPkg/Include/Protocol/ConfigurationManagerProtocol.h
@@ -0,0 +1,128 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef CONFIGURATION_MANAGER_PROTOCOL_H_
+#define CONFIGURATION_MANAGER_PROTOCOL_H_
+
+#include <ConfigurationManagerObject.h>
+
+/** This macro defines the Configuration Manager Protocol GUID.
+
+ GUID: {D85A4835-5A82-4894-AC02-706F43D5978E}
+*/
+#define EDKII_CONFIGURATION_MANAGER_PROTOCOL_GUID \
+ { 0xd85a4835, 0x5a82, 0x4894, \
+ { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } \
+ };
+
+/** This macro defines the Configuration Manager Protocol Revision.
+*/
+#define EDKII_CONFIGURATION_MANAGER_PROTOCOL_REVISION CREATE_REVISION (1, 0)
+
+#pragma pack(1)
+
+/**
+ Forward declarations:
+*/
+typedef struct ConfigurationManagerProtocol EDKII_CONFIGURATION_MANAGER_PROTOCOL;
+typedef struct PlatformRepositoryInfo EDKII_PLATFORM_REPOSITORY_INFO;
+
+/** The GetObject function defines the interface implemented by the
+ Configuration Manager Protocol for returning the Configuration
+ Manager Objects.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the requested Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration Manager
+ is less than the Object size for the requested
+ object.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_CONFIGURATION_MANAGER_GET_OBJECT) (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
+ IN OUT CM_OBJ_DESCRIPTOR * CONST CmObject
+ );
+
+/** The SetObject function defines the interface implemented by the
+ Configuration Manager Protocol for updating the Configuration
+ Manager Objects.
+
+ @param [in] This Pointer to the Configuration Manager Protocol.
+ @param [in] CmObjectId The Configuration Manager Object ID.
+ @param [in] Token An optional token identifying the object. If
+ unused this must be CM_NULL_TOKEN.
+ @param [out] CmObject Pointer to the Configuration Manager Object
+ descriptor describing the Object.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration Manager
+ is less than the Object size for the requested
+ object.
+ @retval EFI_UNSUPPORTED This operation is not supported.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_CONFIGURATION_MANAGER_SET_OBJECT) (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST This,
+ IN CONST CM_OBJECT_ID CmObjectId,
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
+ IN CM_OBJ_DESCRIPTOR * CONST CmObject
+ );
+
+/** The EDKII_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.
+ */
+ EDKII_CONFIGURATION_MANAGER_GET_OBJECT GetObject;
+
+ /** The interface used to update the information stored
+ in the Configuration Manager repository.
+ */
+ EDKII_CONFIGURATION_MANAGER_SET_OBJECT SetObject;
+
+ /** Pointer to an implementation defined abstract repository
+ provisioned by the Configuration Manager.
+ */
+ EDKII_PLATFORM_REPOSITORY_INFO * PlatRepoInfo;
+} EDKII_CONFIGURATION_MANAGER_PROTOCOL;
+
+/** The Configuration Manager Protocol GUID.
+*/
+extern EFI_GUID gEdkiiConfigurationManagerProtocolGuid;
+
+#pragma pack()
+
+#endif // CONFIGURATION_MANAGER_PROTOCOL_H_
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 10/22] DynamicTablesPkg: Configuration Manager Helper
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (8 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 09/22] DynamicTablesPkg: Configuration Manager Protocol Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 11/22] DynamicTablesPkg: Table Helper Library Sami Mujawar
` (11 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
This patch defines a helper macro 'GET_OBJECT_LIST()' that
expands to a function that uses the configuration manager
protocol to retrieve configuration manager object(s).
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Include/ConfigurationManagerHelper.h | 119 ++++++++++++++++++++
1 file changed, 119 insertions(+)
diff --git a/DynamicTablesPkg/Include/ConfigurationManagerHelper.h b/DynamicTablesPkg/Include/ConfigurationManagerHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..0630afc5ad755a613c273bfd02cf53fefcedccc5
--- /dev/null
+++ b/DynamicTablesPkg/Include/ConfigurationManagerHelper.h
@@ -0,0 +1,119 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+**/
+
+#ifndef CONFIGURATION_MANAGER_HELPER_H_
+#define CONFIGURATION_MANAGER_HELPER_H_
+
+/** The GET_OBJECT_LIST macro expands to a function that is used to retrieve
+ an object or an object list from the Configuration Manager using the
+ Configuration Manager Protocol interface.
+
+ The macro expands to a function which has the following prototype:
+
+ STATIC
+ EFI_STATUS
+ EFIAPI
+ Get<CmObjectId> (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL,
+ OUT Type ** List,
+ OUT UINT32 * Count OPTIONAL
+ );
+
+ Generated function parameters:
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager protocol
+ interface.
+ @param [in] Token Reference token for the Object.
+ @param [out] List Pointer to the Object list.
+ @param [out] Count Count of the objects returned in the list.
+
+ Macro Parameters:
+ @param [in] CmObjectNameSpace The Object Namespace
+ @param [in] CmObjectId Object Id.
+ @param [in] Type Structure used to describe the Object.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+#define GET_OBJECT_LIST(CmObjectNameSpace, CmObjectId, Type) \
+STATIC \
+EFI_STATUS \
+EFIAPI \
+Get##CmObjectId ( \
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol, \
+ IN CONST CM_OBJECT_TOKEN Token OPTIONAL, \
+ OUT Type ** List, \
+ OUT UINT32 * CONST Count OPTIONAL \
+ ) \
+{ \
+ EFI_STATUS Status; \
+ CM_OBJ_DESCRIPTOR CmObjectDesc; \
+ UINT32 ObjCount = 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 \
+ ), \
+ Token, \
+ &CmObjectDesc \
+ ); \
+ if (EFI_ERROR (Status)) { \
+ DEBUG (( \
+ DEBUG_INFO, \
+ "INFO: 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_
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 11/22] DynamicTablesPkg: Table Helper Library
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (9 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 10/22] DynamicTablesPkg: Configuration Manager Helper Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 12/22] DynamicTablesPkg: Dynamic Table Factory Protocol Sami Mujawar
` (10 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
A helper library that implements common functionality
for use by table generators.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 20 +++
DynamicTablesPkg/Include/Library/TableHelperLib.h | 66 ++++++++
DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c | 164 ++++++++++++++++++++
DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf | 36 +++++
4 files changed, 286 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
new file mode 100644
index 0000000000000000000000000000000000000000..1cac3e649afebb06190fb5bf6387857437706404
--- /dev/null
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -0,0 +1,20 @@
+## @file
+# Dsc include file for Dynamic Tables Framework.
+#
+# Copyright (c) 2017 - 2018, 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
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+
+[LibraryClasses.common]
+ TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
+
diff --git a/DynamicTablesPkg/Include/Library/TableHelperLib.h b/DynamicTablesPkg/Include/Library/TableHelperLib.h
new file mode 100644
index 0000000000000000000000000000000000000000..f17a0b23ddfc0aea39b08acd2c874dbfe8a0749d
--- /dev/null
+++ b/DynamicTablesPkg/Include/Library/TableHelperLib.h
@@ -0,0 +1,66 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef TABLE_HELPER_LIB_H_
+#define TABLE_HELPER_LIB_H_
+
+/** 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 EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT CM_STD_OBJ_CONFIGURATION_MANAGER_INFO ** CfgMfrInfo
+ );
+
+/** The AddAcpiHeader function updates the ACPI header structure. It uses the
+ ACPI table Generator and the Configuration Manager protocol to obtain the
+ information required for constructing the header.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ protocol interface.
+ @param [in] Generator Pointer to the ACPI table Generator.
+ @param [in,out] AcpiHeader Pointer to the ACPI table header to be
+ updated.
+ @param [in] Length Length of the ACPI table.
+
+ @retval EFI_SUCCESS The ACPI table is updated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object information is not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+EFI_STATUS
+EFIAPI
+AddAcpiHeader (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER * CONST AcpiHeader,
+ IN CONST UINT32 Length
+ );
+
+#endif // TABLE_HELPER_LIB_H_
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a7a44f20690d93891384024b3ac197e37a470cc
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelper.c
@@ -0,0 +1,164 @@
+/** @file
+ Table Helper
+
+Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include <Protocol/AcpiTable.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.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 EDKII_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),
+ CM_NULL_TOKEN,
+ &CmObjectDesc
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Get Configuration Manager Info. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ if (CmObjectDesc.Size < sizeof (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: EStdObjCfgMgrInfo: Buffer too small, size = 0x%x\n",
+ CmObjectDesc.Size
+ ));
+ ASSERT (
+ CmObjectDesc.Size >= sizeof (CM_STD_OBJ_CONFIGURATION_MANAGER_INFO)
+ );
+ 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 EDKII_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;
+ 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;
+
+error_handler:
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
new file mode 100644
index 0000000000000000000000000000000000000000..2568057a9e5021d9779c769e611a86da163f6d1d
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
@@ -0,0 +1,36 @@
+## @file
+# Table Helper
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[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
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[Protocols]
+
+[Guids]
+
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 12/22] DynamicTablesPkg: Dynamic Table Factory Protocol
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (10 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 11/22] DynamicTablesPkg: Table Helper Library Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 13/22] DynamicTablesPkg: Dynamic Table Factory Dxe Sami Mujawar
` (9 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
This patch introduces the dynamic table factory protocol
that provides an interface to register and retrieve
registered generators.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTablesPkg.dec | 3 +
DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h | 269 ++++++++++++++++++++
2 files changed, 272 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec b/DynamicTablesPkg/DynamicTablesPkg.dec
index e5e731085a721f5f2a0129b4678dedbb0c7b985a..3137c14247920974082bd74173cab4e7ac02b3f7 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dec
+++ b/DynamicTablesPkg/DynamicTablesPkg.dec
@@ -27,3 +27,6 @@ [Protocols]
# Configuration Manager Protocol GUID
gEdkiiConfigurationManagerProtocolGuid = { 0xd85a4835, 0x5a82, 0x4894, { 0xac, 0x2, 0x70, 0x6f, 0x43, 0xd5, 0x97, 0x8e } }
+ # Dynamic Table Factory Protocol GUID
+ gEdkiiDynamicTableFactoryProtocolGuid = { 0x91d1e327, 0xfe5a, 0x49b8, { 0xab, 0x65, 0xe, 0xce, 0x2d, 0xdb, 0x45, 0xec } }
+
diff --git a/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h b/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h
new file mode 100644
index 0000000000000000000000000000000000000000..55d62c9e7244c1cca35aaa6c7e3b1dbf9125c3b5
--- /dev/null
+++ b/DynamicTablesPkg/Include/Protocol/DynamicTableFactoryProtocol.h
@@ -0,0 +1,269 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - ACPI - Advanced Configuration and Power Interface
+ - SMBIOS - System Management BIOS
+ - DT - Device Tree
+**/
+
+#ifndef DYNAMIC_TABLE_FACTORY_PROTOCOL_H_
+#define DYNAMIC_TABLE_FACTORY_PROTOCOL_H_
+
+#include <AcpiTableGenerator.h>
+#include <SmbiosTableGenerator.h>
+#include <DeviceTreeTableGenerator.h>
+
+/** This macro defines the Dynamic Table Factory Protocol GUID.
+
+ GUID: {91D1E327-FE5A-49B8-AB65-0ECE2DDB45EC}
+*/
+#define EDKII_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 EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL_REVISION CREATE_REVISION (1, 0)
+
+#pragma pack(1)
+
+/**
+ Forward declarations:
+*/
+typedef struct DynamicTableFactoryProtocol EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL;
+typedef struct DynamicTableFactoryInfo EDKII_DYNAMIC_TABLE_FACTORY_INFO;
+
+/** Return a pointer to the ACPI table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] TableId The ACPI table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested ACPI table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+typedef
+EFI_STATUS
+EFIAPI
+(EFIAPI * EDKII_DYNAMIC_TABLE_FACTORY_GET_ACPI_TABLE_GENERATOR) (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST ACPI_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST ACPI_TABLE_GENERATOR ** CONST Generator
+ );
+
+/** Registers an ACPI table generator.
+
+ @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.
+**/
+typedef
+EFI_STATUS
+EFIAPI
+(EFIAPI * EDKII_DYNAMIC_TABLE_FACTORY_REGISTER_ACPI_TABLE_GENERATOR) (
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator
+ );
+
+/** Deregister an ACPI table generator.
+
+ @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.
+**/
+typedef
+EFI_STATUS
+EFIAPI
+(EFIAPI * EDKII_DYNAMIC_TABLE_FACTORY_DEREGISTER_ACPI_TABLE_GENERATOR) (
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator
+ );
+
+/** Return a pointer to the SMBIOS table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] TableId The SMBIOS table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested SMBIOS table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+typedef
+EFI_STATUS
+EFIAPI
+(EFIAPI * EDKII_DYNAMIC_TABLE_FACTORY_GET_SMBIOS_TABLE_GENERATOR) (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST SMBIOS_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST SMBIOS_TABLE_GENERATOR ** CONST Generator
+ );
+
+/** Register a SMBIOS table generator.
+
+ @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.
+**/
+typedef
+EFI_STATUS
+EFIAPI
+(EFIAPI * EDKII_DYNAMIC_TABLE_FACTORY_REGISTER_SMBIOS_TABLE_GENERATOR) (
+ IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator
+ );
+
+/** Deregister a SMBIOS table generator.
+
+ @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.
+**/
+typedef
+EFI_STATUS
+EFIAPI
+(EFIAPI * EDKII_DYNAMIC_TABLE_FACTORY_DEREGISTER_SMBIOS_TABLE_GENERATOR) (
+ IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator
+ );
+
+/** Return a pointer to the Device Tree table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] TableId The Device Tree table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested Device Tree table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+typedef
+EFI_STATUS
+EFIAPI
+(EFIAPI * EDKII_DYNAMIC_TABLE_FACTORY_GET_DT_TABLE_GENERATOR) (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST DT_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST DT_TABLE_GENERATOR ** CONST Generator
+ );
+
+/** Register a DT table generator.
+
+ @param [in] Generator Pointer to the DT table generator.
+
+ @retval EFI_SUCCESS The Generator was registered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The Generator ID is invalid or
+ the Generator pointer is NULL.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID is
+ already registered.
+**/
+typedef
+EFI_STATUS
+EFIAPI
+(EFIAPI * EDKII_DYNAMIC_TABLE_FACTORY_REGISTER_DT_TABLE_GENERATOR) (
+ IN CONST DT_TABLE_GENERATOR * CONST Generator
+ );
+
+/** Deregister a DT table generator.
+
+ This function is called by the DT table generator to deregister itself
+ from the DT table factory.
+
+ @param [in] Generator Pointer to the DT table generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER The generator is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+typedef
+EFI_STATUS
+EFIAPI
+(EFIAPI * EDKII_DYNAMIC_TABLE_FACTORY_DEREGISTER_DT_TABLE_GENERATOR) (
+ IN CONST DT_TABLE_GENERATOR * CONST Generator
+ );
+
+/** A structure describing the Dynamic Table Factory Protocol interface.
+*/
+typedef struct DynamicTableFactoryProtocol {
+ /// The Dynamic Table Factory Protocol revision.
+ UINT32 Revision;
+
+ /// The interface used to request an ACPI Table Generator.
+ EDKII_DYNAMIC_TABLE_FACTORY_GET_ACPI_TABLE_GENERATOR GetAcpiTableGenerator;
+
+ /// Register an ACPI table Generator
+ EDKII_DYNAMIC_TABLE_FACTORY_REGISTER_ACPI_TABLE_GENERATOR
+ RegisterAcpiTableGenerator;
+
+ /// Deregister an ACPI table Generator
+ EDKII_DYNAMIC_TABLE_FACTORY_DEREGISTER_ACPI_TABLE_GENERATOR
+ DeregisterAcpiTableGenerator;
+
+ /// The interface used to request a SMBIOS Table Generator.
+ EDKII_DYNAMIC_TABLE_FACTORY_GET_SMBIOS_TABLE_GENERATOR GetSmbiosTableGenerator;
+
+ /// Register an SMBIOS table Generator
+ EDKII_DYNAMIC_TABLE_FACTORY_REGISTER_SMBIOS_TABLE_GENERATOR
+ RegisterSmbiosTableGenerator;
+
+ /// Deregister an SMBIOS table Generator
+ EDKII_DYNAMIC_TABLE_FACTORY_REGISTER_SMBIOS_TABLE_GENERATOR
+ DeregisterSmbiosTableGenerator;
+
+ /// The interface used to request a Device Tree Table Generator.
+ EDKII_DYNAMIC_TABLE_FACTORY_GET_DT_TABLE_GENERATOR GetDtTableGenerator;
+
+ /// Register a DT generator
+ EDKII_DYNAMIC_TABLE_FACTORY_REGISTER_DT_TABLE_GENERATOR
+ RegisterDtTableGenerator;
+
+ /// Deregister a DT generator
+ EDKII_DYNAMIC_TABLE_FACTORY_DEREGISTER_DT_TABLE_GENERATOR
+ DeregisterDtTableGenerator;
+
+ /** Pointer to the data structure that holds the
+ list of registered table generators
+ */
+ EDKII_DYNAMIC_TABLE_FACTORY_INFO * TableFactoryInfo;
+} EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL;
+
+/** The Dynamic Table Factory Protocol GUID.
+*/
+extern EFI_GUID gEdkiiDynamicTableFactoryProtocolGuid;
+
+#pragma pack()
+
+#endif // DYNAMIC_TABLE_FACTORY_PROTOCOL_H_
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 13/22] DynamicTablesPkg: Dynamic Table Factory Dxe
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (11 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 12/22] DynamicTablesPkg: Dynamic Table Factory Protocol Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 14/22] DynamicTablesPkg: Dynamic Table Manager Dxe Sami Mujawar
` (8 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The dynamic table factory dxe implements the dynamic table
factory protocol. It also implements the ACPI, SMBIOS and
DT table factories. The table generators register themselves
with the respective table factories and the factories are
responsible for instantiating instances of the generators
to build the firmware tables.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c | 226 ++++++++++++++++++++
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFactory/DeviceTreeTableFactory.c | 225 +++++++++++++++++++
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h | 125 +++++++++++
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c | 90 ++++++++
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf | 60 ++++++
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c | 226 ++++++++++++++++++++
DynamicTablesPkg/DynamicTables.dsc.inc | 6 +
DynamicTablesPkg/{DynamicTables.dsc.inc => DynamicTables.fdf.inc} | 10 +-
DynamicTablesPkg/DynamicTablesPkg.dec | 11 +
9 files changed, 974 insertions(+), 5 deletions(-)
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c
new file mode 100644
index 0000000000000000000000000000000000000000..f60d9f495150e1a2876eb1fa519ac6b6d16a421b
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/AcpiTableFactory/AcpiTableFactory.c
@@ -0,0 +1,226 @@
+/** @file
+ ACPI Table Factory
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Std - Standard
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+
+#include "DynamicTableFactory.h"
+
+extern EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;
+
+/** Return a pointer to the ACPI table generator.
+
+ @param [in] This Pointer 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 EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST ACPI_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST ACPI_TABLE_GENERATOR ** CONST Generator
+ )
+{
+ UINT16 TableId;
+ EDKII_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;
+}
+
+/** Deregister ACPI generator.
+
+ This function is called by the ACPI table generator to deregister 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
+DeregisterAcpiTableGenerator (
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: ACPI deregister - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_ACPI (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: ACPI deregister - Generator" \
+ " Type is not ACPI\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TableId = 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, "Deregistering %s\n", Generator->Description));
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFactory/DeviceTreeTableFactory.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFactory/DeviceTreeTableFactory.c
new file mode 100644
index 0000000000000000000000000000000000000000..5727a26fc99a79fcb43dc2ce951a33fcb87b1546
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DeviceTreeTableFactory/DeviceTreeTableFactory.c
@@ -0,0 +1,225 @@
+/** @file
+ Device Tree Table Factory
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Std - Standard
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+// Module specific include files.
+#include <DeviceTreeTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+
+#include "DynamicTableFactory.h"
+
+extern EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;
+
+/** Return a pointer to the DT table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] GeneratorId The DT table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested DT table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+GetDtTableGenerator (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST DT_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST DT_TABLE_GENERATOR ** CONST Generator
+ )
+{
+ UINT16 TableId;
+ EDKII_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_DT (GeneratorId)) {
+ DEBUG ((DEBUG_ERROR, "ERROR: Generator Type is not DT\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Generator = NULL;
+ TableId = GET_TABLE_ID (GeneratorId);
+ if (IS_GENERATOR_NAMESPACE_STD (GeneratorId)) {
+ if (TableId >= (ESTD_DT_TABLE_ID_MAX)) {
+ ASSERT (TableId < (ESTD_DT_TABLE_ID_MAX));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (FactoryInfo->StdDtTableGeneratorList[TableId] != NULL) {
+ *Generator = FactoryInfo->StdDtTableGeneratorList[TableId];
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomDTGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomDTGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (FactoryInfo->CustomDtTableGeneratorList[TableId] != NULL) {
+ *Generator = FactoryInfo->CustomDtTableGeneratorList[TableId];
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/** Register DT table factory generator.
+
+ The DT table factory maintains a list of the Standard and OEM DT
+ table generators.
+
+ @param [in] Generator Pointer to the DT table generator.
+
+ @retval EFI_SUCCESS The Generator was registered
+ successfully.
+ @retval EFI_INVALID_PARAMETER The Generator ID is invalid or
+ the Generator pointer is NULL.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID is
+ already registered.
+**/
+EFI_STATUS
+EFIAPI
+RegisterDtTableGenerator (
+ IN CONST DT_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: DT register - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_DT (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: DT register - Generator" \
+ " Type is not DT\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DEBUG ((DEBUG_INFO, "Registering %s\n", Generator->Description));
+
+ TableId = GET_TABLE_ID (Generator->GeneratorID);
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {
+ if (TableId >= (ESTD_DT_TABLE_ID_MAX)) {
+ ASSERT (TableId < (ESTD_DT_TABLE_ID_MAX));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.StdDtTableGeneratorList[TableId] == NULL) {
+ TableFactoryInfo.StdDtTableGeneratorList[TableId] = Generator;
+ } else {
+ return EFI_ALREADY_STARTED;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomDTGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomDTGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.CustomDtTableGeneratorList[TableId] == NULL) {
+ TableFactoryInfo.CustomDtTableGeneratorList[TableId] = Generator;
+ } else {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/** Deregister DT generator.
+
+ This function is called by the DT table generator to deregister itself
+ from the DT table factory.
+
+ @param [in] Generator Pointer to the DT table generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER The generator is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+DeregisterDtTableGenerator (
+ IN CONST DT_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: DT deregister - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_DT (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: DT deregister - Generator" \
+ " Type is not DT\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TableId = GET_TABLE_ID (Generator->GeneratorID);
+ if (IS_GENERATOR_NAMESPACE_STD (Generator->GeneratorID)) {
+ if (TableId >= (ESTD_DT_TABLE_ID_MAX)) {
+ ASSERT (TableId < (ESTD_DT_TABLE_ID_MAX));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.StdDtTableGeneratorList[TableId] != NULL) {
+ if (Generator != TableFactoryInfo.StdDtTableGeneratorList[TableId]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ TableFactoryInfo.StdDtTableGeneratorList[TableId] = NULL;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ if (TableId > FixedPcdGet16 (PcdMaxCustomDTGenerators)) {
+ ASSERT (TableId <= FixedPcdGet16 (PcdMaxCustomDTGenerators));
+ return EFI_INVALID_PARAMETER;
+ }
+ if (TableFactoryInfo.CustomDtTableGeneratorList[TableId] != NULL) {
+ if (Generator !=
+ TableFactoryInfo.CustomDtTableGeneratorList[TableId]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ TableFactoryInfo.CustomDtTableGeneratorList[TableId] = NULL;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ DEBUG ((DEBUG_INFO, "Deregistering %s\n", Generator->Description));
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h
new file mode 100644
index 0000000000000000000000000000000000000000..cc2dd0edbed1b45defe920f8d35535deb1ba78fd
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactory.h
@@ -0,0 +1,125 @@
+/** @file
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Std - Standard
+ - ACPI - Advanced Configuration and Power Interface
+ - SMBIOS - System Management BIOS
+ - DT - Device Tree
+**/
+
+#ifndef DYNAMIC_TABLE_FACTORY_H_
+#define DYNAMIC_TABLE_FACTORY_H_
+
+#pragma pack(1)
+
+/** A structure that holds the list of registered ACPI and
+ SMBIOS table generators.
+*/
+typedef struct DynamicTableFactoryInfo {
+ /// An array for holding the list of Standard ACPI Table Generators.
+ CONST ACPI_TABLE_GENERATOR *
+ StdAcpiTableGeneratorList[ESTD_ACPI_TABLE_ID_MAX];
+
+ /// An array for holding the list of Custom ACPI Table Generators.
+ CONST ACPI_TABLE_GENERATOR *
+ CustomAcpiTableGeneratorList[FixedPcdGet16 (
+ PcdMaxCustomACPIGenerators
+ )];
+
+ /// An array for holding the list of Standard SMBIOS Table Generators.
+ CONST SMBIOS_TABLE_GENERATOR *
+ StdSmbiosTableGeneratorList[ESTD_SMBIOS_TABLE_ID_MAX];
+
+ /// An array for holding the list of Custom SMBIOS Table Generators.
+ CONST SMBIOS_TABLE_GENERATOR *
+ CustomSmbiosTableGeneratorList[FixedPcdGet16 (
+ PcdMaxCustomSMBIOSGenerators
+ )];
+
+ /// An array for holding the list of Standard DT Table Generators.
+ CONST DT_TABLE_GENERATOR *
+ StdDtTableGeneratorList[ESTD_DT_TABLE_ID_MAX];
+
+ /// An array for holding the list of Custom DT Table Generators.
+ CONST DT_TABLE_GENERATOR *
+ CustomDtTableGeneratorList[FixedPcdGet16 (
+ PcdMaxCustomDTGenerators
+ )];
+} EDKII_DYNAMIC_TABLE_FACTORY_INFO;
+
+/** Return a pointer to the ACPI table generator.
+
+ @param [in] This Pointer 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 EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST ACPI_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST ACPI_TABLE_GENERATOR ** CONST Generator
+ );
+
+/** Return a pointer to the SMBIOS table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] 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 EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST SMBIOS_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST SMBIOS_TABLE_GENERATOR ** CONST Generator
+ );
+
+/** Return a pointer to the DT table generator.
+
+ @param [in] This Pointer to the Dynamic Table Factory Protocol.
+ @param [in] GeneratorId The DT table generator ID for the
+ requested generator.
+ @param [out] Generator Pointer to the requested DT table
+ generator.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The requested generator is not found
+ in the list of registered generators.
+**/
+EFI_STATUS
+EFIAPI
+GetDtTableGenerator (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST DT_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST DT_TABLE_GENERATOR ** CONST Generator
+ );
+
+#pragma pack()
+
+#endif // DYNAMIC_TABLE_FACTORY_H_
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c
new file mode 100644
index 0000000000000000000000000000000000000000..4915d379e88bdb9e0fb023d7ad8fb8dd73870f04
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.c
@@ -0,0 +1,90 @@
+/** @file
+ Dynamic Table Factory Dxe
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <DeviceTreeTableGenerator.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+#include <SmbiosTableGenerator.h>
+
+#include "DynamicTableFactory.h"
+
+/** The Dynamic Table Factory protocol structure that holds the
+ list of registered ACPI and SMBIOS table generators.
+*/
+EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;
+
+/** A structure describing the Dynamic Table Factory protocol.
+*/
+STATIC
+CONST
+EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL DynamicTableFactoryProtocol = {
+ CREATE_REVISION (1, 0),
+ GetAcpiTableGenerator,
+ RegisterAcpiTableGenerator,
+ DeregisterAcpiTableGenerator,
+ GetSmbiosTableGenerator,
+ RegisterSmbiosTableGenerator,
+ DeregisterSmbiosTableGenerator,
+ GetDtTableGenerator,
+ RegisterDtTableGenerator,
+ DeregisterDtTableGenerator,
+ &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,
+ &gEdkiiDynamicTableFactoryProtocolGuid,
+ 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/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
new file mode 100644
index 0000000000000000000000000000000000000000..740811d0fc0590543a62360e6753eb04fb675d70
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
@@ -0,0 +1,60 @@
+## @file
+# Module to manage the list of available table factories.
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[Defines]
+ INF_VERSION = 0x00010019
+ 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]
+ AcpiTableFactory/AcpiTableFactory.c
+ DeviceTreeTableFactory/DeviceTreeTableFactory.c
+ DynamicTableFactoryDxe.c
+ SmbiosTableFactory/SmbiosTableFactory.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ PrintLib
+ TableHelperLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[FixedPcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomACPIGenerators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomSMBIOSGenerators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomDTGenerators
+
+[Protocols]
+ gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiSmbiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEdkiiConfigurationManagerProtocolGuid
+ gEdkiiDynamicTableFactoryProtocolGuid
+
+[Depex]
+ TRUE
diff --git a/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c
new file mode 100644
index 0000000000000000000000000000000000000000..f37e9deb627f905107a4af093a16fe2bbe50d51e
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/SmbiosTableFactory/SmbiosTableFactory.c
@@ -0,0 +1,226 @@
+/** @file
+ SMBIOS Table Factory
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Std - Standard
+**/
+
+#include <IndustryStandard/SmBios.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+// Module specific include files.
+#include <SmbiosTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+
+#include "DynamicTableFactory.h"
+
+extern EDKII_DYNAMIC_TABLE_FACTORY_INFO TableFactoryInfo;
+
+/** Return a pointer to the SMBIOS table generator.
+
+ @param [in] This Pointer 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 EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST This,
+ IN CONST SMBIOS_TABLE_GENERATOR_ID GeneratorId,
+ OUT CONST SMBIOS_TABLE_GENERATOR ** CONST Generator
+ )
+{
+ UINT16 TableId;
+ EDKII_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;
+}
+
+/** Deregister SMBIOS generator.
+
+ This function is called by the SMBIOS table generator to deregister 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
+DeregisterSmbiosTableGenerator (
+ IN CONST SMBIOS_TABLE_GENERATOR * CONST Generator
+ )
+{
+ UINT16 TableId;
+
+ if (Generator == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR: SMBIOS deregister - Invalid Generator\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IS_GENERATOR_TYPE_SMBIOS (Generator->GeneratorID)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SMBIOS deregister - Generator" \
+ " Type is not SMBIOS\n"
+ ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TableId = 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, "Deregistering %s\n", Generator->Description));
+ return EFI_SUCCESS;
+}
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 1cac3e649afebb06190fb5bf6387857437706404..9803b345c6660ad9d5c6b2e0617e856c10069a32 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -18,3 +18,9 @@ [Defines]
[LibraryClasses.common]
TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
+[Components.common]
+ #
+ # Dynamic Table Factory Dxe
+ #
+ DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
+
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.fdf.inc
similarity index 73%
copy from DynamicTablesPkg/DynamicTables.dsc.inc
copy to DynamicTablesPkg/DynamicTables.fdf.inc
index 1cac3e649afebb06190fb5bf6387857437706404..4123c6a8b751b2454c8890a75e925a7c9af97afc 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.fdf.inc
@@ -1,5 +1,5 @@
## @file
-# Dsc include file for Dynamic Tables Framework.
+# fdf include file for Dynamic Tables Framework.
#
# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.<BR>
#
@@ -13,8 +13,8 @@
#
##
-[Defines]
-
-[LibraryClasses.common]
- TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
+ #
+ # Dynamic Table Factory Dxe
+ #
+ INF DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
diff --git a/DynamicTablesPkg/DynamicTablesPkg.dec b/DynamicTablesPkg/DynamicTablesPkg.dec
index 3137c14247920974082bd74173cab4e7ac02b3f7..21e904ce1e250477be899b506bce72d12087ed74 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.dec
+++ b/DynamicTablesPkg/DynamicTablesPkg.dec
@@ -30,3 +30,14 @@ [Protocols]
# Dynamic Table Factory Protocol GUID
gEdkiiDynamicTableFactoryProtocolGuid = { 0x91d1e327, 0xfe5a, 0x49b8, { 0xab, 0x65, 0xe, 0xce, 0x2d, 0xdb, 0x45, 0xec } }
+[PcdsFixedAtBuild]
+
+ # Maximum number of Custom ACPI Generators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomACPIGenerators|1|UINT16|0xC0000001
+
+ # Maximum number of Custom SMBIOS Generators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomSMBIOSGenerators|1|UINT16|0xC0000002
+
+ # Maximum number of Custom DT Generators
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxCustomDTGenerators|1|UINT16|0xC0000003
+
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 14/22] DynamicTablesPkg: Dynamic Table Manager Dxe
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (12 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 13/22] DynamicTablesPkg: Dynamic Table Factory Dxe Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 15/22] DynamicTablesPkg: Arm Raw/DSDT/SSDT Generator Sami Mujawar
` (7 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The dynamic table manager implements the top level component
that drives the table generation and installation process.
It uses the configuration manager protocol to get the list
of tables to be installed from the configuration manager.
It iterates through the list of tables, requests the table
factories for corresponding generators and invokes the
generator interface to build the tables.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c | 735 ++++++++++++++++++++
DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf | 50 ++
DynamicTablesPkg/DynamicTables.dsc.inc | 4 +
DynamicTablesPkg/DynamicTables.fdf.inc | 4 +
4 files changed, 793 insertions(+)
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
new file mode 100644
index 0000000000000000000000000000000000000000..090f102fae0d45040ae2a60003dc84bab1271416
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
@@ -0,0 +1,735 @@
+/** @file
+ Dynamic Table Manager Dxe
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <DeviceTreeTableGenerator.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include <Protocol/DynamicTableFactoryProtocol.h>
+#include <SmbiosTableGenerator.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 build and install a single ACPI table.
+
+ 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] Generator Pointer to the AcpiTable generator.
+ @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
+BuildAndInstallSingleAcpiTable (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator,
+ IN EFI_ACPI_TABLE_PROTOCOL * AcpiTableProtocol,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ EFI_ACPI_DESCRIPTION_HEADER * AcpiTable;
+ UINTN TableHandle;
+
+ 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 exit_handler;
+ }
+
+ if (AcpiTable == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto exit_handler;
+ }
+
+ // 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 exit_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: ACPI Table installed. Status = %r\n",
+ Status
+ ));
+
+exit_handler:
+ // Free any resources allocated for generating the tables.
+ if (Generator->FreeTableResources != NULL) {
+ Status1 = Generator->FreeTableResources (
+ Generator,
+ AcpiTableInfo,
+ CfgMgrProtocol,
+ &AcpiTable
+ );
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Free Table Resources." \
+ "TableGeneratorId = 0x%x. Status = %r\n",
+ AcpiTableInfo->TableGeneratorId,
+ Status1
+ ));
+ }
+
+ // Return the first error status in case of failure
+ if (!EFI_ERROR (Status)) {
+ Status = Status1;
+ }
+ }
+ return Status;
+}
+
+/** A helper function to build and install multiple ACPI tables.
+
+ 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] Generator Pointer to the AcpiTable generator.
+ @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
+BuildAndInstallMultipleAcpiTable (
+ IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST ACPI_TABLE_GENERATOR * CONST Generator,
+ IN EFI_ACPI_TABLE_PROTOCOL * AcpiTableProtocol,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ EFI_ACPI_DESCRIPTION_HEADER ** AcpiTable;
+ UINTN TableCount;
+ UINTN TableHandle;
+ UINTN Index;
+
+ AcpiTable = NULL;
+ TableCount = 0;
+ Status = Generator->BuildAcpiTableEx (
+ Generator,
+ AcpiTableInfo,
+ CfgMgrProtocol,
+ &AcpiTable,
+ &TableCount
+ );
+ 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 exit_handler;
+ }
+
+ if ((AcpiTable == NULL) || (TableCount == 0)) {
+ Status = EFI_NOT_FOUND;
+ goto exit_handler;
+ }
+
+ for (Index = 0; Index < TableCount; Index++) {
+ // Dump ACPI Table Header
+ DUMP_ACPI_TABLE_HEADER (AcpiTable[Index]);
+ // Install ACPI table
+ Status = AcpiTableProtocol->InstallAcpiTable (
+ AcpiTableProtocol,
+ AcpiTable[Index],
+ AcpiTable[Index]->Length,
+ &TableHandle
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Install ACPI Table. Status = %r\n",
+ Status
+ ));
+ // Free any allocated resources.
+ goto exit_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: ACPI Table installed. Status = %r\n",
+ Status
+ ));
+ }
+
+exit_handler:
+ // Free any resources allocated for generating the tables.
+ if (Generator->FreeTableResourcesEx != NULL) {
+ Status1 = Generator->FreeTableResourcesEx (
+ Generator,
+ AcpiTableInfo,
+ CfgMgrProtocol,
+ &AcpiTable,
+ TableCount
+ );
+ if (EFI_ERROR (Status1)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to Free Table Resources." \
+ "TableGeneratorId = 0x%x. Status = %r\n",
+ AcpiTableInfo->TableGeneratorId,
+ Status1
+ ));
+ }
+
+ // Return the first error status in case of failure
+ if (!EFI_ERROR (Status)) {
+ Status = Status1;
+ }
+ }
+ return Status;
+}
+
+/** 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 EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol,
+ IN CONST EDKII_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;
+
+ 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
+ ));
+
+ Generator = NULL;
+ 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;
+ }
+
+ if (Generator == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: Generator found : %s\n",
+ Generator->Description
+ ));
+
+ if (Generator->BuildAcpiTableEx != NULL) {
+ Status = BuildAndInstallMultipleAcpiTable (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ Generator,
+ AcpiTableProtocol,
+ AcpiTableInfo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find build and install ACPI Table." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+ } else if (Generator->BuildAcpiTable != NULL) {
+ Status = BuildAndInstallSingleAcpiTable (
+ TableFactoryProtocol,
+ CfgMgrProtocol,
+ Generator,
+ AcpiTableProtocol,
+ AcpiTableInfo
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: Failed to find build and install ACPI Table." \
+ " Status = %r\n",
+ Status
+ ));
+ }
+ } else {
+ 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;
+}
+
+/** The function checks if the Configuration Manager has provided the
+ mandatory ACPI tables for installation.
+
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info list.
+ @param [in] AcpiTableCount Count of ACPI Table Info.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_NOT_FOUND If mandatory table is not found.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+VerifyMandatoryTablesArePresent (
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN UINT32 AcpiTableCount
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN FadtFound;
+ BOOLEAN MadtFound;
+ BOOLEAN GtdtFound;
+ BOOLEAN DsdtFound;
+ BOOLEAN Dbg2Found;
+ BOOLEAN SpcrFound;
+
+ Status = EFI_SUCCESS;
+ FadtFound = FALSE;
+ MadtFound = FALSE;
+ GtdtFound = FALSE;
+ DsdtFound = FALSE;
+ Dbg2Found = FALSE;
+ SpcrFound = FALSE;
+ ASSERT (AcpiTableInfo != NULL);
+
+ while (AcpiTableCount-- != 0) {
+ switch (AcpiTableInfo[AcpiTableCount].AcpiTableSignature) {
+ case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
+ FadtFound = TRUE;
+ break;
+ case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:
+ MadtFound = TRUE;
+ break;
+ case EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE:
+ GtdtFound = TRUE;
+ break;
+ case EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
+ DsdtFound = TRUE;
+ break;
+ case EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE:
+ Dbg2Found = TRUE;
+ break;
+ case EFI_ACPI_6_2_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 EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * CONST TableFactoryProtocol,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_TABLE_PROTOCOL * AcpiTableProtocol;
+ CM_STD_OBJ_ACPI_TABLE_INFO * AcpiTableInfo;
+ UINT32 AcpiTableCount;
+ UINT32 Idx;
+
+ ASSERT (TableFactoryProtocol != 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,
+ CM_NULL_TOKEN,
+ &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 for standard generators
+ if ((IS_GENERATOR_NAMESPACE_STD (AcpiTableInfo[Idx].TableGeneratorId)) &&
+ ((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;
+ EDKII_CONFIGURATION_MANAGER_PROTOCOL * CfgMgrProtocol;
+ CM_STD_OBJ_CONFIGURATION_MANAGER_INFO * CfgMfrInfo;
+ EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL * TableFactoryProtocol;
+
+ // Locate the Dynamic Table Factory
+ Status = gBS->LocateProtocol (
+ &gEdkiiDynamicTableFactoryProtocolGuid,
+ 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 (
+ &gEdkiiConfigurationManagerProtocolGuid,
+ 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/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
new file mode 100644
index 0000000000000000000000000000000000000000..2aeaf15b157c0172c9cb073e55d789944a73e2ec
--- /dev/null
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
@@ -0,0 +1,50 @@
+## @file
+# Module that drives the table generation and installation process.
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[Defines]
+ INF_VERSION = 0x00010019
+ 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
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ PrintLib
+ TableHelperLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEdkiiConfigurationManagerProtocolGuid
+ gEdkiiDynamicTableFactoryProtocolGuid
+
+[Depex]
+ gEdkiiConfigurationManagerProtocolGuid
+
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 9803b345c6660ad9d5c6b2e0617e856c10069a32..c419c63bc1b2a6a5efa549061837adaf4ed6e8a3 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -24,3 +24,7 @@ [Components.common]
#
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
+ #
+ # Dynamic Tables Manager Dxe
+ #
+ DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
\ No newline at end of file
diff --git a/DynamicTablesPkg/DynamicTables.fdf.inc b/DynamicTablesPkg/DynamicTables.fdf.inc
index 4123c6a8b751b2454c8890a75e925a7c9af97afc..897a7e7857a7af06f394863b953a908df5d57f15 100644
--- a/DynamicTablesPkg/DynamicTables.fdf.inc
+++ b/DynamicTablesPkg/DynamicTables.fdf.inc
@@ -18,3 +18,7 @@
#
INF DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
+ #
+ # Dynamic Tables Dxe
+ #
+ INF DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 15/22] DynamicTablesPkg: Arm Raw/DSDT/SSDT Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (13 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 14/22] DynamicTablesPkg: Dynamic Table Manager Dxe Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 16/22] DynamicTablesPkg: Arm ACPI FADT Generator Sami Mujawar
` (6 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
A Raw generator is a simple generator. This generator provides
the ability to install a binary blob (that contains ACPI table
data) as an ACPI table. The binary blob could be pre-generated
ACPI table data or it may be the pre-compiled output from an
iAsl compiler for a DSDT or SSDT table.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 8 +-
DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf | 42 ++++++
DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c | 143 ++++++++++++++++++++
3 files changed, 192 insertions(+), 1 deletion(-)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index c419c63bc1b2a6a5efa549061837adaf4ed6e8a3..9b733d39776d183122815aa850747fba8110b643 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -15,6 +15,9 @@
[Defines]
+[BuildOptions]
+ *_*_*_ASL_FLAGS = -tc -li -so
+
[LibraryClasses.common]
TableHelperLib|DynamicTablesPkg/Library/Common/TableHelperLib/TableHelperLib.inf
@@ -22,7 +25,10 @@ [Components.common]
#
# Dynamic Table Factory Dxe
#
- DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf
+ DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf {
+ <LibraryClasses>
+ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
+ }
#
# Dynamic Tables Manager Dxe
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..213dbd1cd7b69b3088afb09bdaaf1355c81d8f35
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
@@ -0,0 +1,42 @@
+## @file
+# Raw Table Generator
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[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
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[Pcd]
+
+[Protocols]
+
+[Guids]
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..5059af5bb054853fb391ff7af3c43162cfb13614
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/RawGenerator.c
@@ -0,0 +1,143 @@
+/** @file
+ MCFG Table Generator
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** Construct the ACPI table using the ACPI table data provided.
+
+ This function invokes the Configuration Manager protocol interface
+ to get the required hardware information for generating the ACPI
+ table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildRawTable (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_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;
+}
+
+/** 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,
+ // No additional resources are allocated by the generator.
+ // Hence the Free Resource function is not required.
+ NULL
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiRawLibConstructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = RegisterAcpiTableGenerator (&RawGenerator);
+ DEBUG ((DEBUG_INFO, "RAW: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiRawLibDestructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = DeregisterAcpiTableGenerator (&RawGenerator);
+ DEBUG ((DEBUG_INFO, "RAW: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 16/22] DynamicTablesPkg: Arm ACPI FADT Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (14 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 15/22] DynamicTablesPkg: Arm Raw/DSDT/SSDT Generator Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 17/22] DynamicTablesPkg: Arm ACPI MADT Generator Sami Mujawar
` (5 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The FADT generator collates the relevant information required
for generating a FADT table from configuration manager using
the configuration manager protocol. It then updates a template
FADT table structure. This table data is used by the Table
Manager to install the FADT table.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 1 +
DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf | 42 ++
DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c | 668 ++++++++++++++++++++
3 files changed, 711 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 9b733d39776d183122815aa850747fba8110b643..742bd1e1d87f9c2ce82abd705ef0a501fd294fba 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -27,6 +27,7 @@ [Components.common]
#
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf {
<LibraryClasses>
+ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..e772409069caad8563e37be43ec2841f9d22e62d
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
@@ -0,0 +1,42 @@
+## @file
+# FADT Table Generator
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[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
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[Pcd]
+
+[Protocols]
+
+[Guids]
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..07bedfc14fd2f14bbebc72bd4b4be9eb5b8682eb
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/FadtGenerator.c
@@ -0,0 +1,668 @@
+/** @file
+ FADT Table Generator
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** ARM standard FADT Generator
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjPowerManagementProfileInfo
+ - EArmObjBootArchInfo
+ - EArmObjHypervisorVendorIdentity (OPTIONAL)
+*/
+
+/** This macro defines the FADT flag options for ARM Platforms.
+*/
+#define FADT_FLAGS (EFI_ACPI_6_2_HW_REDUCED_ACPI | \
+ EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE)
+
+/** This macro defines the valid mask for the FADT flag option
+ if HW_REDUCED_ACPI flag in the table is set.
+
+ Invalid bits are: 1, 2, 3,7, 8, 13, 14,16, 17 and
+ 22-31 (reserved).
+
+ Valid bits are:
+ EFI_ACPI_6_2_WBINVD BIT0
+ EFI_ACPI_6_2_PWR_BUTTON BIT4
+ EFI_ACPI_6_2_SLP_BUTTON BIT5
+ EFI_ACPI_6_2_FIX_RTC BIT6
+ EFI_ACPI_6_2_DCK_CAP BIT9
+ EFI_ACPI_6_2_RESET_REG_SUP BIT10
+ EFI_ACPI_6_2_SEALED_CASE BIT11
+ EFI_ACPI_6_2_HEADLESS BIT12
+ EFI_ACPI_6_2_USE_PLATFORM_CLOCK BIT15
+ EFI_ACPI_6_2_FORCE_APIC_CLUSTER_MODEL BIT18
+ EFI_ACPI_6_2_FORCE_APIC_PHYSICAL_DESTINATION_MODE BIT19
+ EFI_ACPI_6_2_HW_REDUCED_ACPI BIT20
+ EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE BIT21
+*/
+#define VALID_HARDWARE_REDUCED_FLAG_MASK ( \
+ EFI_ACPI_6_2_WBINVD | \
+ EFI_ACPI_6_2_PWR_BUTTON | \
+ EFI_ACPI_6_2_SLP_BUTTON | \
+ EFI_ACPI_6_2_FIX_RTC | \
+ EFI_ACPI_6_2_DCK_CAP | \
+ EFI_ACPI_6_2_RESET_REG_SUP | \
+ EFI_ACPI_6_2_SEALED_CASE | \
+ EFI_ACPI_6_2_HEADLESS | \
+ EFI_ACPI_6_2_USE_PLATFORM_CLOCK | \
+ EFI_ACPI_6_2_FORCE_APIC_CLUSTER_MODEL | \
+ EFI_ACPI_6_2_FORCE_APIC_PHYSICAL_DESTINATION_MODE | \
+ EFI_ACPI_6_2_HW_REDUCED_ACPI | \
+ EFI_ACPI_6_2_LOW_POWER_S0_IDLE_CAPABLE)
+
+#pragma pack(1)
+
+/** The AcpiFadt is a template EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE
+ structure used for generating the FADT Table.
+ Note: fields marked with "{Template}" will be updated dynamically.
+*/
+STATIC
+EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE AcpiFadt = {
+ ACPI_HEADER (
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE,
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
+ ),
+ // UINT32 FirmwareCtrl
+ 0,
+ // UINT32 Dsdt
+ 0,
+ // UINT8 Reserved0
+ EFI_ACPI_RESERVED_BYTE,
+ // UINT8 PreferredPmProfile
+ EFI_ACPI_6_2_PM_PROFILE_UNSPECIFIED, // {Template}: Power Management Profile
+ // UINT16 SciInt
+ 0,
+ // UINT32 SmiCmd
+ 0,
+ // UINT8 AcpiEnable
+ 0,
+ // UINT8 AcpiDisable
+ 0,
+ // UINT8 S4BiosReq
+ 0,
+ // UINT8 PstateCnt
+ 0,
+ // UINT32 Pm1aEvtBlk
+ 0,
+ // UINT32 Pm1bEvtBlk
+ 0,
+ // UINT32 Pm1aCntBlk
+ 0,
+ // UINT32 Pm1bCntBlk
+ 0,
+ // UINT32 Pm2CntBlk
+ 0,
+ // UINT32 PmTmrBlk
+ 0,
+ // UINT32 Gpe0Blk
+ 0,
+ // UINT32 Gpe1Blk
+ 0,
+ // UINT8 Pm1EvtLen
+ 0,
+ // UINT8 Pm1CntLen
+ 0,
+ // UINT8 Pm2CntLen
+ 0,
+ // UINT8 PmTmrLen
+ 0,
+ // UINT8 Gpe0BlkLen
+ 0,
+ // UINT8 Gpe1BlkLen
+ 0,
+ // UINT8 Gpe1Base
+ 0,
+ // UINT8 CstCnt
+ 0,
+ // UINT16 PLvl2Lat
+ 0,
+ // UINT16 PLvl3Lat
+ 0,
+ // UINT16 FlushSize
+ 0,
+ // UINT16 FlushStride
+ 0,
+ // UINT8 DutyOffset
+ 0,
+ // UINT8 DutyWidth
+ 0,
+ // UINT8 DayAlrm
+ 0,
+ // UINT8 MonAlrm
+ 0,
+ // UINT8 Century
+ 0,
+ // UINT16 IaPcBootArch
+ 0,
+ // UINT8 Reserved1
+ 0,
+ // UINT32 Flags
+ FADT_FLAGS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE ResetReg
+ NULL_GAS,
+ // UINT8 ResetValue
+ 0,
+ // UINT16 ArmBootArch
+ EFI_ACPI_6_2_ARM_PSCI_COMPLIANT, // {Template}: ARM Boot Architecture Flags
+ // UINT8 MinorRevision
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION,
+ // UINT64 XFirmwareCtrl
+ 0,
+ // UINT64 XDsdt
+ 0,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk
+ NULL_GAS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk
+ NULL_GAS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk
+ NULL_GAS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk
+ NULL_GAS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk
+ NULL_GAS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk
+ NULL_GAS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XGpe0Blk
+ NULL_GAS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE XGpe1Blk
+ NULL_GAS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE SleepControlReg
+ NULL_GAS,
+ // EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE SleepStatusReg
+ NULL_GAS,
+ // UINT64 HypervisorVendorIdentity
+ EFI_ACPI_RESERVED_QWORD // {Template}: Hypervisor Vendor ID
+};
+
+#pragma pack()
+
+/** This macro expands to a function that retrieves the Power
+ Management Profile Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPowerManagementProfileInfo,
+ CM_ARM_POWER_MANAGEMENT_PROFILE_INFO
+ );
+
+/** This macro expands to a function that retrieves the Boot
+ Architecture Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjBootArchInfo,
+ CM_ARM_BOOT_ARCH_INFO
+ );
+
+/** This macro expands to a function that retrieves the Hypervisor
+ Vendor ID from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjHypervisorVendorIdentity,
+ CM_ARM_HYPERVISOR_VENDOR_ID
+ );
+
+/** This macro expands to a function that retrieves the Fixed
+ feature flags for the platform from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjFixedFeatureFlags,
+ CM_ARM_FIXED_FEATURE_FLAGS
+ );
+
+/** Update the Power Management Profile information in the FADT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FadtAddPmProfileInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol
+)
+{
+ EFI_STATUS Status;
+ CM_ARM_POWER_MANAGEMENT_PROFILE_INFO * PmProfile;
+
+ ASSERT (CfgMgrProtocol != NULL);
+
+ // Get the Power Management Profile from the Platform Configuration Manager
+ Status = GetEArmObjPowerManagementProfileInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &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 EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol
+)
+{
+ EFI_STATUS Status;
+ CM_ARM_BOOT_ARCH_INFO * BootArchInfo;
+
+ ASSERT (CfgMgrProtocol != NULL);
+
+ // Get the Boot Architecture flags from the Platform Configuration Manager
+ Status = GetEArmObjBootArchInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &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 EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol
+)
+{
+ EFI_STATUS Status;
+ CM_ARM_HYPERVISOR_VENDOR_ID * HypervisorVendorInfo;
+
+ ASSERT (CfgMgrProtocol != NULL);
+
+ // Get the Hypervisor Vendor ID from the Platform Configuration Manager
+ Status = GetEArmObjHypervisorVendorIdentity (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &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;
+}
+
+/** Update the Fixed Feature Flags in the FADT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FadtAddFixedFeatureFlags (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol
+)
+{
+ EFI_STATUS Status;
+ CM_ARM_FIXED_FEATURE_FLAGS * FixedFeatureFlags;
+
+ ASSERT (CfgMgrProtocol != NULL);
+
+ // Get the Fixed feature flags from the Platform Configuration Manager
+ Status = GetEArmObjFixedFeatureFlags (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &FixedFeatureFlags,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: FADT: Platform does not define additional Fixed feature flags."
+ "Status = %r\n",
+ Status
+ ));
+ } else {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Failed to get Fixed feature flags. Status = %r\n",
+ Status
+ ));
+ }
+ goto error_handler;
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "FADT: EArmObjFixedFeatureFlags = 0x%x\n",
+ FixedFeatureFlags->Flags
+ ));
+
+ if ((FixedFeatureFlags->Flags & ~(VALID_HARDWARE_REDUCED_FLAG_MASK)) != 0) {
+ DEBUG ((
+ DEBUG_WARN,
+ "FADT: Invalid Fixed feature flags defined by platform,"
+ "Invalid Flags bits are = 0x%x\n",
+ (FixedFeatureFlags->Flags & ~(VALID_HARDWARE_REDUCED_FLAG_MASK))
+ ));
+ }
+
+ AcpiFadt.Flags |= (FixedFeatureFlags->Flags &
+ VALID_HARDWARE_REDUCED_FLAG_MASK);
+
+error_handler:
+ return Status;
+}
+
+/** Construct the FADT table.
+
+ This function invokes the Configuration Manager protocol interface
+ to get the required hardware information for generating the ACPI
+ table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildFadtTable (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_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_2_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;
+ }
+ }
+
+ Status = FadtAddFixedFeatureFlags (CfgMgrProtocol);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: FADT: No Fixed feature flags found," \
+ " assuming no additional flags are defined for the platform.\n"
+ ));
+ Status = EFI_SUCCESS;
+ } else {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: FADT: Error reading Fixed feature flags, Status = %r",
+ Status
+ ));
+ goto error_handler;
+ }
+ }
+
+ *Table = (EFI_ACPI_DESCRIPTION_HEADER*)&AcpiFadt;
+error_handler:
+ return Status;
+}
+
+/** This macro defines the FADT Table Generator revision.
+*/
+#define FADT_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the FADT Table Generator.
+*/
+STATIC
+CONST
+ACPI_TABLE_GENERATOR FadtGenerator = {
+ // Generator ID
+ CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_FADT),
+ // Generator Description
+ L"ACPI.STD.FADT.GENERATOR",
+ // ACPI Table Signature
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+ // ACPI Table Revision
+ EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID_ARM,
+ // Creator Revision
+ FADT_GENERATOR_REVISION,
+ // Build Table function
+ BuildFadtTable,
+ // No additional resources are allocated by the generator.
+ // Hence the Free Resource function is not required.
+ NULL
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiFadtLibConstructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = RegisterAcpiTableGenerator (&FadtGenerator);
+ DEBUG ((DEBUG_INFO, "FADT: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiFadtLibDestructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = DeregisterAcpiTableGenerator (&FadtGenerator);
+ DEBUG ((DEBUG_INFO, "FADT: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 17/22] DynamicTablesPkg: Arm ACPI MADT Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (15 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 16/22] DynamicTablesPkg: Arm ACPI FADT Generator Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 18/22] DynamicTablesPkg: Arm ACPI GTDT Generator Sami Mujawar
` (4 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The MADT generator uses the configuration manager protocol to
obtain information about the Arm interrupt controllers (GICC,
GICD, etc.) and generates the ACPI MADT table. This table data
is then used by the Table Manager to install the MADT table.
The Table Manager then invokes the generator interface to free
any resources allocated by the MADT table generator.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 1 +
DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf | 42 ++
DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c | 719 ++++++++++++++++++++
3 files changed, 762 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 742bd1e1d87f9c2ce82abd705ef0a501fd294fba..43e0f564af51cd6327b210af363488ed2a788cc4 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -28,6 +28,7 @@ [Components.common]
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf {
<LibraryClasses>
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..6ba8af4632c25e97b948893c344517ac447ce01a
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
@@ -0,0 +1,42 @@
+## @file
+# MADT Table Generator
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[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
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[Pcd]
+
+[Protocols]
+
+[Guids]
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..76e1712c3bf7f9343ac56d2534ba53b4bdc6d71f
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/MadtGenerator.c
@@ -0,0 +1,719 @@
+/** @file
+ MADT Table Generator
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** ARM standard MADT Generator
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjGicCInfo
+ - EArmObjGicDInfo
+ - EArmObjGicMsiFrameInfo (OPTIONAL)
+ - EArmObjGicRedistributorInfo (OPTIONAL)
+ - EArmObjGicItsInfo (OPTIONAL)
+*/
+
+/** This macro expands to a function that retrieves the GIC
+ CPU interface Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicCInfo,
+ CM_ARM_GICC_INFO
+ );
+
+/** This macro expands to a function that retrieves the GIC
+ Distributor Information from the Configuration Manager.
+*/
+
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicDInfo,
+ CM_ARM_GICD_INFO
+ );
+
+/** This macro expands to a function that retrieves the GIC
+ MSI Frame Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicMsiFrameInfo,
+ CM_ARM_GIC_MSI_FRAME_INFO
+ );
+
+/** This macro expands to a function that retrieves the GIC
+ Redistributor Information from the Configuration Manager.
+*/
+
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicRedistributorInfo,
+ CM_ARM_GIC_REDIST_INFO
+ );
+
+/** This macro expands to a function that retrieves the GIC
+ Interrupt Translation Service Information from the
+ Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicItsInfo,
+ CM_ARM_GIC_ITS_INFO
+ );
+
+/** This function updates the GIC CPU Interface Information in the
+ EFI_ACPI_6_2_GIC_STRUCTURE structure.
+
+ @param [in] Gicc Pointer to GIC CPU Interface structure.
+ @param [in] GicCInfo Pointer to the GIC CPU Interface Information.
+**/
+STATIC
+VOID
+AddGICC (
+ IN EFI_ACPI_6_2_GIC_STRUCTURE * CONST Gicc,
+ IN CONST CM_ARM_GICC_INFO * CONST GicCInfo
+ )
+{
+ ASSERT (Gicc != NULL);
+ ASSERT (GicCInfo != NULL);
+
+ // UINT8 Type
+ Gicc->Type = EFI_ACPI_6_2_GIC;
+ // UINT8 Length
+ Gicc->Length = sizeof (EFI_ACPI_6_2_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_2_GIC_STRUCTURE * Gicc,
+ IN CONST CM_ARM_GICC_INFO * GicCInfo,
+ IN UINT32 GicCCount
+ )
+{
+ ASSERT (Gicc != NULL);
+ ASSERT (GicCInfo != NULL);
+
+ while (GicCCount-- != 0) {
+ AddGICC (Gicc++, GicCInfo++);
+ }
+}
+
+/** Update the GIC Distributor Information in the MADT Table.
+
+ @param [in] Gicd Pointer to GIC Distributor structure.
+ @param [in] GicDInfo Pointer to the GIC Distributor Information.
+**/
+STATIC
+VOID
+AddGICD (
+ EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE * CONST Gicd,
+ CONST CM_ARM_GICD_INFO * CONST GicDInfo
+)
+{
+ ASSERT (Gicd != NULL);
+ ASSERT (GicDInfo != NULL);
+
+ // UINT8 Type
+ Gicd->Type = EFI_ACPI_6_2_GICD;
+ // UINT8 Length
+ Gicd->Length = sizeof (EFI_ACPI_6_2_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 = EFI_ACPI_RESERVED_DWORD;
+ // 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;
+}
+
+/** Update the GIC MSI Frame Information.
+
+ @param [in] GicMsiFrame Pointer to GIC MSI Frame structure.
+ @param [in] GicMsiFrameInfo Pointer to the GIC MSI Frame Information.
+**/
+STATIC
+VOID
+AddGICMsiFrame (
+ IN EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE * CONST GicMsiFrame,
+ IN CONST CM_ARM_GIC_MSI_FRAME_INFO * CONST GicMsiFrameInfo
+)
+{
+ ASSERT (GicMsiFrame != NULL);
+ ASSERT (GicMsiFrameInfo != NULL);
+
+ GicMsiFrame->Type = EFI_ACPI_6_2_GIC_MSI_FRAME;
+ GicMsiFrame->Length = sizeof (EFI_ACPI_6_2_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_2_GIC_MSI_FRAME_STRUCTURE * GicMsiFrame,
+ IN CONST CM_ARM_GIC_MSI_FRAME_INFO * GicMsiFrameInfo,
+ IN UINT32 GicMsiFrameCount
+)
+{
+ ASSERT (GicMsiFrame != NULL);
+ ASSERT (GicMsiFrameInfo != NULL);
+
+ while (GicMsiFrameCount-- != 0) {
+ 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_2_GICR_STRUCTURE * CONST Gicr,
+ IN CONST CM_ARM_GIC_REDIST_INFO * CONST GicRedisributorInfo
+ )
+{
+ ASSERT (Gicr != NULL);
+ ASSERT (GicRedisributorInfo != NULL);
+
+ Gicr->Type = EFI_ACPI_6_2_GICR;
+ Gicr->Length = sizeof (EFI_ACPI_6_2_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_2_GICR_STRUCTURE * Gicr,
+ IN CONST CM_ARM_GIC_REDIST_INFO * GicRInfo,
+ IN UINT32 GicRCount
+)
+{
+ ASSERT (Gicr != NULL);
+ ASSERT (GicRInfo != NULL);
+
+ while (GicRCount-- != 0) {
+ AddGICRedistributor (Gicr++, GicRInfo++);
+ }
+}
+
+/** Update the GIC Interrupt Translation Service Information
+
+ @param [in] GicIts Pointer to GIC ITS structure.
+ @param [in] GicItsInfo Pointer to the GIC ITS Information.
+**/
+STATIC
+VOID
+AddGICInterruptTranslationService (
+ IN EFI_ACPI_6_2_GIC_ITS_STRUCTURE * CONST GicIts,
+ IN CONST CM_ARM_GIC_ITS_INFO * CONST GicItsInfo
+)
+{
+ ASSERT (GicIts != NULL);
+ ASSERT (GicItsInfo != NULL);
+
+ GicIts->Type = EFI_ACPI_6_2_GIC_ITS;
+ GicIts->Length = sizeof (EFI_ACPI_6_2_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_2_GIC_ITS_STRUCTURE * GicIts,
+ IN CONST CM_ARM_GIC_ITS_INFO * GicItsInfo,
+ IN UINT32 GicItsCount
+)
+{
+ ASSERT (GicIts != NULL);
+ ASSERT (GicItsInfo != NULL);
+
+ while (GicItsCount-- != 0) {
+ AddGICInterruptTranslationService (GicIts++, GicItsInfo++);
+ }
+}
+
+/** Construct the MADT ACPI table.
+
+ This function invokes the Configuration Manager protocol interface
+ to get the required hardware information for generating the ACPI
+ table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildMadtTable (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TableSize;
+ UINT32 GicCCount;
+ UINT32 GicDCount;
+ UINT32 GicMSICount;
+ UINT32 GicRedistCount;
+ UINT32 GicItsCount;
+ CM_ARM_GICC_INFO * GicCInfo;
+ CM_ARM_GICD_INFO * GicDInfo;
+ CM_ARM_GIC_MSI_FRAME_INFO * GicMSIInfo;
+ CM_ARM_GIC_REDIST_INFO * GicRedistInfo;
+ CM_ARM_GIC_ITS_INFO * GicItsInfo;
+ UINT32 GicCOffset;
+ UINT32 GicDOffset;
+ UINT32 GicMSIOffset;
+ UINT32 GicRedistOffset;
+ UINT32 GicItsOffset;
+
+ EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER * Madt;
+
+ ASSERT (This != 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,
+ CM_NULL_TOKEN,
+ &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,
+ CM_NULL_TOKEN,
+ &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;
+ }
+
+ if (GicDCount > 1) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: MADT: One, and only one, GIC distributor must be present."
+ "GicDCount = %d\n",
+ GicDCount
+ ));
+ ASSERT (GicDCount <= 1);
+ Status = EFI_INVALID_PARAMETER;
+ goto error_handler;
+ }
+
+ Status = GetEArmObjGicMsiFrameInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &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,
+ CM_NULL_TOKEN,
+ &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,
+ CM_NULL_TOKEN,
+ &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_2_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER);
+
+ GicCOffset = TableSize;
+ TableSize += (sizeof (EFI_ACPI_6_2_GIC_STRUCTURE) * GicCCount);
+
+ GicDOffset = TableSize;
+ TableSize += (sizeof (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE) * GicDCount);
+
+ GicMSIOffset = TableSize;
+ TableSize += (sizeof (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE) * GicMSICount);
+
+ GicRedistOffset = TableSize;
+ TableSize += (sizeof (EFI_ACPI_6_2_GICR_STRUCTURE) * GicRedistCount);
+
+ GicItsOffset = TableSize;
+ TableSize += (sizeof (EFI_ACPI_6_2_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_2_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_2_GIC_STRUCTURE*)((UINT8*)Madt + GicCOffset),
+ GicCInfo,
+ GicCCount
+ );
+
+ AddGICD (
+ (EFI_ACPI_6_2_GIC_DISTRIBUTOR_STRUCTURE*)((UINT8*)Madt + GicDOffset),
+ GicDInfo
+ );
+
+ if (GicMSICount != 0) {
+ AddGICMsiFrameInfoList (
+ (EFI_ACPI_6_2_GIC_MSI_FRAME_STRUCTURE*)((UINT8*)Madt + GicMSIOffset),
+ GicMSIInfo,
+ GicMSICount
+ );
+ }
+
+ if (GicRedistCount != 0) {
+ AddGICRedistributorList (
+ (EFI_ACPI_6_2_GICR_STRUCTURE*)((UINT8*)Madt + GicRedistOffset),
+ GicRedistInfo,
+ GicRedistCount
+ );
+ }
+
+ if (GicItsCount != 0) {
+ AddGICItsList (
+ (EFI_ACPI_6_2_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, out] Table Pointer to the ACPI Table.
+
+ @retval EFI_SUCCESS The resources were freed successfully.
+ @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
+**/
+STATIC
+EFI_STATUS
+FreeMadtTableResources (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN OUT 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_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+ // ACPI Table Revision
+ EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID_ARM,
+ // Creator Revision
+ MADT_GENERATOR_REVISION,
+ // Build Table function
+ BuildMadtTable,
+ // Free Resource function
+ FreeMadtTableResources
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiMadtLibConstructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = RegisterAcpiTableGenerator (&MadtGenerator);
+ DEBUG ((DEBUG_INFO, "MADT: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiMadtLibDestructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = DeregisterAcpiTableGenerator (&MadtGenerator);
+ DEBUG ((DEBUG_INFO, "MADT: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 18/22] DynamicTablesPkg: Arm ACPI GTDT Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (16 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 17/22] DynamicTablesPkg: Arm ACPI MADT Generator Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 19/22] DynamicTablesPkg: Arm SPCR Table Generator Sami Mujawar
` (3 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The GTDT generator uses the configuration manager protocol to
obtain information about the architectural and platform timers
available on the platform and generates the ACPI GTDT table.
This table data is then used by the Table Manager to install
the GTDT table.
The Table Manager then invokes the generator interface to free
any resources allocated by the GTDT table generator.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 1 +
DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf | 42 ++
DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c | 674 ++++++++++++++++++++
3 files changed, 717 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 43e0f564af51cd6327b210af363488ed2a788cc4..056a1293c93268a6203fc3711079880d11cbc1bc 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -28,6 +28,7 @@ [Components.common]
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf {
<LibraryClasses>
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..da3db2b1ff882a9e3a71810eff3d76681ec9d208
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
@@ -0,0 +1,42 @@
+## @file
+# GTDT Table Generator
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[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
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[FixedPcd]
+
+[Protocols]
+
+[Guids]
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..8414225291a68a888f13799e92e0c39b7f3bffc2
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/GtdtGenerator.c
@@ -0,0 +1,674 @@
+/** @file
+ GTDT Table Generator
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** ARM standard GTDT Generator
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjGenericTimerInfo
+ - EArmObjPlatformGenericWatchdogInfo (OPTIONAL)
+ - EArmObjPlatformGTBlockInfo (OPTIONAL)
+ - EArmObjGTBlockTimerFrameInfo (OPTIONAL)
+*/
+
+/** This macro expands to a function that retrieves the Generic
+ Timer Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGenericTimerInfo,
+ CM_ARM_GENERIC_TIMER_INFO
+ );
+
+/** This macro expands to a function that retrieves the SBSA Generic
+ Watchdog Timer Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPlatformGenericWatchdogInfo,
+ CM_ARM_GENERIC_WATCHDOG_INFO
+ );
+
+/** This macro expands to a function that retrieves the Platform Generic
+ Timer Block Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPlatformGTBlockInfo,
+ CM_ARM_GTBLOCK_INFO
+ );
+
+/** This macro expands to a function that retrieves the Generic
+ Timer Block Timer Frame Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGTBlockTimerFrameInfo,
+ CM_ARM_GTBLOCK_TIMER_FRAME_INFO
+ );
+
+/** Add the Generic Timer Information to the GTDT table.
+
+ Also update the Platform Timer offset information if the platform
+ implements platform timers.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Gtdt Pointer to the GTDT Table.
+ @param [in] PlatformTimerCount Platform timer count.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+AddGenericTimerInfo (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE * CONST Gtdt,
+ IN CONST UINT32 PlatformTimerCount
+)
+{
+ EFI_STATUS Status;
+ CM_ARM_GENERIC_TIMER_INFO * GenericTimerInfo;
+
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Gtdt != NULL);
+
+ Status = GetEArmObjGenericTimerInfo (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &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->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;
+ Gtdt->CntReadBasePhysicalAddress =
+ GenericTimerInfo->CounterReadBaseAddress;
+ Gtdt->PlatformTimerCount = PlatformTimerCount;
+ Gtdt->PlatformTimerOffset = (PlatformTimerCount == 0) ? 0 :
+ sizeof (EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE);
+
+ return EFI_SUCCESS;
+}
+
+/** Add the SBSA Generic Watchdog Timers to the GTDT table.
+
+ @param [in] Gtdt Pointer to the GTDT Table.
+ @param [in] WatchdogOffset Offset to the watchdog information in 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_2_GENERIC_TIMER_DESCRIPTION_TABLE * CONST Gtdt,
+ IN CONST UINT32 WatchdogOffset,
+ IN CONST CM_ARM_GENERIC_WATCHDOG_INFO * WatchdogInfoList,
+ IN UINT32 WatchdogCount
+ )
+{
+ EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE * Watchdog;
+
+ ASSERT (Gtdt != NULL);
+ ASSERT (WatchdogInfoList != NULL);
+
+ Watchdog = (EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE *)
+ ((UINT8*)Gtdt + WatchdogOffset);
+
+ while (WatchdogCount-- != 0) {
+ // Add watchdog entry
+ DEBUG ((DEBUG_INFO, "GTDT: Watchdog = 0x%p\n", Watchdog));
+ Watchdog->Type = EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG;
+ Watchdog->Length =
+ sizeof (EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE);
+ Watchdog->Reserved = EFI_ACPI_RESERVED_BYTE;
+ Watchdog->RefreshFramePhysicalAddress =
+ WatchdogInfoList->RefreshFrameAddress;
+ Watchdog->WatchdogControlFramePhysicalAddress =
+ WatchdogInfoList->ControlFrameAddress;
+ Watchdog->WatchdogTimerGSIV = WatchdogInfoList->TimerGSIV;
+ Watchdog->WatchdogTimerFlags = WatchdogInfoList->Flags;
+ Watchdog++;
+ WatchdogInfoList++;
+ } // for
+}
+
+/** Update the GT Block Timer Frame lists in the GTDT Table.
+
+ @param [in] GtBlockFrame Pointer to the GT Block Frames
+ list to be updated.
+ @param [in] GTBlockTimerFrameList Pointer to the GT Block Frame
+ Information List.
+ @param [in] GTBlockFrameCount Number of GT Block Frames.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+AddGTBlockTimerFrames (
+ IN EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCTURE * GtBlockFrame,
+ IN CONST CM_ARM_GTBLOCK_TIMER_FRAME_INFO * GTBlockTimerFrameList,
+ IN UINT32 GTBlockFrameCount
+)
+{
+ 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;
+ }
+
+ while (GTBlockFrameCount-- != 0) {
+ DEBUG ((
+ DEBUG_INFO,
+ "GTDT: GtBlockFrame = 0x%p\n",
+ GtBlockFrame
+ ));
+
+ GtBlockFrame->GTFrameNumber = GTBlockTimerFrameList->FrameNumber;
+ GtBlockFrame->Reserved[0] = EFI_ACPI_RESERVED_BYTE;
+ GtBlockFrame->Reserved[1] = EFI_ACPI_RESERVED_BYTE;
+ GtBlockFrame->Reserved[2] = EFI_ACPI_RESERVED_BYTE;
+
+ GtBlockFrame->CntBaseX = GTBlockTimerFrameList->PhysicalAddressCntBase;
+ GtBlockFrame->CntEL0BaseX =
+ GTBlockTimerFrameList->PhysicalAddressCntEL0Base;
+
+ GtBlockFrame->GTxPhysicalTimerGSIV =
+ GTBlockTimerFrameList->PhysicalTimerGSIV;
+ GtBlockFrame->GTxPhysicalTimerFlags =
+ GTBlockTimerFrameList->PhysicalTimerFlags;
+
+ GtBlockFrame->GTxVirtualTimerGSIV = GTBlockTimerFrameList->VirtualTimerGSIV;
+ GtBlockFrame->GTxVirtualTimerFlags =
+ GTBlockTimerFrameList->VirtualTimerFlags;
+
+ GtBlockFrame->GTxCommonFlags = GTBlockTimerFrameList->CommonFlags;
+ GtBlockFrame++;
+ GTBlockTimerFrameList++;
+ } // for
+ return EFI_SUCCESS;
+}
+
+/** Add the GT Block Timers in the GTDT Table.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Gtdt Pointer to the GTDT Table.
+ @param [in] GTBlockOffset Offset of the GT Block
+ information in the GTDT Table.
+ @param [in] GTBlockInfo Pointer to the GT Block
+ Information List.
+ @param [in] BlockTimerCount Number of GT Block Timers.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+STATIC
+EFI_STATUS
+AddGTBlockList (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE * CONST Gtdt,
+ IN CONST UINT32 GTBlockOffset,
+ IN CONST CM_ARM_GTBLOCK_INFO * GTBlockInfo,
+ IN UINT32 BlockTimerCount
+)
+{
+ EFI_STATUS Status;
+ EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE * GTBlock;
+ EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCTURE * GtBlockFrame;
+ CM_ARM_GTBLOCK_TIMER_FRAME_INFO * GTBlockTimerFrameList;
+ UINT32 GTBlockTimerFrameCount;
+
+ ASSERT (Gtdt != NULL);
+ ASSERT (GTBlockInfo != NULL);
+
+ GTBlock = (EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE *)((UINT8*)Gtdt +
+ GTBlockOffset);
+
+ while (BlockTimerCount-- != 0) {
+ DEBUG ((DEBUG_INFO, "GTDT: GTBlock = 0x%p\n", GTBlock));
+
+ Status = GetEArmObjGTBlockTimerFrameInfo (
+ CfgMgrProtocol,
+ GTBlockInfo->GTBlockTimerFrameToken,
+ >BlockTimerFrameList,
+ >BlockTimerFrameCount
+ );
+ if (EFI_ERROR (Status) ||
+ (GTBlockTimerFrameCount != GTBlockInfo->GTBlockTimerFrameCount)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: GTDT: Failed to get Generic Timer Frames. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ GTBlock->Type = EFI_ACPI_6_2_GTDT_GT_BLOCK;
+ GTBlock->Length = sizeof (EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE) +
+ (sizeof (EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCTURE) *
+ GTBlockInfo->GTBlockTimerFrameCount);
+
+ GTBlock->Reserved = EFI_ACPI_RESERVED_BYTE;
+ GTBlock->CntCtlBase = GTBlockInfo->GTBlockPhysicalAddress;
+ GTBlock->GTBlockTimerCount = GTBlockInfo->GTBlockTimerFrameCount;
+ GTBlock->GTBlockTimerOffset =
+ sizeof (EFI_ACPI_6_2_GTDT_GT_BLOCK_STRUCTURE);
+
+ GtBlockFrame = (EFI_ACPI_6_2_GTDT_GT_BLOCK_TIMER_STRUCTURE*)
+ ((UINT8*)GTBlock + GTBlock->GTBlockTimerOffset);
+
+ // Add GT Block Timer frames
+ Status = AddGTBlockTimerFrames (
+ GtBlockFrame,
+ GTBlockTimerFrameList,
+ 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_2_GTDT_GT_BLOCK_STRUCTURE *)((UINT8*)GTBlock +
+ GTBlock->Length);
+ GTBlockInfo++;
+ }// for
+ return EFI_SUCCESS;
+}
+
+/** Construct the GTDT ACPI table.
+
+ Called by the Dynamic Table Manager, this function invokes the
+ Configuration Manager protocol interface to get the required hardware
+ information for generating the ACPI table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildGtdtTable (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TableSize;
+ UINT32 PlatformTimerCount;
+ UINT32 WatchdogCount;
+ UINT32 BlockTimerCount;
+ CM_ARM_GENERIC_WATCHDOG_INFO * WatchdogInfoList;
+ CM_ARM_GTBLOCK_INFO * GTBlockInfo;
+ EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE * Gtdt;
+ UINT32 Idx;
+ UINT32 GTBlockOffset;
+ UINT32 WatchdogOffset;
+
+ 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,
+ CM_NULL_TOKEN,
+ >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,
+ CM_NULL_TOKEN,
+ &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
+ PlatformTimerCount = 0;
+ TableSize = sizeof (EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE);
+ if (BlockTimerCount != 0) {
+ GTBlockOffset = TableSize;
+ PlatformTimerCount += BlockTimerCount;
+ TableSize += (sizeof (EFI_ACPI_6_2_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_2_GTDT_GT_BLOCK_TIMER_STRUCTURE) *
+ GTBlockInfo[Idx].GTBlockTimerFrameCount);
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "GTDT: GTBockOffset = 0x%x, PLATFORM_TIMER_COUNT = %d\n",
+ GTBlockOffset,
+ PlatformTimerCount
+ ));
+ }
+
+ WatchdogOffset = 0;
+ if (WatchdogCount != 0) {
+ WatchdogOffset = TableSize;
+ PlatformTimerCount += WatchdogCount;
+ TableSize += (sizeof (EFI_ACPI_6_2_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_2_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 (
+ CfgMgrProtocol,
+ 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, out] Table Pointer to the ACPI Table.
+
+ @retval EFI_SUCCESS The resources were freed successfully.
+ @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
+**/
+STATIC
+EFI_STATUS
+FreeGtdtTableResources (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN OUT 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_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
+ // ACPI Table Revision
+ EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID_ARM,
+ // Creator Revision
+ GTDT_GENERATOR_REVISION,
+ // Build Table function
+ BuildGtdtTable,
+ // Free Resource function
+ FreeGtdtTableResources
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiGtdtLibConstructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = RegisterAcpiTableGenerator (&GtdtGenerator);
+ DEBUG ((DEBUG_INFO, "GTDT: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiGtdtLibDestructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = DeregisterAcpiTableGenerator (&GtdtGenerator);
+ DEBUG ((DEBUG_INFO, "GTDT: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 19/22] DynamicTablesPkg: Arm SPCR Table Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (17 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 18/22] DynamicTablesPkg: Arm ACPI GTDT Generator Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 20/22] DynamicTablesPkg: Arm DBG2 " Sami Mujawar
` (2 subsequent siblings)
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The SPCR generator uses the configuration manager protocol to
obtain the serial port information from the platform configuration
manager. It then updates a template SPCR table structure. This
table data is used by the Table Manager to install the SPCR table.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 1 +
DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf | 42 +++
DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c | 326 ++++++++++++++++++++
3 files changed, 369 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 056a1293c93268a6203fc3711079880d11cbc1bc..cfefd57d451155880e6b0e62f1f0605160e6a9aa 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -31,6 +31,7 @@ [Components.common]
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
}
#
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..8dd94e550b8181dea13d5be81688cc35b8b80eac
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
@@ -0,0 +1,42 @@
+## @file
+# SPCR Table Generator
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[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
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[Pcd]
+
+[Protocols]
+
+[Guids]
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..52c7e475baf511c0abf1442113e88248c5d035b3
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/SpcrGenerator.c
@@ -0,0 +1,326 @@
+/** @file
+ SPCR Table Generator
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - Microsoft Serial Port Console Redirection Table
+ Specification - Version 1.03 - August 10, 2015.
+
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** ARM standard SPCR Table Generator
+
+ Constructs the SPCR table for PL011 or SBSA UART peripherals.
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjSerialConsolePortInfo
+
+NOTE: This implementation ignores the possibility that the Serial 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_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
+ EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE,
+ EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION
+ ),
+ 0, // {Template}: Serial Port Subtype
+ {
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE,
+ EFI_ACPI_RESERVED_BYTE
+ },
+ ARM_GAS32 (0), // {Template}: Serial Port Base Address
+ EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC,
+ 0, // Not used on ARM
+ 0, // {Template}: Serial Port Interrupt
+ 0, // {Template}: Serial Port Baudrate
+ EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_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 Configuration Manager protocol interface
+ to get the required hardware information for generating the ACPI
+ table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_UNSUPPORTED An unsupported baudrate was specified by the
+ Configuration Manager.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildSpcrTable (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_SERIAL_PORT_INFO * SerialPortInfo;
+
+ 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,
+ CM_NULL_TOKEN,
+ &SerialPortInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPCR: Failed to get serial port information. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ if (SerialPortInfo->BaseAddress == 0) {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPCR: Uart port base address is invalid. BaseAddress = 0x%lx\n",
+ SerialPortInfo->BaseAddress
+ ));
+ goto error_handler;
+ }
+
+ if ((SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_DCC)) {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: SPCR: Uart port sybtype is invalid. PortSubtype = 0x%x\n",
+ SerialPortInfo->PortSubtype
+ ));
+ 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;
+ }
+
+ // Update the serial port subtype
+ AcpiSpcr.InterfaceType = SerialPortInfo->PortSubtype;
+
+ // Update the base address
+ AcpiSpcr.BaseAddress.Address = SerialPortInfo->BaseAddress;
+
+ // Update the UART interrupt
+ 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;
+}
+
+/** 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_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
+ // ACPI Table Revision
+ EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID_ARM,
+ // Creator Revision
+ SPCR_GENERATOR_REVISION,
+ // Build Table function
+ BuildSpcrTable,
+ // No additional resources are allocated by the generator.
+ // Hence the Free Resource function is not required.
+ NULL
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiSpcrLibConstructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = RegisterAcpiTableGenerator (&SpcrGenerator);
+ DEBUG ((DEBUG_INFO, "SPCR: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiSpcrLibDestructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = DeregisterAcpiTableGenerator (&SpcrGenerator);
+ DEBUG ((DEBUG_INFO, "SPCR: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 20/22] DynamicTablesPkg: Arm DBG2 Table Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (18 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 19/22] DynamicTablesPkg: Arm SPCR Table Generator Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 21/22] DynamicTablesPkg: Arm PCI MCFG " Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 22/22] DynamicTablesPkg: Arm IORT " Sami Mujawar
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The DBG2 generator uses the configuration manager protocol
to obtain the debug serial port information from the platform
configuration manager. It then updates a template DBG2 table
structure. This table data is used by the Table Manager to
install the DBG2 table.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 1 +
DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf | 48 +++
DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c | 442 ++++++++++++++++++++
3 files changed, 491 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index cfefd57d451155880e6b0e62f1f0605160e6a9aa..5ff981619fcd3a579afc50faff41e474a5d604ad 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -27,6 +27,7 @@ [Components.common]
#
DynamicTablesPkg/Drivers/DynamicTableFactoryDxe/DynamicTableFactoryDxe.inf {
<LibraryClasses>
+ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..4075862204c9a12cfd26002e359e054c36914ef0
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf
@@ -0,0 +1,48 @@
+## @file
+# DBG2 Table Generator
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[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
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ SerialPortLib
+
+[FixedPcd]
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+
+[Protocols]
+
+[Guids]
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c
new file mode 100644
index 0000000000000000000000000000000000000000..2c41afd8a50ca6fbea6950fa59af74b528111840
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/Dbg2Generator.c
@@ -0,0 +1,442 @@
+/** @file
+ DBG2 Table Generator
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
+
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PL011UartLib.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/SerialIo.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** ARM standard DBG2 Table Generator
+
+ Constructs the DBG2 table for PL011 or SBSA UART peripherals.
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjSerialDebugPortInfo
+*/
+
+#pragma pack(1)
+
+/** The number of debug ports represented by the Table.
+*/
+#define DBG2_NUM_DEBUG_PORTS 1
+
+/** The number of Generic Address Registers
+ presented in the debug device information.
+*/
+#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS 1
+
+/** The index for the debug port 1 in the Debug port information list.
+*/
+#define DBG_PORT_INDEX_PORT1 0
+
+/** A string representing the name of the debug port 1.
+*/
+#define NAME_STR_PORT1 "COM1"
+
+/** The length of the namespace string.
+*/
+#define DBG2_NAMESPACESTRING_FIELD_SIZE sizeof (NAME_STR_PORT1)
+
+/** The PL011 UART address range length.
+*/
+#define PL011_UART_LENGTH 0x1000
+
+/** A structure that provides the OS with the required information
+ for initializing a debugger connection.
+*/
+typedef struct {
+ /// The debug device information for the platform
+ EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device;
+
+ /// The base address register for the serial port
+ EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister;
+
+ /// The address size
+ UINT32 AddressSize;
+
+ /// The debug port name string
+ UINT8 NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE];
+} DBG2_DEBUG_DEVICE_INFORMATION;
+
+/** A structure representing the information about the debug port(s)
+ available on the platform.
+*/
+typedef struct {
+ /// The DBG2 table header
+ EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE Description;
+
+ /// Debug port information list
+ DBG2_DEBUG_DEVICE_INFORMATION Dbg2DeviceInfo[DBG2_NUM_DEBUG_PORTS];
+} DBG2_TABLE;
+
+/** A helper macro used for initializing the debug port device
+ information structure.
+
+ @param [in] NumReg The number of generic address registers.
+ @param [in] SubType The DBG Port SubType.
+ @param [in] UartBase The UART port base address.
+ @param [in] UartAddrLen The UART port address range length.
+ @param [in] UartNameStr The UART port name string.
+**/
+#define DBG2_DEBUG_PORT_DDI( \
+ NumReg, \
+ SubType, \
+ UartBase, \
+ UartAddrLen, \
+ UartNameStr \
+ ) { \
+ { \
+ /* UINT8 Revision */ \
+ EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, \
+ /* UINT16 Length */ \
+ sizeof (DBG2_DEBUG_DEVICE_INFORMATION), \
+ /* UINT8 NumberofGenericAddressRegisters */ \
+ NumReg, \
+ /* UINT16 NameSpaceStringLength */ \
+ DBG2_NAMESPACESTRING_FIELD_SIZE, \
+ /* UINT16 NameSpaceStringOffset */ \
+ OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString), \
+ /* UINT16 OemDataLength */ \
+ 0, \
+ /* UINT16 OemDataOffset */ \
+ 0, \
+ /* UINT16 Port Type */ \
+ EFI_ACPI_DBG2_PORT_TYPE_SERIAL, \
+ /* UINT16 Port Subtype */ \
+ SubType, \
+ /* UINT8 Reserved[2] */ \
+ {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}, \
+ /* UINT16 BaseAddressRegister Offset */ \
+ OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), \
+ /* UINT16 AddressSize Offset */ \
+ OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize) \
+ }, \
+ /* EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \
+ ARM_GAS32 (UartBase), \
+ /* UINT32 AddressSize */ \
+ UartAddrLen, \
+ /* UINT8 NameSpaceString[MAX_DBG2_NAME_LEN] */ \
+ UartNameStr \
+ }
+
+/** The DBG2 Table template definition.
+
+ Note: fields marked with "{Template}" will be set dynamically
+*/
+STATIC
+DBG2_TABLE AcpiDbg2 = {
+ {
+ ACPI_HEADER (
+ EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE,
+ DBG2_TABLE,
+ EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION
+ ),
+ OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo),
+ DBG2_NUM_DEBUG_PORTS
+ },
+ {
+ /*
+ * Debug port 1
+ */
+ DBG2_DEBUG_PORT_DDI (
+ DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS,
+ 0, // {Template}: Serial Port Subtype
+ 0, // {Template}: Serial Port Base Address
+ PL011_UART_LENGTH,
+ NAME_STR_PORT1
+ )
+ }
+};
+
+#pragma pack()
+
+/** This macro expands to a function that retrieves the Serial
+ debug port information from the Configuration Manager
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjSerialDebugPortInfo,
+ CM_ARM_SERIAL_PORT_INFO
+ );
+
+/** Initialize the PL011 UART with the parameters obtained from
+ the Configuration Manager.
+
+ @param [in] SerialPortInfo Pointer to the Serial Port Information.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER The parameters for serial port initialization
+ are invalid.
+**/
+STATIC
+EFI_STATUS
+SetupDebugUart (
+ IN CONST CM_ARM_SERIAL_PORT_INFO * CONST SerialPortInfo
+ )
+{
+ EFI_STATUS Status;
+ UINT64 BaudRate;
+ UINT32 ReceiveFifoDepth;
+ EFI_PARITY_TYPE Parity;
+ UINT8 DataBits;
+ EFI_STOP_BITS_TYPE StopBits;
+
+ ASSERT (SerialPortInfo != 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 Configuration Manager protocol interface
+ to get the required hardware information for generating the ACPI
+ table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildDbg2Table (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_SERIAL_PORT_INFO * SerialPortInfo;
+
+ 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,
+ CM_NULL_TOKEN,
+ &SerialPortInfo,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: DBG2: Failed to get serial port information. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ if (SerialPortInfo->BaseAddress == 0) {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: DBG2: Uart port base address is invalid. BaseAddress = 0x%lx\n",
+ SerialPortInfo->BaseAddress
+ ));
+ goto error_handler;
+ }
+
+ if ((SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_PL011_UART) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART_2X) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART) &&
+ (SerialPortInfo->PortSubtype !=
+ EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_DCC)) {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: DBG2: Uart port sybtype is invalid. PortSubtype = 0x%x\n",
+ SerialPortInfo->PortSubtype
+ ));
+ 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;
+ }
+
+ // Update the base address
+ AcpiDbg2.Dbg2DeviceInfo[DBG_PORT_INDEX_PORT1].BaseAddressRegister.Address =
+ SerialPortInfo->BaseAddress;
+
+ // Update the serial port subtype
+ AcpiDbg2.Dbg2DeviceInfo[DBG_PORT_INDEX_PORT1].Dbg2Device.PortSubtype =
+ SerialPortInfo->PortSubtype;
+
+ // Initialize the serial port
+ 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;
+}
+
+/** 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_2_DEBUG_PORT_2_TABLE_SIGNATURE,
+ // ACPI Table Revision
+ EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID_ARM,
+ // Creator Revision
+ DBG2_GENERATOR_REVISION,
+ // Build Table function
+ BuildDbg2Table,
+ // No additional resources are allocated by the generator.
+ // Hence the Free Resource function is not required.
+ NULL
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiDbg2LibConstructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = RegisterAcpiTableGenerator (&Dbg2Generator);
+ DEBUG ((DEBUG_INFO, "DBG2: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiDbg2LibDestructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = DeregisterAcpiTableGenerator (&Dbg2Generator);
+ DEBUG ((DEBUG_INFO, "DBG2: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 21/22] DynamicTablesPkg: Arm PCI MCFG Table Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (19 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 20/22] DynamicTablesPkg: Arm DBG2 " Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
2018-12-21 16:57 ` [PATCH v1 22/22] DynamicTablesPkg: Arm IORT " Sami Mujawar
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The MCFG generator uses the configuration manager protocol
to obtain the PCI Configuration space information from the
platform configuration manager and builds the MCFG table.
This table data is then used by the Table Manager to install
the MCFG table.
The Table Manager then invokes the generator interface to free
any resources allocated by the MCFG table generator.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 1 +
DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf | 42 +++
DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c | 344 ++++++++++++++++++++
3 files changed, 387 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 5ff981619fcd3a579afc50faff41e474a5d604ad..98a37efa5d567942a18163c44961bd4c86552bb6 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -31,6 +31,7 @@ [Components.common]
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSpcrLibArm/AcpiSpcrLibArm.inf
}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..e491ad6b24faae24e473f0fd501e06a6f3b456b5
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
@@ -0,0 +1,42 @@
+## @file
+# MCFG Table Generator
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[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
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[Pcd]
+
+[Protocols]
+
+[Guids]
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..1be27160c12b51b36b90cd5f5c9e01efecd8cc03
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/McfgGenerator.c
@@ -0,0 +1,344 @@
+/** @file
+ MCFG Table Generator
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - PCI Firmware Specification - Revision 3.2, January 26, 2015.
+
+**/
+
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+#include <Library/AcpiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+/** ARM standard MCFG Generator
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjPciConfigSpaceInfo
+*/
+
+#pragma pack(1)
+
+/** This typedef is used to shorten the name of the MCFG Table
+ header structure.
+*/
+typedef
+ EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_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 UINT32 PciCfgSpaceOffset,
+ IN CONST CM_ARM_PCI_CONFIG_SPACE_INFO * PciCfgSpaceInfoList,
+ IN UINT32 PciCfgSpaceCount
+)
+{
+ MCFG_CFG_SPACE_ADDR * PciCfgSpace;
+
+ ASSERT (Mcfg != NULL);
+ ASSERT (PciCfgSpaceInfoList != NULL);
+
+ PciCfgSpace = (MCFG_CFG_SPACE_ADDR *)((UINT8*)Mcfg + PciCfgSpaceOffset);
+
+ while (PciCfgSpaceCount-- != 0) {
+ // Add PCI Configuration Space entry
+ PciCfgSpace->BaseAddress = PciCfgSpaceInfoList->BaseAddress;
+ PciCfgSpace->PciSegmentGroupNumber =
+ PciCfgSpaceInfoList->PciSegmentGroupNumber;
+ PciCfgSpace->StartBusNumber = PciCfgSpaceInfoList->StartBusNumber;
+ PciCfgSpace->EndBusNumber = PciCfgSpaceInfoList->EndBusNumber;
+ PciCfgSpace->Reserved = EFI_ACPI_RESERVED_DWORD;
+ PciCfgSpace++;
+ PciCfgSpaceInfoList++;
+ }
+}
+
+/** Construct the MCFG ACPI table.
+
+ This function invokes the Configuration Manager protocol interface
+ to get the required hardware information for generating the ACPI
+ table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildMcfgTable (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TableSize;
+ UINT32 ConfigurationSpaceCount;
+ CM_ARM_PCI_CONFIG_SPACE_INFO * PciConfigSpaceInfoList;
+ MCFG_TABLE * Mcfg;
+
+ ASSERT (This != 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,
+ CM_NULL_TOKEN,
+ &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;
+ }
+
+ if (ConfigurationSpaceCount == 0) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: MCFG: Configuration Space Count = %d\n",
+ ConfigurationSpaceCount
+ ));
+ Status = EFI_INVALID_PARAMETER;
+ ASSERT (ConfigurationSpaceCount != 0);
+ goto error_handler;
+ }
+
+ 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, out] Table Pointer to the ACPI Table.
+
+ @retval EFI_SUCCESS The resources were freed successfully.
+ @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
+**/
+STATIC
+EFI_STATUS
+FreeMcfgTableResources (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN OUT 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_2_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;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiMcfgLibDestructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = DeregisterAcpiTableGenerator (&McfgGenerator);
+ DEBUG ((DEBUG_INFO, "MCFG: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v1 22/22] DynamicTablesPkg: Arm IORT Table Generator
2018-12-21 16:56 [PATCH v1 00/22] DynamicTablesPkg: Introduce Dynamic Tables Framework Sami Mujawar
` (20 preceding siblings ...)
2018-12-21 16:57 ` [PATCH v1 21/22] DynamicTablesPkg: Arm PCI MCFG " Sami Mujawar
@ 2018-12-21 16:57 ` Sami Mujawar
21 siblings, 0 replies; 23+ messages in thread
From: Sami Mujawar @ 2018-12-21 16:57 UTC (permalink / raw)
To: edk2-devel
Cc: alexei.fedorov, leif.lindholm, Matteo.Carlini,
Stephanie.Hughes-Fitt, nd
The IORT generator uses the configuration manager protocol
to obtain information about the PCI Root Complex, SMMU,
GIC ITS, Performance Monitoring counters etc. and generates
the IORT table.
The mappings between the components are represented using
tokens. The generator invokes the configuration manager
protocol interfaces and requests for objects referenced by
tokens to establish the link.
This table data is then used by the Table Manager to install
the IORT table.
The Table Manager then invokes the generator interface to free
any resources allocated by the IORT table generator.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
DynamicTablesPkg/DynamicTables.dsc.inc | 1 +
DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf | 42 +
DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c | 2055 ++++++++++++++++++++
DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h | 50 +
4 files changed, 2148 insertions(+)
diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 98a37efa5d567942a18163c44961bd4c86552bb6..a6bb9d3c71a548161af48b45812a233afd2bd0ef 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -30,6 +30,7 @@ [Components.common]
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiDbg2LibArm/AcpiDbg2LibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiFadtLibArm/AcpiFadtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiGtdtLibArm/AcpiGtdtLibArm.inf
+ NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMadtLibArm/AcpiMadtLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiMcfgLibArm/AcpiMcfgLibArm.inf
NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiRawLibArm/AcpiRawLibArm.inf
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..ce828eb09147d8cc149902c852cc8eaac9b12dc4
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/AcpiIortLibArm.inf
@@ -0,0 +1,42 @@
+## @file
+# IORT Table Generator
+#
+# Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+##
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = AcpiIortLibArm
+ FILE_GUID = 25682BA8-B41D-4403-B034-253769E0DAD5
+ VERSION_STRING = 1.0
+ MODULE_TYPE = DXE_DRIVER
+ LIBRARY_CLASS = NULL|DXE_DRIVER
+ CONSTRUCTOR = AcpiIortLibConstructor
+ DESTRUCTOR = AcpiIortLibDestructor
+
+[Sources]
+ IortGenerator.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+ BaseLib
+
+[Pcd]
+
+[Protocols]
+
+[Guids]
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..979024493dfd47b45eb621b44616076e4b883231
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.c
@@ -0,0 +1,2055 @@
+/** @file
+ IORT Table Generator
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - IO Remapping Table, Platform Design Document,
+ Document number: ARM DEN 0049D, Issue D, March 2018
+
+**/
+
+#include <IndustryStandard/IoRemappingTable.h>
+#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+
+#include "IortGenerator.h"
+
+/** ARM standard IORT Generator
+
+Requirements:
+ The following Configuration Manager Object(s) are required by
+ this Generator:
+ - EArmObjItsGroup
+ - EArmObjNamedComponent
+ - EArmObjRootComplex
+ - EArmObjSmmuV1SmmuV2
+ - EArmObjSmmuV3
+ - EArmObjPmcg
+ - EArmObjGicItsIdentifierArray
+ - EArmObjIdMapping
+ - EArmObjGicItsIdentifierArray
+*/
+
+/** This macro expands to a function that retrieves the ITS
+ Group node information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjItsGroup,
+ CM_ARM_ITS_GROUP_NODE
+ );
+
+/** This macro expands to a function that retrieves the
+ Named Component node information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjNamedComponent,
+ CM_ARM_NAMED_COMPONENT_NODE
+ );
+
+/** This macro expands to a function that retrieves the
+ Root Complex node information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjRootComplex,
+ CM_ARM_ROOT_COMPLEX_NODE
+ );
+
+/** This macro expands to a function that retrieves the
+ SMMU v1/v2 node information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjSmmuV1SmmuV2,
+ CM_ARM_SMMUV1_SMMUV2_NODE
+ );
+
+/** This macro expands to a function that retrieves the
+ SMMU v3 node information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjSmmuV3,
+ CM_ARM_SMMUV3_NODE
+ );
+
+/** This macro expands to a function that retrieves the
+ PMCG node information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjPmcg,
+ CM_ARM_PMCG_NODE
+ );
+
+/** This macro expands to a function that retrieves the
+ ITS Identifier Array information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjGicItsIdentifierArray,
+ CM_ARM_ITS_IDENTIFIER
+ );
+
+/** This macro expands to a function that retrieves the
+ Id Mapping Array information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjIdMapping,
+ CM_ARM_ID_MAPPING
+ );
+
+/** This macro expands to a function that retrieves the
+ SMMU Interrupt Array information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+ EObjNameSpaceArm,
+ EArmObjSmmuInterruptArray,
+ CM_ARM_SMMU_INTERRUPT
+ );
+
+/** Returns the size of the ITS Group node.
+
+ @param [in] Node Pointer to ITS Group node.
+
+ @retval Size of the ITS Group Node.
+**/
+STATIC
+UINT32
+GetItsGroupNodeSize (
+ IN CONST CM_ARM_ITS_GROUP_NODE * Node
+ )
+{
+ ASSERT (Node != NULL);
+
+ /* Size of ITS Group Node +
+ Size of ITS Identifier array
+ */
+ return sizeof (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE) +
+ (Node->ItsIdCount * sizeof (UINT32));
+}
+
+/** Returns the total size required for the ITS Group nodes and
+ updates the Node Indexer.
+
+ This function calculates the size required for the node group
+ and also populates the Node Indexer array with offsets for the
+ individual nodes.
+
+ @param [in] NodeStartOffset Offset from the start of the
+ IORT where this node group starts.
+ @param [in] NodeList Pointer to ITS Group node list.
+ @param [in] NodeCount Count of the ITS Group nodes.
+ @param [in, out] NodeIndexer Pointer to the next Node Indexer.
+
+ @retval Total size of the ITS Group Nodes.
+**/
+STATIC
+UINT32
+GetSizeofItsGroupNodes (
+ IN CONST UINT32 NodeStartOffset,
+ IN CONST CM_ARM_ITS_GROUP_NODE * NodeList,
+ IN UINT32 NodeCount,
+ IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer
+ )
+{
+ UINT32 Size;
+
+ ASSERT (NodeList != NULL);
+
+ Size = 0;
+ while (NodeCount-- != 0) {
+ (*NodeIndexer)->Token = NodeList->Token;
+ (*NodeIndexer)->Object = (VOID*)NodeList;
+ (*NodeIndexer)->Offset = Size + NodeStartOffset;
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n",
+ *NodeIndexer,
+ (*NodeIndexer)->Token,
+ (*NodeIndexer)->Object,
+ (*NodeIndexer)->Offset
+ ));
+
+ Size += GetItsGroupNodeSize (NodeList);
+ (*NodeIndexer)++;
+ NodeList++;
+ }
+ return Size;
+}
+
+/** Returns the size of the Named Component node.
+
+ @param [in] Node Pointer to Named Component node.
+
+ @retval Size of the Named Component node.
+**/
+STATIC
+UINT32
+GetNamedComponentNodeSize (
+ IN CONST CM_ARM_NAMED_COMPONENT_NODE * Node
+ )
+{
+ ASSERT (Node != NULL);
+
+ /* Size of Named Component node +
+ Size of ID mapping array +
+ Size of ASCII string + 'padding to 32-bit word aligned'.
+ */
+ return sizeof (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE) +
+ (Node->IdMappingCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE)) +
+ ALIGN_VALUE (AsciiStrSize (Node->ObjectName), 4);
+}
+
+/** Returns the total size required for the Named Component nodes and
+ updates the Node Indexer.
+
+ This function calculates the size required for the node group
+ and also populates the Node Indexer array with offsets for the
+ individual nodes.
+
+ @param [in] NodeStartOffset Offset from the start of the
+ IORT where this node group starts.
+ @param [in] NodeList Pointer to Named Component node list.
+ @param [in] NodeCount Count of the Named Component nodes.
+ @param [in, out] NodeIndexer Pointer to the next Node Indexer.
+
+ @retval Total size of the Named Component nodes.
+**/
+STATIC
+UINT32
+GetSizeofNamedComponentNodes (
+ IN CONST UINT32 NodeStartOffset,
+ IN CONST CM_ARM_NAMED_COMPONENT_NODE * NodeList,
+ IN UINT32 NodeCount,
+ IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer
+ )
+{
+ UINT32 Size;
+
+ ASSERT (NodeList != NULL);
+
+ Size = 0;
+ while (NodeCount-- != 0) {
+ (*NodeIndexer)->Token = NodeList->Token;
+ (*NodeIndexer)->Object = (VOID*)NodeList;
+ (*NodeIndexer)->Offset = Size + NodeStartOffset;
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n",
+ *NodeIndexer,
+ (*NodeIndexer)->Token,
+ (*NodeIndexer)->Object,
+ (*NodeIndexer)->Offset
+ ));
+
+ Size += GetNamedComponentNodeSize (NodeList);
+ (*NodeIndexer)++;
+ NodeList++;
+ }
+
+ return Size;
+}
+
+/** Returns the size of the Root Complex node.
+
+ @param [in] Node Pointer to Root Complex node.
+
+ @retval Size of the Root Complex node.
+**/
+STATIC
+UINT32
+GetRootComplexNodeSize (
+ IN CONST CM_ARM_ROOT_COMPLEX_NODE * Node
+ )
+{
+ ASSERT (Node != NULL);
+
+ /* Size of Root Complex node +
+ Size of ID mapping array
+ */
+ return sizeof (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE) +
+ (Node->IdMappingCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE));
+}
+
+/** Returns the total size required for the Root Complex nodes and
+ updates the Node Indexer.
+
+ This function calculates the size required for the node group
+ and also populates the Node Indexer array with offsets for the
+ individual nodes.
+
+ @param [in] NodeStartOffset Offset from the start of the
+ IORT where this node group starts.
+ @param [in] NodeList Pointer to Root Complex node list.
+ @param [in] NodeCount Count of the Root Complex nodes.
+ @param [in, out] NodeIndexer Pointer to the next Node Indexer.
+
+ @retval Total size of the Root Complex nodes.
+**/
+STATIC
+UINT32
+GetSizeofRootComplexNodes (
+ IN CONST UINT32 NodeStartOffset,
+ IN CONST CM_ARM_ROOT_COMPLEX_NODE * NodeList,
+ IN UINT32 NodeCount,
+ IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer
+ )
+{
+ UINT32 Size;
+
+ ASSERT (NodeList != NULL);
+
+ Size = 0;
+ while (NodeCount-- != 0) {
+ (*NodeIndexer)->Token = NodeList->Token;
+ (*NodeIndexer)->Object = (VOID*)NodeList;
+ (*NodeIndexer)->Offset = Size + NodeStartOffset;
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n",
+ *NodeIndexer,
+ (*NodeIndexer)->Token,
+ (*NodeIndexer)->Object,
+ (*NodeIndexer)->Offset
+ ));
+
+ Size += GetRootComplexNodeSize (NodeList);
+ (*NodeIndexer)++;
+ NodeList++;
+ }
+
+ return Size;
+}
+
+/** Returns the size of the SMMUv1/SMMUv2 node.
+
+ @param [in] Node Pointer to SMMUv1/SMMUv2 node list.
+
+ @retval Size of the SMMUv1/SMMUv2 node.
+**/
+STATIC
+UINT32
+GetSmmuV1V2NodeSize (
+ IN CONST CM_ARM_SMMUV1_SMMUV2_NODE * Node
+ )
+{
+ ASSERT (Node != NULL);
+
+ /* Size of SMMU v1/SMMU v2 node +
+ Size of ID mapping array +
+ Size of context interrupt array +
+ Size of PMU interrupt array
+ */
+ return sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE) +
+ (Node->IdMappingCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE)) +
+ (Node->ContextInterruptCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT)) +
+ (Node->PmuInterruptCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT));
+}
+
+/** Returns the total size required for the SMMUv1/SMMUv2 nodes and
+ updates the Node Indexer.
+
+ This function calculates the size required for the node group
+ and also populates the Node Indexer array with offsets for the
+ individual nodes.
+
+ @param [in] NodeStartOffset Offset from the start of the
+ IORT where this node group starts.
+ @param [in] NodeList Pointer to SMMUv1/SMMUv2 node list.
+ @param [in] NodeCount Count of the SMMUv1/SMMUv2 nodes.
+ @param [in, out] NodeIndexer Pointer to the next Node Indexer.
+
+ @retval Total size of the SMMUv1/SMMUv2 nodes.
+**/
+STATIC
+UINT32
+GetSizeofSmmuV1V2Nodes (
+ IN CONST UINT32 NodeStartOffset,
+ IN CONST CM_ARM_SMMUV1_SMMUV2_NODE * NodeList,
+ IN UINT32 NodeCount,
+ IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer
+ )
+{
+ UINT32 Size;
+
+ ASSERT (NodeList != NULL);
+
+ Size = 0;
+ while (NodeCount-- != 0) {
+ (*NodeIndexer)->Token = NodeList->Token;
+ (*NodeIndexer)->Object = (VOID*)NodeList;
+ (*NodeIndexer)->Offset = Size + NodeStartOffset;
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n",
+ *NodeIndexer,
+ (*NodeIndexer)->Token,
+ (*NodeIndexer)->Object,
+ (*NodeIndexer)->Offset
+ ));
+
+ Size += GetSmmuV1V2NodeSize (NodeList);
+ (*NodeIndexer)++;
+ NodeList++;
+ }
+ return Size;
+}
+
+/** Returns the size of the SMMUv3 node.
+
+ @param [in] Node Pointer to SMMUv3 node list.
+
+ @retval Total size of the SMMUv3 nodes.
+**/
+STATIC
+UINT32
+GetSmmuV3NodeSize (
+ IN CONST CM_ARM_SMMUV3_NODE * Node
+ )
+{
+ ASSERT (Node != NULL);
+
+ /* Size of SMMU v1/SMMU v2 node +
+ Size of ID mapping array
+ */
+ return sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE) +
+ (Node->IdMappingCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE));
+}
+
+/** Returns the total size required for the SMMUv3 nodes and
+ updates the Node Indexer.
+
+ This function calculates the size required for the node group
+ and also populates the Node Indexer array with offsets for the
+ individual nodes.
+
+ @param [in] NodeStartOffset Offset from the start of the
+ IORT where this node group starts.
+ @param [in] NodeList Pointer to SMMUv3 node list.
+ @param [in] NodeCount Count of the SMMUv3 nodes.
+ @param [in, out] NodeIndexer Pointer to the next Node Indexer.
+
+ @retval Total size of the SMMUv3 nodes.
+**/
+STATIC
+UINT32
+GetSizeofSmmuV3Nodes (
+ IN CONST UINT32 NodeStartOffset,
+ IN CONST CM_ARM_SMMUV3_NODE * NodeList,
+ IN UINT32 NodeCount,
+ IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer
+ )
+{
+ UINT32 Size;
+
+ ASSERT (NodeList != NULL);
+
+ Size = 0;
+ while (NodeCount-- != 0) {
+ (*NodeIndexer)->Token = NodeList->Token;
+ (*NodeIndexer)->Object = (VOID*)NodeList;
+ (*NodeIndexer)->Offset = Size + NodeStartOffset;
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n",
+ *NodeIndexer,
+ (*NodeIndexer)->Token,
+ (*NodeIndexer)->Object,
+ (*NodeIndexer)->Offset
+ ));
+
+ Size += GetSmmuV3NodeSize (NodeList);
+ (*NodeIndexer)++;
+ NodeList++;
+ }
+ return Size;
+}
+
+/** Returns the size of the PMCG node.
+
+ @param [in] Node Pointer to PMCG node.
+
+ @retval Size of the PMCG node.
+**/
+STATIC
+UINT32
+GetPmcgNodeSize (
+ IN CONST CM_ARM_PMCG_NODE * Node
+ )
+{
+ ASSERT (Node != NULL);
+
+ /* Size of PMCG node +
+ Size of ID mapping array
+ */
+ return sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE) +
+ (Node->IdMappingCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE));
+}
+
+/** Returns the total size required for the PMCG nodes and
+ updates the Node Indexer.
+
+ This function calculates the size required for the node group
+ and also populates the Node Indexer array with offsets for the
+ individual nodes.
+
+ @param [in] NodeStartOffset Offset from the start of the
+ IORT where this node group starts.
+ @param [in] NodeList Pointer to PMCG node list.
+ @param [in] NodeCount Count of the PMCG nodes.
+ @param [in, out] NodeIndexer Pointer to the next Node Indexer.
+
+ @retval Total size of the PMCG nodes.
+**/
+STATIC
+UINT32
+GetSizeofPmcgNodes (
+ IN CONST UINT32 NodeStartOffset,
+ IN CONST CM_ARM_PMCG_NODE * NodeList,
+ IN UINT32 NodeCount,
+ IN OUT IORT_NODE_INDEXER ** CONST NodeIndexer
+ )
+{
+ UINT32 Size;
+
+ ASSERT (NodeList != NULL);
+
+ Size = 0;
+ while (NodeCount-- != 0) {
+ (*NodeIndexer)->Token = NodeList->Token;
+ (*NodeIndexer)->Object = (VOID*)NodeList;
+ (*NodeIndexer)->Offset = Size + NodeStartOffset;
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer = %p, Token = %p, Object = %p, Offset = 0x%x\n",
+ *NodeIndexer,
+ (*NodeIndexer)->Token,
+ (*NodeIndexer)->Object,
+ (*NodeIndexer)->Offset
+ ));
+
+ Size += GetPmcgNodeSize (NodeList);
+ (*NodeIndexer)++;
+ NodeList++;
+ }
+ return Size;
+}
+
+/** Returns the offset of the Node referenced by the Token.
+
+ @param [in] NodeIndexer Pointer to node indexer array.
+ @param [in] NodeCount Count of the nodes.
+ @param [in] Token Reference token for the node.
+ @param [out] NodeOffset Offset of the node from the
+ start of the IORT table.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_NOT_FOUND No matching token reference
+ found in node indexer array.
+**/
+STATIC
+EFI_STATUS
+GetNodeOffsetReferencedByToken (
+ IN IORT_NODE_INDEXER * NodeIndexer,
+ IN UINT32 NodeCount,
+ IN CM_OBJECT_TOKEN Token,
+ OUT UINT32 * NodeOffset
+ )
+{
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer: Search Token = %p\n",
+ Token
+ ));
+ while (NodeCount-- != 0) {
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer: NodeIndexer->Token = %p, Offset = %d\n",
+ NodeIndexer->Token,
+ NodeIndexer->Offset
+ ));
+ if (NodeIndexer->Token == Token) {
+ *NodeOffset = NodeIndexer->Offset;
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer: Token = %p, Found\n",
+ Token
+ ));
+ return EFI_SUCCESS;
+ }
+ NodeIndexer++;
+ }
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Node Indexer: Token = %p, Not Found\n",
+ Token
+ ));
+ return EFI_NOT_FOUND;
+}
+
+/** Update the Id Mapping Array.
+
+ This function retrieves the Id Mapping Array object referenced by the
+ IdMappingToken and updates the IdMapArray.
+
+ @param [in] This Pointer to the table Generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] IdMapArray Pointer to an array of Id Mappings.
+ @param [in] IdCount Number of Id Mappings.
+ @param [in] IdMappingToken Reference Token for retrieving the
+ Id Mapping Array object.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+**/
+STATIC
+EFI_STATUS
+AddIdMappingArray (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray,
+ IN UINT32 IdCount,
+ IN CONST CM_OBJECT_TOKEN IdMappingToken
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_ID_MAPPING * IdMappings;
+ UINT32 IdMappingCount;
+ ACPI_IORT_GENERATOR * Generator;
+
+ ASSERT (IdMapArray != NULL);
+
+ Generator = (ACPI_IORT_GENERATOR*)This;
+
+ // Get the Id Mapping Array
+ Status = GetEArmObjIdMapping (
+ CfgMgrProtocol,
+ IdMappingToken,
+ &IdMappings,
+ &IdMappingCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get Id Mapping array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ if (IdMappingCount < IdCount) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get the required number of Id Mappings.\n"
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ // Populate the Id Mapping array
+ while (IdCount-- != 0) {
+ Status = GetNodeOffsetReferencedByToken (
+ Generator->NodeIndexer,
+ Generator->IortNodeCount,
+ IdMappings->OutputReferenceToken,
+ &IdMapArray->OutputReference
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get Output Reference for ITS Identifier array."
+ "Reference Token = %p"
+ " Status = %r\n",
+ IdMappings->OutputReferenceToken,
+ Status
+ ));
+ return Status;
+ }
+
+ IdMapArray->InputBase = IdMappings->InputBase;
+ IdMapArray->NumIds = IdMappings->NumIds;
+ IdMapArray->OutputBase = IdMappings->OutputBase;
+ IdMapArray->Flags = IdMappings->Flags;
+
+ IdMapArray++;
+ IdMappings++;
+ } // Id Mapping array
+
+ return EFI_SUCCESS;
+}
+
+/** Update the ITS Group Node Information.
+
+ @param [in] This Pointer to the table Generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Iort Pointer to IORT table structure.
+ @param [in] NodesStartOffset Offset for the start of the ITS Group
+ Nodes.
+ @param [in] NodeList Pointer to an array of ITS Group Node
+ Objects.
+ @param [in] NodeCount Number of ITS Group Node Objects.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+**/
+STATIC
+EFI_STATUS
+AddItsGroupNodes (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort,
+ IN CONST UINT32 NodesStartOffset,
+ IN CONST CM_ARM_ITS_GROUP_NODE * NodeList,
+ IN UINT32 NodeCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE * ItsGroupNode;
+ UINT32 * ItsIds;
+ CM_ARM_ITS_IDENTIFIER * ItsIdentifier;
+ UINT32 ItsIdentifierCount;
+ UINT32 IdIndex;
+
+ ASSERT (Iort != NULL);
+
+ ItsGroupNode = (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE*)((UINT8*)Iort +
+ NodesStartOffset);
+
+ while (NodeCount-- != 0) {
+ // Populate the node header
+ ItsGroupNode->Node.Type = EFI_ACPI_IORT_TYPE_ITS_GROUP;
+ ItsGroupNode->Node.Length = GetItsGroupNodeSize (NodeList);
+ ItsGroupNode->Node.Revision = 0;
+ ItsGroupNode->Node.Reserved = EFI_ACPI_RESERVED_DWORD;
+ ItsGroupNode->Node.NumIdMappings = 0;
+ ItsGroupNode->Node.IdReference = 0;
+
+ // IORT specific data
+ ItsGroupNode->NumItsIdentifiers = NodeList->ItsIdCount;
+ ItsIds = (UINT32*)((UINT8*)ItsGroupNode +
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE));
+
+ Status = GetEArmObjGicItsIdentifierArray (
+ CfgMgrProtocol,
+ NodeList->ItsIdToken,
+ &ItsIdentifier,
+ &ItsIdentifierCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get ITS Identifier array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ if (ItsIdentifierCount < ItsGroupNode->NumItsIdentifiers) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get the required number of ITS Identifiers.\n"
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ // Populate the ITS identifier array
+ for (IdIndex = 0; IdIndex < ItsGroupNode->NumItsIdentifiers; IdIndex++) {
+ ItsIds[IdIndex] = ItsIdentifier[IdIndex].ItsId;
+ } // ITS identifier array
+
+ // Next IORT Group Node
+ ItsGroupNode = (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE*)((UINT8*)ItsGroupNode +
+ ItsGroupNode->Node.Length);
+ NodeList++;
+ } // IORT Group Node
+
+ return EFI_SUCCESS;
+}
+
+/** Update the Named Component Node Information.
+
+ This function updates the Named Component node information in the IORT
+ table.
+
+ @param [in] This Pointer to the table Generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Iort Pointer to IORT table structure.
+ @param [in] NodesStartOffset Offset for the start of the Named
+ Component Nodes.
+ @param [in] NodeList Pointer to an array of Named Component
+ Node Objects.
+ @param [in] NodeCount Number of Named Component Node Objects.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+**/
+STATIC
+EFI_STATUS
+AddNamedComponentNodes (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort,
+ IN CONST UINT32 NodesStartOffset,
+ IN CONST CM_ARM_NAMED_COMPONENT_NODE * NodeList,
+ IN UINT32 NodeCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE * NcNode;
+ EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray;
+ UINT32 ObjectNameLenght;
+ CHAR8 * ObjectName;
+
+ ASSERT (Iort != NULL);
+
+ NcNode = (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE*)((UINT8*)Iort +
+ NodesStartOffset);
+
+ while (NodeCount-- != 0) {
+ // Populate the node header
+ NcNode->Node.Type = EFI_ACPI_IORT_TYPE_NAMED_COMP;
+ NcNode->Node.Length =
+ GetNamedComponentNodeSize (NodeList);
+ NcNode->Node.Revision = 2;
+ NcNode->Node.Reserved = EFI_ACPI_RESERVED_DWORD;
+ NcNode->Node.NumIdMappings = NodeList->IdMappingCount;
+
+ ObjectNameLenght = AsciiStrLen (NodeList->ObjectName) + 1;
+ NcNode->Node.IdReference =
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE) +
+ (ALIGN_VALUE (ObjectNameLenght, 4));
+
+ // Named Component specific data
+ NcNode->Flags = NodeList->Flags;
+ NcNode->CacheCoherent = NodeList->CacheCoherent;
+ NcNode->AllocationHints = NodeList->AllocationHints;
+ NcNode->Reserved = EFI_ACPI_RESERVED_WORD;
+ NcNode->MemoryAccessFlags = NodeList->MemoryAccessFlags;
+ NcNode->AddressSizeLimit = NodeList->AddressSizeLimit;
+
+ // Copy the object name
+ ObjectName = (CHAR8*)((UINT8*)NcNode +
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE));
+ Status = AsciiStrCpyS (
+ ObjectName,
+ ObjectNameLenght,
+ NodeList->ObjectName
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to copy Object Name. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ if ((NodeList->IdMappingCount > 0) &&
+ (NodeList->IdMappingToken != CM_NULL_TOKEN)) {
+ // Ids for Named Component
+ IdMapArray = (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)NcNode +
+ NcNode->Node.IdReference);
+
+ Status = AddIdMappingArray (
+ This,
+ CfgMgrProtocol,
+ IdMapArray,
+ NodeList->IdMappingCount,
+ NodeList->IdMappingToken
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add Id Mapping Array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+ }
+
+ // Next Named Component Node
+ NcNode = (EFI_ACPI_6_0_IO_REMAPPING_NAMED_COMP_NODE*)((UINT8*)NcNode +
+ NcNode->Node.Length);
+ NodeList++;
+ } // Named Component Node
+
+ return EFI_SUCCESS;
+}
+
+/** Update the Root Complex Node Information.
+
+ This function updates the Root Complex node information in the IORT table.
+
+ @param [in] This Pointer to the table Generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Iort Pointer to IORT table structure.
+ @param [in] NodesStartOffset Offset for the start of the Root Complex
+ Nodes.
+ @param [in] NodeList Pointer to an array of Root Complex Node
+ Objects.
+ @param [in] NodeCount Number of Root Complex Node Objects.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+**/
+STATIC
+EFI_STATUS
+AddRootComplexNodes (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort,
+ IN CONST UINT32 NodesStartOffset,
+ IN CONST CM_ARM_ROOT_COMPLEX_NODE * NodeList,
+ IN UINT32 NodeCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_6_0_IO_REMAPPING_RC_NODE * RcNode;
+ EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray;
+
+ ASSERT (Iort != NULL);
+
+ RcNode = (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE*)((UINT8*)Iort +
+ NodesStartOffset);
+
+ while (NodeCount-- != 0) {
+ // Populate the node header
+ RcNode->Node.Type = EFI_ACPI_IORT_TYPE_ROOT_COMPLEX;
+ RcNode->Node.Length = GetRootComplexNodeSize (NodeList);
+ RcNode->Node.Revision = 1;
+ RcNode->Node.Reserved = EFI_ACPI_RESERVED_DWORD;
+ RcNode->Node.NumIdMappings = NodeList->IdMappingCount;
+ RcNode->Node.IdReference = sizeof (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE);
+
+ // Root Complex specific data
+ RcNode->CacheCoherent = NodeList->CacheCoherent;
+ RcNode->AllocationHints = NodeList->AllocationHints;
+ RcNode->Reserved = EFI_ACPI_RESERVED_WORD;
+ RcNode->MemoryAccessFlags = NodeList->MemoryAccessFlags;
+ RcNode->AtsAttribute = NodeList->AtsAttribute;
+ RcNode->PciSegmentNumber = NodeList->PciSegmentNumber;
+ RcNode->MemoryAddressSize = NodeList->MemoryAddressSize;
+ RcNode->Reserved1[0] = EFI_ACPI_RESERVED_BYTE;
+ RcNode->Reserved1[1] = EFI_ACPI_RESERVED_BYTE;
+ RcNode->Reserved1[2] = EFI_ACPI_RESERVED_BYTE;
+
+ if ((NodeList->IdMappingCount > 0) &&
+ (NodeList->IdMappingToken != CM_NULL_TOKEN)) {
+ // Ids for Root Complex
+ IdMapArray = (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)RcNode +
+ RcNode->Node.IdReference);
+ Status = AddIdMappingArray (
+ This,
+ CfgMgrProtocol,
+ IdMapArray,
+ NodeList->IdMappingCount,
+ NodeList->IdMappingToken
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add Id Mapping Array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+ }
+
+ // Next Root Complex Node
+ RcNode = (EFI_ACPI_6_0_IO_REMAPPING_RC_NODE*)((UINT8*)RcNode +
+ RcNode->Node.Length);
+ NodeList++;
+ } // Root Complex Node
+
+ return EFI_SUCCESS;
+}
+
+/** Update the SMMU Interrupt Array.
+
+ This function retrieves the InterruptArray object referenced by the
+ InterruptToken and updates the SMMU InterruptArray.
+
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] InterruptArray Pointer to an array of Interrupts.
+ @param [in] InterruptCount Number of entries in the InterruptArray.
+ @param [in] InterruptToken Reference Token for retrieving the SMMU
+ InterruptArray object.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+**/
+STATIC
+EFI_STATUS
+AddSmmuInterrruptArray (
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT * InterruptArray,
+ IN UINT32 InterruptCount,
+ IN CONST CM_OBJECT_TOKEN InterruptToken
+ )
+{
+ EFI_STATUS Status;
+ CM_ARM_SMMU_INTERRUPT * SmmuInterrupt;
+ UINT32 SmmuInterruptCount;
+
+ ASSERT (InterruptArray != NULL);
+
+ // Get the SMMU Interrupt Array
+ Status = GetEArmObjSmmuInterruptArray (
+ CfgMgrProtocol,
+ InterruptToken,
+ &SmmuInterrupt,
+ &SmmuInterruptCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get SMMU Interrupt array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ if (SmmuInterruptCount < InterruptCount) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get the required number of SMMU Interrupts.\n"
+ ));
+ return EFI_NOT_FOUND;
+ }
+
+ // Populate the Id Mapping array
+ while (InterruptCount-- != 0) {
+ InterruptArray->Interrupt = SmmuInterrupt->Interrupt;
+ InterruptArray->InterruptFlags = SmmuInterrupt->Flags;
+ InterruptArray++;
+ SmmuInterrupt++;
+ } // Id Mapping array
+
+ return EFI_SUCCESS;
+}
+
+/** Update the SMMU v1/v2 Node Information.
+
+ @param [in] This Pointer to the table Generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Iort Pointer to IORT table structure.
+ @param [in] NodesStartOffset Offset for the start of the SMMU v1/v2
+ Nodes.
+ @param [in] NodeList Pointer to an array of SMMU v1/v2 Node
+ Objects.
+ @param [in] NodeCount Number of SMMU v1/v2 Node Objects.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+**/
+STATIC
+EFI_STATUS
+AddSmmuV1V2Nodes (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort,
+ IN CONST UINT32 NodesStartOffset,
+ IN CONST CM_ARM_SMMUV1_SMMUV2_NODE * NodeList,
+ IN UINT32 NodeCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE * SmmuNode;
+ EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray;
+
+ EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT * ContextInterruptArray;
+ EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT * PmuInterruptArray;
+
+ ASSERT (Iort != NULL);
+
+ SmmuNode = (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE*)((UINT8*)Iort +
+ NodesStartOffset);
+
+ while (NodeCount-- != 0) {
+ // Populate the node header
+ SmmuNode->Node.Type = EFI_ACPI_IORT_TYPE_SMMUv1v2;
+ SmmuNode->Node.Length = GetSmmuV1V2NodeSize (NodeList);
+ SmmuNode->Node.Revision = 0;
+ SmmuNode->Node.Reserved = EFI_ACPI_RESERVED_DWORD;
+ SmmuNode->Node.NumIdMappings = NodeList->IdMappingCount;
+ SmmuNode->Node.IdReference = sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE) +
+ (NodeList->ContextInterruptCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT)) +
+ (NodeList->PmuInterruptCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT));
+
+ // SMMU v1/v2 specific data
+ SmmuNode->Base = NodeList->BaseAddress;
+ SmmuNode->Span = NodeList->Span;
+ SmmuNode->Model = NodeList->Model;
+ SmmuNode->Flags = NodeList->Flags;
+
+ // Reference to Global Interrupt Array
+ SmmuNode->GlobalInterruptArrayRef =
+ OFFSET_OF (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE, SMMU_NSgIrpt);
+
+ // Context Interrupt
+ SmmuNode->NumContextInterrupts = NodeList->ContextInterruptCount;
+ SmmuNode->ContextInterruptArrayRef =
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE);
+ ContextInterruptArray =
+ (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT*)((UINT8*)SmmuNode +
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE));
+
+ // PMU Interrupt
+ SmmuNode->NumPmuInterrupts = NodeList->PmuInterruptCount;
+ SmmuNode->PmuInterruptArrayRef = SmmuNode->ContextInterruptArrayRef +
+ (NodeList->ContextInterruptCount *
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT));
+ PmuInterruptArray =
+ (EFI_ACPI_6_0_IO_REMAPPING_SMMU_INT*)((UINT8*)SmmuNode +
+ SmmuNode->PmuInterruptArrayRef);
+
+ SmmuNode->SMMU_NSgIrpt = NodeList->SMMU_NSgIrpt;
+ SmmuNode->SMMU_NSgIrptFlags = NodeList->SMMU_NSgIrptFlags;
+ SmmuNode->SMMU_NSgCfgIrpt = NodeList->SMMU_NSgCfgIrpt;
+ SmmuNode->SMMU_NSgCfgIrptFlags = NodeList->SMMU_NSgCfgIrptFlags;
+
+ // Add Context Interrupt Array
+ Status = AddSmmuInterrruptArray (
+ CfgMgrProtocol,
+ ContextInterruptArray,
+ SmmuNode->NumContextInterrupts,
+ NodeList->ContextInterruptToken
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to Context Interrupt Array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+
+ // Add PMU Interrupt Array
+ if ((SmmuNode->NumPmuInterrupts > 0) &&
+ (NodeList->PmuInterruptToken != CM_NULL_TOKEN)) {
+ Status = AddSmmuInterrruptArray (
+ CfgMgrProtocol,
+ PmuInterruptArray,
+ SmmuNode->NumPmuInterrupts,
+ NodeList->PmuInterruptToken
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to PMU Interrupt Array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+ }
+
+ if ((NodeList->IdMappingCount > 0) &&
+ (NodeList->IdMappingToken != CM_NULL_TOKEN)) {
+ // Ids for SMMU v1/v2 Node
+ IdMapArray = (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)SmmuNode +
+ SmmuNode->Node.IdReference);
+ Status = AddIdMappingArray (
+ This,
+ CfgMgrProtocol,
+ IdMapArray,
+ NodeList->IdMappingCount,
+ NodeList->IdMappingToken
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add Id Mapping Array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+ }
+ // Next SMMU v1/v2 Node
+ SmmuNode = (EFI_ACPI_6_0_IO_REMAPPING_SMMU_NODE*)((UINT8*)SmmuNode +
+ SmmuNode->Node.Length);
+ NodeList++;
+ } // SMMU v1/v2 Node
+
+ return EFI_SUCCESS;
+}
+
+/** Update the SMMUv3 Node Information.
+
+ This function updates the SMMUv3 node information in the IORT table.
+
+ @param [in] This Pointer to the table Generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Iort Pointer to IORT table structure.
+ @param [in] NodesStartOffset Offset for the start of the SMMUv3 Nodes.
+ @param [in] NodeList Pointer to an array of SMMUv3 Node Objects.
+ @param [in] NodeCount Number of SMMUv3 Node Objects.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+**/
+STATIC
+EFI_STATUS
+AddSmmuV3Nodes (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort,
+ IN CONST UINT32 NodesStartOffset,
+ IN CONST CM_ARM_SMMUV3_NODE * NodeList,
+ IN UINT32 NodeCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE * SmmuV3Node;
+ EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray;
+
+ ASSERT (Iort != NULL);
+
+ SmmuV3Node = (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE*)((UINT8*)Iort +
+ NodesStartOffset);
+
+ while (NodeCount-- != 0) {
+ // Populate the node header
+ SmmuV3Node->Node.Type = EFI_ACPI_IORT_TYPE_SMMUv3;
+ SmmuV3Node->Node.Length = GetSmmuV3NodeSize (NodeList);
+ SmmuV3Node->Node.Revision = 2;
+ SmmuV3Node->Node.Reserved = EFI_ACPI_RESERVED_DWORD;
+ SmmuV3Node->Node.NumIdMappings = NodeList->IdMappingCount;
+ SmmuV3Node->Node.IdReference =
+ sizeof (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE);
+
+ // SMMUv3 specific data
+ SmmuV3Node->Base = NodeList->BaseAddress;
+ SmmuV3Node->Flags = NodeList->Flags;
+ SmmuV3Node->Reserved = EFI_ACPI_RESERVED_WORD;
+ SmmuV3Node->VatosAddress = NodeList->VatosAddress;
+ SmmuV3Node->Model = NodeList->Model;
+ SmmuV3Node->Event = NodeList->EventInterrupt;
+ SmmuV3Node->Pri = NodeList->PriInterrupt;
+ SmmuV3Node->Gerr = NodeList->GerrInterrupt;
+ SmmuV3Node->Sync = NodeList->SyncInterrupt;
+
+ if ((SmmuV3Node->Flags & EFI_ACPI_IORT_SMMUv3_FLAG_PROXIMITY_DOMAIN) != 0) {
+ // The Proximity Domain Valid flag is set to 1
+ SmmuV3Node->ProximityDomain = NodeList->ProximityDomain;
+ } else {
+ SmmuV3Node->ProximityDomain = 0;
+ }
+
+ if ((SmmuV3Node->Event != 0) && (SmmuV3Node->Pri != 0) &&
+ (SmmuV3Node->Gerr != 0) && (SmmuV3Node->Sync != 0)) {
+ // If all the SMMU control interrupts are GSIV based,
+ // the DeviceID mapping index field is ignored.
+ SmmuV3Node->DeviceIdMappingIndex = 0;
+ } else {
+ SmmuV3Node->DeviceIdMappingIndex = NodeList->DeviceIdMappingIndex;
+ }
+
+ if ((NodeList->IdMappingCount > 0) &&
+ (NodeList->IdMappingToken != CM_NULL_TOKEN)) {
+ // Ids for SMMUv3 node
+ IdMapArray = (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)SmmuV3Node +
+ SmmuV3Node->Node.IdReference);
+ Status = AddIdMappingArray (
+ This,
+ CfgMgrProtocol,
+ IdMapArray,
+ NodeList->IdMappingCount,
+ NodeList->IdMappingToken
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add Id Mapping Array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+ }
+
+ // Next SMMUv3 Node
+ SmmuV3Node = (EFI_ACPI_6_0_IO_REMAPPING_SMMU3_NODE*)((UINT8*)SmmuV3Node +
+ SmmuV3Node->Node.Length);
+ NodeList++;
+ } // SMMUv3 Node
+
+ return EFI_SUCCESS;
+}
+
+/** Update the PMCG Node Information.
+
+ This function updates the PMCG node information in the IORT table.
+
+ @param [in] This Pointer to the table Generator.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in] Iort Pointer to IORT table structure.
+ @param [in] NodesStartOffset Offset for the start of the PMCG Nodes.
+ @param [in] NodeList Pointer to an array of PMCG Node Objects.
+ @param [in] NodeCount Number of PMCG Node Objects.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+**/
+STATIC
+EFI_STATUS
+AddPmcgNodes (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN CONST EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort,
+ IN CONST UINT32 NodesStartOffset,
+ IN CONST CM_ARM_PMCG_NODE * NodeList,
+ IN UINT32 NodeCount
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE * PmcgNode;
+ EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE * IdMapArray;
+ ACPI_IORT_GENERATOR * Generator;
+
+ ASSERT (Iort != NULL);
+
+ Generator = (ACPI_IORT_GENERATOR*)This;
+ PmcgNode = (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE*)((UINT8*)Iort +
+ NodesStartOffset);
+
+ while (NodeCount-- != 0) {
+ // Populate the node header
+ PmcgNode->Node.Type = EFI_ACPI_IORT_TYPE_PMCG;
+ PmcgNode->Node.Length = GetPmcgNodeSize (NodeList);
+ PmcgNode->Node.Revision = 1;
+ PmcgNode->Node.Reserved = EFI_ACPI_RESERVED_DWORD;
+ PmcgNode->Node.NumIdMappings = NodeList->IdMappingCount;
+ PmcgNode->Node.IdReference = sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE);
+
+ // PMCG specific data
+ PmcgNode->Base = NodeList->BaseAddress;
+ PmcgNode->OverflowInterruptGsiv = NodeList->OverflowInterrupt;
+ PmcgNode->Page1Base = NodeList->Page1BaseAddress;
+
+ Status = GetNodeOffsetReferencedByToken (
+ Generator->NodeIndexer,
+ Generator->IortNodeCount,
+ NodeList->ReferenceToken,
+ &PmcgNode->NodeReference
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get Output Reference for PMCG Node."
+ "Reference Token = %p"
+ " Status = %r\n",
+ NodeList->ReferenceToken,
+ Status
+ ));
+ return Status;
+ }
+
+ if ((NodeList->IdMappingCount > 0) &&
+ (NodeList->IdMappingToken != CM_NULL_TOKEN)) {
+ // Ids for PMCG node
+ IdMapArray = (EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE*)((UINT8*)PmcgNode +
+ PmcgNode->Node.IdReference);
+
+ Status = AddIdMappingArray (
+ This,
+ CfgMgrProtocol,
+ IdMapArray,
+ NodeList->IdMappingCount,
+ NodeList->IdMappingToken
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add Id Mapping Array. Status = %r\n",
+ Status
+ ));
+ return Status;
+ }
+ }
+
+ // Next PMCG Node
+ PmcgNode = (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE*)((UINT8*)PmcgNode +
+ PmcgNode->Node.Length);
+ NodeList++;
+ } // PMCG Node
+
+ return EFI_SUCCESS;
+}
+
+/** Construct the IORT ACPI table.
+
+ This function invokes the Configuration Manager protocol interface
+ to get the required hardware information for generating the ACPI
+ table.
+
+ If this function allocates any resources then they must be freed
+ in the FreeXXXXTableResources function.
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [out] Table Pointer to the constructed ACPI Table.
+
+ @retval EFI_SUCCESS Table generated successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The required object was not found.
+ @retval EFI_BAD_BUFFER_SIZE The size returned by the Configuration
+ Manager is less than the Object size for the
+ requested object.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildIortTable (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TableSize;
+ UINT32 IortNodeCount;
+
+ UINT32 ItsGroupNodeCount;
+ UINT32 NamedComponentNodeCount;
+ UINT32 RootComplexNodeCount;
+ UINT32 SmmuV1V2NodeCount;
+ UINT32 SmmuV3NodeCount;
+ UINT32 PmcgNodeCount;
+
+ UINT32 ItsGroupOffset;
+ UINT32 NamedComponentOffset;
+ UINT32 RootComplexOffset;
+ UINT32 SmmuV1V2Offset;
+ UINT32 SmmuV3Offset;
+ UINT32 PmcgOffset;
+
+ CM_ARM_ITS_GROUP_NODE * ItsGroupNodeList;
+ CM_ARM_NAMED_COMPONENT_NODE * NamedComponentNodeList;
+ CM_ARM_ROOT_COMPLEX_NODE * RootComplexNodeList;
+ CM_ARM_SMMUV1_SMMUV2_NODE * SmmuV1V2NodeList;
+ CM_ARM_SMMUV3_NODE * SmmuV3NodeList;
+ CM_ARM_PMCG_NODE * PmcgNodeList;
+
+ EFI_ACPI_6_0_IO_REMAPPING_TABLE * Iort;
+ IORT_NODE_INDEXER * NodeIndexer;
+ ACPI_IORT_GENERATOR * Generator;
+
+ ASSERT (This != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (Table != NULL);
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+ Generator = (ACPI_IORT_GENERATOR*)This;
+ *Table = NULL;
+
+ // Get the ITS group node info
+ Status = GetEArmObjItsGroup (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &ItsGroupNodeList,
+ &ItsGroupNodeCount
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get ITS Group Node Info. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ // Add the ITS group node count
+ IortNodeCount = ItsGroupNodeCount;
+
+ // Get the Named component node info
+ Status = GetEArmObjNamedComponent (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &NamedComponentNodeList,
+ &NamedComponentNodeCount
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get Named Component Node Info. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ // Add the Named Component group count
+ IortNodeCount += NamedComponentNodeCount;
+
+ // Get the Root complex node info
+ Status = GetEArmObjRootComplex (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &RootComplexNodeList,
+ &RootComplexNodeCount
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get Root Complex Node Info. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ // Add the Root Complex node count
+ IortNodeCount += RootComplexNodeCount;
+
+ // Get the SMMU v1/v2 node info
+ Status = GetEArmObjSmmuV1SmmuV2 (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &SmmuV1V2NodeList,
+ &SmmuV1V2NodeCount
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get SMMUv1/SMMUv2 Node Info. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ // Add the SMMU v1/v2 node count
+ IortNodeCount += SmmuV1V2NodeCount;
+
+ // Get the SMMUv3 node info
+ Status = GetEArmObjSmmuV3 (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &SmmuV3NodeList,
+ &SmmuV3NodeCount
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get SMMUv3 Node Info. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ // Add the SMMUv3 node count
+ IortNodeCount += SmmuV3NodeCount;
+
+ // Get the PMCG node info
+ Status = GetEArmObjPmcg (
+ CfgMgrProtocol,
+ CM_NULL_TOKEN,
+ &PmcgNodeList,
+ &PmcgNodeCount
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to get PMCG Node Info. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ // Add the PMCG node count
+ IortNodeCount += PmcgNodeCount;
+
+ // Allocate Node Indexer array
+ NodeIndexer = (IORT_NODE_INDEXER*)AllocateZeroPool (
+ (sizeof (IORT_NODE_INDEXER) *
+ IortNodeCount)
+ );
+ if (NodeIndexer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to allocate memory for Node Indexer" \
+ " Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ DEBUG ((DEBUG_INFO, "INFO: NodeIndexer = %p\n", NodeIndexer));
+ Generator->IortNodeCount = IortNodeCount;
+ Generator->NodeIndexer = NodeIndexer;
+
+ // Calculate the size of the IORT table
+ TableSize = sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE);
+
+ // ITS Group Nodes
+ if (ItsGroupNodeCount > 0) {
+ ItsGroupOffset = TableSize;
+ // Size of ITS Group node list.
+ TableSize += GetSizeofItsGroupNodes (
+ ItsGroupOffset,
+ ItsGroupNodeList,
+ ItsGroupNodeCount,
+ &NodeIndexer
+ );
+ }
+
+ // Named Component Nodes
+ if (NamedComponentNodeCount > 0) {
+ NamedComponentOffset = TableSize;
+ // Size of Named Component node list.
+ TableSize += GetSizeofNamedComponentNodes (
+ NamedComponentOffset,
+ NamedComponentNodeList,
+ NamedComponentNodeCount,
+ &NodeIndexer
+ );
+ }
+
+ // Root Complex Nodes
+ if (RootComplexNodeCount > 0) {
+ RootComplexOffset = TableSize;
+ // Size of Root Complex node list.
+ TableSize += GetSizeofRootComplexNodes (
+ RootComplexOffset,
+ RootComplexNodeList,
+ RootComplexNodeCount,
+ &NodeIndexer
+ );
+ }
+
+ // SMMUv1/SMMUv2 Nodes
+ if (SmmuV1V2NodeCount > 0) {
+ SmmuV1V2Offset = TableSize;
+ // Size of SMMUv1/SMMUv2 node list.
+ TableSize += GetSizeofSmmuV1V2Nodes (
+ SmmuV1V2Offset,
+ SmmuV1V2NodeList,
+ SmmuV1V2NodeCount,
+ &NodeIndexer
+ );
+ }
+
+ // SMMUv3 Nodes
+ if (SmmuV3NodeCount > 0) {
+ SmmuV3Offset = TableSize;
+ // Size of SMMUv3 node list.
+ TableSize += GetSizeofSmmuV3Nodes (
+ SmmuV3Offset,
+ SmmuV3NodeList,
+ SmmuV3NodeCount,
+ &NodeIndexer
+ );
+ }
+
+ // PMCG Nodes
+ if (PmcgNodeCount > 0) {
+ PmcgOffset = TableSize;
+ // Size of PMCG node list.
+ TableSize += GetSizeofPmcgNodes (
+ PmcgOffset,
+ PmcgNodeList,
+ PmcgNodeCount,
+ &NodeIndexer
+ );
+ }
+
+ DEBUG ((
+ DEBUG_INFO,
+ "INFO: IORT:\n" \
+ " IortNodeCount = %d\n" \
+ " TableSize = %d\n",
+ IortNodeCount,
+ TableSize
+ ));
+
+ DEBUG ((
+ DEBUG_INFO,
+ " ItsGroupNodeCount = %d\n" \
+ " ItsGroupOffset = %d\n",
+ ItsGroupNodeCount,
+ ItsGroupOffset
+ ));
+
+ DEBUG ((
+ DEBUG_INFO,
+ " NamedComponentNodeCount = %d\n" \
+ " NamedComponentOffset = %d\n",
+ NamedComponentNodeCount,
+ NamedComponentOffset
+ ));
+
+ DEBUG ((
+ DEBUG_INFO,
+ " RootComplexNodeCount = %d\n" \
+ " RootComplexOffset = %d\n",
+ RootComplexNodeCount,
+ RootComplexOffset
+ ));
+
+ DEBUG ((
+ DEBUG_INFO,
+ " SmmuV1V2NodeCount = %d\n" \
+ " SmmuV1V2Offset = %d\n",
+ SmmuV1V2NodeCount,
+ SmmuV1V2Offset
+ ));
+
+ DEBUG ((
+ DEBUG_INFO,
+ " SmmuV3NodeCount = %d\n" \
+ " SmmuV3Offset = %d\n",
+ SmmuV3NodeCount,
+ SmmuV3Offset
+ ));
+
+ DEBUG ((
+ DEBUG_INFO,
+ " PmcgNodeCount = %d\n" \
+ " PmcgOffset = %d\n",
+ PmcgNodeCount,
+ PmcgOffset
+ ));
+
+ // Allocate the Buffer for IORT table
+ *Table = (EFI_ACPI_DESCRIPTION_HEADER*)AllocateZeroPool (TableSize);
+ if (*Table == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to allocate memory for IORT Table, Size = %d," \
+ " Status = %r\n",
+ TableSize,
+ Status
+ ));
+ goto error_handler;
+ }
+
+ Iort = (EFI_ACPI_6_0_IO_REMAPPING_TABLE*)*Table;
+
+ DEBUG ((
+ DEBUG_INFO,
+ "IORT: Iort = 0x%p TableSize = 0x%x\n",
+ Iort,
+ TableSize
+ ));
+
+ Status = AddAcpiHeader (CfgMgrProtocol, This, &Iort->Header, TableSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add ACPI header. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+
+ // Update IORT table
+ Iort->NumNodes = IortNodeCount;
+ Iort->NodeOffset = sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE);
+ Iort->Reserved = EFI_ACPI_RESERVED_DWORD;
+
+ if (ItsGroupNodeCount > 0) {
+ Status = AddItsGroupNodes (
+ This,
+ CfgMgrProtocol,
+ Iort,
+ ItsGroupOffset,
+ ItsGroupNodeList,
+ ItsGroupNodeCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add ITS Group Node. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+ }
+
+ if (NamedComponentNodeCount > 0) {
+ Status = AddNamedComponentNodes (
+ This,
+ CfgMgrProtocol,
+ Iort,
+ NamedComponentOffset,
+ NamedComponentNodeList,
+ NamedComponentNodeCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add Named Component Node. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+ }
+
+ if (RootComplexNodeCount > 0) {
+ Status = AddRootComplexNodes (
+ This,
+ CfgMgrProtocol,
+ Iort,
+ RootComplexOffset,
+ RootComplexNodeList,
+ RootComplexNodeCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add Root Complex Node. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+ }
+
+ if (SmmuV1V2NodeCount > 0) {
+ Status = AddSmmuV1V2Nodes (
+ This,
+ CfgMgrProtocol,
+ Iort,
+ SmmuV1V2Offset,
+ SmmuV1V2NodeList,
+ SmmuV1V2NodeCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add SMMU v1/v2 Node. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+ }
+
+ if (SmmuV3NodeCount > 0) {
+ Status = AddSmmuV3Nodes (
+ This,
+ CfgMgrProtocol,
+ Iort,
+ SmmuV3Offset,
+ SmmuV3NodeList,
+ SmmuV3NodeCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add SMMUv3 Node. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+ }
+
+ if (PmcgNodeCount > 0) {
+ Status = AddPmcgNodes (
+ This,
+ CfgMgrProtocol,
+ Iort,
+ PmcgOffset,
+ PmcgNodeList,
+ PmcgNodeCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "ERROR: IORT: Failed to add SMMUv3 Node. Status = %r\n",
+ Status
+ ));
+ goto error_handler;
+ }
+ }
+
+ return EFI_SUCCESS;
+
+error_handler:
+ if (Generator->NodeIndexer != NULL) {
+ FreePool (Generator->NodeIndexer);
+ Generator->NodeIndexer = NULL;
+ }
+
+ if (*Table != NULL) {
+ FreePool (*Table);
+ *Table = NULL;
+ }
+ return Status;
+}
+
+/** Free any resources allocated for constructing the IORT
+
+ @param [in] This Pointer to the table generator.
+ @param [in] AcpiTableInfo Pointer to the ACPI Table Info.
+ @param [in] CfgMgrProtocol Pointer to the Configuration Manager
+ Protocol Interface.
+ @param [in, out] Table Pointer to the ACPI Table.
+
+ @retval EFI_SUCCESS The resources were freed successfully.
+ @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
+**/
+STATIC
+EFI_STATUS
+FreeIortTableResources (
+ IN CONST ACPI_TABLE_GENERATOR * CONST This,
+ IN CONST CM_STD_OBJ_ACPI_TABLE_INFO * CONST AcpiTableInfo,
+ IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL * CONST CfgMgrProtocol,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER ** CONST Table
+ )
+{
+ ACPI_IORT_GENERATOR * Generator;
+ ASSERT (This != NULL);
+ ASSERT (AcpiTableInfo != NULL);
+ ASSERT (CfgMgrProtocol != NULL);
+ ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+ ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+ Generator = (ACPI_IORT_GENERATOR*)This;
+
+ // Free any memory allocated by the generator
+ if (Generator->NodeIndexer != NULL) {
+ FreePool (Generator->NodeIndexer);
+ Generator->NodeIndexer = NULL;
+ }
+
+ if ((Table == NULL) || (*Table == NULL)) {
+ DEBUG ((DEBUG_ERROR, "ERROR: IORT: Invalid Table Pointer\n"));
+ ASSERT ((Table != NULL) && (*Table != NULL));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FreePool (*Table);
+ *Table = NULL;
+ return EFI_SUCCESS;
+}
+
+/** The IORT Table Generator revision.
+*/
+#define IORT_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the MADT Table Generator.
+*/
+STATIC
+ACPI_IORT_GENERATOR IortGenerator = {
+ // ACPI table generator header
+ {
+ // Generator ID
+ CREATE_STD_ACPI_TABLE_GEN_ID (ESTD_ACPI_TABLE_ID_IORT),
+ // Generator Description
+ L"ACPI.STD.IORT.GENERATOR",
+ // ACPI Table Signature
+ EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE,
+ // ACPI Table Revision
+ EFI_ACPI_IO_REMAPPING_TABLE_REVISION,
+ // Creator ID
+ TABLE_GENERATOR_CREATOR_ID_ARM,
+ // Creator Revision
+ IORT_GENERATOR_REVISION,
+ // Build Table function
+ BuildIortTable,
+ // Free Resource function
+ FreeIortTableResources
+ },
+
+ // IORT Generator private data
+
+ // Iort Node count
+ 0,
+ // Pointer to Iort node indexer
+ NULL
+};
+
+/** Register the Generator with the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The Generator for the Table ID
+ is already registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiIortLibConstructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = RegisterAcpiTableGenerator (&IortGenerator.Header);
+ DEBUG ((DEBUG_INFO, "IORT: Register Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/** Deregister the Generator from the ACPI Table Factory.
+
+ @param [in] ImageHandle The handle to the image.
+ @param [in] SystemTable Pointer to the System Table.
+
+ @retval EFI_SUCCESS The Generator is deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND The Generator is not registered.
+**/
+EFI_STATUS
+EFIAPI
+AcpiIortLibDestructor (
+ IN CONST EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * CONST SystemTable
+ )
+{
+ EFI_STATUS Status;
+ Status = DeregisterAcpiTableGenerator (&IortGenerator.Header);
+ DEBUG ((DEBUG_INFO, "Iort: Deregister Generator. Status = %r\n", Status));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..44c89042e23d50ca7370ee6cae0761e692b78d31
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiIortLibArm/IortGenerator.h
@@ -0,0 +1,50 @@
+/** @file
+
+ Copyright (c) 2018, ARM Limited. All rights reserved.
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Glossary:
+ - Cm or CM - Configuration Manager
+ - Obj or OBJ - Object
+ - Std or STD - Standard
+**/
+
+#ifndef IORT_GENERATOR_H_
+#define IORT_GENERATOR_H_
+
+#pragma pack(1)
+
+/** A structure that describes the Node indexer
+ used for indexing the IORT nodes.
+*/
+typedef struct IortNodeIndexer {
+ /// Index token for the Node
+ CM_OBJECT_TOKEN Token;
+ /// Pointer to the node
+ VOID * Object;
+ /// Node offset from the start of the IORT table
+ UINT32 Offset;
+} IORT_NODE_INDEXER;
+
+typedef struct AcpiIortGenerator {
+ /// ACPI Table generator header
+ ACPI_TABLE_GENERATOR Header;
+
+ // IORT Generator private data
+
+ /// IORT node count
+ UINT32 IortNodeCount;
+ /// Pointer to the node indexer array
+ IORT_NODE_INDEXER * NodeIndexer;
+} ACPI_IORT_GENERATOR;
+
+#pragma pack()
+
+#endif // IORT_GENERATOR_H_
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
^ permalink raw reply related [flat|nested] 23+ messages in thread