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>
		
			
				
	
	
		
			598 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			598 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   AML Node Interface.
 | |
| 
 | |
|   Copyright (c) 2019 - 2020, Arm Limited. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| **/
 | |
| 
 | |
| #include <AmlNodeDefines.h>
 | |
| 
 | |
| #include <AmlCoreInterface.h>
 | |
| #include <ResourceData/AmlResourceData.h>
 | |
| #include <String/AmlString.h>
 | |
| #include <Tree/AmlNode.h>
 | |
| #include <Tree/AmlTree.h>
 | |
| #include <Utils/AmlUtility.h>
 | |
| 
 | |
| /** Returns the tree node type (Root/Object/Data).
 | |
| 
 | |
|   @param [in] Node  Pointer to a Node.
 | |
| 
 | |
|   @return The node type.
 | |
|            EAmlNodeUnknown if invalid parameter.
 | |
| **/
 | |
| EAML_NODE_TYPE
 | |
| EFIAPI
 | |
| AmlGetNodeType (
 | |
|   IN  AML_NODE_HEADER  *Node
 | |
|   )
 | |
| {
 | |
|   if (!IS_AML_NODE_VALID (Node)) {
 | |
|     ASSERT (0);
 | |
|     return EAmlNodeUnknown;
 | |
|   }
 | |
| 
 | |
|   return Node->NodeType;
 | |
| }
 | |
| 
 | |
| /** Get the RootNode information.
 | |
|     The Node must be a root node.
 | |
| 
 | |
|   @param  [in]  RootNode          Pointer to a root node.
 | |
|   @param  [out] SdtHeaderBuffer   Buffer to copy the ACPI DSDT/SSDT header to.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlGetRootNodeInfo (
 | |
|   IN  AML_ROOT_NODE                *RootNode,
 | |
|   OUT EFI_ACPI_DESCRIPTION_HEADER  *SdtHeaderBuffer
 | |
|   )
 | |
| {
 | |
|   if (!IS_AML_ROOT_NODE (RootNode)  ||
 | |
|       (SdtHeaderBuffer == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   CopyMem (
 | |
|     SdtHeaderBuffer,
 | |
|     RootNode->SdtHeader,
 | |
|     sizeof (EFI_ACPI_DESCRIPTION_HEADER)
 | |
|     );
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Get the ObjectNode information.
 | |
|     The Node must be an object node.
 | |
| 
 | |
|   @ingroup NodeInterfaceApi
 | |
| 
 | |
|   @param  [in]  ObjectNode        Pointer to an object node.
 | |
|   @param  [out] OpCode            Pointer holding the OpCode.
 | |
|                                   Optional, can be NULL.
 | |
|   @param  [out] SubOpCode         Pointer holding the SubOpCode.
 | |
|                                   Optional, can be NULL.
 | |
|   @param  [out] PkgLen            Pointer holding the PkgLen.
 | |
|                                   The PkgLen is 0 for nodes
 | |
|                                   not having the Pkglen attribute.
 | |
|                                   Optional, can be NULL.
 | |
|   @param  [out] IsNameSpaceNode   Pointer holding TRUE if the node is defining
 | |
|                                   or changing the NameSpace scope.
 | |
|                                   E.g.: The "Name ()" and "Scope ()" ASL
 | |
|                                   statements add/modify the NameSpace scope.
 | |
|                                   Their corresponding node are NameSpace nodes.
 | |
|                                   Optional, can be NULL.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlGetObjectNodeInfo (
 | |
|   IN  AML_OBJECT_NODE  *ObjectNode,
 | |
|   OUT UINT8            *OpCode            OPTIONAL,
 | |
|   OUT UINT8            *SubOpCode         OPTIONAL,
 | |
|   OUT UINT32           *PkgLen            OPTIONAL,
 | |
|   OUT BOOLEAN          *IsNameSpaceNode   OPTIONAL
 | |
|   )
 | |
| {
 | |
|   if (!IS_AML_OBJECT_NODE (ObjectNode)) {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if (OpCode != NULL) {
 | |
|     *OpCode = ObjectNode->AmlByteEncoding->OpCode;
 | |
|   }
 | |
| 
 | |
|   if (SubOpCode != NULL) {
 | |
|     *SubOpCode = ObjectNode->AmlByteEncoding->SubOpCode;
 | |
|   }
 | |
| 
 | |
|   if (PkgLen != NULL) {
 | |
|     *PkgLen = ObjectNode->PkgLen;
 | |
|   }
 | |
| 
 | |
|   if (IsNameSpaceNode != NULL) {
 | |
|     *IsNameSpaceNode = AmlNodeHasAttribute (ObjectNode, AML_IN_NAMESPACE);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Returns the count of the fixed arguments for the input Node.
 | |
| 
 | |
|   @param  [in]  Node  Pointer to an object node.
 | |
| 
 | |
|   @return Number of fixed arguments of the object node.
 | |
|           Return 0 if the node is not an object node.
 | |
| **/
 | |
