/** @file
  AML Node.

  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Tree/AmlNode.h>

#include <AmlCoreInterface.h>
#include <Tree/AmlTree.h>

/** Initialize an AML_NODE_HEADER structure.

  @param  [in]  Node      Pointer to a node header.
  @param  [in]  NodeType  NodeType to initialize the Node with.
                          Must be an EAML_NODE_TYPE.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlInitializeNodeHeader (
  IN  AML_NODE_HEADER  *Node,
  IN  EAML_NODE_TYPE   NodeType
  )
{
  if (Node == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  InitializeListHead (&Node->Link);

  Node->Parent   = NULL;
  Node->NodeType = NodeType;

  return EFI_SUCCESS;
}

/** Delete a root node and its ACPI DSDT/SSDT header.

  It is the caller's responsibility to check the RootNode has been removed
  from the tree and is not referencing any other node in the tree.

  @param  [in]  RootNode  Pointer to a root node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlDeleteRootNode (
  IN  AML_ROOT_NODE  *RootNode
  )
{
  if (!IS_AML_ROOT_NODE (RootNode)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if ((RootNode->SdtHeader != NULL)) {
    FreePool (RootNode->SdtHeader);
  } else {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  FreePool (RootNode);
  return EFI_SUCCESS;
}

/** Create an AML_ROOT_NODE.
    This node will be the root of the tree.

  @param  [in]  SdtHeader       Pointer to an ACPI DSDT/SSDT header to copy
                                the data from.
  @param  [out] NewRootNodePtr  If success, contains the created
                                AML_ROOT_NODE.
                                Otherwise reset to NULL.

  @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
AmlCreateRootNode (
  IN  CONST EFI_ACPI_DESCRIPTION_HEADER  *SdtHeader,
  OUT       AML_ROOT_NODE                **NewRootNodePtr
  )
{
  EFI_STATUS     Status;
  AML_ROOT_NODE  *RootNode;

  if ((SdtHeader == NULL) ||
      (NewRootNodePtr == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *NewRootNodePtr = NULL;

  RootNode = AllocateZeroPool (sizeof (AML_ROOT_NODE));
  if (RootNode == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = AmlInitializeNodeHeader (&RootNode->NodeHeader, EAmlNodeRoot);
  if (EFI_ERROR (Status)) {
    FreePool (RootNode);
    ASSERT (0);
    return Status;
  }

  InitializeListHead (&RootNode->VariableArgs);

  RootNode->SdtHeader = AllocateCopyPool (
                          sizeof (EFI_ACPI_DESCRIPTION_HEADER),
                          SdtHeader
                          );
  if (RootNode->SdtHeader == NULL) {
    ASSERT (0);
    AmlDeleteRootNode (RootNode);
    return EFI_OUT_OF_RESOURCES;
  }

  *NewRootNodePtr = RootNode;

  return EFI_SUCCESS;
}

/** Delete an object node.

  It is the caller's responsibility to check the ObjectNode has been removed
  from the tree and is not referencing any other node in the tree.

  @param  [in]  ObjectNode  Pointer to an object node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlDeleteObjectNode (
  IN  AML_OBJECT_NODE  *ObjectNode
  )
{
  if (!IS_AML_OBJECT_NODE (ObjectNode)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  FreePool (ObjectNode);
  return EFI_SUCCESS;
}

/** Create an AML_OBJECT_NODE.

  @param  [in]  AmlByteEncoding   Byte encoding entry.
  @param  [in]  PkgLength         PkgLength of the node if the AmlByteEncoding
                                  has the PkgLen attribute.
                                  0 otherwise.
  @param  [out] NewObjectNodePtr  If success, contains the created
                                  AML_OBJECT_NODE.
                                  Otherwise reset to NULL.

  @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
AmlCreateObjectNode (
  IN  CONST  AML_BYTE_ENCODING  *AmlByteEncoding,
  IN         UINT32             PkgLength,
  OUT        AML_OBJECT_NODE    **NewObjectNodePtr
  )
{
  EFI_STATUS       Status;
  AML_OBJECT_NODE  *ObjectNode;

  if ((AmlByteEncoding == NULL)  ||
      (NewObjectNodePtr == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *NewObjectNodePtr = NULL;

  ObjectNode = AllocateZeroPool (sizeof (AML_OBJECT_NODE));
  if (ObjectNode == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = AmlInitializeNodeHeader (&ObjectNode->NodeHeader, EAmlNodeObject);
  if (EFI_ERROR (Status)) {
    FreePool (ObjectNode);
    ASSERT (0);
    return Status;
  }

  InitializeListHead (&ObjectNode->VariableArgs);

  // ObjectNode->FixedArgs[...] is already initialised to NULL as the
  // ObjectNode is Zero allocated.
  ObjectNode->AmlByteEncoding = AmlByteEncoding;
  ObjectNode->PkgLen          = PkgLength;

  *NewObjectNodePtr = ObjectNode;

  return EFI_SUCCESS;
}

/** Delete a data node and its buffer.

  It is the caller's responsibility to check the DataNode has been removed
  from the tree and is not referencing any other node in the tree.

  @param  [in]  DataNode  Pointer to a data 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
AmlDeleteDataNode (
  IN  AML_DATA_NODE  *DataNode
  )
{
  if (!IS_AML_DATA_NODE (DataNode)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if (DataNode->Buffer != NULL) {
    FreePool (DataNode->Buffer);
  } else {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  FreePool (DataNode);
  return EFI_SUCCESS;
}

/** Create an AML_DATA_NODE.

  @param  [in]  DataType        DataType of the node.
  @param  [in]  Data            Pointer to the AML bytecode corresponding to
                                this node. Data is copied from there.
  @param  [in]  DataSize        Number of bytes to consider at the address
                                pointed by Data.
  @param  [out] NewDataNodePtr  If success, contains the created
                                AML_DATA_NODE.
                                Otherwise reset to NULL.

  @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
AmlCreateDataNode (
  IN        EAML_NODE_DATA_TYPE  DataType,
  IN  CONST UINT8                *Data,
  IN        UINT32               DataSize,
  OUT       AML_DATA_NODE        **NewDataNodePtr
  )
{
  EFI_STATUS     Status;
  AML_DATA_NODE  *DataNode;

  // A data node must not be created for certain data types.
  if ((DataType == EAmlNodeDataTypeNone)       ||
      (DataType == EAmlNodeDataTypeReserved1)  ||
      (DataType == EAmlNodeDataTypeReserved2)  ||
      (DataType == EAmlNodeDataTypeReserved3)  ||
      (DataType == EAmlNodeDataTypeReserved4)  ||
      (DataType == EAmlNodeDataTypeReserved5)  ||
      (Data == NULL)                           ||
      (DataSize == 0)                          ||
      (NewDataNodePtr == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *NewDataNodePtr = NULL;

  DataNode = AllocateZeroPool (sizeof (AML_DATA_NODE));
  if (DataNode == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = AmlInitializeNodeHeader (&DataNode->NodeHeader, EAmlNodeData);
  if (EFI_ERROR (Status)) {
    FreePool (DataNode);
    ASSERT (0);
    return Status;
  }

  DataNode->Buffer = AllocateCopyPool (DataSize, Data);
  if (DataNode->Buffer == NULL) {
    AmlDeleteDataNode (DataNode);
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  DataNode->DataType = DataType;
  DataNode->Size     = DataSize;

  *NewDataNodePtr = DataNode;

  return EFI_SUCCESS;
}

/** Delete a Node.

  @param  [in]  Node  Pointer to a Node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlDeleteNode (
  IN  AML_NODE_HEADER  *Node
  )
{
  EFI_STATUS        Status;
  EAML_PARSE_INDEX  Index;

  // Check that the node being deleted is unlinked.
  // When removing the node, its parent and list are reset
  // with InitializeListHead. Thus it must be empty.
  if (!IS_AML_NODE_VALID (Node) ||
      !AML_NODE_IS_DETACHED (Node))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  switch (Node->NodeType) {
    case EAmlNodeRoot:
    {
      // Check the variable list of arguments has been cleaned.
      if (!IsListEmpty (AmlNodeGetVariableArgList (Node))) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      Status = AmlDeleteRootNode ((AML_ROOT_NODE *)Node);
      if (EFI_ERROR (Status)) {
        ASSERT (0);
      }

      break;
    }

    case EAmlNodeObject:
    {
      // Check the variable list of arguments has been cleaned.
      if (!IsListEmpty (AmlNodeGetVariableArgList (Node))) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      // Check the fixed argument list has been cleaned.
      for (Index = EAmlParseIndexTerm0; Index < EAmlParseIndexMax; Index++) {
        if (((AML_OBJECT_NODE *)Node)->FixedArgs[Index] != NULL) {
          ASSERT (0);
          return EFI_INVALID_PARAMETER;
        }
      }

      Status = AmlDeleteObjectNode ((AML_OBJECT_NODE *)Node);
      if (EFI_ERROR (Status)) {
        ASSERT (0);
      }

      break;
    }

    case EAmlNodeData:
    {
      Status = AmlDeleteDataNode ((AML_DATA_NODE *)Node);
      if (EFI_ERROR (Status)) {
        ASSERT (0);
      }

      break;
    }

    default:
    {
      ASSERT (0);
      Status = EFI_INVALID_PARAMETER;
      break;
    }
  } // switch

  return Status;
}

/** Check whether ObjectNode has the input attribute.
    This function can be used to check ObjectNode is an object node
    at the same time.

  @param  [in]  ObjectNode  Pointer to an object node.
  @param  [in]  Attribute   Attribute to check for.

  @retval TRUE    The node is an AML object and the attribute is present.
  @retval FALSE   Otherwise.
**/
BOOLEAN
EFIAPI
AmlNodeHasAttribute (
  IN  CONST AML_OBJECT_NODE   *ObjectNode,
  IN        AML_OP_ATTRIBUTE  Attribute
  )
{
  if (!IS_AML_OBJECT_NODE (ObjectNode) ||
      (ObjectNode->AmlByteEncoding == NULL))
  {
    return FALSE;
  }

  return ((ObjectNode->AmlByteEncoding->Attribute &
           Attribute) == 0 ? FALSE : TRUE);
}

