/** @file
  AML Utility.

  Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Utils/AmlUtility.h>

#include <AmlCoreInterface.h>
#include <Tree/AmlNode.h>
#include <Tree/AmlTree.h>

/** This function computes and updates the ACPI table checksum.

  @param  [in]  AcpiTable   Pointer to an Acpi table.

  @retval EFI_SUCCESS   The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AcpiPlatformChecksum (
  IN  EFI_ACPI_DESCRIPTION_HEADER  *AcpiTable
  )
{
  UINT8   *Ptr;
  UINT8   Sum;
  UINT32  Size;

  if (AcpiTable == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Ptr  = (UINT8 *)AcpiTable;
  Size = AcpiTable->Length;
  Sum  = 0;

  // Set the checksum field to 0 first.
  AcpiTable->Checksum = 0;

  // Compute the checksum.
  while ((Size--) != 0) {
    Sum = (UINT8)(Sum + (*Ptr++));
  }

  // Set the checksum.
  AcpiTable->Checksum = (UINT8)(0xFF - Sum + 1);

  return EFI_SUCCESS;
}

/** A callback function that computes the size of a Node and adds it to the
    Size pointer stored in the Context.
    Calling this function on the root node will compute the total size of the
    AML bytestream.

  @param  [in]      Node      Node to compute the size.
  @param  [in, out] Context   Pointer holding the computed size.
                              (UINT32 *) Context.
  @param  [in, out] Status    Pointer holding:
                               - At entry, the Status returned by the
                                 last call to this exact function during
                                 the enumeration;
                               - At exit, he returned status of the
                                 call to this function.
                              Optional, can be NULL.

  @retval TRUE if the enumeration can continue or has finished without
          interruption.
  @retval FALSE if the enumeration needs to stopped or has stopped.
**/
STATIC
BOOLEAN
EFIAPI
AmlComputeSizeCallback (
  IN      AML_NODE_HEADER  *Node,
  IN  OUT VOID             *Context,
  IN  OUT EFI_STATUS       *Status   OPTIONAL
  )
{
  UINT32                 Size;
  EAML_PARSE_INDEX       IndexPtr;
  CONST AML_OBJECT_NODE  *ParentNode;

  if (!IS_AML_NODE_VALID (Node) ||
      (Context == NULL))
  {
    ASSERT (0);
    if (Status != NULL) {
      *Status = EFI_INVALID_PARAMETER;
    }

    return FALSE;
  }

  // Ignore the second fixed argument of method invocation nodes
  // as the information stored there (the argument count) is not in the
  // ACPI specification.
  ParentNode = (CONST AML_OBJECT_NODE *)AmlGetParent (Node);
  if (IS_AML_OBJECT_NODE (ParentNode)                             &&
      AmlNodeCompareOpCode (ParentNode, AML_METHOD_INVOC_OP, 0)   &&
      AmlIsNodeFixedArgument (Node, &IndexPtr))
  {
    if (IndexPtr == EAmlParseIndexTerm1) {
      if (Status != NULL) {
        *Status = EFI_SUCCESS;
      }

      return TRUE;
    }
  }

  Size = *((UINT32 *)Context);

  if (IS_AML_DATA_NODE (Node)) {
    Size += ((AML_DATA_NODE *)Node)->Size;
  } else if (IS_AML_OBJECT_NODE (Node)  &&
             !AmlNodeHasAttribute (
                (CONST AML_OBJECT_NODE *)Node,
                AML_IS_PSEUDO_OPCODE
                ))
  {
    // Ignore pseudo-opcodes as they are not part of the
    // ACPI specification.

    Size += (((AML_OBJECT_NODE *)Node)->AmlByteEncoding->OpCode ==
             AML_EXT_OP) ? 2 : 1;

    // Add the size of the PkgLen.
    if (AmlNodeHasAttribute (
          (AML_OBJECT_NODE *)Node,
          AML_HAS_PKG_LENGTH
          ))
    {
      Size += AmlComputePkgLengthWidth (((AML_OBJECT_NODE *)Node)->PkgLen);
    }
  }

  // Check for overflow.
  // The root node has a null size, thus the strict comparison.
  if (*((UINT32 *)Context) > Size) {
    ASSERT (0);
    *Status = EFI_INVALID_PARAMETER;
    return FALSE;
  }

  *((UINT32 *)Context) = Size;

  if (Status != NULL) {
    *Status = EFI_SUCCESS;
  }

  return TRUE;
}

