/** @file
  AML NameSpace.

  Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

/* Lexicon:

  NameSeg:
  - An ASL NameSeg is a name made of at most 4 chars.
    Cf. ACPI 6.3 specification, s19.2.2 'Name and Pathname Terms'.
  - An AML NameSeg is a name made of 4 chars.
    Cf. ACPI 6.3 specification, s20.2.2 'Name Objects Encoding'.

  NameString:
  A NameString is analogous to a pathname. It is made of 0 to 255 NameSegs.
  A NameString can be prefixed by a root char ('\') or 0 to 255 carets ('^').

  A NameString can be ASL or AML encoded.
  AML NameStrings can have a NameString prefix (dual or multi-name prefix)
  between the root/carets and the list of NameSegs. If the prefix is the
  multi-name prefix, then the number of NameSegs is encoded on one single byte.
  Cf. ACPI 6.3 specification, s19.2.2 'Name and Pathname Terms'.
  Cf. ACPI 6.3 specification, s20.2.2 'Name Objects Encoding'.

  Namespace level:
  One level in the AML Namespace level corresponds to one NameSeg. In ASL,
  objects names are NameStrings. This means a device can have a name which
  spans multiple levels.
  E.g.: The ASL code: Device (CLU0.CPU0) corresponds to 2 levels.

  Namespace node:
  A namespace node is an object node which has an associated name, and which
  changes the current scope.
  E.g.:
    1. The "Device ()" ASL statement adds a name to the AML namespace and
       changes the current scope to the device scope, this is a namespace node.
    2. The "Scope ()" ASL statement changes the current scope, this is a
       namespace node.
    3. A method invocation has a name, but does not add nor change the current
       AML scope. This is not a namespace node.

  - Object nodes with the AML_IN_NAMESPACE attribute are namespace nodes.
    Buffers (), Packages (), etc. are not part of the namespace. It is however
    possible to associate them with a name with the Name () ASL statement.
  - The root node is considered as being part of the namespace.
  - Some resource data elements can have a name when defining them in
    an ASL statement. However, this name is stripped by the ASL compiler.
    Thus, they don't have a name in the AML bytestream, and are therefore
    not part of the AML namespace.
  - Field list elements are part of the namespace.
    Fields created by an CreateXXXField () ASL statement are part of the
    namespace. The name of these node can be found in the third or fourth
    fixed argument. The exact index of the name can be found in the NameIndex
    field of the AML_BYTE_ENCODING array.
    Field are at the same level as their ASL statement in the namespace.
    E.g:
    Scope (\) {
      OperationRegion (REG0, SystemIO, 0x100, 0x100)
      Field (REG0, ByteAcc, NoLock, Preserve) {
        FIE0, 1,
        FIE1, 5
      }

      Name (BUF0, Buffer (100) {})
      CreateField (BUF0, 5, 2, MEM0)
    }

    produces this namespace:
    \ (Root)
    \-REG0
    \-FIE0
    \-FIE1
    \-BUF0
    \-MEM0

  Raw AML pathname or Raw AML NameString:
  In order to easily manipulate AML NameStrings, the non-NameSegs chars are
  removed in raw pathnames/NameStrings. Non-NameSegs chars are the
  root char ('\'), carets ('^') and NameString prefixes (Dual/Multi name char).
  E.g. The following terminology is defined in this AML Library.
  ASL absolute path:  "[RootChar]AAAA.BBBB.CCCC\0"
  AML absolute path:  "[RootChar][MultiNamePrefix][3(NameSegs)]AAAABBBBCCCC"
  Raw absolute path:  "AAAABBBBCCCC"

  Multi-name:
  A NameString with at least 2 NameSegs. A node can have a name which spans
  multiple namespace levels.
*/

#include <NameSpace/AmlNameSpace.h>

#include <AmlCoreInterface.h>
#include <AmlDbgPrint/AmlDbgPrint.h>
#include <String/AmlString.h>
#include <Tree/AmlNode.h>
#include <Tree/AmlTree.h>
#include <Tree/AmlTreeTraversal.h>

/** Context of the path search callback function.

  The function finding a node from a path and a reference node enumerates
  the namespace nodes in the tree and compares their absolute path with the
  searched path. The enumeration function uses a callback function that can
  receive a context.
  This structure is used to store the context information required in the
  callback function.
*/
typedef struct AmlPathSearchContext {
  /// Backward stream holding the raw AML absolute searched path.
  AML_STREAM         *SearchPathBStream;

  /// An empty backward stream holding a pre-allocated buffer. This prevents
  /// from having to do multiple allocations during the search.
  /// This stream is used to query the raw AML absolute path of the node
  /// currently being probed.
  AML_STREAM         *CurrNodePathBStream;

  /// If the node being visited is the node being searched,
  /// i.e. its path and the searched path match,
  /// save its reference in this pointer.
  AML_NODE_HEADER    *OutNode;
} AML_PATH_SEARCH_CONTEXT;

/** Return the first AML namespace node up in the parent hierarchy.

    Return the root node if no namespace node is found is the hierarchy.

  @param  [in]  Node      Node to look at the parents from.
                          If Node is the root node, OutNode is NULL.
  @param  [out] OutNode   If a namespace node is found, pointer to the
                          first namespace node of Node's parents.
                          Stop at the root node otherwise.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  **/