/** Check whether ObjectNode has the input OpCode/SubOpcode couple.

  @param  [in]  ObjectNode  Pointer to an object node.
  @param  [in]  OpCode      OpCode to check
  @param  [in]  SubOpCode   SubOpCode to check

  @retval TRUE    The node is an AML object and
                  the Opcode and the SubOpCode match.
  @retval FALSE   Otherwise.
**/
BOOLEAN
EFIAPI
AmlNodeCompareOpCode (
  IN  CONST  AML_OBJECT_NODE  *ObjectNode,
  IN         UINT8            OpCode,
  IN         UINT8            SubOpCode
  )
{
  if (!IS_AML_OBJECT_NODE (ObjectNode) ||
      (ObjectNode->AmlByteEncoding == NULL))
  {
    return FALSE;
  }

  ASSERT (AmlIsOpCodeValid (OpCode, SubOpCode));

  return ((ObjectNode->AmlByteEncoding->OpCode == OpCode) &&
          (ObjectNode->AmlByteEncoding->SubOpCode == SubOpCode)) ?
         TRUE : FALSE;
}

/** Check whether a Node is an integer node.

  By integer node we mean an object node having one of the following opcode:
   - AML_BYTE_PREFIX;
   - AML_WORD_PREFIX;
   - AML_DWORD_PREFIX;
   - AML_QWORD_PREFIX.

  @param  [in]  Node  The node to check.

  @retval TRUE  The Node is an integer node.
  @retval FALSE Otherwise.
**/
BOOLEAN
EFIAPI
IsIntegerNode (
  IN  AML_OBJECT_NODE  *Node
  )
{
  UINT8  OpCode;

  if (!IS_AML_OBJECT_NODE (Node)  ||
      (Node->AmlByteEncoding == NULL))
  {
    return FALSE;
  }

  // Check Node is an integer node.
  OpCode = Node->AmlByteEncoding->OpCode;
  if ((OpCode != AML_BYTE_PREFIX)   &&
      (OpCode != AML_WORD_PREFIX)   &&
      (OpCode != AML_DWORD_PREFIX)  &&
      (OpCode != AML_QWORD_PREFIX))
  {
    return FALSE;
  }

  return TRUE;
}

