/** @file
  AML Resource Data Code Generation.

  Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
  Copyright (C) 2023 - 2025 Advanced Micro Devices, Inc. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Glossary:
  - Rd or RD   - Resource Data
  - Rds or RDS - Resource Data Small
  - Rdl or RDL - Resource Data Large
**/

#include <AmlNodeDefines.h>
#include <CodeGen/AmlResourceDataCodeGen.h>

#include <AmlCoreInterface.h>
#include <AmlDefines.h>
#include <Api/AmlApiHelper.h>
#include <Tree/AmlNode.h>
#include <ResourceData/AmlResourceData.h>
#include <Utils/AmlUtility.h>

/** If ParentNode is not NULL, append RdNode.
    If NewRdNode is not NULL, update its value to RdNode.

  @param [in]  RdNode       Newly created Resource Data node.
                            RdNode is deleted if an error occurs.
  @param [in]  ParentNode   If not NULL, ParentNode must:
                             - be a NameOp node, i.e. have the AML_NAME_OP
                               opcode (cf "Name ()" ASL statement)
                             - contain a list of resource data elements
                               (cf "ResourceTemplate ()" ASL statement)
                            RdNode is then added at the end of the variable
                            list of resource data elements, but before the
                            "End Tag" Resource Data.
  @param [out] NewRdNode    If not NULL:
                             - and Success, contains RdNode.
                             - and Error, reset to NULL.

  @retval  EFI_SUCCESS            The function completed successfully.
  @retval  EFI_INVALID_PARAMETER  Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
LinkRdNode (
  IN  AML_DATA_NODE    *RdNode,
  IN  AML_OBJECT_NODE  *ParentNode,
  OUT AML_DATA_NODE    **NewRdNode
  )
{
  EFI_STATUS       Status;
  EFI_STATUS       Status1;
  AML_OBJECT_NODE  *BufferOpNode;

  if (NewRdNode != NULL) {
    *NewRdNode = NULL;
  }

  if (ParentNode != NULL) {
    // Check this is a NameOp node.
    if ((!AmlNodeHasOpCode (ParentNode, AML_NAME_OP, 0))) {
      ASSERT (0);
      Status = EFI_INVALID_PARAMETER;
      goto error_handler;
    }

    // Get the value which is represented as a BufferOp object node
    // which is the 2nd fixed argument (i.e. index 1).
    BufferOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
                                             ParentNode,
                                             EAmlParseIndexTerm1
                                             );
    if ((BufferOpNode == NULL)                                             ||
        (AmlGetNodeType ((AML_NODE_HANDLE)BufferOpNode) != EAmlNodeObject) ||
        (!AmlNodeHasOpCode (BufferOpNode, AML_BUFFER_OP, 0)))
    {
      ASSERT (0);
      Status = EFI_INVALID_PARAMETER;
      goto error_handler;
    }

    // Add RdNode as the last element, but before the EndTag.
    Status = AmlAppendRdNode (BufferOpNode, RdNode);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      goto error_handler;
    }
  }

  if (NewRdNode != NULL) {
    *NewRdNode = RdNode;
  }

  return EFI_SUCCESS;

error_handler:
  Status1 = AmlDeleteTree ((AML_NODE_HEADER *)RdNode);
  ASSERT_EFI_ERROR (Status1);
  // Return original error.
  return Status;
}

/** Construct the TypeSpecificFlags field for IO ranges.

  See ACPI 6.4 spec, s19.6.34 for more.

  @param [in]  IsaRanges            Possible values are:
                                     0-Reserved
                                     1-NonISAOnly
                                     2-ISAOnly
                                     3-EntireRange
                                    See ACPI 6.4 spec, s19.6.34 for more.
  @param [in]  IsDenseTranslation   TranslationDensity parameter.
  @param [in]  IsTypeStatic         TranslationType parameter.

  @return A type specific flags value.
          MAX_UINT8 if error.
**/
STATIC
UINT8
EFIAPI
RdIoRangeSpecificFlags (
  IN  UINT8    IsaRanges,
  IN  BOOLEAN  IsDenseTranslation,
  IN  BOOLEAN  IsTypeStatic
  )
{
  // Only check type specific parameters.
  if (IsaRanges > 3) {
    ASSERT (0);
    return MAX_UINT8;
  }

  // Construct TypeSpecificFlags and call the generic function.
  // Cf ACPI 6.4 specification, Table 6.50:
  // "Table 6.50: I/O Resource Flag (Resource Type = 1) Definitions"
  return IsaRanges                 |
         (IsTypeStatic ? 0 : BIT4) |
         (IsDenseTranslation ? 0 : BIT5);
}

/** Construct the TypeSpecificFlags field for Memory ranges.

  @param [in]  Cacheable            Possible values are:
                                    0-The memory is non-cacheable
                                    1-The memory is cacheable
                                    2-The memory is cacheable and supports
                                      write combining
                                    3-The memory is cacheable and prefetchable
  @param [in]  IsReadWrite          ReadAndWrite parameter.
  @param [in]  MemoryRangeType      Possible values are:
                                      0-AddressRangeMemory
                                      1-AddressRangeReserved
                                      2-AddressRangeACPI
                                      3-AddressRangeNVS
                                    See ACPI 6.4 spec, s19.6.35 for more.
  @param [in]  IsTypeStatic         TranslationType parameter.

  @return A type specific flags value.
          MAX_UINT8 if error.
**/
STATIC
UINT8
EFIAPI
MemoryRangeSpecificFlags (
  IN  UINT8    Cacheable,
  IN  BOOLEAN  IsReadWrite,
  IN  UINT8    MemoryRangeType,
  IN  BOOLEAN  IsTypeStatic
  )
{
  // Only check type specific parameters.
  if ((Cacheable > 3) ||
      (MemoryRangeType > 3))
  {
    ASSERT (0);
    return MAX_UINT8;
  }

  // Construct TypeSpecificFlags and call the generic function.
  // Cf ACPI 6.4 specification, Table 6.49:
  // "Memory Resource Flag (Resource Type = 0) Definitions"
  return (IsReadWrite ? BIT0 : 0)  |
         (Cacheable << 1)          |
         (MemoryRangeType << 3)    |
         (IsTypeStatic ? 0 : BIT5);
}

/** Construct the GeneralFlags field of any Address Space Resource Descriptors.

  E.g.:
  ACPI 6.4 specification, s6.4.3.5.1 "QWord Address Space Descriptor"
  for QWord

  See ACPI 6.4 spec, s19.6.36 for more.

  @param [in]  IsPosDecode          Decode parameter
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.

  @return A type specific flags value.
**/
STATIC
UINT8
EFIAPI
AddressSpaceGeneralFlags (
  IN  BOOLEAN  IsPosDecode,
  IN  BOOLEAN  IsMinFixed,
  IN  BOOLEAN  IsMaxFixed
  )
{
  return (IsPosDecode ? 0 : BIT1)    |
         (IsMinFixed ? BIT2 : 0)     |
         (IsMaxFixed ? BIT3 : 0);
}

