public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v1 0/2] Support for dynamic CMN-600 AML generation
@ 2020-09-22 14:08 Sami Mujawar
  2020-09-22 14:08 ` [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags Sami Mujawar
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Sami Mujawar @ 2020-09-22 14:08 UTC (permalink / raw)
  To: devel
  Cc: Sami Mujawar, michael.d.kinney, gaoliming, zhiguang.liu,
	Alexei.Fedorov, pierre.gondois, Matteo.Carlini, Ben.Adderson, nd

The 'Generic ACPI for Arm Components 1.0 Platform Design Document' provides
a standard description for an 'Arm CoreLink CMN-600 Coherent Mesh Network'.

This patch series adds:
  - definition for extended interrupt flags.
  - support for generating SSDT table(s) describing the CMN-600 mesh(es) using
    Dynamic AML. This also demonstrates the use of AML Fixup and AML Codegen
    techniques.

The changes can be seen at:
https://github.com/samimujawar/edk2/tree/1411_cmn600_generator_v1

Pierre Gondois (1):
  DynamicTablesPkg: Add SSDT CMN-600 Table generator

Sami Mujawar (1):
  MdePkg: Definitions for Extended Interrupt Flags

 DynamicTablesPkg/DynamicTables.dsc.inc                                        |   2 +
 DynamicTablesPkg/DynamicTablesPkg.ci.yaml                                     |   4 +
 DynamicTablesPkg/Include/AcpiTableGenerator.h                                 |   5 +
 DynamicTablesPkg/Include/ArmNameSpaceObjects.h                                |  64 +-
 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c  | 701 ++++++++++++++++++++
 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h  |  51 ++
 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf   |  34 +
 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl |  81 +++
 MdePkg/Include/IndustryStandard/Acpi10.h                                      |  85 +++
 9 files changed, 1021 insertions(+), 6 deletions(-)
 create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
 create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h
 create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf
 create mode 100644 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl

-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags
  2020-09-22 14:08 [PATCH v1 0/2] Support for dynamic CMN-600 AML generation Sami Mujawar
@ 2020-09-22 14:08 ` Sami Mujawar
  2020-09-22 15:06   ` [edk2-devel] " Alexei Fedorov
  2020-09-24 22:07   ` Michael D Kinney
  2020-09-22 14:08 ` [PATCH v1 2/2] DynamicTablesPkg: Add SSDT CMN-600 Table generator Sami Mujawar
  2020-09-22 15:05 ` [edk2-devel] [PATCH v1 0/2] Support for dynamic CMN-600 AML generation Alexei Fedorov
  2 siblings, 2 replies; 8+ messages in thread
From: Sami Mujawar @ 2020-09-22 14:08 UTC (permalink / raw)
  To: devel
  Cc: Sami Mujawar, michael.d.kinney, gaoliming, zhiguang.liu,
	Alexei.Fedorov, pierre.gondois, Matteo.Carlini, Ben.Adderson, nd

Add Interrupt Vector Flag definitions for Extended Interrupt
Descriptor, and macros to test the flags.
Ref: ACPI specification 6.4.3.6

Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
 MdePkg/Include/IndustryStandard/Acpi10.h | 85 ++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/MdePkg/Include/IndustryStandard/Acpi10.h b/MdePkg/Include/IndustryStandard/Acpi10.h
index adeb5ae8c219f31d2403fc7aa217bfb4e1e44694..fa3f0694b9cf80bf9c1a325099a970b9cf8c1426 100644
--- a/MdePkg/Include/IndustryStandard/Acpi10.h
+++ b/MdePkg/Include/IndustryStandard/Acpi10.h
@@ -2,6 +2,7 @@
   ACPI 1.0b definitions from the ACPI Specification, revision 1.0b
 
 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 **/
 
@@ -377,6 +378,90 @@ typedef struct {
 #define   EFI_ACPI_MEMORY_NON_WRITABLE                  0x00
 
 //
+// Interrupt Vector Flags definitions for Extended Interrupt Descriptor
+// Ref ACPI specification 6.4.3.6
+//
+#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK   BIT0
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER               0
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_CONSUMER               BIT0
+
+#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK                BIT1
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_LEVEL_TRIGGERED        0
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EDGE_TRIGGERED         BIT1
+
+#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK            BIT2
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_HIGH            0
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_LOW             BIT2
+
+#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK            BIT3
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EXCLUSIVE              0
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARED                 BIT3
+
+#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLITY_MASK      BIT4
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_NOT_WAKE_CAPABLE       0
+#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLE           BIT4
+
+/* Helper macros to test Extended Interrupt Resource descriptor flags.
+*/
+
+/** Test the Extended Interrupt flags to determine if the Device
+    is an Interrupt Consumer or Producer.
+
+  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
+
+  @retval TRUE            Device is Interrupt Consumer.
+  @retval FALSE           Device is Interrupt Producer.
+*/
+#define IS_EXTENDED_INTERRUPT_CONSUMER(Flag)                      \
+  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_CONSUMER) ==        \
+    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_CONSUMER)
+
+/** Test if the Extended Interrupt is Edge or Level triggered.
+
+  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
+
+  @retval TRUE            Interrupt is Edge triggered.
+  @retval FALSE           Interrupt is Level triggered.
+*/
+#define IS_EXTENDED_INTERRUPT_EDGE_TRIGGERED(Flag)                \
+  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EDGE_TRIGGERED) ==  \
+    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EDGE_TRIGGERED)
+
+/** Test if the Extended Interrupt is Active Low or Active High.
+
+  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
+
+  @retval TRUE            Interrupt is Active Low.
+  @retval FALSE           Interrupt is Active High.
+*/
+#define IS_EXTENDED_INTERRUPT_ACTIVE_LOW(Flag)                    \
+  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_LOW) ==      \
+    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_LOW)
+
+/** Test if the Extended Interrupt is Shared or Exclusive.
+
+  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
+
+  @retval TRUE            Interrupt is Shared.
+  @retval FALSE           Interrupt is Exclusive.
+*/
+#define IS_EXTENDED_INTERRUPT_SHARED(Flag)                        \
+  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARED) ==          \
+    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARED)
+
+/** Test the Extended Interrupt flags to determine if the Device
+    is Wake capable or not.
+
+  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
+
+  @retval TRUE            Interrupt is Wake Capable.
+  @retval FALSE           Interrupt is not Wake Capable.
+*/
+#define IS_EXTENDED_INTERRUPT_WAKE_CAPABLE(Flag)                  \
+  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLE) ==    \
+    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLE)
+
+//
 // Ensure proper structure formats
 //
 #pragma pack(1)
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v1 2/2] DynamicTablesPkg: Add SSDT CMN-600 Table generator
  2020-09-22 14:08 [PATCH v1 0/2] Support for dynamic CMN-600 AML generation Sami Mujawar
  2020-09-22 14:08 ` [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags Sami Mujawar
@ 2020-09-22 14:08 ` Sami Mujawar
  2020-09-22 15:06   ` [edk2-devel] " Alexei Fedorov
  2020-09-22 15:05 ` [edk2-devel] [PATCH v1 0/2] Support for dynamic CMN-600 AML generation Alexei Fedorov
  2 siblings, 1 reply; 8+ messages in thread
From: Sami Mujawar @ 2020-09-22 14:08 UTC (permalink / raw)
  To: devel
  Cc: Sami Mujawar, michael.d.kinney, gaoliming, zhiguang.liu,
	Alexei.Fedorov, pierre.gondois, Matteo.Carlini, Ben.Adderson, nd

