Exemple #1
0
ACPI_STATUS
AcpiGetTableHeader (
    ACPI_TABLE_TYPE         TableType,
    UINT32                  Instance,
    ACPI_TABLE_HEADER       *OutTableHeader)
{
    ACPI_TABLE_HEADER       *TblPtr;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE ("AcpiGetTableHeader");


    if ((Instance == 0)                 ||
        (TableType == ACPI_TABLE_RSDP)  ||
        (!OutTableHeader))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /* Check the table type and instance */

    if ((TableType > ACPI_TABLE_MAX)    ||
        (ACPI_IS_SINGLE_TABLE (AcpiGbl_AcpiTableData[TableType].Flags) &&
         Instance > 1))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }


    /* Get a pointer to the entire table */

    Status = AcpiTbGetTablePtr (TableType, Instance, &TblPtr);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * The function will return a NULL pointer if the table is not loaded
     */
    if (TblPtr == NULL)
    {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    /*
     * Copy the header to the caller's buffer
     */
    ACPI_MEMCPY ((void *) OutTableHeader, (void *) TblPtr,
                sizeof (ACPI_TABLE_HEADER));

    return_ACPI_STATUS (Status);
}
acpi_status
acpi_get_table_header (
    acpi_table_type                 table_type,
    u32                             instance,
    struct acpi_table_header        *out_table_header)
{
    struct acpi_table_header        *tbl_ptr;
    acpi_status                     status;


    ACPI_FUNCTION_TRACE ("acpi_get_table_header");


