public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Sami Mujawar" <sami.mujawar@arm.com>
To: <devel@edk2.groups.io>
Cc: Sami Mujawar <sami.mujawar@arm.com>, <Alexei.Fedorov@arm.com>,
	<pierre.gondois@arm.com>, <ard.biesheuvel@arm.com>,
	<Matteo.Carlini@arm.com>, <Ben.Adderson@arm.com>, <nd@arm.com>
Subject: [PATCH v1 22/30] DynamicTablesPkg: AML Resource Data Codegen
Date: Wed, 12 Aug 2020 16:22:28 +0100	[thread overview]
Message-ID: <20200812152236.31164-23-sami.mujawar@arm.com> (raw)
In-Reply-To: <20200812152236.31164-1-sami.mujawar@arm.com>

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

AML Codegen is a Dynamic AML technique that facilitates
generation of small segments of AML code. The AML code
generated using AML Codegen is represented as nodes in
the AML Tree.

AML Resource Data Codegen implements interfaces required
for generating Resource Data elements that can be attached
to an AML tree.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---
 DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c | 256 ++++++++++++++++++++
 DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h |  59 +++++
 2 files changed, 315 insertions(+)

diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e7a508e60721558ab59b375dbd526c7066d7329
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.c
@@ -0,0 +1,256 @@
+/** @file
+  AML Resource Data Code Generation.
+
+  Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Glossary:
+  - Rd or RD   - Resource Data
+  - Rds or RDS - Resource Data Small
+  - Rdl or RDL - Resource Data Large
+**/
+
+#include <AmlNodeDefines.h>
+#include <CodeGen/AmlResourceDataCodeGen.h>
+
+#include <AmlCoreInterface.h>
+#include <AmlDefines.h>
+#include <Api/AmlApiHelper.h>
+#include <Tree/AmlNode.h>
+#include <ResourceData/AmlResourceData.h>
+
+/** If ParentNode is not NULL, append RdNode.
+    If NewRdNode is not NULL, update its value to RdNode.
+
+  @param [in]  RdNode       Newly created Resource Data node.
+  @param [in]  ParentNode   If not NULL, add the generated node
+                            to the end of the variable list of
+                            argument of the ParentNode, but
+                            before the "End Tag" Resource Data.
+                            Must be a BufferOpNode.
+  @param [out] NewRdNode    If not NULL, update the its value to RdNode.
+
+  @retval  EFI_SUCCESS            The function completed successfully.
+  @retval  EFI_INVALID_PARAMETER  Invalid parameter.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+LinkRdNode (
+  IN  AML_DATA_NODE      * RdNode,
+  IN  AML_OBJECT_NODE    * ParentNode,
+  IN  AML_DATA_NODE     ** NewRdNode
+  )
+{
+  EFI_STATUS    Status;
+  EFI_STATUS    Status1;
+
+  if (NewRdNode != NULL) {
+    *NewRdNode = RdNode;
+  }
+
+  // Add RdNode as the last element, but before the EndTag.
+  if (ParentNode != NULL) {
+    Status = AmlAppendRdNode (ParentNode, RdNode);
+    if (EFI_ERROR (Status)) {
+      ASSERT (0);
+      Status1 = AmlDeleteTree ((AML_NODE_HEADER*)RdNode);
+      ASSERT_EFI_ERROR (Status1);
+      // Return original error.
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/** Code generation for the "Interrupt ()" ASL function.
+
+  This function creates a Resource Data element corresponding to the
+  "Interrupt ()" ASL function and stores it in an AML Data Node.
+
+  The Resource Data effectively created is an Extended Interrupt Resource
+  Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"
+  for more information about Extended Interrupt Resource Data.
+
+  This function allocates memory to create a data node. It is the caller's
+  responsibility to either:
+   - attach this node to an AML tree;
+   - delete this node.
+
+  @param [in]  ResourceConsumer    The device consumes the specified interrupt
+                                   or produces it for use by a child device.
+  @param [in]  EdgeTriggered       The interrupt is edge triggered or
+                                   level triggered.
+  @param [in]  ActiveLow           The interrupt is active-high or active-low.
+  @param [in]  Shared              The interrupt can be shared with other
+                                   devices or not (Exclusive).
+  @param [in]  IrqList             Interrupt list. Must be non-NULL.
+  @param [in]  IrqCount            Interrupt count. Must be non-zero.
+  @param [in]  ParentNode          If not NULL, add the generated node
+                                   to the end of the variable list of
+                                   argument of the ParentNode, but
+                                   before the "End Tag" Resource Data.
+                                   Must be a BufferOpNode.
+  @param  [out] NewRdNode          If success, contains the generated node.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenInterrupt (
+  IN  BOOLEAN             ResourceConsumer,
+  IN  BOOLEAN             EdgeTriggered,
+  IN  BOOLEAN             ActiveLow,
+  IN  BOOLEAN             Shared,
+  IN  UINT32            * IrqList,
+  IN  UINT8               IrqCount,
+  IN  AML_OBJECT_NODE   * ParentNode,   OPTIONAL
+  OUT AML_DATA_NODE    ** NewRdNode     OPTIONAL
+  )
+{
+  EFI_STATUS                               Status;
+
+  AML_DATA_NODE                          * RdNode;
+  EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR   RdInterrupt;
+  UINT32                                 * FirstInterrupt;
+
+  if ((IrqList == NULL) ||
+      (IrqCount == 0)   ||
+      ((ParentNode == NULL) && (NewRdNode == NULL))) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RdInterrupt.Header.Header.Bits.Name =
+    ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME;
+  RdInterrupt.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
+  RdInterrupt.Header.Length = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) -
+                                sizeof (ACPI_LARGE_RESOURCE_HEADER);
+  RdInterrupt.InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) |
+                                     (EdgeTriggered ? BIT1 : 0)    |
+                                     (ActiveLow ? BIT2 : 0)        |
+                                     (Shared ? BIT3 : 0);
+  RdInterrupt.InterruptTableLength = IrqCount;
+
+  // Get the address of the first interrupt field.
+  FirstInterrupt = RdInterrupt.InterruptNumber;
+
+  // Copy the list of interrupts.
+  CopyMem (FirstInterrupt, IrqList, (sizeof (UINT32) * IrqCount));
+
+  Status = AmlCreateDataNode (
+             EAmlNodeDataTypeResourceData,
+             (UINT8*)&RdInterrupt,
+             sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR),
+             &RdNode
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+    return Status;
+  }
+
+  return LinkRdNode (RdNode, ParentNode, NewRdNode);
+}
+
+/** Add an Interrupt Resource Data node.
+
+  This function creates a Resource Data element corresponding to the
+  "Interrupt ()" ASL function, stores it in an AML Data Node.
+
+  It then adds it after the input CurrRdNode in the list of resource data
+  element.
+
+  The Resource Data effectively created is an Extended Interrupt Resource
+  Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"
+  for more information about Extended Interrupt Resource Data.
+
+  The Extended Interrupt contains one single interrupt.
+
+  This function allocates memory to create a data node. It is the caller's
+  responsibility to either:
+   - attach this node to an AML tree;
+   - delete this node.
+
+  Note: The _CRS node must be defined using the ASL Name () function.
+        e.g. Name (_CRS, ResourceTemplate () {
+               ...
+             }
+
+  @param  [in]  NameOpCrsNode    NameOp object node defining a "_CRS" object.
+                                 Must have an OpCode=AML_NAME_OP, SubOpCode=0.
+                                 NameOp object nodes are defined in ASL
+                                 using the "Name ()" function.
+  @param  [in]  ResourceConsumer The device consumes the specified interrupt
+                                 or produces it for use by a child device.
+  @param  [in]  EdgeTriggered    The interrupt is edge triggered or
+                                 level triggered.
+  @param  [in]  ActiveLow        The interrupt is active-high or active-low.
+  @param  [in]  Shared           The interrupt can be shared with other
+                                 devices or not (Exclusive).
+  @param  [in]  IrqList          Interrupt list. Must be non-NULL.
+  @param  [in]  IrqCount         Interrupt count. Must be non-zero.
+
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenCrsAddRdInterrupt (
+  IN  AML_OBJECT_NODE_HANDLE  NameOpCrsNode,
+  IN  BOOLEAN                 ResourceConsumer,
+  IN  BOOLEAN                 EdgeTriggered,
+  IN  BOOLEAN                 ActiveLow,
+  IN  BOOLEAN                 Shared,
+  IN  UINT32                * IrqList,
+  IN  UINT8                   IrqCount
+  )
+{
+  EFI_STATUS              Status;
+
+  AML_OBJECT_NODE_HANDLE  BufferOpNode;
+
+  if ((IrqList == NULL)                                                   ||
+      (IrqCount == 0)                                                     ||
+      (!AmlNodeHasOpCode (NameOpCrsNode, AML_NAME_OP, 0))                 ||
+      (!AmlNameOpCompareName (NameOpCrsNode, "_CRS"))) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Get the _CRS value which is represented as a BufferOp object node
+  // which is the 2nd fixed argument (i.e. index 1).
+  BufferOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
+                                           NameOpCrsNode,
+                                           EAmlParseIndexTerm1
+                                           );
+  if ((BufferOpNode == NULL)                                             ||
+      (AmlGetNodeType ((AML_NODE_HANDLE)BufferOpNode) != EAmlNodeObject) ||
+      (!AmlNodeHasOpCode (BufferOpNode, AML_BUFFER_OP, 0))) {
+    ASSERT (0);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Generate the Extended Interrupt Resource Data node,
+  // and attach it as the last variable argument of the BufferOpNode.
+  Status = AmlCodeGenInterrupt (
+             ResourceConsumer,
+             EdgeTriggered,
+             ActiveLow,
+             Shared,
+             IrqList,
+             IrqCount,
+             BufferOpNode,
+             NULL
+             );
+  if (EFI_ERROR (Status)) {
+    ASSERT (0);
+  }
+
+  return Status;
+}
diff --git a/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h
new file mode 100644
index 0000000000000000000000000000000000000000..08364db4431f8d41c70f220ee7417453ceb2496d
--- /dev/null
+++ b/DynamicTablesPkg/Library/Common/AmlLib/CodeGen/AmlResourceDataCodeGen.h
@@ -0,0 +1,59 @@
+/** @file
+  AML Resource Data Code Generation.
+
+  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef AML_RESOURCE_DATA_CODE_GEN_H_
+#define AML_RESOURCE_DATA_CODE_GEN_H_
+
+/** Code generation for the "Interrupt ()" ASL function.
+
+  This function creates a Resource Data element corresponding to the
+  "Interrupt ()" ASL function and stores it in an AML Data Node.
+
+  The Resource Data effectively created is an Extended Interrupt Resource
+  Data. See ACPI 6.3 specification, s6.4.3.6 "Extended Interrupt Descriptor"
+  for more information about Extended Interrupt Resource Data.
+
+  This function allocates memory to create a data node. It is the caller's
+  responsibility to either:
+   - attach this node to an AML tree;
+   - delete this node.
+
+  @param [in]  ResourceConsumer    The device consumes the specified interrupt
+                                   or produces it for use by a child device.
+  @param [in]  EdgeTriggered       The interrupt is edge triggered or
+                                   level triggered.
+  @param [in]  ActiveLow           The interrupt is active-high or active-low.
+  @param [in]  Shared              The interrupt can be shared with other
+                                   devices or not (Exclusive).
+  @param [in]  IrqList             Interrupt list. Must be non-NULL.
+  @param [in]  IrqCount            Interrupt count. Must be non-zero.
+  @param [in]  ParentNode          If not NULL, add the generated node
+                                   to the end of the variable list of
+                                   argument of the ParentNode, but
+                                   before the "End Tag" Resource Data.
+                                   Must be a BufferOpNode.
+  @param  [out] NewRdNode          If success, contains the generated node.
+
+  @retval EFI_SUCCESS             The function completed successfully.
+  @retval EFI_INVALID_PARAMETER   Invalid parameter.
+  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+AmlCodeGenInterrupt (
+  IN  BOOLEAN             ResourceConsumer,
+  IN  BOOLEAN             EdgeTriggered,
+  IN  BOOLEAN             ActiveLow,
+  IN  BOOLEAN             Shared,
+  IN  UINT32            * IrqList,
+  IN  UINT8               IrqCount,
+  IN  AML_OBJECT_NODE   * ParentNode,   OPTIONAL
+  OUT AML_DATA_NODE    ** NewRdNode     OPTIONAL
+  );
+
+#endif // AML_RESOURCE_DATA_CODE_GEN_H_
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'


  parent reply	other threads:[~2020-08-12 15:23 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-12 15:22 [PATCH v1 00/30] Add Dynamic AML generation support Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 01/30] DynamicTablesPkg: Introduction to Dynamic AML Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 02/30] DynamicTablesPkg: AmlLib definitions Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 03/30] DynamicTablesPkg: AML grammar definition Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 04/30] DynamicTablesPkg: AML node definitions Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 05/30] DynamicTablesPkg: AML tree interface Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 06/30] DynamicTablesPkg: AML tree enumerator Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 07/30] DynamicTablesPkg: AML tree traversal Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 08/30] DynamicTablesPkg: AML tree iterator Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 09/30] DynamicTablesPkg: AML tree/node cloning Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 10/30] DynamicTablesPkg: AML utility interfaces Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 11/30] DynamicTablesPkg: AML and ASL string helper Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 12/30] DynamicTablesPkg: AML stream interface Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 13/30] DynamicTablesPkg: AML serialise interface Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 14/30] DynamicTablesPkg: AML debug logging Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 15/30] DynamicTablesPkg: AML ACPI Namespace interface Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 16/30] DynamicTablesPkg: AML Parser Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 17/30] DynamicTablesPkg: AML resource data helper Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 18/30] DynamicTablesPkg: AML resource data parser Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 19/30] DynamicTablesPkg: AML Method parser Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 20/30] DynamicTablesPkg: AML Field list parser Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 21/30] DynamicTablesPkg: AML Codegen Sami Mujawar
2020-08-12 15:22 ` Sami Mujawar [this message]
2020-08-12 15:22 ` [PATCH v1 23/30] DynamicTablesPkg: AML Core interface Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 24/30] DynamicTablesPkg: AmlLib APIs Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 25/30] DynamicTablesPkg: Dynamic AML: Add AmlLib library Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 26/30] DynamicTablesPkg: Add AsciiFromHex helper function Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 27/30] DynamicTablesPkg: SSDT Serial Port Fixup library Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 28/30] DynamicTablesPkg: SSDT Serial Port generator Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 29/30] DynamicTablesPkg: Add SSDT Serial port for SPCR Sami Mujawar
2020-08-12 15:22 ` [PATCH v1 30/30] DynamicTablesPkg: Add SSDT Serial port for DBG2 Sami Mujawar
2020-08-13 15:16 ` [edk2-devel] [PATCH v1 00/30] Add Dynamic AML generation support Alexei Fedorov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200812152236.31164-23-sami.mujawar@arm.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox