/** @file
  AML Api.

  Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

/* Even though this file has access to the internal Node definition,
   i.e. AML_ROOT_NODE, AML_OBJECT_NODE, etc. Only the external node
   handle types should be used, i.e. AML_NODE_HANDLE, AML_ROOT_NODE_HANDLE,
   etc.
   Indeed, the functions in the "Api" folder should be implemented only
   using the "safe" functions available in the "Include" folder. This
   makes the functions available in the "Api" folder easy to export.
*/
#include <AmlNodeDefines.h>

#include <AmlCoreInterface.h>
#include <AmlInclude.h>
#include <Api/AmlApiHelper.h>
#include <String/AmlString.h>

/** Update the name of a DeviceOp object node.

  @param  [in] DeviceOpNode   Object node representing a Device.
                              Must have an OpCode=AML_NAME_OP, SubOpCode=0.
                              OpCode/SubOpCode.
                              DeviceOp object nodes are defined in ASL
                              using the "Device ()" function.
  @param  [in] NewNameString  The new Device's name.
                              Must be a NULL-terminated ASL NameString
                              e.g.: "DEV0", "DV15.DEV0", etc.
                              The input string is copied.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlDeviceOpUpdateName (
  IN  AML_OBJECT_NODE_HANDLE  DeviceOpNode,
  IN  CHAR8                   *NewNameString
  )
{
  EFI_STATUS  Status;

  AML_DATA_NODE_HANDLE  DeviceNameDataNode;
  CHAR8                 *NewAmlNameString;
  UINT32                NewAmlNameStringSize;

  // Check the input node is an object node.
  if ((DeviceOpNode == NULL)                                              ||
      (AmlGetNodeType ((AML_NODE_HANDLE)DeviceOpNode) != EAmlNodeObject)  ||
      (!AmlNodeHasOpCode (DeviceOpNode, AML_EXT_OP, AML_EXT_DEVICE_OP))   ||
      (NewNameString == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the Device's name, being a data node
  // which is the 1st fixed argument (i.e. index 0).
  DeviceNameDataNode = (AML_DATA_NODE_HANDLE)AmlGetFixedArgument (
                                               DeviceOpNode,
                                               EAmlParseIndexTerm0
                                               );
  if ((DeviceNameDataNode == NULL)                                            ||
      (AmlGetNodeType ((AML_NODE_HANDLE)DeviceNameDataNode) != EAmlNodeData)  ||
      (!AmlNodeHasDataType (DeviceNameDataNode, EAmlNodeDataTypeNameString)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = ConvertAslNameToAmlName (NewNameString, &NewAmlNameString);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlGetNameStringSize (NewAmlNameString, &NewAmlNameStringSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // Update the Device's name node.
  Status = AmlUpdateDataNode (
             DeviceNameDataNode,
             EAmlNodeDataTypeNameString,
             (UINT8 *)NewAmlNameString,
             NewAmlNameStringSize
             );
  ASSERT_EFI_ERROR (Status);

exit_handler:
  FreePool (NewAmlNameString);
  return Status;
}

/** Update an integer value defined by a NameOp object node.

  For compatibility reasons, the NameOpNode must initially
  contain an integer.

  @param  [in] NameOpNode   NameOp object node.
                            Must have an OpCode=AML_NAME_OP, SubOpCode=0.
                            NameOp object nodes are defined in ASL
                            using the "Name ()" function.
  @param  [in] NewInt       New Integer value to assign.
                            Must be a UINT64.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlNameOpUpdateInteger (
  IN  AML_OBJECT_NODE_HANDLE  NameOpNode,
  IN  UINT64                  NewInt
  )
{
  EFI_STATUS              Status;
  AML_OBJECT_NODE_HANDLE  IntegerOpNode;

  if ((NameOpNode == NULL)                                             ||
      (AmlGetNodeType ((AML_NODE_HANDLE)NameOpNode) != EAmlNodeObject) ||
      (!AmlNodeHasOpCode (NameOpNode, AML_NAME_OP, 0)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the Integer object node defined by the "Name ()" function:
  // it must have an Integer OpCode (Byte/Word/DWord/QWord).
  // It is the 2nd fixed argument (i.e. index 1) of the NameOp node.
  // This can also be a ZeroOp or OneOp node.
  IntegerOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
                                            NameOpNode,
                                            EAmlParseIndexTerm1
                                            );
  if ((IntegerOpNode == NULL)  ||
      (AmlGetNodeType ((AML_NODE_HANDLE)IntegerOpNode) != EAmlNodeObject))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Update the Integer value.
  Status = AmlUpdateInteger (IntegerOpNode, NewInt);
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Update a string value defined by a NameOp object node.

  The NameOpNode must initially contain a string.
  The EISAID ASL macro converts a string to an integer. This, it is
  not accepted.

  @param  [in] NameOpNode   NameOp object node.
                            Must have an OpCode=AML_NAME_OP, SubOpCode=0.
                            NameOp object nodes are defined in ASL
                            using the "Name ()" function.
  @param  [in] NewName      New NULL terminated string to assign to
                            the NameOpNode.
                            The input string is copied.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlNameOpUpdateString (
  IN        AML_OBJECT_NODE_HANDLE  NameOpNode,
  IN  CONST CHAR8                   *NewName
  )
{
  EFI_STATUS              Status;
  AML_OBJECT_NODE_HANDLE  StringOpNode;
  AML_DATA_NODE_HANDLE    StringDataNode;

  if ((NameOpNode == NULL)                                             ||
      (AmlGetNodeType ((AML_NODE_HANDLE)NameOpNode) != EAmlNodeObject) ||
      (!AmlNodeHasOpCode (NameOpNode, AML_NAME_OP, 0)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the String object node defined by the "Name ()" function:
  // it must have a string OpCode.
  // It is the 2nd fixed argument (i.e. index 1) of the NameOp node.
  StringOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
                                           NameOpNode,
                                           EAmlParseIndexTerm1
                                           );
  if ((StringOpNode == NULL)  ||
      (AmlGetNodeType ((AML_NODE_HANDLE)StringOpNode) != EAmlNodeObject))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the string data node.
  // It is the 1st fixed argument (i.e. index 0) of the StringOpNode node.
  StringDataNode = (AML_DATA_NODE_HANDLE)AmlGetFixedArgument (
                                           StringOpNode,
                                           EAmlParseIndexTerm0
                                           );
  if ((StringDataNode == NULL)  ||
      (AmlGetNodeType ((AML_NODE_HANDLE)StringDataNode) != EAmlNodeData))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Update the string value.
  Status = AmlUpdateDataNode (
             StringDataNode,
             EAmlNodeDataTypeString,
             (UINT8 *)NewName,
             (UINT32)AsciiStrLen (NewName) + 1
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Get the first Resource Data element contained in a named object.

  In the following ASL code, the function will return the Resource Data
  node corresponding to the "QWordMemory ()" ASL macro.
  Name (_CRS, ResourceTemplate() {
      QWordMemory (...) {...},
      Interrupt (...) {...}
    }
  )

  Note:
  "_CRS" names defined as methods are not handled by this function.
  They must be defined as names, using the "Name ()" statement.

  @param  [in] NameOpNode   NameOp object node defining a named object.
                            Must have an OpCode=AML_NAME_OP, SubOpCode=0.
                            NameOp object nodes are defined in ASL
                            using the "Name ()" function.
  @param  [out] OutRdNode   Pointer to the first Resource Data element of
                            the named object. A Resource Data element
                            is stored in a data node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlNameOpGetFirstRdNode (
  IN  AML_OBJECT_NODE_HANDLE  NameOpNode,
  OUT AML_DATA_NODE_HANDLE    *OutRdNode
  )
{
  AML_OBJECT_NODE_HANDLE  BufferOpNode;
  AML_DATA_NODE_HANDLE    FirstRdNode;

  if ((NameOpNode == NULL)                                              ||
      (AmlGetNodeType ((AML_NODE_HANDLE)NameOpNode) != EAmlNodeObject)  ||
      (!AmlNodeHasOpCode (NameOpNode, AML_NAME_OP, 0))                  ||
      (OutRdNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *OutRdNode = NULL;

  // Get the value of the variable which is represented as a BufferOp object
  // node which is the 2nd fixed argument (i.e. index 1).
  BufferOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
                                           NameOpNode,
                                           EAmlParseIndexTerm1
                                           );
  if ((BufferOpNode == NULL)                                             ||
      (AmlGetNodeType ((AML_NODE_HANDLE)BufferOpNode) != EAmlNodeObject) ||
      (!AmlNodeHasOpCode (BufferOpNode, AML_BUFFER_OP, 0)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the first Resource data node in the variable list of
  // argument of the BufferOp node.
  FirstRdNode = (AML_DATA_NODE_HANDLE)AmlGetNextVariableArgument (
                                        (AML_NODE_HANDLE)BufferOpNode,
                                        NULL
                                        );
  if ((FirstRdNode == NULL)                                            ||
      (AmlGetNodeType ((AML_NODE_HANDLE)FirstRdNode) != EAmlNodeData)  ||
      (!AmlNodeHasDataType (FirstRdNode, EAmlNodeDataTypeResourceData)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *OutRdNode = FirstRdNode;
  return EFI_SUCCESS;
}

/** Get the Resource Data element following the CurrRdNode Resource Data.

  In the following ASL code, if CurrRdNode corresponds to the first
  "QWordMemory ()" ASL macro, the function will return the Resource Data
  node corresponding to the "Interrupt ()" ASL macro.
  Name (_CRS, ResourceTemplate() {
      QwordMemory (...) {...},
      Interrupt (...) {...}
    }
  )

  Note:
  "_CRS" names defined as methods are not handled by this function.
  They must be defined as names, using the "Name ()" statement.

  @param  [in]  CurrRdNode   Pointer to the current Resource Data element of
                             the named object.
  @param  [out] OutRdNode    Pointer to the Resource Data element following
                             the CurrRdNode.
                             Contain a NULL pointer if CurrRdNode is the
                             last Resource Data element in the list.
                             The "End Tag" is not considered as a resource
                             data element and is not returned.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlNameOpGetNextRdNode (
  IN  AML_DATA_NODE_HANDLE  CurrRdNode,
  OUT AML_DATA_NODE_HANDLE  *OutRdNode
  )
{
  AML_OBJECT_NODE_HANDLE  NameOpNode;
  AML_OBJECT_NODE_HANDLE  BufferOpNode;

  if ((CurrRdNode == NULL)                                              ||
      (AmlGetNodeType ((AML_NODE_HANDLE)CurrRdNode) != EAmlNodeData)    ||
      (!AmlNodeHasDataType (CurrRdNode, EAmlNodeDataTypeResourceData))  ||
      (OutRdNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *OutRdNode = NULL;

  // The parent of the CurrRdNode must be a BufferOp node.
  BufferOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetParent (
                                           (AML_NODE_HANDLE)CurrRdNode
                                           );
  if ((BufferOpNode == NULL)  ||
      (!AmlNodeHasOpCode (BufferOpNode, AML_BUFFER_OP, 0)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // The parent of the BufferOpNode must be a NameOp node.
  NameOpNode = (AML_OBJECT_NODE_HANDLE)AmlGetParent (
                                         (AML_NODE_HANDLE)BufferOpNode
                                         );
  if ((NameOpNode == NULL)  ||
      (!AmlNodeHasOpCode (NameOpNode, AML_NAME_OP, 0)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *OutRdNode = (AML_DATA_NODE_HANDLE)AmlGetNextVariableArgument (
                                       (AML_NODE_HANDLE)BufferOpNode,
                                       (AML_NODE_HANDLE)CurrRdNode
                                       );

  // If the Resource Data is an End Tag, return NULL.
  if (AmlNodeHasRdDataType (
        *OutRdNode,
        AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME)
        ))
  {
    *OutRdNode = NULL;
  }

  return EFI_SUCCESS;
}

/** Attach a node in an AML tree.

  The node will be added as the last statement of the ParentNode.
  E.g.:
  ASL code corresponding to NewNode:
  Name (_UID, 0)

  ASL code corresponding to ParentNode:
  Device (PCI0) {
    Name(_HID, EISAID("PNP0A08"))
  }

  "AmlAttachNode (ParentNode, NewNode)" will result in:
  ASL code:
  Device (PCI0) {
    Name(_HID, EISAID("PNP0A08"))
    Name (_UID, 0)
  }

  @param  [in]  ParentNode  Pointer to the parent node.
                            Must be a root or an object node.
  @param  [in]  NewNode     Pointer to the node to add.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlAttachNode (
  IN  AML_NODE_HANDLE  ParentNode,
  IN  AML_NODE_HANDLE  NewNode
  )
{
  return AmlVarListAddTail (ParentNode, NewNode);
}
