diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/ACPI/AmlChild.c | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/EM/ACPI/AmlChild.c')
-rw-r--r-- | Core/EM/ACPI/AmlChild.c | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/Core/EM/ACPI/AmlChild.c b/Core/EM/ACPI/AmlChild.c new file mode 100644 index 0000000..1c6ecc2 --- /dev/null +++ b/Core/EM/ACPI/AmlChild.c @@ -0,0 +1,326 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** + +//********************************************************************** +// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AmlChild.c 2 5/14/11 2:10p Yakovlevs $ +// +// $Revision: 2 $ +// +// $Date: 5/14/11 2:10p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AmlChild.c $ +// +// 2 5/14/11 2:10p Yakovlevs +// [TAG] EIP 56526 +// [Category] New Feature +// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section +// 9. Initial checkin. +// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c; +// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c; +// Protocol\AcpiSdt.h. +// +//********************************************************************** + + +//********************************************************************** +//<AMI_FHDR_START> +// +// Name: AmlChild.c +// +// Description: +// ACPI AML Name space parsing/manipulation functions for ACPI SDT. +// +//<AMI_FHDR_END> +//********************************************************************** + +#include "AcpiCore.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; + + 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); +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2011, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** |