Fix the following ECC reported errors in AmlLib.
  - [1008]  File has invalid Non-ACSII char.
  - [9002]  The function headers should follow Doxygen special
            documentation blocks in section 2.3.5 Comment does NOT
            have tail **/
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
		
	
		
			
				
	
	
		
			702 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			702 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  AML Code Generation.
 | 
						|
 | 
						|
  Copyright (c) 2020, 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 <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 success, contains the created object node.
 | 
						|
 | 
						|
  @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 = Node;
 | 
						|
  }
 | 
						|
 | 
						|
  // Add RdNode as the last element.
 | 
						|
  if (ParentNode != NULL) {
 | 
						|
    Status = AmlVarListAddTail (ParentNode, (AML_NODE_HEADER*)Node);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      ASSERT (0);
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  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;
 | 
						|
  }
 | 
						|
 | 
						|
  ObjectNode = NULL;
 | 
						|
  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:
 | 
						|
  if (ObjectNode != NULL) {
 | 
						|
    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 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;
 | 
						|
}
 |