mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-03 14:05:03 +00:00 
			
		
		
		
	REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the DynamicTablesPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
		
			
				
	
	
		
			703 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			703 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  AML Node.
 | 
						|
 | 
						|
  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
**/
 | 
						|
 | 
						|
#include <Tree/AmlNode.h>
 | 
						|
 | 
						|
#include <AmlCoreInterface.h>
 | 
						|
#include <Tree/AmlTree.h>
 | 
						|
 | 
						|
/** Initialize an AML_NODE_HEADER structure.
 | 
						|
 | 
						|
  @param  [in]  Node      Pointer to a node header.
 | 
						|
  @param  [in]  NodeType  NodeType to initialize the Node with.
 | 
						|
                          Must be an EAML_NODE_TYPE.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The function completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlInitializeNodeHeader (
 | 
						|
  IN  AML_NODE_HEADER  *Node,
 | 
						|
  IN  EAML_NODE_TYPE   NodeType
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (Node == NULL) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  InitializeListHead (&Node->Link);
 | 
						|
 | 
						|
  Node->Parent   = NULL;
 | 
						|
  Node->NodeType = NodeType;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/** Delete a root node and its ACPI DSDT/SSDT header.
 | 
						|
 | 
						|
  It is the caller's responsibility to check the RootNode has been removed
 | 
						|
  from the tree and is not referencing any other node in the tree.
 | 
						|
 | 
						|
  @param  [in]  RootNode  Pointer to a root node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The function completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlDeleteRootNode (
 | 
						|
  IN  AML_ROOT_NODE  *RootNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (!IS_AML_ROOT_NODE (RootNode)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if ((RootNode->SdtHeader != NULL)) {
 | 
						|
    FreePool (RootNode->SdtHeader);
 | 
						|
  } else {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (RootNode);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/** Create an AML_ROOT_NODE.
 | 
						|
    This node will be the root of the tree.
 | 
						|
 | 
						|
  @param  [in]  SdtHeader       Pointer to an ACPI DSDT/SSDT header to copy
 | 
						|
                                the data from.
 | 
						|
  @param  [out] NewRootNodePtr  If success, contains the created
 | 
						|
                                AML_ROOT_NODE.
 | 
						|
                                Otherwise reset to NULL.
 | 
						|
 | 
						|
  @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
 | 
						|
AmlCreateRootNode (
 | 
						|
  IN  CONST EFI_ACPI_DESCRIPTION_HEADER  *SdtHeader,
 | 
						|
  OUT       AML_ROOT_NODE                **NewRootNodePtr
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS     Status;
 | 
						|
  AML_ROOT_NODE  *RootNode;
 | 
						|
 | 
						|
  if ((SdtHeader == NULL) ||
 | 
						|
      (NewRootNodePtr == NULL))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *NewRootNodePtr = NULL;
 | 
						|
 | 
						|
  RootNode = AllocateZeroPool (sizeof (AML_ROOT_NODE));
 | 
						|
  if (RootNode == NULL) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlInitializeNodeHeader (&RootNode->NodeHeader, EAmlNodeRoot);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FreePool (RootNode);
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  InitializeListHead (&RootNode->VariableArgs);
 | 
						|
 | 
						|
  RootNode->SdtHeader = AllocateCopyPool (
 | 
						|
                          sizeof (EFI_ACPI_DESCRIPTION_HEADER),
 | 
						|
                          SdtHeader
 | 
						|
                          );
 | 
						|
  if (RootNode->SdtHeader == NULL) {
 | 
						|
    ASSERT (0);
 | 
						|
    AmlDeleteRootNode (RootNode);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  *NewRootNodePtr = RootNode;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/** Delete an object node.
 | 
						|
 | 
						|
  It is the caller's responsibility to check the ObjectNode has been removed
 | 
						|
  from the tree and is not referencing any other node in the tree.
 | 
						|
 | 
						|
  @param  [in]  ObjectNode  Pointer to an object node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The function completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlDeleteObjectNode (
 | 
						|
  IN  AML_OBJECT_NODE  *ObjectNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (!IS_AML_OBJECT_NODE (ObjectNode)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (ObjectNode);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/** Create an AML_OBJECT_NODE.
 | 
						|
 | 
						|
  @param  [in]  AmlByteEncoding   Byte encoding entry.
 | 
						|
  @param  [in]  PkgLength         PkgLength of the node if the AmlByteEncoding
 | 
						|
                                  has the PkgLen attribute.
 | 
						|
                                  0 otherwise.
 | 
						|
  @param  [out] NewObjectNodePtr  If success, contains the created
 | 
						|
                                  AML_OBJECT_NODE.
 | 
						|
                                  Otherwise reset to NULL.
 | 
						|
 | 
						|
  @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
 | 
						|
AmlCreateObjectNode (
 | 
						|
  IN  CONST  AML_BYTE_ENCODING  *AmlByteEncoding,
 | 
						|
  IN         UINT32             PkgLength,
 | 
						|
  OUT        AML_OBJECT_NODE    **NewObjectNodePtr
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *ObjectNode;
 | 
						|
 | 
						|
  if ((AmlByteEncoding == NULL)  ||
 | 
						|
      (NewObjectNodePtr == NULL))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *NewObjectNodePtr = NULL;
 | 
						|
 | 
						|
  ObjectNode = AllocateZeroPool (sizeof (AML_OBJECT_NODE));
 | 
						|
  if (ObjectNode == NULL) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlInitializeNodeHeader (&ObjectNode->NodeHeader, EAmlNodeObject);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FreePool (ObjectNode);
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  InitializeListHead (&ObjectNode->VariableArgs);
 | 
						|
 | 
						|
  // ObjectNode->FixedArgs[...] is already initialised to NULL as the
 | 
						|
  // ObjectNode is Zero allocated.
 | 
						|
  ObjectNode->AmlByteEncoding = AmlByteEncoding;
 | 
						|
  ObjectNode->PkgLen          = PkgLength;
 | 
						|
 | 
						|
  *NewObjectNodePtr = ObjectNode;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/** Delete a data node and its buffer.
 | 
						|
 | 
						|
  It is the caller's responsibility to check the DataNode has been removed
 | 
						|
  from the tree and is not referencing any other node in the tree.
 | 
						|
 | 
						|
  @param  [in]  DataNode  Pointer to a data 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
 | 
						|
AmlDeleteDataNode (
 | 
						|
  IN  AML_DATA_NODE  *DataNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (!IS_AML_DATA_NODE (DataNode)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  if (DataNode->Buffer != NULL) {
 | 
						|
    FreePool (DataNode->Buffer);
 | 
						|
  } else {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (DataNode);
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/** Create an AML_DATA_NODE.
 | 
						|
 | 
						|
  @param  [in]  DataType        DataType of the node.
 | 
						|
  @param  [in]  Data            Pointer to the AML bytecode corresponding to
 | 
						|
                                this node. Data is copied from there.
 | 
						|
  @param  [in]  DataSize        Number of bytes to consider at the address
 | 
						|
                                pointed by Data.
 | 
						|
  @param  [out] NewDataNodePtr  If success, contains the created
 | 
						|
                                AML_DATA_NODE.
 | 
						|
                                Otherwise reset to NULL.
 | 
						|
 | 
						|
  @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
 | 
						|
AmlCreateDataNode (
 | 
						|
  IN        EAML_NODE_DATA_TYPE  DataType,
 | 
						|
  IN  CONST UINT8                *Data,
 | 
						|
  IN        UINT32               DataSize,
 | 
						|
  OUT       AML_DATA_NODE        **NewDataNodePtr
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS     Status;
 | 
						|
  AML_DATA_NODE  *DataNode;
 | 
						|
 | 
						|
  // A data node must not be created for certain data types.
 | 
						|
  if ((DataType == EAmlNodeDataTypeNone)       ||
 | 
						|
      (DataType == EAmlNodeDataTypeReserved1)  ||
 | 
						|
      (DataType == EAmlNodeDataTypeReserved2)  ||
 | 
						|
      (DataType == EAmlNodeDataTypeReserved3)  ||
 | 
						|
      (DataType == EAmlNodeDataTypeReserved4)  ||
 | 
						|
      (DataType == EAmlNodeDataTypeReserved5)  ||
 | 
						|
      (Data == NULL)                           ||
 | 
						|
      (DataSize == 0)                          ||
 | 
						|
      (NewDataNodePtr == NULL))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *NewDataNodePtr = NULL;
 | 
						|
 | 
						|
  DataNode = AllocateZeroPool (sizeof (AML_DATA_NODE));
 | 
						|
  if (DataNode == NULL) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlInitializeNodeHeader (&DataNode->NodeHeader, EAmlNodeData);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FreePool (DataNode);
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  DataNode->Buffer = AllocateCopyPool (DataSize, Data);
 | 
						|
  if (DataNode->Buffer == NULL) {
 | 
						|
    AmlDeleteDataNode (DataNode);
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  DataNode->DataType = DataType;
 | 
						|
  DataNode->Size     = DataSize;
 | 
						|
 | 
						|
  *NewDataNodePtr = DataNode;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/** Delete a Node.
 | 
						|
 | 
						|
  @param  [in]  Node  Pointer to a Node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The function completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlDeleteNode (
 | 
						|
  IN  AML_NODE_HEADER  *Node
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS        Status;
 | 
						|
  EAML_PARSE_INDEX  Index;
 | 
						|
 | 
						|
  // Check that the node being deleted is unlinked.
 | 
						|
  // When removing the node, its parent and list are reset
 | 
						|
  // with InitializeListHead. Thus it must be empty.
 | 
						|
  if (!IS_AML_NODE_VALID (Node) ||
 | 
						|
      !AML_NODE_IS_DETACHED (Node))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  switch (Node->NodeType) {
 | 
						|
    case EAmlNodeRoot:
 | 
						|
    {
 | 
						|
      // Check the variable list of arguments has been cleaned.
 | 
						|
      if (!IsListEmpty (AmlNodeGetVariableArgList (Node))) {
 | 
						|
        ASSERT (0);
 | 
						|
        return EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
 | 
						|
      Status = AmlDeleteRootNode ((AML_ROOT_NODE *)Node);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        ASSERT (0);
 | 
						|
      }
 | 
						|
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    case EAmlNodeObject:
 | 
						|
    {
 | 
						|
      // Check the variable list of arguments has been cleaned.
 | 
						|
      if (!IsListEmpty (AmlNodeGetVariableArgList (Node))) {
 | 
						|
        ASSERT (0);
 | 
						|
        return EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
 | 
						|
      // Check the fixed argument list has been cleaned.
 | 
						|
      for (Index = EAmlParseIndexTerm0; Index < EAmlParseIndexMax; Index++) {
 | 
						|
        if (((AML_OBJECT_NODE *)Node)->FixedArgs[Index] != NULL) {
 | 
						|
          ASSERT (0);
 | 
						|
          return EFI_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      Status = AmlDeleteObjectNode ((AML_OBJECT_NODE *)Node);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        ASSERT (0);
 | 
						|
      }
 | 
						|
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    case EAmlNodeData:
 | 
						|
    {
 | 
						|
      Status = AmlDeleteDataNode ((AML_DATA_NODE *)Node);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        ASSERT (0);
 | 
						|
      }
 | 
						|
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    default:
 | 
						|
    {
 | 
						|
      ASSERT (0);
 | 
						|
      Status = EFI_INVALID_PARAMETER;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  } // switch
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** Check whether ObjectNode has the input attribute.
 | 
						|
    This function can be used to check ObjectNode is an object node
 | 
						|
    at the same time.
 | 
						|
 | 
						|
  @param  [in]  ObjectNode  Pointer to an object node.
 | 
						|
  @param  [in]  Attribute   Attribute to check for.
 | 
						|
 | 
						|
  @retval TRUE    The node is an AML object and the attribute is present.
 | 
						|
  @retval FALSE   Otherwise.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
AmlNodeHasAttribute (
 | 
						|
  IN  CONST AML_OBJECT_NODE   *ObjectNode,
 | 
						|
  IN        AML_OP_ATTRIBUTE  Attribute
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (!IS_AML_OBJECT_NODE (ObjectNode) ||
 | 
						|
      (ObjectNode->AmlByteEncoding == NULL))
 | 
						|
  {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  return ((ObjectNode->AmlByteEncoding->Attribute &
 | 
						|
           Attribute) == 0 ? FALSE : TRUE);
 | 
						|
}
 | 
						|
 | 
						|
/** Check whether ObjectNode has the input OpCode/SubOpcode couple.
 | 
						|
 | 
						|
  @param  [in]  ObjectNode  Pointer to an object node.
 | 
						|
  @param  [in]  OpCode      OpCode to check
 | 
						|
  @param  [in]  SubOpCode   SubOpCode to check
 | 
						|
 | 
						|
  @retval TRUE    The node is an AML object and
 | 
						|
                  the Opcode and the SubOpCode match.
 | 
						|
  @retval FALSE   Otherwise.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
AmlNodeCompareOpCode (
 | 
						|
  IN  CONST  AML_OBJECT_NODE  *ObjectNode,
 | 
						|
  IN         UINT8            OpCode,
 | 
						|
  IN         UINT8            SubOpCode
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (!IS_AML_OBJECT_NODE (ObjectNode) ||
 | 
						|
      (ObjectNode->AmlByteEncoding == NULL))
 | 
						|
  {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  ASSERT (AmlIsOpCodeValid (OpCode, SubOpCode));
 | 
						|
 | 
						|
  return ((ObjectNode->AmlByteEncoding->OpCode == OpCode) &&
 | 
						|
          (ObjectNode->AmlByteEncoding->SubOpCode == SubOpCode)) ?
 | 
						|
         TRUE : FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/** Check whether a Node is an integer node.
 | 
						|
 | 
						|
  By integer node we mean an object node having one of the following opcode:
 | 
						|
   - AML_BYTE_PREFIX;
 | 
						|
   - AML_WORD_PREFIX;
 | 
						|
   - AML_DWORD_PREFIX;
 | 
						|
   - AML_QWORD_PREFIX.
 | 
						|
 | 
						|
  @param  [in]  Node  The node to check.
 | 
						|
 | 
						|
  @retval TRUE  The Node is an integer node.
 | 
						|
  @retval FALSE Otherwise.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
IsIntegerNode (
 | 
						|
  IN  AML_OBJECT_NODE  *Node
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8  OpCode;
 | 
						|
 | 
						|
  if (!IS_AML_OBJECT_NODE (Node)  ||
 | 
						|
      (Node->AmlByteEncoding == NULL))
 | 
						|
  {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  // Check Node is an integer node.
 | 
						|
  OpCode = Node->AmlByteEncoding->OpCode;
 | 
						|
  if ((OpCode != AML_BYTE_PREFIX)   &&
 | 
						|
      (OpCode != AML_WORD_PREFIX)   &&
 | 
						|
      (OpCode != AML_DWORD_PREFIX)  &&
 | 
						|
      (OpCode != AML_QWORD_PREFIX))
 | 
						|
  {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/** Check whether a Node is a ZeroOp, a OneOp or a OnesOp.
 | 
						|
 | 
						|
  These two objects don't have a data node holding
 | 
						|
  a value. This require special handling.
 | 
						|
 | 
						|
  @param  [in]  Node  The node to check.
 | 
						|
 | 
						|
  @retval TRUE  The Node is a ZeroOp or OneOp.
 | 
						|
  @retval FALSE Otherwise.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
IsSpecialIntegerNode (
 | 
						|
  IN  AML_OBJECT_NODE  *Node
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8  OpCode;
 | 
						|
 | 
						|
  if (!IS_AML_OBJECT_NODE (Node)  ||
 | 
						|
      (Node->AmlByteEncoding == NULL))
 | 
						|
  {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  OpCode = Node->AmlByteEncoding->OpCode;
 | 
						|
 | 
						|
  if ((OpCode != AML_ZERO_OP) &&
 | 
						|
      (OpCode != AML_ONE_OP)  &&
 | 
						|
      (OpCode != AML_ONES_OP))
 | 
						|
  {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/** Check whether Node corresponds to a method definition.
 | 
						|
 | 
						|
  A method definition can be introduced:
 | 
						|
   - By a method object, having an AML_METHOD_OP OpCode;
 | 
						|
   - By an external definition of a method, having an AML_EXTERNAL_OP OpCode
 | 
						|
     and an ObjectType byte set to the MethodObj.
 | 
						|
 | 
						|
  Note:
 | 
						|
  An alias node, having an AML_ALIAS_OP, can be resolved to a method
 | 
						|
  definition. This function doesn't handle this case.
 | 
						|
 | 
						|
  @param [in] Node    Node to check whether it is a method definition.
 | 
						|
 | 
						|
  @retval TRUE  The Node is a method definition.
 | 
						|
  @retval FALSE Otherwise.
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
AmlIsMethodDefinitionNode (
 | 
						|
  IN  CONST AML_OBJECT_NODE  *Node
 | 
						|
  )
 | 
						|
{
 | 
						|
  AML_DATA_NODE  *ObjectType;
 | 
						|
 | 
						|
  // Node is checked to be an object node aswell.
 | 
						|
  if (AmlNodeCompareOpCode (Node, AML_METHOD_OP, 0)) {
 | 
						|
    return TRUE;
 | 
						|
  } else if (AmlNodeCompareOpCode (Node, AML_EXTERNAL_OP, 0)) {
 | 
						|
    // If the node is an external definition, check this is a method.
 | 
						|
    // DefExternal := ExternalOp NameString ObjectType ArgumentCount
 | 
						|
    // ExternalOp := 0x15
 | 
						|
    // ObjectType := ByteData
 | 
						|
    // ArgumentCount := ByteData (0 - 7)
 | 
						|
    ObjectType = (AML_DATA_NODE *)AmlGetFixedArgument (
 | 
						|
                                    (AML_OBJECT_NODE *)Node,
 | 
						|
                                    EAmlParseIndexTerm1
 | 
						|
                                    );
 | 
						|
    if (IS_AML_DATA_NODE (ObjectType)                   &&
 | 
						|
        (ObjectType->DataType == EAmlNodeDataTypeUInt)  &&
 | 
						|
        ((ObjectType->Size == 1)))
 | 
						|
    {
 | 
						|
      if (*((UINT8 *)ObjectType->Buffer) == (UINT8)EAmlObjTypeMethodObj) {
 | 
						|
        // The external definition is a method.
 | 
						|
        return TRUE;
 | 
						|
      } else {
 | 
						|
        // The external definition is not a method.
 | 
						|
        return FALSE;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      // The tree is inconsistent.
 | 
						|
      ASSERT (0);
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // This is not a method definition.
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
/** Get the index at which the name of the node is stored.
 | 
						|
 | 
						|
  @param  [in]  ObjectNode  Pointer to an object node.
 | 
						|
                            Must have the AML_IN_NAMESPACE attribute.
 | 
						|
  @param  [out] Index       Index of the name in the fixed list of arguments.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The function completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
AmlNodeGetNameIndex (
 | 
						|
  IN  CONST AML_OBJECT_NODE   *ObjectNode,
 | 
						|
  OUT       EAML_PARSE_INDEX  *Index
 | 
						|
  )
 | 
						|
{
 | 
						|
  EAML_PARSE_INDEX  NameIndex;
 | 
						|
 | 
						|
  if (!AmlNodeHasAttribute (ObjectNode, AML_IN_NAMESPACE)   ||
 | 
						|
      (ObjectNode->AmlByteEncoding == NULL)                 ||
 | 
						|
      (Index == NULL))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  NameIndex = ObjectNode->AmlByteEncoding->NameIndex;
 | 
						|
 | 
						|
  if ((NameIndex > ObjectNode->AmlByteEncoding->MaxIndex)   ||
 | 
						|
      (ObjectNode->AmlByteEncoding->Format[NameIndex] != EAmlName))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *Index = NameIndex;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/** Get the name of the Node.
 | 
						|
 | 
						|
  Node must be part of the namespace.
 | 
						|
 | 
						|
  @param [in] ObjectNode    Pointer to an object node,
 | 
						|
                            which is part of the namespace.
 | 
						|
 | 
						|
  @return A pointer to the name.
 | 
						|
          NULL otherwise.
 | 
						|
          Return NULL for the root node.
 | 
						|
**/
 | 
						|