/** Code generation for the "DWordSpace ()" ASL function.

  The Resource Data effectively created is a DWord Address Space Resource
  Data. Cf ACPI 6.4:
   - s6.4.3.5.2 "DWord Address Space Descriptor".
   - s19.6.36 "DWordSpace".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  See ACPI 6.4 spec, s19.6.36 for more.

  @param [in]  ResourceType         Resource type.
                                    Possible values are:
                                      0:        Memory range
                                      1:        I/O range
                                      2:        Bus number range
                                      3-191:    Reserved
                                      192-255:  Hardware Vendor Defined
                                    See ACPI 6.4 spec, s6.4.3.5.2 for more.
  @param [in]  IsResourceConsumer   ResourceUsage parameter.
  @param [in]  IsPosDecode          Decode parameter
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.
  @param [in]  TypeSpecificFlags    Type specific flags.
                                    See ACPI 6.4 spec, s6.4.3.5.5
                                    "Resource Type Specific Flags".
  @param [in]  AddressGranularity   Address granularity.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  AddressTranslation   Address translation.
  @param [in]  RangeLength          Range length.
  @param [in]  ResourceSourceIndex  Resource Source index.
                                    Unused. Must be 0.
  @param [in]  ResourceSource       Resource Source.
                                    Unused. Must be NULL.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenRdDWordSpace (
  IN        UINT8 ResourceType,
  IN        BOOLEAN IsResourceConsumer,
  IN        BOOLEAN IsPosDecode,
  IN        BOOLEAN IsMinFixed,
  IN        BOOLEAN IsMaxFixed,
  IN        UINT8 TypeSpecificFlags,
  IN        UINT32 AddressGranularity,
  IN        UINT32 AddressMinimum,
  IN        UINT32 AddressMaximum,
  IN        UINT32 AddressTranslation,
  IN        UINT32 RangeLength,
  IN        UINT8 ResourceSourceIndex,
  IN  CONST CHAR8 *ResourceSource,
  IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  EFI_STATUS                               Status;
  AML_DATA_NODE                            *RdNode;
  EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR  RdDWord;

  // ResourceSource and ResourceSourceIndex are unused.
  if ((TypeSpecificFlags == MAX_UINT8)  ||
      (ResourceSourceIndex != 0)        ||
      (ResourceSource != NULL)          ||
      ((NameOpNode == NULL) && (NewRdNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = CheckAddressSpaceFields (
             IsMinFixed,
             IsMaxFixed,
             AddressGranularity,
             AddressMinimum,
             AddressMaximum,
             AddressTranslation,
             RangeLength
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Header
  RdDWord.Header.Header.Bits.Name =
    ACPI_LARGE_DWORD_ADDRESS_SPACE_DESCRIPTOR_NAME;
  RdDWord.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
  RdDWord.Header.Length           = sizeof (EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR) -
                                    sizeof (ACPI_LARGE_RESOURCE_HEADER);

  // Body
  RdDWord.ResType = ResourceType;
  RdDWord.GenFlag = AddressSpaceGeneralFlags (
                      IsPosDecode,
                      IsMinFixed,
                      IsMaxFixed
                      );
  RdDWord.SpecificFlag          = TypeSpecificFlags;
  RdDWord.AddrSpaceGranularity  = AddressGranularity;
  RdDWord.AddrRangeMin          = AddressMinimum;
  RdDWord.AddrRangeMax          = AddressMaximum;
  RdDWord.AddrTranslationOffset = AddressTranslation;
  RdDWord.AddrLen               = RangeLength;

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             (UINT8 *)&RdDWord,
             sizeof (EFI_ACPI_DWORD_ADDRESS_SPACE_DESCRIPTOR),
             &RdNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  return LinkRdNode (RdNode, NameOpNode, NewRdNode);
}

/** Code generation for the "DWordIO ()" ASL function.

  The Resource Data effectively created is a DWord Address Space Resource
  Data. Cf ACPI 6.4:
   - s6.4.3.5.2 "DWord Address Space Descriptor".
   - s19.6.34 "DWordIO".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  See ACPI 6.4 spec, s19.6.34 for more.

  @param [in]  IsResourceConsumer   ResourceUsage parameter.
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.
  @param [in]  IsPosDecode          Decode parameter
  @param [in]  IsaRanges            Possible values are:
                                     0-Reserved
                                     1-NonISAOnly
                                     2-ISAOnly
                                     3-EntireRange
  @param [in]  AddressGranularity   Address granularity.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  AddressTranslation   Address translation.
  @param [in]  RangeLength          Range length.
  @param [in]  ResourceSourceIndex  Resource Source index.
                                    Unused. Must be 0.
  @param [in]  ResourceSource       Resource Source.
                                    Unused. Must be NULL.
  @param [in]  IsDenseTranslation   TranslationDensity parameter.
  @param [in]  IsTypeStatic         TranslationType parameter.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdDWordIo (
  IN        BOOLEAN IsResourceConsumer,
  IN        BOOLEAN IsMinFixed,
  IN        BOOLEAN IsMaxFixed,
  IN        BOOLEAN IsPosDecode,
  IN        UINT8 IsaRanges,
  IN        UINT32 AddressGranularity,
  IN        UINT32 AddressMinimum,
  IN        UINT32 AddressMaximum,
  IN        UINT32 AddressTranslation,
  IN        UINT32 RangeLength,
  IN        UINT8 ResourceSourceIndex,
  IN  CONST CHAR8 *ResourceSource,
  IN        BOOLEAN IsDenseTranslation,
  IN        BOOLEAN IsTypeStatic,
  IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  return AmlCodeGenRdDWordSpace (
           ACPI_ADDRESS_SPACE_TYPE_IO,
           IsResourceConsumer,
           IsPosDecode,
           IsMinFixed,
           IsMaxFixed,
           RdIoRangeSpecificFlags (
             IsaRanges,
             IsDenseTranslation,
             IsTypeStatic
             ),
           AddressGranularity,
           AddressMinimum,
           AddressMaximum,
           AddressTranslation,
           RangeLength,
           ResourceSourceIndex,
           ResourceSource,
           NameOpNode,
           NewRdNode
           );
}

/** Code generation for the "DWordMemory ()" ASL function.

  The Resource Data effectively created is a DWord Address Space Resource
  Data. Cf ACPI 6.4:
   - s6.4.3.5.2 "DWord Address Space Descriptor".
   - s19.6.35 "DWordMemory".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  See ACPI 6.4 spec, s19.6.35 for more.

  @param [in]  IsResourceConsumer   ResourceUsage parameter.
  @param [in]  IsPosDecode          Decode parameter
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.
  @param [in]  Cacheable            Possible values are:
                                    0-The memory is non-cacheable
                                    1-The memory is cacheable
                                    2-The memory is cacheable and supports
                                      write combining
                                    3-The memory is cacheable and prefetchable
  @param [in]  IsReadWrite          ReadAndWrite parameter.
  @param [in]  AddressGranularity   Address granularity.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  AddressTranslation   Address translation.
  @param [in]  RangeLength          Range length.
  @param [in]  ResourceSourceIndex  Resource Source index.
                                    Unused. Must be 0.
  @param [in]  ResourceSource       Resource Source.
                                    Unused. Must be NULL.
  @param [in]  MemoryRangeType      Possible values are:
                                      0-AddressRangeMemory
                                      1-AddressRangeReserved
                                      2-AddressRangeACPI
                                      3-AddressRangeNVS
  @param [in]  IsTypeStatic         TranslationType parameter.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdDWordMemory (
  IN        BOOLEAN IsResourceConsumer,
  IN        BOOLEAN IsPosDecode,
  IN        BOOLEAN IsMinFixed,
  IN        BOOLEAN IsMaxFixed,
  IN        AML_MEMORY_ATTRIBUTES_MEM Cacheable,
  IN        BOOLEAN IsReadWrite,
  IN        UINT32 AddressGranularity,
  IN        UINT32 AddressMinimum,
  IN        UINT32 AddressMaximum,
  IN        UINT32 AddressTranslation,
  IN        UINT32 RangeLength,
  IN        UINT8 ResourceSourceIndex,
  IN  CONST CHAR8 *ResourceSource,
  IN        AML_MEMORY_ATTRIBUTES_MTP MemoryRangeType,
  IN        BOOLEAN IsTypeStatic,
  IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  return AmlCodeGenRdDWordSpace (
           ACPI_ADDRESS_SPACE_TYPE_MEM,
           IsResourceConsumer,
           IsPosDecode,
           IsMinFixed,
           IsMaxFixed,
           MemoryRangeSpecificFlags (
             Cacheable,
             IsReadWrite,
             MemoryRangeType,
             IsTypeStatic
             ),
           AddressGranularity,
           AddressMinimum,
           AddressMaximum,
           AddressTranslation,
           RangeLength,
           ResourceSourceIndex,
           ResourceSource,
           NameOpNode,
           NewRdNode
           );
}

/** Code generation for the "Memory32Fixed ()" ASL macro.

  The Resource Data effectively created is a 32-bit Memory Resource
  Data. Cf ACPI 6.4:
   - s19.6.83 "Memory Resource Descriptor Macro".
   - s19.2.8 "Memory32FixedTerm".

  See ACPI 6.4 spec, s19.2.8 for more.

  @param [in]  IsReadWrite          ReadAndWrite parameter.
  @param [in]  Address              AddressBase parameter.
  @param [in]  RangeLength          Range length.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewMemNode           If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdMemory32Fixed (
  BOOLEAN                 IsReadWrite,
  UINT32                  Address,
  UINT32                  RangeLength,
  AML_OBJECT_NODE_HANDLE  NameOpNode,
  AML_DATA_NODE_HANDLE    *NewMemNode
  )
{
  EFI_STATUS                                     Status;
  AML_DATA_NODE                                  *MemNode;
  EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR  RangeDesc;

  RangeDesc.Header.Header.Byte = ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR;
  RangeDesc.Header.Length      = sizeof (EFI_ACPI_32_BIT_FIXED_MEMORY_RANGE_DESCRIPTOR) -
                                 sizeof (ACPI_LARGE_RESOURCE_HEADER);
  RangeDesc.Information = IsReadWrite ? BIT0 : 0;
  RangeDesc.BaseAddress = Address;
  RangeDesc.Length      = RangeLength;

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             (UINT8 *)&RangeDesc,
             sizeof (RangeDesc),
             &MemNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  return LinkRdNode (MemNode, NameOpNode, NewMemNode);
}

/** Code generation for the "WordSpace ()" ASL function.

  The Resource Data effectively created is a Word Address Space Resource
  Data. Cf ACPI 6.4:
   - s6.4.3.5.3 "Word Address Space Descriptor".
   - s19.6.151 "WordSpace".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  See ACPI 6.4 spec, s19.6.151 for more.

  @param [in]  ResourceType         Resource type.
                                    Possible values are:
                                      0:        Memory range
                                      1:        I/O range
                                      2:        Bus number range
                                      3-191:    Reserved
                                      192-255:  Hardware Vendor Defined
                                    See ACPI 6.4 spec, s6.4.3.5.3 for more.
  @param [in]  IsResourceConsumer   ResourceUsage parameter.
  @param [in]  IsPosDecode          Decode parameter
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.
  @param [in]  TypeSpecificFlags    Type specific flags.
                                    See ACPI 6.4 spec, s6.4.3.5.5
                                    "Resource Type Specific Flags".
  @param [in]  AddressGranularity   Address granularity.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  AddressTranslation   Address translation.
  @param [in]  RangeLength          Range length.
  @param [in]  ResourceSourceIndex  Resource Source index.
                                    Unused. Must be 0.
  @param [in]  ResourceSource       Resource Source.
                                    Unused. Must be NULL.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenRdWordSpace (
  IN        UINT8 ResourceType,
  IN        BOOLEAN IsResourceConsumer,
  IN        BOOLEAN IsPosDecode,
  IN        BOOLEAN IsMinFixed,
  IN        BOOLEAN IsMaxFixed,
  IN        UINT8 TypeSpecificFlags,
  IN        UINT16 AddressGranularity,
  IN        UINT16 AddressMinimum,
  IN        UINT16 AddressMaximum,
  IN        UINT16 AddressTranslation,
  IN        UINT16 RangeLength,
  IN        UINT8 ResourceSourceIndex,
  IN  CONST CHAR8 *ResourceSource,
  IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  EFI_STATUS                              Status;
  AML_DATA_NODE                           *RdNode;
  EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR  Rdword;

  // ResourceSource and ResourceSourceIndex are unused.
  if ((TypeSpecificFlags == MAX_UINT8)  ||
      (ResourceSourceIndex != 0)        ||
      (ResourceSource != NULL)          ||
      ((NameOpNode == NULL) && (NewRdNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = CheckAddressSpaceFields (
             IsMinFixed,
             IsMaxFixed,
             AddressGranularity,
             AddressMinimum,
             AddressMaximum,
             AddressTranslation,
             RangeLength
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Header
  Rdword.Header.Header.Bits.Name =
    ACPI_LARGE_WORD_ADDRESS_SPACE_DESCRIPTOR_NAME;
  Rdword.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
  Rdword.Header.Length           = sizeof (EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR) -
                                   sizeof (ACPI_LARGE_RESOURCE_HEADER);

  // Body
  Rdword.ResType = ResourceType;
  Rdword.GenFlag = AddressSpaceGeneralFlags (
                     IsPosDecode,
                     IsMinFixed,
                     IsMaxFixed
                     );
  Rdword.SpecificFlag          = TypeSpecificFlags;
  Rdword.AddrSpaceGranularity  = AddressGranularity;
  Rdword.AddrRangeMin          = AddressMinimum;
  Rdword.AddrRangeMax          = AddressMaximum;
  Rdword.AddrTranslationOffset = AddressTranslation;
  Rdword.AddrLen               = RangeLength;

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             (UINT8 *)&Rdword,
             sizeof (EFI_ACPI_WORD_ADDRESS_SPACE_DESCRIPTOR),
             &RdNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  return LinkRdNode (RdNode, NameOpNode, NewRdNode);
}

/** Code generation for the "WordBusNumber ()" ASL function.

  The Resource Data effectively created is a Word Address Space Resource
  Data. Cf ACPI 6.4:
   - s6.4.3.5.3 "Word Address Space Descriptor".
   - s19.6.149 "WordBusNumber".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  See ACPI 6.4 spec, s19.6.149 for more.

  @param [in]  IsResourceConsumer   ResourceUsage parameter.
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.
  @param [in]  IsPosDecode          Decode parameter
  @param [in]  AddressGranularity   Address granularity.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  AddressTranslation   Address translation.
  @param [in]  RangeLength          Range length.
  @param [in]  ResourceSourceIndex  Resource Source index.
                                    Unused. Must be 0.
  @param [in]  ResourceSource       Resource Source.
                                    Unused. Must be NULL.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdWordBusNumber (
  IN        BOOLEAN IsResourceConsumer,
  IN        BOOLEAN IsMinFixed,
  IN        BOOLEAN IsMaxFixed,
  IN        BOOLEAN IsPosDecode,
  IN        UINT16 AddressGranularity,
  IN        UINT16 AddressMinimum,
  IN        UINT16 AddressMaximum,
  IN        UINT16 AddressTranslation,
  IN        UINT16 RangeLength,
  IN        UINT8 ResourceSourceIndex,
  IN  CONST CHAR8 *ResourceSource,
  IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  // There is no Type Specific Flags for buses.
  return AmlCodeGenRdWordSpace (
           ACPI_ADDRESS_SPACE_TYPE_BUS,
           IsResourceConsumer,
           IsPosDecode,
           IsMinFixed,
           IsMaxFixed,
           0,
           AddressGranularity,
           AddressMinimum,
           AddressMaximum,
           AddressTranslation,
           RangeLength,
           ResourceSourceIndex,
           ResourceSource,
           NameOpNode,
           NewRdNode
           );
}

/** Code generation for the "WordIO ()" ASL function.

  The Resource Data effectively created is a Word Address Space Resource
  Data. Cf ACPI 6.5:
   - s6.4.3.5.3 "Word Address Space Descriptor".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  @param [in]  IsResourceConsumer   ResourceUsage parameter.
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.
  @param [in]  IsPosDecode          Decode parameter
  @param [in]  IsaRanges            Possible values are:
                                     0-Reserved
                                     1-NonISAOnly
                                     2-ISAOnly
                                     3-EntireRange
  @param [in]  AddressGranularity   Address granularity.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  AddressTranslation   Address translation.
  @param [in]  RangeLength          Range length.
  @param [in]  ResourceSourceIndex  Resource Source index.
                                    Not supported. Must be 0.
  @param [in]  ResourceSource       Resource Source.
                                    Not supported. Must be NULL.
  @param [in]  IsDenseTranslation   TranslationDensity parameter.
  @param [in]  IsTypeStatic         TranslationType parameter.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdWordIo (
  IN        BOOLEAN IsResourceConsumer,
  IN        BOOLEAN IsMinFixed,
  IN        BOOLEAN IsMaxFixed,
  IN        BOOLEAN IsPosDecode,
  IN        UINT8 IsaRanges,
  IN        UINT16 AddressGranularity,
  IN        UINT16 AddressMinimum,
  IN        UINT16 AddressMaximum,
  IN        UINT16 AddressTranslation,
  IN        UINT16 RangeLength,
  IN        UINT8 ResourceSourceIndex,
  IN  CONST CHAR8 *ResourceSource,
  IN        BOOLEAN IsDenseTranslation,
  IN        BOOLEAN IsTypeStatic,
  IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  return AmlCodeGenRdWordSpace (
           ACPI_ADDRESS_SPACE_TYPE_IO,
           IsResourceConsumer,
           IsPosDecode,
           IsMinFixed,
           IsMaxFixed,
           RdIoRangeSpecificFlags (
             IsaRanges,
             IsDenseTranslation,
             IsTypeStatic
             ),
           AddressGranularity,
           AddressMinimum,
           AddressMaximum,
           AddressTranslation,
           RangeLength,
           ResourceSourceIndex,
           ResourceSource,
           NameOpNode,
           NewRdNode
           );
}

/** Code generation for the "QWordSpace ()" ASL function.

  The Resource Data effectively created is a QWord Address Space Resource
  Data. Cf ACPI 6.4:
   - s6.4.3.5.1 "QWord Address Space Descriptor".
   - s19.6.111 "QWordSpace".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  See ACPI 6.4 spec, s19.6.111 for more.

  @param [in]  ResourceType         Resource type.
                                    Possible values are:
                                      0:        Memory range
                                      1:        I/O range
                                      2:        Bus number range
                                      3-191:    Reserved
                                      192-255:  Hardware Vendor Defined
                                    See ACPI 6.4 spec, s6.4.3.5.1 for more.
  @param [in]  IsResourceConsumer   ResourceUsage parameter.
  @param [in]  IsPosDecode          Decode parameter
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.
  @param [in]  TypeSpecificFlags    Type specific flags.
                                    See ACPI 6.4 spec, s6.4.3.5.5
                                    "Resource Type Specific Flags".
  @param [in]  AddressGranularity   Address granularity.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  AddressTranslation   Address translation.
  @param [in]  RangeLength          Range length.
  @param [in]  ResourceSourceIndex  Resource Source index.
                                    Unused. Must be 0.
  @param [in]  ResourceSource       Resource Source.
                                    Unused. Must be NULL.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenRdQWordSpace (
  IN        UINT8 ResourceType,
  IN        BOOLEAN IsResourceConsumer,
  IN        BOOLEAN IsPosDecode,
  IN        BOOLEAN IsMinFixed,
  IN        BOOLEAN IsMaxFixed,
  IN        UINT8 TypeSpecificFlags,
  IN        UINT64 AddressGranularity,
  IN        UINT64 AddressMinimum,
  IN        UINT64 AddressMaximum,
  IN        UINT64 AddressTranslation,
  IN        UINT64 RangeLength,
  IN        UINT8 ResourceSourceIndex,
  IN  CONST CHAR8 *ResourceSource,
  IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  EFI_STATUS                               Status;
  AML_DATA_NODE                            *RdNode;
  EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR  RdQword;

  // ResourceSource and ResourceSourceIndex are unused.
  if ((TypeSpecificFlags == MAX_UINT8)  ||
      (ResourceSourceIndex != 0)        ||
      (ResourceSource != NULL)          ||
      ((NameOpNode == NULL) && (NewRdNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = CheckAddressSpaceFields (
             IsMinFixed,
             IsMaxFixed,
             AddressGranularity,
             AddressMinimum,
             AddressMaximum,
             AddressTranslation,
             RangeLength
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Header
  RdQword.Header.Header.Bits.Name =
    ACPI_LARGE_QWORD_ADDRESS_SPACE_DESCRIPTOR_NAME;
  RdQword.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
  RdQword.Header.Length           = sizeof (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) -
                                    sizeof (ACPI_LARGE_RESOURCE_HEADER);

  // Body
  RdQword.ResType = ResourceType;
  RdQword.GenFlag = AddressSpaceGeneralFlags (
                      IsPosDecode,
                      IsMinFixed,
                      IsMaxFixed
                      );
  RdQword.SpecificFlag          = TypeSpecificFlags;
  RdQword.AddrSpaceGranularity  = AddressGranularity;
  RdQword.AddrRangeMin          = AddressMinimum;
  RdQword.AddrRangeMax          = AddressMaximum;
  RdQword.AddrTranslationOffset = AddressTranslation;
  RdQword.AddrLen               = RangeLength;

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             (UINT8 *)&RdQword,
             sizeof (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR),
             &RdNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  return LinkRdNode (RdNode, NameOpNode, NewRdNode);
}

/** Code generation for the "QWordIO ()" ASL function.

  The Resource Data effectively created is a QWord Address Space Resource
  Data. Cf ACPI 6.4:
   - s6.4.3.5.1 "QWord Address Space Descriptor".
   - s19.6.109 "QWordIO".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  See ACPI 6.4 spec, s19.6.109 for more.

  @param [in]  IsResourceConsumer   ResourceUsage parameter.
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.
  @param [in]  IsPosDecode          Decode parameter
  @param [in]  IsaRanges            Possible values are:
                                     0-Reserved
                                     1-NonISAOnly
                                     2-ISAOnly
                                     3-EntireRange
  @param [in]  AddressGranularity   Address granularity.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  AddressTranslation   Address translation.
  @param [in]  RangeLength          Range length.
  @param [in]  ResourceSourceIndex  Resource Source index.
                                    Unused. Must be 0.
  @param [in]  ResourceSource       Resource Source.
                                    Unused. Must be NULL.
  @param [in]  IsDenseTranslation   TranslationDensity parameter.
  @param [in]  IsTypeStatic         TranslationType parameter.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdQWordIo (
  IN        BOOLEAN IsResourceConsumer,
  IN        BOOLEAN IsMinFixed,
  IN        BOOLEAN IsMaxFixed,
  IN        BOOLEAN IsPosDecode,
  IN        UINT8 IsaRanges,
  IN        UINT64 AddressGranularity,
  IN        UINT64 AddressMinimum,
  IN        UINT64 AddressMaximum,
  IN        UINT64 AddressTranslation,
  IN        UINT64 RangeLength,
  IN        UINT8 ResourceSourceIndex,
  IN  CONST CHAR8 *ResourceSource,
  IN        BOOLEAN IsDenseTranslation,
  IN        BOOLEAN IsTypeStatic,
  IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  return AmlCodeGenRdQWordSpace (
           ACPI_ADDRESS_SPACE_TYPE_IO,
           IsResourceConsumer,
           IsPosDecode,
           IsMinFixed,
           IsMaxFixed,
           RdIoRangeSpecificFlags (
             IsaRanges,
             IsDenseTranslation,
             IsTypeStatic
             ),
           AddressGranularity,
           AddressMinimum,
           AddressMaximum,
           AddressTranslation,
           RangeLength,
           ResourceSourceIndex,
           ResourceSource,
           NameOpNode,
           NewRdNode
           );
}

/** Code generation for the "QWordMemory ()" ASL function.

  The Resource Data effectively created is a QWord Address Space Resource
  Data. Cf ACPI 6.4:
   - s6.4.3.5.1 "QWord Address Space Descriptor".
   - s19.6.110 "QWordMemory".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  See ACPI 6.4 spec, s19.6.110 for more.

  @param [in]  IsResourceConsumer   ResourceUsage parameter.
  @param [in]  IsPosDecode          Decode parameter.
  @param [in]  IsMinFixed           Minimum address is fixed.
  @param [in]  IsMaxFixed           Maximum address is fixed.
  @param [in]  Cacheable            Possible values are:
                                    0-The memory is non-cacheable
                                    1-The memory is cacheable
                                    2-The memory is cacheable and supports
                                      write combining
                                    3-The memory is cacheable and prefetchable
  @param [in]  IsReadWrite          ReadAndWrite parameter.
  @param [in]  AddressGranularity   Address granularity.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  AddressTranslation   Address translation.
  @param [in]  RangeLength          Range length.
  @param [in]  ResourceSourceIndex  Resource Source index.
                                    Unused. Must be 0.
  @param [in]  ResourceSource       Resource Source.
                                    Unused. Must be NULL.
  @param [in]  MemoryRangeType      Possible values are:
                                      0-AddressRangeMemory
                                      1-AddressRangeReserved
                                      2-AddressRangeACPI
                                      3-AddressRangeNVS
  @param [in]  IsTypeStatic         TranslationType parameter.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdQWordMemory (
  IN        BOOLEAN IsResourceConsumer,
  IN        BOOLEAN IsPosDecode,
  IN        BOOLEAN IsMinFixed,
  IN        BOOLEAN IsMaxFixed,
  IN        AML_MEMORY_ATTRIBUTES_MEM Cacheable,
  IN        BOOLEAN IsReadWrite,
  IN        UINT64 AddressGranularity,
  IN        UINT64 AddressMinimum,
  IN        UINT64 AddressMaximum,
  IN        UINT64 AddressTranslation,
  IN        UINT64 RangeLength,
  IN        UINT8 ResourceSourceIndex,
  IN  CONST CHAR8 *ResourceSource,
  IN        AML_MEMORY_ATTRIBUTES_MTP MemoryRangeType,
  IN        BOOLEAN IsTypeStatic,
  IN        AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT       AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  return AmlCodeGenRdQWordSpace (
           ACPI_ADDRESS_SPACE_TYPE_MEM,
           IsResourceConsumer,
           IsPosDecode,
           IsMinFixed,
           IsMaxFixed,
           MemoryRangeSpecificFlags (
             Cacheable,
             IsReadWrite,
             MemoryRangeType,
             IsTypeStatic
             ),
           AddressGranularity,
           AddressMinimum,
           AddressMaximum,
           AddressTranslation,
           RangeLength,
           ResourceSourceIndex,
           ResourceSource,
           NameOpNode,
           NewRdNode
           );
}

/** Code generation for the "Interrupt ()" ASL function.

  The Resource Data effectively created is an Extended Interrupt Resource
  Data. Cf ACPI 6.4:
   - s6.4.3.6 "Extended Interrupt Descriptor"
   - s19.6.64 "Interrupt (Interrupt Resource Descriptor Macro)"

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  @param  [in]  ResourceConsumer The device consumes the specified interrupt
                                 or produces it for use by a child device.
  @param  [in]  EdgeTriggered    The interrupt is edge triggered or
                                 level triggered.
  @param  [in]  ActiveLow        The interrupt is active-high or active-low.
  @param  [in]  Shared           The interrupt can be shared with other
                                 devices or not (Exclusive).
  @param  [in]  IrqList          Interrupt list. Must be non-NULL.
  @param  [in]  IrqCount         Interrupt count. Must be non-zero.
  @param  [in]  NameOpNode       NameOp object node defining a named object.
                                 If provided, append the new resource data node
                                 to the list of resource data elements of this
                                 node.
  @param  [out] NewRdNode        If provided and success,
                                 contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdInterrupt (
  IN  BOOLEAN                 ResourceConsumer,
  IN  BOOLEAN                 EdgeTriggered,
  IN  BOOLEAN                 ActiveLow,
  IN  BOOLEAN                 Shared,
  IN  UINT32                  *IrqList,
  IN  UINT8                   IrqCount,
  IN  AML_OBJECT_NODE_HANDLE  NameOpNode  OPTIONAL,
  OUT AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  EFI_STATUS  Status;

  AML_DATA_NODE                           *RdNode;
  EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR  *RdInterrupt;
  UINT16                                  RdInterruptSize;
  UINT32                                  *FirstInterrupt;

  if ((IrqList == NULL) ||
      (IrqCount == 0)   ||
      ((NameOpNode == NULL) && (NewRdNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR already includes the first interrupt
  RdInterruptSize = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) + (IrqCount - 1) * sizeof (UINT32);
  RdInterrupt     = (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR *)AllocateZeroPool (RdInterruptSize);
  if (RdInterrupt == NULL) {
    ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
    return EFI_OUT_OF_RESOURCES;
  }

  // Header
  RdInterrupt->Header.Header.Bits.Name =
    ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME;
  RdInterrupt->Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
  RdInterrupt->Header.Length           = RdInterruptSize - sizeof (ACPI_LARGE_RESOURCE_HEADER);

  // Body
  RdInterrupt->InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) |
                                      (EdgeTriggered ? BIT1 : 0)    |
                                      (ActiveLow ? BIT2 : 0)        |
                                      (Shared ? BIT3 : 0);
  RdInterrupt->InterruptTableLength = IrqCount;

  // Get the address of the first interrupt field.
  FirstInterrupt = RdInterrupt->InterruptNumber;

  // Copy the list of interrupts.
  CopyMem (FirstInterrupt, IrqList, (sizeof (UINT32) * IrqCount));

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             (UINT8 *)RdInterrupt,
             RdInterruptSize,
             &RdNode
             );
  FreePool (RdInterrupt);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  return LinkRdNode (RdNode, NameOpNode, NewRdNode);
}

/** Code generation for the "Register ()" ASL function.

  The Resource Data effectively created is a Generic Register Descriptor.
  Data. Cf ACPI 6.4:
   - s6.4.3.7 "Generic Register Descriptor".
   - s19.6.114 "Register".

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  @param [in]  AddressSpace    Address space where the register exists.
                               Can be one of I/O space, System Memory, etc.
  @param [in]  BitWidth        Number of bits in the register.
  @param [in]  BitOffset       Offset in bits from the start of the register
                               indicated by the Address.
  @param [in]  Address         Register address.
  @param [in]  AccessSize      Size of data values used when accessing the
                               address space. Can be one of:
                                 0 - Undefined, legacy (EFI_ACPI_6_4_UNDEFINED)
                                 1 - Byte access (EFI_ACPI_6_4_BYTE)
                                 2 - Word access (EFI_ACPI_6_4_WORD)
                                 3 - DWord access (EFI_ACPI_6_4_DWORD)
                                 4 - QWord access (EFI_ACPI_6_4_QWORD)
  @param  [in]  NameOpNode       NameOp object node defining a named object.
                                 If provided, append the new resource data node
                                 to the list of resource data elements of this
                                 node.
  @param  [out] NewRdNode        If provided and success,
                                 contain the created node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdRegister (
  IN  UINT8                   AddressSpace,
  IN  UINT8                   BitWidth,
  IN  UINT8                   BitOffset,
  IN  UINT64                  Address,
  IN  UINT8                   AccessSize,
  IN  AML_OBJECT_NODE_HANDLE  NameOpNode  OPTIONAL,
  OUT AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  EFI_STATUS                            Status;
  AML_DATA_NODE                         *RdNode;
  EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR  RdRegister;

  // Cf. ACPI 6.4, s14.7 Referencing the PCC address space
  // The AccessSize represents the Subspace Id for the PCC address space.
  if (((AddressSpace != EFI_ACPI_6_4_PLATFORM_COMMUNICATION_CHANNEL) &&
       (AccessSize > EFI_ACPI_6_4_QWORD)) ||
      ((NameOpNode == NULL) && (NewRdNode == NULL)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Header
  RdRegister.Header.Header.Bits.Name =
    ACPI_LARGE_GENERIC_REGISTER_DESCRIPTOR_NAME;
  RdRegister.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
  RdRegister.Header.Length           = sizeof (EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR) -
                                       sizeof (ACPI_LARGE_RESOURCE_HEADER);

  // Body
  RdRegister.AddressSpaceId    = AddressSpace;
  RdRegister.RegisterBitWidth  = BitWidth;
  RdRegister.RegisterBitOffset = BitOffset;
  RdRegister.AddressSize       = AccessSize;
  RdRegister.RegisterAddress   = Address;

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             (UINT8 *)&RdRegister,
             sizeof (EFI_ACPI_GENERIC_REGISTER_DESCRIPTOR),
             &RdNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  return LinkRdNode (RdNode, NameOpNode, NewRdNode);
}

/** Code generation for the "IO ()" ASL function.

  The Resource Data effectively created is a IO Resource
  Data. Cf ACPI 6.5:
   - s19.6.65 IO (IO Resource Descriptor Macro)
   - s6.4.2.5 I/O Port Descriptor

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  @param [in]  IsDecoder16          Decoder parameter.
                                    TRUE if 16-bit decoder.
                                    FALSE if 10-bit decoder.
  @param [in]  AddressMinimum       Minimum address.
  @param [in]  AddressMaximum       Maximum address.
  @param [in]  Alignment            Alignment.
  @param [in]  RangeLength          Range length.
  @param [in]  NameOpNode           NameOp object node defining a named object.
                                    If provided, append the new resource data
                                    node to the list of resource data elements
                                    of this node.
  @param [out] NewRdNode            If provided and success,
                                    contain the created node.

  @retval EFI_SUCCESS               The function completed successfully.
  @retval EFI_INVALID_PARAMETER     Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdIo (
  IN  BOOLEAN IsDecoder16,
  IN  UINT16 AddressMinimum,
  IN  UINT16 AddressMaximum,
  IN  UINT8 Alignment,
  IN  UINT8 RangeLength,
  IN  AML_OBJECT_NODE_HANDLE NameOpNode, OPTIONAL
  OUT AML_DATA_NODE_HANDLE  *NewRdNode  OPTIONAL
  )
{
  EFI_STATUS                   Status;
  EFI_ACPI_IO_PORT_DESCRIPTOR  IoDesc;
  AML_DATA_NODE                *IoNode;

  if (AddressMinimum > AddressMaximum) {
    return EFI_INVALID_PARAMETER;
  }

  if (Alignment != 0) {
    /// check the alignment
    if ((AddressMinimum % Alignment) != 0) {
      return EFI_INVALID_PARAMETER;
    }

    if ((AddressMaximum % Alignment) != 0) {
      return EFI_INVALID_PARAMETER;
    }
  }

  IoDesc.Header.Byte = ACPI_IO_PORT_DESCRIPTOR;
  IoDesc.Information = IsDecoder16 ? BIT0 : 0;

  IoDesc.BaseAddressMin = AddressMinimum;
  IoDesc.BaseAddressMax = AddressMaximum;
  IoDesc.Alignment      = Alignment;
  IoDesc.Length         = RangeLength;

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             (UINT8 *)&IoDesc,
             sizeof (IoDesc),
             &IoNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  return LinkRdNode (IoNode, NameOpNode, NewRdNode);
}

/** Code generation for the EndTag resource data.

  The EndTag resource data is automatically generated by the ASL compiler
  at the end of a list of resource data elements. Thus, it doesn't have
  a corresponding ASL function.

  This function allocates memory to create a data node. It is the caller's
  responsibility to either:
   - attach this node to an AML tree;
   - delete this node.

  ACPI 6.4, s6.4.2.9 "End Tag":
  "This checksum is generated such that adding it to the sum of all the data
  bytes will produce a zero sum."
  "If the checksum field is zero, the resource data is treated as if the
  checksum operation succeeded. Configuration proceeds normally."

  To avoid re-computing checksums, if a new resource data elements is
  added/removed/modified in a list of resource data elements, the AmlLib
  resets the checksum to 0.

  @param [in]  CheckSum        CheckSum to store in the EndTag.
                               To ignore/avoid computing the checksum,
                               give 0.
  @param [in]  ParentNode      If not NULL, add the generated node
                               to the end of the variable list of
                               argument of the ParentNode.
                               The ParentNode must not initially contain
                               an EndTag resource data element.
  @param  [out] NewRdNode      If success, contains the generated node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCodeGenEndTag (
  IN  UINT8            CheckSum    OPTIONAL,
  IN  AML_OBJECT_NODE  *ParentNode  OPTIONAL,
  OUT AML_DATA_NODE    **NewRdNode   OPTIONAL
  )
{
  EFI_STATUS                   Status;
  AML_DATA_NODE                *RdNode;
  EFI_ACPI_END_TAG_DESCRIPTOR  EndTag;
  ACPI_SMALL_RESOURCE_HEADER   SmallResHdr;

  if ((ParentNode == NULL) && (NewRdNode == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  RdNode = NULL;

  // Header
  SmallResHdr.Bits.Length = sizeof (EFI_ACPI_END_TAG_DESCRIPTOR) -
                            sizeof (ACPI_SMALL_RESOURCE_HEADER);
  SmallResHdr.Bits.Name = ACPI_SMALL_END_TAG_DESCRIPTOR_NAME;
  SmallResHdr.Bits.Type = ACPI_SMALL_ITEM_FLAG;

  // Body
  EndTag.Desc     = SmallResHdr.Byte;
  EndTag.Checksum = CheckSum;

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             (UINT8 *)&EndTag,
             sizeof (EFI_ACPI_END_TAG_DESCRIPTOR),
             &RdNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  if (NewRdNode != NULL) {
    *NewRdNode = RdNode;
  }

  if (ParentNode != NULL) {
    // Check the BufferOp doesn't contain any resource data yet.
    // This is a hard check: do not allow to add an EndTag if the BufferNode
    // already has resource data elements attached. Indeed, the EndTag should
    // have already been added.
    if (AmlGetNextVariableArgument ((AML_NODE_HEADER *)ParentNode, NULL) !=
        NULL)
    {
      ASSERT (0);
      Status = EFI_INVALID_PARAMETER;
      goto error_handler;
    }

    // Add the EndTag RdNode. Indeed, the AmlAppendRdNode function
    // is looking for an EndTag, which we are adding here.
    Status = AmlVarListAddTail (
               (AML_NODE_HEADER *)ParentNode,
               (AML_NODE_HEADER *)RdNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      goto error_handler;
    }
  }

  return Status;

error_handler:
  if (RdNode != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)RdNode);
  }

  return Status;
}

/** Code generation for the IRQ Descriptor.

  The Resource Data effectively created is an IRQ Resource
  Data. Cf ACPI 6.5 specification:
   - s6.4.2.1 "IRQ Descriptor"
   - s19.6.66 "IRQ (Interrupt Resource Descriptor Macro)"


  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  @param  [in]  IsEdgeTriggered The interrupt is edge triggered or
                                level triggered.
  @param  [in]  IsActiveLow     The interrupt is active-high or active-low.
  @param  [in]  IsShared        The interrupt can be shared with other
                                devices or not (Exclusive).
  @param  [in]  IrqList         List of IRQ numbers. Must be non-NULL.
  @param  [in]  IrqCount        Number of IRQs in IrqList. Must be > 0 and <= 16.
  @param  [in]  NameOpNode      NameOp object node defining a named object.
                                If provided, append the new resource data node
                                to the list of resource data elements of this node.
  @param  [out] NewRdNode       If provided and success, contain the created node.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_INVALID_PARAMETER Invalid parameter.
  @retval various               Other errors as indicated.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdIrq (
  IN  BOOLEAN                 IsEdgeTriggered,
  IN  BOOLEAN                 IsActiveLow,
  IN  BOOLEAN                 IsShared,
  IN  UINT8                   *IrqList,
  IN  UINT8                   IrqCount,
  IN  AML_OBJECT_NODE_HANDLE  NameOpNode  OPTIONAL,
  OUT AML_DATA_NODE_HANDLE    *NewRdNode  OPTIONAL
  )
{
  AML_DATA_NODE            *RdNode;
  EFI_ACPI_IRQ_DESCRIPTOR  IrqDesc;
  EFI_STATUS               Status;
  UINT8                    Index;
  UINT16                   Mask;

  if ((NameOpNode == NULL) && (NewRdNode == NULL)) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
  if ((IsEdgeTriggered && !IsActiveLow) ||
      (!IsEdgeTriggered && IsActiveLow))
  {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

 #endif

  if ((IrqList == NULL) || (IrqCount == 0) || (IrqCount > 16)) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  Mask = 0;
  for (Index = 0; Index < IrqCount; Index++) {
    if (IrqList[Index] > 16) {
      ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
      return EFI_INVALID_PARAMETER;
    }

    if ((Mask & (1 << IrqList[Index])) != 0) {
      ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
      return EFI_INVALID_PARAMETER;
    }

    Mask |= (1 << IrqList[Index]);
  }

  if (Mask == 0) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  IrqDesc.Header.Bits.Type   = ACPI_SMALL_ITEM_FLAG;
  IrqDesc.Header.Bits.Name   = ACPI_SMALL_IRQ_DESCRIPTOR_NAME;
  IrqDesc.Header.Bits.Length = sizeof (EFI_ACPI_IRQ_DESCRIPTOR) -
                               sizeof (ACPI_SMALL_RESOURCE_HEADER);
  IrqDesc.Mask        = Mask;
  IrqDesc.Information = (IsEdgeTriggered ? BIT0 : 0) |
                        (IsActiveLow ? BIT3 : 0)    |
                        (IsShared ? BIT4 : 0);

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             (UINT8 *)&IrqDesc,
             sizeof (EFI_ACPI_IRQ_DESCRIPTOR),
             &RdNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  return LinkRdNode (RdNode, NameOpNode, NewRdNode);
}

/** Code generation for the UART Serial Bus Connection Resource Descriptor.

  The Resource Data effectively created is a UART Serial Bus Connection
  Resource Descriptor Resource Data.
  Cf ACPI 6.5:
   - s19.6.143 UARTSerialBusV2
     (UART Serial Bus Connection Resource Descriptor Version 2 Macro)
   - s6.4.3.8.2.3 UART Serial Bus Connection Resource Descriptor

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  @param [in] IsResourceConsumer          ResourceUsage parameter.
  @param [in] IsSlaveMode                 Indicates whether the uart operates in slave mode.
  @param [in] IsBigEndian                 Indicates whether the bit transfer is big-endian.
  @param [in] BitsPerByte                 Indicates the number of bits per byte.
  @param [in] StopBits                    Specifies the stop bits format used.
  @param [in] FlowControl                 Specifies the flow control protocol used.
  @param [in] BaudRate                    Specifies the baud rate.
  @param [in] RxFifo                      Number of bytes in the receiver FIFO.
  @param [in] TxFifo                      Number of bytes in the transmitter FIFO.
  @param [in] Parity                      Specifies the parity format used.
  @param [in] SerialLinesEnabled          Specifies which serial lines are enabled.
  @param [in] VendorDefinedData           VendorDefinedData parameter.
  @param [in] VendorDefinedDataLength     VendorDefinedDataLength parameter.
  @param [in] ResourceSource              Name of source resource used.
  @param [in] ResourceSourceLength        Resource Source Length.
  @param [in] NameOpNode                  NameOpNode object node defining a named object.
                                          If provided, append the new resource data
                                          node to the list of resource data elements
                                          of this node.
  @param [out] NewRdNode                  If provided and success,
                                          contain the created node.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_INVALID_PARAMETER Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES  Could not allocate memory.
  @retval various               Other errors as indicated.

**/
STATIC
EFI_STATUS
EFIAPI
AmlCodeGenRdUartSerialBus (
  IN  BOOLEAN                 IsResourceConsumer,
  IN  BOOLEAN                 IsSlaveMode,
  IN  BOOLEAN                 IsBigEndian,
  IN  UINT8                   BitsPerByte,
  IN  UINT8                   StopBits,
  IN  UINT8                   FlowControl,
  IN  UINT32                  BaudRate,
  IN  UINT16                  RxFifo,
  IN  UINT16                  TxFifo,
  IN  UINT8                   Parity,
  IN  UINT8                   SerialLinesEnabled,
  IN  UINT8                   *VendorDefinedData OPTIONAL,
  IN  UINT16                  VendorDefinedDataLength,
  IN  CHAR8                   *ResourceSource,
  IN  UINT16                  ResourceSourceLength,
  IN  AML_OBJECT_NODE_HANDLE  NameOpNode OPTIONAL,
  OUT AML_DATA_NODE_HANDLE    *NewRdNode OPTIONAL
  )
{
  AML_DATA_NODE  *RdNode;
  EFI_STATUS     Status;
  UINT16         UartDescBuffLength;
  UINT8          *UartDescBuff;
  UINT8          BitsPerByteMask;

  EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR  UartDesc;

  if ((NameOpNode == NULL) && (NewRdNode == NULL)) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  if (((VendorDefinedData == NULL) && (VendorDefinedDataLength > 0)) ||
      ((VendorDefinedData != NULL) && (VendorDefinedDataLength == 0)))
  {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  if ((ResourceSource == NULL) || (ResourceSourceLength <= 0)) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  if (StopBits > EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_2) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  if (FlowControl > EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_FC_XON_XOFF) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  if (Parity > EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_SPACE) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  switch (BitsPerByte) {
    case 5:
      BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_5_BITS_PER_BYTE;
      break;
    case 6:
      BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_6_BITS_PER_BYTE;
      break;
    case 7:
      BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_7_BITS_PER_BYTE;
      break;
    case 8:
      BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_8_BITS_PER_BYTE;
      break;
    case 9:
      BitsPerByteMask = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_9_BITS_PER_BYTE;
      break;
    default:
      ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
      return EFI_INVALID_PARAMETER;
  }

  /// as per spec last two bits are reserved and must be 0.
  if ((SerialLinesEnabled &
       ~(EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_RTS |
         EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_CTS |
         EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DTR |
         EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DSR |
         EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_RI |
         EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_LIN_DTD)) != 0)
  {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  UartDesc.Header.Header.Bits.Type = ACPI_LARGE_ITEM_FLAG;
  UartDesc.Header.Header.Bits.Name = ACPI_LARGE_GENERIC_SERIAL_BUS_CONNECTION_DESCRIPTOR_NAME;
  UartDesc.RevisionId              = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_REVISION_ID;
  UartDesc.ResourceSourceIndex     = 0;
  UartDesc.SerialBusType           = EFI_ACPI_SERIAL_BUS_RESOURCE_TYPE_UART;
  UartDesc.GeneralFlags            = (IsResourceConsumer ? BIT1 : 0) |
                                     (IsSlaveMode ? BIT0 : 0);
  UartDesc.TypeSpecificFlags = (IsBigEndian ? BIT7 : 0) |
                               (BitsPerByteMask << 4) |
                               (StopBits << 2)        |
                               (FlowControl);
  UartDesc.TypeSpecificRevisionId = EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_REVISION_ID;
  /// TypeDataLength is the length of the data following the TypeDataLength,
  /// up to the Additional vendor supplied data (not included).
  UartDesc.TypeDataLength = sizeof (UartDesc.DefaultBaudRate) +
                            sizeof (UartDesc.RxFIFO) +
                            sizeof (UartDesc.TxFIFO) +
                            sizeof (UartDesc.Parity) +
                            sizeof (UartDesc.SerialLinesEnabled) +
                            VendorDefinedDataLength;
  UartDesc.DefaultBaudRate    = BaudRate;
  UartDesc.RxFIFO             = RxFifo;
  UartDesc.TxFIFO             = TxFifo;
  UartDesc.Parity             = Parity;
  UartDesc.SerialLinesEnabled = SerialLinesEnabled;

  UartDescBuffLength = sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR) +
                       VendorDefinedDataLength +
                       ResourceSourceLength;

  UartDesc.Header.Length = UartDescBuffLength - sizeof (ACPI_LARGE_RESOURCE_HEADER);

  UartDescBuff = AllocateZeroPool (UartDescBuffLength);
  if (UartDescBuff == NULL) {
    ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (
    UartDescBuff,
    &UartDesc,
    sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR)
    );

  if (VendorDefinedData != NULL) {
    CopyMem (
      UartDescBuff + sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR),
      VendorDefinedData,
      VendorDefinedDataLength
      );
  }

  CopyMem (
    UartDescBuff +
    sizeof (EFI_ACPI_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR) +
    VendorDefinedDataLength,
    ResourceSource,
    ResourceSourceLength
    );

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeResourceData,
             UartDescBuff,
             UartDescBuffLength,
             &RdNode
             );
  FreePool (UartDescBuff);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  return LinkRdNode (RdNode, NameOpNode, NewRdNode);
}

