/******************************************************************************* * * 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); }
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); } } }