CHAR8 *
 | 
						|
EFIAPI
 | 
						|
AmlNodeGetName (
 | 
						|
  IN  CONST AML_OBJECT_NODE  *ObjectNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS        Status;
 | 
						|
  EAML_PARSE_INDEX  NameIndex;
 | 
						|
  AML_DATA_NODE     *DataNode;
 | 
						|
 | 
						|
  if (!AmlNodeHasAttribute (ObjectNode, AML_IN_NAMESPACE)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  // Get the index at which the name is stored in the fixed arguments list.
 | 
						|
  Status = AmlNodeGetNameIndex (ObjectNode, &NameIndex);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  // The name is stored in a Data node.
 | 
						|
  DataNode = (AML_DATA_NODE *)ObjectNode->FixedArgs[NameIndex];
 | 
						|
  if (IS_AML_DATA_NODE (DataNode) &&
 | 
						|
      (DataNode->DataType == EAmlNodeDataTypeNameString))
 | 
						|
  {
 | 
						|
    return (CHAR8 *)DataNode->Buffer;
 | 
						|
  }
 | 
						|
 | 
						|
  /* Return NULL if no name is found.
 | 
						|
     This can occur if the name of a node is defined as a further
 | 
						|
     fixed argument.
 | 
						|
     E.g.:  CreateField (BD03, 0x28, Add (ID03 + 0x08), BF33)
 | 
						|
                                     ^
 | 
						|
                             The parser is here.
 | 
						|
     The parent of the Add statement is the CreateField statement. This
 | 
						|
     statement defines a name in the AML namespace. This name defined as
 | 
						|
     the fourth fixed argument. It hasn't been parsed yet.
 | 
						|
  */
 | 
						|
  return NULL;
 | 
						|
}
 |