From: Pierre Gondois <pierre.gondois@arm.com>

The Generic ACPI for Arm Components 1.0 Platform Design
Document, s2.6.4 "ASL code examples" provides information
to describe an Arm CoreLink CMN-600 Coherent Mesh Network
using an ASL definition block table.

The SSDT CMN-600 Table Generator uses the Configuration
Manager protocol to obtain the following information about
the CMN-600 device on the platform:
 - the PERIPHBASE address location and address range;
 - the ROOTNODEBASE address location;
 - the number of Debug and Trace Controller (DTC)
   and their respective interrupt number;

The CMN-600 mesh is described using the CM_ARM_CMN_600_INFO
and CM_ARM_EXTENDED_INTERRUPT structures in the Configuration
Manager.

The SSDT CMN-600 Table generator:
 - gets the CMN-600 hardware information
   from the configuration manager.
 - uses the AmlLib interfaces to parse the AML
   template BLOB and construct an AML tree.
 - uses the AmlLib to update:
   - the "_UID" value;
   - the address location and range of the PERIPHBASE;
   - the address location of the ROOTNODEBASE;
   - the number of Debug and Trace Controller (DTC)
     and their respective interrupt number;
 - serializes the AML tree to an output buffer.
   This output buffer contains the fixed-up AML code,
   which is then installed as an ACPI SSDT table.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
Co-authored-by: Sami Mujawar <sami.mujawar@arm.com>
---
 DynamicTablesPkg/DynamicTables.dsc.inc                                        |   2 +
 DynamicTablesPkg/DynamicTablesPkg.ci.yaml                                     |   4 +
 DynamicTablesPkg/Include/AcpiTableGenerator.h                                 |   5 +
 DynamicTablesPkg/Include/ArmNameSpaceObjects.h                                |  64 +-
 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c  | 701 ++++++++++++++++++++
 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h  |  51 ++
 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf   |  34 +
 DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl |  81 +++
 8 files changed, 936 insertions(+), 6 deletions(-)

diff --git a/DynamicTablesPkg/DynamicTables.dsc.inc b/DynamicTablesPkg/DynamicTables.dsc.inc
index 7fb14d8d1463f7d4502fd3a7708bc94bc336357d..fa33b7ee67e615e236cb13224c859594566df19f 100644
--- a/DynamicTablesPkg/DynamicTables.dsc.inc
+++ b/DynamicTablesPkg/DynamicTables.dsc.inc
@@ -34,6 +34,7 @@ [Components.common]
 
   # AML Fixup
   DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf
+  DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf
 
   #
   # Dynamic Table Factory Dxe
@@ -53,6 +54,7 @@ [Components.common]
 
       # AML Fixup
       NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtSerialPortLibArm/SsdtSerialPortLibArm.inf
+      NULL|DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf
   }
 
   #