    if ((instance == 0)                 ||
            (table_type == ACPI_TABLE_RSDP) ||
            (!out_table_header)) {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /* Check the table type and instance */

    if ((table_type > ACPI_TABLE_MAX)   ||
            (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
             instance > 1)) {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }


    /* Get a pointer to the entire table */

    status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
    if (ACPI_FAILURE (status)) {
        return_ACPI_STATUS (status);
    }

    /*
     * The function will return a NULL pointer if the table is not loaded
     */
    if (tbl_ptr == NULL) {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    /*
     * Copy the header to the caller's buffer
     */
    ACPI_MEMCPY ((void *) out_table_header, (void *) tbl_ptr,
                 sizeof (struct acpi_table_header));

    return_ACPI_STATUS (status);
}
acpi_status
acpi_get_table (
    acpi_table_type                 table_type,
    u32                             instance,
    struct acpi_buffer              *ret_buffer)
{
    struct acpi_table_header        *tbl_ptr;
    acpi_status                     status;
    acpi_size                       table_length;


    ACPI_FUNCTION_TRACE ("acpi_get_table");


    /* Parameter validation */

    if (instance == 0) {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    status = acpi_ut_validate_buffer (ret_buffer);
    if (ACPI_FAILURE (status)) {
        return_ACPI_STATUS (status);
    }

    /* Check the table type and instance */

    if ((table_type > ACPI_TABLE_MAX)   ||
            (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
             instance > 1)) {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }


    /* Get a pointer to the entire table */

    status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
    if (ACPI_FAILURE (status)) {
        return_ACPI_STATUS (status);
    }

    /*
     * acpi_tb_get_table_ptr will return a NULL pointer if the
     * table is not loaded.
     */
    if (tbl_ptr == NULL) {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    /* Get the table length */

    if (table_type == ACPI_TABLE_RSDP) {
        /*
         *  RSD PTR is the only "table" without a header
         */
        table_length = sizeof (struct rsdp_descriptor);
    }
    else {
        table_length = (acpi_size) tbl_ptr->length;
    }

    /* Validate/Allocate/Clear caller buffer */

    status = acpi_ut_initialize_buffer (ret_buffer, table_length);
    if (ACPI_FAILURE (status)) {
        return_ACPI_STATUS (status);
    }

    /* Copy the table to the buffer */

    ACPI_MEMCPY ((void *) ret_buffer->pointer, (void *) tbl_ptr, table_length);
    return_ACPI_STATUS (AE_OK);
}
/**ltl
 * 功能:将ACPI表的描述符信息插入到全局列表中
 * 参数:
 * 返回值:
 * 说明:表类型table_type分别为:0(RSDP)、6 (XSDT)、2 (FADT)、5 (SSDT)、5 (SSDT)、3 (FACS)、1 (DSDT)
 */
acpi_status
acpi_tb_init_table_descriptor(acpi_table_type table_type,
			      struct acpi_table_desc *table_info)
{
	struct acpi_table_list *list_head;
	struct acpi_table_desc *table_desc;
	acpi_status status;

	ACPI_FUNCTION_TRACE_U32(tb_init_table_descriptor, table_type);

	/* Allocate a descriptor for this table */
	/* 分配ACPI表描述符信息 */
	table_desc = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_table_desc));
	if (!table_desc) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	/* Get a new owner ID for the table */
	/* 为ACPI表描述符分配ID */
	status = acpi_ut_allocate_owner_id(&table_desc->owner_id);
	if (ACPI_FAILURE(status)) {
		goto error_exit1;
	}

	/* Install the table into the global data structure */
	/* 全局列表 */
	list_head = &acpi_gbl_table_lists[table_type];

	/*
	 * Two major types of tables:  1) Only one instance is allowed.  This
	 * includes most ACPI tables such as the DSDT.  2) Multiple instances of
	 * the table are allowed.  This includes SSDT and PSDTs.
	 */
	/* 如果此ACPI表在系统中只能是唯一一个 */
	if (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags)) {
		/*
		 * Only one table allowed, and a table has alread been installed
		 * at this location, so return an error.
		 */
		if (list_head->next) { /* 表示此表已经存在,退出 */
			status = AE_ALREADY_EXISTS;
			goto error_exit2;
		}
		/*  将ACPI表描述符对象插入到全局列表中 */
		table_desc->next = list_head->next;	
		list_head->next = table_desc;

		if (table_desc->next) {
			table_desc->next->prev = table_desc;
		}

		list_head->count++;
	} else {
		/*
		 * Link the new table in to the list of tables of this type.
		 * Insert at the end of the list, order IS IMPORTANT.
		 *
		 * table_desc->Prev & Next are already NULL from calloc()
		 */
		/* 在系统中引出现多张相同的ACPI表,把它们以链表的形式链接 */
		list_head->count++;

		if (!list_head->next) {
			list_head->next = table_desc;
		} else {
			table_desc->next = list_head->next;

			while (table_desc->next->next) {
				table_desc->next = table_desc->next->next;
			}

			table_desc->next->next = table_desc;
			table_desc->prev = table_desc->next;
			table_desc->next = NULL;
		}
	}

	/* Finish initialization of the table descriptor */

	table_desc->loaded_into_namespace = FALSE;
	table_desc->type = (u8) table_type;
	table_desc->pointer = table_info->pointer;
	table_desc->length = table_info->length;
	table_desc->allocation = table_info->allocation;
	table_desc->aml_start = (u8 *) (table_desc->pointer + 1),
	    table_desc->aml_length = (u32)
	    (table_desc->length - (u32) sizeof(struct acpi_table_header));

	/*
	 * Set the appropriate global pointer (if there is one) to point to the
	 * newly installed table
	 */
	/* 将ACPI表的起始地址保存到global_ptr中。在这语句是对全局变量:acpi_gbl_FADT、acpi_gbl_FACS、acpi_gbl_DSDT
      * 进行赋值
	 */
	if (acpi_gbl_table_data[table_type].global_ptr) { 
		*(acpi_gbl_table_data[table_type].global_ptr) =
		    table_info->pointer;
	}

	/* Return Data */

	table_info->owner_id = table_desc->owner_id;
	table_info->installed_desc = table_desc;
	return_ACPI_STATUS(AE_OK);

	/* Error exit with cleanup */

      error_exit2:

	acpi_ut_release_owner_id(&table_desc->owner_id);

      error_exit1:

	ACPI_FREE(table_desc);
	return_ACPI_STATUS(status);
}
Exemple #5
0
ACPI_STATUS
AcpiGetTable (
    ACPI_TABLE_TYPE         TableType,
    UINT32                  Instance,
    ACPI_BUFFER             *RetBuffer)
{
    ACPI_TABLE_HEADER       *TblPtr;
    ACPI_STATUS             Status;
    ACPI_SIZE               TableLength;


    ACPI_FUNCTION_TRACE ("AcpiGetTable");


    /* Parameter validation */

    if (Instance == 0)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    Status = AcpiUtValidateBuffer (RetBuffer);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Check the table type and instance */

    if ((TableType > ACPI_TABLE_MAX)    ||
        (ACPI_IS_SINGLE_TABLE (AcpiGbl_AcpiTableData[TableType].Flags) &&
         Instance > 1))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }


