/** @file
  AML Parser.

  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Parser/AmlParser.h>

#include <AmlCoreInterface.h>
#include <AmlDbgPrint/AmlDbgPrint.h>
#include <Parser/AmlFieldListParser.h>
#include <Parser/AmlMethodParser.h>
#include <Parser/AmlResourceDataParser.h>
#include <String/AmlString.h>
#include <Tree/AmlNode.h>
#include <Tree/AmlTree.h>

/*
  AML Tree
  --------

  Each ASL Statement is represented in AML as and ObjectNode.
  Each ObjectNode has an Opcode and has up to six FixedArguments
  followed by a list of VariableArguments.
  (ObjectNode)
    \
    |- [0][1][2][3][4][5]                        # Fixed Arguments
    |- {(VarArg1)->(VarArg2)->(VarArg3)->...N}   # Variable Arguments

  A RootNode is a special type of Object Node that does not have an
  Opcode or Fixed Arguments. It only has a list of VariableArguments
  (RootNode)
    \
    |- {(VarArg1)->(VarArg2)->(VarArg3)->...N}   # Variable Arguments

  A DataNode consists of a data buffer.

  A FixedArgument or VariableArgument can be either an ObjectNode or
  a DataNode.

  Example:
  ASL code sample:
  Device (DEV0) {
    Name (VAR0, 0x6)
  }

  Tree generated from the ASL code:
  (RootNode)
    \
    |- {(Device statement (ObjectNode))}                # Variable Arg of the
          \                                             #   RootNode
           |
           |- [0] - Device Name (DataNode)(="DEV0")     # Fixed Arg0 of the
           |                                            #   Device() statement
           |
           |- {(Name statement (ObjectNode))}           # Variable Arg of the
                \                                       #   Device() statement
                |
                |- [0] - Name statement(DataNode)(="VAR0")  # Fixed Arg0 of the
                |                                           #   Name() statement
                |- [1] - Value(DataNode)(=0x6)              # Fixed Arg1 of the
                                                            #   Name() statement
*/

// Forward declaration.
STATIC
EFI_STATUS
EFIAPI
AmlParseStream (
  IN      AML_NODE_HEADER  *Node,
  IN  OUT AML_STREAM       *FStream,
  IN  OUT LIST_ENTRY       *NameSpaceRefList
  );

/** Function pointer to parse an AML construct.

  The expected format of the AML construct is passed in the
  ExpectedFormat argument. The available formats are available in
  the AML_PARSE_FORMAT enum definition.

  An object node or a data node is created in the function,
  and returned through the OutNode parameter. This node should
  be attached after this function returns.

  @param  [in]      ParentNode      Parent node to which the parsed
                                    AML construct will be attached.
  @param  [in]      ExpectedFormat  Format of the AML construct to parse.
  @param  [in, out] FStream         Forward stream containing the AML bytecode
                                    to parse.
                                    The stream must not be at its end.
  @param  [out]     OutNode         Pointer holding the node created from the
                                    parsed AML bytecode.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
typedef
EFI_STATUS
(EFIAPI *AML_PARSE_FUNCTION)(
  IN      CONST AML_NODE_HEADER   *Node,
  IN            AML_PARSE_FORMAT  ExpectedFormat,
  IN  OUT       AML_STREAM        *FStream,
  OUT       AML_NODE_HEADER       **OutNode
  );

/** Parse a UInt<X> (where X=8, 16, 32 or 64).

  A data node is created and returned through the OutNode parameter.

  @param  [in]      ParentNode      Parent node to which the parsed
                                    AML construct will be attached.
  @param  [in]      ExpectedFormat  Format of the AML construct to parse.
  @param  [in, out] FStream         Forward stream containing the AML bytecode
                                    to parse.
                                    The stream must not be at its end.
  @param  [out]     OutNode         Pointer holding the node created from the
                                    parsed AML bytecode.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlParseUIntX (
  IN      CONST AML_NODE_HEADER   *ParentNode,
  IN            AML_PARSE_FORMAT  ExpectedFormat,
  IN  OUT       AML_STREAM        *FStream,
  OUT       AML_NODE_HEADER       **OutNode
  )
{
  EFI_STATUS  Status;
  UINT32      UIntXSize;

  if ((!IS_AML_ROOT_NODE (ParentNode)       &&
       !IS_AML_OBJECT_NODE (ParentNode))    ||
      ((ExpectedFormat != EAmlUInt8)        &&
       (ExpectedFormat != EAmlUInt16)       &&
       (ExpectedFormat != EAmlUInt32)       &&
       (ExpectedFormat != EAmlUInt64))      ||
      !IS_STREAM (FStream)                  ||
      IS_END_OF_STREAM (FStream)            ||
      !IS_STREAM_FORWARD (FStream)          ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  switch (ExpectedFormat) {
    case EAmlUInt8:
      UIntXSize = 1;
      break;
    case EAmlUInt16:
      UIntXSize = 2;
      break;
    case EAmlUInt32:
      UIntXSize = 4;
      break;
    case EAmlUInt64:
      UIntXSize = 8;
      break;
    default:
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
  }

  Status = AmlCreateDataNode (
             AmlTypeToNodeDataType (ExpectedFormat),
             AmlStreamGetCurrPos (FStream),
             UIntXSize,
             (AML_DATA_NODE **)OutNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  AMLDBG_DUMP_RAW (AmlStreamGetCurrPos (FStream), UIntXSize);

  // Move stream forward by the size of UIntX.
  Status = AmlStreamProgress (FStream, UIntXSize);
  if (EFI_ERROR (Status)) {
    AmlDeleteTree (*OutNode);
    ASSERT (0);
  }

  return Status;
}

/** Parse an AML NameString.

  A data node is created and returned through the OutNode parameter.

  @param  [in]      ParentNode      Parent node to which the parsed
                                    AML construct will be attached.
  @param  [in]      ExpectedFormat  Format of the AML construct to parse.
  @param  [in, out] FStream         Forward stream containing the AML bytecode
                                    to parse.
                                    The stream must not be at its end.
  @param  [out]     OutNode         Pointer holding the node created from the
                                    parsed AML bytecode.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlParseNameString (
  IN      CONST AML_NODE_HEADER   *ParentNode,
  IN            AML_PARSE_FORMAT  ExpectedFormat,
  IN  OUT       AML_STREAM        *FStream,
  OUT       AML_NODE_HEADER       **OutNode
  )
{
  EFI_STATUS  Status;

  CONST UINT8              *Buffer;
  CONST AML_BYTE_ENCODING  *ByteEncoding;
  UINT32                   StrSize;

  if ((!IS_AML_ROOT_NODE (ParentNode)     &&
       !IS_AML_OBJECT_NODE (ParentNode))  ||
      (ExpectedFormat != EAmlName)        ||
      !IS_STREAM (FStream)                ||
      IS_END_OF_STREAM (FStream)          ||
      !IS_STREAM_FORWARD (FStream)        ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Buffer       = (CONST UINT8 *)AmlStreamGetCurrPos (FStream);
  ByteEncoding = AmlGetByteEncoding (Buffer);
  if ((ByteEncoding == NULL)    ||
      ((ByteEncoding->Attribute & AML_IS_NAME_CHAR) == 0))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Parse the NameString.
  Status = AmlGetNameStringSize ((CONST CHAR8 *)Buffer, &StrSize);
  if ((EFI_ERROR (Status))  ||
      (StrSize > AmlStreamGetFreeSpace (FStream)))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlCreateDataNode (
             EAmlNodeDataTypeNameString,
             Buffer,
             StrSize,
             (AML_DATA_NODE **)OutNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  AMLDBG_DUMP_RAW (AmlStreamGetCurrPos (FStream), StrSize);

  // Move the stream forward by StrSize.
  Status = AmlStreamProgress (FStream, StrSize);
  if (EFI_ERROR (Status)) {
    AmlDeleteTree (*OutNode);
    ASSERT (0);
  }

  return Status;
}

/** Parse an AML String.

  A data node is created and returned through the OutNode parameter.

  @param  [in]      ParentNode      Parent node to which the parsed
                                    AML construct will be attached.
  @param  [in]      ExpectedFormat  Format of the AML construct to parse.
  @param  [in, out] FStream         Forward stream containing the AML bytecode
                                    to parse.
                                    The stream must not be at its end.
  @param  [out]     OutNode         Pointer holding the node created from the
                                    parsed AML bytecode.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlParseString (
  IN      CONST AML_NODE_HEADER   *ParentNode,
  IN            AML_PARSE_FORMAT  ExpectedFormat,
  IN  OUT       AML_STREAM        *FStream,
  OUT       AML_NODE_HEADER       **OutNode
  )
{
  EFI_STATUS   Status;
  UINT32       StrSize;
  UINT8        Byte;
  CONST UINT8  *Buffer;

  if ((!IS_AML_ROOT_NODE (ParentNode)     &&
       !IS_AML_OBJECT_NODE (ParentNode))  ||
      (ExpectedFormat != EAmlString)      ||
      !IS_STREAM (FStream)                ||
      IS_END_OF_STREAM (FStream)          ||
      !IS_STREAM_FORWARD (FStream)        ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Buffer  = (CONST UINT8 *)AmlStreamGetCurrPos (FStream);
  StrSize = 0;
  // AML String is NULL terminated.
  do {
    // Reading the stream moves the stream forward as well.
    Status = AmlStreamReadByte (FStream, &Byte);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    StrSize++;
  } while (Byte != '\0');

  AMLDBG_DUMP_RAW (Buffer, StrSize);

  Status = AmlCreateDataNode (
             AmlTypeToNodeDataType (ExpectedFormat),
             Buffer,
             StrSize,
             (AML_DATA_NODE **)OutNode
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Parse an AML object.

  An object can be resolved as an AML object with an OpCode,
  or a NameString. An object node or a data node is created
  and returned through the OutNode parameter.

  @param  [in]      ParentNode      Parent node to which the parsed
                                    AML construct will be attached.
  @param  [in]      ExpectedFormat  Format of the AML construct to parse.
  @param  [in, out] FStream         Forward stream containing the AML bytecode
                                    to parse.
                                    The stream must not be at its end.
  @param  [out]     OutNode         Pointer holding the node created from the
                                    parsed AML bytecode.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlParseObject (
  IN      CONST AML_NODE_HEADER   *ParentNode,
  IN            AML_PARSE_FORMAT  ExpectedFormat,
  IN  OUT       AML_STREAM        *FStream,
  OUT       AML_NODE_HEADER       **OutNode
  )
{
  EFI_STATUS  Status;

  UINT8   OpCodeSize;
  UINT32  PkgLength;
  UINT32  PkgOffset;
  UINT32  FreeSpace;

  CONST AML_BYTE_ENCODING  *AmlByteEncoding;
  CONST UINT8              *Buffer;

  if ((!IS_AML_ROOT_NODE (ParentNode)     &&
       !IS_AML_OBJECT_NODE (ParentNode))  ||
      (ExpectedFormat != EAmlObject)      ||
      !IS_STREAM (FStream)                ||
      IS_END_OF_STREAM (FStream)          ||
      !IS_STREAM_FORWARD (FStream)        ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  PkgLength = 0;

  // 0. Get the AML Byte encoding.
  AmlByteEncoding = AmlGetByteEncoding (AmlStreamGetCurrPos (FStream));
  if (AmlByteEncoding == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // 1. Check for NameString.
  //    Indeed a NameString can be found when an AML object is expected.
  //    e.g. VAR0 = 3         // VAR0 is assigned an object which is a UINT.
  //         VAR1 = VAR2      // VAR2 is a NameString.
  //    If this is a NameString, return. A NameString can be a variable, a
  //    method invocation, etc.
  if ((AmlByteEncoding->Attribute & AML_IS_NAME_CHAR) != 0) {
    Status = AmlParseNameString (
               ParentNode,
               EAmlName,
               FStream,
               OutNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }

    return Status;
  }

  // 2. Determine the OpCode size to move the stream forward.
  Buffer = (CONST UINT8 *)AmlStreamGetCurrPos (FStream);
  if (*Buffer == AML_EXT_OP) {
    OpCodeSize = 2;
  } else {
    OpCodeSize = 1;
  }

  Status = AmlStreamProgress (FStream, OpCodeSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Print the opcode.
  AMLDBG_DUMP_RAW (Buffer, OpCodeSize);

  if (!IS_END_OF_STREAM (FStream)) {
    // 3. Parse the PkgLength field, if present.
    if ((AmlByteEncoding->Attribute & AML_HAS_PKG_LENGTH) != 0) {
      Buffer    = (CONST UINT8 *)AmlStreamGetCurrPos (FStream);
      PkgOffset = AmlGetPkgLength (Buffer, &PkgLength);
      if (PkgOffset == 0) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      // Print the package length.
      AMLDBG_DUMP_RAW (Buffer, PkgOffset);

      // Adjust the size of the stream if it is valid  package length.
      FreeSpace = AmlStreamGetFreeSpace (FStream);
      if (FreeSpace > PkgLength) {
        // Reduce the stream size by (FreeSpace - PkgLength) bytes.
        AmlStreamReduceMaxBufferSize (FStream, FreeSpace - PkgLength);
      } else if (FreeSpace != PkgLength) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      Status = AmlStreamProgress (FStream, PkgOffset);
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }
    }
  } else if ((AmlByteEncoding->Attribute & AML_HAS_PKG_LENGTH) != 0) {
    // The stream terminated unexpectedly. A PkgLen had to be parsed.
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // 4. Create an Object Node.
  Status = AmlCreateObjectNode (
             AmlByteEncoding,
             PkgLength,
             (AML_OBJECT_NODE **)OutNode
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Parse a FieldPkgLen.

  A FieldPkgLen can only be found in a field list, i.e. in a NamedField field
  element. The PkgLen is otherwise part of the object node structure.
  A data node is created and returned through the OutNode parameter.

  @param  [in]      ParentNode      Parent node to which the parsed
                                    AML construct will be attached.
  @param  [in]      ExpectedFormat  Format of the AML construct to parse.
  @param  [in, out] FStream         Forward stream containing the AML bytecode
                                    to parse.
                                    The stream must not be at its end.
  @param  [out]     OutNode         Pointer holding the node created from the
                                    parsed AML bytecode.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlParseFieldPkgLen (
  IN      CONST AML_NODE_HEADER   *ParentNode,
  IN            AML_PARSE_FORMAT  ExpectedFormat,
  IN  OUT       AML_STREAM        *FStream,
  OUT       AML_NODE_HEADER       **OutNode
  )
{
  EFI_STATUS   Status;
  EFI_STATUS   Status1;
  CONST UINT8  *Buffer;
  UINT32       PkgOffset;
  UINT32       PkgLength;

  if (!AmlNodeHasAttribute (
         (CONST AML_OBJECT_NODE *)ParentNode,
         AML_IS_FIELD_ELEMENT
         )                                ||
      (ExpectedFormat != EAmlFieldPkgLen) ||
      !IS_STREAM (FStream)                ||
      IS_END_OF_STREAM (FStream)          ||
      !IS_STREAM_FORWARD (FStream)        ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Buffer = (CONST UINT8 *)AmlStreamGetCurrPos (FStream);

  PkgOffset = AmlGetPkgLength (Buffer, &PkgLength);
  if (PkgOffset == 0) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Warning: Since, updating of field elements is not supported, store the
  // FieldPkgLength in a Data Node as a raw buffer.
  Status = AmlCreateDataNode (
             AmlTypeToNodeDataType (ExpectedFormat),
             Buffer,
             PkgOffset,
             (AML_DATA_NODE **)OutNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  AMLDBG_DUMP_RAW (Buffer, PkgOffset);

  Status = AmlStreamProgress (FStream, PkgOffset);
  if (EFI_ERROR (Status)) {
    Status1 = AmlDeleteNode (*OutNode);
    ASSERT_EFI_ERROR (Status1);
    ASSERT (0);
  }

  return Status;
}

/** Array of functions pointers to parse the AML constructs.

  The AML Byte encoding tables in Aml.c describe the format of the AML
  statements. The AML_PARSE_FORMAT enum definition lists these constructs
  and the corresponding parsing functions.
*/
AML_PARSE_FUNCTION  mParseType[EAmlParseFormatMax] = {
  NULL,                    // EAmlNone
  AmlParseUIntX,           // EAmlUInt8
  AmlParseUIntX,           // EAmlUInt16
  AmlParseUIntX,           // EAmlUInt32
  AmlParseUIntX,           // EAmlUInt64
  AmlParseObject,          // EAmlObject
  AmlParseNameString,      // EAmlName
  AmlParseString,          // EAmlString
  AmlParseFieldPkgLen      // EAmlFieldPkgLen
};

/** Check whether the NameString stored in the data node is a method invocation.
    If so, create a method invocation node and return it.

  @param  [in]      ParentNode        Node to which the parsed AML construct
                                      will be attached.
  @param  [in]      DataNode          Data node containing a NameString,
                                      potentially being a method invocation.
  @param  [in, out] NameSpaceRefList  List of namespace reference nodes.
  @param  [out]     OutNode           Pointer holding the method invocation
                                      node if the NameString contained in the
                                      data node is a method invocation.
                                      NULL otherwise.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCheckAndParseMethodInvoc (
  IN  CONST AML_NODE_HEADER  *ParentNode,
  IN        AML_DATA_NODE    *DataNode,
  IN  OUT   LIST_ENTRY       *NameSpaceRefList,
  OUT   AML_OBJECT_NODE      **OutNode
  )
{
  EFI_STATUS              Status;
  AML_NAMESPACE_REF_NODE  *NameSpaceRefNode;
  AML_OBJECT_NODE         *MethodInvocationNode;
  AML_STREAM              FStream;

  if ((!IS_AML_ROOT_NODE (ParentNode)                     &&
       !IS_AML_OBJECT_NODE (ParentNode))                  ||
      !IS_AML_DATA_NODE (DataNode)                        ||
      (DataNode->DataType != EAmlNodeDataTypeNameString)  ||
      (NameSpaceRefList == NULL)                          ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Initialize a stream containing the NameString which is checked.
  Status = AmlStreamInit (
             &FStream,
             DataNode->Buffer,
             DataNode->Size,
             EAmlStreamDirectionForward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Check whether the NameString is a method invocation.
  NameSpaceRefNode = NULL;
  Status           = AmlIsMethodInvocation (
                       ParentNode,
                       &FStream,
                       NameSpaceRefList,
                       &NameSpaceRefNode
                       );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  MethodInvocationNode = NULL;
  if (NameSpaceRefNode != NULL) {
    // A matching method definition has been found.
    // Create a method invocation node.
    Status = AmlCreateMethodInvocationNode (
               NameSpaceRefNode,
               (AML_DATA_NODE *)DataNode,
               &MethodInvocationNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  }

  *OutNode = MethodInvocationNode;

  return EFI_SUCCESS;
}

/** Call the appropriate function to parse the AML construct in the stream.

  The ExpectedFormat parameter allows to choose the right parsing function.
  An object node or a data node is created according to format.

  @param  [in]      ParentNode        Node to which the parsed AML construct
                                      will be attached.
  @param  [in]      ExpectedFormat    Format of the AML construct to parse.
  @param  [in, out] FStream           Forward stream containing the AML
                                      bytecode to parse.
                                      The stream must not be at its end.
  @param  [in, out] NameSpaceRefList  List of namespace reference nodes.
  @param  [out]     OutNode           Pointer holding the node created from the
                                      parsed AML bytecode.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlParseArgument (
  IN      CONST AML_NODE_HEADER   *ParentNode,
  IN            AML_PARSE_FORMAT  ExpectedFormat,
  IN  OUT       AML_STREAM        *FStream,
  IN  OUT       LIST_ENTRY        *NameSpaceRefList,
  OUT       AML_NODE_HEADER       **OutNode
  )
{
  EFI_STATUS          Status;
  AML_PARSE_FUNCTION  ParsingFunction;
  AML_DATA_NODE       *DataNode;
  AML_OBJECT_NODE     *MethodInvocationNode;

  if ((!IS_AML_ROOT_NODE (ParentNode)         &&
       !IS_AML_OBJECT_NODE (ParentNode))      ||
      (ExpectedFormat >= EAmlParseFormatMax)  ||
      !IS_STREAM (FStream)                    ||
      IS_END_OF_STREAM (FStream)              ||
      !IS_STREAM_FORWARD (FStream)            ||
      (NameSpaceRefList == NULL)              ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ParsingFunction = mParseType[ExpectedFormat];
  if (ParsingFunction == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Note: The ParsingFunction moves the stream forward as it
  // consumes the AML bytecode
  Status = ParsingFunction (
             ParentNode,
             ExpectedFormat,
             FStream,
             OutNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Check whether the parsed argument is a NameString when an object
  // is expected. In such case, it could be a method invocation.
  DataNode = (AML_DATA_NODE *)*OutNode;
  if (IS_AML_DATA_NODE (DataNode)                         &&
      (DataNode->DataType == EAmlNodeDataTypeNameString)  &&
      (ExpectedFormat == EAmlObject))
  {
    Status = AmlCheckAndParseMethodInvoc (
               ParentNode,
               (AML_DATA_NODE *)*OutNode,
               NameSpaceRefList,
               &MethodInvocationNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    // A method invocation node has been created and the DataNode containing
    // the NameString has been attached to the MethodInvocationNode.
    // Replace the OutNode with the MethodInvocationNode.
    if (MethodInvocationNode != NULL) {
      *OutNode = (AML_NODE_HEADER *)MethodInvocationNode;
    }
  }

  return Status;
}

/** Parse the Bytelist in the stream.
    According to the content of the stream, create data node(s)
    and add them to the variable list of arguments.
    The byte list may be a list of resource data element or a simple byte list.

  @param  [in]  BufferNode    Object node having a byte list.
  @param  [in, out] FStream   Forward stream containing the AML bytecode
                              to parse.
                              The stream must not be at its end.

  @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
AmlParseByteList (
  IN      AML_OBJECT_NODE  *BufferNode,
  IN  OUT AML_STREAM       *FStream
  )
{
  EFI_STATUS       Status;
  AML_NODE_HEADER  *NewNode;
  CONST UINT8      *Buffer;
  UINT32           BufferSize;

  // Check whether the node is an Object Node and has byte list.
  if (!AmlNodeHasAttribute (BufferNode, AML_HAS_BYTE_LIST)  ||
      !IS_STREAM (FStream)                                  ||
      IS_END_OF_STREAM (FStream)                            ||
      !IS_STREAM_FORWARD (FStream))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // The buffer contains a list of resource data elements.
  if (AmlRdIsResourceDataBuffer (FStream)) {
    // Parse the resource data elements and add them as data nodes.
    // AmlParseResourceData() moves the stream forward.
    Status = AmlParseResourceData (BufferNode, FStream);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }
  } else {
    // The buffer doesn't contain a list of resource data elements.
    // Create a single node holding the whole buffer data.

    // CreateDataNode checks the Buffer and BufferSize values.
    Buffer     = (CONST UINT8 *)AmlStreamGetCurrPos (FStream);
    BufferSize = AmlStreamGetFreeSpace (FStream);

    Status = AmlCreateDataNode (
               EAmlNodeDataTypeRaw,
               Buffer,
               BufferSize,
               (AML_DATA_NODE **)&NewNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    Status = AmlVarListAddTailInternal (
               (AML_NODE_HEADER *)BufferNode,
               NewNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      AmlDeleteTree (NewNode);
      return Status;
    }

    AMLDBG_DUMP_RAW (Buffer, BufferSize);

    // Move the stream forward as we have consumed the Buffer.
    Status = AmlStreamProgress (FStream, BufferSize);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }
  }

  return Status;
}

/** Parse the list of fixed arguments of the input ObjectNode.

  For each argument, create a node and add it to the fixed argument list
  of the Node.
  If a fixed argument has children, parse them.

  @param  [in]  ObjectNode        Object node to parse the fixed arguments
                                  from.
  @param  [in]  FStream           Forward stream containing the AML
                                  bytecode to parse.
                                  The stream must not be at its end.
  @param  [in]  NameSpaceRefList  List of namespace reference nodes.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlParseFixedArguments (
  IN  AML_OBJECT_NODE  *ObjectNode,
  IN  AML_STREAM       *FStream,
  IN  LIST_ENTRY       *NameSpaceRefList
  )
{
  EFI_STATUS  Status;

  AML_NODE_HEADER  *FixedArgNode;
  AML_STREAM       FixedArgFStream;

  EAML_PARSE_INDEX        TermIndex;
  EAML_PARSE_INDEX        MaxIndex;
  CONST AML_PARSE_FORMAT  *Format;

  // Fixed arguments of method invocations node are handled differently.
  if (!IS_AML_OBJECT_NODE (ObjectNode)                              ||
      AmlNodeCompareOpCode (ObjectNode, AML_METHOD_INVOC_OP, 0)     ||
      !IS_STREAM (FStream)                                          ||
      IS_END_OF_STREAM (FStream)                                    ||
      !IS_STREAM_FORWARD (FStream)                                  ||
      (NameSpaceRefList == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  TermIndex = EAmlParseIndexTerm0;
  MaxIndex  = (EAML_PARSE_INDEX)AmlGetFixedArgumentCount (
                                  (AML_OBJECT_NODE *)ObjectNode
                                  );
  if ((ObjectNode->AmlByteEncoding != NULL)   &&
      (ObjectNode->AmlByteEncoding->Format != NULL))
  {
    Format = ObjectNode->AmlByteEncoding->Format;
  } else {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Parse all the FixedArgs.
  while ((TermIndex < MaxIndex)       &&
         !IS_END_OF_STREAM (FStream)  &&
         (Format[TermIndex] != EAmlNone))
  {
    // Initialize a FixedArgStream to parse the current fixed argument.
    Status = AmlStreamInitSubStream (FStream, &FixedArgFStream);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    // Parse the current fixed argument.
    Status = AmlParseArgument (
               (CONST AML_NODE_HEADER *)ObjectNode,
               Format[TermIndex],
               &FixedArgFStream,
               NameSpaceRefList,
               &FixedArgNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    // Add the fixed argument to the parent node's fixed argument list.
    // FixedArgNode can be an object or data node.
    Status = AmlSetFixedArgument (
               (AML_OBJECT_NODE *)ObjectNode,
               TermIndex,
               FixedArgNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      // Delete the sub-tree if the insertion failed.
      // Otherwise its reference will be lost.
      // Use DeleteTree because if the argument was a method invocation,
      // multiple nodes have been created.
      AmlDeleteTree (FixedArgNode);
      return Status;
    }

    // Parse the AML bytecode of the FixedArgNode if this is an object node.
    if (IS_AML_OBJECT_NODE (FixedArgNode) &&
        !IS_END_OF_STREAM (&FixedArgFStream))
    {
      Status = AmlParseStream (
                 FixedArgNode,
                 &FixedArgFStream,
                 NameSpaceRefList
                 );
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }
    }

    // Move the stream forward as we have consumed the sub-stream.
    Status = AmlStreamProgress (
               FStream,
               AmlStreamGetIndex (&FixedArgFStream)
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    TermIndex++;
  } // while

  return EFI_SUCCESS;
}

/** Parse the variable list of arguments of the input ObjectNode.

  For each variable argument, create a node and add it to the variable list of
  arguments of the Node.
  If a variable argument has children, parse them recursively.

  The arguments of method invocation nodes are added to the variable list of
  arguments of the method invocation node. It is necessary to first get
  the number of arguments to parse for this kind of node. A method invocation
  can have at most 7 fixed arguments.

  @param  [in]  Node              Node to parse the variable arguments
                                  from.
  @param  [in]  FStream           Forward stream containing the AML
                                  bytecode to parse.
                                  The stream must not be at its end.
  @param  [in]  NameSpaceRefList  List of namespace reference nodes.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlParseVariableArguments (
  IN  AML_NODE_HEADER  *Node,
  IN  AML_STREAM       *FStream,
  IN  LIST_ENTRY       *NameSpaceRefList
  )
{
  EFI_STATUS  Status;

  BOOLEAN  IsMethodInvocation;
  UINT8    MethodInvocationArgCount;

  AML_NODE_HEADER  *VarArgNode;
  AML_STREAM       VarArgFStream;

  if ((!AmlNodeHasAttribute (
          (CONST AML_OBJECT_NODE *)Node,
          AML_HAS_CHILD_OBJ
          ) &&
       !IS_AML_ROOT_NODE (Node))        ||
      !IS_STREAM (FStream)              ||
      IS_END_OF_STREAM (FStream)        ||
      !IS_STREAM_FORWARD (FStream)      ||
      (NameSpaceRefList == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlGetMethodInvocationArgCount (
             (CONST AML_OBJECT_NODE *)Node,
             &IsMethodInvocation,
             &MethodInvocationArgCount
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Parse variable arguments while the Stream is not empty.
  while (!IS_END_OF_STREAM (FStream)) {
    // If the number of variable arguments are counted, decrement the counter.
    if ((IsMethodInvocation) && (MethodInvocationArgCount-- == 0)) {
      return EFI_SUCCESS;
    }

    // Initialize a VarArgStream to parse the current variable argument.
    Status = AmlStreamInitSubStream (FStream, &VarArgFStream);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    // Parse the current variable argument.
    Status = AmlParseArgument (
               Node,
               EAmlObject,
               &VarArgFStream,
               NameSpaceRefList,
               &VarArgNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    // Add the variable argument to its parent variable list of arguments.
    // VarArgNode can be an object or data node.
    Status = AmlVarListAddTailInternal (
               (AML_NODE_HEADER *)Node,
               VarArgNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      // Delete the sub-tree if the insertion failed.
      // Otherwise its reference will be lost.
      // Use DeleteTree because if the argument was a method invocation,
      // multiple nodes have been created.
      AmlDeleteTree (VarArgNode);
      return Status;
    }

    // Parse the AML bytecode of the VarArgNode if this is an object node.
    if (IS_AML_OBJECT_NODE (VarArgNode)       &&
        (!IS_END_OF_STREAM (&VarArgFStream)))
    {
      Status = AmlParseStream (VarArgNode, &VarArgFStream, NameSpaceRefList);
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }
    }

    // Move the stream forward as we have consumed the sub-stream.
    Status = AmlStreamProgress (
               FStream,
               AmlStreamGetIndex (&VarArgFStream)
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  } // while

  // If the number of variable arguments are counted, check all the
  // MethodInvocationArgCount have been parsed.
  if (IsMethodInvocation && (MethodInvocationArgCount != 0)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  return Status;
}

/** Parse the AML stream and populate the root node.

  @param  [in]      RootNode          RootNode to which the children are
                                      added.
  @param  [in, out] FStream           Forward stream containing the AML
                                      bytecode to parse.
                                      The stream must not be at its end.
  @param  [in, out] NameSpaceRefList  List of namespace reference nodes.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlPopulateRootNode (
  IN      AML_ROOT_NODE  *RootNode,
  IN  OUT AML_STREAM     *FStream,
  IN  OUT LIST_ENTRY     *NameSpaceRefList
  )
{
  EFI_STATUS  Status;

  if (!IS_AML_ROOT_NODE (RootNode)  ||
      !IS_STREAM (FStream)          ||
      IS_END_OF_STREAM (FStream)    ||
      !IS_STREAM_FORWARD (FStream)  ||
      (NameSpaceRefList == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // A Root Node only has variable arguments.
  Status = AmlParseVariableArguments (
             (AML_NODE_HEADER *)RootNode,
             FStream,
             NameSpaceRefList
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Parse the AML stream an populate the object node.

  @param  [in]      ObjectNode        ObjectNode to which the children are
                                      added.
  @param  [in, out] FStream           Forward stream containing the AML
                                      bytecode to parse.
                                      The stream must not be at its end.
  @param  [in, out] NameSpaceRefList  List of namespace reference nodes.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlPopulateObjectNode (
  IN      AML_OBJECT_NODE  *ObjectNode,
  IN  OUT AML_STREAM       *FStream,
  IN  OUT LIST_ENTRY       *NameSpaceRefList
  )
{
  EFI_STATUS  Status;

  if (!IS_AML_OBJECT_NODE (ObjectNode)  ||
      !IS_STREAM (FStream)              ||
      IS_END_OF_STREAM (FStream)        ||
      !IS_STREAM_FORWARD (FStream)      ||
      (NameSpaceRefList == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = EFI_SUCCESS;

  // Don't parse the fixed arguments of method invocation nodes.
  // The AML encoding for method invocations in the ACPI specification 6.3 is:
  // MethodInvocation := NameString TermArgList
  // Since the AML specification does not define an OpCode for method
  // invocation, this AML parser defines a pseudo opcode and redefines the
  // grammar for simplicity as:
  // MethodInvocation := MethodInvocationOp NameString ArgumentCount TermArgList
  // ArgumentCount    := ByteData
  // Due to this difference, the MethodInvocationOp and the fixed argument
  // i.e. ArgumentCount is not available in the AML stream and need to be
  // handled differently.
  if (!AmlNodeCompareOpCode (ObjectNode, AML_METHOD_INVOC_OP, 0)) {
    // Parse the fixed list of arguments.
    Status = AmlParseFixedArguments (
               ObjectNode,
               FStream,
               NameSpaceRefList
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  }

  // Save the association [node reference/pathname] in the NameSpaceRefList.
  // This allows to identify method invocations from other namespace
  // paths. Method invocation need to be parsed differently.
  if (AmlNodeHasAttribute (
        (CONST AML_OBJECT_NODE *)ObjectNode,
        AML_IN_NAMESPACE
        ))
  {
    Status = AmlAddNameSpaceReference (
               (CONST AML_OBJECT_NODE *)ObjectNode,
               NameSpaceRefList
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  }

  if (!IS_END_OF_STREAM (FStream)) {
    // Parse the variable list of arguments if present.
    if (AmlNodeHasAttribute (ObjectNode, AML_HAS_CHILD_OBJ)) {
      Status = AmlParseVariableArguments (
                 (AML_NODE_HEADER *)ObjectNode,
                 FStream,
                 NameSpaceRefList
                 );
    } else if (AmlNodeHasAttribute (ObjectNode, AML_HAS_BYTE_LIST)) {
      // Parse the byte list if present.
      Status = AmlParseByteList (
                 ObjectNode,
                 FStream
                 );
    } else if (AmlNodeHasAttribute (ObjectNode, AML_HAS_FIELD_LIST)) {
      // Parse the field list if present.
      Status = AmlParseFieldList (
                 ObjectNode,
                 FStream,
                 NameSpaceRefList
                 );
    }

    // Check status and assert
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }
  }

  return Status;
}

/** Invoke the appropriate parsing functions based on the Node type.

  @param  [in]      Node              Node from which the children are parsed.
                                      Must be a root node or an object node.
  @param  [in]      FStream           Forward stream containing the AML
                                      bytecode to parse.
                                      The stream must not be at its end.
  @param  [in]      NameSpaceRefList  List of namespace reference nodes.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlParseStream (
  IN  AML_NODE_HEADER  *Node,
  IN  AML_STREAM       *FStream,
  IN  LIST_ENTRY       *NameSpaceRefList
  )
{
  EFI_STATUS  Status;

  if (IS_AML_ROOT_NODE (Node)) {
    Status = AmlPopulateRootNode (
               (AML_ROOT_NODE *)Node,
               FStream,
               NameSpaceRefList
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }
  } else if (IS_AML_OBJECT_NODE (Node)) {
    Status = AmlPopulateObjectNode (
               (AML_OBJECT_NODE *)Node,
               FStream,
               NameSpaceRefList
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }
  } else {
    // Data node or other.
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
  }

  return Status;
}

/** Parse the definition block.

  This function parses the whole AML blob. It starts with the ACPI DSDT/SSDT
  header and then parses the AML bytestream.
  A tree structure is returned via the RootPtr.
  The tree must be deleted with the AmlDeleteTree function.

  @param  [in]  DefinitionBlock   Pointer to the definition block.
  @param  [out] RootPtr           Pointer to the root node of the tree.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlParseDefinitionBlock (
  IN  CONST EFI_ACPI_DESCRIPTION_HEADER  *DefinitionBlock,
  OUT       AML_ROOT_NODE                **RootPtr
  )
{
  EFI_STATUS     Status;
  EFI_STATUS     Status1;
  AML_STREAM     Stream;
  AML_ROOT_NODE  *Root;

  LIST_ENTRY  NameSpaceRefList;

  UINT8   *Buffer;
  UINT32  MaxBufferSize;

  if ((DefinitionBlock == NULL)   ||
      (RootPtr == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Buffer = (UINT8 *)DefinitionBlock + sizeof (EFI_ACPI_DESCRIPTION_HEADER);
  if (DefinitionBlock->Length < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  MaxBufferSize = DefinitionBlock->Length -
                  (UINT32)sizeof (EFI_ACPI_DESCRIPTION_HEADER);

  // Create a root node.
  Status = AmlCreateRootNode (
             (EFI_ACPI_DESCRIPTION_HEADER *)DefinitionBlock,
             &Root
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  *RootPtr = Root;

  if (MaxBufferSize == 0) {
    return EFI_SUCCESS;
  }

  // Initialize a stream to parse the AML bytecode.
  Status = AmlStreamInit (
             &Stream,
             Buffer,
             MaxBufferSize,
             EAmlStreamDirectionForward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // Initialize the NameSpaceRefList, holding references to nodes declaring
  // a name in the AML namespace.
  InitializeListHead (&NameSpaceRefList);

  // Parse the whole AML blob.
  Status = AmlParseStream (
             (AML_NODE_HEADER *)Root,
             &Stream,
             &NameSpaceRefList
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // Check the whole AML blob has been parsed.
  if (!IS_END_OF_STREAM (&Stream)) {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto error_handler;
  }

  // Print the list of NameSpace reference nodes.
  // AmlDbgPrintNameSpaceRefList (&NameSpaceRefList);

  // Delete the NameSpaceRefList
  goto exit_handler;

error_handler:
  if (Root != NULL) {
    AmlDeleteTree ((AML_NODE_HEADER *)Root);
  }

exit_handler:
  Status1 = AmlDeleteNameSpaceRefList (&NameSpaceRefList);
  if (EFI_ERROR (Status1)) {
    ASSERT (0);
    if (!EFI_ERROR (Status)) {
      return Status1;
    }
  }

  return Status;
}
