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>
		
			
				
	
	
		
			332 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			332 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  AML Serialize.
 | 
						|
 | 
						|
  Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
**/
 | 
						|
 | 
						|
#include <AmlNodeDefines.h>
 | 
						|
 | 
						|
#include <AmlCoreInterface.h>
 | 
						|
#include <Stream/AmlStream.h>
 | 
						|
#include <Tree/AmlNode.h>
 | 
						|
#include <Tree/AmlTree.h>
 | 
						|
#include <Utils/AmlUtility.h>
 | 
						|
 | 
						|
/** Callback function to copy the AML bytecodes contained in a node
 | 
						|
    to the Stream stored in the Context.
 | 
						|
    The SDT header data contained in the root node is not serialized
 | 
						|
    by this function.
 | 
						|
 | 
						|
  @param  [in]      Node      Pointer to the node to copy the AML bytecodes
 | 
						|
                              from.
 | 
						|
  @param  [in, out] Context   Contains a forward Stream to write to.
 | 
						|
                              (AML_STREAM*)Context.
 | 
						|
  @param  [in, out] Status    At entry, contains the status returned by the
 | 
						|
                              last call to this exact function during the
 | 
						|
                              enumeration.
 | 
						|
                              As exit, contains the returned status of the
 | 
						|
                              call to this function.
 | 
						|
                              Optional, can be NULL.
 | 
						|
 | 
						|
  @retval TRUE if the enumeration can continue or has finished without
 | 
						|
          interruption.
 | 
						|
  @retval FALSE if the enumeration needs to stopped or has stopped.
 | 
						|
**/
 | 
						|