/** Check whether a Node is a ZeroOp, a OneOp or a OnesOp.

  These two objects don't have a data node holding
  a value. This require special handling.

  @param  [in]  Node  The node to check.

  @retval TRUE  The Node is a ZeroOp or OneOp.
  @retval FALSE Otherwise.
**/
BOOLEAN
EFIAPI
IsSpecialIntegerNode (
  IN  AML_OBJECT_NODE  *Node
  )
{
  UINT8  OpCode;

  if (!IS_AML_OBJECT_NODE (Node)  ||
      (Node->AmlByteEncoding == NULL))
  {
    return FALSE;
  }

  OpCode = Node->AmlByteEncoding->OpCode;

  if ((OpCode != AML_ZERO_OP) &&
      (OpCode != AML_ONE_OP)  &&
      (OpCode != AML_ONES_OP))
  {
    return FALSE;
  }

  return TRUE;
}

/** Check whether Node corresponds to a method definition.

  A method definition can be introduced:
   - By a method object, having an AML_METHOD_OP OpCode;
   - By an external definition of a method, having an AML_EXTERNAL_OP OpCode
     and an ObjectType byte set to the MethodObj.

  Note:
  An alias node, having an AML_ALIAS_OP, can be resolved to a method
  definition. This function doesn't handle this case.

  @param [in] Node    Node to check whether it is a method definition.

  @retval TRUE  The Node is a method definition.
  @retval FALSE Otherwise.
**/
BOOLEAN
EFIAPI
AmlIsMethodDefinitionNode (
  IN  CONST AML_OBJECT_NODE  *Node
  )
{
  AML_DATA_NODE  *ObjectType;

  // Node is checked to be an object node as well.
  if (AmlNodeCompareOpCode (Node, AML_METHOD_OP, 0)) {
    return TRUE;
  } else if (AmlNodeCompareOpCode (Node, AML_EXTERNAL_OP, 0)) {
    // If the node is an external definition, check this is a method.
    // DefExternal := ExternalOp NameString ObjectType ArgumentCount
    // ExternalOp := 0x15
    // ObjectType := ByteData
    // ArgumentCount := ByteData (0 - 7)
    ObjectType = (AML_DATA_NODE *)AmlGetFixedArgument (
                                    (AML_OBJECT_NODE *)Node,
                                    EAmlParseIndexTerm1
                                    );
    if (IS_AML_DATA_NODE (ObjectType)                   &&
        (ObjectType->DataType == EAmlNodeDataTypeUInt)  &&
        ((ObjectType->Size == 1)))
    {
      if (*((UINT8 *)ObjectType->Buffer) == (UINT8)EAmlObjTypeMethodObj) {
        // The external definition is a method.
        return TRUE;
      } else {
        // The external definition is not a method.
        return FALSE;
      }
    } else {
      // The tree is inconsistent.
      ASSERT (0);
      return FALSE;
    }
  }

  // This is not a method definition.
  return FALSE;
}

