/** 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; }
/** Create a handle from an ACPI opcode @param[in] Buffer Points to the ACPI opcode. @param[in] BufferSize Max buffer size. @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 SdtOpenEx ( IN VOID *Buffer, IN UINTN BufferSize, OUT EFI_ACPI_HANDLE *Handle ) { AML_BYTE_ENCODING *AmlByteEncoding; EFI_AML_HANDLE *AmlHandle; AmlByteEncoding = AmlSearchByOpByte (Buffer); if (AmlByteEncoding == NULL) { return EFI_INVALID_PARAMETER; } // // Do not open NameString as handle // if ((AmlByteEncoding->Attribute & AML_IS_NAME_CHAR) != 0) { return EFI_INVALID_PARAMETER; } // // Good, find it // AmlHandle = AllocatePool (sizeof(*AmlHandle)); ASSERT (AmlHandle != NULL); AmlHandle->Signature = EFI_AML_HANDLE_SIGNATURE; AmlHandle->Buffer = Buffer; AmlHandle->AmlByteEncoding = AmlByteEncoding; AmlHandle->Modified = FALSE; AmlHandle->Size = AmlGetObjectSize (AmlByteEncoding, Buffer, BufferSize); if (AmlHandle->Size == 0) { FreePool (AmlHandle); return EFI_INVALID_PARAMETER; } *Handle = (EFI_ACPI_HANDLE)AmlHandle; return EFI_SUCCESS; }
/** Retrieve option term according to AmlByteEncoding and Buffer. @param[in] AmlByteEncoding AML Byte Encoding. @param[in] Buffer AML buffer. @param[in] MaxBufferSize AML buffer MAX size. The parser can not parse any data exceed this region. @param[in] TermIndex Index of the data to retrieve from the object. @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 Buffer does not refer to a valid ACPI object. **/ EFI_STATUS AmlParseOptionTerm ( IN AML_BYTE_ENCODING *AmlByteEncoding, IN UINT8 *Buffer, IN UINTN MaxBufferSize, IN AML_OP_PARSE_INDEX TermIndex, OUT EFI_ACPI_DATA_TYPE *DataType, OUT VOID **Data, OUT UINTN *DataSize ) { AML_BYTE_ENCODING *ChildAmlByteEncoding; EFI_STATUS Status; if (DataType != NULL) { *DataType = AmlTypeToAcpiType (AmlByteEncoding->Format[TermIndex - 1]); } if (Data != NULL) { *Data = Buffer; } // // Parse term according to AML type // switch (AmlByteEncoding->Format[TermIndex - 1]) { case AML_UINT8: *DataSize = sizeof(UINT8); break; case AML_UINT16: *DataSize = sizeof(UINT16); break; case AML_UINT32: *DataSize = sizeof(UINT32); break; case AML_UINT64: *DataSize = sizeof(UINT64); break; case AML_STRING: *DataSize = AsciiStrSize((CHAR8 *)Buffer); break; case AML_NAME: Status = AmlGetNameStringSize (Buffer, DataSize); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } break; case AML_OBJECT: ChildAmlByteEncoding = AmlSearchByOpByte (Buffer); if (ChildAmlByteEncoding == NULL) { return EFI_INVALID_PARAMETER; } // // NOTE: We need override DataType here, if there is a case the AML_OBJECT is AML_NAME. // We need convert type from EFI_ACPI_DATA_TYPE_CHILD to EFI_ACPI_DATA_TYPE_NAME_STRING. // We should not return CHILD because there is NO OpCode for NameString. // if ((ChildAmlByteEncoding->Attribute & AML_IS_NAME_CHAR) != 0) { if (DataType != NULL) { *DataType = AmlTypeToAcpiType (AML_NAME); } Status = AmlGetNameStringSize (Buffer, DataSize); if (EFI_ERROR (Status)) { return EFI_INVALID_PARAMETER; } break; } // // It is real AML_OBJECT // *DataSize = AmlGetObjectSize ( ChildAmlByteEncoding, Buffer, MaxBufferSize ); if (*DataSize == 0) { return EFI_INVALID_PARAMETER; } break; case AML_NONE: // // No term // case AML_OPCODE: default: ASSERT (FALSE); return EFI_INVALID_PARAMETER; } if (*DataSize > MaxBufferSize) { return EFI_INVALID_PARAMETER; } return EFI_SUCCESS; }