/** @file ACPI Sdt Protocol Driver Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
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); }