Ejemplo n.º 1
0
void acpi_tb_parse_fadt(u32 table_index)
{
	u32 length;
	struct acpi_table_header *table;

	
	length = acpi_gbl_root_table_list.tables[table_index].length;

	table =
	    acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
			       address, length);
	if (!table) {
		return;
	}

	
	(void)acpi_tb_verify_checksum(table, length);

	

	acpi_tb_create_local_fadt(table, length);

	

	acpi_os_unmap_memory(table, length);

	

	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
			      ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);

	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
			      ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
}
Ejemplo n.º 2
0
void acpi_tb_parse_fadt(u32 table_index)
{
	u32 length;
	struct acpi_table_header *table;

	/*
	 * The FADT has multiple versions with different lengths,
	 * and it contains pointers to both the DSDT and FACS tables.
	 *
	 * Get a local copy of the FADT and convert it to a common format
	 * Map entire FADT, assumed to be smaller than one page.
	 */
	length = acpi_gbl_root_table_list.tables[table_index].length;

	table =
	    acpi_os_map_memory(acpi_gbl_root_table_list.tables[table_index].
			       address, length);
	if (!table) {
		return;
	}

	/*
	 * Validate the FADT checksum before we copy the table. Ignore
	 * checksum error as we want to try to get the DSDT and FACS.
	 */
	(void)acpi_tb_verify_checksum(table, length);

	/* Create a local copy of the FADT in common ACPI 2.0+ format */

	acpi_tb_create_local_fadt(table, length);

	/* All done with the real FADT, unmap it */

	acpi_os_unmap_memory(table, length);

	/* Obtain the DSDT and FACS tables via their addresses within the FADT */

	acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
			      ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);

	/* If Hardware Reduced flag is set, there is no FACS */

	if (!acpi_gbl_reduced_hardware) {
		acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.
				      Xfacs, ACPI_SIG_FACS,
				      ACPI_TABLE_INDEX_FACS);
	}
}
Ejemplo n.º 3
0
acpi_status
acpi_tb_get_primary_table (
	struct acpi_pointer             *address,
	struct acpi_table_desc          *table_info)
{
	acpi_status                     status;
	struct acpi_table_header        header;


	ACPI_FUNCTION_TRACE ("tb_get_primary_table");


	/* Ignore a NULL address in the RSDT */

	if (!address->pointer.value) {
		return_ACPI_STATUS (AE_OK);
	}

	/*
	 * Get the header in order to get signature and table size
	 */
	status = acpi_tb_get_table_header (address, &header);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Clear the table_info */

	ACPI_MEMSET (table_info, 0, sizeof (struct acpi_table_desc));

	/*
	 * Check the table signature and make sure it is recognized.
	 * Also checks the header checksum
	 */
	table_info->pointer = &header;
	status = acpi_tb_recognize_table (table_info, ACPI_TABLE_PRIMARY);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Get the entire table */

	status = acpi_tb_get_table_body (address, &header, table_info);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Install the table */

	status = acpi_tb_install_table (table_info);
	return_ACPI_STATUS (status);
}
Ejemplo n.º 4
0
static acpi_status
acpi_tb_get_secondary_table (
	struct acpi_pointer             *address,
	acpi_string                     signature,
	struct acpi_table_desc          *table_info)
{
	acpi_status                     status;
	struct acpi_table_header        header;


	ACPI_FUNCTION_TRACE_STR ("tb_get_secondary_table", signature);


	/* Get the header in order to match the signature */

	status = acpi_tb_get_table_header (address, &header);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Signature must match request */