/** Get the index at which the name of the node is stored.

  @param  [in]  ObjectNode  Pointer to an object node.
                            Must have the AML_IN_NAMESPACE attribute.
  @param  [out] Index       Index of the name in the fixed list of arguments.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
AmlNodeGetNameIndex (
  IN  CONST AML_OBJECT_NODE   *ObjectNode,
  OUT       EAML_PARSE_INDEX  *Index
  )
{
  EAML_PARSE_INDEX  NameIndex;

  if (!AmlNodeHasAttribute (ObjectNode, AML_IN_NAMESPACE)   ||
      (ObjectNode->AmlByteEncoding == NULL)                 ||
      (Index == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  NameIndex = ObjectNode->AmlByteEncoding->NameIndex;

  if ((NameIndex > ObjectNode->AmlByteEncoding->MaxIndex)   ||
      (ObjectNode->AmlByteEncoding->Format[NameIndex] != EAmlName))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *Index = NameIndex;

  return EFI_SUCCESS;
}

/** Get the name of the Node.

  Node must be part of the namespace.

  @param [in] ObjectNode    Pointer to an object node,
                            which is part of the namespace.

  @return A pointer to the name.
          NULL otherwise.
          Return NULL for the root node.
**/
CHAR8 *
EFIAPI
AmlNodeGetName (
  IN  CONST AML_OBJECT_NODE  *ObjectNode
  )
{
  EFI_STATUS        Status;
  EAML_PARSE_INDEX  NameIndex;
  AML_DATA_NODE     *DataNode;

  if (!AmlNodeHasAttribute (ObjectNode, AML_IN_NAMESPACE)) {
    ASSERT (0);
    return NULL;
  }

  // Get the index at which the name is stored in the fixed arguments list.
  Status = AmlNodeGetNameIndex (ObjectNode, &NameIndex);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return NULL;
  }

  // The name is stored in a Data node.
  DataNode = (AML_DATA_NODE *)ObjectNode->FixedArgs[NameIndex];
  if (IS_AML_DATA_NODE (DataNode) &&
      (DataNode->DataType == EAmlNodeDataTypeNameString))
  {
    return (CHAR8 *)DataNode->Buffer;
  }

  /* Return NULL if no name is found.
     This can occur if the name of a node is defined as a further
     fixed argument.
     E.g.:  CreateField (BD03, 0x28, Add (ID03 + 0x08), BF33)
                                     ^
                             The parser is here.
     The parent of the Add statement is the CreateField statement. This
     statement defines a name in the AML namespace. This name defined as
     the fourth fixed argument. It hasn't been parsed yet.
  */
  return NULL;
}
