Esempio n. 1
0
/*******************************************************************************
 *
 * FUNCTION:    acpi_load_table
 *
 * PARAMETERS:  table               - Pointer to a buffer containing the ACPI
 *                                    table to be loaded.
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must
 *              be a valid ACPI table with a valid ACPI table header.
 *              Note1: Mainly intended to support hotplug addition of SSDTs.
 *              Note2: Does not copy the incoming table. User is responsible
 *              to ensure that the table is not deleted or unmapped.
 *
 ******************************************************************************/
acpi_status acpi_load_table(struct acpi_table_header *table)
{
	acpi_status status;
	u32 table_index;

	ACPI_FUNCTION_TRACE(acpi_load_table);

	/* Parameter validation */

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

	/* Must acquire the interpreter lock during this operation */

	status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/* Install the table and load it into the namespace */

	ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:"));
	(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);

	status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
						ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
						TRUE, FALSE, &table_index);

	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
	if (ACPI_FAILURE(status)) {
		goto unlock_and_exit;
	}

	/*
	 * Note: Now table is "INSTALLED", it must be validated before
	 * using.
	 */
	status =
	    acpi_tb_validate_table(&acpi_gbl_root_table_list.
				   tables[table_index]);
	if (ACPI_FAILURE(status)) {
		goto unlock_and_exit;
	}

	status = acpi_ns_load_table(table_index, acpi_gbl_root_node);

	/* Invoke table handler if present */

	if (acpi_gbl_table_handler) {
		(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
					     acpi_gbl_table_handler_context);
	}

unlock_and_exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
	return_ACPI_STATUS(status);
}
Esempio n. 2
0
acpi_status ACPI_INIT_FUNCTION
acpi_install_table(acpi_physical_address address, u8 physical)
{
	acpi_status status;
	u8 flags;
	u32 table_index;

	ACPI_FUNCTION_TRACE(acpi_install_table);

	if (physical) {
		flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL;
	} else {
		flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL;
	}

	status = acpi_tb_install_standard_table(address, flags,
						FALSE, FALSE, &table_index);

	return_ACPI_STATUS(status);
}
void acpi_tb_parse_fadt(void)
{
	u32 length;
	struct acpi_table_header *table;
	struct acpi_table_desc *fadt_desc;
	acpi_status status;

	/*
	 * 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.
	 */
	fadt_desc = &acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index];
	status = acpi_tb_get_table(fadt_desc, &table);
	if (ACPI_FAILURE(status)) {
		return;
	}
	length = fadt_desc->length;

	/*
	 * 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_tb_put_table(fadt_desc);

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

	acpi_tb_install_standard_table((acpi_physical_address)acpi_gbl_FADT.
				       Xdsdt,
				       ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
				       FALSE, TRUE, &acpi_gbl_dsdt_index);

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

	if (!acpi_gbl_reduced_hardware) {
		if (acpi_gbl_FADT.facs) {
			acpi_tb_install_standard_table((acpi_physical_address)
						       acpi_gbl_FADT.facs,
						       ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
						       FALSE, TRUE,
						       &acpi_gbl_facs_index);
		}
		if (acpi_gbl_FADT.Xfacs) {
			acpi_tb_install_standard_table((acpi_physical_address)
						       acpi_gbl_FADT.Xfacs,
						       ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL,
						       FALSE, TRUE,
						       &acpi_gbl_xfacs_index);
		}
	}
}