| UINT8
 | |
| AmlGetFixedArgumentCount (
 | |
|   IN  AML_OBJECT_NODE  *Node
 | |
|   )
 | |
| {
 | |
|   if (IS_AML_OBJECT_NODE (Node) &&
 | |
|       (Node->AmlByteEncoding != NULL))
 | |
|   {
 | |
|     return (UINT8)Node->AmlByteEncoding->MaxIndex;
 | |
|   }
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| /** Get the data type of the DataNode.
 | |
|     The Node must be a data node.
 | |
| 
 | |
|   @param  [in]  DataNode  Pointer to a data node.
 | |
|   @param  [out] DataType  Pointer holding the data type of the data buffer.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlGetNodeDataType (
 | |
|   IN  AML_DATA_NODE        *DataNode,
 | |
|   OUT EAML_NODE_DATA_TYPE  *DataType
 | |
|   )
 | |
| {
 | |
|   if (!IS_AML_DATA_NODE (DataNode)  ||
 | |
|       (DataType == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   *DataType = DataNode->DataType;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Get the descriptor Id of the resource data element
 | |
|     contained in the DataNode.
 | |
| 
 | |
|   The Node must be a data node.
 | |
|   The Node must have the resource data type, i.e. have the
 | |
|   EAmlNodeDataTypeResourceData data type.
 | |
| 
 | |
|   @param  [in]  DataNode          Pointer to a data node containing a
 | |
|                                   resource data element.
 | |
|   @param  [out] ResourceDataType  Pointer holding the descriptor Id of
 | |
|                                   the resource data.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlGetResourceDataType (
 | |
|   IN  AML_DATA_NODE  *DataNode,
 | |
|   OUT AML_RD_HEADER  *ResourceDataType
 | |
|   )
 | |
| {
 | |
|   if (!IS_AML_DATA_NODE (DataNode)  ||
 | |
|       (ResourceDataType == NULL)    ||
 | |
|       (DataNode->DataType != EAmlNodeDataTypeResourceData))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   *ResourceDataType = AmlRdGetDescId (DataNode->Buffer);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Get the data buffer and size of the DataNode.
 | |
|     The Node must be a data node.
 | |
| 
 | |
|   BufferSize is always updated to the size of buffer of the DataNode.
 | |
| 
 | |
|   If:
 | |
|    - the content of BufferSize is >= to the DataNode's buffer size;
 | |
|    - Buffer is not NULL;
 | |
|   then copy the content of the DataNode's buffer in Buffer.
 | |
| 
 | |
|   @param  [in]      DataNode      Pointer to a data node.
 | |
|   @param  [out]     Buffer        Buffer to write the data to.
 | |
|                                   Optional, if NULL, only update BufferSize.
 | |
|   @param  [in, out] BufferSize    Pointer holding:
 | |
|                                    - At entry, the size of the Buffer;
 | |
|                                    - At exit, the size of the DataNode's
 | |
|                                      buffer size.
 | |
| 
 | |
|   @retval EFI_SUCCESS           The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlGetDataNodeBuffer (
 | |
|   IN      AML_DATA_NODE  *DataNode,
 | |
|   OUT UINT8              *Buffer        OPTIONAL,
 | |
|   IN  OUT UINT32         *BufferSize
 | |
|   )
 | |
| {
 | |
|   if (!IS_AML_DATA_NODE (DataNode) ||
 | |
|       (BufferSize == NULL))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   if ((*BufferSize >= DataNode->Size)  &&
 | |
|       (Buffer != NULL))
 | |
|   {
 | |
|     CopyMem (Buffer, DataNode->Buffer, DataNode->Size);
 | |
|   }
 | |
| 
 | |
|   *BufferSize = DataNode->Size;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /** Update the ACPI DSDT/SSDT table header.
 | |
| 
 | |
|   The input SdtHeader information is copied to the tree RootNode.
 | |
|   The table Length field is automatically updated.
 | |
|   The checksum field is only updated when serializing the tree.
 | |
| 
 | |
|   @param  [in]  RootNode    Pointer to a root node.
 | |
|   @param  [in]  SdtHeader   Pointer to an ACPI DSDT/SSDT table header.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlUpdateRootNode (
 | |
|   IN        AML_ROOT_NODE                *RootNode,
 | |
|   IN  CONST EFI_ACPI_DESCRIPTION_HEADER  *SdtHeader
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINT32      Length;
 | |
| 
 | |
|   if (!IS_AML_ROOT_NODE (RootNode)  ||
 | |
|       (SdtHeader == NULL)           ||
 | |
|       ((SdtHeader->Signature !=
 | |
|         EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) &&
 | |
|        (SdtHeader->Signature !=
 | |
|         EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   CopyMem (
 | |
|     RootNode->SdtHeader,
 | |
|     SdtHeader,
 | |
|     sizeof (EFI_ACPI_DESCRIPTION_HEADER)
 | |
|     );
 | |
| 
 | |
|   // Update the Length field.
 | |
|   Status = AmlComputeSize ((AML_NODE_HEADER *)RootNode, &Length);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   RootNode->SdtHeader->Length = Length +
 | |
|                                 (UINT32)sizeof (EFI_ACPI_DESCRIPTION_HEADER);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /** Update an object node representing an integer with a new value.
 | |
| 
 | |
|   The object node must have one of the following OpCodes:
 | |
|    - AML_BYTE_PREFIX
 | |
|    - AML_WORD_PREFIX
 | |
|    - AML_DWORD_PREFIX
 | |
|    - AML_QWORD_PREFIX
 | |
|    - AML_ZERO_OP
 | |
|    - AML_ONE_OP
 | |
| 
 | |
|   The following OpCode is not supported:
 | |
|    - AML_ONES_OP
 | |
| 
 | |
|   @param  [in] IntegerOpNode   Pointer an object node containing an integer.
 | |
|                                Must not be an object node with an AML_ONES_OP
 | |
|                                OpCode.
 | |
|   @param  [in] NewInteger      New integer value to set.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlUpdateInteger (
 | |
|   IN  AML_OBJECT_NODE  *IntegerOpNode,
 | |
|   IN  UINT64           NewInteger
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   INT8  ValueWidthDiff;
 | |
| 
 | |
|   if (!IS_AML_OBJECT_NODE (IntegerOpNode)     ||
 | |
|       (!IsIntegerNode (IntegerOpNode)         &&
 | |
|        !IsSpecialIntegerNode (IntegerOpNode)) ||
 | |
|       AmlNodeCompareOpCode (IntegerOpNode, AML_ONES_OP, 0))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   Status = AmlNodeSetIntegerValue (IntegerOpNode, NewInteger, &ValueWidthDiff);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     ASSERT (0);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   // If the new size is different from the old size, propagate the new size.
 | |
|   if (ValueWidthDiff != 0) {
 | |
|     // Propagate the information.
 | |
|     Status = AmlPropagateInformation (
 | |
|                (AML_NODE_HEADER *)IntegerOpNode,
 | |
|                (ValueWidthDiff > 0) ? TRUE : FALSE,
 | |
|                ABS (ValueWidthDiff),
 | |
|                0
 | |
|                );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       ASSERT (0);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /** Update the buffer of a data node.
 | |
| 
 | |
|   Note: The data type of the buffer's content must match the data type of the
 | |
|         DataNode. This is a hard restriction to prevent undesired behaviour.
 | |
| 
 | |
|   @param  [in]  DataNode  Pointer to a data node.
 | |
|   @param  [in]  DataType  Data type of the Buffer's content.
 | |
|   @param  [in]  Buffer    Buffer containing the new data. The content of
 | |
|                           the Buffer is copied.
 | |
|   @param  [in]  Size      Size of the Buffer.
 | |
| 
 | |
|   @retval EFI_SUCCESS             The function completed successfully.
 | |
|   @retval EFI_INVALID_PARAMETER   Invalid parameter.
 | |
|   @retval EFI_UNSUPPORTED         Operation not supporter.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| AmlUpdateDataNode (
 | |
|   IN  AML_DATA_NODE        *DataNode,
 | |
|   IN  EAML_NODE_DATA_TYPE  DataType,
 | |
|   IN  UINT8                *Buffer,
 | |
|   IN  UINT32               Size
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   UINT32               ExpectedSize;
 | |
|   AML_OBJECT_NODE      *ParentNode;
 | |
|   EAML_NODE_DATA_TYPE  ExpectedArgType;
 | |
|   EAML_PARSE_INDEX     Index;
 | |
| 
 | |
|   if (!IS_AML_DATA_NODE (DataNode)      ||
 | |
|       (DataType > EAmlNodeDataTypeMax)  ||
 | |
|       (Buffer == NULL)                  ||
 | |
|       (Size == 0))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   ParentNode = (AML_OBJECT_NODE *)AmlGetParent ((AML_NODE_HEADER *)DataNode);
 | |
|   if (!IS_AML_OBJECT_NODE (ParentNode)) {
 | |
|     ASSERT (0);
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   // The NewNode and OldNode must have the same type.
 | |
|   // We do not allow to change the argument type of a data node.
 | |
|   // If required, the initial ASL template should be modified
 | |
|   // accordingly.
 | |
|   // It is however possible to interchange a raw buffer and a
 | |
|   // resource data element, since raw data can be misinterpreted
 | |
|   // as a resource data element.
 | |
|   ExpectedArgType = DataNode->DataType;
 | |
|   if ((ExpectedArgType != DataType)                         &&
 | |
|       (((ExpectedArgType != EAmlNodeDataTypeRaw)            &&
 | |
|         (ExpectedArgType != EAmlNodeDataTypeResourceData))  ||
 | |
|        ((DataType != EAmlNodeDataTypeRaw)                   &&
 | |
|         (DataType != EAmlNodeDataTypeResourceData))))
 | |
|   {
 | |
|     ASSERT (0);
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   // Perform some compatibility checks.
 | |
|   switch (DataType) {
 | |
|     case EAmlNodeDataTypeNameString:
 | |
|     {
 | |
|       // Check the name contained in the Buffer is an AML name
 | |
|       // with the right size.
 | |
|       Status = AmlGetNameStringSize ((CONST CHAR8 *)Buffer, &ExpectedSize);
 | |
|       if (EFI_ERROR (Status)  ||
 | |
|           (Size != ExpectedSize))
 | |
|       {
 | |
|         ASSERT (0);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
|     case EAmlNodeDataTypeString:
 | |
|     {
 | |
|       ExpectedSize = 0;
 | |
|       while (ExpectedSize < Size) {
 | |
|         // Cf ACPI 6.3 specification 20.2.3 Data Objects Encoding.
 | |
|         // AsciiCharList := Nothing | <AsciiChar AsciiCharList>
 | |
|         // AsciiChar := 0x01 - 0x7F
 | |
|         // NullChar := 0x00
 | |
|         if (Buffer[ExpectedSize] > 0x7F) {
 | |
|           ASSERT (0);
 | |
|           return EFI_INVALID_PARAMETER;
 | |
|         }
 | |
| 
 | |
|         ExpectedSize++;
 | |
|       }
 | |
| 
 | |
|       if (ExpectedSize != Size) {
 | |
|         ASSERT (0);
 | |
|         return EFI_INVALID_PARAMETER;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
|     case EAmlNodeDataTypeUInt:
 | |
|     {
 | |
|       if (AmlIsNodeFixedArgument ((CONST AML_NODE_HEADER *)DataNode, &Index)) {
 | |
|         if ((ParentNode->AmlByteEncoding == NULL) ||
 | |
|             (ParentNode->AmlByteEncoding->Format == NULL))
 | |
|         {
 | |
|           ASSERT (0);
 | |
|           return EFI_INVALID_PARAMETER;
 | |
|         }
 | |
| 
 | |
|         // It is not possible to change the size of a fixed length UintX.
 | |
|         // E.g. for PackageOp the first fixed argument is of type EAmlUInt8
 | |
|         // and represents the count of elements. This type cannot be changed.
 | |
|         if ((ParentNode->AmlByteEncoding->Format[Index] != EAmlObject) &&
 | |
|             (DataNode->Size != Size))
 | |
|         {
 | |
|           ASSERT (0);
 | |
|           return EFI_UNSUPPORTED;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
|     case EAmlNodeDataTypeRaw:
 | |
|     {
 | |
|       // Check if the parent node has the byte list flag set.
 | |
|       if (!AmlNodeHasAttribute (ParentNode, AML_HAS_BYTE_LIST)) {
 | |
|         ASSERT (0);
 | |
|         return EFI_INVALID_PARAMETER;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
|     case EAmlNodeDataTypeResourceData:
 | |
|     {
 | |
|       // The resource data can be either small or large resource data.
 | |
|       // Small resource data must be at least 1 byte.
 | |
|       // Large resource data must be at least as long as the header
 | |
|       // of a large resource data.
 | |
|       if (AML_RD_IS_LARGE (Buffer)  &&
 | |
|           (Size < sizeof (ACPI_LARGE_RESOURCE_HEADER)))
 | |
|       {
 | |
|         ASSERT (0);
 | |
|         return EFI_INVALID_PARAMETER;
 | |
|       }
 | |
| 
 | |
|       // Check if the parent node has the byte list flag set.
 | |
|       if (!AmlNodeHasAttribute (ParentNode, AML_HAS_BYTE_LIST)) {
 | |
|         ASSERT (0);
 | |
|         return EFI_INVALID_PARAMETER;
 | |
|       }
 | |
| 
 | |
|       // Check the size of the buffer is equal to the resource data size
 | |
|       // encoded in the input buffer.
 | |
|       ExpectedSize = AmlRdGetSize (Buffer);
 | |
|       if (ExpectedSize != Size) {
 | |
|         ASSERT (0);
 | |
|         return EFI_INVALID_PARAMETER;
 | |
|       }
 | |
| 
 | |
|       Status = AmlSetRdListCheckSum (ParentNode, 0);
 | |
|       if (EFI_ERROR (Status)) {
 | |
|         ASSERT (0);
 | |
|         return Status;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
|     case EAmlNodeDataTypeFieldPkgLen:
 | |
|     {
 | |
|       // Check the parent is a FieldNamed field element.
 | |
|       if (!AmlNodeCompareOpCode (ParentNode, AML_FIELD_NAMED_OP, 0)) {
 | |
|         ASSERT (0);
 | |
|         return EFI_INVALID_PARAMETER;
 | |
|       }
 | |
| 
 | |
|       break;
 | |
|     }
 | |
|     // None and reserved types.
 | |
|     default:
 | |
|     {
 | |
|       ASSERT (0);
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|       break;
 | |
|     }
 | |
|   } // switch
 | |
| 
 | |
|   // If the new size is different from the old size, propagate the new size.
 | |
|   if (DataNode->Size != Size) {
 | |
|     // Propagate the information.
 | |
|     Status = AmlPropagateInformation (
 | |
|                DataNode->NodeHeader.Parent,
 | |
|                (Size > DataNode->Size) ? TRUE : FALSE,
 | |
|                (Size > DataNode->Size) ?
 | |
|                (Size - DataNode->Size) :
 | |
|                (DataNode->Size - Size),
 | |
|                0
 | |
|                );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       ASSERT (0);
 | |
|       return Status;
 | |
|     }
 | |
| 
 | |
|     // Free the old DataNode buffer and allocate a new buffer to store the
 | |
|     // new data.
 | |
|     FreePool (DataNode->Buffer);
 | |
|     DataNode->Buffer = AllocateZeroPool (Size);
 | |
|     if (DataNode->Buffer == NULL) {
 | |
|       ASSERT (0);
 | |
|       return EFI_OUT_OF_RESOURCES;
 | |
|     }
 | |
| 
 | |
|     DataNode->Size = Size;
 | |
|   }
 | |
| 
 | |
|   CopyMem (DataNode->Buffer, Buffer, Size);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |