/** Return offset of last option. @param[in] AmlHandle AML Handle. @param[out] Buffer Upon return, points to the offset after last option. @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER AmlHandle does not refer to a valid ACPI object. **/ EFI_STATUS AmlGetOffsetAfterLastOption ( IN EFI_AML_HANDLE *AmlHandle, OUT UINT8 **Buffer ) { EFI_ACPI_DATA_TYPE DataType; VOID *Data; UINTN DataSize; EFI_STATUS Status; Status = AmlParseOptionHandleCommon ( AmlHandle, AmlHandle->AmlByteEncoding->MaxIndex, &DataType, &Data, &DataSize ); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } // // We need to parse the rest buffer after last node. // *Buffer = (UINT8 *)((UINTN)Data + DataSize); // // We need skip PkgLength if no Option // if (DataType == EFI_ACPI_DATA_TYPE_OPCODE) { *Buffer += AmlGetPkgLength (*Buffer, &DataSize); } return EFI_SUCCESS; }
/** 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; }
/** Retrieve information about an ACPI object. @param[in] Handle ACPI object handle. @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right in the ACPI encoding, with index 0 always being the ACPI opcode. @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists for the specified index. @param[out] Data Upon return, points to the pointer to the data. @param[out] DataSize Upon return, points to the size of Data. @retval EFI_SUCCESS Success. @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object. **/ EFI_STATUS EFIAPI GetOption ( IN EFI_ACPI_HANDLE Handle, IN UINTN Index, OUT EFI_ACPI_DATA_TYPE *DataType, OUT CONST VOID **Data, OUT UINTN *DataSize ) { EFI_AML_HANDLE *AmlHandle; AML_BYTE_ENCODING *AmlByteEncoding; EFI_STATUS Status; ASSERT (DataType != NULL); ASSERT (Data != NULL); ASSERT (DataSize != NULL); // // Check for invalid input parameters // if (Handle == NULL) { return EFI_INVALID_PARAMETER; } AmlHandle = (EFI_AML_HANDLE *)Handle; // // Do not check EFI_AML_ROOT_HANDLE_SIGNATURE because there is no option for Root handle // if (AmlHandle->Signature != EFI_AML_HANDLE_SIGNATURE) { return EFI_INVALID_PARAMETER; } AmlByteEncoding = AmlHandle->AmlByteEncoding; if (Index > AmlByteEncoding->MaxIndex) { *DataType = EFI_ACPI_DATA_TYPE_NONE; return EFI_SUCCESS; } // // Parse option // Status = AmlParseOptionHandleCommon (AmlHandle, (AML_OP_PARSE_INDEX)Index, DataType, (VOID **)Data, DataSize); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } return EFI_SUCCESS; }
/** Return object name. @param[in] AmlHandle AML handle. @return Name of the object. **/ CHAR8 * AmlGetObjectName ( IN EFI_AML_HANDLE *AmlHandle ) { AML_BYTE_ENCODING *AmlByteEncoding; VOID *NameString; UINTN NameSize; AML_OP_PARSE_INDEX TermIndex; EFI_STATUS Status; EFI_ACPI_DATA_TYPE DataType; AmlByteEncoding = AmlHandle->AmlByteEncoding; ASSERT ((AmlByteEncoding->Attribute & AML_IN_NAMESPACE) != 0); // // Find out Last Name index, according to OpCode table. // The last name will be the node name by design. // TermIndex = AmlByteEncoding->MaxIndex; for (TermIndex = AmlByteEncoding->MaxIndex; TermIndex > 0; TermIndex--) { if (AmlByteEncoding->Format[TermIndex - 1] == AML_NAME) { break; } } ASSERT (TermIndex != 0); // // Get Name for this node. // Status = AmlParseOptionHandleCommon ( AmlHandle, TermIndex, &DataType, &NameString, &NameSize ); if (EFI_ERROR (Status)) { return NULL; } ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING); return NameString; }
/** Change information about an ACPI object. @param[in] Handle ACPI object handle. @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right in the ACPI encoding, with index 0 always being the ACPI opcode. @param[in] Data Points to the data. @param[in] DataSize The size of the Data. @retval EFI_SUCCESS Success @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object. @retval EFI_BAD_BUFFER_SIZE Data cannot be accommodated in the space occupied by the option. **/ EFI_STATUS EFIAPI SetOption ( IN EFI_ACPI_HANDLE Handle, IN UINTN Index, IN CONST VOID *Data, IN UINTN DataSize ) { EFI_AML_HANDLE *AmlHandle; AML_BYTE_ENCODING *AmlByteEncoding; EFI_STATUS Status; EFI_ACPI_DATA_TYPE DataType; VOID *OrgData; UINTN OrgDataSize; ASSERT (Data != NULL); // // Check for invalid input parameters // if (Handle == NULL) { return EFI_INVALID_PARAMETER; } AmlHandle = (EFI_AML_HANDLE *)Handle; // // Do not check EFI_AML_ROOT_HANDLE_SIGNATURE because there is no option for Root handle // if (AmlHandle->Signature != EFI_AML_HANDLE_SIGNATURE) { return EFI_INVALID_PARAMETER; } AmlByteEncoding = AmlHandle->AmlByteEncoding; if (Index > AmlByteEncoding->MaxIndex) { return EFI_INVALID_PARAMETER; } // // Parse option // Status = AmlParseOptionHandleCommon (AmlHandle, (AML_OP_PARSE_INDEX)Index, &DataType, &OrgData, &OrgDataSize); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } if (DataType == EFI_ACPI_DATA_TYPE_NONE) { return EFI_INVALID_PARAMETER; } if (DataSize > OrgDataSize) { return EFI_BAD_BUFFER_SIZE; } // // Update // CopyMem (OrgData, Data, DataSize); AmlHandle->Modified = TRUE; return EFI_SUCCESS; }