Ejemplo n.º 1
0
/**
  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;
}
Ejemplo n.º 2
0
/**
  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;
}