diff --git a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
index c0d09e79fdf7f6003b5bbda45abc82a0caf4e53f..52c8c2ab4aefb21bea0289a4fd02209ae937a221 100644
--- a/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
+++ b/DynamicTablesPkg/DynamicTablesPkg.ci.yaml
@@ -70,6 +70,7 @@
                                      # in matching files
         "ExtendWords": [
            "ARMHB",                  # ARMHB000
+           "ARMHC",                  # ARMHC600
            "ARMLTD",
            "EISAID",
            "CCIDX",
@@ -81,8 +82,11 @@
            "lgreater",
            "lless",
            "MPIDR",
+           "PERIPHBASE",
            "pytool",
            "Roadmap",
+           "ROOTNODEBASE",
+           "ssdtcmn",
            "ssdtserialporttemplate",
            "SMMUV",
            "standardised",
diff --git a/DynamicTablesPkg/Include/AcpiTableGenerator.h b/DynamicTablesPkg/Include/AcpiTableGenerator.h
index ef5018c312c1abbc205a06b037ffd6063cf02f0a..352331d6dc957b664d31d55b50efcce5b90d8ada 100644
--- a/DynamicTablesPkg/Include/AcpiTableGenerator.h
+++ b/DynamicTablesPkg/Include/AcpiTableGenerator.h
@@ -59,6 +59,10 @@ The Dynamic Tables Framework implements the following ACPI table generators:
             The SSDT Serial generator collates the Serial port information
             from the Configuration Manager and patches the SSDT Serial Port
             template to build the SSDT Serial port table.
+  - SSDT CMN-600:
+            The SSDT CMN-600 generator collates the CMN-600 information
+            from the Configuration Manager and patches the SSDT CMN-600
+            template to build the SSDT CMN-600 table.
 */
 
 /** The ACPI_TABLE_GENERATOR_ID type describes ACPI table generator ID.
@@ -83,6 +87,7 @@ typedef enum StdAcpiTableId {
   EStdAcpiTableIdPptt,                          ///< PPTT Generator
   EStdAcpiTableIdSrat,                          ///< SRAT Generator
   EStdAcpiTableIdSsdtSerialPort,                ///< SSDT Serial-Port Generator
+  EStdAcpiTableIdSsdtCmn600,                    ///< SSDT Cmn-600 Generator
   EStdAcpiTableIdMax
 } ESTD_ACPI_TABLE_ID;
 
diff --git a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
index b2534a6505d6fb695f0751bbb09d365bd93d092e..f0654866444e5497a010f7e7177199604f5d32b6 100644
--- a/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
+++ b/DynamicTablesPkg/Include/ArmNameSpaceObjects.h
@@ -57,6 +57,7 @@ typedef enum ArmObjectID {
   EArmObjDeviceHandlePci,              ///< 33 - Device Handle Pci
   EArmObjGenericInitiatorAffinityInfo, ///< 34 - Generic Initiator Affinity
   EArmObjSerialPortInfo,               ///< 35 - Generic Serial Port Info
+  EArmObjCmn600Info,                   ///< 36 - CMN-600 Info
   EArmObjMax
 } EARM_OBJECT_ID;
 
@@ -653,18 +654,37 @@ typedef struct CmArmIdMapping {
   UINT32    Flags;
 } CM_ARM_ID_MAPPING;
 
-/** A structure that describes the
-    SMMU interrupts for the Platform.
-
-    ID: EArmObjSmmuInterruptArray
+/** A structure that describes the Arm
+    Generic Interrupts.
 */
-typedef struct CmArmSmmuInterrupt {
+typedef struct CmArmGenericInterrupt {
   /// Interrupt number
   UINT32    Interrupt;
 
   /// Flags
   UINT32    Flags;
-} CM_ARM_SMMU_INTERRUPT;
+} CM_ARM_GENERIC_INTERRUPT;
+
+/** A structure that describes the SMMU interrupts for the Platform.
+
+    Interrupt   Interrupt number.
+    Flags       Interrupt flags as defined for SMMU node.
+
+    ID: EArmObjSmmuInterruptArray
+*/
+typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_SMMU_INTERRUPT;
+
+/** A structure that describes the AML Extended Interrupts.
+
+    Interrupt   Interrupt number.
+    Flags       Interrupt flags as defined by the Interrupt
+                Vector Flags (Byte 3) of the Extended Interrupt
+                resource descriptor.
+                See EFI_ACPI_EXTENDED_INTERRUPT_FLAG_xxx in Acpi10.h
+
+    ID: EArmObjExtendedInterruptInfo
+*/
+typedef CM_ARM_GENERIC_INTERRUPT CM_ARM_EXTENDED_INTERRUPT;
 
 /** A structure that describes the Processor Hierarchy Node (Type 0) in PPTT
 
@@ -825,6 +845,38 @@ typedef struct CmArmGenericInitiatorAffinityInfo {
   CM_OBJECT_TOKEN   DeviceHandleToken;
 } CM_ARM_GENERIC_INITIATOR_AFFINITY_INFO;
 
+/** A structure that describes the CMN-600 hardware.
+
+    ID: EArmObjCmn600Info
+*/
+typedef struct CmArmCmn600Info {
+  /// The PERIPHBASE address.
+  /// Corresponds to the Configuration Node Region (CFGR) base address.
+  UINT64                     PeriphBaseAddress;
+
+  /// The PERIPHBASE address length.
+  /// Corresponds to the CFGR base address length.
+  UINT64                     PeriphBaseAddressLength;
+
+  /// The ROOTNODEBASE address.
+  /// Corresponds to the Root node (ROOT) base address.
+  UINT64                     RootNodeBaseAddress;
+
+  /// The Debug and Trace Logic Controller (DTC) count.
+  /// CMN-600 can have maximum 4 DTCs.
+  UINT8                      DtcCount;
+
+  /// DTC Interrupt list.
+  /// The first interrupt resource descriptor pertains to
+  /// DTC[0], the second to DTC[1] and so on.
+  /// DtcCount determines the number of DTC Interrupts that
+  /// are populated. If DTC count is 2 then DtcInterrupt[2]
+  /// and DtcInterrupt[3] are ignored.
+  /// Note: The size of CM_ARM_CMN_600_INFO structure remains
+  /// constant and does not vary with the DTC count.
+  CM_ARM_EXTENDED_INTERRUPT  DtcInterrupt[4];
+} CM_ARM_CMN_600_INFO;
+
 #pragma pack()
 
 #endif // ARM_NAMESPACE_OBJECTS_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
new file mode 100644
index 0000000000000000000000000000000000000000..a2ff3387a807bad81c4c62b843d797020b677548
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.c
@@ -0,0 +1,701 @@
+/** @file
+  SSDT CMN-600 AML Table Generator.
+
+  Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Reference(s):
+  - Arm CoreLink CMN-600 Coherent Mesh Network Technical Reference Manual r3p0
+  - Generic ACPI for Arm Components 1.0 Platform Design Document
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiTable.h>
+
+// Module specific include files.
+#include <AcpiTableGenerator.h>
+#include <ConfigurationManagerObject.h>
+#include <ConfigurationManagerHelper.h>
+#include <Library/AmlLib/AmlLib.h>
+#include <Library/TableHelperLib.h>
+#include <Protocol/ConfigurationManagerProtocol.h>
+#include "SsdtCmn600Generator.h"
+
+/** C array containing the compiled AML template.
+    This symbol is defined in the auto generated C file
+    containing the AML bytecode array.
+*/
+extern CHAR8  ssdtcmn600template_aml_code[];
+
+/** SSDT CMN-600 Table Generator.
+
+  Requirements:
+  The following Configuration Manager Object(s) are required by
+  this Generator:
+  - EArmObjCmn600Info
+*/
+
+/** This macro expands to a function that retrieves the CMN-600
+    Information from the Configuration Manager.
+*/
+GET_OBJECT_LIST (
+  EObjNameSpaceArm,
+  EArmObjCmn600Info,
+  CM_ARM_CMN_600_INFO
+  );
+
+/** Check the CMN-600 Information.
+
+  @param [in]  Cmn600InfoList           Array of CMN-600 information structure.
+  @param [in]  Cmn600Count              Count of CMN-600 information structure.
+
+  @retval  EFI_SUCCESS            The function completed successfully.
+  @retval  EFI_INVALID_PARAMETER  Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+ValidateCmn600Info (
+  IN  CONST CM_ARM_CMN_600_INFO       * Cmn600InfoList,
+  IN  CONST UINT32                      Cmn600Count
+  )
+{
+  UINT32                            Index;
+  UINT32                            DtcIndex;
+  CONST CM_ARM_CMN_600_INFO       * Cmn600Info;
+  CONST CM_ARM_GENERIC_INTERRUPT  * DtcInterrupt;
+
+  if ((Cmn600InfoList == NULL) ||
+      (Cmn600Count == 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Validate each Cmn600Info structure.
+  for (Index = 0; Index < Cmn600Count; Index++) {
+    Cmn600Info = &Cmn600InfoList[Index];
+
+    // At least one DTC is required.
+    if ((Cmn600Info->DtcCount == 0) ||
+        (Cmn600Info->DtcCount > MAX_DTC_COUNT)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600: Invalid DTC configuration:\n"
+        ));
+      goto error_handler;
+    }
+
+    // Check PERIPHBASE and ROOTNODEBASE address spaces are initialized.
+    if ((Cmn600Info->PeriphBaseAddress == 0)    ||
+        (Cmn600Info->RootNodeBaseAddress == 0)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600: Invalid PERIPHBASE or ROOTNODEBASE.\n"
+        ));
+      goto error_handler;
+    }
+
+    // The PERIPHBASE address must be 64MB aligned for a (X < 4) && (Y < 4)
+    // dimension mesh, and 256MB aligned otherwise.
+    // Check it is a least 64MB aligned.
+    if ((Cmn600Info->PeriphBaseAddress &
+        (PERIPHBASE_MIN_ADDRESS_LENGTH - 1)) != 0) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600: PERIPHBASE address must be 64MB aligned.\n"
+        ));
+      goto error_handler;
+    }
+
+    // The PERIPHBASE address is at most 64MB for a (X < 4) && (Y < 4)
+    // dimension mesh, and 256MB otherwise. Check it is not more than 256MB.
+    if (Cmn600Info->PeriphBaseAddressLength > PERIPHBASE_MAX_ADDRESS_LENGTH) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600: PERIPHBASE address range must be < 256MB.\n"
+        ));
+      goto error_handler;
+    }
+
+    // Check the 16 KB alignment of the ROOTNODEBASE address.
+    if ((Cmn600Info->PeriphBaseAddress &
+        (ROOTNODEBASE_ADDRESS_LENGTH - 1)) != 0) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600: Root base address must be 16KB aligned.\n"
+        ));
+      goto error_handler;
+    }
+
+    // The ROOTNODEBASE address space should be included in the PERIPHBASE
+    // address space.
+    if ((Cmn600Info->PeriphBaseAddress > Cmn600Info->RootNodeBaseAddress)  ||
+        ((Cmn600Info->PeriphBaseAddress + Cmn600Info->PeriphBaseAddressLength) <
+         (Cmn600Info->RootNodeBaseAddress + ROOTNODEBASE_ADDRESS_LENGTH))) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600:"
+        " ROOTNODEBASE address space not in PERIPHBASE address space.\n"
+        ));
+      goto error_handler;
+    }
+
+    for (DtcIndex = 0; DtcIndex < Cmn600Info->DtcCount; DtcIndex++) {
+      DtcInterrupt = &Cmn600Info->DtcInterrupt[DtcIndex];
+      if (!IS_EXTENDED_INTERRUPT_CONSUMER (DtcInterrupt->Flags)) {
+        DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600: DTC Interrupt must be consumer.\n"
+        ));
+        goto error_handler;
+      }
+    } // for DTC Interrupt
+
+  } //for Cmn600InfoList
+
+  return EFI_SUCCESS;
+
+error_handler:
+
+  DEBUG ((
+    DEBUG_ERROR,
+    "PeriphBaseAddress = 0x%llx\n"
+    "PeriphBaseAddressLength = 0x%llx\n"
+    "RootNodeBaseAddress = 0x%llx\n"
+    "DtcCount = %u\n",
+    Cmn600Info->PeriphBaseAddress,
+    Cmn600Info->PeriphBaseAddressLength,
+    Cmn600Info->RootNodeBaseAddress,
+    Cmn600Info->DtcCount
+    ));
+
+  for (DtcIndex = 0; DtcIndex < Cmn600Info->DtcCount; DtcIndex++) {
+    DtcInterrupt = &Cmn600Info->DtcInterrupt[DtcIndex];
+    DEBUG ((
+      DEBUG_ERROR,
+      "  DTC[%d]:\n",
+      DtcIndex
+      ));
+    DEBUG ((
+      DEBUG_ERROR,
+      "    Interrupt = 0x%lx\n",
+      DtcInterrupt->Interrupt
+      ));
+    DEBUG ((
+      DEBUG_ERROR,
+      "    Flags = 0x%lx\n",
+      DtcInterrupt->Flags
+      ));
+  } // for
+
+  return EFI_INVALID_PARAMETER;
+}
+
+/** Build a SSDT table describing the CMN-600 device.
+
+  The table created by this function must be freed by FreeSsdtCmn600Table.
+
+  @param [in]  Cmn600Info       Pointer to a Cmn600 structure.
+  @param [in]  Name             The Name to give to the Device.
+                                Must be a NULL-terminated ASL NameString
+                                e.g.: "DEV0", "DV15.DEV0", etc.
+  @param [in]  Uid              UID for the CMN600 device.
+  @param [out] Table            If success, pointer to the created SSDT table.
+
+  @retval EFI_SUCCESS            Table generated successfully.
+  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
+  @retval EFI_NOT_FOUND          Could not find information.
+  @retval EFI_OUT_OF_RESOURCES   Could not allocate memory.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FixupCmn600Info (
+  IN  CONST CM_ARM_CMN_600_INFO           * Cmn600Info,
+  IN  CONST CHAR8                         * Name,
+  IN  CONST UINT64                          Uid,
+  OUT       EFI_ACPI_DESCRIPTION_HEADER  ** Table
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_STATUS                        Status1;
+  UINT8                             Index;
+  CONST CM_ARM_GENERIC_INTERRUPT  * DtcInt;
+
+  EFI_ACPI_DESCRIPTION_HEADER     * SsdtCmn600Template;
+  AML_ROOT_NODE_HANDLE              RootNodeHandle;
+  AML_OBJECT_NODE_HANDLE            NameOpIdNode;
+  AML_OBJECT_NODE_HANDLE            NameOpCrsNode;
+  AML_DATA_NODE_HANDLE              CmnPeriphBaseRdNode;
+  AML_DATA_NODE_HANDLE              CmnRootNodeBaseRdNode;
+  AML_OBJECT_NODE_HANDLE            DeviceNode;
+
+  // Parse the Ssdt CMN-600 Template.
+  SsdtCmn600Template = (EFI_ACPI_DESCRIPTION_HEADER*)
+                          ssdtcmn600template_aml_code;
+
+  RootNodeHandle = NULL;
+  Status = AmlParseDefinitionBlock (
+             SsdtCmn600Template,
+             &RootNodeHandle
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: SSDT-CMN-600: Failed to parse SSDT CMN-600 Template."
+      " Status = %r\n",
+      Status
+      ));
+    return Status;
+  }
+
+  // Get the _UID NameOp object defined by the "Name ()" statement,
+  // and update its value.
+  Status = AmlFindNode (
+             RootNodeHandle,
+             "\\_SB_.CMN0._UID",
+             &NameOpIdNode
+             );
+  if (EFI_ERROR (Status)) {
+    goto error_handler;
+  }
+
+  Status = AmlNameOpUpdateInteger (NameOpIdNode, (UINT64)Uid);
+  if (EFI_ERROR (Status)) {
+    goto error_handler;
+  }
+
+  // Get the _CRS object defined by the "Name ()" statement.
+  Status = AmlFindNode (
+             RootNodeHandle,
+             "\\_SB.CMN0._CRS",
+             &NameOpCrsNode
+             );
+  if (EFI_ERROR (Status)) {
+    goto error_handler;
+  }
+
+  // Get the first Rd node in the "_CRS" object.
+  // This is the PERIPHBASE node.
+  Status = AmlNameOpCrsGetFirstRdNode (NameOpCrsNode, &CmnPeriphBaseRdNode);
+  if (EFI_ERROR (Status)) {
+    goto error_handler;
+  }
+
+  if (CmnPeriphBaseRdNode == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto error_handler;
+  }
+
+  // Update the PERIPHBASE base address and length.
+  Status = AmlUpdateRdQWord (
+             CmnPeriphBaseRdNode,
+             Cmn600Info->PeriphBaseAddress,
+             Cmn600Info->PeriphBaseAddressLength
+             );
+  if (EFI_ERROR (Status)) {
+    goto error_handler;
+  }
+
+  // Get the QWord node corresponding to the ROOTNODEBASE.
+  // It is the second Resource Data element in the BufferNode's
+  // variable list of arguments.
+  Status = AmlNameOpCrsGetNextRdNode (
+             CmnPeriphBaseRdNode,
+             &CmnRootNodeBaseRdNode
+             );
+  if (EFI_ERROR (Status)) {
+    goto error_handler;
+  }
+
+  if (CmnRootNodeBaseRdNode == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto error_handler;
+  }
+
+  // Update the ROOTNODEBASE base address and length.
+  Status = AmlUpdateRdQWord (
+             CmnRootNodeBaseRdNode,
+             Cmn600Info->RootNodeBaseAddress,
+             ROOTNODEBASE_ADDRESS_LENGTH
+             );
+  if (EFI_ERROR (Status)) {
+    goto error_handler;
+  }
+
+  // Add the Interrupt node(s).
+  // Generate Resource Data node(s) corresponding to the "Interrupt ()"
+  // ASL function and add it at the last position in the list of
+  // Resource Data nodes.
+  for (Index = 0; Index < Cmn600Info->DtcCount; Index++) {
+    DtcInt = &Cmn600Info->DtcInterrupt[Index];
+    Status = AmlCodeGenCrsAddRdInterrupt (
+               NameOpCrsNode,
+               IS_EXTENDED_INTERRUPT_CONSUMER (DtcInt->Flags),
+               IS_EXTENDED_INTERRUPT_EDGE_TRIGGERED (DtcInt->Flags),
+               IS_EXTENDED_INTERRUPT_ACTIVE_LOW (DtcInt->Flags),
+               IS_EXTENDED_INTERRUPT_SHARED (DtcInt->Flags),
+               (UINT32*)&DtcInt->Interrupt,
+               1
+               );
+    if (EFI_ERROR (Status)) {
+      goto error_handler;
+    }
+  } // for
+
+  // Fixup the CMN600 device name.
+  // This MUST be done at the end, otherwise AML paths won't be valid anymore.
+  // Get the CMN0 variable defined by the "Device ()" statement.
+  Status = AmlFindNode (RootNodeHandle, "\\_SB_.CMN0", &DeviceNode);
+  if (EFI_ERROR (Status)) {
+    goto error_handler;
+  }
+
+  // Update the CMN600 Device's name.
+  Status = AmlDeviceOpUpdateName (DeviceNode, (CHAR8*)Name);
+  if (EFI_ERROR (Status)) {
+    goto error_handler;
+  }
+
+  // Serialise the definition block
+  Status = AmlSerializeDefinitionBlock (
+             RootNodeHandle,
+             Table
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: SSDT-CMN-600: Failed to Serialize SSDT Table Data."
+      " Status = %r\n",
+      Status
+      ));
+  }
+
+error_handler:
+  // Cleanup
+  if (RootNodeHandle != NULL) {
+    Status1 = AmlDeleteTree (RootNodeHandle);
+    if (EFI_ERROR (Status1)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600: Failed to cleanup AML tree."
+        " Status = %r\n",
+        Status1
+        ));
+      // If Status was success but we failed to delete the AML Tree
+      // return Status1 else return the original error code, i.e. Status.
+      if (!EFI_ERROR (Status)) {
+        return Status1;
+      }
+    }
+  }
+
+  return Status;
+}
+
+/** Free any resources allocated for constructing the SSDT tables for CMN-600.
+
+  @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 an array of pointers
+                                  to ACPI Table(s).
+  @param [in]      TableCount     Number of ACPI table(s).
+
+  @retval EFI_SUCCESS           The resources were freed successfully.
+  @retval EFI_INVALID_PARAMETER The table pointer is NULL or invalid.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+FreeSsdtCmn600TableResourcesEx (
+  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
+  )
+{
+  EFI_ACPI_DESCRIPTION_HEADER    ** TableList;
+  UINTN                             Index;
+
+  ASSERT (This != NULL);
+  ASSERT (AcpiTableInfo != NULL);
+  ASSERT (CfgMgrProtocol != NULL);
+  ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+  ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+  if ((Table == NULL)   ||
+      (*Table == NULL)  ||
+      (TableCount == 0)) {
+    DEBUG ((DEBUG_ERROR, "ERROR: SSDT-CMN-600: Invalid Table Pointer\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TableList = *Table;
+
+  for (Index = 0; Index < TableCount; Index++) {
+    if ((TableList[Index] != NULL) &&
+        (TableList[Index]->Signature ==
+         EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)) {
+      FreePool (TableList[Index]);
+    } else {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600: Could not free SSDT table at index %d."
+        " Status = %r\n",
+        Index,
+        EFI_INVALID_PARAMETER
+        ));
+      return EFI_INVALID_PARAMETER;
+    }
+  } //for
+
+  // Free the table list.
+  FreePool (*Table);
+  *Table = NULL;
+  return EFI_SUCCESS;
+}
+
+/** Construct SSDT tables for describing CMN-600 meshes.
+
+  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 FreeXXXXTableResourcesEx function.
+
+  @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).
+
+  @retval EFI_SUCCESS            Table generated successfully.
+  @retval EFI_BAD_BUFFER_SIZE    The size returned by the Configuration
+                                 Manager is less than the Object size for
+                                 the requested object.
+  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
+  @retval EFI_NOT_FOUND          Could not find information.
+  @retval EFI_OUT_OF_RESOURCES   Could not allocate memory.
+  @retval EFI_UNSUPPORTED        Unsupported configuration.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+BuildSsdtCmn600TableEx (
+  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
+  )
+{
+  EFI_STATUS                        Status;
+  UINT64                            Index;
+  CM_ARM_CMN_600_INFO             * Cmn600Info;
+  UINT32                            Cmn600Count;
+  CHAR8                             NewName[5];
+  EFI_ACPI_DESCRIPTION_HEADER    ** TableList;
+
+  ASSERT (This != NULL);
+  ASSERT (AcpiTableInfo != NULL);
+  ASSERT (CfgMgrProtocol != NULL);
+  ASSERT (Table != NULL);
+  ASSERT (TableCount != NULL);
+  ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
+  ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);
+
+  *Table = NULL;
+
+  // Get CMN-600 information.
+  Status = GetEArmObjCmn600Info (
+             CfgMgrProtocol,
+             CM_NULL_TOKEN,
+             &Cmn600Info,
+             &Cmn600Count
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: SSDT-CMN-600: Failed to get the CMN-600 information."
+      " Status = %r\n",
+      Status
+      ));
+    return Status;
+  }
+
+  if ((Cmn600Count == 0) || (Cmn600Count > MAX_CMN600_DEVICES_SUPPORTED)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: SSDT-CMN-600: CMN600 peripheral count = %d."
+      " This must be between 1 to 16.\n",
+      Cmn600Count
+      ));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Validate the CMN-600 Info.
+  Status = ValidateCmn600Info (Cmn600Info, Cmn600Count);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: SSDT-CMN-600: Invalid CMN600 information. Status = %r\n",
+      Status
+      ));
+    return Status;
+  }
+
+  // Allocate a table to store pointers to the SSDT tables.
+  TableList = (EFI_ACPI_DESCRIPTION_HEADER**)
+              AllocateZeroPool (
+                (sizeof (EFI_ACPI_DESCRIPTION_HEADER*) * Cmn600Count)
+                );
+  if (TableList == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    DEBUG ((
+      DEBUG_ERROR,
+      "ERROR: SSDT-CMN-600: Failed to allocate memory for Table List."
+      " Status = %r\n",
+      Status
+      ));
+    return Status;
+  }
+
+  // Setup the table list early so that that appropriate cleanup
+  // can be done in case of failure.
+  *Table = TableList;
+
+  NewName[0] = 'C';
+  NewName[1] = 'M';
+  NewName[2] = 'N';
+  NewName[4] = '\0';
+  for (Index = 0; Index < Cmn600Count; Index++) {
+    NewName[3] = AsciiFromHex ((UINT8)(Index));
+
+    // Build a SSDT table describing the CMN600 device.
+    Status = FixupCmn600Info (
+               &Cmn600Info[Index],
+               NewName,
+               Index,
+               &TableList[Index]
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "ERROR: SSDT-CMN-600: Failed to build associated SSDT table."
+        " Status = %r\n",
+        Status
+        ));
+      break;
+    }
+
+    // Increment the table count here so that appropriate clean-up
+    // can be done in case of failure.
+    *TableCount += 1;
+  } // for
+
+  // Note: Table list and CMN600 device count has been setup. The
+  // framework will invoke FreeSsdtCmn600TableResourcesEx() even
+  // on failure, so appropriate clean-up will be done.
+  return Status;
+}
+
+/** This macro defines the Raw Generator revision.
+*/
+#define SSDT_CMN_600_GENERATOR_REVISION CREATE_REVISION (1, 0)
+
+/** The interface for the Raw Table Generator.
+*/
+STATIC
+CONST
+ACPI_TABLE_GENERATOR SsdtCmn600Generator = {
+  // Generator ID
+  CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCmn600),
+  // Generator Description
+  L"ACPI.STD.SSDT.CMN600.GENERATOR",
+  // ACPI Table Signature
+  EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+  // ACPI Table Revision - Unused
+  0,
+  // Minimum ACPI Table Revision - Unused
+  0,
+  // Creator ID
+  TABLE_GENERATOR_CREATOR_ID_ARM,
+  // Creator Revision
+  SSDT_CMN_600_GENERATOR_REVISION,
+  // Build table function. Use the extended version instead.
+  NULL,
+  // Free table function. Use the extended version instead.
+  NULL,
+  // Build Table function
+  BuildSsdtCmn600TableEx,
+  // Free Resource function
+  FreeSsdtCmn600TableResourcesEx
+};
+
+/** 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
+AcpiSsdtCmn600LibConstructor (
+  IN  EFI_HANDLE           ImageHandle,
+  IN  EFI_SYSTEM_TABLE  *  SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = RegisterAcpiTableGenerator (&SsdtCmn600Generator);
+  DEBUG ((
+    DEBUG_INFO,
+    "SSDT-CMN-600: 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
+AcpiSsdtCmn600LibDestructor (
+  IN  EFI_HANDLE           ImageHandle,
+  IN  EFI_SYSTEM_TABLE  *  SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = DeregisterAcpiTableGenerator (&SsdtCmn600Generator);
+  DEBUG ((
+    DEBUG_INFO,
+    "SSDT-CMN-600: Deregister Generator. Status = %r\n",
+    Status
+    ));
+  ASSERT_EFI_ERROR (Status);
+  return Status;
+}
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab03b72236e78c28a5e36452bb5d7e93e957332d
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Generator.h
@@ -0,0 +1,51 @@
+/** @file
+
+  Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+    - Cm or CM   - Configuration Manager
+    - Obj or OBJ - Object
+    - Std or STD - Standard
+
+  @par Reference(s):
+  - Arm CoreLink CMN-600 Coherent Mesh Network Technical Reference Manual r3p0
+  - Generic ACPI for Arm Components 1.0 Platform Design Document
+**/
+
+#ifndef SSDT_CMN600_GENERATOR_H_
+#define SSDT_CMN600_GENERATOR_H_
+
+/** PeriphBase maximum address length is 256MB (0x10000000)
+    for a (X >= 4) || (Y >= 4) dimensions mesh.
+*/
+#define PERIPHBASE_MAX_ADDRESS_LENGTH   SIZE_256MB
+
+/** PeriphBase minimum address length is 64MB (0x04000000)
+    for a (X < 4) && (Y < 4) dimensions mesh.
+*/
+#define PERIPHBASE_MIN_ADDRESS_LENGTH   SIZE_64MB
+
+/** RootNodeBase address length is 16KB (0x00004000).
+*/
+#define ROOTNODEBASE_ADDRESS_LENGTH     SIZE_16KB
+
+/** Maximum number of CMN-600 Debug and Trace Logic Controllers (DTC).
+*/
+#define MAX_DTC_COUNT                   4
+
+/** Starting value for the UID to represent the CMN600 devices.
+*/
+#define CMN600_DEVICE_START_UID         0
+
+/** Maximum CMN-600 devices supported by this generator.
+    This generator supports a maximum of 16 CMN-600 devices.
+    Note: This is not a hard limitation and can be extended if needed.
+          Corresponding changes would be needed to support the Name and
+          UID fields describing the serial port.
+
+*/
+#define MAX_CMN600_DEVICES_SUPPORTED    16
+
+#endif // SSDT_CMN600_GENERATOR_H_
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf
new file mode 100644
index 0000000000000000000000000000000000000000..821c0d531b983e19278062a11317bba83fdc141a
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600LibArm.inf
@@ -0,0 +1,34 @@
+## @file
+# Ssdt CMN-600 Table Generator
+#
+#  Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+  INF_VERSION    = 0x0001001B
+  BASE_NAME      = SsdtCmn600LibArm
+  FILE_GUID      = CEDB450D-8F0E-4ACC-8FB7-F72EC7D216A4
+  VERSION_STRING = 1.0
+  MODULE_TYPE    = DXE_DRIVER
+  LIBRARY_CLASS  = NULL|DXE_DRIVER
+  CONSTRUCTOR    = AcpiSsdtCmn600LibConstructor
+  DESTRUCTOR     = AcpiSsdtCmn600LibDestructor
+
+[Sources]
+  SsdtCmn600Generator.c
+  SsdtCmn600Generator.h
+  SsdtCmn600Template.asl
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  DynamicTablesPkg/DynamicTablesPkg.dec
+
+[LibraryClasses]
+  AmlLib
+  BaseLib
+
diff --git a/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl
new file mode 100644
index 0000000000000000000000000000000000000000..023a89e2ab3d753cb1cdb8c423766294b0ea3fab
--- /dev/null
+++ b/DynamicTablesPkg/Library/Acpi/Arm/AcpiSsdtCmn600LibArm/SsdtCmn600Template.asl
@@ -0,0 +1,81 @@
+/** @file
+  SSDT CMN-600 Template
+
+  Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Reference(s):
+  - Arm CoreLink CMN-600 Coherent Mesh Network Technical Reference Manual r3p0
+  - Generic ACPI for Arm Components 1.0 Platform Design Document
+
+  @par Glossary:
+    - {template} - Data fixed up using AML Fixup APIs.
+    - {codegen}  - Data generated using AML Codegen APIs.
+**/
+
+DefinitionBlock ("SsdtCmn600.aml", "SSDT", 2, "ARMLTD", "CMN-600", 1) {
+  Scope (_SB) {
+    // CMN-600 device object for a X * Y mesh, where (X >= 4) || (Y >= 4).
+    Device (CMN0) {                        // {template}
+      Name (_HID, "ARMHC600")
+      Name (_UID, 0x0)                     // {template}
+
+      Name (_CRS, ResourceTemplate () {
+        // Descriptor for 256 MB of the CFG region at offset PERIPHBASE.
+        QWordMemory (
+          ResourceConsumer,                // bit 0 of general flags is 0.
+          PosDecode,
+          MinFixed,                        // Range is fixed.
+          MaxFixed,                        // Range is Fixed.
+          NonCacheable,
+          ReadWrite,
+          0x00000000,                      // Granularity
+          0xA0000000,                      // MinAddress         // {template}
+          0xAFFFFFFF,                      // MaxAddress         // {template}
+          0x00000000,                      // Translation
+          0x10000000,                      // RangeLength        // {template}
+          ,                                // ResourceSourceIndex
+          ,                                // ResourceSource
+          CFGR                             // DescriptorName
+        ) // QWordMemory
+
+        // Descriptor for the root node. This is a 16 KB region at offset
+        // ROOTNODEBASE. In this example, ROOTNODEBASE starts at the 16 KB
+        // aligned offset of PERIPHBASE.
+        QWordMemory (
+          ResourceConsumer,                // bit 0 of general flags is 0.
+          PosDecode,
+          MinFixed,                        // Range is fixed.
+          MaxFixed,                        // Range is Fixed.
+          NonCacheable,
+          ReadWrite,
+          0x00000000,                      // Granularity
+          0xA0000000,                      // MinAddress         // {template}
+          0xAFFFFFFF,                      // MaxAddress         // {template}
+          0x00000000,                      // Translation
+          0x10000000,                      // RangeLength        // {template}
+          ,                                // ResourceSourceIndex
+          ,                                // ResourceSource
+          ROOT                             // DescriptorName
+        ) // QWordMemory
+
+        // The Interrupt information is generated using AmlCodegen.
+        // Interrupt on PMU0 overflow, attached to DTC [0], with GSIV = <gsiv0>.
+        //
+        // Interrupt (                                            // {codegen}
+        //  ResourceConsumer,                // ResourceUsage
+        //  Level,                           // EdgeLevel
+        //  ActiveHigh,                      // ActiveLevel
+        //  Exclusive,                       // Shared
+        //  ,                                // ResourceSourceIndex
+        //  ,                                // ResourceSource
+        //                                   // DescriptorName
+        //  ) {
+        //    0xA5                           // <gsiv0 >
+        // } // Interrupt
+
+      }) // Name
+    } // Device
+  } // _SB
+} // DefinitionBlock
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [edk2-devel] [PATCH v1 0/2] Support for dynamic CMN-600 AML generation
  2020-09-22 14:08 [PATCH v1 0/2] Support for dynamic CMN-600 AML generation Sami Mujawar
  2020-09-22 14:08 ` [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags Sami Mujawar
  2020-09-22 14:08 ` [PATCH v1 2/2] DynamicTablesPkg: Add SSDT CMN-600 Table generator Sami Mujawar