EFI_STATUS
EFIAPI
AmlGetFirstAncestorNameSpaceNode (
  IN  CONST AML_NODE_HEADER  *Node,
  OUT       AML_NODE_HEADER  **OutNode
  )
{
  if (!IS_AML_NODE_VALID (Node) ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // If Node is the root node, return NULL.
  if (IS_AML_ROOT_NODE (Node)) {
    *OutNode = NULL;
    return EFI_SUCCESS;
  } else {
    // Else, get the parent node.
    Node = AmlGetParent ((AML_NODE_HEADER *)Node);
    if (!IS_AML_NODE_VALID (Node)) {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }
  }

  // Continue getting the parent node while no namespace node is encountered.
  while (TRUE) {
    if (IS_AML_ROOT_NODE (Node)) {
      break;
    } else if (AmlNodeHasAttribute (
                 (CONST AML_OBJECT_NODE *)Node,
                 AML_IN_NAMESPACE
                 ))
    {
      break;
    } else {
      Node = AmlGetParent ((AML_NODE_HEADER *)Node);
      if (!IS_AML_NODE_VALID (Node)) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }
    }
  } // while

  *OutNode = (AML_NODE_HEADER *)Node;
  return EFI_SUCCESS;
}

/** Climb up the AML namespace hierarchy.

  This function get the ancestor namespace node in the AML namespace.
  If Levels is not zero, skip Levels namespace nodes in the AML namespace.
  If Levels is zero, return the first ancestor namespace node.
    I.e. if Levels = n, this function returns the (n + 1) ancestor.

  @param  [in] Node         Pointer to an object node.
  @param  [in, out] Levels  Pointer holding a number of AML namespace levels:
                             - At entry, the number of levels to go up in
                               the AML namespace;
                             - At exit, the number of levels that still need
                               to be climbed in case of a multi-named node.
                               Indeed, if a node with a multi-name is found,
                               and Levels is less than the number of NameSegs
                               in this name, then the function returns with
                               the number of levels that still need to be
                               climbed.
                               E.g.: If the first ancestor node's name is
                                     "AAAA.BBBB.CCCC" and
                                     Levels = 2  -> i.e go up 3 levels
                                      \
                                      ...
                                      \-"AAAA.BBBB.CCCC"    <----- OutNode
                                         \-"DDDD"           <----- Node (Input)

                                     The function should ideally return a node
                                     with the name "AAAA". However, it is not
                                     possible to split the node name
                                     "AAAA.BBBB.CCCC" to "AAAA".
                                     Thus, OutNode is set to the input node,
                                     and Levels = 2.
                               In most cases the number of levels to climb
                               correspond to non multi-name node, and therefore
                               Levels = 0 at exit.
  @param  [out] HasRoot     The returned node in OutNode has an AML absolute
                            name, starting with a root char ('\'), or if OutNode
                            is the root node.
  @param  [out] OutNode     The Levels+1 namespace ancestor of the input node in
                            the AML namespace. Must be the root node or a
                            namespace node.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlGetAncestorNameSpaceNode (
  IN      CONST AML_OBJECT_NODE  *Node,
  IN OUT        UINT32           *Levels,
  OUT        UINT32              *HasRoot,
  OUT  CONST AML_NODE_HEADER     **OutNode
  )
{
  EFI_STATUS  Status;

  CONST AML_NODE_HEADER  *NameSpaceNode;
  CHAR8                  *NodeName;
  UINT32                 ParentCnt;

  UINT32  Root;
  UINT32  ParentPrefix;
  UINT32  SegCount;

  if (!IS_AML_OBJECT_NODE (Node)    ||
      (Levels == NULL)              ||
      (HasRoot == NULL)             ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  ParentCnt = *Levels;
  *HasRoot  = 0;

  // ParentCnt namespace levels need to be climbed.
  do {
    // Get the next namespace node in the hierarchy.
    Status = AmlGetFirstAncestorNameSpaceNode (
               (CONST AML_NODE_HEADER *)Node,
               (AML_NODE_HEADER **)&NameSpaceNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    Node = (CONST AML_OBJECT_NODE *)NameSpaceNode;

    if (IS_AML_ROOT_NODE (Node)) {
      // Node is the root node. It is not possible to go beyond.
      if (ParentCnt != 0) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      *HasRoot = 1;
      break;
    }

    NodeName = AmlNodeGetName ((CONST AML_OBJECT_NODE *)Node);
    if (NodeName == NULL) {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }

    // Analyze the node name.
    Status = AmlParseNameStringInfo (
               NodeName,
               &Root,
               &ParentPrefix,
               &SegCount
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    if (Root != 0) {
      // NodeName is an absolute pathname.
      *HasRoot = Root;

      // If the node has Root then it cannot have ParentPrefixes (Carets).
      if (ParentPrefix != 0) {
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }

      if (SegCount == ParentCnt) {
        // There are exactly enough AML namespace levels to consume.
        // This means the root node was the searched node.
        Node = (CONST AML_OBJECT_NODE *)AmlGetRootNode (
                                          (CONST AML_NODE_HEADER *)Node
                                          );
        if (!IS_AML_ROOT_NODE (Node)) {
          ASSERT (0);
          return EFI_INVALID_PARAMETER;
        }

        ParentCnt = 0;
        break;
      } else if (ParentCnt < SegCount) {
        // There are too many AML namespace levels in this name.
        // ParentCnt has the right value, just return.
        break;
      } else {
        // ParentCnt > SegCount
        // Return error as there must be at least ParentCnt AML namespace
        // levels left in the absolute path.
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
      }
    } else {
      // Root is 0.
      if (ParentCnt < SegCount) {
        // NodeName is a relative path.
        // NodeName has enough levels to consume all the ParentCnt.
        // Exit.
        break;
      } else if (SegCount == ParentCnt) {
        // There are exactly enough AML namespace levels to consume.
        if (ParentPrefix == 0) {
          // The node name doesn't have any carets. Get the next namespace
          // node and return.
          Status = AmlGetFirstAncestorNameSpaceNode (
                     (CONST AML_NODE_HEADER *)Node,
                     (AML_NODE_HEADER **)&NameSpaceNode
                     );
          if (EFI_ERROR (Status)) {
            ASSERT (0);
            return Status;
          }

          Node      = (CONST AML_OBJECT_NODE *)NameSpaceNode;
          ParentCnt = 0;
          break;
        } else {
          // The node name has carets. Need to continue climbing the
          // AML namespace.
          ParentCnt = ParentPrefix;
        }
      } else {
        // ParentCnt > SegCount
        // NodeName doesn't have enough levels to consume all the ParentCnt.
        // Update ParentCnt: Consume SegCount levels and add ParentPrefix
        // levels. Continue climbing the tree.
        ParentCnt = ParentCnt + ParentPrefix - SegCount;
      }
    }
  } while (ParentCnt != 0);

  *OutNode = (CONST AML_NODE_HEADER *)Node;
  *Levels  = ParentCnt;

  return EFI_SUCCESS;
}

/** Build the raw absolute AML pathname to Node and write it to a stream.

  A raw AML pathname is an AML pathname where the root char ('\'),
  prefix chars ('^') and NameString prefix byte (e.g.: DualNamePrefix)
  have been removed. A raw AML pathname is a list of concatenated
  NameSegs.

  E.g.:
  ASL absolute path:  "[RootChar]AAAA.BBBB.CCCC\0"
  AML absolute path:  "[RootChar][MultiNamePrefix][3(NameSegs)]AAAABBBBCCCC"
  Raw absolute path:  "AAAABBBBCCCC"

  @param  [in]   Node         Node to build the raw absolute path to
                              Must be a root node, or a namespace node.
  @param  [in]  InputParent   Skip InputParent AML namespace levels before
                              starting building the raw absolute pathname.
                              E.g.: - Node's name being "^AAAA.BBBB.CCCC";
                                    - InputParent = 2;
                                    "BBBB.CCCC" will be skipped (2
                                    levels), and "^AAAA" will remain. The
                                    first caret is not related to InputParent.
  @param  [out]  RawAbsPathBStream  Backward stream to write the raw
                                    pathname to.
                                    If Node is the root node, the Stream data
                                    Buffer will stay empty.
                                    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.
**/
EFI_STATUS
EFIAPI
AmlGetRawNameSpacePath (
  IN  CONST AML_NODE_HEADER  *Node,
  IN        UINT32           InputParent,
  OUT       AML_STREAM       *RawAbsPathBStream
  )
{
  EFI_STATUS  Status;

  AML_NODE_HEADER  *ParentNode;
  CHAR8            *NodeName;

  UINT32         Root;
  UINT32         ParentPrefix;
  UINT32         SegCount;
  CONST   CHAR8  *NameSeg;

  if ((!IS_AML_ROOT_NODE (Node)                 &&
       !AmlNodeHasAttribute (
          (CONST AML_OBJECT_NODE *)Node,
          AML_IN_NAMESPACE
          ))                     ||
      !IS_STREAM (RawAbsPathBStream)            ||
      IS_END_OF_STREAM (RawAbsPathBStream)      ||
      !IS_STREAM_BACKWARD (RawAbsPathBStream)   ||
      (InputParent > MAX_UINT8))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  while (1) {
    if (IS_AML_ROOT_NODE (Node)) {
      break;
    }

    NodeName = AmlNodeGetName ((CONST AML_OBJECT_NODE *)Node);
    if (NodeName == NULL) {
      ASSERT (0);
      return EFI_INVALID_PARAMETER;
    }

    Status = AmlParseNameStringInfo (
               NodeName,
               &Root,
               &ParentPrefix,
               &SegCount
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }

    if (SegCount > InputParent) {
      // 1.1. If the Node's name has enough levels to consume all the
      //      InputParent carets, write the levels that are left.
      NameSeg = AmlGetFirstNameSeg (NodeName, Root, ParentPrefix);
      Status  = AmlStreamWrite (
                  RawAbsPathBStream,
                  (CONST UINT8 *)NameSeg,
                  (SegCount - InputParent) * AML_NAME_SEG_SIZE
                  );
      if (EFI_ERROR (Status)) {
        ASSERT (0);
        return Status;
      }

      InputParent = 0;
    } else {
      // (SegCount <= InputParent)
      // 1.2. Else save the InputParent in TotalParent to climb
      //      them later.
      InputParent -= SegCount;
    }

    InputParent += ParentPrefix;

    if (Root != 0) {
      // 2. The Node's name is an absolute path.
      //    Exit, the root has been reached.
      if (InputParent != 0) {
        ASSERT (0);
        return EFI_NOT_FOUND;
      }

      break;
    }

    Status = AmlGetAncestorNameSpaceNode (
               (CONST AML_OBJECT_NODE *)Node,
               &InputParent,
               &Root,
               (CONST AML_NODE_HEADER **)&ParentNode
               );
    if (EFI_ERROR (Status)  ||
        (!IS_AML_NODE_VALID (ParentNode)))
    {
      ASSERT (0);
      return Status;
    }

    Node = ParentNode;

    if (IS_AML_ROOT_NODE (Node)) {
      // 3.1. If the root node has been found while climbing,
      //      no need to write NameSegs.
      //      Exit.
      break;
    } else if (Root != 0) {
      // 3.2. An absolute path has been found while climbing the tree.
      //      If (InputParent != 0), the raw pathname is not the root.
      //      Write the first [SegCount - InputParent] NameSegs of this
      //      absolute path.
      //      Then exit.
      if (InputParent != 0) {
        // Get the absolute pathname.
        NodeName = AmlNodeGetName ((CONST AML_OBJECT_NODE *)Node);
        if (NodeName == NULL) {
          ASSERT (0);
          return EFI_INVALID_PARAMETER;
        }

        // Analyze the absolute pathname.
        Status = AmlParseNameStringInfo (
                   NodeName,
                   &Root,
                   &ParentPrefix,
                   &SegCount
                   );
        if (EFI_ERROR (Status)) {
          ASSERT (0);
          return Status;
        }

        // Writing the n first NameSegs.
        // n = SegCount - InputParent
        NameSeg = AmlGetFirstNameSeg (NodeName, Root, ParentPrefix);
        Status  = AmlStreamWrite (
                    RawAbsPathBStream,
                    (CONST UINT8 *)NameSeg,
                    (SegCount - InputParent) * AML_NAME_SEG_SIZE
                    );
        if (EFI_ERROR (Status)) {
          ASSERT (0);
          return Status;
        }

        break;
      } // (InputParent != 0)
    }
  } // while

  return EFI_SUCCESS;
}

