/** @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 aswell.
    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;
}