	if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) {
		ACPI_REPORT_ERROR ((
			"Incorrect table signature - wanted [%s] found [%4.4s]\n",
			signature, header.signature));
		return_ACPI_STATUS (AE_BAD_SIGNATURE);
	}

	/*
	 * Check the table signature and make sure it is recognized.
	 * Also checks the header checksum
	 */
	table_info->pointer = &header;
	status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Get the entire table */

	status = acpi_tb_get_table_body (address, &header, table_info);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Install the table */

	status = acpi_tb_install_table (table_info);
	return_ACPI_STATUS (status);
}
Ejemplo n.º 5
0
acpi_status
acpi_load_table (
	acpi_table_header       *table_ptr)
{
	acpi_status             status;
	acpi_table_desc         table_info;


	FUNCTION_TRACE ("Acpi_load_table");


	if (!table_ptr) {
		return_ACPI_STATUS (AE_BAD_PARAMETER);
	}

	/* Copy the table to a local buffer */

	status = acpi_tb_get_table (0, table_ptr, &table_info);
	if (ACPI_FAILURE (status)) {
		return_ACPI_STATUS (status);
	}

	/* Install the new table into the local data structures */

	status = acpi_tb_install_table (NULL, &table_info);
	if (ACPI_FAILURE (status)) {
		/* Free table allocated by Acpi_tb_get_table */

		acpi_tb_delete_single_table (&table_info);
		return_ACPI_STATUS (status);
	}


	status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
	if (ACPI_FAILURE (status)) {
		/* Uninstall table and free the buffer */

		acpi_tb_uninstall_table (table_info.installed_desc);
		return_ACPI_STATUS (status);
	}


	return_ACPI_STATUS (status);
}
Ejemplo n.º 6
0
acpi_status
acpi_load_table (
    struct acpi_table_header        *table_ptr)
{
    acpi_status                     status;
    struct acpi_table_desc          table_info;
    struct acpi_pointer             address;


    ACPI_FUNCTION_TRACE ("acpi_load_table");


    if (!table_ptr) {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /* Copy the table to a local buffer */

    address.pointer_type    = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
    address.pointer.logical = table_ptr;

    status = acpi_tb_get_table_body (&address, table_ptr, &table_info);
    if (ACPI_FAILURE (status)) {
        return_ACPI_STATUS (status);
    }

    /* Install the new table into the local data structures */

    status = acpi_tb_install_table (&table_info);
    if (ACPI_FAILURE (status)) {
        /* Free table allocated by acpi_tb_get_table_body */

        acpi_tb_delete_single_table (&table_info);
        return_ACPI_STATUS (status);
    }

    /* Convert the table to common format if necessary */

    switch (table_info.type) {
    case ACPI_TABLE_FADT:

        status = acpi_tb_convert_table_fadt ();
        break;

    case ACPI_TABLE_FACS:

        status = acpi_tb_build_common_facs (&table_info);
        break;

    default:
        /* Load table into namespace if it contains executable AML */

        status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
        break;
    }

    if (ACPI_FAILURE (status)) {
        /* Uninstall table and free the buffer */

        (void) acpi_tb_uninstall_table (table_info.installed_desc);
    }

    return_ACPI_STATUS (status);
}
Ejemplo n.º 7
0
static acpi_status
acpi_ex_add_table(struct acpi_table_header *table,
		  struct acpi_namespace_node *parent_node,
		  union acpi_operand_object **ddb_handle)
{
	acpi_status status;
	struct acpi_table_desc table_info;
	union acpi_operand_object *obj_desc;

	ACPI_FUNCTION_TRACE(ex_add_table);

	/* Create an object to be the table handle */

	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE);
	if (!obj_desc) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	/* Init the table handle */

	obj_desc->reference.opcode = AML_LOAD_OP;
	*ddb_handle = obj_desc;

	/* Install the new table into the local data structures */

	ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc));

	table_info.type = ACPI_TABLE_ID_SSDT;
	table_info.pointer = table;
	table_info.length = (acpi_size) table->length;
	table_info.allocation = ACPI_MEM_ALLOCATED;

	status = acpi_tb_install_table(&table_info);
	obj_desc->reference.object = table_info.installed_desc;

	if (ACPI_FAILURE(status)) {
		if (status == AE_ALREADY_EXISTS) {

			/* Table already exists, just return the handle */

			return_ACPI_STATUS(AE_OK);
		}
		goto cleanup;
	}

	/* Add the table to the namespace */

	status = acpi_ns_load_table(table_info.installed_desc, parent_node);
	if (ACPI_FAILURE(status)) {

		/* Uninstall table on error */

		(void)acpi_tb_uninstall_table(table_info.installed_desc);
		goto cleanup;
	}

	return_ACPI_STATUS(AE_OK);

      cleanup:
	acpi_ut_remove_reference(obj_desc);
	*ddb_handle = NULL;
	return_ACPI_STATUS(status);
}