/** Insert the NameString to the AmlNodeList. @param[in] NameString AML NameString. @param[in] Buffer Buffer for the Node. @param[in] Size Size for the Node. @param[in] AmlRootNodeList AML root node list. @param[in] AmlParentNodeList AML parent node list. @return AmlChildNode whoes name is NameString. **/ EFI_AML_NODE_LIST * AmlInsertNodeToTree ( IN UINT8 *NameString, IN VOID *Buffer, IN UINTN Size, IN EFI_AML_NODE_LIST *AmlRootNodeList, IN EFI_AML_NODE_LIST *AmlParentNodeList ) { EFI_AML_NODE_LIST *AmlNodeList; AmlNodeList = AmlFindNodeInTheTree ( NameString, AmlRootNodeList, AmlParentNodeList, TRUE // Find and Create ); ASSERT (AmlNodeList != NULL); if (AmlNodeList == NULL) { return NULL; } // // Check buffer // if (AmlNodeList->Buffer == NULL) { // // NULL means new added one or SCOPE_OP // if (*(UINT8 *)Buffer != AML_SCOPE_OP) { // // We need check if new one is SCOPE_OP, because SCOPE_OP just means namespace, not a real device. // We should not return SCOPE_OP. // AmlNodeList->Buffer = Buffer; AmlNodeList->Size = Size; AmlNodeList->AmlByteEncoding = AmlSearchByOpByte (Buffer); } return AmlNodeList; } // // Already added // if (*(UINT8 *)Buffer == AML_SCOPE_OP) { // // The new one is SCOPE_OP, OK just return; // return AmlNodeList; } // // Oops!!!, There must be something wrong. // DEBUG ((EFI_D_ERROR, "AML: Override Happen - %a!\n", NameString)); DEBUG ((EFI_D_ERROR, "AML: Existing Node - %x\n", AmlNodeList->Buffer)); DEBUG ((EFI_D_ERROR, "AML: New Buffer - %x\n", Buffer)); return NULL; }
/** 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; }