https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
		
			
				
	
	
		
			275 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			275 lines
		
	
	
		
			7.7 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"
 | |
| 
 | |
| /**
 | |
|   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);
 | |
| }
 |