/** Returns the handle of the ACPI object representing the specified ACPI path @param[in] HandleIn Points to the handle of the object representing the starting point for the path search. @param[in] AmlPath Points to the AML path. @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to HandleIn. @retval EFI_SUCCESS Success @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object. **/ EFI_STATUS SdtFindPathFromNonRoot ( IN EFI_ACPI_HANDLE HandleIn, IN UINT8 *AmlPath, OUT EFI_ACPI_HANDLE *HandleOut ) { EFI_AML_HANDLE *AmlHandle; VOID *Buffer; EFI_STATUS Status; AmlHandle = (EFI_AML_HANDLE *)HandleIn; // // For non-root handle, we need search from THIS node instead of ROOT. // Status = AmlFindPath (AmlHandle, AmlPath, &Buffer, FALSE); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } if (Buffer == NULL) { *HandleOut = NULL; return EFI_SUCCESS; } return SdtOpenEx (Buffer, (UINTN)AmlHandle->Buffer + AmlHandle->Size - (UINTN)Buffer, HandleOut); }
/** Create a handle from an ACPI opcode @param[in] Buffer Points to the ACPI opcode. @param[out] Handle Upon return, holds the handle. @retval EFI_SUCCESS Success @retval EFI_INVALID_PARAMETER Buffer is NULL or Handle is NULL or Buffer points to an invalid opcode. **/ EFI_STATUS EFIAPI Open ( IN VOID *Buffer, OUT EFI_ACPI_HANDLE *Handle ) { EFI_STATUS Status; UINTN MaxSize; MaxSize = 0; // // Check for invalid input parameters // if (Buffer == NULL || Handle == NULL) { return EFI_INVALID_PARAMETER; } Status = SdtGetMaxAmlBufferSize (Buffer, &MaxSize); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } return SdtOpenEx (Buffer, MaxSize, Handle); }
/** Return the child ACPI objects. @param[in] ParentHandle Parent handle. @param[in, out] Handle On entry, points to the previously returned handle or NULL to start with the first handle. 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 EFIAPI GetChild ( IN EFI_ACPI_HANDLE ParentHandle, IN OUT EFI_ACPI_HANDLE *Handle ) { EFI_AML_HANDLE *AmlParentHandle; EFI_AML_HANDLE *AmlHandle; VOID *Buffer; EFI_STATUS Status; ASSERT (Handle != NULL); // // Check for invalid input parameters // if (ParentHandle == NULL) { return EFI_INVALID_PARAMETER; } AmlHandle = *Handle; if ((AmlHandle != NULL) && (AmlHandle->Signature != EFI_AML_HANDLE_SIGNATURE)) { return EFI_INVALID_PARAMETER; } AmlParentHandle = (EFI_AML_HANDLE *)ParentHandle; if (AmlParentHandle->Signature == EFI_AML_ROOT_HANDLE_SIGNATURE) { // // Root handle // Status = AmlGetChildFromRoot (AmlParentHandle, AmlHandle, &Buffer); } else if (AmlParentHandle->Signature == EFI_AML_HANDLE_SIGNATURE) { // // Non-root handle // Status = AmlGetChildFromNonRoot (AmlParentHandle, AmlHandle, &Buffer); } else { // // Invalid // return EFI_INVALID_PARAMETER; } if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } if (Buffer == NULL) { *Handle = NULL; return EFI_SUCCESS; } return SdtOpenEx (Buffer, (UINTN)AmlParentHandle->Buffer + AmlParentHandle->Size - (UINTN)Buffer, Handle); }
/** Returns the handle of the ACPI object representing the specified ACPI path @param[in] HandleIn Points to the handle of the object representing the starting point for the path search. @param[in] AmlPath Points to the AML path. @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to HandleIn. @retval EFI_SUCCESS Success @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object. **/ EFI_STATUS SdtFindPathFromRoot ( IN EFI_ACPI_HANDLE HandleIn, IN UINT8 *AmlPath, OUT EFI_ACPI_HANDLE *HandleOut ) { EFI_ACPI_HANDLE ChildHandle; EFI_AML_HANDLE *AmlHandle; EFI_STATUS Status; VOID *Buffer; AmlHandle = (EFI_AML_HANDLE *)HandleIn; // // Handle case that AcpiPath is Root // if (AmlIsRootPath (AmlPath)) { // // Duplicate RootHandle // *HandleOut = (EFI_ACPI_HANDLE)SdtDuplicateHandle (AmlHandle); return EFI_SUCCESS; } // // Let children find it. // ChildHandle = NULL; while (TRUE) { Status = GetChild (HandleIn, &ChildHandle); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } if (ChildHandle == NULL) { // // Not found // *HandleOut = NULL; return EFI_SUCCESS; } // // More child // AmlHandle = (EFI_AML_HANDLE *)ChildHandle; Status = AmlFindPath (AmlHandle, AmlPath, &Buffer, TRUE); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } if (Buffer != NULL) { // // Great! Find it, open // Status = SdtOpenEx (Buffer, (UINTN)AmlHandle->Buffer + AmlHandle->Size - (UINTN)Buffer, HandleOut); if (!EFI_ERROR (Status)) { return EFI_SUCCESS; } // // Not success, try next one // } } // // Should not run here // }
/** 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; }