mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-11-04 03:57:26 +00:00 
			
		
		
		
	REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg 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: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			615 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			615 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  ACPI Sdt Protocol Driver
 | 
						|
 | 
						|
  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "AcpiTable.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Construct node list according to the AML handle.
 | 
						|
 | 
						|
  @param[in]    AmlHandle            AML handle.
 | 
						|
  @param[in]    AmlRootNodeList      AML root node list.
 | 
						|
  @param[in]    AmlParentNodeList    AML parent node list.
 | 
						|
 | 
						|
  @retval       EFI_SUCCESS           Success.
 | 
						|
  @retval       EFI_INVALID_PARAMETER AML handle does not refer to a valid ACPI object.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
AmlConstructNodeList (
 | 
						|
  IN EFI_AML_HANDLE     *AmlHandle,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlRootNodeList,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlParentNodeList
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
  Create AML Node.
 | 
						|
 | 
						|
  @param[in]    NameSeg              AML NameSeg.
 | 
						|
  @param[in]    Parent               AML parent node list.
 | 
						|
  @param[in]    AmlByteEncoding      AML Byte Encoding.
 | 
						|
 | 
						|
  @return       AML Node.
 | 
						|
**/
 | 
						|
EFI_AML_NODE_LIST *
 | 
						|
AmlCreateNode (
 | 
						|
  IN UINT8              *NameSeg,
 | 
						|
  IN EFI_AML_NODE_LIST  *Parent,
 | 
						|
  IN AML_BYTE_ENCODING  *AmlByteEncoding
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_AML_NODE_LIST  *AmlNodeList;
 | 
						|
 | 
						|
  AmlNodeList = AllocatePool (sizeof (*AmlNodeList));
 | 
						|
  ASSERT (AmlNodeList != NULL);
 | 
						|
 | 
						|
  AmlNodeList->Signature = EFI_AML_NODE_LIST_SIGNATURE;
 | 
						|
  CopyMem (AmlNodeList->Name, NameSeg, AML_NAME_SEG_SIZE);
 | 
						|
  AmlNodeList->Buffer = NULL;
 | 
						|
  AmlNodeList->Size   = 0;
 | 
						|
  InitializeListHead (&AmlNodeList->Link);
 | 
						|
  InitializeListHead (&AmlNodeList->Children);
 | 
						|
  AmlNodeList->Parent          = Parent;
 | 
						|
  AmlNodeList->AmlByteEncoding = AmlByteEncoding;
 | 
						|
 | 
						|
  return AmlNodeList;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Find the AML NameSeg in the children of AmlParentNodeList.
 | 
						|
 | 
						|
  @param[in]    NameSeg              AML NameSeg.
 | 
						|
  @param[in]    AmlParentNodeList    AML parent node list.
 | 
						|
  @param[in]    Create               TRUE means to create node if not found.
 | 
						|
 | 
						|
  @return       AmlChildNode whoes name is same as NameSeg.
 | 
						|
**/
 | 
						|
EFI_AML_NODE_LIST *
 | 
						|
AmlFindNodeInThis (
 | 
						|
  IN UINT8              *NameSeg,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlParentNodeList,
 | 
						|
  IN BOOLEAN            Create
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_AML_NODE_LIST  *CurrentAmlNodeList;
 | 
						|
  LIST_ENTRY         *CurrentLink;
 | 
						|
  LIST_ENTRY         *StartLink;
 | 
						|
  EFI_AML_NODE_LIST  *AmlNodeList;
 | 
						|
 | 
						|
  StartLink   = &AmlParentNodeList->Children;
 | 
						|
  CurrentLink = StartLink->ForwardLink;
 | 
						|
 | 
						|
  while (CurrentLink != StartLink) {
 | 
						|
    CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
 | 
						|
    //
 | 
						|
    // AML name is same as the one stored
 | 
						|
    //
 | 
						|
    if (CompareMem (CurrentAmlNodeList->Name, NameSeg, AML_NAME_SEG_SIZE) == 0) {
 | 
						|
      //
 | 
						|
      // Good! Found it
 | 
						|
      //
 | 
						|
      return CurrentAmlNodeList;
 | 
						|
    }
 | 
						|
 | 
						|
    CurrentLink = CurrentLink->ForwardLink;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Not found
 | 
						|
  //
 | 
						|
  if (!Create) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Create new node with NULL buffer - it means namespace not be returned.
 | 
						|
  //
 | 
						|
  AmlNodeList = AmlCreateNode (NameSeg, AmlParentNodeList, NULL);
 | 
						|
  InsertTailList (&AmlParentNodeList->Children, &AmlNodeList->Link);
 | 
						|
 | 
						|
  return AmlNodeList;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Find the AML NameString in the children of AmlParentNodeList or AmlRootNodeList.
 | 
						|
 | 
						|
  @param[in]    NameString           AML NameString.
 | 
						|
  @param[in]    AmlRootNodeList      AML root node list.
 | 
						|
  @param[in]    AmlParentNodeList    AML parent node list.
 | 
						|
  @param[in]    Create               TRUE means to create node if not found.
 | 
						|
 | 
						|
  @return       AmlChildNode whoes name is same as NameSeg.
 | 
						|
**/
 | 
						|
EFI_AML_NODE_LIST *
 | 
						|
AmlFindNodeInTheTree (
 | 
						|
  IN UINT8              *NameString,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlRootNodeList,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlParentNodeList,
 | 
						|
  IN BOOLEAN            Create
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8              *Buffer;
 | 
						|
  EFI_AML_NODE_LIST  *AmlNodeList;
 | 
						|
  EFI_AML_NODE_LIST  *AmlCurrentNodeList;
 | 
						|
  UINT8              Index;
 | 
						|
  UINT8              SegCount;
 | 
						|
 | 
						|
  Buffer = NameString;
 | 
						|
 | 
						|
  //
 | 
						|
  // Handle root or parent prefix
 | 
						|
  //
 | 
						|
  if (*Buffer == AML_ROOT_CHAR) {
 | 
						|
    AmlCurrentNodeList = AmlRootNodeList;
 | 
						|
    Buffer            += 1;
 | 
						|
  } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
 | 
						|
    AmlCurrentNodeList = AmlParentNodeList;
 | 
						|
    do {
 | 
						|
      if (AmlCurrentNodeList->Parent != NULL) {
 | 
						|
        AmlCurrentNodeList = AmlCurrentNodeList->Parent;
 | 
						|
      } else {
 | 
						|
        //
 | 
						|
        // Only root has no parent
 | 
						|
        //
 | 
						|
        ASSERT (AmlCurrentNodeList == AmlRootNodeList);
 | 
						|
      }
 | 
						|
 | 
						|
      Buffer += 1;
 | 
						|
    } while (*Buffer == AML_PARENT_PREFIX_CHAR);
 | 
						|
  } else {
 | 
						|
    AmlCurrentNodeList = AmlParentNodeList;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Handle name segment
 | 
						|
  //
 | 
						|
  if (*Buffer == AML_DUAL_NAME_PREFIX) {
 | 
						|
    Buffer  += 1;
 | 
						|
    SegCount = 2;
 | 
						|
  } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
 | 
						|
    Buffer  += 1;
 | 
						|
    SegCount = *Buffer;
 | 
						|
    Buffer  += 1;
 | 
						|
  } else if (*Buffer == 0) {
 | 
						|
    //
 | 
						|
    // NULL name, only for Root
 | 
						|
    //
 | 
						|
    ASSERT (AmlCurrentNodeList == AmlRootNodeList);
 | 
						|
    return AmlCurrentNodeList;
 | 
						|
  } else {
 | 
						|
    SegCount = 1;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Handle NamePath
 | 
						|
  //
 | 
						|
  Index = 0;
 | 
						|
  do {
 | 
						|
    AmlNodeList = AmlFindNodeInThis (Buffer, AmlCurrentNodeList, Create);
 | 
						|
    if (AmlNodeList == NULL) {
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    AmlCurrentNodeList = AmlNodeList;
 | 
						|
    Buffer            += AML_NAME_SEG_SIZE;
 | 
						|
    Index++;
 | 
						|
  } while (Index < SegCount);
 | 
						|
 | 
						|
  return AmlNodeList;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Insert the NameString to the AmlNodeList.
 | 
						|
 | 
						|
  @param[in]    NameString           AML NameString.
 | 
						|
  @param[in]    Buffer               Buffer for the Node.
 | 
						|
  @param[in]    Size                 Size for the Node.
 | 
						|
  @param[in]    AmlRootNodeList      AML root node list.
 | 
						|
  @param[in]    AmlParentNodeList    AML parent node list.
 | 
						|
 | 
						|
  @return       AmlChildNode whoes name is NameString.
 | 
						|
**/
 | 
						|
EFI_AML_NODE_LIST *
 | 
						|
AmlInsertNodeToTree (
 | 
						|
  IN UINT8              *NameString,
 | 
						|
  IN VOID               *Buffer,
 | 
						|
  IN UINTN              Size,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlRootNodeList,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlParentNodeList
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_AML_NODE_LIST  *AmlNodeList;
 | 
						|
 | 
						|
  AmlNodeList = AmlFindNodeInTheTree (
 | 
						|
                  NameString,
 | 
						|
                  AmlRootNodeList,
 | 
						|
                  AmlParentNodeList,
 | 
						|
                  TRUE  // Find and Create
 | 
						|
                  );
 | 
						|
  ASSERT (AmlNodeList != NULL);
 | 
						|
  if (AmlNodeList == NULL) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check buffer
 | 
						|
  //
 | 
						|
  if (AmlNodeList->Buffer == NULL) {
 | 
						|
    //
 | 
						|
    // NULL means new added one or SCOPE_OP
 | 
						|
    //
 | 
						|
    if (*(UINT8 *)Buffer != AML_SCOPE_OP) {
 | 
						|
      //
 | 
						|
      // We need check if new one is SCOPE_OP, because SCOPE_OP just means namespace, not a real device.
 | 
						|
      // We should not return SCOPE_OP.
 | 
						|
      //
 | 
						|
      AmlNodeList->Buffer          = Buffer;
 | 
						|
      AmlNodeList->Size            = Size;
 | 
						|
      AmlNodeList->AmlByteEncoding = AmlSearchByOpByte (Buffer);
 | 
						|
    }
 | 
						|
 | 
						|
    return AmlNodeList;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Already added
 | 
						|
  //
 | 
						|
  if (*(UINT8 *)Buffer == AML_SCOPE_OP) {
 | 
						|
    //
 | 
						|
    // The new one is SCOPE_OP, OK just return;
 | 
						|
    //
 | 
						|
    return AmlNodeList;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Oops!!!, There must be something wrong.
 | 
						|
  //
 | 
						|
  DEBUG ((DEBUG_ERROR, "AML: Override Happen - %a!\n", NameString));
 | 
						|
  DEBUG ((DEBUG_ERROR, "AML: Existing Node - %x\n", AmlNodeList->Buffer));
 | 
						|
  DEBUG ((DEBUG_ERROR, "AML: New Buffer - %x\n", Buffer));
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Construct child node list according to the AML handle.
 | 
						|
 | 
						|
  @param[in]    AmlHandle            AML handle.
 | 
						|
  @param[in]    AmlRootNodeList      AML root node list.
 | 
						|
  @param[in]    AmlParentNodeList    AML parent node list.
 | 
						|
 | 
						|
  @retval       EFI_SUCCESS           Success.
 | 
						|
  @retval       EFI_INVALID_PARAMETER AML handle does not refer to a valid ACPI object.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
AmlConstructNodeListForChild (
 | 
						|
  IN EFI_AML_HANDLE     *AmlHandle,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlRootNodeList,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlParentNodeList
 | 
						|
  )
 | 
						|
{
 | 
						|
  AML_BYTE_ENCODING  *AmlByteEncoding;
 | 
						|
  UINT8              *Buffer;
 | 
						|
  UINTN              BufferSize;
 | 
						|
  UINT8              *CurrentBuffer;
 | 
						|
  EFI_AML_HANDLE     *AmlChildHandle;
 | 
						|
  EFI_STATUS         Status;
 | 
						|
 | 
						|
  CurrentBuffer   = NULL;
 | 
						|
  AmlChildHandle  = NULL;
 | 
						|
  AmlByteEncoding = AmlHandle->AmlByteEncoding;
 | 
						|
  Buffer          = AmlHandle->Buffer;
 | 
						|
  BufferSize      = AmlHandle->Size;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if we need recursively add node
 | 
						|
  //
 | 
						|
  if ((AmlByteEncoding->Attribute & AML_HAS_CHILD_OBJ) == 0) {
 | 
						|
    //
 | 
						|
    // No more node need to be added
 | 
						|
    //
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Do we need add node within METHOD?
 | 
						|
  // Yes, just add Object is OK. But we need filter NameString for METHOD invoke.
 | 
						|
  //
 | 
						|
 | 
						|
  //
 | 
						|
  // Now, we get the last node.
 | 
						|
  //
 | 
						|
  Status = AmlGetOffsetAfterLastOption (AmlHandle, &CurrentBuffer);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Go through all the reset buffer.
 | 
						|
  //
 | 
						|
  while ((UINTN)CurrentBuffer < (UINTN)Buffer + BufferSize) {
 | 
						|
    //
 | 
						|
    // Find the child node.
 | 
						|
    //
 | 
						|
    Status = SdtOpenEx (CurrentBuffer, (UINTN)Buffer + BufferSize - (UINTN)CurrentBuffer, (EFI_ACPI_HANDLE *)&AmlChildHandle);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // No child found, break now.
 | 
						|
      //
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Good, find the child. Construct node recursively
 | 
						|
    //
 | 
						|
    Status = AmlConstructNodeList (
 | 
						|
               AmlChildHandle,
 | 
						|
               AmlRootNodeList,
 | 
						|
               AmlParentNodeList
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Parse next one
 | 
						|
    //
 | 
						|
    CurrentBuffer += AmlChildHandle->Size;
 | 
						|
 | 
						|
    Close ((EFI_ACPI_HANDLE)AmlChildHandle);
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Construct node list according to the AML handle.
 | 
						|
 | 
						|
  @param[in]    AmlHandle            AML handle.
 | 
						|
  @param[in]    AmlRootNodeList      AML root node list.
 | 
						|
  @param[in]    AmlParentNodeList    AML parent node list.
 | 
						|
 | 
						|
  @retval       EFI_SUCCESS           Success.
 | 
						|
  @retval       EFI_INVALID_PARAMETER AML handle does not refer to a valid ACPI object.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
AmlConstructNodeList (
 | 
						|
  IN EFI_AML_HANDLE     *AmlHandle,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlRootNodeList,
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlParentNodeList
 | 
						|
  )
 | 
						|
{
 | 
						|
  VOID               *NameString;
 | 
						|
  EFI_AML_NODE_LIST  *AmlNodeList;
 | 
						|
 | 
						|
  //
 | 
						|
  // 1. Check if there is need to construct node for this OpCode.
 | 
						|
  //
 | 
						|
  if ((AmlHandle->AmlByteEncoding->Attribute & AML_IN_NAMESPACE) == 0) {
 | 
						|
    //
 | 
						|
    // No need to construct node, so we just skip this OpCode.
 | 
						|
    //
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // 2. Now, we need construct node for this OpCode.
 | 
						|
  //
 | 
						|
  NameString = AmlGetObjectName (AmlHandle);
 | 
						|
  if (NameString == NULL) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Now, we need to insert node to the node list.
 | 
						|
  // NOTE: The name here could be AML NameString. So the callee need parse it.
 | 
						|
  //
 | 
						|
  AmlNodeList = AmlInsertNodeToTree (NameString, AmlHandle->Buffer, AmlHandle->Size, AmlRootNodeList, AmlParentNodeList);
 | 
						|
  ASSERT (AmlNodeList != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // 3. Ok, we need to parse the object list to see if there are more node to be added.
 | 
						|
  //
 | 
						|
  return AmlConstructNodeListForChild (AmlHandle, AmlRootNodeList, AmlNodeList);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Destruct node list
 | 
						|
 | 
						|
  @param[in]    AmlParentNodeList    AML parent node list.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
AmlDestructNodeList (
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlParentNodeList
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_AML_NODE_LIST  *CurrentAmlNodeList;
 | 
						|
  LIST_ENTRY         *CurrentLink;
 | 
						|
  LIST_ENTRY         *StartLink;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the children link
 | 
						|
  //
 | 
						|
  StartLink   = &AmlParentNodeList->Children;
 | 
						|
  CurrentLink = StartLink->ForwardLink;
 | 
						|
 | 
						|
  //
 | 
						|
  // Go through all the children
 | 
						|
  //
 | 
						|
  while (CurrentLink != StartLink) {
 | 
						|
    //
 | 
						|
    // Destruct the child's list recursively
 | 
						|
    //
 | 
						|
    CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
 | 
						|
    CurrentLink        = CurrentLink->ForwardLink;
 | 
						|
 | 
						|
    //
 | 
						|
    // Remove this child from list and free the node
 | 
						|
    //
 | 
						|
    RemoveEntryList (&(CurrentAmlNodeList->Link));
 | 
						|
 | 
						|
    AmlDestructNodeList (CurrentAmlNodeList);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Done.
 | 
						|
  //
 | 
						|
  FreePool (AmlParentNodeList);
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dump node list
 | 
						|
 | 
						|
  @param[in]    AmlParentNodeList    AML parent node list.
 | 
						|
  @param[in]    Level                Output debug level.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
AmlDumpNodeInfo (
 | 
						|
  IN EFI_AML_NODE_LIST  *AmlParentNodeList,
 | 
						|
  IN UINTN              Level
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_AML_NODE_LIST    *CurrentAmlNodeList;
 | 
						|
  volatile LIST_ENTRY  *CurrentLink;
 | 
						|
  UINTN                Index;
 | 
						|
 | 
						|
  CurrentLink = AmlParentNodeList->Children.ForwardLink;
 | 
						|
 | 
						|
  if (Level == 0) {
 | 
						|
    DEBUG ((DEBUG_ERROR, "\\"));
 | 
						|
  } else {
 | 
						|
    for (Index = 0; Index < Level; Index++) {
 | 
						|
      DEBUG ((DEBUG_ERROR, "    "));
 | 
						|
    }
 | 
						|
 | 
						|
    AmlPrintNameSeg (AmlParentNodeList->Name);
 | 
						|
  }
 | 
						|
 | 
						|
  DEBUG ((DEBUG_ERROR, "\n"));
 | 
						|
 | 
						|
  while (CurrentLink != &AmlParentNodeList->Children) {
 | 
						|
    CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
 | 
						|
    AmlDumpNodeInfo (CurrentAmlNodeList, Level + 1);
 | 
						|
    CurrentLink = CurrentLink->ForwardLink;
 | 
						|
  }
 | 
						|
 | 
						|
  return;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns the handle of the ACPI object representing the specified ACPI AML path
 | 
						|
 | 
						|
  @param[in]    AmlHandle   Points to the handle of the object representing the starting point for the path search.
 | 
						|
  @param[in]    AmlPath     Points to the ACPI AML path.
 | 
						|
  @param[out]   Buffer      On return, points to the ACPI object which represents AcpiPath, relative to
 | 
						|
                            HandleIn.
 | 
						|
  @param[in]    FromRoot    TRUE means to find AML path from \ (Root) Node.
 | 
						|
                            FALSE means to find AML path from this Node (The HandleIn).
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           Success
 | 
						|
  @retval EFI_INVALID_PARAMETER HandleIn does not refer to a valid ACPI object.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
AmlFindPath (
 | 
						|
  IN    EFI_AML_HANDLE  *AmlHandle,
 | 
						|
  IN    UINT8           *AmlPath,
 | 
						|
  OUT   VOID            **Buffer,
 | 
						|
  IN    BOOLEAN         FromRoot
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_AML_NODE_LIST  *AmlRootNodeList;
 | 
						|
  EFI_STATUS         Status;
 | 
						|
  EFI_AML_NODE_LIST  *AmlNodeList;
 | 
						|
  UINT8              RootNameSeg[AML_NAME_SEG_SIZE];
 | 
						|
  EFI_AML_NODE_LIST  *CurrentAmlNodeList;
 | 
						|
  LIST_ENTRY         *CurrentLink;
 | 
						|
 | 
						|
  //
 | 
						|
  // 1. create tree
 | 
						|
  //
 | 
						|
 | 
						|
  //
 | 
						|
  // Create root handle
 | 
						|
  //
 | 
						|
  RootNameSeg[0]  = AML_ROOT_CHAR;
 | 
						|
  RootNameSeg[1]  = 0;
 | 
						|
  AmlRootNodeList = AmlCreateNode (RootNameSeg, NULL, AmlHandle->AmlByteEncoding);
 | 
						|
 | 
						|
  Status = AmlConstructNodeList (
 | 
						|
             AmlHandle,
 | 
						|
             AmlRootNodeList, // Root
 | 
						|
             AmlRootNodeList  // Parent
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  DEBUG_CODE_BEGIN ();
 | 
						|
  DEBUG ((DEBUG_ERROR, "AcpiSdt: NameSpace:\n"));
 | 
						|
  AmlDumpNodeInfo (AmlRootNodeList, 0);
 | 
						|
  DEBUG_CODE_END ();
 | 
						|
 | 
						|
  //
 | 
						|
  // 2. Search the node in the tree
 | 
						|
  //
 | 
						|
  if (FromRoot) {
 | 
						|
    //
 | 
						|
    // Search from Root
 | 
						|
    //
 | 
						|
    CurrentAmlNodeList = AmlRootNodeList;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Search from this node, NOT ROOT.
 | 
						|
    // Since we insert node to ROOT one by one, we just get the first node and search from it.
 | 
						|
    //
 | 
						|
    CurrentLink = AmlRootNodeList->Children.ForwardLink;
 | 
						|
    if (CurrentLink != &AmlRootNodeList->Children) {
 | 
						|
      //
 | 
						|
      // First node
 | 
						|
      //
 | 
						|
      CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // No child
 | 
						|
      //
 | 
						|
      CurrentAmlNodeList = NULL;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Search
 | 
						|
  //
 | 
						|
  if (CurrentAmlNodeList != NULL) {
 | 
						|
    DEBUG_CODE_BEGIN ();
 | 
						|
    DEBUG ((DEBUG_ERROR, "AcpiSdt: Search from: \\"));
 | 
						|
    AmlPrintNameSeg (CurrentAmlNodeList->Name);
 | 
						|
    DEBUG ((DEBUG_ERROR, "\n"));
 | 
						|
    DEBUG_CODE_END ();
 | 
						|
    AmlNodeList = AmlFindNodeInTheTree (
 | 
						|
                    AmlPath,
 | 
						|
                    AmlRootNodeList,    // Root
 | 
						|
                    CurrentAmlNodeList, // Parent
 | 
						|
                    FALSE
 | 
						|
                    );
 | 
						|
  } else {
 | 
						|
    AmlNodeList = NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  *Buffer = NULL;
 | 
						|
  Status  = EFI_SUCCESS;
 | 
						|
  if ((AmlNodeList != NULL) && (AmlNodeList->Buffer != NULL)) {
 | 
						|
    *Buffer = AmlNodeList->Buffer;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // 3. free the tree
 | 
						|
  //
 | 
						|
  AmlDestructNodeList (AmlRootNodeList);
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 |