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>
		
			
				
	
	
		
			2097 lines
		
	
	
		
			59 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2097 lines
		
	
	
		
			59 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  AML Code Generation.
 | 
						|
 | 
						|
  Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
**/
 | 
						|
 | 
						|
#include <AmlNodeDefines.h>
 | 
						|
 | 
						|
#include <AcpiTableGenerator.h>
 | 
						|
 | 
						|
#include <AmlCoreInterface.h>
 | 
						|
#include <AmlEncoding/Aml.h>
 | 
						|
#include <Api/AmlApiHelper.h>
 | 
						|
#include <CodeGen/AmlResourceDataCodeGen.h>
 | 
						|
#include <Tree/AmlNode.h>
 | 
						|
#include <Tree/AmlTree.h>
 | 
						|
#include <String/AmlString.h>
 | 
						|
#include <Utils/AmlUtility.h>
 | 
						|
 | 
						|
/** Utility function to link a node when returning from a CodeGen function.
 | 
						|
 | 
						|
  @param [in]  Node           Newly created node.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
  @param [out] NewObjectNode  If not NULL:
 | 
						|
                               - and Success, contains the created Node.
 | 
						|
                               - and Error, reset to NULL.
 | 
						|
 | 
						|
  @retval  EFI_SUCCESS            The function completed successfully.
 | 
						|
  @retval  EFI_INVALID_PARAMETER  Invalid parameter.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
LinkNode (
 | 
						|
  IN  AML_OBJECT_NODE  *Node,
 | 
						|
  IN  AML_NODE_HEADER  *ParentNode,
 | 
						|
  OUT AML_OBJECT_NODE  **NewObjectNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  if (NewObjectNode != NULL) {
 | 
						|
    *NewObjectNode = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  // Add RdNode as the last element.
 | 
						|
  if (ParentNode != NULL) {
 | 
						|
    Status = AmlVarListAddTail (ParentNode, (AML_NODE_HEADER *)Node);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (NewObjectNode != NULL) {
 | 
						|
    *NewObjectNode = Node;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for DefinitionBlock.
 | 
						|
 | 
						|
  Create a Root Node handle.
 | 
						|
  It is the caller's responsibility to free the allocated memory
 | 
						|
  with the AmlDeleteTree function.
 | 
						|
 | 
						|
  AmlCodeGenDefinitionBlock (TableSignature, OemID, TableID, OEMRevision) is
 | 
						|
  equivalent to the following ASL code:
 | 
						|
    DefinitionBlock (AMLFileName, TableSignature, ComplianceRevision,
 | 
						|
      OemID, TableID, OEMRevision) {}
 | 
						|
  with the ComplianceRevision set to 2 and the AMLFileName is ignored.
 | 
						|
 | 
						|
  @param[in]  TableSignature       4-character ACPI signature.
 | 
						|
                                   Must be 'DSDT' or 'SSDT'.
 | 
						|
  @param[in]  OemId                6-character string OEM identifier.
 | 
						|
  @param[in]  OemTableId           8-character string OEM table identifier.
 | 
						|
  @param[in]  OemRevision          OEM revision number.
 | 
						|
  @param[out] NewRootNode          Pointer to the root node representing a
 | 
						|
                                   Definition Block.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenDefinitionBlock (
 | 
						|
  IN  CONST CHAR8          *TableSignature,
 | 
						|
  IN  CONST CHAR8          *OemId,
 | 
						|
  IN  CONST CHAR8          *OemTableId,
 | 
						|
  IN        UINT32         OemRevision,
 | 
						|
  OUT       AML_ROOT_NODE  **NewRootNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                   Status;
 | 
						|
  EFI_ACPI_DESCRIPTION_HEADER  AcpiHeader;
 | 
						|
 | 
						|
  if ((TableSignature == NULL)  ||
 | 
						|
      (OemId == NULL)           ||
 | 
						|
      (OemTableId == NULL)      ||
 | 
						|
      (NewRootNode == NULL))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  CopyMem (&AcpiHeader.Signature, TableSignature, 4);
 | 
						|
  AcpiHeader.Length   = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
 | 
						|
  AcpiHeader.Revision = 2;
 | 
						|
  CopyMem (&AcpiHeader.OemId, OemId, 6);
 | 
						|
  CopyMem (&AcpiHeader.OemTableId, OemTableId, 8);
 | 
						|
  AcpiHeader.OemRevision     = OemRevision;
 | 
						|
  AcpiHeader.CreatorId       = TABLE_GENERATOR_CREATOR_ID_ARM;
 | 
						|
  AcpiHeader.CreatorRevision = CREATE_REVISION (1, 0);
 | 
						|
 | 
						|
  Status = AmlCreateRootNode (&AcpiHeader, NewRootNode);
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a String object node.
 | 
						|
 | 
						|
  @param [in]  String          Pointer to a NULL terminated string.
 | 
						|
  @param [out] NewObjectNode   If success, contains the created
 | 
						|
                               String object node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenString (
 | 
						|
  IN  CHAR8            *String,
 | 
						|
  OUT AML_OBJECT_NODE  **NewObjectNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *ObjectNode;
 | 
						|
  AML_DATA_NODE    *DataNode;
 | 
						|
 | 
						|
  if ((String == NULL)  ||
 | 
						|
      (NewObjectNode == NULL))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  DataNode = NULL;
 | 
						|
 | 
						|
  Status = AmlCreateObjectNode (
 | 
						|
             AmlGetByteEncodingByOpCode (AML_STRING_PREFIX, 0),
 | 
						|
             0,
 | 
						|
             &ObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateDataNode (
 | 
						|
             EAmlNodeDataTypeString,
 | 
						|
             (UINT8 *)String,
 | 
						|
             (UINT32)AsciiStrLen (String) + 1,
 | 
						|
             &DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             ObjectNode,
 | 
						|
             EAmlParseIndexTerm0,
 | 
						|
             (AML_NODE_HEADER *)DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  *NewObjectNode = ObjectNode;
 | 
						|
  return Status;
 | 
						|
 | 
						|
error_handler:
 | 
						|
  AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for an Integer object node.
 | 
						|
 | 
						|
  @param [in]  Integer         Integer of the Integer object node.
 | 
						|
  @param [out] NewObjectNode   If success, contains the created
 | 
						|
                               Integer object node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenInteger (
 | 
						|
  IN  UINT64           Integer,
 | 
						|
  OUT AML_OBJECT_NODE  **NewObjectNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  INT8        ValueWidthDiff;
 | 
						|
 | 
						|
  if (NewObjectNode == NULL) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  // Create an object node containing Zero.
 | 
						|
  Status = AmlCreateObjectNode (
 | 
						|
             AmlGetByteEncodingByOpCode (AML_ZERO_OP, 0),
 | 
						|
             0,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // Update the object node with integer value.
 | 
						|
  Status = AmlNodeSetIntegerValue (*NewObjectNode, Integer, &ValueWidthDiff);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)*NewObjectNode);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Package object node.
 | 
						|
 | 
						|
  The package generated is empty. New elements can be added via its
 | 
						|
  list of variable arguments.
 | 
						|
 | 
						|
  @param [out] NewObjectNode   If success, contains the created
 | 
						|
                               Package object node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenPackage (
 | 
						|
  OUT AML_OBJECT_NODE  **NewObjectNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS     Status;
 | 
						|
  AML_DATA_NODE  *DataNode;
 | 
						|
  UINT8          NodeCount;
 | 
						|
 | 
						|
  if (NewObjectNode == NULL) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  NodeCount = 0;
 | 
						|
 | 
						|
  // Create an object node.
 | 
						|
  // PkgLen is 2:
 | 
						|
  //  - one byte to store the PkgLength
 | 
						|
  //  - one byte for the NumElements.
 | 
						|
  // Cf ACPI6.3, s20.2.5 "Term Objects Encoding"
 | 
						|
  // DefPackage  := PackageOp PkgLength NumElements PackageElementList
 | 
						|
  // NumElements := ByteData
 | 
						|
  Status = AmlCreateObjectNode (
 | 
						|
             AmlGetByteEncodingByOpCode (AML_PACKAGE_OP, 0),
 | 
						|
             2,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // NumElements is a ByteData.
 | 
						|
  Status = AmlCreateDataNode (
 | 
						|
             EAmlNodeDataTypeUInt,
 | 
						|
             &NodeCount,
 | 
						|
             sizeof (NodeCount),
 | 
						|
             &DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             *NewObjectNode,
 | 
						|
             EAmlParseIndexTerm0,
 | 
						|
             (AML_NODE_HEADER *)DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
 | 
						|
error_handler:
 | 
						|
  AmlDeleteTree ((AML_NODE_HEADER *)*NewObjectNode);
 | 
						|
  if (DataNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Buffer object node.
 | 
						|
 | 
						|
  To create a Buffer object node with an empty buffer,
 | 
						|
  call the function with (Buffer=NULL, BufferSize=0).
 | 
						|
 | 
						|
  @param [in]  Buffer          Buffer to set for the created Buffer
 | 
						|
                               object node. The Buffer's content is copied.
 | 
						|
                               NULL if there is no buffer to set for
 | 
						|
                               the Buffer node.
 | 
						|
  @param [in]  BufferSize      Size of the Buffer.
 | 
						|
                               0 if there is no buffer to set for
 | 
						|
                               the Buffer node.
 | 
						|
  @param [out] NewObjectNode   If success, contains the created
 | 
						|
                               Buffer object node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenBuffer (
 | 
						|
  IN  CONST UINT8            *Buffer        OPTIONAL,
 | 
						|
  IN        UINT32           BufferSize    OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE  **NewObjectNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *BufferNode;
 | 
						|
  AML_OBJECT_NODE  *BufferSizeNode;
 | 
						|
  UINT32           BufferSizeNodeSize;
 | 
						|
  AML_DATA_NODE    *DataNode;
 | 
						|
  UINT32           PkgLen;
 | 
						|
 | 
						|
  // Buffer and BufferSize must be either both set, or both clear.
 | 
						|
  if ((NewObjectNode == NULL)                 ||
 | 
						|
      ((Buffer == NULL) != (BufferSize == 0)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  BufferNode = NULL;
 | 
						|
  DataNode   = NULL;
 | 
						|
 | 
						|
  // Cf ACPI 6.3 specification, s20.2.5.4 "Type 2 Opcodes Encoding"
 | 
						|
  // DefBuffer := BufferOp PkgLength BufferSize ByteList
 | 
						|
  // BufferOp  := 0x11
 | 
						|
  // BufferSize := TermArg => Integer
 | 
						|
 | 
						|
  Status = AmlCodeGenInteger (BufferSize, &BufferSizeNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // Get the number of bytes required to encode the BufferSizeNode.
 | 
						|
  Status = AmlComputeSize (
 | 
						|
             (AML_NODE_HEADER *)BufferSizeNode,
 | 
						|
             &BufferSizeNodeSize
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  // Compute the size to write in the PkgLen.
 | 
						|
  Status = AmlComputePkgLength (BufferSizeNodeSize + BufferSize, &PkgLen);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  // Create an object node for the buffer.
 | 
						|
  Status = AmlCreateObjectNode (
 | 
						|
             AmlGetByteEncodingByOpCode (AML_BUFFER_OP, 0),
 | 
						|
             PkgLen,
 | 
						|
             &BufferNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  // Set the BufferSizeNode as a fixed argument of the BufferNode.
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             BufferNode,
 | 
						|
             EAmlParseIndexTerm0,
 | 
						|
             (AML_NODE_HEADER *)BufferSizeNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  // BufferSizeNode is now attached.
 | 
						|
  BufferSizeNode = NULL;
 | 
						|
 | 
						|
  // If there is a buffer, create a DataNode and attach it to the BufferNode.
 | 
						|
  if (Buffer != NULL) {
 | 
						|
    Status = AmlCreateDataNode (
 | 
						|
               EAmlNodeDataTypeRaw,
 | 
						|
               Buffer,
 | 
						|
               BufferSize,
 | 
						|
               &DataNode
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = AmlVarListAddTail (
 | 
						|
               (AML_NODE_HEADER *)BufferNode,
 | 
						|
               (AML_NODE_HEADER *)DataNode
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  *NewObjectNode = BufferNode;
 | 
						|
  return Status;
 | 
						|
 | 
						|
error_handler:
 | 
						|
  if (BufferSizeNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)BufferSizeNode);
 | 
						|
  }
 | 
						|
 | 
						|
  if (BufferNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)BufferNode);
 | 
						|
  }
 | 
						|
 | 
						|
  if (DataNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a ResourceTemplate.
 | 
						|
 | 
						|
  "ResourceTemplate" is a macro defined in ACPI 6.3, s19.3.3
 | 
						|
  "ASL Resource Templates". It allows to store resource data elements.
 | 
						|
 | 
						|
  In AML, a ResourceTemplate is implemented as a Buffer storing resource
 | 
						|
  data elements. An EndTag resource data descriptor must be at the end
 | 
						|
  of the list of resource data elements.
 | 
						|
  This function generates a Buffer node with an EndTag resource data
 | 
						|
  descriptor. It can be seen as an empty list of resource data elements.
 | 
						|
 | 
						|
  @param [out] NewObjectNode   If success, contains the created
 | 
						|
                               ResourceTemplate object node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenResourceTemplate (
 | 
						|
  OUT AML_OBJECT_NODE  **NewObjectNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *BufferNode;
 | 
						|
 | 
						|
  if (NewObjectNode == NULL) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  // Create a BufferNode with an empty buffer.
 | 
						|
  Status = AmlCodeGenBuffer (NULL, 0, &BufferNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // Create an EndTag resource data element and attach it to the Buffer.
 | 
						|
  Status = AmlCodeGenEndTag (0, BufferNode, NULL);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)BufferNode);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  *NewObjectNode = BufferNode;
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Name object node.
 | 
						|
 | 
						|
  @param  [in] NameString     The new variable name.
 | 
						|
                              Must be a NULL-terminated ASL NameString
 | 
						|
                              e.g.: "DEV0", "DV15.DEV0", etc.
 | 
						|
                              This input string is copied.
 | 
						|
  @param [in]  Object         Object associated to the NameString.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
  @param [out] NewObjectNode  If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenName (
 | 
						|
  IN  CONST CHAR8            *NameString,
 | 
						|
  IN        AML_OBJECT_NODE  *Object,
 | 
						|
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *ObjectNode;
 | 
						|
  AML_DATA_NODE    *DataNode;
 | 
						|
  CHAR8            *AmlNameString;
 | 
						|
  UINT32           AmlNameStringSize;
 | 
						|
 | 
						|
  if ((NameString == NULL)    ||
 | 
						|
      (Object == NULL)        ||
 | 
						|
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  ObjectNode    = NULL;
 | 
						|
  DataNode      = NULL;
 | 
						|
  AmlNameString = NULL;
 | 
						|
 | 
						|
  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler1;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateObjectNode (
 | 
						|
             AmlGetByteEncodingByOpCode (AML_NAME_OP, 0),
 | 
						|
             0,
 | 
						|
             &ObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler1;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateDataNode (
 | 
						|
             EAmlNodeDataTypeNameString,
 | 
						|
             (UINT8 *)AmlNameString,
 | 
						|
             AmlNameStringSize,
 | 
						|
             &DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             ObjectNode,
 | 
						|
             EAmlParseIndexTerm0,
 | 
						|
             (AML_NODE_HEADER *)DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             ObjectNode,
 | 
						|
             EAmlParseIndexTerm1,
 | 
						|
             (AML_NODE_HEADER *)Object
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = LinkNode (
 | 
						|
             ObjectNode,
 | 
						|
             ParentNode,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  // Free AmlNameString before returning as it is copied
 | 
						|
  // in the call to AmlCreateDataNode().
 | 
						|
  goto error_handler1;
 | 
						|
 | 
						|
error_handler2:
 | 
						|
  if (ObjectNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
 | 
						|
  }
 | 
						|
 | 
						|
error_handler1:
 | 
						|
  if (AmlNameString != NULL) {
 | 
						|
    FreePool (AmlNameString);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Name object node, containing a String.
 | 
						|
 | 
						|
  AmlCodeGenNameString ("_HID", "HID0000", ParentNode, NewObjectNode) is
 | 
						|
  equivalent of the following ASL code:
 | 
						|
    Name(_HID, "HID0000")
 | 
						|
 | 
						|
  @param  [in] NameString     The new variable name.
 | 
						|
                              Must be a NULL-terminated ASL NameString
 | 
						|
                              e.g.: "DEV0", "DV15.DEV0", etc.
 | 
						|
                              The input string is copied.
 | 
						|
  @param [in]  String         NULL terminated String to associate to the
 | 
						|
                              NameString.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
  @param [out] NewObjectNode  If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenNameString (
 | 
						|
  IN  CONST CHAR8            *NameString,
 | 
						|
  IN        CHAR8            *String,
 | 
						|
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *ObjectNode;
 | 
						|
 | 
						|
  if ((NameString == NULL)  ||
 | 
						|
      (String == NULL)      ||
 | 
						|
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCodeGenString (String, &ObjectNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCodeGenName (
 | 
						|
             NameString,
 | 
						|
             ObjectNode,
 | 
						|
             ParentNode,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Name object node, containing an Integer.
 | 
						|
 | 
						|
  AmlCodeGenNameInteger ("_UID", 1, ParentNode, NewObjectNode) is
 | 
						|
  equivalent of the following ASL code:
 | 
						|
    Name(_UID, One)
 | 
						|
 | 
						|
  @param  [in] NameString     The new variable name.
 | 
						|
                              Must be a NULL-terminated ASL NameString
 | 
						|
                              e.g.: "DEV0", "DV15.DEV0", etc.
 | 
						|
                              The input string is copied.
 | 
						|
  @param [in]  Integer        Integer to associate to the NameString.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
  @param [out] NewObjectNode  If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenNameInteger (
 | 
						|
  IN  CONST CHAR8            *NameString,
 | 
						|
  IN        UINT64           Integer,
 | 
						|
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *ObjectNode;
 | 
						|
 | 
						|
  if ((NameString == NULL)  ||
 | 
						|
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCodeGenInteger (Integer, &ObjectNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCodeGenName (
 | 
						|
             NameString,
 | 
						|
             ObjectNode,
 | 
						|
             ParentNode,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Device object node.
 | 
						|
 | 
						|
  AmlCodeGenDevice ("COM0", ParentNode, NewObjectNode) is
 | 
						|
  equivalent of the following ASL code:
 | 
						|
    Device(COM0) {}
 | 
						|
 | 
						|
  @param  [in] NameString     The new Device's name.
 | 
						|
                              Must be a NULL-terminated ASL NameString
 | 
						|
                              e.g.: "DEV0", "DV15.DEV0", etc.
 | 
						|
                              The input string is copied.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
  @param [out] NewObjectNode  If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenDevice (
 | 
						|
  IN  CONST CHAR8            *NameString,
 | 
						|
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *ObjectNode;
 | 
						|
  AML_DATA_NODE    *DataNode;
 | 
						|
  CHAR8            *AmlNameString;
 | 
						|
  UINT32           AmlNameStringSize;
 | 
						|
 | 
						|
  if ((NameString == NULL)  ||
 | 
						|
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  ObjectNode    = NULL;
 | 
						|
  DataNode      = NULL;
 | 
						|
  AmlNameString = NULL;
 | 
						|
 | 
						|
  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler1;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateObjectNode (
 | 
						|
             AmlGetByteEncodingByOpCode (AML_EXT_OP, AML_EXT_DEVICE_OP),
 | 
						|
             AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),
 | 
						|
             &ObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler1;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateDataNode (
 | 
						|
             EAmlNodeDataTypeNameString,
 | 
						|
             (UINT8 *)AmlNameString,
 | 
						|
             AmlNameStringSize,
 | 
						|
             &DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             ObjectNode,
 | 
						|
             EAmlParseIndexTerm0,
 | 
						|
             (AML_NODE_HEADER *)DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = LinkNode (
 | 
						|
             ObjectNode,
 | 
						|
             ParentNode,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  // Free AmlNameString before returning as it is copied
 | 
						|
  // in the call to AmlCreateDataNode().
 | 
						|
  goto error_handler1;
 | 
						|
 | 
						|
error_handler2:
 | 
						|
  if (ObjectNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
 | 
						|
  }
 | 
						|
 | 
						|
error_handler1:
 | 
						|
  if (AmlNameString != NULL) {
 | 
						|
    FreePool (AmlNameString);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Scope object node.
 | 
						|
 | 
						|
  AmlCodeGenScope ("_SB", ParentNode, NewObjectNode) is
 | 
						|
  equivalent of the following ASL code:
 | 
						|
    Scope(_SB) {}
 | 
						|
 | 
						|
  @param  [in] NameString     The new Scope's name.
 | 
						|
                              Must be a NULL-terminated ASL NameString
 | 
						|
                              e.g.: "DEV0", "DV15.DEV0", etc.
 | 
						|
                              The input string is copied.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
  @param [out] NewObjectNode  If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenScope (
 | 
						|
  IN  CONST CHAR8            *NameString,
 | 
						|
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *ObjectNode;
 | 
						|
  AML_DATA_NODE    *DataNode;
 | 
						|
  CHAR8            *AmlNameString;
 | 
						|
  UINT32           AmlNameStringSize;
 | 
						|
 | 
						|
  if ((NameString == NULL)  ||
 | 
						|
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  ObjectNode    = NULL;
 | 
						|
  DataNode      = NULL;
 | 
						|
  AmlNameString = NULL;
 | 
						|
 | 
						|
  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler1;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateObjectNode (
 | 
						|
             AmlGetByteEncodingByOpCode (AML_SCOPE_OP, 0),
 | 
						|
             AmlNameStringSize + AmlComputePkgLengthWidth (AmlNameStringSize),
 | 
						|
             &ObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler1;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateDataNode (
 | 
						|
             EAmlNodeDataTypeNameString,
 | 
						|
             (UINT8 *)AmlNameString,
 | 
						|
             AmlNameStringSize,
 | 
						|
             &DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             ObjectNode,
 | 
						|
             EAmlParseIndexTerm0,
 | 
						|
             (AML_NODE_HEADER *)DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = LinkNode (
 | 
						|
             ObjectNode,
 | 
						|
             ParentNode,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  // Free AmlNameString before returning as it is copied
 | 
						|
  // in the call to AmlCreateDataNode().
 | 
						|
  goto error_handler1;
 | 
						|
 | 
						|
error_handler2:
 | 
						|
  if (ObjectNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
 | 
						|
  }
 | 
						|
 | 
						|
error_handler1:
 | 
						|
  if (AmlNameString != NULL) {
 | 
						|
    FreePool (AmlNameString);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Method object node.
 | 
						|
 | 
						|
  AmlCodeGenMethod ("MET0", 1, TRUE, 3, ParentNode, NewObjectNode) is
 | 
						|
  equivalent of the following ASL code:
 | 
						|
    Method(MET0, 1, Serialized, 3) {}
 | 
						|
 | 
						|
  ACPI 6.4, s20.2.5.2 "Named Objects Encoding":
 | 
						|
    DefMethod := MethodOp PkgLength NameString MethodFlags TermList
 | 
						|
    MethodOp := 0x14
 | 
						|
 | 
						|
  The ASL parameters "ReturnType" and "ParameterTypes" are not asked
 | 
						|
  in this function. They are optional parameters in ASL.
 | 
						|
 | 
						|
  @param [in]  NameString     The new Method's name.
 | 
						|
                              Must be a NULL-terminated ASL NameString
 | 
						|
                              e.g.: "MET0", "_SB.MET0", etc.
 | 
						|
                              The input string is copied.
 | 
						|
  @param [in]  NumArgs        Number of arguments.
 | 
						|
                              Must be 0 <= NumArgs <= 6.
 | 
						|
  @param [in]  IsSerialized   TRUE is equivalent to Serialized.
 | 
						|
                              FALSE is equivalent to NotSerialized.
 | 
						|
                              Default is NotSerialized in ASL spec.
 | 
						|
  @param [in]  SyncLevel      Synchronization level for the method.
 | 
						|
                              Must be 0 <= SyncLevel <= 15.
 | 
						|
                              Default is 0 in ASL.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
  @param [out] NewObjectNode  If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenMethod (
 | 
						|
  IN  CONST CHAR8            *NameString,
 | 
						|
  IN        UINT8            NumArgs,
 | 
						|
  IN        BOOLEAN          IsSerialized,
 | 
						|
  IN        UINT8            SyncLevel,
 | 
						|
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  UINT32           PkgLen;
 | 
						|
  UINT8            Flags;
 | 
						|
  AML_OBJECT_NODE  *ObjectNode;
 | 
						|
  AML_DATA_NODE    *DataNode;
 | 
						|
  CHAR8            *AmlNameString;
 | 
						|
  UINT32           AmlNameStringSize;
 | 
						|
 | 
						|
  if ((NameString == NULL)    ||
 | 
						|
      (NumArgs > 6)           ||
 | 
						|
      (SyncLevel > 15)        ||
 | 
						|
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  ObjectNode = NULL;
 | 
						|
  DataNode   = NULL;
 | 
						|
 | 
						|
  // ACPI 6.4, s20.2.5.2 "Named Objects Encoding":
 | 
						|
  //   DefMethod := MethodOp PkgLength NameString MethodFlags TermList
 | 
						|
  //   MethodOp := 0x14
 | 
						|
  // So:
 | 
						|
  //  1- Create the NameString
 | 
						|
  //  2- Compute the size to write in the PkgLen
 | 
						|
  //  3- Create nodes for the NameString and Method object node
 | 
						|
  //  4- Set the NameString DataNode as a fixed argument
 | 
						|
  //  5- Create and link the MethodFlags node
 | 
						|
 | 
						|
  // 1- Create the NameString
 | 
						|
  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler1;
 | 
						|
  }
 | 
						|
 | 
						|
  // 2- Compute the size to write in the PkgLen
 | 
						|
  //    Add 1 byte (ByteData) for MethodFlags.
 | 
						|
  Status = AmlComputePkgLength (AmlNameStringSize + 1, &PkgLen);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler1;
 | 
						|
  }
 | 
						|
 | 
						|
  //  3- Create nodes for the NameString and Method object node
 | 
						|
  Status = AmlCreateObjectNode (
 | 
						|
             AmlGetByteEncodingByOpCode (AML_METHOD_OP, 0),
 | 
						|
             PkgLen,
 | 
						|
             &ObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler1;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateDataNode (
 | 
						|
             EAmlNodeDataTypeNameString,
 | 
						|
             (UINT8 *)AmlNameString,
 | 
						|
             AmlNameStringSize,
 | 
						|
             &DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  //  4- Set the NameString DataNode as a fixed argument
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             ObjectNode,
 | 
						|
             EAmlParseIndexTerm0,
 | 
						|
             (AML_NODE_HEADER *)DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  DataNode = NULL;
 | 
						|
 | 
						|
  //  5- Create and link the MethodFlags node
 | 
						|
  Flags = NumArgs                   |
 | 
						|
          (IsSerialized ? BIT3 : 0) |
 | 
						|
          (SyncLevel << 4);
 | 
						|
 | 
						|
  Status = AmlCreateDataNode (EAmlNodeDataTypeUInt, &Flags, 1, &DataNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             ObjectNode,
 | 
						|
             EAmlParseIndexTerm1,
 | 
						|
             (AML_NODE_HEADER *)DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  // Data node is attached so set the pointer to
 | 
						|
  // NULL to ensure correct error handling.
 | 
						|
  DataNode = NULL;
 | 
						|
 | 
						|
  Status = LinkNode (
 | 
						|
             ObjectNode,
 | 
						|
             ParentNode,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler2;
 | 
						|
  }
 | 
						|
 | 
						|
  // Free AmlNameString before returning as it is copied
 | 
						|
  // in the call to AmlCreateDataNode().
 | 
						|
  goto error_handler1;
 | 
						|
 | 
						|
error_handler2:
 | 
						|
  if (ObjectNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
 | 
						|
  }
 | 
						|
 | 
						|
  if (DataNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)DataNode);
 | 
						|
  }
 | 
						|
 | 
						|
error_handler1:
 | 
						|
  if (AmlNameString != NULL) {
 | 
						|
    FreePool (AmlNameString);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Return object node.
 | 
						|
 | 
						|
  AmlCodeGenReturn (ReturnNode, ParentNode, NewObjectNode) is
 | 
						|
  equivalent of the following ASL code:
 | 
						|
    Return([Content of the ReturnNode])
 | 
						|
 | 
						|
  The ACPI 6.3 specification, s20.2.5.3 "Type 1 Opcodes Encoding" states:
 | 
						|
    DefReturn := ReturnOp ArgObject
 | 
						|
    ReturnOp := 0xA4
 | 
						|
    ArgObject := TermArg => DataRefObject
 | 
						|
 | 
						|
  Thus, the ReturnNode must be evaluated as a DataRefObject. It can
 | 
						|
  be a NameString referencing an object. As this CodeGen Api doesn't
 | 
						|
  do semantic checking, it is strongly advised to check the AML bytecode
 | 
						|
  generated by this function against an ASL compiler.
 | 
						|
 | 
						|
  The ReturnNode must be generated inside a Method body scope.
 | 
						|
 | 
						|
  @param [in]  ReturnNode     The object returned by the Return ASL statement.
 | 
						|
                              This node is deleted if an error occurs.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
                              Must be a MethodOp node.
 | 
						|
  @param [out] NewObjectNode  If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenReturn (
 | 
						|
  IN  AML_NODE_HEADER  *ReturnNode,
 | 
						|
  IN  AML_NODE_HEADER  *ParentNode      OPTIONAL,
 | 
						|
  OUT AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS       Status;
 | 
						|
  AML_OBJECT_NODE  *ObjectNode;
 | 
						|
 | 
						|
  if ((ReturnNode == NULL)                              ||
 | 
						|
      ((ParentNode == NULL) && (NewObjectNode == NULL)) ||
 | 
						|
      ((ParentNode != NULL) &&
 | 
						|
       !AmlNodeCompareOpCode (
 | 
						|
          (AML_OBJECT_NODE *)ParentNode,
 | 
						|
          AML_METHOD_OP,
 | 
						|
          0
 | 
						|
          )))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateObjectNode (
 | 
						|
             AmlGetByteEncodingByOpCode (AML_RETURN_OP, 0),
 | 
						|
             0,
 | 
						|
             &ObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlSetFixedArgument (
 | 
						|
             ObjectNode,
 | 
						|
             EAmlParseIndexTerm0,
 | 
						|
             (AML_NODE_HEADER *)ReturnNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  ReturnNode = NULL;
 | 
						|
 | 
						|
  Status = LinkNode (
 | 
						|
             ObjectNode,
 | 
						|
             ParentNode,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
 | 
						|
error_handler:
 | 
						|
  if (ReturnNode != NULL) {
 | 
						|
    AmlDeleteTree (ReturnNode);
 | 
						|
  }
 | 
						|
 | 
						|
  if (ObjectNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HEADER *)ObjectNode);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a Return object node,
 | 
						|
    returning the object as an input NameString.
 | 
						|
 | 
						|
  AmlCodeGenReturn ("NAM1", ParentNode, NewObjectNode) is
 | 
						|
  equivalent of the following ASL code:
 | 
						|
    Return(NAM1)
 | 
						|
 | 
						|
  The ACPI 6.3 specification, s20.2.5.3 "Type 1 Opcodes Encoding" states:
 | 
						|
    DefReturn := ReturnOp ArgObject
 | 
						|
    ReturnOp := 0xA4
 | 
						|
    ArgObject := TermArg => DataRefObject
 | 
						|
 | 
						|
  Thus, the ReturnNode must be evaluated as a DataRefObject. It can
 | 
						|
  be a NameString referencing an object. As this CodeGen Api doesn't
 | 
						|
  do semantic checking, it is strongly advised to check the AML bytecode
 | 
						|
  generated by this function against an ASL compiler.
 | 
						|
 | 
						|
  The ReturnNode must be generated inside a Method body scope.
 | 
						|
 | 
						|
  @param [in]  NameString     The object referenced by this NameString
 | 
						|
                              is returned by the Return ASL statement.
 | 
						|
                              Must be a NULL-terminated ASL NameString
 | 
						|
                              e.g.: "NAM1", "_SB.NAM1", etc.
 | 
						|
                              The input string is copied.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
                              Must be a MethodOp node.
 | 
						|
  @param [out] NewObjectNode  If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenReturnNameString (
 | 
						|
  IN  CONST CHAR8            *NameString,
 | 
						|
  IN        AML_NODE_HEADER  *ParentNode      OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE  **NewObjectNode   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS     Status;
 | 
						|
  AML_DATA_NODE  *DataNode;
 | 
						|
  CHAR8          *AmlNameString;
 | 
						|
  UINT32         AmlNameStringSize;
 | 
						|
 | 
						|
  DataNode = NULL;
 | 
						|
 | 
						|
  Status = ConvertAslNameToAmlName (NameString, &AmlNameString);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlGetNameStringSize (AmlNameString, &AmlNameStringSize);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto exit_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCreateDataNode (
 | 
						|
             EAmlNodeDataTypeNameString,
 | 
						|
             (UINT8 *)AmlNameString,
 | 
						|
             AmlNameStringSize,
 | 
						|
             &DataNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto exit_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  // AmlCodeGenReturn() deletes DataNode if error.
 | 
						|
  Status = AmlCodeGenReturn (
 | 
						|
             (AML_NODE_HEADER *)DataNode,
 | 
						|
             ParentNode,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
exit_handler:
 | 
						|
  if (AmlNameString != NULL) {
 | 
						|
    FreePool (AmlNameString);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** AML code generation for a method returning a NameString.
 | 
						|
 | 
						|
  AmlCodeGenMethodRetNameString (
 | 
						|
    "MET0", "_CRS", 1, TRUE, 3, ParentNode, NewObjectNode
 | 
						|
    );
 | 
						|
  is equivalent of the following ASL code:
 | 
						|
    Method(MET0, 1, Serialized, 3) {
 | 
						|
      Return (_CRS)
 | 
						|
    }
 | 
						|
 | 
						|
  The ASL parameters "ReturnType" and "ParameterTypes" are not asked
 | 
						|
  in this function. They are optional parameters in ASL.
 | 
						|
 | 
						|
  @param [in]  MethodNameString     The new Method's name.
 | 
						|
                                    Must be a NULL-terminated ASL NameString
 | 
						|
                                    e.g.: "MET0", "_SB.MET0", etc.
 | 
						|
                                    The input string is copied.
 | 
						|
  @param [in]  ReturnedNameString   The name of the object returned by the
 | 
						|
                                    method. Optional parameter, can be:
 | 
						|
                                     - NULL (ignored).
 | 
						|
                                     - A NULL-terminated ASL NameString.
 | 
						|
                                       e.g.: "MET0", "_SB.MET0", etc.
 | 
						|
                                       The input string is copied.
 | 
						|
  @param [in]  NumArgs              Number of arguments.
 | 
						|
                                    Must be 0 <= NumArgs <= 6.
 | 
						|
  @param [in]  IsSerialized         TRUE is equivalent to Serialized.
 | 
						|
                                    FALSE is equivalent to NotSerialized.
 | 
						|
                                    Default is NotSerialized in ASL spec.
 | 
						|
  @param [in]  SyncLevel            Synchronization level for the method.
 | 
						|
                                    Must be 0 <= SyncLevel <= 15.
 | 
						|
                                    Default is 0 in ASL.
 | 
						|
  @param [in]  ParentNode           If provided, set ParentNode as the parent
 | 
						|
                                    of the node created.
 | 
						|
  @param [out] NewObjectNode        If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Success.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCodeGenMethodRetNameString (
 | 
						|
  IN  CONST CHAR8                   *MethodNameString,
 | 
						|
  IN  CONST CHAR8                   *ReturnedNameString   OPTIONAL,
 | 
						|
  IN        UINT8                   NumArgs,
 | 
						|
  IN        BOOLEAN                 IsSerialized,
 | 
						|
  IN        UINT8                   SyncLevel,
 | 
						|
  IN        AML_NODE_HANDLE         ParentNode           OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE_HANDLE  *NewObjectNode        OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS              Status;
 | 
						|
  AML_OBJECT_NODE_HANDLE  MethodNode;
 | 
						|
 | 
						|
  if ((MethodNameString == NULL)  ||
 | 
						|
      ((ParentNode == NULL) && (NewObjectNode == NULL)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  // Create a Method named MethodNameString.
 | 
						|
  Status = AmlCodeGenMethod (
 | 
						|
             MethodNameString,
 | 
						|
             NumArgs,
 | 
						|
             IsSerialized,
 | 
						|
             SyncLevel,
 | 
						|
             NULL,
 | 
						|
             &MethodNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // Return ReturnedNameString if provided.
 | 
						|
  if (ReturnedNameString != NULL) {
 | 
						|
    Status = AmlCodeGenReturnNameString (
 | 
						|
               ReturnedNameString,
 | 
						|
               (AML_NODE_HANDLE)MethodNode,
 | 
						|
               NULL
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Status = LinkNode (
 | 
						|
             MethodNode,
 | 
						|
             ParentNode,
 | 
						|
             NewObjectNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
 | 
						|
error_handler:
 | 
						|
  if (MethodNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HANDLE)MethodNode);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** Create a _LPI name.
 | 
						|
 | 
						|
  AmlCreateLpiNode ("_LPI", 0, 1, ParentNode, &LpiNode) is
 | 
						|
  equivalent of the following ASL code:
 | 
						|
    Name (_LPI, Package (
 | 
						|
                  0,  // Revision
 | 
						|
                  1,  // LevelId
 | 
						|
                  0   // Count
 | 
						|
                  ))
 | 
						|
 | 
						|
  This function doesn't define any LPI state. As shown above, the count
 | 
						|
  of _LPI state is set to 0.
 | 
						|
  The AmlAddLpiState () function allows to add LPI states.
 | 
						|
 | 
						|
  Cf ACPI 6.3 specification, s8.4.4 "Lower Power Idle States".
 | 
						|
 | 
						|
  @param [in]  LpiNameString  The new LPI 's object name.
 | 
						|
                              Must be a NULL-terminated ASL NameString
 | 
						|
                              e.g.: "_LPI", "DEV0.PLPI", etc.
 | 
						|
                              The input string is copied.
 | 
						|
  @param [in]  Revision       Revision number of the _LPI states.
 | 
						|
  @param [in]  LevelId        A platform defined number that identifies the
 | 
						|
                              level of hierarchy of the processor node to
 | 
						|
                              which the LPI states apply.
 | 
						|
  @param [in]  ParentNode     If provided, set ParentNode as the parent
 | 
						|
                              of the node created.
 | 
						|
  @param [out] NewLpiNode     If success, contains the created node.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The function completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlCreateLpiNode (
 | 
						|
  IN  CONST CHAR8                   *LpiNameString,
 | 
						|
  IN        UINT16                  Revision,
 | 
						|
  IN        UINT64                  LevelId,
 | 
						|
  IN        AML_NODE_HANDLE         ParentNode   OPTIONAL,
 | 
						|
  OUT       AML_OBJECT_NODE_HANDLE  *NewLpiNode   OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS              Status;
 | 
						|
  AML_OBJECT_NODE_HANDLE  PackageNode;
 | 
						|
  AML_OBJECT_NODE_HANDLE  IntegerNode;
 | 
						|
 | 
						|
  if ((LpiNameString == NULL)                           ||
 | 
						|
      ((ParentNode == NULL) && (NewLpiNode == NULL)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  Status = AmlCodeGenPackage (&PackageNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // Create and attach Revision
 | 
						|
  Status = AmlCodeGenInteger (Revision, &IntegerNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    IntegerNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)PackageNode,
 | 
						|
             (AML_NODE_HANDLE)IntegerNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  // Create and attach LevelId
 | 
						|
  Status = AmlCodeGenInteger (LevelId, &IntegerNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    IntegerNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)PackageNode,
 | 
						|
             (AML_NODE_HANDLE)IntegerNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  // Create and attach Count. No LPI state is added, so 0.
 | 
						|
  Status = AmlCodeGenInteger (0, &IntegerNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    IntegerNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)PackageNode,
 | 
						|
             (AML_NODE_HANDLE)IntegerNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  Status = AmlCodeGenName (LpiNameString, PackageNode, ParentNode, NewLpiNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
 | 
						|
error_handler:
 | 
						|
  AmlDeleteTree ((AML_NODE_HANDLE)PackageNode);
 | 
						|
  if (IntegerNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/** Add an _LPI state to a LPI node created using AmlCreateLpiNode.
 | 
						|
 | 
						|
  AmlAddLpiState increments the Count of LPI states in the LPI node by one,
 | 
						|
  and adds the following package:
 | 
						|
    Package() {
 | 
						|
      MinResidency,
 | 
						|
      WorstCaseWakeLatency,
 | 
						|
      Flags,
 | 
						|
      ArchFlags,
 | 
						|
      ResCntFreq,
 | 
						|
      EnableParentState,
 | 
						|
      (GenericRegisterDescriptor != NULL) ?           // Entry method. If a
 | 
						|
        ResourceTemplate(GenericRegisterDescriptor) : // Register is given,
 | 
						|
        Integer,                                      // use it. Use the
 | 
						|
                                                      // Integer otherwise.
 | 
						|
      ResourceTemplate() {                            // NULL Residency Counter
 | 
						|
        Register (SystemMemory, 0, 0, 0, 0)
 | 
						|
      },
 | 
						|
      ResourceTemplate() {                            // NULL Usage Counter
 | 
						|
        Register (SystemMemory, 0, 0, 0, 0)
 | 
						|
      },
 | 
						|
      ""                                              // NULL State Name
 | 
						|
    },
 | 
						|
 | 
						|
  Cf ACPI 6.3 specification, s8.4.4 "Lower Power Idle States".
 | 
						|
 | 
						|
  @param [in]  MinResidency               Minimum Residency.
 | 
						|
  @param [in]  WorstCaseWakeLatency       Worst case wake-up latency.
 | 
						|
  @param [in]  Flags                      Flags.
 | 
						|
  @param [in]  ArchFlags                  Architectural flags.
 | 
						|
  @param [in]  ResCntFreq                 Residency Counter Frequency.
 | 
						|
  @param [in]  EnableParentState          Enabled Parent State.
 | 
						|
  @param [in]  GenericRegisterDescriptor  Entry Method.
 | 
						|
                                          If not NULL, use this Register to
 | 
						|
                                          describe the entry method address.
 | 
						|
  @param [in]  Integer                    Entry Method.
 | 
						|
                                          If GenericRegisterDescriptor is NULL,
 | 
						|
                                          take this value.
 | 
						|
  @param [in]  ResidencyCounterRegister   If not NULL, use it to populate the
 | 
						|
                                          residency counter register.
 | 
						|
  @param [in]  UsageCounterRegister       If not NULL, use it to populate the
 | 
						|
                                          usage counter register.
 | 
						|
  @param [in]  StateName                  If not NULL, use it to populate the
 | 
						|
                                          state name.
 | 
						|
  @param [in]  LpiNode                    Lpi node created with the function
 | 
						|
                                          AmlCreateLpiNode to which the new LPI
 | 
						|
                                          state is appended.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The function completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlAddLpiState (
 | 
						|
  IN  UINT32                                  MinResidency,
 | 
						|
  IN  UINT32                                  WorstCaseWakeLatency,
 | 
						|
  IN  UINT32                                  Flags,
 | 
						|
  IN  UINT32                                  ArchFlags,
 | 
						|
  IN  UINT32                                  ResCntFreq,
 | 
						|
  IN  UINT32                                  EnableParentState,
 | 
						|
  IN  EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  *GenericRegisterDescriptor   OPTIONAL,
 | 
						|
  IN  UINT64                                  Integer                     OPTIONAL,
 | 
						|
  IN  EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  *ResidencyCounterRegister    OPTIONAL,
 | 
						|
  IN  EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  *UsageCounterRegister        OPTIONAL,
 | 
						|
  IN  CHAR8                                   *StateName                   OPTIONAL,
 | 
						|
  IN  AML_OBJECT_NODE_HANDLE                  LpiNode
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS              Status;
 | 
						|
  AML_DATA_NODE_HANDLE    RdNode;
 | 
						|
  AML_OBJECT_NODE_HANDLE  PackageNode;
 | 
						|
  AML_OBJECT_NODE_HANDLE  IntegerNode;
 | 
						|
  AML_OBJECT_NODE_HANDLE  StringNode;
 | 
						|
  AML_OBJECT_NODE_HANDLE  NewLpiPackageNode;
 | 
						|
  AML_OBJECT_NODE_HANDLE  ResourceTemplateNode;
 | 
						|
 | 
						|
  UINT32                  Index;
 | 
						|
  AML_OBJECT_NODE_HANDLE  CountNode;
 | 
						|
  UINT64                  Count;
 | 
						|
 | 
						|
  if ((LpiNode == NULL)                                              ||
 | 
						|
      (AmlGetNodeType ((AML_NODE_HANDLE)LpiNode) != EAmlNodeObject)  ||
 | 
						|
      (!AmlNodeHasOpCode (LpiNode, AML_NAME_OP, 0)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  RdNode               = 0;
 | 
						|
  StringNode           = NULL;
 | 
						|
  IntegerNode          = NULL;
 | 
						|
  ResourceTemplateNode = NULL;
 | 
						|
 | 
						|
  // AmlCreateLpiNode () created a LPI container such as:
 | 
						|
  //  Name (_LPI, Package (
 | 
						|
  //                0,  // Revision
 | 
						|
  //                1,  // LevelId
 | 
						|
  //                0   // Count
 | 
						|
  //                ))
 | 
						|
  // Get the LPI container, a PackageOp object node stored as the 2nd fixed
 | 
						|
  // argument (i.e. index 1) of LpiNode.
 | 
						|
  PackageNode = (AML_OBJECT_NODE_HANDLE)AmlGetFixedArgument (
 | 
						|
                                          LpiNode,
 | 
						|
                                          EAmlParseIndexTerm1
 | 
						|
                                          );
 | 
						|
  if ((PackageNode == NULL)                                             ||
 | 
						|
      (AmlGetNodeType ((AML_NODE_HANDLE)PackageNode) != EAmlNodeObject) ||
 | 
						|
      (!AmlNodeHasOpCode (PackageNode, AML_PACKAGE_OP, 0)))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  CountNode = NULL;
 | 
						|
  // The third variable argument is the LPI Count node.
 | 
						|
  for (Index = 0; Index < 3; Index++) {
 | 
						|
    CountNode = (AML_OBJECT_NODE_HANDLE)AmlGetNextVariableArgument (
 | 
						|
                                          (AML_NODE_HANDLE)PackageNode,
 | 
						|
                                          (AML_NODE_HANDLE)CountNode
 | 
						|
                                          );
 | 
						|
    if (CountNode == NULL) {
 | 
						|
      ASSERT (0);
 | 
						|
      return EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlNodeGetIntegerValue (CountNode, &Count);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlUpdateInteger (CountNode, Count + 1);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlCodeGenPackage (&NewLpiPackageNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // MinResidency
 | 
						|
  Status = AmlCodeGenInteger (MinResidency, &IntegerNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    IntegerNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
             (AML_NODE_HANDLE)IntegerNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  // WorstCaseWakeLatency
 | 
						|
  Status = AmlCodeGenInteger (WorstCaseWakeLatency, &IntegerNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    IntegerNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
             (AML_NODE_HANDLE)IntegerNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  // Flags
 | 
						|
  Status = AmlCodeGenInteger (Flags, &IntegerNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    IntegerNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
             (AML_NODE_HANDLE)IntegerNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  // ArchFlags
 | 
						|
  Status = AmlCodeGenInteger (ArchFlags, &IntegerNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    IntegerNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
             (AML_NODE_HANDLE)IntegerNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  // ResCntFreq
 | 
						|
  Status = AmlCodeGenInteger (ResCntFreq, &IntegerNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    IntegerNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
             (AML_NODE_HANDLE)IntegerNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  // EnableParentState
 | 
						|
  Status = AmlCodeGenInteger (EnableParentState, &IntegerNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    IntegerNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
             (AML_NODE_HANDLE)IntegerNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  IntegerNode = NULL;
 | 
						|
 | 
						|
  // Entry Method
 | 
						|
  if (GenericRegisterDescriptor != NULL) {
 | 
						|
    // Entry Method: As a Register resource data
 | 
						|
    Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      ResourceTemplateNode = NULL;
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = AmlCodeGenRdRegister (
 | 
						|
               GenericRegisterDescriptor->AddressSpaceId,
 | 
						|
               GenericRegisterDescriptor->RegisterBitWidth,
 | 
						|
               GenericRegisterDescriptor->RegisterBitOffset,
 | 
						|
               GenericRegisterDescriptor->Address,
 | 
						|
               GenericRegisterDescriptor->AccessSize,
 | 
						|
               NULL,
 | 
						|
               &RdNode
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      RdNode = NULL;
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
 | 
						|
    RdNode = NULL;
 | 
						|
 | 
						|
    Status = AmlVarListAddTail (
 | 
						|
               (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
               (AML_NODE_HANDLE)ResourceTemplateNode
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
 | 
						|
    ResourceTemplateNode = NULL;
 | 
						|
  } else {
 | 
						|
    // Entry Method: As an integer
 | 
						|
    Status = AmlCodeGenInteger (Integer, &IntegerNode);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      IntegerNode = NULL;
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = AmlVarListAddTail (
 | 
						|
               (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
               (AML_NODE_HANDLE)IntegerNode
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
 | 
						|
    IntegerNode = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  // Residency Counter Register.
 | 
						|
  Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    ResourceTemplateNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  if (ResidencyCounterRegister != NULL) {
 | 
						|
    Status = AmlCodeGenRdRegister (
 | 
						|
               ResidencyCounterRegister->AddressSpaceId,
 | 
						|
               ResidencyCounterRegister->RegisterBitWidth,
 | 
						|
               ResidencyCounterRegister->RegisterBitOffset,
 | 
						|
               ResidencyCounterRegister->Address,
 | 
						|
               ResidencyCounterRegister->AccessSize,
 | 
						|
               NULL,
 | 
						|
               &RdNode
 | 
						|
               );
 | 
						|
  } else {
 | 
						|
    Status = AmlCodeGenRdRegister (
 | 
						|
               EFI_ACPI_6_4_SYSTEM_MEMORY,
 | 
						|
               0,
 | 
						|
               0,
 | 
						|
               0,
 | 
						|
               0,
 | 
						|
               NULL,
 | 
						|
               &RdNode
 | 
						|
               );
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    RdNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  RdNode = NULL;
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
             (AML_NODE_HANDLE)ResourceTemplateNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  ResourceTemplateNode = NULL;
 | 
						|
 | 
						|
  // Usage Counter Register.
 | 
						|
  Status = AmlCodeGenResourceTemplate (&ResourceTemplateNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    ResourceTemplateNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  if (UsageCounterRegister != NULL) {
 | 
						|
    Status = AmlCodeGenRdRegister (
 | 
						|
               UsageCounterRegister->AddressSpaceId,
 | 
						|
               UsageCounterRegister->RegisterBitWidth,
 | 
						|
               UsageCounterRegister->RegisterBitOffset,
 | 
						|
               UsageCounterRegister->Address,
 | 
						|
               UsageCounterRegister->AccessSize,
 | 
						|
               NULL,
 | 
						|
               &RdNode
 | 
						|
               );
 | 
						|
  } else {
 | 
						|
    Status = AmlCodeGenRdRegister (
 | 
						|
               EFI_ACPI_6_4_SYSTEM_MEMORY,
 | 
						|
               0,
 | 
						|
               0,
 | 
						|
               0,
 | 
						|
               0,
 | 
						|
               NULL,
 | 
						|
               &RdNode
 | 
						|
               );
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    RdNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlAppendRdNode (ResourceTemplateNode, RdNode);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  RdNode = NULL;
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
             (AML_NODE_HANDLE)ResourceTemplateNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  ResourceTemplateNode = NULL;
 | 
						|
 | 
						|
  // State name.
 | 
						|
  if (UsageCounterRegister != NULL) {
 | 
						|
    Status = AmlCodeGenString (StateName, &StringNode);
 | 
						|
  } else {
 | 
						|
    Status = AmlCodeGenString ("", &StringNode);
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    StringNode = NULL;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode,
 | 
						|
             (AML_NODE_HANDLE)StringNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  StringNode = NULL;
 | 
						|
 | 
						|
  // Add the new LPI state to the LpiNode.
 | 
						|
  Status = AmlVarListAddTail (
 | 
						|
             (AML_NODE_HANDLE)PackageNode,
 | 
						|
             (AML_NODE_HANDLE)NewLpiPackageNode
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
 | 
						|
error_handler:
 | 
						|
  if (RdNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HANDLE)RdNode);
 | 
						|
  }
 | 
						|
 | 
						|
  if (NewLpiPackageNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HANDLE)NewLpiPackageNode);
 | 
						|
  }
 | 
						|
 | 
						|
  if (StringNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HANDLE)StringNode);
 | 
						|
  }
 | 
						|
 | 
						|
  if (IntegerNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HANDLE)IntegerNode);
 | 
						|
  }
 | 
						|
 | 
						|
  if (ResourceTemplateNode != NULL) {
 | 
						|
    AmlDeleteTree ((AML_NODE_HANDLE)ResourceTemplateNode);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 |