/** Code generation for the UARTSerialBusV2() ASL macro.

  The Resource Data effectively created is a UART Serial Bus Connection
  Resource Descriptor Resource Data.
  Cf ACPI 6.5:
   - s19.6.143 UARTSerialBusV2
     (UART Serial Bus Connection Resource Descriptor Version 2 Macro)
   - s6.4.3.8.2.3 UART Serial Bus Connection Resource Descriptor

  The created resource data node can be:
   - appended to the list of resource data elements of the NameOpNode.
     In such case NameOpNode must be defined by a the "Name ()" ASL statement
     and initially contain a "ResourceTemplate ()".
   - returned through the NewRdNode parameter.

  @param [in]  InitialBaudRate           Initial baud rate.
  @param [in]  BitsPerByte               Number of bits per byte.
                                         Optional, default is 8.
  @param [in]  StopBits                  Number of stop bits.
                                         Optional, default is 1.
  @param [in]  LinesInUse                Number of lines in use.
  @param [in]  IsBigEndian               Indicates whether the bit transfer is big-endian.
                                         Optional, default is FALSE (little-endian).
  @param [in]  Parity                    Parity format used.
                                          Optional, default is no parity.
  @param [in]  FlowControl               Flow control protocol used.
                                          Optional, default is no flow control.
  @param [in]  ReceiveBufferSize         Size of the receive buffer.
  @param [in]  TransmitBufferSize        Size of the transmit buffer.
  @param [in]  ResourceSource            Name of source resource used.
  @param [in]  ResourceSourceLength      Length of the Resource Source.
  @param [in]  ResourceSourceIndex       Resource Source index.
                                         Optional, default is 0.
  @param [in]  ResourceUsage             Resource usage, TRUE for consumer,
                                         FALSE for producer.
                                         Optional, default is TRUE (consumer).
  @param [in]  IsShared                  Indicates whether the resource is shared.
                                         Optional, default is FALSE (exclusive).
  @param [in]  VendorDefinedData         Vendor defined data.
                                         Optional, can be NULL.
  @param [in]  VendorDefinedDataLength   Length of the vendor defined data.
  @param [in]  NameOpNode                NameOp object node defining a named object.
                                         If provided, append the new resource data
                                         node to the list of resource data elements
                                         of this node.
  @param [out] NewRdNode                 If provided and success,
                                         contain the created node.

  @retval EFI_SUCCESS                   The function completed successfully.
  @retval EFI_INVALID_PARAMETER         Invalid parameter.
  @retval various                       Various failure values of called functions.
**/
EFI_STATUS
EFIAPI
AmlCodeGenRdUartSerialBusV2 (
  IN  UINT32                  InitialBaudRate,
  IN  UINT8                   *BitsPerByte OPTIONAL,
  IN  UINT8                   *StopBits OPTIONAL,
  IN  UINT8                   LinesInUse,
  IN  BOOLEAN                 *IsBigEndian OPTIONAL,
  IN  UINT8                   *Parity OPTIONAL,
  IN  UINT8                   *FlowControl OPTIONAL,
  IN  UINT16                  ReceiveBufferSize,
  IN  UINT16                  TransmitBufferSize,
  IN  CHAR8                   *ResourceSource,
  IN  UINT16                  ResourceSourceLength,
  IN  UINT8                   *ResourceSourceIndex OPTIONAL,
  IN  BOOLEAN                 *ResourceUsage OPTIONAL,
  IN  BOOLEAN                 *IsShared OPTIONAL,
  IN  UINT8                   *VendorDefinedData OPTIONAL,
  IN  UINT16                  VendorDefinedDataLength,
  IN  AML_OBJECT_NODE_HANDLE  NameOpNode OPTIONAL,
  OUT AML_DATA_NODE_HANDLE    *NewRdNode OPTIONAL
  )
{
  EFI_STATUS  Status;

  if ((NameOpNode == NULL) && (NewRdNode == NULL)) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  if (((VendorDefinedData == NULL) && (VendorDefinedDataLength > 0)) ||
      ((VendorDefinedData != NULL) && (VendorDefinedDataLength == 0)))
  {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  if ((ResourceSource == NULL) || (ResourceSourceLength <= 0)) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  if (ResourceSourceIndex != NULL) {
    if (*ResourceSourceIndex != 0) {
      ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
      return EFI_INVALID_PARAMETER;
    }
  }

  Status = AmlCodeGenRdUartSerialBus (
             /// default is resource consumer
             (ResourceUsage != NULL) ? *ResourceUsage : TRUE,
             /// slave mode
             TRUE,
             /// default is little-endian
             (IsBigEndian != NULL) ? *IsBigEndian : FALSE,
             /// default is 8 bits per byte
             (BitsPerByte != NULL) ? *BitsPerByte : 8,
             /// default is 1 stop bit
             (StopBits != NULL) ? *StopBits : EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_STOP_BIT_1,
             /// default is no flow control
             (FlowControl != NULL) ? *FlowControl : EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_TSF_FC_NONE,
             InitialBaudRate,
             ReceiveBufferSize,
             TransmitBufferSize,
             /// default is no parity
             (Parity != NULL) ? *Parity : EFI_ACPI_5_0_SERIAL_BUS_RESOURCE_UART_DESCRIPTOR_PARITY_NONE,
             LinesInUse,
             VendorDefinedData,
             VendorDefinedDataLength,
             ResourceSource,
             ResourceSourceLength,
             NameOpNode,
             NewRdNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  return Status;
}