STATIC
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
AmlSerializeNodeCallback (
 | 
						|
  IN       AML_NODE_HEADER  *Node,
 | 
						|
  IN  OUT  VOID             *Context     OPTIONAL,
 | 
						|
  IN  OUT  EFI_STATUS       *Status      OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status1;
 | 
						|
 | 
						|
  CONST AML_DATA_NODE    *DataNode;
 | 
						|
  CONST AML_OBJECT_NODE  *ObjectNode;
 | 
						|
  AML_STREAM             *FStream;
 | 
						|
 | 
						|
  // Bytes needed to store OpCode[1] + SubOpcode[1] + MaxPkgLen[4] = 6 bytes.
 | 
						|
  UINT8    ObjectNodeInfoArray[6];
 | 
						|
  UINT32   Index;
 | 
						|
  BOOLEAN  ContinueEnum;
 | 
						|
 | 
						|
  CONST AML_OBJECT_NODE  *ParentNode;
 | 
						|
  EAML_PARSE_INDEX       IndexPtr;
 | 
						|
 | 
						|
  if (!IS_AML_NODE_VALID (Node)   ||
 | 
						|
      (Context == NULL))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    Status1      = EFI_INVALID_PARAMETER;
 | 
						|
    ContinueEnum = FALSE;
 | 
						|
    goto error_handler;
 | 
						|
  }
 | 
						|
 | 
						|
  // Ignore the second fixed argument of method invocation nodes
 | 
						|
  // as the information stored there (the argument count) is not in the
 | 
						|
  // ACPI specification.
 | 
						|
  ParentNode = (CONST AML_OBJECT_NODE *)AmlGetParent ((AML_NODE_HEADER *)Node);
 | 
						|
  if (IS_AML_OBJECT_NODE (ParentNode)                             &&
 | 
						|
      AmlNodeCompareOpCode (ParentNode, AML_METHOD_INVOC_OP, 0)   &&
 | 
						|
      AmlIsNodeFixedArgument (Node, &IndexPtr))
 | 
						|
  {
 | 
						|
    if (IndexPtr == EAmlParseIndexTerm1) {
 | 
						|
      if (Status != NULL) {
 | 
						|
        *Status = EFI_SUCCESS;
 | 
						|
      }
 | 
						|
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Status1      = EFI_SUCCESS;
 | 
						|
  ContinueEnum = TRUE;
 | 
						|
  FStream      = (AML_STREAM *)Context;
 | 
						|
 | 
						|
  if (IS_AML_DATA_NODE (Node)) {
 | 
						|
    // Copy the content of the Buffer for a DataNode.
 | 
						|
    DataNode = (AML_DATA_NODE *)Node;
 | 
						|
    Status1  = AmlStreamWrite (
 | 
						|
                 FStream,
 | 
						|
                 DataNode->Buffer,
 | 
						|
                 DataNode->Size
 | 
						|
                 );
 | 
						|
    if (EFI_ERROR (Status1)) {
 | 
						|
      ASSERT (0);
 | 
						|
      ContinueEnum = FALSE;
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
  } else if (IS_AML_OBJECT_NODE (Node)  &&
 | 
						|
             !AmlNodeHasAttribute (
 | 
						|
                (CONST AML_OBJECT_NODE *)Node,
 | 
						|
                AML_IS_PSEUDO_OPCODE
 | 
						|
                ))
 | 
						|
  {
 | 
						|
    // Ignore pseudo-opcodes as they are not part of the
 | 
						|
    // ACPI specification.
 | 
						|
 | 
						|
    ObjectNode = (AML_OBJECT_NODE *)Node;
 | 
						|
 | 
						|
    Index = 0;
 | 
						|
    // Copy the opcode(s).
 | 
						|
    ObjectNodeInfoArray[Index++] = ObjectNode->AmlByteEncoding->OpCode;
 | 
						|
    if (ObjectNode->AmlByteEncoding->OpCode == AML_EXT_OP) {
 | 
						|
      ObjectNodeInfoArray[Index++] = ObjectNode->AmlByteEncoding->SubOpCode;
 | 
						|
    }
 | 
						|
 | 
						|
    // Copy the PkgLen.
 | 
						|
    if (AmlNodeHasAttribute (ObjectNode, AML_HAS_PKG_LENGTH)) {
 | 
						|
      Index += AmlSetPkgLength (
 | 
						|
                 ObjectNode->PkgLen,
 | 
						|
                 &ObjectNodeInfoArray[Index]
 | 
						|
                 );
 | 
						|
    }
 | 
						|
 | 
						|
    Status1 = AmlStreamWrite (
 | 
						|
                FStream,
 | 
						|
                ObjectNodeInfoArray,
 | 
						|
                Index
 | 
						|
                );
 | 
						|
    if (EFI_ERROR (Status1)) {
 | 
						|
      ASSERT (0);
 | 
						|
      ContinueEnum = FALSE;
 | 
						|
      goto error_handler;
 | 
						|
    }
 | 
						|
  } // IS_AML_OBJECT_NODE (Node)
 | 
						|
 | 
						|
error_handler:
 | 
						|
  if (Status != NULL) {
 | 
						|
    *Status = Status1;
 | 
						|
  }
 | 
						|
 | 
						|
  return ContinueEnum;
 | 
						|
}
 | 
						|
 | 
						|
/** Serialize a tree to create an ACPI DSDT/SSDT table.
 | 
						|
 | 
						|
  If:
 | 
						|
   - the content of BufferSize is >= to the size needed to serialize the
 | 
						|
     definition block;
 | 
						|
   - Buffer is not NULL;
 | 
						|
  first serialize the ACPI DSDT/SSDT header from the root node,
 | 
						|
  then serialize the AML blob from the rest of the tree.
 | 
						|
 | 
						|
  The content of BufferSize is always updated to the size needed to
 | 
						|
  serialize the definition block.
 | 
						|
 | 
						|
  @param  [in]      RootNode    Pointer to a root node.
 | 
						|
  @param  [in]      Buffer      Buffer to write the DSDT/SSDT table to.
 | 
						|
                                If Buffer is NULL, the size needed to
 | 
						|
                                serialize the DSDT/SSDT table is returned
 | 
						|
                                in BufferSize.
 | 
						|
  @param  [in, out] BufferSize  Pointer holding the size of the Buffer.
 | 
						|
                                Its content is always updated to the size
 | 
						|
                                needed to serialize the DSDT/SSDT table.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             The function completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | 
						|
  @retval EFI_BUFFER_TOO_SMALL    No space left in the buffer.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
AmlSerializeTree (
 | 
						|
  IN      AML_ROOT_NODE  *RootNode,
 | 
						|
  IN      UINT8          *Buffer      OPTIONAL,
 | 
						|
  IN  OUT UINT32         *BufferSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  AML_STREAM  FStream;
 | 
						|
  UINT32      TableSize;
 | 
						|
 | 
						|
  if (!IS_AML_ROOT_NODE (RootNode) ||
 | 
						|
      (BufferSize == NULL))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  // Compute the total size of the AML blob.
 | 
						|
  Status = AmlComputeSize (
 | 
						|
             (CONST AML_NODE_HEADER *)RootNode,
 | 
						|
             &TableSize
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // Add the size of the ACPI header.
 | 
						|
  TableSize += (UINT32)sizeof (EFI_ACPI_DESCRIPTION_HEADER);
 | 
						|
 | 
						|
  // Check the size against the SDT header.
 | 
						|
  // The Length field in the SDT Header is updated if the tree has
 | 
						|
  // been modified.
 | 
						|
  if (TableSize != RootNode->SdtHeader->Length) {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  // Buffer is not big enough, or NULL.
 | 
						|
  if ((TableSize < *BufferSize) || (Buffer == NULL)) {
 | 
						|
    *BufferSize = TableSize;
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  // Initialize the stream to the TableSize that is needed.
 | 
						|
  Status = AmlStreamInit (
 | 
						|
             &FStream,
 | 
						|
             Buffer,
 | 
						|
             TableSize,
 | 
						|
             EAmlStreamDirectionForward
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // Serialize the header.
 | 
						|
  Status = AmlStreamWrite (
 | 
						|
             &FStream,
 | 
						|
             (UINT8 *)RootNode->SdtHeader,
 | 
						|
             sizeof (EFI_ACPI_DESCRIPTION_HEADER)
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  AmlEnumTree (
 | 
						|
    (AML_NODE_HEADER *)RootNode,
 | 
						|
    AmlSerializeNodeCallback,
 | 
						|
    (VOID *)&FStream,
 | 
						|
    &Status
 | 
						|
    );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  // Update the checksum.
 | 
						|
  return AcpiPlatformChecksum ((EFI_ACPI_DESCRIPTION_HEADER *)Buffer);
 | 
						|
}
 | 
						|
 | 
						|
/** Serialize an AML definition block.
 | 
						|
 | 
						|
  This functions allocates memory with the "AllocateZeroPool ()"
 | 
						|
  function. This memory is used to serialize the AML tree and is
 | 
						|
  returned in the Table.
 | 
						|
 | 
						|
  @param [in]  RootNode         Root node of the tree.
 | 
						|
  @param [out] Table            On return, hold the serialized
 | 
						|
                                definition block.
 | 
						|
 | 
						|
  @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
 | 
						|
AmlSerializeDefinitionBlock (
 | 
						|
  IN  AML_ROOT_NODE                *RootNode,
 | 
						|
  OUT EFI_ACPI_DESCRIPTION_HEADER  **Table
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINT8       *TableBuffer;
 | 
						|
  UINT32      TableSize;
 | 
						|
 | 
						|
  if (!IS_AML_ROOT_NODE (RootNode) ||
 | 
						|
      (Table == NULL))
 | 
						|
  {
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  *Table      = NULL;
 | 
						|
  TableBuffer = NULL;
 | 
						|
  TableSize   = 0;
 | 
						|
 | 
						|
  // Get the size of the SSDT table.
 | 
						|
  Status = AmlSerializeTree (
 | 
						|
             RootNode,
 | 
						|
             TableBuffer,
 | 
						|
             &TableSize
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ASSERT (0);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  TableBuffer = (UINT8 *)AllocateZeroPool (TableSize);
 | 
						|
  if (TableBuffer == NULL) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_ERROR,
 | 
						|
      "ERROR: Failed to allocate memory for Table Buffer."
 | 
						|
      ));
 | 
						|
    ASSERT (0);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  // Serialize the tree to a SSDT table.
 | 
						|
  Status = AmlSerializeTree (
 | 
						|
             RootNode,
 | 
						|
             TableBuffer,
 | 
						|
             &TableSize
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    FreePool (TableBuffer);
 | 
						|
    ASSERT (0);
 | 
						|
  } else {
 | 
						|
    // Save the allocated Table buffer in the table list
 | 
						|
    *Table = (EFI_ACPI_DESCRIPTION_HEADER *)TableBuffer;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 |