@ 2020-09-22 15:05 ` Alexei Fedorov
  2 siblings, 0 replies; 8+ messages in thread
From: Alexei Fedorov @ 2020-09-22 15:05 UTC (permalink / raw)
  To: Sami Mujawar, devel

[-- Attachment #1: Type: text/plain, Size: 54 bytes --]

Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com>

[-- Attachment #2: Type: text/html, Size: 60 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [edk2-devel] [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags
  2020-09-22 14:08 ` [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags Sami Mujawar
@ 2020-09-22 15:06   ` Alexei Fedorov
  2020-09-24 22:07   ` Michael D Kinney
  1 sibling, 0 replies; 8+ messages in thread
From: Alexei Fedorov @ 2020-09-22 15:06 UTC (permalink / raw)
  To: Sami Mujawar, devel

[-- Attachment #1: Type: text/plain, Size: 54 bytes --]

Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com>

[-- Attachment #2: Type: text/html, Size: 60 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [edk2-devel] [PATCH v1 2/2] DynamicTablesPkg: Add SSDT CMN-600 Table generator
  2020-09-22 14:08 ` [PATCH v1 2/2] DynamicTablesPkg: Add SSDT CMN-600 Table generator Sami Mujawar
@ 2020-09-22 15:06   ` Alexei Fedorov
  0 siblings, 0 replies; 8+ messages in thread
From: Alexei Fedorov @ 2020-09-22 15:06 UTC (permalink / raw)
  To: Sami Mujawar, devel

[-- Attachment #1: Type: text/plain, Size: 54 bytes --]

Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com>

[-- Attachment #2: Type: text/html, Size: 60 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags
  2020-09-22 14:08 ` [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags Sami Mujawar
  2020-09-22 15:06   ` [edk2-devel] " Alexei Fedorov
@ 2020-09-24 22:07   ` Michael D Kinney
  2020-09-25  7:53     ` Sami Mujawar
  1 sibling, 1 reply; 8+ messages in thread
From: Michael D Kinney @ 2020-09-24 22:07 UTC (permalink / raw)
  To: Sami Mujawar, devel@edk2.groups.io, Kinney, Michael D
  Cc: gaoliming@byosoft.com.cn, Liu, Zhiguang, Alexei.Fedorov@arm.com,
	pierre.gondois@arm.com, Matteo.Carlini@arm.com,
	Ben.Adderson@arm.com, nd@arm.com

Hi Sami,

The set of define values looks more complex than needed for single bit field checks.

Perhaps we can simplify to just defining the bit locations and the IS_ macros check
for 0 or non-zer0 results?

#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK   BIT0
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK                BIT1
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK            BIT2
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK            BIT3
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLITY_MASK      BIT4

#define IS_EXTENDED_INTERRUPT_CONSUMER(Flag)                      \
  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) != 0)

#define IS_EXTENDED_INTERRUPT_EDGE_TRIGGERED(Flag)                \
  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK) != 0)

Are the IS_ macros really required?  I do not see those for other bit
fields in ACPI structs.

Thanks,

Mike

> -----Original Message-----
> From: Sami Mujawar <sami.mujawar@arm.com>
> Sent: Tuesday, September 22, 2020 7:08 AM
> To: devel@edk2.groups.io
> Cc: Sami Mujawar <sami.mujawar@arm.com>; Kinney, Michael D <michael.d.kinney@intel.com>; gaoliming@byosoft.com.cn; Liu, Zhiguang
> <zhiguang.liu@intel.com>; Alexei.Fedorov@arm.com; pierre.gondois@arm.com; Matteo.Carlini@arm.com; Ben.Adderson@arm.com; nd@arm.com
> Subject: [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags
> 
> Add Interrupt Vector Flag definitions for Extended Interrupt
> Descriptor, and macros to test the flags.
> Ref: ACPI specification 6.4.3.6
> 
> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
> ---
>  MdePkg/Include/IndustryStandard/Acpi10.h | 85 ++++++++++++++++++++
>  1 file changed, 85 insertions(+)
> 
> diff --git a/MdePkg/Include/IndustryStandard/Acpi10.h b/MdePkg/Include/IndustryStandard/Acpi10.h
> index adeb5ae8c219f31d2403fc7aa217bfb4e1e44694..fa3f0694b9cf80bf9c1a325099a970b9cf8c1426 100644
> --- a/MdePkg/Include/IndustryStandard/Acpi10.h
> +++ b/MdePkg/Include/IndustryStandard/Acpi10.h
> @@ -2,6 +2,7 @@
>    ACPI 1.0b definitions from the ACPI Specification, revision 1.0b
> 
>  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
>  **/
> 
> @@ -377,6 +378,90 @@ typedef struct {
>  #define   EFI_ACPI_MEMORY_NON_WRITABLE                  0x00
> 
>  //
> +// Interrupt Vector Flags definitions for Extended Interrupt Descriptor
> +// Ref ACPI specification 6.4.3.6
> +//
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK   BIT0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER               0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_CONSUMER               BIT0
> +
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK                BIT1
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_LEVEL_TRIGGERED        0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EDGE_TRIGGERED         BIT1
> +
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK            BIT2
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_HIGH            0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_LOW             BIT2
> +
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK            BIT3
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EXCLUSIVE              0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARED                 BIT3
> +
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLITY_MASK      BIT4
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_NOT_WAKE_CAPABLE       0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLE           BIT4> +
> +/* Helper macros to test Extended Interrupt Resource descriptor flags.
> +*/
> +
> +/** Test the Extended Interrupt flags to determine if the Device
> +    is an Interrupt Consumer or Producer.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Device is Interrupt Consumer.
> +  @retval FALSE           Device is Interrupt Producer.
> +*/
> +#define IS_EXTENDED_INTERRUPT_CONSUMER(Flag)                      \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_CONSUMER) ==        \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_CONSUMER)
> +
> +/** Test if the Extended Interrupt is Edge or Level triggered.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Interrupt is Edge triggered.
> +  @retval FALSE           Interrupt is Level triggered.
> +*/
> +#define IS_EXTENDED_INTERRUPT_EDGE_TRIGGERED(Flag)                \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EDGE_TRIGGERED) ==  \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EDGE_TRIGGERED)> +
> +/** Test if the Extended Interrupt is Active Low or Active High.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Interrupt is Active Low.
> +  @retval FALSE           Interrupt is Active High.
> +*/
> +#define IS_EXTENDED_INTERRUPT_ACTIVE_LOW(Flag)                    \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_LOW) ==      \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_LOW)
> +
> +/** Test if the Extended Interrupt is Shared or Exclusive.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Interrupt is Shared.
> +  @retval FALSE           Interrupt is Exclusive.
> +*/
> +#define IS_EXTENDED_INTERRUPT_SHARED(Flag)                        \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARED) ==          \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARED)
> +
> +/** Test the Extended Interrupt flags to determine if the Device
> +    is Wake capable or not.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Interrupt is Wake Capable.
> +  @retval FALSE           Interrupt is not Wake Capable.
> +*/
> +#define IS_EXTENDED_INTERRUPT_WAKE_CAPABLE(Flag)                  \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLE) ==    \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLE)
> +
> +//
>  // Ensure proper structure formats
>  //
>  #pragma pack(1)
> --
> 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags
  2020-09-24 22:07   ` Michael D Kinney
@ 2020-09-25  7:53     ` Sami Mujawar
  0 siblings, 0 replies; 8+ messages in thread
From: Sami Mujawar @ 2020-09-25  7:53 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: gaoliming@byosoft.com.cn, Liu, Zhiguang, Alexei Fedorov,
	Pierre Gondois, Matteo Carlini, Ben Adderson, nd

Hi Mike,

I will send an updated patch with the suggested changes. I will also drop the IS_xxx macros.

Regards,

Sami Mujawar

-----Original Message-----
From: Kinney, Michael D <michael.d.kinney@intel.com> 
Sent: 24 September 2020 11:07 PM
To: Sami Mujawar <Sami.Mujawar@arm.com>; devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
Cc: gaoliming@byosoft.com.cn; Liu, Zhiguang <zhiguang.liu@intel.com>; Alexei Fedorov <Alexei.Fedorov@arm.com>; Pierre Gondois <Pierre.Gondois@arm.com>; Matteo Carlini <Matteo.Carlini@arm.com>; Ben Adderson <Ben.Adderson@arm.com>; nd <nd@arm.com>
Subject: RE: [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags

Hi Sami,

The set of define values looks more complex than needed for single bit field checks.

Perhaps we can simplify to just defining the bit locations and the IS_ macros check
for 0 or non-zer0 results?

#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK   BIT0
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK                BIT1
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK            BIT2
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK            BIT3
#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLITY_MASK      BIT4

#define IS_EXTENDED_INTERRUPT_CONSUMER(Flag)                      \
  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK) != 0)

#define IS_EXTENDED_INTERRUPT_EDGE_TRIGGERED(Flag)                \
  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK) != 0)