    /* Get a pointer to the entire table */

    Status = AcpiTbGetTablePtr (TableType, Instance, &TblPtr);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * AcpiTbGetTablePtr will return a NULL pointer if the
     * table is not loaded.
     */
    if (TblPtr == NULL)
    {
        return_ACPI_STATUS (AE_NOT_EXIST);
    }

    /* Get the table length */

    if (TableType == ACPI_TABLE_RSDP)
    {
        /*
         *  RSD PTR is the only "table" without a header
         */
        TableLength = sizeof (RSDP_DESCRIPTOR);
    }
    else
    {
        TableLength = (ACPI_SIZE) TblPtr->Length;
    }

    /* Validate/Allocate/Clear caller buffer */

    Status = AcpiUtInitializeBuffer (RetBuffer, TableLength);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Copy the table to the buffer */

    ACPI_MEMCPY ((void *) RetBuffer->Pointer, (void *) TblPtr, TableLength);
    return_ACPI_STATUS (AE_OK);
}
acpi_status
acpi_tb_init_table_descriptor (
    acpi_table_type                 table_type,
    struct acpi_table_desc          *table_info)
{
    struct acpi_table_list          *list_head;
    struct acpi_table_desc          *table_desc;


    ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type);


    /* Allocate a descriptor for this table */

    table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
    if (!table_desc) {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /*
     * Install the table into the global data structure
     */
    list_head = &acpi_gbl_table_lists[table_type];

    /*
     * Two major types of tables:  1) Only one instance is allowed.  This
     * includes most ACPI tables such as the DSDT.  2) Multiple instances of
     * the table are allowed.  This includes SSDT and PSDTs.
     */
    if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) {
        /*
         * Only one table allowed, and a table has alread been installed
         * at this location, so return an error.
         */
        if (list_head->next) {
            ACPI_MEM_FREE (table_desc);
            return_ACPI_STATUS (AE_ALREADY_EXISTS);
        }

        table_desc->next = list_head->next;
        list_head->next = table_desc;

        if (table_desc->next) {
            table_desc->next->prev = table_desc;
        }

        list_head->count++;
    }
    else {
        /*
         * Link the new table in to the list of tables of this type.
         * Insert at the end of the list, order IS IMPORTANT.
         *
         * table_desc->Prev & Next are already NULL from calloc()
         */
        list_head->count++;

        if (!list_head->next) {
            list_head->next = table_desc;
        }
        else {
            table_desc->next = list_head->next;

            while (table_desc->next->next) {
                table_desc->next = table_desc->next->next;
            }

            table_desc->next->next = table_desc;
            table_desc->prev = table_desc->next;
            table_desc->next = NULL;
        }
    }

    /* Finish initialization of the table descriptor */

    table_desc->type                = (u8) table_type;
    table_desc->pointer             = table_info->pointer;
    table_desc->length              = table_info->length;
    table_desc->allocation          = table_info->allocation;
    table_desc->aml_start           = (u8 *) (table_desc->pointer + 1),
                table_desc->aml_length          = (u32) (table_desc->length -
                        (u32) sizeof (struct acpi_table_header));
    table_desc->table_id            = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_TABLE);
    table_desc->loaded_into_namespace = FALSE;

    /*
     * Set the appropriate global pointer (if there is one) to point to the
     * newly installed table
     */
    if (acpi_gbl_table_data[table_type].global_ptr) {
        *(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer;
    }

    /* Return Data */

    table_info->table_id        = table_desc->table_id;
    table_info->installed_desc  = table_desc;

    return_ACPI_STATUS (AE_OK);
}
Exemple #7
0
ACPI_STATUS
AcpiTbInitTableDescriptor (
    ACPI_TABLE_TYPE         TableType,
    ACPI_TABLE_DESC         *TableInfo)
{
    ACPI_TABLE_LIST         *ListHead;
    ACPI_TABLE_DESC         *TableDesc;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE_U32 (TbInitTableDescriptor, TableType);


    /* Allocate a descriptor for this table */

    TableDesc = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_TABLE_DESC));
    if (!TableDesc)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Get a new owner ID for the table */

    Status = AcpiUtAllocateOwnerId (&TableDesc->OwnerId);
    if (ACPI_FAILURE (Status))
    {
        goto ErrorExit1;
    }

    /* Install the table into the global data structure */

    ListHead = &AcpiGbl_TableLists[TableType];

    /*
     * Two major types of tables:  1) Only one instance is allowed.  This
     * includes most ACPI tables such as the DSDT.  2) Multiple instances of
     * the table are allowed.  This includes SSDT and PSDTs.
     */
    if (ACPI_IS_SINGLE_TABLE (AcpiGbl_TableData[TableType].Flags))
    {
        /*
         * Only one table allowed, and a table has alread been installed
         * at this location, so return an error.
         */
        if (ListHead->Next)
        {
            Status = AE_ALREADY_EXISTS;
            goto ErrorExit2;
        }

        TableDesc->Next = ListHead->Next;
        ListHead->Next = TableDesc;

        if (TableDesc->Next)
        {
            TableDesc->Next->Prev = TableDesc;
        }

        ListHead->Count++;
    }
    else
    {
        /*
         * Link the new table in to the list of tables of this type.
         * Insert at the end of the list, order IS IMPORTANT.
         *
         * TableDesc->Prev & Next are already NULL from calloc()
         */
        ListHead->Count++;

        if (!ListHead->Next)
        {
            ListHead->Next = TableDesc;
        }
        else
        {
            TableDesc->Next = ListHead->Next;

            while (TableDesc->Next->Next)
            {
                TableDesc->Next = TableDesc->Next->Next;
            }

            TableDesc->Next->Next = TableDesc;
            TableDesc->Prev = TableDesc->Next;
            TableDesc->Next = NULL;
        }
    }

    /* Finish initialization of the table descriptor */

    TableDesc->LoadedIntoNamespace = FALSE;
    TableDesc->Type = (UINT8) TableType;
    TableDesc->Pointer = TableInfo->Pointer;
    TableDesc->Length = TableInfo->Length;
    TableDesc->Allocation = TableInfo->Allocation;
    TableDesc->AmlStart = (UINT8 *) (TableDesc->Pointer + 1),
    TableDesc->AmlLength = (UINT32)
        (TableDesc->Length - (UINT32) sizeof (ACPI_TABLE_HEADER));

    /*
     * Set the appropriate global pointer (if there is one) to point to the
     * newly installed table
     */
    if (AcpiGbl_TableData[TableType].GlobalPtr)
    {
        *(AcpiGbl_TableData[TableType].GlobalPtr) = TableInfo->Pointer;
    }

    /* Return Data */

    TableInfo->OwnerId = TableDesc->OwnerId;
    TableInfo->InstalledDesc = TableDesc;
    return_ACPI_STATUS (AE_OK);


    /* Error exit with cleanup */

ErrorExit2:

    AcpiUtReleaseOwnerId (&TableDesc->OwnerId);

ErrorExit1:

    ACPI_FREE (TableDesc);
    return_ACPI_STATUS (Status);
}