/** Compute the size of a tree/sub-tree.

  @param  [in]      Node      Node to compute the size.
  @param  [in, out] Size      Pointer holding the computed size.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlComputeSize (
  IN      CONST AML_NODE_HEADER  *Node,
  IN  OUT       UINT32           *Size
  )
{
  EFI_STATUS  Status;

  if (!IS_AML_NODE_VALID (Node) ||
      (Size == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *Size = 0;

  AmlEnumTree (
    (AML_NODE_HEADER *)Node,
    AmlComputeSizeCallback,
    (VOID *)Size,
    &Status
    );

  return Status;
}

/** Get the value contained in an integer node.

  @param  [in]  Node    Pointer to an integer node.
                        Must be an object node.
  @param  [out] Value   Value contained in the integer node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlNodeGetIntegerValue (
  IN  AML_OBJECT_NODE  *Node,
  OUT UINT64           *Value
  )
{
  AML_DATA_NODE  *DataNode;

  if ((!IsIntegerNode (Node)            &&
       !IsSpecialIntegerNode (Node))    ||
      (Value == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // For ZeroOp and OneOp, there is no data node.
  if (IsSpecialIntegerNode (Node)) {
    if (AmlNodeCompareOpCode (Node, AML_ZERO_OP, 0)) {
      *Value = 0;
    } else if (AmlNodeCompareOpCode (Node, AML_ONE_OP, 0)) {
      *Value = 1;
    } else {
      // OnesOp cannot be handled: it represents a maximum value.
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }

    return EFI_SUCCESS;
  }

  // For integer nodes, the value is in the first fixed argument.
  DataNode = (AML_DATA_NODE *)Node->FixedArgs[EAmlParseIndexTerm0];
  if (!IS_AML_DATA_NODE (DataNode) ||
      (DataNode->DataType != EAmlNodeDataTypeUInt))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  switch (DataNode->Size) {
    case 1:
    {
      *Value = *((UINT8 *)(DataNode->Buffer));
      break;
    }
    case 2:
    {
      *Value = *((UINT16 *)(DataNode->Buffer));
      break;
    }
    case 4:
    {
      *Value = *((UINT32 *)(DataNode->Buffer));
      break;
    }
    case 8:
    {
      *Value = *((UINT64 *)(DataNode->Buffer));
      break;
    }
    default:
    {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }
  } // switch

  return EFI_SUCCESS;
}

/** Replace a Zero (AML_ZERO_OP) or One (AML_ONE_OP) object node
    with a byte integer (AML_BYTE_PREFIX) object node having the same value.

  @param  [in]  Node    Pointer to an integer node.
                        Must be an object node having ZeroOp or OneOp.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlUnwindSpecialInteger (
  IN  AML_OBJECT_NODE  *Node
  )
{
  EFI_STATUS  Status;

  AML_DATA_NODE            *NewDataNode;
  UINT8                    Value;
  CONST AML_BYTE_ENCODING  *ByteEncoding;

  if (!IsSpecialIntegerNode (Node)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Find the value.
  if (AmlNodeCompareOpCode (Node, AML_ZERO_OP, 0)) {
    Value = 0;
  } else if (AmlNodeCompareOpCode (Node, AML_ONE_OP, 0)) {
    Value = 1;
  } else {
    // OnesOp cannot be handled: it represents a maximum value.
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeUInt,
             &Value,
             sizeof (UINT8),
             (AML_DATA_NODE **)&NewDataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Change the encoding of the special node to a ByteOp encoding.
  ByteEncoding = AmlGetByteEncodingByOpCode (AML_BYTE_PREFIX, 0);
  if (ByteEncoding == NULL) {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto error_handler;
  }

  // Update the ByteEncoding from ZERO_OP/ONE_OP to AML_BYTE_PREFIX.
  Node->AmlByteEncoding = ByteEncoding;

  // Add the data node as the first fixed argument of the ByteOp object.
  Status = AmlSetFixedArgument (
             (AML_OBJECT_NODE *)Node,
             EAmlParseIndexTerm0,
             (AML_NODE_HEADER *)NewDataNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  return Status;

error_handler:
  AmlDeleteTree ((AML_NODE_HEADER *)NewDataNode);
  return Status;
}

/** Set the value contained in an integer node.

  The OpCode is updated accordingly to the new value
  (e.g.: If the original value was a UINT8 value, then the OpCode
         would be AML_BYTE_PREFIX. If it the new value is a UINT16
         value then the OpCode will be updated to AML_WORD_PREFIX).

  @param  [in]  Node            Pointer to an integer node.
                                Must be an object node.
  @param  [in]  NewValue        New value to write in the integer node.
  @param  [out] ValueWidthDiff  Difference in number of bytes used to store
                                the new value.
                                Can be negative.

  @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
AmlNodeSetIntegerValue (
  IN  AML_OBJECT_NODE  *Node,
  IN  UINT64           NewValue,
  OUT INT8             *ValueWidthDiff
  )
{
  EFI_STATUS     Status;
  AML_DATA_NODE  *DataNode;

  UINT8  NewOpCode;
  UINT8  NumberOfBytes;

  if ((!IsIntegerNode (Node)            &&
       !IsSpecialIntegerNode (Node))    ||
      (ValueWidthDiff == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *ValueWidthDiff = 0;
  // For ZeroOp and OneOp, there is no data node.
  // Thus the object node is converted to a byte object node holding 0 or 1.
  if (IsSpecialIntegerNode (Node)) {
    switch (NewValue) {
      case AML_ZERO_OP:
        Node->AmlByteEncoding = AmlGetByteEncodingByOpCode (AML_ZERO_OP, 0);
        return EFI_SUCCESS;
      case AML_ONE_OP:
        Node->AmlByteEncoding = AmlGetByteEncodingByOpCode (AML_ONE_OP, 0);
        return EFI_SUCCESS;
      default:
      {
        Status = AmlUnwindSpecialInteger (Node);
        if (EFI_ERROR (Status)) {
          ASSERT (0);
          return Status;
        }

        // The AmlUnwindSpecialInteger functions converts a special integer
        // node to a UInt8/Byte data node. Thus, the size increments by one:
        // special integer are encoded as one byte (the opcode only) while byte
        // integers are encoded as two bytes (the opcode + the value).
        *ValueWidthDiff += sizeof (UINT8);
      }
    } // switch
  } // IsSpecialIntegerNode (Node)

  // For integer nodes, the value is in the first fixed argument.
  DataNode = (AML_DATA_NODE *)Node->FixedArgs[EAmlParseIndexTerm0];
  if (!IS_AML_DATA_NODE (DataNode) ||
      (DataNode->DataType != EAmlNodeDataTypeUInt))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // The value can be encoded with a special 0 or 1 OpCode.
  // The AML_ONES_OP is not handled.
  if (NewValue <= 1) {
    NewOpCode             = (NewValue == 0) ? AML_ZERO_OP : AML_ONE_OP;
    Node->AmlByteEncoding = AmlGetByteEncodingByOpCode (NewOpCode, 0);

    // The value is encoded with a AML_ZERO_OP or AML_ONE_OP.
    // This means there is no need for a DataNode containing the value.
    // The change in size is equal to the size of the DataNode's buffer.
    *ValueWidthDiff = -((INT8)DataNode->Size);

    // Detach and free the DataNode containing the integer value.
    DataNode->NodeHeader.Parent          = NULL;
    Node->FixedArgs[EAmlParseIndexTerm0] = NULL;
    Status                               = AmlDeleteNode ((AML_NODE_HEADER *)DataNode);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    return EFI_SUCCESS;
  }

  // Check the number of bits needed to represent the value.
  if (NewValue > MAX_UINT32) {
    // Value is 64 bits.
    NewOpCode     = AML_QWORD_PREFIX;
    NumberOfBytes = 8;
  } else if (NewValue > MAX_UINT16) {
    // Value is 32 bits.
    NewOpCode     = AML_DWORD_PREFIX;
    NumberOfBytes = 4;
  } else if (NewValue > MAX_UINT8) {
    // Value is 16 bits.
    NewOpCode     = AML_WORD_PREFIX;
    NumberOfBytes = 2;
  } else {
    // Value is 8 bits.
    NewOpCode     = AML_BYTE_PREFIX;
    NumberOfBytes = 1;
  }

  *ValueWidthDiff += (INT8)(NumberOfBytes - DataNode->Size);

  // Update the ByteEncoding as it may have changed between [8 .. 64] bits.
  Node->AmlByteEncoding = AmlGetByteEncodingByOpCode (NewOpCode, 0);
  if (Node->AmlByteEncoding == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Free the old DataNode buffer and allocate a buffer with the right size
  // to store the new data.
  if (*ValueWidthDiff != 0) {
    FreePool (DataNode->Buffer);
    DataNode->Buffer = AllocateZeroPool (NumberOfBytes);
    if (DataNode->Buffer == NULL) {
      ASSERT (0);
      return EFI_OUT_OF_RESOURCES;
    }

    DataNode->Size = NumberOfBytes;
  }

  // Write the new value.
  CopyMem (DataNode->Buffer, &NewValue, NumberOfBytes);

  return EFI_SUCCESS;
}

/** Increment/decrement the value contained in the IntegerNode.

  @param  [in]  IntegerNode     Pointer to an object node containing
                                an integer.
  @param  [in]  IsIncrement     Choose the operation to do:
                                 - TRUE:  Increment the Node's size and
                                          the Node's count;
                                 - FALSE: Decrement the Node's size and
                                          the Node's count.
  @param  [in]  Diff            Value to add/subtract to the integer.
  @param  [out] ValueWidthDiff  When modifying the integer, it can be
                                promoted/demoted, e.g. from UINT8 to UINT16.
                                Stores the change in width.
                                Can be negative.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlNodeUpdateIntegerValue (
  IN  AML_OBJECT_NODE  *IntegerNode,
  IN  BOOLEAN          IsIncrement,
  IN  UINT64           Diff,
  OUT INT8             *ValueWidthDiff
  )
{
  EFI_STATUS  Status;
  UINT64      Value;

  if (ValueWidthDiff == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the current value.
  // Checks on the IntegerNode are done in the call.
  Status = AmlNodeGetIntegerValue (IntegerNode, &Value);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Check for UINT64 over/underflow.
  if ((IsIncrement && (Value > (MAX_UINT64 - Diff))) ||
      (!IsIncrement && (Value < Diff)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Compute the new value.
  if (IsIncrement) {
    Value += Diff;
  } else {
    Value -= Diff;
  }

  Status = AmlNodeSetIntegerValue (
             IntegerNode,
             Value,
             ValueWidthDiff
             );
  ASSERT_EFI_ERROR (Status);
  return Status;
}

/** Propagate the size information up the tree.

  The length of the ACPI table is updated in the RootNode,
  but not the checksum.

  @param  [in]  Node          Pointer to a node.
                              Must be a root node or an object node.
  @param  [in]  IsIncrement   Choose the operation to do:
                               - TRUE:  Increment the Node's size and
                                        the Node's count;
                               - FALSE: Decrement the Node's size and
                                        the Node's count.
  @param  [in]  Diff          Value to add/subtract to the Node's size.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlPropagateSize (
  IN  AML_NODE_HEADER  *Node,
  IN  BOOLEAN          IsIncrement,
  IN  UINT32           *Diff
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ObjectNode;
  AML_NODE_HEADER  *ParentNode;

  UINT32  Value;
  UINT32  InitialPkgLenWidth;
  UINT32  NewPkgLenWidth;
  UINT32  ReComputedPkgLenWidth;
  INT8    FieldWidthChange;

  if (!IS_AML_OBJECT_NODE (Node) &&
      !IS_AML_ROOT_NODE (Node))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if (IS_AML_OBJECT_NODE (Node)) {
    ObjectNode = (AML_OBJECT_NODE *)Node;

    // For BufferOp, the buffer size is stored in BufferSize. Therefore,
    // BufferOp needs special handling to update the BufferSize.
    // BufferSize must be updated before the PkgLen to accommodate any
    // increment resulting from the update of the BufferSize.
    // DefBuffer := BufferOp PkgLength BufferSize ByteList
    // BufferOp := 0x11
    // BufferSize := TermArg => Integer
    if (AmlNodeCompareOpCode (ObjectNode, AML_BUFFER_OP, 0)) {
      // First fixed argument of BufferOp is an integer (BufferSize)
      // (can be a BYTE, WORD, DWORD or QWORD).
      // BufferSize is an object node.
      Status = AmlNodeUpdateIntegerValue (
                 (AML_OBJECT_NODE *)AmlGetFixedArgument (
                                      ObjectNode,
                                      EAmlParseIndexTerm0
                                      ),
                 IsIncrement,
                 (UINT64)(*Diff),
                 &FieldWidthChange
                 );
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }

      // FieldWidthChange is an integer.
      // It must be positive if IsIncrement is TRUE, negative otherwise.
      if ((IsIncrement              &&
           (FieldWidthChange < 0))  ||
          (!IsIncrement             &&
           (FieldWidthChange > 0)))
      {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      // Check for UINT32 overflow.
      if (*Diff > (MAX_UINT32 - (UINT32)ABS (FieldWidthChange))) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      // Update Diff if the field width changed.
      *Diff = (UINT32)(*Diff + ABS (FieldWidthChange));
    } // AML_BUFFER_OP node.

    // Update the PgkLen.
    // Needs to be done at last to reflect the potential field width changes.
    if (AmlNodeHasAttribute (ObjectNode, AML_HAS_PKG_LENGTH)) {
      Value = ObjectNode->PkgLen;

      // Subtract the size of the PkgLen encoding. The size of the PkgLen
      // encoding must be computed after having updated Value.
      InitialPkgLenWidth = AmlComputePkgLengthWidth (Value);
      Value             -= InitialPkgLenWidth;

      // Check for an over/underflows.
      // PkgLen is a 28 bit value, cf 20.2.4 Package Length Encoding
      // i.e. the maximum value is (2^28 - 1) = ((BIT0 << 28) - 1).
      if ((IsIncrement && ((((BIT0 << 28) - 1) - Value) < *Diff))   ||
          (!IsIncrement && (Value < *Diff)))
      {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      // Update the size.
      if (IsIncrement) {
        Value += *Diff;
      } else {
        Value -= *Diff;
      }

      // Compute the new PkgLenWidth.
      NewPkgLenWidth = AmlComputePkgLengthWidth (Value);
      if (NewPkgLenWidth == 0) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      // Add it to the Value.
      Value += NewPkgLenWidth;

      // Check that adding the PkgLenWidth didn't trigger a domino effect,
      // increasing the encoding width of the PkgLen again.
      // The PkgLen is encoded on at most 4 bytes. It is possible to increase
      // the PkgLen width if its encoding is on less than 3 bytes.
      ReComputedPkgLenWidth = AmlComputePkgLengthWidth (Value);
      if (ReComputedPkgLenWidth != NewPkgLenWidth) {
        if ((ReComputedPkgLenWidth != 0)   &&
            (ReComputedPkgLenWidth < 4))
        {
          // No need to recompute the PkgLen since a new threshold cannot
          // be reached by incrementing the value by one.
          Value += 1;
        } else {
          ASSERT (0);
          return EFI_INVALID_PARAMETER;
        }
      }

      *Diff += (InitialPkgLenWidth > ReComputedPkgLenWidth) ?
               (InitialPkgLenWidth - ReComputedPkgLenWidth) :
               (ReComputedPkgLenWidth - InitialPkgLenWidth);
      ObjectNode->PkgLen = Value;
    } // PkgLen update.

    // During CodeGeneration, the tree is incomplete and
    // there is no root node at the top of the tree. Stop
    // propagating the new size when finding a root node
    // OR when a NULL parent is found.
    ParentNode = AmlGetParent ((AML_NODE_HEADER *)Node);
    if (ParentNode != NULL) {
      // Propagate the size up the tree.
      Status = AmlPropagateSize (
                 Node->Parent,
                 IsIncrement,
                 Diff
                 );
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }
    }
  } else if (IS_AML_ROOT_NODE (Node)) {
    // Update the length field in the SDT header.
    Value = ((AML_ROOT_NODE *)Node)->SdtHeader->Length;

    // Check for an over/underflows.
    if ((IsIncrement && (Value > (MAX_UINT32 - *Diff))) ||
        (!IsIncrement && (Value < *Diff)))
    {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }

    // Update the size.
    if (IsIncrement) {
      Value += *Diff;
    } else {
      Value -= *Diff;
    }

    ((AML_ROOT_NODE *)Node)->SdtHeader->Length = Value;
  }

  return EFI_SUCCESS;
}

/** Propagate the node count information up the tree.

  @param  [in]  ObjectNode        Pointer to an object node.
  @param  [in]  IsIncrement       Choose the operation to do:
                                   - TRUE:  Increment the Node's size and
                                            the Node's count;
                                   - FALSE: Decrement the Node's size and
                                           the Node's count.
  @param  [in]  NodeCount         Number of nodes added/removed (depends on the
                                  value of Operation).
  @param  [out] FieldWidthChange  When modifying the integer, it can be
                                  promoted/demoted, e.g. from UINT8 to UINT16.
                                  Stores the change in width.
                                  Can be negative.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlPropagateNodeCount (
  IN  AML_OBJECT_NODE  *ObjectNode,
  IN  BOOLEAN          IsIncrement,
  IN  UINT8            NodeCount,
  OUT INT8             *FieldWidthChange
  )
{
  EFI_STATUS  Status;

  AML_NODE_HEADER  *NodeCountArg;
  UINT8            CurrNodeCount;

  // Currently there is no use case where (NodeCount > 1).
  if (!IS_AML_OBJECT_NODE (ObjectNode)  ||
      (FieldWidthChange == NULL)        ||
      (NodeCount > 1))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *FieldWidthChange = 0;

  // Update the number of elements stored in PackageOp and VarPackageOp.
  // The number of elements is stored as the first fixed argument.
  // DefPackage := PackageOp PkgLength NumElements PackageElementList
  // PackageOp := 0x12
  // DefVarPackage := VarPackageOp PkgLength VarNumElements PackageElementList
  // VarPackageOp := 0x13
  // NumElements := ByteData
  // VarNumElements := TermArg => Integer
  NodeCountArg = AmlGetFixedArgument (ObjectNode, EAmlParseIndexTerm0);
  if (AmlNodeCompareOpCode (ObjectNode, AML_PACKAGE_OP, 0)) {
    // First fixed argument of PackageOp stores the number of elements
    // in the package. It is an UINT8.

    // Check for over/underflow.
    CurrNodeCount = *(((AML_DATA_NODE *)NodeCountArg)->Buffer);
    if ((IsIncrement && (CurrNodeCount == MAX_UINT8)) ||
        (!IsIncrement && (CurrNodeCount == 0)))
    {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }

    // Update the node count in the DataNode.
    CurrNodeCount                              = IsIncrement ? (CurrNodeCount + 1) : (CurrNodeCount - 1);
    *(((AML_DATA_NODE *)NodeCountArg)->Buffer) =  CurrNodeCount;
  } else if (AmlNodeCompareOpCode (ObjectNode, AML_VAR_PACKAGE_OP, 0)) {
    // First fixed argument of PackageOp stores the number of elements
    // in the package. It is an integer (can be a BYTE, WORD, DWORD, QWORD).
    Status = AmlNodeUpdateIntegerValue (
               (AML_OBJECT_NODE *)NodeCountArg,
               IsIncrement,
               NodeCount,
               FieldWidthChange
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/** Propagate information up the tree.

  The information can be a new size, a new number of arguments.

  @param  [in]  Node          Pointer to a node.
                              Must be a root node or an object node.
  @param  [in]  IsIncrement   Choose the operation to do:
                               - TRUE:  Increment the Node's size and
                                        the Node's count;
                               - FALSE: Decrement the Node's size and
                                        the Node's count.
  @param  [in]  Diff          Value to add/subtract to the Node's size.
  @param  [in]  NodeCount     Number of nodes added/removed.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlPropagateInformation (
  IN  AML_NODE_HEADER  *Node,
  IN  BOOLEAN          IsIncrement,
  IN  UINT32           Diff,
  IN  UINT8            NodeCount
  )
{
  EFI_STATUS  Status;
  INT8        FieldWidthChange;

  // Currently there is no use case where (NodeCount > 1).
  if ((!IS_AML_ROOT_NODE (Node)     &&
       !IS_AML_OBJECT_NODE (Node))  ||
      (NodeCount > 1))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Propagate the node count first as it may change the number of bytes
  // needed to store the node count, and then impact FieldWidthChange.
  if ((NodeCount != 0) &&
      IS_AML_OBJECT_NODE (Node))
  {
    Status = AmlPropagateNodeCount (
               (AML_OBJECT_NODE *)Node,
               IsIncrement,
               NodeCount,
               &FieldWidthChange
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    // Propagate the potential field width change.
    // Maximum change is between UINT8/UINT64: 8 bytes.
    if ((ABS (FieldWidthChange) > 8)                          ||
        (IsIncrement                                          &&
         ((FieldWidthChange < 0)                             ||
          ((Diff + (UINT8)FieldWidthChange) > MAX_UINT32)))  ||
        (!IsIncrement                                         &&
         ((FieldWidthChange > 0)                             ||
          (Diff < (UINT32)ABS (FieldWidthChange)))))
    {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }

    Diff = (UINT32)(Diff + (UINT8)ABS (FieldWidthChange));
  }

  // Diff can be zero if some data is updated without modifying the data size.
  if (Diff != 0) {
    Status = AmlPropagateSize (Node, IsIncrement, &Diff);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/** Find and set the EndTag's Checksum of a list of Resource Data elements.

  Lists of Resource Data elements end with an EndTag (most of the time). This
  function finds the EndTag (if present) in a list of Resource Data elements
  and sets the checksum.

  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]  BufferOpNode   Node having a list of Resource Data elements.
  @param [in]  CheckSum       CheckSum to store in the EndTag.
                              To ignore/avoid computing the checksum,
                              give 0.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND           No EndTag found.
**/
EFI_STATUS
EFIAPI
AmlSetRdListCheckSum (
  IN  AML_OBJECT_NODE  *BufferOpNode,
  IN  UINT8            CheckSum
  )
{
  EFI_STATUS     Status;
  AML_DATA_NODE  *LastRdNode;
  AML_RD_HEADER  RdDataType;

  if (!AmlNodeCompareOpCode (BufferOpNode, AML_BUFFER_OP, 0)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the last Resource data node in the variable list of
  // argument of the BufferOp node.
  LastRdNode = (AML_DATA_NODE *)AmlGetPreviousVariableArgument (
                                  (AML_NODE_HEADER *)BufferOpNode,
                                  NULL
                                  );
  if ((LastRdNode == NULL)             ||
      !IS_AML_DATA_NODE (LastRdNode)   ||
      (LastRdNode->DataType != EAmlNodeDataTypeResourceData))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlGetResourceDataType (LastRdNode, &RdDataType);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Check the LastRdNode is an EndTag.
  // It is possible to have only one Resource Data in a BufferOp with
  // no EndTag. Return EFI_NOT_FOUND is such case.
  if (!AmlRdCompareDescId (
         &RdDataType,
         AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME)
         ))
  {
    ASSERT (0);
    return EFI_NOT_FOUND;
  }

  Status = AmlRdSetEndTagChecksum (LastRdNode->Buffer, CheckSum);
  ASSERT_EFI_ERROR (Status);

  return Status;
}