Are the IS_ macros really required?  I do not see those for other bit
fields in ACPI structs.

Thanks,

Mike

> -----Original Message-----
> From: Sami Mujawar <sami.mujawar@arm.com>
> Sent: Tuesday, September 22, 2020 7:08 AM
> To: devel@edk2.groups.io
> Cc: Sami Mujawar <sami.mujawar@arm.com>; Kinney, Michael D <michael.d.kinney@intel.com>; gaoliming@byosoft.com.cn; Liu, Zhiguang
> <zhiguang.liu@intel.com>; Alexei.Fedorov@arm.com; pierre.gondois@arm.com; Matteo.Carlini@arm.com; Ben.Adderson@arm.com; nd@arm.com
> Subject: [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags
> 
> Add Interrupt Vector Flag definitions for Extended Interrupt
> Descriptor, and macros to test the flags.
> Ref: ACPI specification 6.4.3.6
> 
> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
> ---
>  MdePkg/Include/IndustryStandard/Acpi10.h | 85 ++++++++++++++++++++
>  1 file changed, 85 insertions(+)
> 
> diff --git a/MdePkg/Include/IndustryStandard/Acpi10.h b/MdePkg/Include/IndustryStandard/Acpi10.h
> index adeb5ae8c219f31d2403fc7aa217bfb4e1e44694..fa3f0694b9cf80bf9c1a325099a970b9cf8c1426 100644
> --- a/MdePkg/Include/IndustryStandard/Acpi10.h
> +++ b/MdePkg/Include/IndustryStandard/Acpi10.h
> @@ -2,6 +2,7 @@
>    ACPI 1.0b definitions from the ACPI Specification, revision 1.0b
> 
>  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
>  SPDX-License-Identifier: BSD-2-Clause-Patent
>  **/
> 
> @@ -377,6 +378,90 @@ typedef struct {
>  #define   EFI_ACPI_MEMORY_NON_WRITABLE                  0x00
> 
>  //
> +// Interrupt Vector Flags definitions for Extended Interrupt Descriptor
> +// Ref ACPI specification 6.4.3.6
> +//
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER_CONSUMER_MASK   BIT0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_PRODUCER               0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_CONSUMER               BIT0
> +
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_MODE_MASK                BIT1
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_LEVEL_TRIGGERED        0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EDGE_TRIGGERED         BIT1
> +
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_POLARITY_MASK            BIT2
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_HIGH            0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_LOW             BIT2
> +
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARABLE_MASK            BIT3
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EXCLUSIVE              0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARED                 BIT3
> +
> +#define EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLITY_MASK      BIT4
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_NOT_WAKE_CAPABLE       0
> +#define   EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLE           BIT4> +
> +/* Helper macros to test Extended Interrupt Resource descriptor flags.
> +*/
> +
> +/** Test the Extended Interrupt flags to determine if the Device
> +    is an Interrupt Consumer or Producer.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Device is Interrupt Consumer.
> +  @retval FALSE           Device is Interrupt Producer.
> +*/
> +#define IS_EXTENDED_INTERRUPT_CONSUMER(Flag)                      \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_CONSUMER) ==        \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_CONSUMER)
> +
> +/** Test if the Extended Interrupt is Edge or Level triggered.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Interrupt is Edge triggered.
> +  @retval FALSE           Interrupt is Level triggered.
> +*/
> +#define IS_EXTENDED_INTERRUPT_EDGE_TRIGGERED(Flag)                \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EDGE_TRIGGERED) ==  \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_EDGE_TRIGGERED)> +
> +/** Test if the Extended Interrupt is Active Low or Active High.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Interrupt is Active Low.
> +  @retval FALSE           Interrupt is Active High.
> +*/
> +#define IS_EXTENDED_INTERRUPT_ACTIVE_LOW(Flag)                    \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_LOW) ==      \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_ACTIVE_LOW)
> +
> +/** Test if the Extended Interrupt is Shared or Exclusive.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Interrupt is Shared.
> +  @retval FALSE           Interrupt is Exclusive.
> +*/
> +#define IS_EXTENDED_INTERRUPT_SHARED(Flag)                        \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARED) ==          \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_SHARED)
> +
> +/** Test the Extended Interrupt flags to determine if the Device
> +    is Wake capable or not.
> +
> +  @param [in]  Flag       Extended Interrupt Resource descriptor flag.
> +
> +  @retval TRUE            Interrupt is Wake Capable.
> +  @retval FALSE           Interrupt is not Wake Capable.
> +*/
> +#define IS_EXTENDED_INTERRUPT_WAKE_CAPABLE(Flag)                  \
> +  (((Flag) & EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLE) ==    \
> +    EFI_ACPI_EXTENDED_INTERRUPT_FLAG_WAKE_CAPABLE)
> +
> +//
>  // Ensure proper structure formats
>  //
>  #pragma pack(1)
> --
> 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-09-25  7:53 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-09-22 14:08 [PATCH v1 0/2] Support for dynamic CMN-600 AML generation Sami Mujawar
2020-09-22 14:08 ` [PATCH v1 1/2] MdePkg: Definitions for Extended Interrupt Flags Sami Mujawar
2020-09-22 15:06   ` [edk2-devel] " Alexei Fedorov
2020-09-24 22:07   ` Michael D Kinney
2020-09-25  7:53     ` Sami Mujawar
2020-09-22 14:08 ` [PATCH v1 2/2] DynamicTablesPkg: Add SSDT CMN-600 Table generator Sami Mujawar
2020-09-22 15:06   ` [edk2-devel] " Alexei Fedorov
2020-09-22 15:05 ` [edk2-devel] [PATCH v1 0/2] Support for dynamic CMN-600 AML generation Alexei Fedorov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox