/** @file
  AML Method Parser.

  Copyright (c) 2020, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Parser/AmlMethodParser.h>

#include <AmlCoreInterface.h>
#include <AmlDbgPrint/AmlDbgPrint.h>
#include <NameSpace/AmlNameSpace.h>
#include <Parser/AmlParser.h>
#include <Tree/AmlNode.h>
#include <Tree/AmlTree.h>
#include <String/AmlString.h>

/** Delete a namespace reference node and its pathname.

  It is the caller's responsibility to check the NameSpaceRefNode has been
  removed from any list the node is part of.

  @param  [in]  NameSpaceRefNode   Pointer to an AML_NAMESPACE_REF_NODE.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlDeleteNameSpaceRefNode (
  IN  AML_NAMESPACE_REF_NODE    * NameSpaceRefNode
  )
{
  if (NameSpaceRefNode == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  if (NameSpaceRefNode->RawAbsolutePath != NULL) {
    FreePool ((CHAR8*)NameSpaceRefNode->RawAbsolutePath);
  } else {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  FreePool (NameSpaceRefNode);
  return EFI_SUCCESS;
}

/** Delete a list of namespace reference nodes.

  @param  [in]  NameSpaceRefList    List of namespace reference nodes.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlDeleteNameSpaceRefList (
  IN  LIST_ENTRY      * NameSpaceRefList
  )
{
  EFI_STATUS        Status;
  LIST_ENTRY      * CurrentLink;

  if (NameSpaceRefList == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  while (!IsListEmpty (NameSpaceRefList)) {
    CurrentLink = NameSpaceRefList->ForwardLink;
    RemoveEntryList (CurrentLink);
    Status = AmlDeleteNameSpaceRefNode (
               (AML_NAMESPACE_REF_NODE*)CurrentLink
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  } // while

  return EFI_SUCCESS;
}

/** Create an AML_NAMESPACE_REF_NODE.

  A Buffer is allocated to store the raw AML absolute path.

  @param  [in]  ObjectNode          Node being part of the namespace.
                                    Must be have the AML_IN_NAMESPACE
                                    attribute.
  @param  [in]  RawAbsolutePath     AML raw absolute path of the ObjectNode.
                                    A raw NameString is a concatenated list
                                    of 4 chars long names.
  @param  [in]  RawAbsolutePathSize Size of the RawAbsolutePath buffer.
  @param  [out] NameSpaceRefNodePtr The created AML_METHOD_REF_NODE.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCreateMethodRefNode (
  IN  CONST AML_OBJECT_NODE         * ObjectNode,
  IN  CONST CHAR8                   * RawAbsolutePath,
  IN        UINT32                    RawAbsolutePathSize,
  OUT       AML_NAMESPACE_REF_NODE ** NameSpaceRefNodePtr
  )
{
  AML_NAMESPACE_REF_NODE     * NameSpaceRefNode;

  if (!AmlNodeHasAttribute (ObjectNode, AML_IN_NAMESPACE) ||
      (RawAbsolutePath == NULL)                           ||
      (RawAbsolutePathSize == 0)                          ||
      (NameSpaceRefNodePtr == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  NameSpaceRefNode = AllocateZeroPool (sizeof (AML_NAMESPACE_REF_NODE));
  if (NameSpaceRefNode == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  NameSpaceRefNode->RawAbsolutePathSize = RawAbsolutePathSize;
  NameSpaceRefNode->RawAbsolutePath = AllocateCopyPool (
                                        RawAbsolutePathSize,
                                        RawAbsolutePath
                                        );
  if (NameSpaceRefNode->RawAbsolutePath == NULL) {
    FreePool (NameSpaceRefNode);
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (&NameSpaceRefNode->Link);

  NameSpaceRefNode->NodeRef = ObjectNode;
  *NameSpaceRefNodePtr = NameSpaceRefNode;

  return EFI_SUCCESS;
}

#if !defined (MDEPKG_NDEBUG)

/** Print the list of raw absolute paths of the NameSpace reference list.

  @param  [in]  NameSpaceRefList    List of NameSpace reference nodes.
**/
VOID
EFIAPI
AmlDbgPrintNameSpaceRefList (
  IN  CONST LIST_ENTRY    * NameSpaceRefList
  )
{
  LIST_ENTRY              * CurrLink;
  AML_NAMESPACE_REF_NODE  * CurrNameSpaceNode;

  if (NameSpaceRefList == NULL) {
    ASSERT (0);
    return;
  }

  DEBUG ((DEBUG_INFO, "AmlMethodParser: List of available raw AML paths:\n"));

  CurrLink = NameSpaceRefList->ForwardLink;
  while (CurrLink != NameSpaceRefList) {
    CurrNameSpaceNode = (AML_NAMESPACE_REF_NODE*)CurrLink;

    AMLDBG_PRINT_CHARS (
      DEBUG_INFO,
      CurrNameSpaceNode->RawAbsolutePath,
      CurrNameSpaceNode->RawAbsolutePathSize
      );
    DEBUG ((DEBUG_INFO, "\n"));

    CurrLink = CurrLink->ForwardLink;
  }

  DEBUG ((DEBUG_INFO, "\n"));
}

#endif // MDEPKG_NDEBUG

/** From a forward stream pointing to a NameString,
    initialize a raw backward stream.

        StartOfStream
  Fstream: CurrPos                                 EndOfStream
             v                                        v
             +-----------------------------------------+
             |^^^[Multi-name prefix]AAAA.BBBB.CCCC     |
             +-----------------------------------------+
                                    ^            ^
  RawPathNameBStream:           EndOfStream    CurrPos
                                            StartOfStream

  No memory is allocated when initializing the stream.

  @param  [in]  FStream             Forward stream pointing to a NameString.
                                    The stream must not be at its end.
  @param  [out] RawPathNameBStream  Backward stream containing the
                                    raw AML path.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlInitRawPathBStream (
  IN  CONST AML_STREAM    * FStream,
  OUT       AML_STREAM    * RawPathNameBStream
  )
{
  EFI_STATUS    Status;

  UINT8       * RawPathBuffer;
  CONST CHAR8 * Buffer;

  UINT32        Root;
  UINT32        ParentPrefix;
  UINT32        SegCount;

  if (!IS_STREAM (FStream)          ||
      IS_END_OF_STREAM (FStream)    ||
      !IS_STREAM_FORWARD  (FStream) ||
      (RawPathNameBStream == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Buffer = (CONST CHAR8*)AmlStreamGetCurrPos (FStream);
  if (Buffer == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Parse the NameString information.
  Status = AmlParseNameStringInfo (
             Buffer,
             &Root,
             &ParentPrefix,
             &SegCount
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Get the beginning of the raw NameString.
  RawPathBuffer = (UINT8*)AmlGetFirstNameSeg (
                            Buffer,
                            Root,
                            ParentPrefix
                            );
  if (RawPathBuffer == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Initialize a backward stream containing the raw path.
  Status = AmlStreamInit (
             RawPathNameBStream,
             RawPathBuffer,
             (SegCount * AML_NAME_SEG_SIZE),
             EAmlStreamDirectionBackward
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Get the first node in the ParentNode branch that is part of the
    AML namespace and has its name defined.

  This is different from getting the first namespace node. This function is
  necessary because an absolute path is built while the tree is not complete
  yet. The parsing is ongoing.

  For instance, the ASL statement "CreateXXXField ()" adds a field in the
  AML namespace, but the name it defines is the last fixed argument of the
  corresponding object.
  If an AML path is referenced in its first fixed argument, it is not
  possible to resolve the name of the CreateXXXField object. However, the AML
  path is not part of the scope created by the CreateXXXField object, so this
  scope can be skipped.

  In the following ASL code, the method invocation to MET0 is done in the
  "CreateField" statement. The "CreateField" statement defines the "FIEL"
  path in the AML namespace. However, MET0 must be not be resolved in the
  "CreateField" object scope. It needs to be resolved in its parent.
  ASL code:
  Method (MET0, 0,,, BuffObj) {
    Return (Buffer (0x1000) {})
  }
  CreateField (MET0(), 0x100, 0x4, FIEL)

  @param  [in]  Node          Node to get the first named node from, in
                              its hierarchy.
  @param  [out] OutNamedNode  First named node in Node's hierarchy.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlGetFirstNamedAncestorNode (
  IN  CONST AML_NODE_HEADER   * Node,
  OUT       AML_NODE_HEADER  ** OutNamedNode
  )
{
  EFI_STATUS                Status;
  CONST AML_NODE_HEADER   * NameSpaceNode;

  if ((!IS_AML_OBJECT_NODE (Node)   &&
       !IS_AML_ROOT_NODE (Node))    ||
      (OutNamedNode == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // If Node is not the root node and doesn't have a name defined yet,
  // get the ancestor NameSpace node.
  while (!IS_AML_ROOT_NODE (Node)             &&
         !(AmlNodeHasAttribute (
             (CONST AML_OBJECT_NODE*)Node,
              AML_IN_NAMESPACE)               &&
           AmlNodeGetName ((CONST AML_OBJECT_NODE*)Node) != NULL)) {
    Status = AmlGetFirstAncestorNameSpaceNode (
                Node,
                (AML_NODE_HEADER**)&NameSpaceNode
                );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
    // The NameSpaceNode may not have its name defined as yet. In this
    // case get the next ancestor node.
    Node = NameSpaceNode;
  }

  *OutNamedNode = (AML_NODE_HEADER*)Node;

  return EFI_SUCCESS;
}

/** From a ParentNode and a forward stream pointing to a relative path,
    build a raw AML absolute path and return it in a backward stream.

  No memory is allocated in this function, the out stream must be initialized
  with a buffer long enough to hold any raw absolute AML path.

  @param  [in]  ParentNode                  Parent node of the namespace
                                            node from which the absolute
                                            path is built. ParentNode isn't
                                            necessarily a namespace node.
                                            Must be a root or an object node.
  @param  [in]  PathnameFStream             Forward stream pointing to the
                                            beginning of a pathname (any
                                            NameString).
                                            The stream must not be at its end.
  @param  [in, out] AbsolutePathBStream     Backward stream where the raw
                                            absolute path is written. The
                                            stream must be already initialized.
                                            The stream must not be at its end.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlBuildRawMethodAbsolutePath (
  IN      CONST AML_NODE_HEADER   * ParentNode,
  IN      CONST AML_STREAM        * PathnameFStream,
  IN  OUT       AML_STREAM        * AbsolutePathBStream
  )
{
  EFI_STATUS          Status;

  AML_NODE_HEADER   * NamedParentNode;
  UINT8             * RawPathBuffer;
  CONST CHAR8       * CurrPos;

  UINT32              Root;
  UINT32              ParentPrefix;
  UINT32              SegCount;

  if ((!IS_AML_OBJECT_NODE (ParentNode)         &&
       !IS_AML_ROOT_NODE (ParentNode))          ||
      !IS_STREAM (PathnameFStream)              ||
      IS_END_OF_STREAM (PathnameFStream)        ||
      !IS_STREAM_FORWARD (PathnameFStream)      ||
      !IS_STREAM (AbsolutePathBStream)          ||
      IS_END_OF_STREAM (AbsolutePathBStream)    ||
      !IS_STREAM_BACKWARD (AbsolutePathBStream)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  CurrPos = (CONST CHAR8*)AmlStreamGetCurrPos (PathnameFStream);
  if (CurrPos == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Parse the NameString information.
  Status = AmlParseNameStringInfo (
             CurrPos,
             &Root,
             &ParentPrefix,
             &SegCount
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Copy the method invocation raw relative path at the end of the Stream.
  if (SegCount != 0) {
    // Get the beginning of the raw NameString.
    RawPathBuffer = (UINT8*)AmlGetFirstNameSeg (
                              CurrPos,
                              Root,
                              ParentPrefix
                              );

    Status = AmlStreamWrite (
               AbsolutePathBStream,
               RawPathBuffer,
               SegCount * AML_NAME_SEG_SIZE
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  }

  // If the pathname contained an absolute path, this is finished, return.
  if (Root) {
    return Status;
  }

  // Get the first named node of the parent node in its hierarchy.
  Status = AmlGetFirstNamedAncestorNode (ParentNode, &NamedParentNode);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Build the raw absolute path of the namespace node.
  Status = AmlGetRawNameSpacePath (
             NamedParentNode,
             ParentPrefix,
             AbsolutePathBStream
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/** Compare two raw NameStrings stored in forward streams.
    Compare them NameSeg by NameSeg (a NameSeg is 4 bytes long).

  The two raw NameStrings can be of different size.

  @param  [in]  RawFStream1     First forward stream to compare.
                                Points to the beginning of the raw NameString.
  @param  [in]  RawFStream2     Second forward stream to compare.
                                Points to the beginning of the raw NameString.
  @param  [out] CompareCount    Count of identic bytes.
                                Must be a multiple of 4 (size of a NameSeg).

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlCompareRawNameString (
  IN  CONST AML_STREAM    * RawFStream1,
  IN  CONST AML_STREAM    * RawFStream2,
  OUT       UINT32        * CompareCount
  )
{
  EFI_STATUS    Status;
  UINT32        Index;

  AML_STREAM    RawFStream1Clone;
  AML_STREAM    RawFStream2Clone;
  UINT32        Stream1Size;
  UINT32        Stream2Size;
  UINT32        CompareLen;

  // Raw NameStrings have a size that is a multiple of the size of NameSegs.
  if (!IS_STREAM (RawFStream1)          ||
      IS_END_OF_STREAM (RawFStream1)    ||
      !IS_STREAM_FORWARD (RawFStream1)  ||
      !IS_STREAM (RawFStream2)          ||
      IS_END_OF_STREAM (RawFStream2)    ||
      (CompareCount == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Stream1Size = AmlStreamGetFreeSpace (RawFStream1);
  if ((Stream1Size & (AML_NAME_SEG_SIZE - 1)) != 0) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Stream2Size = AmlStreamGetFreeSpace (RawFStream2);
  if ((Stream2Size & (AML_NAME_SEG_SIZE - 1)) != 0) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlStreamClone (RawFStream1, &RawFStream1Clone);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlStreamClone (RawFStream2, &RawFStream2Clone);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  CompareLen = MIN (Stream1Size, Stream2Size);
  Index = 0;
  // Check there is enough space for a NameSeg in both Stream1 and Stream2.
  while (Index < CompareLen) {
    if (!AmlStreamCmp (
           &RawFStream1Clone,
           &RawFStream2Clone,
           AML_NAME_SEG_SIZE)
           ) {
      // NameSegs are different. Break.
      break;
    }

    Status = AmlStreamProgress (&RawFStream1Clone, AML_NAME_SEG_SIZE);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
    Status = AmlStreamProgress (&RawFStream2Clone, AML_NAME_SEG_SIZE);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    Index += AML_NAME_SEG_SIZE;
  }

  *CompareCount = Index;

  return EFI_SUCCESS;
}

/** Check whether an alias can be resolved to a method definition.

  Indeed, the following ASL code must be handled:
    Method (MET0, 1) {
      Return (0x9)
    }
    Alias (\MET0, \ALI0)
    Alias (\ALI0, \ALI1)
    \ALI1(0x5)
  When searching for \ALI1 in the AML NameSpace, it resolves to \ALI0.
  When searching for \ALI0 in the AML NameSpace, it resolves to \MET0.
  When searching for \MET0 in the AML NameSpace, it resolves to a method
  definition.

  This method is a wrapper to recursively call AmlFindMethodDefinition.

  @param  [in]  AliasNode             Pointer to an Alias object node.
  @param  [in]  NameSpaceRefList      List of NameSpaceRef nodes.
  @param  [out] OutNameSpaceRefNode   If success, and if the alias is resolved
                                      to a method definition (this can go
                                      through other alias indirections),
                                      containing the corresponding
                                      NameSpaceRef node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlResolveAliasMethod (
  IN  CONST AML_OBJECT_NODE           * AliasNode,
  IN  CONST LIST_ENTRY                * NameSpaceRefList,
  OUT       AML_NAMESPACE_REF_NODE   ** OutNameSpaceRefNode
  )
{
  EFI_STATUS              Status;
  AML_STREAM              SourceAliasFStream;
  CONST AML_DATA_NODE   * DataNode;

  if (!AmlNodeCompareOpCode (AliasNode, AML_ALIAS_OP, 0)  ||
      (NameSpaceRefList == NULL)                          ||
      (OutNameSpaceRefNode == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // The aliased NameString (the source name) is the first fixed argument,
  // cf. ACPI6.3 spec, s19.6.4: Alias (SourceObject, AliasObject)
  DataNode = (CONST AML_DATA_NODE*)AmlGetFixedArgument (
                                     (AML_OBJECT_NODE*)AliasNode,
                                     EAmlParseIndexTerm0
                                     );
  if (DataNode == NULL) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Initialize a stream on the source alias NameString.
  Status = AmlStreamInit (
             &SourceAliasFStream,
             DataNode->Buffer,
             DataNode->Size,
             EAmlStreamDirectionForward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Recursively check whether the source alias NameString
  // is a method invocation.
  Status = AmlIsMethodInvocation (
             AmlGetParent ((AML_NODE_HEADER*)AliasNode),
             &SourceAliasFStream,
             NameSpaceRefList,
             OutNameSpaceRefNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
  }

  return Status;
}

/** Iterate through the MethodList to find the best namespace resolution.
    If the pathname resolves to a method definition, returns it.

  For instance, if the AML namespace is:
  \
  \-MET0         <- Device definition, absolute path: \MET0
  \-AAAA
    \-MET0       <- Method definition, absolute path: \AAAA.MET0
    \-MET1       <- Method definition, absolute path: \AAAA.MET1
    \-BBBB
      \-CCCC
        \-DDDD
          \-MET0 <- Method definition, absolute path: \AAAA.BBBB.CCCC.DDDD.MET0

  The list of the available pathnames is:
  [NameSpaceRefList]
   - \MET0                          <-  Device definition
   - \AAAA
   - \AAAA.MET0                     <-  Method definition
   - \AAAA.MET1                     <-  Method definition
   - \AAAA.BBBB
   - \AAAA.BBBB.CCCC
   - \AAAA.BBBB.CCCC.DDDD
   - \AAAA.BBBB.CCCC.DDDD.MET0      <-  Method definition

  Depending on where the method invocation is done, the method definition
  referenced changes. If the method call "MET0" is done from
  \AAAA.BBBB.CCCC:
    1. Identify which pathnames end with "MET0":
     - \MET0                          <-  Device definition
     - \AAAA.MET0                     <-  Method definition
     - \AAAA.BBBB.CCCC.DDDD.MET0      <-  Method definition
    2. Resolve the method invocation:
     - \AAAA.MET0                     <-  Method definition
    3. \AAAA.MET0 is a method definition, so return the corresponding
       reference node.

  @param  [in]  RawAbsolutePathFStream    Forward stream pointing to a raw
                                          absolute path.
                                          The stream must not be at its end.
  @param  [in]  RawPathNameBStream        Backward stream pointing to a raw
                                          pathname. This raw pathname is the
                                          raw NameString of namespace node.
                                          The stream must not be at its end.
  @param  [in]  NameSpaceRefList          List of NameSpaceRef nodes.
  @param  [out] OutNameSpaceRefNode       If the two input paths are
                                          referencing a method definition,
                                          returns the corresponding
                                          NameSpaceRef node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlFindMethodDefinition (
  IN  CONST AML_STREAM                * RawAbsolutePathFStream,
  IN  CONST AML_STREAM                * RawPathNameBStream,
  IN  CONST LIST_ENTRY                * NameSpaceRefList,
  OUT       AML_NAMESPACE_REF_NODE   ** OutNameSpaceRefNode
  )
{
  EFI_STATUS                Status;

  LIST_ENTRY              * NextLink;

  // To resolve a pathname, scope levels need to be compared.
  UINT32                    NameSegScopeCount;
  UINT32                    PathNameSegScopeCount;
  UINT32                    ProbedScopeCount;
  UINT32                    BestScopeCount;

  AML_STREAM                ProbedRawAbsoluteFStream;
  AML_STREAM                ProbedRawAbsoluteBStream;

  AML_NAMESPACE_REF_NODE  * ProbedNameSpaceRefNode;
  AML_NAMESPACE_REF_NODE  * BestNameSpaceRefNode;

  if (!IS_STREAM (RawAbsolutePathFStream)                               ||
      IS_END_OF_STREAM (RawAbsolutePathFStream)                         ||
      !IS_STREAM_FORWARD (RawAbsolutePathFStream)                       ||
      ((AmlStreamGetIndex (RawAbsolutePathFStream) &
        (AML_NAME_SEG_SIZE - 1)) != 0)                                  ||
      !IS_STREAM (RawPathNameBStream)                                   ||
      IS_END_OF_STREAM (RawPathNameBStream)                             ||
      !IS_STREAM_BACKWARD (RawPathNameBStream)                          ||
      ((AmlStreamGetIndex (RawPathNameBStream) &
        (AML_NAME_SEG_SIZE - 1)) != 0)                                  ||
      (NameSpaceRefList == NULL)                                        ||
      (OutNameSpaceRefNode == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((DEBUG_VERBOSE, "AmlMethodParser: Checking absolute name: "));
  AMLDBG_PRINT_CHARS (
    DEBUG_VERBOSE,
    (CONST CHAR8*)AmlStreamGetCurrPos (RawAbsolutePathFStream),
    AmlStreamGetMaxBufferSize (RawAbsolutePathFStream)
    );
  DEBUG ((DEBUG_VERBOSE, ".\n"));

  BestNameSpaceRefNode = NULL;
  BestScopeCount = 0;
  NameSegScopeCount = AmlStreamGetMaxBufferSize (RawAbsolutePathFStream);
  PathNameSegScopeCount = AmlStreamGetMaxBufferSize (RawPathNameBStream);

  // Iterate through the raw AML absolute path to find the best match.
  DEBUG ((DEBUG_VERBOSE, "AmlMethodParser: Comparing with: "));
  NextLink = NameSpaceRefList->ForwardLink;
  while (NextLink != NameSpaceRefList) {
    ProbedNameSpaceRefNode = (AML_NAMESPACE_REF_NODE*)NextLink;

    // Print the raw absolute path of the probed node.
    AMLDBG_PRINT_CHARS (
      DEBUG_VERBOSE,
      ProbedNameSpaceRefNode->RawAbsolutePath,
      ProbedNameSpaceRefNode->RawAbsolutePathSize
      );
    DEBUG ((DEBUG_VERBOSE, "; "));

    // If the raw AML absolute path of the probed node is longer than the
    // searched pathname, continue.
    // E.g.: The method call \MET0 cannot resolve to a method defined at
    //       \AAAA.MET0. The method definition is out of scope.
    if (PathNameSegScopeCount > ProbedNameSpaceRefNode->RawAbsolutePathSize) {
      NextLink = NextLink->ForwardLink;
      continue;
    }

    // Initialize a backward stream for the probed node.
    // This stream is used to compare the ending of the pathnames.
    // E.g. if the method searched ends with "MET0", pathnames not ending with
    //      "MET0" should be skipped.
    Status = AmlStreamInit (
               &ProbedRawAbsoluteBStream,
               (UINT8*)ProbedNameSpaceRefNode->RawAbsolutePath,
               ProbedNameSpaceRefNode->RawAbsolutePathSize,
               EAmlStreamDirectionBackward
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    // Compare the pathname endings. If they don't match, continue.
    if (!AmlStreamCmp (
           RawPathNameBStream,
           &ProbedRawAbsoluteBStream,
           AmlStreamGetMaxBufferSize (RawPathNameBStream))) {
      NextLink = NextLink->ForwardLink;
      continue;
    }

    // Initialize a forward stream for the probed node.
    // This stream is used to count how many scope levels from the root
    // are common with the probed node. The more there are, the better it is.
    // E.g.: For the method invocation \AAAA.BBBB.MET0, if there are 2
    //       pathnames ending with MET0:
    //        - \AAAA.MET0 has 1 NameSeg in common with \AAAA.BBBB.MET0
    //          from the root (this is "AAAA");
    //        - \MET0 has 0 NameSeg in common with \AAAA.BBBB.MET0
    //          from the root;
    //       Thus, the best match is \AAAA.MET0.
    Status = AmlStreamInit (
               &ProbedRawAbsoluteFStream,
               (UINT8*)ProbedNameSpaceRefNode->RawAbsolutePath,
               ProbedNameSpaceRefNode->RawAbsolutePathSize,
               EAmlStreamDirectionForward
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    // Count how many namespace levels are in common from the root.
    Status = AmlCompareRawNameString (
               RawAbsolutePathFStream,
               &ProbedRawAbsoluteFStream,
               &ProbedScopeCount
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }

    if (ProbedScopeCount == NameSegScopeCount) {
      // This is a perfect match. Exit the loop.
      BestNameSpaceRefNode = ProbedNameSpaceRefNode;
      break;
    } else if (ProbedScopeCount > BestScopeCount) {
      // The probed node has more scope levels in common than the
      // last best match. Update the best match.
      BestScopeCount = ProbedScopeCount;
      BestNameSpaceRefNode = ProbedNameSpaceRefNode;
    } else if (ProbedScopeCount == BestScopeCount) {
      // The probed node has the same number of scope levels in
      // common as the last best match.
      if (ProbedScopeCount == 0) {
        // There was not best match previously. Set it.
        BestNameSpaceRefNode = ProbedNameSpaceRefNode;
      } else {
        // (ProbedScopeCount != 0)
        // If there is an equivalent candidate, the best has the shortest
        // absolute path. Indeed, a similar ProbedScopeCount and a longer
        // path means the definition is out of the scope.
        // E.g.: For the method invocation \AAAA.BBBB.MET0, if there are 2
        //       pathnames ending with MET0:
        //        - \AAAA.MET0 has 1 NameSegs in common with \AAAA.BBBB.MET0
        //          from the root (this is "AAAA");
        //        - \AAAA.CCCC.MET0 has 1 NameSegs in common with
        //          \AAAA.BBBB.MET0 from the root (this is "AAAA");
        //       As \AAAA.CCCC.MET0 is longer than \AAAA.MET0, it means that
        //       the pathname could have matched on more NameSegs, but it
        //       didn't because it is out of scope.
        //       Thus, the best match is \AAAA.MET0.
        if (AmlStreamGetIndex (&ProbedRawAbsoluteFStream) <
              BestNameSpaceRefNode->RawAbsolutePathSize) {
          BestScopeCount = ProbedScopeCount;
          BestNameSpaceRefNode = ProbedNameSpaceRefNode;
        } else if (AmlStreamGetIndex (&ProbedRawAbsoluteFStream) ==
                     BestNameSpaceRefNode->RawAbsolutePathSize) {
          ASSERT (0);
          return EFI_INVALID_PARAMETER;
        }
      }
    }

    NextLink = NextLink->ForwardLink;
  }

  DEBUG ((DEBUG_VERBOSE, "\n"));

  // Check whether the BestNameSpaceRefNode is a method definition.
  if (BestNameSpaceRefNode != NULL) {
    if (AmlIsMethodDefinitionNode (BestNameSpaceRefNode->NodeRef)) {
      *OutNameSpaceRefNode = BestNameSpaceRefNode;
    } else if (AmlNodeCompareOpCode (
                 BestNameSpaceRefNode->NodeRef,
                 AML_ALIAS_OP, 0)) {
      // The path matches an alias. Resolve the alias and check whether
      // this is a method defintion.
      Status = AmlResolveAliasMethod (
                 BestNameSpaceRefNode->NodeRef,
                 NameSpaceRefList,
                 OutNameSpaceRefNode
                 );
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }
    }
  } else {
    // If no, return NULL, even if a matching pathname has been found.
    *OutNameSpaceRefNode = NULL;
  }

  return EFI_SUCCESS;
}

/** Check whether a pathname is a method invocation.

  If there is a matching method definition, returns the corresponding
  NameSpaceRef node.

  To do so, the NameSpaceRefList is keeping track of every namespace node
  and its raw AML absolute path.
  To check whether a pathname is a method invocation, a corresponding raw
  absolute pathname is built. This raw absolute pathname is then compared
  to the list of available pathnames. If a pathname defining a method
  matches the scope of the input pathname, return.

  @param  [in]  ParentNode          Parent node. Node to which the node to be
                                    created will be attached.
  @param  [in]  FStream             Forward stream pointing to the NameString
                                    to find.
  @param  [in]  NameSpaceRefList    List of NameSpaceRef nodes.
  @param  [out] OutNameSpaceRefNode If the NameString pointed by FStream is
                                    a method invocation, OutNameSpaceRefNode
                                    contains the NameSpaceRef corresponding
                                    to the method definition.
                                    NULL otherwise.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlIsMethodInvocation (
  IN  CONST AML_NODE_HEADER     * ParentNode,
  IN  CONST AML_STREAM          * FStream,
  IN  CONST LIST_ENTRY          * NameSpaceRefList,
  OUT AML_NAMESPACE_REF_NODE   ** OutNameSpaceRefNode
  )
{
  EFI_STATUS                Status;

  AML_STREAM                RawPathNameBStream;
  AML_STREAM                RawAbsolutePathFStream;

  AML_STREAM                RawAbsolutePathBStream;
  UINT8                   * RawAbsolutePathBuffer;
  UINT32                    RawAbsolutePathBufferSize;

  AML_NAMESPACE_REF_NODE  * NameSpaceRefNode;

  if ((!IS_AML_OBJECT_NODE (ParentNode) &&
       !IS_AML_ROOT_NODE (ParentNode))  ||
      !IS_STREAM (FStream)              ||
      IS_END_OF_STREAM (FStream)        ||
      !IS_STREAM_FORWARD (FStream)      ||
      (NameSpaceRefList == NULL)        ||
      (OutNameSpaceRefNode == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // There cannot be a method invocation in a field list. Return.
  if (AmlNodeHasAttribute (
        (CONST AML_OBJECT_NODE*)ParentNode,
        AML_HAS_FIELD_LIST)) {
    *OutNameSpaceRefNode = NULL;
    return EFI_SUCCESS;
  }

  // Allocate memory for the raw absolute path.
  RawAbsolutePathBufferSize = MAX_AML_NAMESTRING_SIZE;
  RawAbsolutePathBuffer = AllocateZeroPool (RawAbsolutePathBufferSize);
  if (RawAbsolutePathBuffer == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  // Initialize a backward stream to get the raw absolute path.
  Status = AmlStreamInit (
             &RawAbsolutePathBStream,
             RawAbsolutePathBuffer,
             RawAbsolutePathBufferSize,
             EAmlStreamDirectionBackward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // Build the raw AML absolute path of the namespace node.
  Status = AmlBuildRawMethodAbsolutePath (
             ParentNode,
             FStream,
             &RawAbsolutePathBStream
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // If this is the root path: it cannot be a method invocation. Just return.
  if (AmlStreamGetIndex (&RawAbsolutePathBStream) == 0) {
    DEBUG ((
      DEBUG_VERBOSE,
      "AmlMethodParser: "
      "Root node cannot be a method invocation\n"
      ));
    *OutNameSpaceRefNode = NULL;
    Status = EFI_SUCCESS;
    goto exit_handler;
  }

  // Create a forward stream for the raw absolute path.
  // This forward stream only contains the raw absolute path with
  // no extra free space.
  Status = AmlStreamInit (
             &RawAbsolutePathFStream,
             AmlStreamGetCurrPos (&RawAbsolutePathBStream),
             AmlStreamGetIndex (&RawAbsolutePathBStream),
             EAmlStreamDirectionForward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // Create a backward stream for the node name.
  Status = AmlInitRawPathBStream (
             FStream,
             &RawPathNameBStream
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // Go through the NameSpaceRefList elements to check for
  // a corresponding method definition.
  NameSpaceRefNode = NULL;
  Status = AmlFindMethodDefinition (
             &RawAbsolutePathFStream,
             &RawPathNameBStream,
             NameSpaceRefList,
             &NameSpaceRefNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

#if !defined(MDEPKG_NDEBUG)
  // Print whether a method definition has been found.
  if (NameSpaceRefNode != NULL) {
    DEBUG ((
      DEBUG_VERBOSE,
      "AmlMethodParser: Corresponding method definition: "
      ));
    AMLDBG_PRINT_CHARS (
      DEBUG_VERBOSE,
      NameSpaceRefNode->RawAbsolutePath,
      NameSpaceRefNode->RawAbsolutePathSize
      );
    DEBUG ((DEBUG_VERBOSE, ".\n"));

  } else {
    DEBUG ((DEBUG_VERBOSE, "AmlMethodParser: No method definition found.\n"));
  }
#endif // MDEPKG_NDEBUG

  *OutNameSpaceRefNode = NameSpaceRefNode;

exit_handler:
  // Free allocated memory.
  FreePool (RawAbsolutePathBuffer);
  return Status;
}

/** Create a namespace reference node and add it to the NameSpaceRefList.

  When a namespace node is encountered, the namespace it defines must be
  associated to the node. This allow to keep track of the nature of each
  name present in the AML namespace.

  In the end, this allows to recognize method invocations and parse the right
  number of arguments after the method name.

  @param [in]       Node              Namespace node.
  @param [in, out]  NameSpaceRefList  List of namespace reference nodes.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
EFI_STATUS
EFIAPI
AmlAddNameSpaceReference (
  IN      CONST AML_OBJECT_NODE   * Node,
  IN  OUT       LIST_ENTRY        * NameSpaceRefList
  )
{
  EFI_STATUS                Status;
  AML_NAMESPACE_REF_NODE  * NameSpaceRefNode;

  AML_STREAM                NodeNameFStream;
  EAML_PARSE_INDEX          NameIndex;
  CONST AML_DATA_NODE     * NameNode;

  AML_STREAM                RawAbsolutePathBStream;
  UINT32                    RawAbsolutePathBStreamSize;

  CHAR8                   * AbsolutePathBuffer;
  UINT32                    AbsolutePathBufferSize;

  CONST AML_NODE_HEADER   * ParentNode;

  if (!AmlNodeHasAttribute (Node, AML_IN_NAMESPACE)   ||
      (NameSpaceRefList == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Allocate a buffer to get the raw AML absolute pathname of the
  // namespace node.
  AbsolutePathBufferSize = MAX_AML_NAMESTRING_SIZE;
  AbsolutePathBuffer = AllocateZeroPool (AbsolutePathBufferSize);
  if (AbsolutePathBuffer == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = AmlStreamInit (
             &RawAbsolutePathBStream,
             (UINT8*)AbsolutePathBuffer,
             AbsolutePathBufferSize,
             EAmlStreamDirectionBackward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto exit_handler;
  }

  // Get the index where the name of the Node is stored in its
  // fixed list of arguments.
  Status = AmlNodeGetNameIndex (Node, &NameIndex);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto exit_handler;
  }

  // Get the Node name.
  NameNode = (CONST AML_DATA_NODE*)AmlGetFixedArgument (
                                     (AML_OBJECT_NODE*)Node,
                                     NameIndex
                                     );
  if (!IS_AML_DATA_NODE (NameNode)    ||
      (NameNode->DataType != EAmlNodeDataTypeNameString)) {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto exit_handler;
  }

  // Initialize a stream on the node name of the namespace node.
  // This is an AML NameString.
  Status = AmlStreamInit (
             &NodeNameFStream,
             NameNode->Buffer,
             NameNode->Size,
             EAmlStreamDirectionForward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto exit_handler;
  }

  ParentNode = AmlGetParent ((AML_NODE_HEADER*)Node);
  if (ParentNode == NULL) {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto exit_handler;
  }

  // Build the raw AML absolute path of the namespace node.
  Status = AmlBuildRawMethodAbsolutePath (
             ParentNode,
             &NodeNameFStream,
             &RawAbsolutePathBStream
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  RawAbsolutePathBStreamSize = AmlStreamGetIndex (&RawAbsolutePathBStream);
  // This is the root path: this cannot be a method invocation.
  if (RawAbsolutePathBStreamSize == 0) {
    Status = EFI_SUCCESS;
    goto exit_handler;
  }

  // Create a NameSpace reference node.
  Status = AmlCreateMethodRefNode (
             Node,
             (CONST CHAR8*)AmlStreamGetCurrPos (&RawAbsolutePathBStream),
             RawAbsolutePathBStreamSize,
             &NameSpaceRefNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // Add the created NameSpaceRefNode to the list.
  InsertTailList (NameSpaceRefList, &NameSpaceRefNode->Link);

  DEBUG ((
    DEBUG_VERBOSE,
    "AmlMethodParser: Adding namespace reference with name:\n"
    ));
  AMLDBG_PRINT_CHARS (
    DEBUG_VERBOSE,
    (CONST CHAR8*)AmlStreamGetCurrPos (&RawAbsolutePathBStream),
    AmlStreamGetIndex (&RawAbsolutePathBStream)
    );
  DEBUG ((DEBUG_VERBOSE, "\n"));

exit_handler:
  // Free allocated memory.
  FreePool (AbsolutePathBuffer);

  return Status;
}

/** Create a method invocation node.

  The AML grammar does not attribute an OpCode/SubOpCode couple for
  method invocations. This library is representing method invocations
  as if they had one.

  The AML encoding for method invocations in the ACPI specification 6.3 is:
    MethodInvocation := NameString TermArgList
  In this library, it is:
    MethodInvocation := MethodInvocationOp NameString ArgumentCount TermArgList
    ArgumentCount    := ByteData

  When computing the size of a tree or serializing it, the additional data is
  not taken into account (i.e. the MethodInvocationOp and the ArgumentCount).

  Method invocation nodes have the AML_METHOD_INVOVATION attribute.

  @param  [in]  NameSpaceRefNode          NameSpaceRef node pointing to the
                                          the definition of the invoked
                                          method.
  @param  [in]  MethodInvocationName      Data node containing the method
                                          invocation name.
  @param  [out] MethodInvocationNodePtr   Created method invocation node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate memory.
**/
EFI_STATUS
EFIAPI
AmlCreateMethodInvocationNode (
  IN  CONST AML_NAMESPACE_REF_NODE   * NameSpaceRefNode,
  IN        AML_DATA_NODE            * MethodInvocationName,
  OUT       AML_OBJECT_NODE         ** MethodInvocationNodePtr
  )
{
  EFI_STATUS            Status;

  UINT8                 ArgCount;
  AML_DATA_NODE       * ArgCountNode;
  AML_NODE_HEADER    ** FixedArgs;
  AML_OBJECT_NODE     * MethodDefinitionNode;
  AML_OBJECT_NODE     * MethodInvocationNode;

  if ((NameSpaceRefNode == NULL)                                      ||
      !AmlIsMethodDefinitionNode (NameSpaceRefNode->NodeRef)          ||
      !IS_AML_DATA_NODE (MethodInvocationName)                        ||
      (MethodInvocationName->DataType != EAmlNodeDataTypeNameString)  ||
      (MethodInvocationNodePtr == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Get the number of arguments of the method.
  MethodDefinitionNode = (AML_OBJECT_NODE*)NameSpaceRefNode->NodeRef;
  FixedArgs = MethodDefinitionNode->FixedArgs;
  // The method definition is an actual method definition.
  if (AmlNodeCompareOpCode (MethodDefinitionNode, AML_METHOD_OP, 0)) {
    // Cf ACPI 6.3 specification:
    //  DefMethod := MethodOp PkgLength NameString MethodFlags TermList
    //  MethodOp := 0x14
    //  MethodFlags := ByteData  bit 0-2: ArgCount (0-7)
    //                           bit 3: SerializeFlag
    //                                    0 NotSerialized
    //                                    1 Serialized
    //                           bit 4-7: SyncLevel (0x00-0x0f)

    // Read the MethodFlags to decode the ArgCount.
    ArgCountNode = (AML_DATA_NODE*)FixedArgs[EAmlParseIndexTerm1];
    ArgCount = *((UINT8*)ArgCountNode->Buffer) & 0x7;
  } else if (AmlNodeCompareOpCode (MethodDefinitionNode, AML_EXTERNAL_OP, 0)) {
    // The method definition is an external statement.
    // Cf ACPI 6.3 specification:
    //  DefExternal := ExternalOp NameString ObjectType ArgumentCount
    //  ExternalOp := 0x15
    //  ObjectType := ByteData
    //  ArgumentCount := ByteData (0 - 7)

    // Read the ArgumentCount.
    ArgCountNode = (AML_DATA_NODE*)FixedArgs[EAmlParseIndexTerm2];
    ArgCount = *((UINT8*)ArgCountNode->Buffer);
  } else {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Create the object node for the method invocation.
  // MethodInvocation := MethodInvocationOp NameString ArgumentCount
  // MethodInvocationOp := Pseudo Opcode for Method Invocation
  // NameString := Method Name
  // ArgumentCount := ByteData (0 - 7)
  Status = AmlCreateObjectNode (
             AmlGetByteEncodingByOpCode (AML_METHOD_INVOC_OP, 0),
             0,
             &MethodInvocationNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  // The first fixed argument is the method name.
  Status = AmlSetFixedArgument (
             MethodInvocationNode,
             EAmlParseIndexTerm0,
             (AML_NODE_HEADER*)MethodInvocationName
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // Create a data node holding the number of arguments
  // of the method invocation.
  ArgCountNode = NULL;
  Status = AmlCreateDataNode (
             EAmlNodeDataTypeUInt,
             &ArgCount,
             sizeof (UINT8),
             &ArgCountNode
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  // The second fixed argument is the number of arguments.
  Status = AmlSetFixedArgument (
              MethodInvocationNode,
              EAmlParseIndexTerm1,
              (AML_NODE_HEADER*)ArgCountNode
              );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto error_handler;
  }

  *MethodInvocationNodePtr = MethodInvocationNode;
  return Status;

error_handler:
  // Delete the sub-tree: the method invocation name is already attached.
  AmlDeleteTree ((AML_NODE_HEADER*)MethodInvocationNode);
  if (ArgCountNode != NULL) {
    AmlDeleteNode ((AML_NODE_HEADER*)ArgCountNode);
  }

  return Status;
}

/** Get the number of arguments of a method invocation node.

  This function also allow to identify whether a node is a method invocation
  node. If the input node is not a method invocation node, just return.

  @param  [in]  MethodInvocationNode  Method invocation node.
  @param  [out] IsMethodInvocation    Boolean stating whether the input
                                      node is a method invocation.
  @param  [out] ArgCount              Number of arguments of the method
                                      invocation.
                                      Set to 0 if MethodInvocationNode
                                      is not a method invocation.

  @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
AmlGetMethodInvocationArgCount (
  IN  CONST AML_OBJECT_NODE   * MethodInvocationNode,
  OUT       BOOLEAN           * IsMethodInvocation,
  OUT       UINT8             * ArgCount
  )
{
  AML_DATA_NODE   * NumArgsNode;

  if (!IS_AML_NODE_VALID (MethodInvocationNode) ||
      (IsMethodInvocation == NULL)              ||
      (ArgCount == NULL)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Check whether MethodInvocationNode is a method invocation.
  if (!AmlNodeCompareOpCode (MethodInvocationNode, AML_METHOD_INVOC_OP, 0)) {
    *IsMethodInvocation = FALSE;
    *ArgCount = 0;
    return EFI_SUCCESS;
  }

  // MethodInvocation := MethodInvocationOp NameString ArgumentCount
  // MethodInvocationOp := Pseudo Opcode for Method Invocation
  // NameString := Method Name
  // ArgumentCount := ByteData (0 - 7)
  NumArgsNode = (AML_DATA_NODE*)AmlGetFixedArgument (
                                  (AML_OBJECT_NODE*)MethodInvocationNode,
                                  EAmlParseIndexTerm1
                                  );
  if (!IS_AML_NODE_VALID (NumArgsNode)                ||
      (NumArgsNode->Buffer == NULL)                   ||
      (NumArgsNode->DataType != EAmlNodeDataTypeUInt) ||
      (NumArgsNode->Size != 1)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }
  *ArgCount = *NumArgsNode->Buffer;

  *IsMethodInvocation = TRUE;
  return EFI_SUCCESS;
}
