Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15695 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			281 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   ACPI Sdt Protocol Driver
 | |
| 
 | |
|   Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved. <BR>
 | |
|   This program and the accompanying materials
 | |
|   are licensed and made available under the terms and conditions of the BSD License
 | |
|   which accompanies this distribution.  The full text of the license may be found at
 | |
|   http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
|   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
|   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "AcpiTable.h"
 | |
| 
 | |
| /**
 | |
|   Return the child objects buffer from AML Handle's buffer.
 | |
|   
 | |
|   @param[in]        AmlParentHandle Parent handle.
 | |
|   @param[in]        CurrentBuffer   The current child buffer.
 | |
|   @param[out]       Buffer          On return, points to the next returned child buffer or NULL if there are no
 | |
|                                     child buffer.
 | |
| 
 | |
|   @retval EFI_SUCCESS               Success
 | |
|   @retval EFI_INVALID_PARAMETER     AmlParentHandle does not refer to a valid ACPI object.                                
 | |
| **/
 | |
| EFI_STATUS
 | |
| AmlGetChildFromObjectBuffer (
 | |
|   IN EFI_AML_HANDLE         *AmlParentHandle,
 | |
|   IN UINT8                  *CurrentBuffer,
 | |
|   OUT VOID                  **Buffer
 | |
|   )
 | |
| {
 | |
|   AML_BYTE_ENCODING   *AmlByteEncoding;
 | |
|   UINTN               DataSize;
 | |
| 
 | |
|   //
 | |
|   // Root is considered as SCOPE, which has TermList.
 | |
|   // We need return only Object in TermList.
 | |
|   //
 | |
|   while ((UINTN)CurrentBuffer < (UINTN)(AmlParentHandle->Buffer + AmlParentHandle->Size)) {
 | |
|     AmlByteEncoding = AmlSearchByOpByte (CurrentBuffer);
 | |
|     if (AmlByteEncoding == NULL) {
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
|     //
 | |
|     // NOTE: We need return everything, because user might need parse the returned object.
 | |
|     //
 | |
|     if ((AmlByteEncoding->Attribute & AML_IS_NAME_CHAR) == 0) {
 | |
|       *Buffer = CurrentBuffer;
 | |
|       return EFI_SUCCESS;
 | |
|     }
 | |
| 
 | |
|     DataSize = AmlGetObjectSize (
 | |
|                  AmlByteEncoding,
 | |
|                  CurrentBuffer,
 | |
|                  (UINTN)AmlParentHandle->Buffer + AmlParentHandle->Size - (UINTN)CurrentBuffer
 | |
|                  );
 | |
|     if (DataSize == 0) {
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
|     CurrentBuffer += DataSize;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // No more
 | |
|   //
 | |
|   *Buffer = NULL;
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Return the child ACPI objects from Root Handle.
 | |
|   
 | |
|   @param[in]        AmlParentHandle Parent handle. It is Root Handle.
 | |
|   @param[in]        AmlHandle       The previously returned handle or NULL to start with the first handle.
 | |
|   @param[out]       Buffer          On return, points to the next returned ACPI handle or NULL if there are no
 | |
|                                     child objects.
 | |
| 
 | |
|   @retval EFI_SUCCESS               Success
 | |
|   @retval EFI_INVALID_PARAMETER     ParentHandle is NULL or does not refer to a valid ACPI object.                                
 | |
| **/
 | |
| EFI_STATUS
 | |
| AmlGetChildFromRoot (
 | |
|   IN EFI_AML_HANDLE         *AmlParentHandle,
 | |
|   IN EFI_AML_HANDLE         *AmlHandle,
 | |
|   OUT VOID                  **Buffer
 | |
|   )
 | |
| {
 | |
|   UINT8               *CurrentBuffer;
 | |
| 
 | |
|   if (AmlHandle == NULL) {
 | |
|     //
 | |
|     // First One
 | |
|     //
 | |
|     CurrentBuffer = (VOID *)AmlParentHandle->Buffer;
 | |
|   } else {
 | |
|     CurrentBuffer = (VOID *)(AmlHandle->Buffer + AmlHandle->Size);
 | |
|   }
 | |
| 
 | |
|   return AmlGetChildFromObjectBuffer (AmlParentHandle, CurrentBuffer, Buffer);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Return the child objects buffer from AML Handle's option list.
 | |
|   
 | |
|   @param[in]        AmlParentHandle Parent handle.
 | |
|   @param[in]        AmlHandle       The current child handle.
 | |
|   @param[out]       Buffer          On return, points to the next returned child buffer or NULL if there are no
 | |
|                                     child buffer.
 | |
| 
 | |
|   @retval EFI_SUCCESS               Success
 | |
|   @retval EFI_INVALID_PARAMETER     AmlParentHandle does not refer to a valid ACPI object.                                
 | |
| **/
 | |
| EFI_STATUS
 | |
| AmlGetChildFromOptionList (
 | |
|   IN EFI_AML_HANDLE         *AmlParentHandle,
 | |
|   IN EFI_AML_HANDLE         *AmlHandle,
 | |
|   OUT VOID                  **Buffer
 | |
|   )
 | |
| {
 | |
|   EFI_ACPI_DATA_TYPE  DataType;
 | |
|   VOID                *Data;
 | |
|   UINTN               DataSize;
 | |
|   AML_OP_PARSE_INDEX  Index;
 | |
|   EFI_STATUS          Status;
 | |
|   AML_OP_PARSE_INDEX  MaxTerm;
 | |
| 
 | |
|   Index = AML_OP_PARSE_INDEX_GET_TERM1;
 | |
|   MaxTerm = AmlParentHandle->AmlByteEncoding->MaxIndex;
 | |
|   while (Index <= MaxTerm) {
 | |
|     Status = AmlParseOptionHandleCommon (
 | |
|                AmlParentHandle,
 | |
|                (AML_OP_PARSE_INDEX)Index,
 | |
|                &DataType,
 | |
|                (VOID **)&Data,
 | |
|                &DataSize
 | |
|                );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return EFI_INVALID_PARAMETER;
 | |
|     }
 | |
|     if (DataType == EFI_ACPI_DATA_TYPE_NONE) {
 | |
|       //
 | |
|       // Not found
 | |
|       //
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     //
 | |
|     // Find it, and Check Data
 | |
|     //
 | |
|     if ((DataType == EFI_ACPI_DATA_TYPE_CHILD) &&
 | |
|         ((UINTN)AmlHandle->Buffer < (UINTN)Data)) {
 | |
|       //
 | |
|       // Buffer < Data means current node is next one
 | |
|       //
 | |
|       *Buffer = Data;
 | |
|       return EFI_SUCCESS;
 | |
|     }
 | |
|     //
 | |
|     // Not Child
 | |
|     //
 | |
|     Index ++;
 | |
|   }
 | |
| 
 | |
|   *Buffer = NULL;
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Return the child objects buffer from AML Handle's object child list.
 | |
|   
 | |
|   @param[in]        AmlParentHandle Parent handle.
 | |
|   @param[in]        AmlHandle       The current child handle.
 | |
|   @param[out]       Buffer          On return, points to the next returned child buffer or NULL if there are no
 | |
|                                     child buffer.
 | |
| 
 | |
|   @retval EFI_SUCCESS               Success
 | |
|   @retval EFI_INVALID_PARAMETER     AmlParentHandle does not refer to a valid ACPI object.                                
 | |
| **/
 | |
| EFI_STATUS
 | |
| AmlGetChildFromObjectChildList (
 | |
|   IN EFI_AML_HANDLE         *AmlParentHandle,
 | |
|   IN EFI_AML_HANDLE         *AmlHandle,
 | |
|   OUT VOID                  **Buffer
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS          Status;
 | |
|   UINT8               *CurrentBuffer;
 | |
| 
 | |
|   CurrentBuffer = NULL;
 | |
| 
 | |
|   if ((AmlParentHandle->AmlByteEncoding->Attribute & AML_HAS_CHILD_OBJ) == 0) {
 | |
|     //
 | |
|     // No ObjectList
 | |
|     //
 | |
|     *Buffer = NULL;
 | |
|     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 (AmlParentHandle, &CurrentBuffer);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Go through all the reset buffer.
 | |
|   //
 | |
|   if ((UINTN)AmlHandle->Buffer < (UINTN)CurrentBuffer) {
 | |
|     //
 | |
|     // Buffer < Data means next node is first object
 | |
|     //
 | |
|   } else if ((UINTN)AmlHandle->Buffer + AmlHandle->Size < (UINTN)AmlParentHandle->Buffer + AmlParentHandle->Size) {
 | |
|     //
 | |
|     // There is still more node
 | |
|     //
 | |
|     CurrentBuffer = AmlHandle->Buffer + AmlHandle->Size;
 | |
|   } else {
 | |
|     //
 | |
|     // No more data
 | |
|     //
 | |
|     *Buffer = NULL;
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   return AmlGetChildFromObjectBuffer (AmlParentHandle, CurrentBuffer, Buffer);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Return the child ACPI objects from Non-Root Handle.
 | |
|   
 | |
|   @param[in]        AmlParentHandle Parent handle. It is Non-Root Handle.
 | |
|   @param[in]        AmlHandle       The previously returned handle or NULL to start with the first handle.
 | |
|   @param[out]       Buffer          On return, points to the next returned ACPI handle or NULL if there are no
 | |
|                                     child objects.
 | |
| 
 | |
|   @retval EFI_SUCCESS               Success
 | |
|   @retval EFI_INVALID_PARAMETER     ParentHandle is NULL or does not refer to a valid ACPI object.                                
 | |
| **/
 | |
| EFI_STATUS
 | |
| AmlGetChildFromNonRoot (
 | |
|   IN EFI_AML_HANDLE         *AmlParentHandle,
 | |
|   IN EFI_AML_HANDLE         *AmlHandle,
 | |
|   OUT VOID                  **Buffer
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS          Status;
 | |
| 
 | |
|   if (AmlHandle == NULL) {
 | |
|     //
 | |
|     // NULL means first one
 | |
|     //
 | |
|     AmlHandle = AmlParentHandle;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // 1. Get Option
 | |
|   //
 | |
|   Status = AmlGetChildFromOptionList (AmlParentHandle, AmlHandle, Buffer);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
|   if (*Buffer != NULL) {
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // 2. search ObjectList
 | |
|   //
 | |
|   return AmlGetChildFromObjectChildList (AmlParentHandle, AmlHandle, Buffer);
 | |
| }
 |