/** @file
  AML Code Generation.

  Copyright (c) 2020 - 2022, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <AmlNodeDefines.h>

#include <AcpiTableGenerator.h>

#include <AmlCoreInterface.h>
#include <AmlCpcInfo.h>
#include <AmlEncoding/Aml.h>
#include <Api/AmlApiHelper.h>
#include <CodeGen/AmlResourceDataCodeGen.h>
#include <Tree/AmlNode.h>
#include <Tree/AmlTree.h>
#include <String/AmlString.h>
#include <Utils/AmlUtility.h>

/** Utility function to link a node when returning from a CodeGen function.

  @param [in]  Node           Newly created node.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewObjectNode  If not NULL:
                               - and Success, contains the created Node.
                               - and Error, reset to NULL.

  @retval  EFI_SUCCESS            The function completed successfully.
  @retval  EFI_INVALID_PARAMETER  Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
LinkNode (
  IN  AML_OBJECT_NODE  *Node,
  IN  AML_NODE_HEADER  *ParentNode,
  OUT AML_OBJECT_NODE  **NewObjectNode
  )
{
  EFI_STATUS  Status;

  if (NewObjectNode != NULL) {
    *NewObjectNode = NULL;
  }

  // Add RdNode as the last element.
  if (ParentNode != NULL) {
    Status = AmlVarListAddTail (ParentNode, (AML_NODE_HEADER *)Node);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  }

  if (NewObjectNode != NULL) {
    *NewObjectNode = Node;
  }

  return EFI_SUCCESS;
}

/** AML code generation for DefinitionBlock.

  Create a Root Node handle.
  It is the caller's responsibility to free the allocated memory
  with the AmlDeleteTree function.

  AmlCodeGenDefinitionBlock (TableSignature, OemID, TableID, OEMRevision) is
  equivalent to the following ASL code:
    DefinitionBlock (AMLFileName, TableSignature, ComplianceRevision,
      OemID, TableID, OEMRevision) {}
  with the ComplianceRevision set to 2 and the AMLFileName is ignored.

  @param[in]  TableSignature       4-character ACPI signature.
                                   Must be 'DSDT' or 'SSDT'.
  @param[in]  OemId                6-character string OEM identifier.
  @param[in]  OemTableId           8-character string OEM table identifier.
  @param[in]  OemRevision          OEM revision number.
  @param[out] NewRootNode          Pointer to the root node representing a
                                   Definition Block.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenDefinitionBlock (
  IN  CONST CHAR8          *TableSignature,
  IN  CONST CHAR8          *OemId,
  IN  CONST CHAR8          *OemTableId,
  IN        UINT32         OemRevision,
  OUT       AML_ROOT_NODE  **NewRootNode
  )
{
  EFI_STATUS                   Status;
  EFI_ACPI_DESCRIPTION_HEADER  AcpiHeader;

  if ((TableSignature == NULL)  ||
      (OemId == NULL)           ||
      (OemTableId == NULL)      ||
      (NewRootNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  CopyMem (&AcpiHeader.Signature, TableSignature, 4);
  AcpiHeader.Length   = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
  AcpiHeader.Revision = 2;
  CopyMem (&AcpiHeader.OemId, OemId, 6);
  CopyMem (&AcpiHeader.OemTableId, OemTableId, 8);
  AcpiHeader.OemRevision     = OemRevision;
  AcpiHeader.CreatorId       = TABLE_GENERATOR_CREATOR_ID_ARM;
  AcpiHeader.CreatorRevision = CREATE_REVISION (1, 0);

  Status = AmlCreateRootNode (&AcpiHeader, NewRootNode);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** AML code generation for a String object node.

  @param [in]  String          Pointer to a NULL terminated string.
  @param [out] NewObjectNode   If success, contains the created
                               String object node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenString (
  IN  CHAR8            *String,
  OUT AML_OBJECT_NODE  **NewObjectNode
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ObjectNode;
  AML_DATA_NODE    *DataNode;

  if ((String == NULL)  ||
      (NewObjectNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  DataNode = NULL;

  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_STRING_PREFIX, 0),
             0,
             &ObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeString,
             (UINT8 *)String,
             (UINT32)AsciiStrLen (String) + 1,
             &DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  Status = AmlSetFixedArgument (
             ObjectNode,
             EAmlParseIndexTerm0,
             (AML_NODE_HEADER *)DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
    goto error_handler;
  }

  *NewObjectNode = ObjectNode;
  return Status;

error_handler:
  AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
  return Status;
}

/** AML code generation for an Integer object node.

  @param [in]  Integer         Integer of the Integer object node.
  @param [out] NewObjectNode   If success, contains the created
                               Integer object node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenInteger (
  IN  UINT64           Integer,
  OUT AML_OBJECT_NODE  **NewObjectNode
  )
{
  EFI_STATUS  Status;
  INT8        ValueWidthDiff;

  if (NewObjectNode == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Create an object node containing Zero.
  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_ZERO_OP, 0),
             0,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Update the object node with integer value.
  Status = AmlNodeSetIntegerValue (*NewObjectNode, Integer, &ValueWidthDiff);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)*NewObjectNode);
  }

  return Status;
}

/** AML code generation for a Package object node.

  The package generated is empty. New elements can be added via its
  list of variable arguments.

  @param [out] NewObjectNode   If success, contains the created
                               Package object node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenPackage (
  OUT AML_OBJECT_NODE  **NewObjectNode
  )
{
  EFI_STATUS     Status;
  AML_DATA_NODE  *DataNode;
  UINT8          NodeCount;

  if (NewObjectNode == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  NodeCount = 0;

  // Create an object node.
  // PkgLen is 2:
  //  - one byte to store the PkgLength
  //  - one byte for the NumElements.
  // Cf ACPI6.3, s20.2.5 "Term Objects Encoding"
  // DefPackage  := PackageOp PkgLength NumElements PackageElementList
  // NumElements := ByteData
  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_PACKAGE_OP, 0),
             2,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // NumElements is a ByteData.
  Status = AmlCreateDataNode (
             EAmlNodeDataTypeUInt,
             &NodeCount,
             sizeof (NodeCount),
             &DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  Status = AmlSetFixedArgument (
             *NewObjectNode,
             EAmlParseIndexTerm0,
             (AML_NODE_HEADER *)DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  return Status;

error_handler:
  AmlDeleteTree ((AML_NODE_HEADER *)*NewObjectNode);
  if (DataNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
  }

  return Status;
}

/** AML code generation for a Buffer object node.

  To create a Buffer object node with an empty buffer,
  call the function with (Buffer=NULL, BufferSize=0).

  @param [in]  Buffer          Buffer to set for the created Buffer
                               object node. The Buffer's content is copied.
                               NULL if there is no buffer to set for
                               the Buffer node.
  @param [in]  BufferSize      Size of the Buffer.
                               0 if there is no buffer to set for
                               the Buffer node.
  @param [out] NewObjectNode   If success, contains the created
                               Buffer object node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenBuffer (
  IN  CONST UINT8            *Buffer        OPTIONAL,
  IN        UINT32           BufferSize    OPTIONAL,
  OUT       AML_OBJECT_NODE  **NewObjectNode
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *BufferNode;
  AML_OBJECT_NODE  *BufferSizeNode;
  UINT32           BufferSizeNodeSize;
  AML_DATA_NODE    *DataNode;
  UINT32           PkgLen;

  // Buffer and BufferSize must be either both set, or both clear.
  if ((NewObjectNode == NULL)                 ||
      ((Buffer == NULL) != (BufferSize == 0)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  BufferNode = NULL;
  DataNode   = NULL;

  // Cf ACPI 6.3 specification, s20.2.5.4 "Type 2 Opcodes Encoding"
  // DefBuffer := BufferOp PkgLength BufferSize ByteList
  // BufferOp  := 0x11
  // BufferSize := TermArg => Integer

  Status = AmlCodeGenInteger (BufferSize, &BufferSizeNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Get the number of bytes required to encode the BufferSizeNode.
  Status = AmlComputeSize (
             (AML_NODE_HEADER *)BufferSizeNode,
             &BufferSizeNodeSize
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // Compute the size to write in the PkgLen.
  Status = AmlComputePkgLength (BufferSizeNodeSize + BufferSize, &PkgLen);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // Create an object node for the buffer.
  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_BUFFER_OP, 0),
             PkgLen,
             &BufferNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // Set the BufferSizeNode as a fixed argument of the BufferNode.
  Status = AmlSetFixedArgument (
             BufferNode,
             EAmlParseIndexTerm0,
             (AML_NODE_HEADER *)BufferSizeNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // BufferSizeNode is now attached.
  BufferSizeNode = NULL;

  // If there is a buffer, create a DataNode and attach it to the BufferNode.
  if (Buffer != NULL) {
    Status = AmlCreateDataNode (
               EAmlNodeDataTypeRaw,
               Buffer,
               BufferSize,
               &DataNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      goto error_handler;
    }

    Status = AmlVarListAddTail (
               (AML_NODE_HEADER *)BufferNode,
               (AML_NODE_HEADER *)DataNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      goto error_handler;
    }
  }

  *NewObjectNode = BufferNode;
  return Status;

error_handler:
  if (BufferSizeNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)BufferSizeNode);
  }

  if (BufferNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)BufferNode);
  }

  if (DataNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
  }

  return Status;
}

/** AML code generation for a ResourceTemplate.

  "ResourceTemplate" is a macro defined in ACPI 6.3, s19.3.3
  "ASL Resource Templates". It allows to store resource data elements.

  In AML, a ResourceTemplate is implemented as a Buffer storing resource
  data elements. An EndTag resource data descriptor must be at the end
  of the list of resource data elements.
  This function generates a Buffer node with an EndTag resource data
  descriptor. It can be seen as an empty list of resource data elements.

  @param [out] NewObjectNode   If success, contains the created
                               ResourceTemplate object node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenResourceTemplate (
  OUT AML_OBJECT_NODE  **NewObjectNode
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *BufferNode;

  if (NewObjectNode == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Create a BufferNode with an empty buffer.
  Status = AmlCodeGenBuffer (NULL, 0, &BufferNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Create an EndTag resource data element and attach it to the Buffer.
  Status = AmlCodeGenEndTag (0, BufferNode, NULL);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)BufferNode);
    return Status;
  }

  *NewObjectNode = BufferNode;
  return Status;
}

/** AML code generation for a Name object node.

  @param  [in] NameString     The new variable name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "DEV0", "DV15.DEV0", etc.
                              This input string is copied.
  @param [in]  Object         Object associated to the NameString.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenName (
  IN  CONST CHAR8            *NameString,
  IN        AML_OBJECT_NODE  *Object,
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ObjectNode;
  AML_DATA_NODE    *DataNode;
  CHAR8            *AmlNameString;
  UINT32           AmlNameStringSize;

  if ((NameString == NULL)    ||
      (Object == NULL)        ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ObjectNode    = NULL;
  DataNode      = NULL;
  AmlNameString = NULL;

  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler1;
  }

  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_NAME_OP, 0),
             0,
             &ObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler1;
  }

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeNameString,
             (UINT8 *)AmlNameString,
             AmlNameStringSize,
             &DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  Status = AmlSetFixedArgument (
             ObjectNode,
             EAmlParseIndexTerm0,
             (AML_NODE_HEADER *)DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
    goto error_handler2;
  }

  Status = AmlSetFixedArgument (
             ObjectNode,
             EAmlParseIndexTerm1,
             (AML_NODE_HEADER *)Object
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  Status = LinkNode (
             ObjectNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  // Free AmlNameString before returning as it is copied
  // in the call to AmlCreateDataNode().
  goto error_handler1;

error_handler2:
  if (ObjectNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
  }

error_handler1:
  if (AmlNameString != NULL) {
    FreePool (AmlNameString);
  }

  return Status;
}

/** AML code generation for a Name object node, containing a String.

  AmlCodeGenNameString ("_HID", "HID0000", ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Name(_HID, "HID0000")

  @param  [in] NameString     The new variable name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "DEV0", "DV15.DEV0", etc.
                              The input string is copied.
  @param [in]  String         NULL terminated String to associate to the
                              NameString.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenNameString (
  IN  CONST CHAR8            *NameString,
  IN        CHAR8            *String,
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ObjectNode;

  if ((NameString == NULL)  ||
      (String == NULL)      ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlCodeGenString (String, &ObjectNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlCodeGenName (
             NameString,
             ObjectNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
  }

  return Status;
}

/** AML code generation for a Name object node, containing an Integer.

  AmlCodeGenNameInteger ("_UID", 1, ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Name(_UID, One)

  @param  [in] NameString     The new variable name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "DEV0", "DV15.DEV0", etc.
                              The input string is copied.
  @param [in]  Integer        Integer to associate to the NameString.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenNameInteger (
  IN  CONST CHAR8            *NameString,
  IN        UINT64           Integer,
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ObjectNode;

  if ((NameString == NULL)  ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlCodeGenInteger (Integer, &ObjectNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlCodeGenName (
             NameString,
             ObjectNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
  }

  return Status;
}

/** AML code generation for a Name object node, containing a Package.

  AmlCodeGenNamePackage ("PKG0", ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Name(PKG0, Package () {})

  @param [in]  NameString     The new variable name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "DEV0", "DV15.DEV0", etc.
                              The input string is copied.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenNamePackage (
  IN  CONST CHAR8 *NameString,
  IN        AML_NODE_HEADER *ParentNode, OPTIONAL
  OUT       AML_OBJECT_NODE   **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *PackageNode;

  if ((NameString == NULL)  ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlCodeGenPackage (&PackageNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlCodeGenName (
             NameString,
             PackageNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)PackageNode);
  }

  return Status;
}

/** AML code generation for a Name object node, containing a ResourceTemplate.

  AmlCodeGenNameResourceTemplate ("PRS0", ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Name(PRS0, ResourceTemplate () {})

  @param [in]  NameString     The new variable name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "DEV0", "DV15.DEV0", etc.
                              The input string is copied.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenNameResourceTemplate (
  IN  CONST CHAR8 *NameString,
  IN        AML_NODE_HEADER *ParentNode, OPTIONAL
  OUT       AML_OBJECT_NODE   **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ResourceTemplateNode;

  if ((NameString == NULL)  ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlCodeGenName (
             NameString,
             ResourceTemplateNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)ResourceTemplateNode);
  }

  return Status;
}

/** Add a _PRT entry.

  AmlCodeGenPrtEntry (0x0FFFF, 0, "LNKA", 0, PrtNameNode) is
  equivalent of the following ASL code:
    Package (4) {
      0x0FFFF, // Address: Device address (([Device Id] << 16) | 0xFFFF).
      0,       // Pin: PCI pin number of the device (0-INTA, ...).
      LNKA     // Source: Name of the device that allocates the interrupt
               // to which the above pin is connected.
      0        // Source Index: Source is assumed to only describe one
               // interrupt, so let it to index 0.
    }

  The 2 models described in ACPI 6.4, s6.2.13 "_PRT (PCI Routing Table)" can
  be generated by this function. The example above matches the first model.

  The package is added at the tail of the list of the input _PRT node
  name:
    Name (_PRT, Package () {
      [Pre-existing _PRT entries],
      [Newly created _PRT entry]
    })

  Cf. ACPI 6.4 specification:
   - s6.2.13 "_PRT (PCI Routing Table)"
   - s6.1.1 "_ADR (Address)"

  @param [in]  Address        Address. Cf ACPI 6.4 specification, Table 6.2:
                              "ADR Object Address Encodings":
                              High word-Device #, Low word-Function #. (for
                              example, device 3, function 2 is 0x00030002).
                              To refer to all the functions on a device #,
                              use a function number of FFFF).
  @param [in]  Pin            PCI pin number of the device (0-INTA ... 3-INTD).
                              Must be between 0-3.
  @param [in]  LinkName       Link Name, i.e. device in the AML NameSpace
                              describing the interrupt used. The input string
                              is copied.
                              If NULL, generate 0 in the 'Source' field (cf.
                              second model, using GSIV).
  @param [in]  SourceIndex    Source index or GSIV.
  @param [in]  PrtNameNode    Prt Named node to add the object to ....

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlAddPrtEntry (
  IN        UINT32                  Address,
  IN        UINT8                   Pin,
  IN  CONST CHAR8                   *LinkName,
  IN        UINT32                  SourceIndex,
  IN        AML_OBJECT_NODE_HANDLE  PrtNameNode
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *PrtEntryList;
  AML_OBJECT_NODE  *PackageNode;
  AML_OBJECT_NODE  *NewElementNode;

  CHAR8          *AmlNameString;
  UINT32         AmlNameStringSize;
  AML_DATA_NODE  *DataNode;

  if ((Pin > 3)                 ||
      (PrtNameNode == NULL)     ||
      (AmlGetNodeType ((AML_NODE_HANDLE)PrtNameNode) != EAmlNodeObject) ||
      (!AmlNodeHasOpCode (PrtNameNode, AML_NAME_OP, 0))                 ||
      !AmlNameOpCompareName (PrtNameNode, "_PRT"))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  NewElementNode = NULL;
  AmlNameString  = NULL;
  DataNode       = NULL;

  // Get the Package object node of the _PRT node,
  // which is the 2nd fixed argument (i.e. index 1).
  PrtEntryList = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
                                           PrtNameNode,
                                           EAmlParseIndexTerm1
                                           );
  if ((PrtEntryList == NULL)                                              ||
      (AmlGetNodeType ((AML_NODE_HANDLE)PrtEntryList) != EAmlNodeObject)  ||
      (!AmlNodeHasOpCode (PrtEntryList, AML_PACKAGE_OP, 0)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // The new _PRT entry.
  Status = AmlCodeGenPackage (&PackageNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlCodeGenInteger (Address, &NewElementNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PackageNode,
             (AML_NODE_HANDLE)NewElementNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  NewElementNode = NULL;

  Status = AmlCodeGenInteger (Pin, &NewElementNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PackageNode,
             (AML_NODE_HANDLE)NewElementNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  NewElementNode = NULL;

  if (LinkName != NULL) {
    Status = ConvertAslNameToAmlName (LinkName, &AmlNameString);
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      goto error_handler;
    }

    Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      goto error_handler;
    }

    Status = AmlCreateDataNode (
               EAmlNodeDataTypeNameString,
               (UINT8 *)AmlNameString,
               AmlNameStringSize,
               &DataNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      goto error_handler;
    }

    // AmlNameString will be freed be fore returning.

    Status = AmlVarListAddTail (
               (AML_NODE_HANDLE)PackageNode,
               (AML_NODE_HANDLE)DataNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      goto error_handler;
    }

    DataNode = NULL;
  } else {
    Status = AmlCodeGenInteger (0, &NewElementNode);
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      goto error_handler;
    }

    Status = AmlVarListAddTail (
               (AML_NODE_HANDLE)PackageNode,
               (AML_NODE_HANDLE)NewElementNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      goto error_handler;
    }
  }

  Status = AmlCodeGenInteger (SourceIndex, &NewElementNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PackageNode,
             (AML_NODE_HANDLE)NewElementNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // Append to the list of _PRT entries.
  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PrtEntryList,
             (AML_NODE_HANDLE)PackageNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // Free AmlNameString before returning as it is copied
  // in the call to AmlCreateDataNode().
  goto exit_handler;

error_handler:
  AmlDeleteTree ((AML_NODE_HANDLE)PackageNode);
  if (NewElementNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)NewElementNode);
  }

  if (DataNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)DataNode);
  }

exit_handler:
  if (AmlNameString != NULL) {
    FreePool (AmlNameString);
  }

  return Status;
}

/** AML code generation for a Device object node.

  AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Device(COM0) {}

  @param  [in] NameString     The new Device's name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "DEV0", "DV15.DEV0", etc.
                              The input string is copied.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenDevice (
  IN  CONST CHAR8            *NameString,
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ObjectNode;
  AML_DATA_NODE    *DataNode;
  CHAR8            *AmlNameString;
  UINT32           AmlNameStringSize;

  if ((NameString == NULL)  ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ObjectNode    = NULL;
  DataNode      = NULL;
  AmlNameString = NULL;

  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler1;
  }

  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_EXT_OP, AML_EXT_DEVICE_OP),
             AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),
             &ObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler1;
  }

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeNameString,
             (UINT8 *)AmlNameString,
             AmlNameStringSize,
             &DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  Status = AmlSetFixedArgument (
             ObjectNode,
             EAmlParseIndexTerm0,
             (AML_NODE_HEADER *)DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
    goto error_handler2;
  }

  Status = LinkNode (
             ObjectNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  // Free AmlNameString before returning as it is copied
  // in the call to AmlCreateDataNode().
  goto error_handler1;

error_handler2:
  if (ObjectNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
  }

error_handler1:
  if (AmlNameString != NULL) {
    FreePool (AmlNameString);
  }

  return Status;
}

/** AML code generation for a Scope object node.

  AmlCodeGenScope ("_SB", ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Scope(_SB) {}

  @param  [in] NameString     The new Scope's name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "DEV0", "DV15.DEV0", etc.
                              The input string is copied.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenScope (
  IN  CONST CHAR8            *NameString,
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ObjectNode;
  AML_DATA_NODE    *DataNode;
  CHAR8            *AmlNameString;
  UINT32           AmlNameStringSize;

  if ((NameString == NULL)  ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ObjectNode    = NULL;
  DataNode      = NULL;
  AmlNameString = NULL;

  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler1;
  }

  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_SCOPE_OP, 0),
             AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),
             &ObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler1;
  }

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeNameString,
             (UINT8 *)AmlNameString,
             AmlNameStringSize,
             &DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  Status = AmlSetFixedArgument (
             ObjectNode,
             EAmlParseIndexTerm0,
             (AML_NODE_HEADER *)DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
    goto error_handler2;
  }

  Status = LinkNode (
             ObjectNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  // Free AmlNameString before returning as it is copied
  // in the call to AmlCreateDataNode().
  goto error_handler1;

error_handler2:
  if (ObjectNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
  }

error_handler1:
  if (AmlNameString != NULL) {
    FreePool (AmlNameString);
  }

  return Status;
}

/** AML code generation for a Method object node.

  AmlCodeGenMethod ("MET0", 1, TRUE, 3, ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Method(MET0, 1, Serialized, 3) {}

  ACPI 6.4, s20.2.5.2 "Named Objects Encoding":
    DefMethod := MethodOp PkgLength NameString MethodFlags TermList
    MethodOp := 0x14

  The ASL parameters "ReturnType" and "ParameterTypes" are not asked
  in this function. They are optional parameters in ASL.

  @param [in]  NameString     The new Method's name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "MET0", "_SB.MET0", etc.
                              The input string is copied.
  @param [in]  NumArgs        Number of arguments.
                              Must be 0 <= NumArgs <= 6.
  @param [in]  IsSerialized   TRUE is equivalent to Serialized.
                              FALSE is equivalent to NotSerialized.
                              Default is NotSerialized in ASL spec.
  @param [in]  SyncLevel      Synchronization level for the method.
                              Must be 0 <= SyncLevel <= 15.
                              Default is 0 in ASL.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenMethod (
  IN  CONST CHAR8            *NameString,
  IN        UINT8            NumArgs,
  IN        BOOLEAN          IsSerialized,
  IN        UINT8            SyncLevel,
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  UINT32           PkgLen;
  UINT8            Flags;
  AML_OBJECT_NODE  *ObjectNode;
  AML_DATA_NODE    *DataNode;
  CHAR8            *AmlNameString;
  UINT32           AmlNameStringSize;

  if ((NameString == NULL)    ||
      (NumArgs > 6)           ||
      (SyncLevel > 15)        ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ObjectNode = NULL;
  DataNode   = NULL;

  // ACPI 6.4, s20.2.5.2 "Named Objects Encoding":
  //   DefMethod := MethodOp PkgLength NameString MethodFlags TermList
  //   MethodOp := 0x14
  // So:
  //  1- Create the NameString
  //  2- Compute the size to write in the PkgLen
  //  3- Create nodes for the NameString and Method object node
  //  4- Set the NameString DataNode as a fixed argument
  //  5- Create and link the MethodFlags node

  // 1- Create the NameString
  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler1;
  }

  // 2- Compute the size to write in the PkgLen
  //    Add 1 byte (ByteData) for MethodFlags.
  Status = AmlComputePkgLength (AmlNameStringSize + 1, &PkgLen);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler1;
  }

  //  3- Create nodes for the NameString and Method object node
  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_METHOD_OP, 0),
             PkgLen,
             &ObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler1;
  }

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeNameString,
             (UINT8 *)AmlNameString,
             AmlNameStringSize,
             &DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  //  4- Set the NameString DataNode as a fixed argument
  Status = AmlSetFixedArgument (
             ObjectNode,
             EAmlParseIndexTerm0,
             (AML_NODE_HEADER *)DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  DataNode = NULL;

  //  5- Create and link the MethodFlags node
  Flags = NumArgs                   |
          (IsSerialized ? BIT3 : 0) |
          (SyncLevel << 4);

  Status = AmlCreateDataNode (EAmlNodeDataTypeUInt, &Flags, 1, &DataNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  Status = AmlSetFixedArgument (
             ObjectNode,
             EAmlParseIndexTerm1,
             (AML_NODE_HEADER *)DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  // Data node is attached so set the pointer to
  // NULL to ensure correct error handling.
  DataNode = NULL;

  Status = LinkNode (
             ObjectNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler2;
  }

  // Free AmlNameString before returning as it is copied
  // in the call to AmlCreateDataNode().
  goto error_handler1;

error_handler2:
  if (ObjectNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
  }

  if (DataNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
  }

error_handler1:
  if (AmlNameString != NULL) {
    FreePool (AmlNameString);
  }

  return Status;
}

/** AML code generation for a Return object node.

  AmlCodeGenReturn (ReturnNode, ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Return([Content of the ReturnNode])

  The ACPI 6.3 specification, s20.2.5.3 "Type 1 Opcodes Encoding" states:
    DefReturn := ReturnOp ArgObject
    ReturnOp := 0xA4
    ArgObject := TermArg => DataRefObject

  Thus, the ReturnNode must be evaluated as a DataRefObject. It can
  be a NameString referencing an object. As this CodeGen Api doesn't
  do semantic checking, it is strongly advised to check the AML bytecode
  generated by this function against an ASL compiler.

  The ReturnNode must be generated inside a Method body scope.

  @param [in]  ReturnNode     The object returned by the Return ASL statement.
                              This node is deleted if an error occurs.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
                              Must be a MethodOp node.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenReturn (
  IN  AML_NODE_HEADER  *ReturnNode,
  IN  AML_NODE_HEADER  *ParentNode      OPTIONAL,
  OUT AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ObjectNode;

  if ((ReturnNode == NULL)                              ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)) ||
      ((ParentNode != NULL) &&
       !AmlNodeCompareOpCode (
          (AML_OBJECT_NODE *)ParentNode,
          AML_METHOD_OP,
          0
          )))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_RETURN_OP, 0),
             0,
             &ObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  Status = AmlSetFixedArgument (
             ObjectNode,
             EAmlParseIndexTerm0,
             ReturnNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  ReturnNode = NULL;

  Status = LinkNode (
             ObjectNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  return Status;

error_handler:
  if (ReturnNode != NULL) {
    AmlDeleteTree (ReturnNode);
  }

  if (ObjectNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
  }

  return Status;
}

/** AML code generation for a Return object node,
    returning the object as an input NameString.

  AmlCodeGenReturn ("NAM1", ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Return(NAM1)

  The ACPI 6.3 specification, s20.2.5.3 "Type 1 Opcodes Encoding" states:
    DefReturn := ReturnOp ArgObject
    ReturnOp := 0xA4
    ArgObject := TermArg => DataRefObject

  Thus, the ReturnNode must be evaluated as a DataRefObject. It can
  be a NameString referencing an object. As this CodeGen Api doesn't
  do semantic checking, it is strongly advised to check the AML bytecode
  generated by this function against an ASL compiler.

  The ReturnNode must be generated inside a Method body scope.

  @param [in]  NameString     The object referenced by this NameString
                              is returned by the Return ASL statement.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "NAM1", "_SB.NAM1", etc.
                              The input string is copied.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
                              Must be a MethodOp node.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenReturnNameString (
  IN  CONST CHAR8            *NameString,
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
  )
{
  EFI_STATUS     Status;
  AML_DATA_NODE  *DataNode;
  CHAR8          *AmlNameString;
  UINT32         AmlNameStringSize;

  DataNode = NULL;

  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeNameString,
             (UINT8 *)AmlNameString,
             AmlNameStringSize,
             &DataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // AmlCodeGenReturn() deletes DataNode if error.
  Status = AmlCodeGenReturn (
             (AML_NODE_HEADER *)DataNode,
             ParentNode,
             NewObjectNode
             );
  ASSERT_EFI_ERROR (Status);

exit_handler:
  if (AmlNameString != NULL) {
    FreePool (AmlNameString);
  }

  return Status;
}

/** AML code generation for a Return object node,
    returning an Integer.

  AmlCodeGenReturn (0), ParentNode, NewObjectNode) is
  equivalent of the following ASL code:
    Return (0)

  The ACPI 6.3 specification, 20.2.8 "Statement Opcodes Encoding" states:
    DefReturn := ReturnOp ArgObject
    ReturnOp := 0xA4
    ArgObject := TermArg => DataRefObject

  Thus, the ReturnNode must be evaluated as a DataRefObject.

  The ReturnNode must be generated inside a Method body scope.

  @param [in]  Integer        The integer is returned by the Return
                              ASL statement.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
                              Must be a MethodOp node.
  @param [out] NewObjectNode  If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenReturnInteger (
  IN        UINT64           Integer,
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
  OUT       AML_OBJECT_NODE  **NewObjectNode  OPTIONAL
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *IntNode;

  IntNode = NULL;

  Status = AmlCodeGenInteger (Integer, &IntNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // AmlCodeGenReturn() deletes DataNode if error.
  Status = AmlCodeGenReturn (
             (AML_NODE_HEADER *)IntNode,
             ParentNode,
             NewObjectNode
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** AML code generation for a method returning a NameString.

  AmlCodeGenMethodRetNameString (
    "MET0", "_CRS", 1, TRUE, 3, ParentNode, NewObjectNode
    );
  is equivalent of the following ASL code:
    Method(MET0, 1, Serialized, 3) {
      Return (_CRS)
    }

  The ASL parameters "ReturnType" and "ParameterTypes" are not asked
  in this function. They are optional parameters in ASL.

  @param [in]  MethodNameString     The new Method's name.
                                    Must be a NULL-terminated ASL NameString
                                    e.g.: "MET0", "_SB.MET0", etc.
                                    The input string is copied.
  @param [in]  ReturnedNameString   The name of the object returned by the
                                    method. Optional parameter, can be:
                                     - NULL (ignored).
                                     - A NULL-terminated ASL NameString.
                                       e.g.: "MET0", "_SB.MET0", etc.
                                       The input string is copied.
  @param [in]  NumArgs              Number of arguments.
                                    Must be 0 <= NumArgs <= 6.
  @param [in]  IsSerialized         TRUE is equivalent to Serialized.
                                    FALSE is equivalent to NotSerialized.
                                    Default is NotSerialized in ASL spec.
  @param [in]  SyncLevel            Synchronization level for the method.
                                    Must be 0 <= SyncLevel <= 15.
                                    Default is 0 in ASL.
  @param [in]  ParentNode           If provided, set ParentNode as the parent
                                    of the node created.
  @param [out] NewObjectNode        If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenMethodRetNameString (
  IN  CONST CHAR8                   *MethodNameString,
  IN  CONST CHAR8                   *ReturnedNameString   OPTIONAL,
  IN        UINT8                   NumArgs,
  IN        BOOLEAN                 IsSerialized,
  IN        UINT8                   SyncLevel,
  IN        AML_NODE_HANDLE         ParentNode           OPTIONAL,
  OUT       AML_OBJECT_NODE_HANDLE  *NewObjectNode        OPTIONAL
  )
{
  EFI_STATUS              Status;
  AML_OBJECT_NODE_HANDLE  MethodNode;

  if ((MethodNameString == NULL)  ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Create a Method named MethodNameString.
  Status = AmlCodeGenMethod (
             MethodNameString,
             NumArgs,
             IsSerialized,
             SyncLevel,
             NULL,
             &MethodNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Return ReturnedNameString if provided.
  if (ReturnedNameString != NULL) {
    Status = AmlCodeGenReturnNameString (
               ReturnedNameString,
               (AML_NODE_HANDLE)MethodNode,
               NULL
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      goto error_handler;
    }
  }

  Status = LinkNode (
             MethodNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  return Status;

error_handler:
  if (MethodNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)MethodNode);
  }

  return Status;
}

/** AML code generation for a method returning an Integer.

  AmlCodeGenMethodRetInteger (
    "_CBA", 0, 1, TRUE, 3, ParentNode, NewObjectNode
    );
  is equivalent of the following ASL code:
    Method(_CBA, 1, Serialized, 3) {
      Return (0)
    }

  The ASL parameters "ReturnType" and "ParameterTypes" are not asked
  in this function. They are optional parameters in ASL.

  @param [in]  MethodNameString     The new Method's name.
                                    Must be a NULL-terminated ASL NameString
                                    e.g.: "MET0", "_SB.MET0", etc.
                                    The input string is copied.
  @param [in]  ReturnedInteger      The value of the integer returned by the
                                    method.
  @param [in]  NumArgs              Number of arguments.
                                    Must be 0 <= NumArgs <= 6.
  @param [in]  IsSerialized         TRUE is equivalent to Serialized.
                                    FALSE is equivalent to NotSerialized.
                                    Default is NotSerialized in ASL spec.
  @param [in]  SyncLevel            Synchronization level for the method.
                                    Must be 0 <= SyncLevel <= 15.
                                    Default is 0 in ASL.
  @param [in]  ParentNode           If provided, set ParentNode as the parent
                                    of the node created.
  @param [out] NewObjectNode        If success, contains the created node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenMethodRetInteger (
  IN  CONST CHAR8                   *MethodNameString,
  IN        UINT64                  ReturnedInteger,
  IN        UINT8                   NumArgs,
  IN        BOOLEAN                 IsSerialized,
  IN        UINT8                   SyncLevel,
  IN        AML_NODE_HANDLE         ParentNode      OPTIONAL,
  OUT       AML_OBJECT_NODE_HANDLE  *NewObjectNode  OPTIONAL
  )
{
  EFI_STATUS              Status;
  AML_OBJECT_NODE_HANDLE  MethodNode;

  if ((MethodNameString == NULL)  ||
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Create a Method named MethodNameString.
  Status = AmlCodeGenMethod (
             MethodNameString,
             NumArgs,
             IsSerialized,
             SyncLevel,
             NULL,
             &MethodNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlCodeGenReturnInteger (
             ReturnedInteger,
             (AML_NODE_HANDLE)MethodNode,
             NULL
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  Status = LinkNode (
             MethodNode,
             ParentNode,
             NewObjectNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  return Status;

error_handler:
  if (MethodNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)MethodNode);
  }

  return Status;
}

/** Create a _LPI name.

  AmlCreateLpiNode ("_LPI", 0, 1, ParentNode, &LpiNode) is
  equivalent of the following ASL code:
    Name (_LPI, Package (
                  0,  // Revision
                  1,  // LevelId
                  0   // Count
                  ))

  This function doesn't define any LPI state. As shown above, the count
  of _LPI state is set to 0.
  The AmlAddLpiState () function allows to add LPI states.

  Cf ACPI 6.3 specification, s8.4.4 "Lower Power Idle States".

  @param [in]  LpiNameString  The new LPI 's object name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "_LPI", "DEV0.PLPI", etc.
                              The input string is copied.
  @param [in]  Revision       Revision number of the _LPI states.
  @param [in]  LevelId        A platform defined number that identifies the
                              level of hierarchy of the processor node to
                              which the LPI states apply.
  @param [in]  ParentNode     If provided, set ParentNode as the parent
                              of the node created.
  @param [out] NewLpiNode     If success, contains the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCreateLpiNode (
  IN  CONST CHAR8                   *LpiNameString,
  IN        UINT16                  Revision,
  IN        UINT64                  LevelId,
  IN        AML_NODE_HANDLE         ParentNode   OPTIONAL,
  OUT       AML_OBJECT_NODE_HANDLE  *NewLpiNode   OPTIONAL
  )
{
  EFI_STATUS              Status;
  AML_OBJECT_NODE_HANDLE  PackageNode;
  AML_OBJECT_NODE_HANDLE  IntegerNode;

  if ((LpiNameString == NULL)                           ||
      ((ParentNode == NULL) && (NewLpiNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  IntegerNode = NULL;

  Status = AmlCodeGenPackage (&PackageNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Create and attach Revision
  Status = AmlCodeGenInteger (Revision, &IntegerNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    IntegerNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PackageNode,
             (AML_NODE_HANDLE)IntegerNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  IntegerNode = NULL;

  // Create and attach LevelId
  Status = AmlCodeGenInteger (LevelId, &IntegerNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    IntegerNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PackageNode,
             (AML_NODE_HANDLE)IntegerNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  IntegerNode = NULL;

  // Create and attach Count. No LPI state is added, so 0.
  Status = AmlCodeGenInteger (0, &IntegerNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    IntegerNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PackageNode,
             (AML_NODE_HANDLE)IntegerNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  IntegerNode = NULL;

  Status = AmlCodeGenName (LpiNameString, PackageNode, ParentNode, NewLpiNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  return Status;

error_handler:
  AmlDeleteTree ((AML_NODE_HANDLE)PackageNode);
  if (IntegerNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
  }

  return Status;
}

/** Add an _LPI state to a LPI node created using AmlCreateLpiNode.

  AmlAddLpiState increments the Count of LPI states in the LPI node by one,
  and adds the following package:
    Package() {
      MinResidency,
      WorstCaseWakeLatency,
      Flags,
      ArchFlags,
      ResCntFreq,
      EnableParentState,
      (GenericRegisterDescriptor != NULL) ?           // Entry method. If a
        ResourceTemplate(GenericRegisterDescriptor) : // Register is given,
        Integer,                                      // use it. Use the
                                                      // Integer otherwise.
      ResourceTemplate() {                            // NULL Residency Counter
        Register (SystemMemory, 0, 0, 0, 0)
      },
      ResourceTemplate() {                            // NULL Usage Counter
        Register (SystemMemory, 0, 0, 0, 0)
      },
      ""                                              // NULL State Name
    },

  Cf ACPI 6.3 specification, s8.4.4 "Lower Power Idle States".

  @param [in]  MinResidency               Minimum Residency.
  @param [in]  WorstCaseWakeLatency       Worst case wake-up latency.
  @param [in]  Flags                      Flags.
  @param [in]  ArchFlags                  Architectural flags.
  @param [in]  ResCntFreq                 Residency Counter Frequency.
  @param [in]  EnableParentState          Enabled Parent State.
  @param [in]  GenericRegisterDescriptor  Entry Method.
                                          If not NULL, use this Register to
                                          describe the entry method address.
  @param [in]  Integer                    Entry Method.
                                          If GenericRegisterDescriptor is NULL,
                                          take this value.
  @param [in]  ResidencyCounterRegister   If not NULL, use it to populate the
                                          residency counter register.
  @param [in]  UsageCounterRegister       If not NULL, use it to populate the
                                          usage counter register.
  @param [in]  StateName                  If not NULL, use it to populate the
                                          state name.
  @param [in]  LpiNode                    Lpi node created with the function
                                          AmlCreateLpiNode to which the new LPI
                                          state is appended.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlAddLpiState (
  IN  UINT32                                  MinResidency,
  IN  UINT32                                  WorstCaseWakeLatency,
  IN  UINT32                                  Flags,
  IN  UINT32                                  ArchFlags,
  IN  UINT32                                  ResCntFreq,
  IN  UINT32                                  EnableParentState,
  IN  EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  *GenericRegisterDescriptor   OPTIONAL,
  IN  UINT64                                  Integer                     OPTIONAL,
  IN  EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  *ResidencyCounterRegister    OPTIONAL,
  IN  EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  *UsageCounterRegister        OPTIONAL,
  IN  CHAR8                                   *StateName                   OPTIONAL,
  IN  AML_OBJECT_NODE_HANDLE                  LpiNode
  )
{
  EFI_STATUS              Status;
  AML_DATA_NODE_HANDLE    RdNode;
  AML_OBJECT_NODE_HANDLE  PackageNode;
  AML_OBJECT_NODE_HANDLE  IntegerNode;
  AML_OBJECT_NODE_HANDLE  StringNode;
  AML_OBJECT_NODE_HANDLE  NewLpiPackageNode;
  AML_OBJECT_NODE_HANDLE  ResourceTemplateNode;

  UINT32                  Index;
  AML_OBJECT_NODE_HANDLE  CountNode;
  UINT64                  Count;

  if ((LpiNode == NULL)                                              ||
      (AmlGetNodeType ((AML_NODE_HANDLE)LpiNode) != EAmlNodeObject)  ||
      (!AmlNodeHasOpCode (LpiNode, AML_NAME_OP, 0)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  RdNode               = 0;
  StringNode           = NULL;
  IntegerNode          = NULL;
  ResourceTemplateNode = NULL;

  // AmlCreateLpiNode () created a LPI container such as:
  //  Name (_LPI, Package (
  //                0,  // Revision
  //                1,  // LevelId
  //                0   // Count
  //                ))
  // Get the LPI container, a PackageOp object node stored as the 2nd fixed
  // argument (i.e. index 1) of LpiNode.
  PackageNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
                                          LpiNode,
                                          EAmlParseIndexTerm1
                                          );
  if ((PackageNode == NULL)                                             ||
      (AmlGetNodeType ((AML_NODE_HANDLE)PackageNode) != EAmlNodeObject) ||
      (!AmlNodeHasOpCode (PackageNode, AML_PACKAGE_OP, 0)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  CountNode = NULL;
  // The third variable argument is the LPI Count node.
  for (Index = 0; Index < 3; Index++) {
    CountNode = (AML_OBJECT_NODE_HANDLE)AmlGetNextVariableArgument (
                                          (AML_NODE_HANDLE)PackageNode,
                                          (AML_NODE_HANDLE)CountNode
                                          );
    if (CountNode == NULL) {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }
  }

  Status = AmlNodeGetIntegerValue (CountNode, &Count);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlUpdateInteger (CountNode, Count + 1);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlCodeGenPackage (&NewLpiPackageNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // MinResidency
  Status = AmlCodeGenInteger (MinResidency, &IntegerNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    IntegerNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewLpiPackageNode,
             (AML_NODE_HANDLE)IntegerNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  IntegerNode = NULL;

  // WorstCaseWakeLatency
  Status = AmlCodeGenInteger (WorstCaseWakeLatency, &IntegerNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    IntegerNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewLpiPackageNode,
             (AML_NODE_HANDLE)IntegerNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  IntegerNode = NULL;

  // Flags
  Status = AmlCodeGenInteger (Flags, &IntegerNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    IntegerNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewLpiPackageNode,
             (AML_NODE_HANDLE)IntegerNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  IntegerNode = NULL;

  // ArchFlags
  Status = AmlCodeGenInteger (ArchFlags, &IntegerNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    IntegerNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewLpiPackageNode,
             (AML_NODE_HANDLE)IntegerNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  IntegerNode = NULL;

  // ResCntFreq
  Status = AmlCodeGenInteger (ResCntFreq, &IntegerNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    IntegerNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewLpiPackageNode,
             (AML_NODE_HANDLE)IntegerNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  IntegerNode = NULL;

  // EnableParentState
  Status = AmlCodeGenInteger (EnableParentState, &IntegerNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    IntegerNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewLpiPackageNode,
             (AML_NODE_HANDLE)IntegerNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  IntegerNode = NULL;

  // Entry Method
  if (GenericRegisterDescriptor != NULL) {
    // Entry Method: As a Register resource data
    Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      ResourceTemplateNode = NULL;
      goto error_handler;
    }

    Status = AmlCodeGenRdRegister (
               GenericRegisterDescriptor->AddressSpaceId,
               GenericRegisterDescriptor->RegisterBitWidth,
               GenericRegisterDescriptor->RegisterBitOffset,
               GenericRegisterDescriptor->Address,
               GenericRegisterDescriptor->AccessSize,
               NULL,
               &RdNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      RdNode = NULL;
      goto error_handler;
    }

    Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      goto error_handler;
    }

    RdNode = NULL;

    Status = AmlVarListAddTail (
               (AML_NODE_HANDLE)NewLpiPackageNode,
               (AML_NODE_HANDLE)ResourceTemplateNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      goto error_handler;
    }

    ResourceTemplateNode = NULL;
  } else {
    // Entry Method: As an integer
    Status = AmlCodeGenInteger (Integer, &IntegerNode);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      IntegerNode = NULL;
      goto error_handler;
    }

    Status = AmlVarListAddTail (
               (AML_NODE_HANDLE)NewLpiPackageNode,
               (AML_NODE_HANDLE)IntegerNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      goto error_handler;
    }

    IntegerNode = NULL;
  }

  // Residency Counter Register.
  Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    ResourceTemplateNode = NULL;
    goto error_handler;
  }

  if (ResidencyCounterRegister != NULL) {
    Status = AmlCodeGenRdRegister (
               ResidencyCounterRegister->AddressSpaceId,
               ResidencyCounterRegister->RegisterBitWidth,
               ResidencyCounterRegister->RegisterBitOffset,
               ResidencyCounterRegister->Address,
               ResidencyCounterRegister->AccessSize,
               NULL,
               &RdNode
               );
  } else {
    Status = AmlCodeGenRdRegister (
               EFI_ACPI_6_4_SYSTEM_MEMORY,
               0,
               0,
               0,
               0,
               NULL,
               &RdNode
               );
  }

  if (EFI_ERROR (Status)) {
    ASSERT (0);
    RdNode = NULL;
    goto error_handler;
  }

  Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  RdNode = NULL;

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewLpiPackageNode,
             (AML_NODE_HANDLE)ResourceTemplateNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  ResourceTemplateNode = NULL;

  // Usage Counter Register.
  Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    ResourceTemplateNode = NULL;
    goto error_handler;
  }

  if (UsageCounterRegister != NULL) {
    Status = AmlCodeGenRdRegister (
               UsageCounterRegister->AddressSpaceId,
               UsageCounterRegister->RegisterBitWidth,
               UsageCounterRegister->RegisterBitOffset,
               UsageCounterRegister->Address,
               UsageCounterRegister->AccessSize,
               NULL,
               &RdNode
               );
  } else {
    Status = AmlCodeGenRdRegister (
               EFI_ACPI_6_4_SYSTEM_MEMORY,
               0,
               0,
               0,
               0,
               NULL,
               &RdNode
               );
  }

  if (EFI_ERROR (Status)) {
    ASSERT (0);
    RdNode = NULL;
    goto error_handler;
  }

  Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  RdNode = NULL;

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewLpiPackageNode,
             (AML_NODE_HANDLE)ResourceTemplateNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  ResourceTemplateNode = NULL;

  // State name.
  if (UsageCounterRegister != NULL) {
    Status = AmlCodeGenString (StateName, &StringNode);
  } else {
    Status = AmlCodeGenString ("", &StringNode);
  }

  if (EFI_ERROR (Status)) {
    ASSERT (0);
    StringNode = NULL;
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewLpiPackageNode,
             (AML_NODE_HANDLE)StringNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  StringNode = NULL;

  // Add the new LPI state to the LpiNode.
  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PackageNode,
             (AML_NODE_HANDLE)NewLpiPackageNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  return Status;

error_handler:
  if (RdNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)RdNode);
  }

  if (NewLpiPackageNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)NewLpiPackageNode);
  }

  if (StringNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)StringNode);
  }

  if (IntegerNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
  }

  if (ResourceTemplateNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)ResourceTemplateNode);
  }

  return Status;
}

/** AML code generation for a _DSD device data object.

  AmlAddDeviceDataDescriptorPackage (Uuid, DsdNode, PackageNode) is
  equivalent of the following ASL code:
    ToUUID(Uuid),
    Package () {}

  Cf ACPI 6.4 specification, s6.2.5 "_DSD (Device Specific Data)".

  _DSD (Device Specific Data) Implementation Guide
  https://github.com/UEFI/DSD-Guide
  Per s3. "'Well-Known _DSD UUIDs and Data Structure Formats'"
  If creating a Device Properties data then UUID daffd814-6eba-4d8c-8a91-bc9bbf4aa301 should be used.

  @param [in]  Uuid           The Uuid of the descriptor to be created
  @param [in]  DsdNode        Node of the DSD Package.
  @param [out] PackageNode    If success, contains the created package node.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlAddDeviceDataDescriptorPackage (
  IN  CONST EFI_GUID                *Uuid,
  IN        AML_OBJECT_NODE_HANDLE  DsdNode,
  OUT       AML_OBJECT_NODE_HANDLE  *PackageNode
  )
{
  EFI_STATUS              Status;
  AML_OBJECT_NODE         *UuidNode;
  AML_DATA_NODE           *UuidDataNode;
  AML_OBJECT_NODE_HANDLE  DsdEntryList;

  if ((Uuid == NULL)     ||
      (PackageNode == NULL) ||
      (AmlGetNodeType ((AML_NODE_HANDLE)DsdNode) != EAmlNodeObject) ||
      (!AmlNodeHasOpCode (DsdNode, AML_NAME_OP, 0))                 ||
      !AmlNameOpCompareName (DsdNode, "_DSD"))
  {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  // Get the Package object node of the _DSD node,
  // which is the 2nd fixed argument (i.e. index 1).
  DsdEntryList = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
                                           DsdNode,
                                           EAmlParseIndexTerm1
                                           );
  if ((DsdEntryList == NULL)                                              ||
      (AmlGetNodeType ((AML_NODE_HANDLE)DsdEntryList) != EAmlNodeObject)  ||
      (!AmlNodeHasOpCode (DsdEntryList, AML_PACKAGE_OP, 0)))
  {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  *PackageNode = NULL;
  UuidDataNode = NULL;

  Status = AmlCodeGenBuffer (NULL, 0, &UuidNode);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeRaw,
             (CONST UINT8 *)Uuid,
             sizeof (EFI_GUID),
             &UuidDataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HEADER *)UuidNode,
             (AML_NODE_HEADER *)UuidDataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  UuidDataNode = NULL;

  // Append to the list of _DSD entries.
  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)DsdEntryList,
             (AML_NODE_HANDLE)UuidNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlCodeGenPackage (PackageNode);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler_detach;
  }

  // Append to the list of _DSD entries.
  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)DsdEntryList,
             (AML_NODE_HANDLE)*PackageNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler_detach;
  }

  return Status;

error_handler_detach:
  if (UuidNode != NULL) {
    AmlDetachNode ((AML_NODE_HANDLE)UuidNode);
  }

error_handler:
  if (UuidNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)UuidNode);
  }

  if (*PackageNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)*PackageNode);
    *PackageNode = NULL;
  }

  if (UuidDataNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)UuidDataNode);
  }

  return Status;
}

/** AML code generation to add a package with a name and value,
    to a parent package.
    This is useful to build the _DSD package but can be used in other cases.

  AmlAddNameIntegerPackage ("Name", Value, PackageNode) is
  equivalent of the following ASL code:
    Package (2) {"Name", Value}

  Cf ACPI 6.4 specification, s6.2.5 "_DSD (Device Specific Data)".

  @param [in]  Name           String to place in first entry of package
  @param [in]  Value          Integer to place in second entry of package
  @param [in]  PackageNode    Package to add new sub package to.

  @retval EFI_SUCCESS             Success.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlAddNameIntegerPackage (
  IN CHAR8                   *Name,
  IN UINT64                  Value,
  IN AML_OBJECT_NODE_HANDLE  PackageNode
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *NameNode;
  AML_OBJECT_NODE  *ValueNode;
  AML_OBJECT_NODE  *NewPackageNode;

  if ((Name == NULL) ||
      (AmlGetNodeType ((AML_NODE_HANDLE)PackageNode) != EAmlNodeObject) ||
      (!AmlNodeHasOpCode (PackageNode, AML_PACKAGE_OP, 0)))
  {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  NameNode  = NULL;
  ValueNode = NULL;

  // The new package entry.
  Status = AmlCodeGenPackage (&NewPackageNode);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  Status = AmlCodeGenString (Name, &NameNode);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewPackageNode,
             (AML_NODE_HANDLE)NameNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  NameNode = NULL;

  Status = AmlCodeGenInteger (Value, &ValueNode);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)NewPackageNode,
             (AML_NODE_HANDLE)ValueNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  ValueNode = NULL;

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PackageNode,
             (AML_NODE_HANDLE)NewPackageNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  return Status;

error_handler:
  if (NewPackageNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)NewPackageNode);
  }

  if (NameNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)NameNode);
  }

  if (ValueNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)ValueNode);
  }

  return Status;
}

/** Adds a register to the package

  @ingroup CodeGenApis

  @param [in]  Register     If provided, register that will be added to package.
                            otherwise NULL register will be added
  @param [in]  PackageNode  Package to add value to

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlAddRegisterToPackage (
  IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE  *Register OPTIONAL,
  IN AML_OBJECT_NODE_HANDLE                  PackageNode
  )
{
  EFI_STATUS              Status;
  AML_DATA_NODE_HANDLE    RdNode;
  AML_OBJECT_NODE_HANDLE  ResourceTemplateNode;

  RdNode = NULL;

  Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  if (Register != NULL) {
    Status = AmlCodeGenRdRegister (
               Register->AddressSpaceId,
               Register->RegisterBitWidth,
               Register->RegisterBitOffset,
               Register->Address,
               Register->AccessSize,
               NULL,
               &RdNode
               );
  } else {
    Status = AmlCodeGenRdRegister (
               EFI_ACPI_6_4_SYSTEM_MEMORY,
               0,
               0,
               0,
               0,
               NULL,
               &RdNode
               );
  }

  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  RdNode = NULL;

  Status = AmlVarListAddTail (
             (AML_NODE_HANDLE)PackageNode,
             (AML_NODE_HANDLE)ResourceTemplateNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  return Status;

error_handler:
  if (RdNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)RdNode);
  }

  if (ResourceTemplateNode != NULL) {
    AmlDeleteTree ((AML_NODE_HANDLE)ResourceTemplateNode);
  }

  return Status;
}

/** Utility function to check if generic address points to NULL

  @param [in]  Address  Pointer to the Generic address

  @retval TRUE          Address is system memory with an Address of 0.
  @retval FALSE         Address does not point to NULL.
**/
STATIC
BOOLEAN
EFIAPI
IsNullGenericAddress (
  IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE  *Address
  )
{
  if ((Address == NULL) ||
      ((Address->AddressSpaceId == EFI_ACPI_6_4_SYSTEM_MEMORY) &&
       (Address->Address == 0x0)))
  {
    return TRUE;
  }

  return FALSE;
}

/** Adds an integer or register to the package

  @ingroup CodeGenApis

  @param [in]  Register     If provided, register that will be added to package
  @param [in]  Integer      If Register is NULL, integer that will be added to the package
  @param [in]  PackageNode  Package to add value to

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlAddRegisterOrIntegerToPackage (
  IN EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE  *Register OPTIONAL,
  IN UINT32                                  Integer,
  IN AML_OBJECT_NODE_HANDLE                  PackageNode
  )
{
  EFI_STATUS              Status;
  AML_OBJECT_NODE_HANDLE  IntegerNode;

  IntegerNode = NULL;

  if (!IsNullGenericAddress (Register)) {
    Status = AmlAddRegisterToPackage (Register, PackageNode);
  } else {
    Status = AmlCodeGenInteger (Integer, &IntegerNode);
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return Status;
    }

    Status = AmlVarListAddTail (
               (AML_NODE_HANDLE)PackageNode,
               (AML_NODE_HANDLE)IntegerNode
               );
  }

  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    if (IntegerNode != NULL) {
      AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
    }
  }

  return Status;
}

/** Create a _CPC node.

  Creates and optionally adds the following node
   Name(_CPC, Package()
   {
    NumEntries,                              // Integer
    Revision,                                // Integer
    HighestPerformance,                      // Integer or Buffer (Resource Descriptor)
    NominalPerformance,                      // Integer or Buffer (Resource Descriptor)
    LowestNonlinearPerformance,              // Integer or Buffer (Resource Descriptor)
    LowestPerformance,                       // Integer or Buffer (Resource Descriptor)
    GuaranteedPerformanceRegister,           // Buffer (Resource Descriptor)
    DesiredPerformanceRegister ,             // Buffer (Resource Descriptor)
    MinimumPerformanceRegister ,             // Buffer (Resource Descriptor)
    MaximumPerformanceRegister ,             // Buffer (Resource Descriptor)
    PerformanceReductionToleranceRegister,   // Buffer (Resource Descriptor)
    TimeWindowRegister,                      // Buffer (Resource Descriptor)
    CounterWraparoundTime,                   // Integer or Buffer (Resource Descriptor)
    ReferencePerformanceCounterRegister,     // Buffer (Resource Descriptor)
    DeliveredPerformanceCounterRegister,     // Buffer (Resource Descriptor)
    PerformanceLimitedRegister,              // Buffer (Resource Descriptor)
    CPPCEnableRegister                       // Buffer (Resource Descriptor)
    AutonomousSelectionEnable,               // Integer or Buffer (Resource Descriptor)
    AutonomousActivityWindowRegister,        // Buffer (Resource Descriptor)
    EnergyPerformancePreferenceRegister,     // Buffer (Resource Descriptor)
    ReferencePerformance                     // Integer or Buffer (Resource Descriptor)
    LowestFrequency,                         // Integer or Buffer (Resource Descriptor)
    NominalFrequency                         // Integer or Buffer (Resource Descriptor)
  })

  If resource buffer is NULL then integer will be used.

  Cf. ACPI 6.4, s8.4.7.1 _CPC (Continuous Performance Control)

  @ingroup CodeGenApis

  @param [in]  CpcInfo               CpcInfo object
  @param [in]  ParentNode            If provided, set ParentNode as the parent
                                     of the node created.
  @param [out] NewCpcNode            If success and provided, contains the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCreateCpcNode (
  IN  AML_CPC_INFO            *CpcInfo,
  IN  AML_NODE_HANDLE         ParentNode   OPTIONAL,
  OUT AML_OBJECT_NODE_HANDLE  *NewCpcNode   OPTIONAL
  )
{
  EFI_STATUS              Status;
  AML_OBJECT_NODE_HANDLE  CpcNode;
  AML_OBJECT_NODE_HANDLE  CpcPackage;
  UINT32                  NumberOfEntries;

  if ((CpcInfo == NULL) ||
      ((ParentNode == NULL) && (NewCpcNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Revision 3 per ACPI 6.4 specification
  if (CpcInfo->Revision == 3) {
    // NumEntries 23 per ACPI 6.4 specification
    NumberOfEntries = 23;
  } else {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if ((IsNullGenericAddress (&CpcInfo->HighestPerformanceBuffer) &&
       (CpcInfo->HighestPerformanceInteger == 0)) ||
      (IsNullGenericAddress (&CpcInfo->NominalPerformanceBuffer) &&
       (CpcInfo->NominalPerformanceInteger == 0)) ||
      (IsNullGenericAddress (&CpcInfo->LowestNonlinearPerformanceBuffer) &&
       (CpcInfo->LowestNonlinearPerformanceInteger == 0)) ||
      (IsNullGenericAddress (&CpcInfo->LowestPerformanceBuffer) &&
       (CpcInfo->LowestPerformanceInteger == 0)) ||
      IsNullGenericAddress (&CpcInfo->DesiredPerformanceRegister) ||
      IsNullGenericAddress (&CpcInfo->ReferencePerformanceCounterRegister) ||
      IsNullGenericAddress (&CpcInfo->DeliveredPerformanceCounterRegister) ||
      IsNullGenericAddress (&CpcInfo->PerformanceLimitedRegister))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  CpcPackage = NULL;

  Status = AmlCodeGenNamePackage ("_CPC", NULL, &CpcNode);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  // Get the Package object node of the _CPC node,
  // which is the 2nd fixed argument (i.e. index 1).
  CpcPackage = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
                                         CpcNode,
                                         EAmlParseIndexTerm1
                                         );
  if ((CpcPackage == NULL)                                              ||
      (AmlGetNodeType ((AML_NODE_HANDLE)CpcPackage) != EAmlNodeObject)  ||
      (!AmlNodeHasOpCode (CpcPackage, AML_PACKAGE_OP, 0)))
  {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             NULL,
             NumberOfEntries,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             NULL,
             CpcInfo->Revision,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             &CpcInfo->HighestPerformanceBuffer,
             CpcInfo->HighestPerformanceInteger,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             &CpcInfo->NominalPerformanceBuffer,
             CpcInfo->NominalPerformanceInteger,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             &CpcInfo->LowestNonlinearPerformanceBuffer,
             CpcInfo->LowestNonlinearPerformanceInteger,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             &CpcInfo->LowestPerformanceBuffer,
             CpcInfo->LowestPerformanceInteger,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->GuaranteedPerformanceRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->DesiredPerformanceRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->MinimumPerformanceRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->MaximumPerformanceRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->PerformanceReductionToleranceRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->TimeWindowRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             &CpcInfo->CounterWraparoundTimeBuffer,
             CpcInfo->CounterWraparoundTimeInteger,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->ReferencePerformanceCounterRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->DeliveredPerformanceCounterRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->PerformanceLimitedRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->CPPCEnableRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             &CpcInfo->AutonomousSelectionEnableBuffer,
             CpcInfo->AutonomousSelectionEnableInteger,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->AutonomousActivityWindowRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterToPackage (&CpcInfo->EnergyPerformancePreferenceRegister, CpcPackage);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             &CpcInfo->ReferencePerformanceBuffer,
             CpcInfo->ReferencePerformanceInteger,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             &CpcInfo->LowestFrequencyBuffer,
             CpcInfo->LowestFrequencyInteger,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = AmlAddRegisterOrIntegerToPackage (
             &CpcInfo->NominalFrequencyBuffer,
             CpcInfo->NominalFrequencyInteger,
             CpcPackage
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  Status = LinkNode (CpcNode, ParentNode, NewCpcNode);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    goto error_handler;
  }

  return Status;

error_handler:
  AmlDeleteTree ((AML_NODE_HANDLE)CpcNode);
  return Status;
}