/** Add the RootChar and prefix byte to the raw AML NameString in the
    input Stream to create a valid absolute path.

  The prefix byte can be AML_DUAL_NAME_PREFIX, AML_MULTI_NAME_PREFIX
  or nothing.

  @param  [in, out] AmlPathBStream  The Stream initially contains a raw
                                    NameString (i.e. a list of NameSegs).
                                    The Stream can be empty (e.g.: for the
                                    root path).
                                    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
AmlAddPrefix (
  IN  OUT AML_STREAM  *AmlPathBStream
  )
{
  EFI_STATUS  Status;
  UINT32      NameSegCount;
  UINT32      NameSegSize;

  // At most 3 bytes are needed for: RootChar + MultiNamePrefix + SegCount.
  CHAR8   Prefix[3];
  UINT32  PrefixSize;

  // The Stream contains concatenated NameSegs.
  if (!IS_STREAM (AmlPathBStream)       ||
      IS_END_OF_STREAM (AmlPathBStream) ||
      !IS_STREAM_BACKWARD (AmlPathBStream))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Its size should be a multiple of AML_NAME_SEG_SIZE.
  // AML_NAME_SEG_SIZE = 4. Check the 2 lowest bits.
  NameSegSize = AmlStreamGetIndex (AmlPathBStream);
  if ((NameSegSize & (AML_NAME_SEG_SIZE - 1)) != 0) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Each NameSeg is 4 bytes so divide the NameSegSize by 4.
  NameSegCount = NameSegSize >> 2;
  if (NameSegCount > MAX_UINT8) {
    // There can be at most 255 NameSegs.
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Prefix[0] = AML_ROOT_CHAR;

  switch (NameSegCount) {
    case 0:
    {
      // Root and parents only NameString (no NameSeg(s)) end with '\0'.
      Prefix[1]  = AML_ZERO_OP;
      PrefixSize = 2;
      break;
    }
    case 1:
    {
      PrefixSize = 1;
      break;
    }
    case 2:
    {
      Prefix[1]  = AML_DUAL_NAME_PREFIX;
      PrefixSize = 2;
      break;
    }
    default:
    {
      Prefix[1]  = AML_MULTI_NAME_PREFIX;
      Prefix[2]  = (UINT8)NameSegCount;
      PrefixSize = 3;
      break;
    }
  }

  // Add the RootChar + prefix (if needed) at the beginning of the pathname.
  Status = AmlStreamWrite (AmlPathBStream, (CONST UINT8 *)Prefix, PrefixSize);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  return Status;
}

/** Remove the prefix bytes of an AML NameString stored in a backward stream
    to get a raw NameString.

  The AML encoding for '\', '^', Dual name or multi-name prefix are
  stripped off.
  E.g: If the ASL path was "\AAAA.BBBB", the AML equivalent would be
       "{RootChar}{DualNamePrefix}AAAABBBB". So resultant raw NameString
       is "AAAABBBB".

  @param  [in, out] AmlPathBStream    Backward stream containing an AML
                                      NameString.
                                      The stream must not be at its end.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
AmlRemovePrefix (
  IN  OUT AML_STREAM  *AmlPathBStream
  )
{
  EFI_STATUS  Status;

  UINT32  TotalSize;
  UINT32  RewindSize;

  UINT32  Root;
  UINT32  ParentPrefix;
  UINT32  SegCount;

  if (!IS_STREAM (AmlPathBStream)         ||
      IS_END_OF_STREAM (AmlPathBStream)   ||
      !IS_STREAM_BACKWARD (AmlPathBStream))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  Status = AmlParseNameStringInfo (
             (CHAR8 *)AmlStreamGetCurrPos (AmlPathBStream),
             &Root,
             &ParentPrefix,
             &SegCount
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  TotalSize = AmlComputeNameStringSize (Root, ParentPrefix, SegCount);
  if (TotalSize == 0) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // Rewind the stream of all the bytes that are not SegCounts
  // to drop the prefix.
  RewindSize = TotalSize - (SegCount * AML_NAME_SEG_SIZE);
  if (RewindSize != 0) {
    Status = AmlStreamRewind (AmlPathBStream, RewindSize);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/** Build the absolute ASL pathname to Node.

  BufferSize is always updated to the size of the pathname.

  If:
   - the content of BufferSize is >= to the size of the pathname AND;
   - Buffer is not NULL.
  then copy the pathname in the Buffer. A buffer of the size
  MAX_ASL_NAMESTRING_SIZE is big enough to receive any ASL pathname.

  @param  [in]      Node            Node to build the absolute path to.
                                    Must be a root node, or a namespace node.
  @param  [out]     Buffer          Buffer to write the path to.
                                    If NULL, only update *BufferSize.
  @param  [in, out] BufferSize      Pointer holding:
                                    - At entry, the size of the Buffer;
                                    - At exit, the size of the pathname.

  @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    Out of memory.
**/
EFI_STATUS
EFIAPI
AmlGetAslPathName (
  IN      AML_NODE_HEADER  *Node,
  OUT CHAR8                *Buffer,
  IN  OUT UINT32           *BufferSize
  )
{
  EFI_STATUS  Status;

  // Backward stream used to build the raw AML absolute path to the node.
  AML_STREAM  RawAmlAbsPathBStream;
  CHAR8       *RawAmlAbsPathBuffer;
  UINT32      RawAmlAbsPathBufferSize;

  CHAR8   *AmlPathName;
  CHAR8   *AslPathName;
  UINT32  AslPathNameSize;

  UINT32  Root;
  UINT32  ParentPrefix;
  UINT32  SegCount;

  if ((!IS_AML_ROOT_NODE (Node)         &&
       !AmlNodeHasAttribute (
          (CONST AML_OBJECT_NODE *)Node,
          AML_IN_NAMESPACE
          ))             ||
      (BufferSize == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  AslPathName = NULL;

  // Allocate a Stream to get the raw AML absolute pathname.
  RawAmlAbsPathBufferSize = MAX_AML_NAMESTRING_SIZE;
  RawAmlAbsPathBuffer     = AllocateZeroPool (RawAmlAbsPathBufferSize);
  if (RawAmlAbsPathBuffer == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = AmlStreamInit (
             &RawAmlAbsPathBStream,
             (UINT8 *)RawAmlAbsPathBuffer,
             RawAmlAbsPathBufferSize,
             EAmlStreamDirectionBackward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // Get the raw pathname of the Node. The raw pathname being an
  // AML NameString without the RootChar and prefix byte.
  // It is a list of concatenated NameSegs.
  Status = AmlGetRawNameSpacePath (Node, 0, &RawAmlAbsPathBStream);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // Add the RootChar and prefix byte.
  Status = AmlAddPrefix (&RawAmlAbsPathBStream);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  AmlPathName = (CHAR8 *)AmlStreamGetCurrPos (&RawAmlAbsPathBStream);

  // Analyze the NameString.
  Status = AmlParseNameStringInfo (
             (CONST CHAR8 *)AmlPathName,
             &Root,
             &ParentPrefix,
             &SegCount
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // Compute the size the ASL pathname will take.
  AslPathNameSize = AslComputeNameStringSize (Root, ParentPrefix, SegCount);
  if (AslPathNameSize == 0) {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto exit_handler;
  }

  // Input Buffer is large enough. Copy the pathname if the Buffer is valid.
  if ((Buffer != NULL) && (AslPathNameSize <= *BufferSize)) {
    Status = ConvertAmlNameToAslName (AmlPathName, &AslPathName);
    if (EFI_ERROR (Status)) {
      ASSERT (0);
      Status = EFI_OUT_OF_RESOURCES;
      goto exit_handler;
    }

    CopyMem (Buffer, AslPathName, AslPathNameSize);
  }

  *BufferSize = AslPathNameSize;

exit_handler:
  // Free allocated memory.
  FreePool (RawAmlAbsPathBuffer);
  if (AslPathName != NULL) {
    FreePool (AslPathName);
  }

  return Status;
}

#if !defined (MDEPKG_NDEBUG)

/** Recursively print the pathnames in the AML namespace in Node's branch.

  @param  [in]  Node          Pointer to a node.
  @param  [in]  Context       An empty forward stream holding a pre-allocated
                              buffer. This prevents from having to do multiple
                              allocations during the enumeration.
  @param  [in, out] Status    At entry, contains the status returned by the
                              last call to this exact function during the
                              enumeration.
                              As exit, contains the returned status of the
                              call to this function.
                              Optional, can be NULL.

  @retval TRUE if the enumeration can continue or has finished without
          interruption.
  @retval FALSE if the enumeration needs to stopped or has stopped.
**/
STATIC
BOOLEAN
EFIAPI
AmlDbgPrintNameSpaceCallback (
  IN      AML_NODE_HEADER  *Node,
  IN      VOID             *Context,
  IN  OUT EFI_STATUS       *Status   OPTIONAL
  )
{
  BOOLEAN     ContinueEnum;
  EFI_STATUS  Status1;

  AML_STREAM  *CurrNodePathFStream;
  CHAR8       *CurrNodePathBuffer;
  UINT32      CurrNodePathBufferSize;

  ContinueEnum = TRUE;
  Status1      = EFI_SUCCESS;

  if (!IS_AML_NODE_VALID (Node) ||
      (Context == NULL))
  {
    ASSERT (0);
    Status1      = EFI_INVALID_PARAMETER;
    ContinueEnum = FALSE;
    goto exit_handler;
  }

  if (!IS_AML_ROOT_NODE (Node)  &&
      !AmlNodeHasAttribute (
         (CONST AML_OBJECT_NODE *)Node,
         AML_IN_NAMESPACE
         ))
  {
    // Skip this node and continue enumeration.
    goto exit_handler;
  }

  if (IS_AML_ROOT_NODE (Node)) {
    DEBUG ((DEBUG_INFO, "\\\n"));
  } else if (AmlNodeHasAttribute (
               (CONST AML_OBJECT_NODE *)Node,
               AML_IN_NAMESPACE
               ))
  {
    CurrNodePathFStream = (AML_STREAM *)Context;

    // Check the Context's content.
    if (!IS_STREAM (CurrNodePathFStream)           ||
        IS_END_OF_STREAM (CurrNodePathFStream)     ||
        !IS_STREAM_FORWARD (CurrNodePathFStream))
    {
      ASSERT (0);
      Status1      = EFI_INVALID_PARAMETER;
      ContinueEnum = FALSE;
      goto exit_handler;
    }

    CurrNodePathBuffer     = (CHAR8 *)AmlStreamGetBuffer (CurrNodePathFStream);
    CurrNodePathBufferSize = AmlStreamGetMaxBufferSize (CurrNodePathFStream);

    Status1 = AmlGetAslPathName (
                (AML_NODE_HEADER *)Node,
                CurrNodePathBuffer,
                &CurrNodePathBufferSize
                );
    if (EFI_ERROR (Status1)) {
      ASSERT (0);
      ContinueEnum = FALSE;
      goto exit_handler;
    }

    DEBUG ((DEBUG_INFO, "%a\n", CurrNodePathBuffer));
  } else {
    ASSERT (0);
    Status1      = EFI_INVALID_PARAMETER;
    ContinueEnum = FALSE;
  }

exit_handler:
  if (Status != NULL) {
    *Status = Status1;
  }

  return ContinueEnum;
}

/** Print the absolute pathnames in the AML namespace of
    all the nodes in the tree starting from the Root node.

  @param  [in]  RootNode    Pointer to a root node.

  @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    Out of memory.
**/
EFI_STATUS
EFIAPI
AmlDbgPrintNameSpace (
  IN  AML_ROOT_NODE  *RootNode
  )
{
  EFI_STATUS  Status;

  AML_STREAM  CurrNodePathFStream;
  CHAR8       *CurrNodePathBuffer;
  UINT32      CurrNodePathBufferSize;

  if (!IS_AML_ROOT_NODE (RootNode)) {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((DEBUG_INFO, "AmlNameSpace: AML namespace:\n"));

  // Allocate memory to build the absolute ASL path to each node.
  CurrNodePathBufferSize = MAX_AML_NAMESTRING_SIZE;
  CurrNodePathBuffer     = AllocateZeroPool (CurrNodePathBufferSize);
  if (CurrNodePathBuffer == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  // An empty forward stream holding a pre-allocated buffer is used
  // to avoid multiple allocations during the enumeration.
  Status = AmlStreamInit (
             &CurrNodePathFStream,
             (UINT8 *)CurrNodePathBuffer,
             CurrNodePathBufferSize,
             EAmlStreamDirectionForward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  AmlEnumTree (
    (AML_NODE_HEADER *)RootNode,
    AmlDbgPrintNameSpaceCallback,
    (VOID *)&CurrNodePathFStream,
    &Status
    );
  ASSERT_EFI_ERROR (Status);

exit_handler:
  FreePool (CurrNodePathBuffer);

  return Status;
}

#endif // MDEPKG_NDEBUG

/** Callback function to find the node corresponding to an absolute pathname.

  For each namespace node, build its raw AML absolute path. Then compare this
  path with the raw AML absolute path of the search node available in the
  Context.

  @param  [in]      Node      Pointer to the node to whose pathname is being
                              tested.
  @param  [in, out] Context   A pointer to AML_PATH_SEARCH_CONTEXT that has:
                               - The searched path stored in a stream;
                               - An empty stream to query the pathname of the
                                 probed node;
                               - A node pointer to store the searched node
                                 if found.
  @param  [in, out] Status    At entry, contains the status returned by the
                              last call to this exact function during the
                              enumeration.
                              As exit, contains the returned status of the
                              call to this function.
                              Optional, can be NULL.

  @retval TRUE if the enumeration can continue or has finished without
          interruption.
  @retval FALSE if the enumeration needs to stopped or has stopped.
**/
STATIC
BOOLEAN
EFIAPI
AmlEnumeratePathCallback (
  IN      AML_NODE_HEADER  *Node,
  IN  OUT VOID             *Context,
  IN  OUT EFI_STATUS       *Status   OPTIONAL
  )
{
  BOOLEAN     ContinueEnum;
  EFI_STATUS  Status1;

  AML_PATH_SEARCH_CONTEXT  *PathSearchContext;

  AML_STREAM  *SearchPathBStream;

  AML_STREAM  *CurrNodePathBStream;
  UINT32      CurrNodePathSize;

  ContinueEnum = TRUE;
  Status1      = EFI_SUCCESS;

  if (!IS_AML_NODE_VALID (Node) ||
      (Context == NULL))
  {
    ASSERT (0);
    Status1      = EFI_INVALID_PARAMETER;
    ContinueEnum = FALSE;
    goto exit_handler;
  }

  if (!AmlNodeHasAttribute (
         (CONST AML_OBJECT_NODE *)Node,
         AML_IN_NAMESPACE
         ))
  {
    goto exit_handler;
  }

  PathSearchContext   = (AML_PATH_SEARCH_CONTEXT *)Context;
  SearchPathBStream   = PathSearchContext->SearchPathBStream;
  CurrNodePathBStream = PathSearchContext->CurrNodePathBStream;

  // Check the Context's content.
  if (!IS_STREAM (SearchPathBStream)            ||
      IS_END_OF_STREAM (SearchPathBStream)      ||
      !IS_STREAM_BACKWARD (SearchPathBStream)   ||
      !IS_STREAM (CurrNodePathBStream)          ||
      IS_END_OF_STREAM (CurrNodePathBStream)    ||
      !IS_STREAM_BACKWARD (CurrNodePathBStream))
  {
    ASSERT (0);
    Status1      = EFI_INVALID_PARAMETER;
    ContinueEnum = FALSE;
    goto exit_handler;
  }

  CurrNodePathSize = AmlStreamGetMaxBufferSize (CurrNodePathBStream);
  if (CurrNodePathSize == 0) {
    ASSERT (0);
    Status1      = EFI_INVALID_PARAMETER;
    ContinueEnum = FALSE;
    goto exit_handler;
  }

  // Get the raw AML absolute pathname of the current node.
  Status1 = AmlGetRawNameSpacePath (Node, 0, CurrNodePathBStream);
  if (EFI_ERROR (Status1)) {
    ASSERT (0);
    ContinueEnum = FALSE;
    goto exit_handler;
  }

  DEBUG ((
    DEBUG_VERBOSE,
    "AmlNameSpace: "
    "Comparing search path with current node path.\n"
    ));
  DEBUG ((DEBUG_VERBOSE, "Search path:"));
  AMLDBG_PRINT_CHARS (
    DEBUG_VERBOSE,
    (CHAR8 *)AmlStreamGetCurrPos (SearchPathBStream),
    AmlStreamGetIndex (SearchPathBStream)
    );
  DEBUG ((DEBUG_VERBOSE, "\nPath of the current node: "));
  AMLDBG_PRINT_CHARS (
    DEBUG_VERBOSE,
    (CHAR8 *)AmlStreamGetCurrPos (CurrNodePathBStream),
    AmlStreamGetIndex (CurrNodePathBStream)
    );
  DEBUG ((DEBUG_VERBOSE, "\n"));

  // Compare the searched path and Node's path.
  if ((AmlStreamGetIndex (CurrNodePathBStream)  ==
       AmlStreamGetIndex (SearchPathBStream))     &&
      (CompareMem (
         AmlStreamGetCurrPos (CurrNodePathBStream),
         AmlStreamGetCurrPos (SearchPathBStream),
         AmlStreamGetIndex (SearchPathBStream)
         ) == 0))
  {
    Status1                    = EFI_SUCCESS;
    ContinueEnum               = FALSE;
    PathSearchContext->OutNode = Node;
  } else {
    // If the paths don't match, reset the CurrNodePathStream's content.
    Status1 = AmlStreamReset (CurrNodePathBStream);
    if (EFI_ERROR (Status1)) {
      ASSERT (0);
      ContinueEnum = FALSE;
    }
  }

exit_handler:
  if (Status != NULL) {
    *Status = Status1;
  }

  return ContinueEnum;
}

/** Build a raw AML absolute path from a reference node and a relative
    ASL path.

  The AslPath can be a relative path or an absolute path.
  Node must be a root node or a namespace node.
  A root node is expected to be at the top of the tree.

  @param  [in]  ReferenceNode               Reference node.
                                            If a relative path is given, the
                                            search is done from this node. If
                                            an absolute path is given, the
                                            search is done from the root node.
                                            Must be a root node or an object
                                            node which is part of the
                                            namespace.
  @param  [in]  AslPath                     ASL path to the searched node in
                                            the namespace. An ASL path name is
                                            NULL terminated. Can be a relative
                                            or absolute path.
                                            E.g.: "\\_SB.CLU0.CPU0".
  @param  [in, out] RawAmlAbsSearchPathBStream  Backward stream to write the
                                                raw absolute AML path of the
                                                searched node.
                                                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.
  @retval EFI_OUT_OF_RESOURCES    Out of memory.
**/
STATIC
EFI_STATUS
EFIAPI
AmlBuildAbsoluteAmlPath (
  IN      AML_NODE_HEADER  *ReferenceNode,
  IN      CONST CHAR8      *AslPath,
  IN  OUT AML_STREAM       *RawAmlAbsSearchPathBStream
  )
{
  EFI_STATUS  Status;
  CHAR8       *AmlPath;

  UINT32  AmlNameStringSize;
  UINT32  Root;
  UINT32  ParentPrefix;
  UINT32  SegCount;

  if ((!IS_AML_ROOT_NODE (ReferenceNode)              &&
       !AmlNodeHasAttribute (
          (CONST AML_OBJECT_NODE *)ReferenceNode,
          AML_IN_NAMESPACE
          ))                           ||
      (AslPath == NULL)                               ||
      !IS_STREAM (RawAmlAbsSearchPathBStream)         ||
      IS_END_OF_STREAM (RawAmlAbsSearchPathBStream)   ||
      !IS_STREAM_BACKWARD (RawAmlAbsSearchPathBStream))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  // 1. Validate, analyze and convert the AslPath to an AmlPath.
  Status = ConvertAslNameToAmlName (AslPath, &AmlPath);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    return Status;
  }

  Status = AmlParseNameStringInfo (AmlPath, &Root, &ParentPrefix, &SegCount);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // Not possible to go beyond the root.
  if (IS_AML_ROOT_NODE (ReferenceNode) && (ParentPrefix != 0)) {
    Status = EFI_INVALID_PARAMETER;
    ASSERT (0);
    goto exit_handler;
  }

  AmlNameStringSize = AmlComputeNameStringSize (Root, ParentPrefix, SegCount);
  if (AmlNameStringSize == 0) {
    Status = EFI_INVALID_PARAMETER;
    ASSERT (0);
    goto exit_handler;
  }

  // 2.1. Write the AML path to the stream.
  Status = AmlStreamWrite (
             RawAmlAbsSearchPathBStream,
             (CONST UINT8 *)AmlPath,
             AmlNameStringSize
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // 2.2. Then remove the AML prefix (root char, parent prefix, etc.)
  //      to obtain a raw AML NameString. Raw AML NameString are easier
  //      to manipulate.
  Status = AmlRemovePrefix (RawAmlAbsSearchPathBStream);
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // 3. If AslPath is a relative path and the reference Node is not
  //    the root node, fill the Stream with the absolute path to the
  //    reference node.
  if ((Root == 0) && !IS_AML_ROOT_NODE (ReferenceNode)) {
    Status = AmlGetRawNameSpacePath (
               ReferenceNode,
               ParentPrefix,
               RawAmlAbsSearchPathBStream
               );
    if (EFI_ERROR (Status)) {
      ASSERT (0);
    }
  }

exit_handler:
  // Free allocated memory.
  FreePool (AmlPath);

  return Status;
}

/** Find a node in the AML namespace, given an ASL path and a reference Node.

   - The AslPath can be an absolute path, or a relative path from the
     reference Node;
   - Node must be a root node or a namespace node;
   - A root node is expected to be at the top of the tree.

  E.g.:
  For the following AML namespace, with the ReferenceNode being the node with
  the name "AAAA":
   - the node with the name "BBBB" can be found by looking for the ASL
     path "BBBB";
   - the root node can be found by looking for the ASL relative path "^",
     or the absolute path "\\".

  AML namespace:
  \
  \-AAAA      <- ReferenceNode
    \-BBBB

  @param  [in]  ReferenceNode   Reference node.
                                If a relative path is given, the
                                search is done from this node. If
                                an absolute path is given, the
                                search is done from the root node.
                                Must be a root node or an object
                                node which is part of the
                                namespace.
  @param  [in]  AslPath         ASL path to the searched node in
                                the namespace. An ASL path name is
                                NULL terminated. Can be a relative
                                or absolute path.
                                E.g.: "\\_SB.CLU0.CPU0" or "^CPU0"
  @param  [out] OutNode         Pointer to the found node.
                                Contains NULL if not found.

  @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    Out of memory.
**/
EFI_STATUS
EFIAPI
AmlFindNode (
  IN  AML_NODE_HEADER  *ReferenceNode,
  IN  CONST CHAR8      *AslPath,
  OUT AML_NODE_HEADER  **OutNode
  )
{
  EFI_STATUS  Status;

  AML_PATH_SEARCH_CONTEXT  PathSearchContext;
  AML_ROOT_NODE            *RootNode;

  // Backward stream used to build the raw AML absolute path to the searched
  // node.
  AML_STREAM  RawAmlAbsSearchPathBStream;
  CHAR8       *RawAmlAbsSearchPathBuffer;
  UINT32      RawAmlAbsSearchPathBufferSize;

  // Backward stream used to store the raw AML absolute path of the node
  // currently enumerated in the tree. This path can then be compared to the
  // RawAmlAbsSearchPath.
  AML_STREAM  RawAmlAbsCurrNodePathBStream;
  CHAR8       *RawAmlAbsCurrNodePathBuffer;
  UINT32      RawAmlAbsCurrNodePathBufferSize;

  if ((!IS_AML_ROOT_NODE (ReferenceNode)        &&
       !AmlNodeHasAttribute (
          (CONST AML_OBJECT_NODE *)ReferenceNode,
          AML_IN_NAMESPACE
          ))                     ||
      (AslPath == NULL)                         ||
      (OutNode == NULL))
  {
    ASSERT (0);
    return EFI_INVALID_PARAMETER;
  }

  *OutNode                    = NULL;
  RawAmlAbsCurrNodePathBuffer = NULL;

  // 1. Build a raw absolute AML path from the reference node and the ASL
  //    path. For this:
  // 1.1. First initialize a backward stream.
  RawAmlAbsSearchPathBufferSize = MAX_AML_NAMESTRING_SIZE;
  RawAmlAbsSearchPathBuffer     = AllocateZeroPool (RawAmlAbsSearchPathBufferSize);
  if (RawAmlAbsSearchPathBuffer == NULL) {
    ASSERT (0);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = AmlStreamInit (
             &RawAmlAbsSearchPathBStream,
             (UINT8 *)RawAmlAbsSearchPathBuffer,
             RawAmlAbsSearchPathBufferSize,
             EAmlStreamDirectionBackward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // 1.2. Then build the raw AML absolute path.
  Status = AmlBuildAbsoluteAmlPath (
             ReferenceNode,
             AslPath,
             &RawAmlAbsSearchPathBStream
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // 2. Find the root node by climbing up the tree from the reference node.
  RootNode = AmlGetRootNode (ReferenceNode);
  if (RootNode == NULL) {
    ASSERT (0);
    Status = EFI_INVALID_PARAMETER;
    goto exit_handler;
  }

  // 3. If the searched node is the root node, return.
  //    For the Root Node there is no NameSegs so the length of
  //     the stream will be zero.
  if (AmlStreamGetIndex (&RawAmlAbsSearchPathBStream) == 0) {
    *OutNode = (AML_NODE_HEADER *)RootNode;
    Status   = EFI_SUCCESS;
    goto exit_handler;
  }

  // 4. Create a backward stream large enough to hold the current node path
  //    during enumeration. This prevents from doing multiple allocation/free
  //    operations.
  RawAmlAbsCurrNodePathBufferSize = MAX_ASL_NAMESTRING_SIZE;
  RawAmlAbsCurrNodePathBuffer     = AllocateZeroPool (
                                      RawAmlAbsCurrNodePathBufferSize
                                      );
  if (RawAmlAbsCurrNodePathBuffer == NULL) {
    ASSERT (0);
    Status = EFI_OUT_OF_RESOURCES;
    goto exit_handler;
  }

  Status = AmlStreamInit (
             &RawAmlAbsCurrNodePathBStream,
             (UINT8 *)RawAmlAbsCurrNodePathBuffer,
             RawAmlAbsCurrNodePathBufferSize,
             EAmlStreamDirectionBackward
             );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  // 5. Fill a path search context structure with:
  //     - SearchPathStream: backward stream containing the raw absolute AML
  //       path to the searched node;
  //     - CurrNodePathStream: backward stream containing the raw absolute AML
  //       of the node currently being enumerated;
  //     - OutNode: node pointer to the store the potentially found node.
  PathSearchContext.SearchPathBStream   = &RawAmlAbsSearchPathBStream;
  PathSearchContext.CurrNodePathBStream = &RawAmlAbsCurrNodePathBStream;
  PathSearchContext.OutNode             = NULL;

  // 6. Iterate through the namespace nodes of the tree.
  //    For each namespace node, build its raw AML absolute path. Then compare
  //    it with the search path.
  AmlEnumTree (
    (AML_NODE_HEADER *)RootNode,
    AmlEnumeratePathCallback,
    (VOID *)&PathSearchContext,
    &Status
    );
  if (EFI_ERROR (Status)) {
    ASSERT (0);
    goto exit_handler;
  }

  *OutNode = PathSearchContext.OutNode;
  if (*OutNode == NULL) {
    Status = EFI_NOT_FOUND;
  }

exit_handler:
  // Free allocated memory.
  FreePool (RawAmlAbsSearchPathBuffer);
  if (RawAmlAbsCurrNodePathBuffer != NULL) {
    FreePool (RawAmlAbsCurrNodePathBuffer);
  }

  return Status;
}
