|
@@ -446,7 +446,7 @@ struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
|
|
|
* RETURN: None
|
|
|
*
|
|
|
* DESCRIPTION: Install an ACPI table into the global data structure. The
|
|
|
- * table override mechanism is implemented here to allow the host
|
|
|
+ * table override mechanism is called to allow the host
|
|
|
* OS to replace any table before it is installed in the root
|
|
|
* table array.
|
|
|
*
|
|
@@ -456,11 +456,9 @@ void
|
|
|
acpi_tb_install_table(acpi_physical_address address,
|
|
|
char *signature, u32 table_index)
|
|
|
{
|
|
|
- u8 flags;
|
|
|
- acpi_status status;
|
|
|
- struct acpi_table_header *table_to_install;
|
|
|
- struct acpi_table_header *mapped_table;
|
|
|
- struct acpi_table_header *override_table = NULL;
|
|
|
+ struct acpi_table_header *table;
|
|
|
+ struct acpi_table_header *final_table;
|
|
|
+ struct acpi_table_desc *table_desc;
|
|
|
|
|
|
if (!address) {
|
|
|
ACPI_ERROR((AE_INFO,
|
|
@@ -471,69 +469,78 @@ acpi_tb_install_table(acpi_physical_address address,
|
|
|
|
|
|
/* Map just the table header */
|
|
|
|
|
|
- mapped_table =
|
|
|
- acpi_os_map_memory(address, sizeof(struct acpi_table_header));
|
|
|
- if (!mapped_table) {
|
|
|
+ table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
|
|
|
+ if (!table) {
|
|
|
+ ACPI_ERROR((AE_INFO,
|
|
|
+ "Could not map memory for table [%s] at %p",
|
|
|
+ signature, ACPI_CAST_PTR(void, address)));
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
/* If a particular signature is expected (DSDT/FACS), it must match */
|
|
|
|
|
|
- if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
|
|
|
+ if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
|
|
|
ACPI_ERROR((AE_INFO,
|
|
|
"Invalid signature 0x%X for ACPI table, expected [%s]",
|
|
|
- *ACPI_CAST_PTR(u32, mapped_table->signature),
|
|
|
- signature));
|
|
|
+ *ACPI_CAST_PTR(u32, table->signature), signature));
|
|
|
goto unmap_and_exit;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Initialize the table entry. Set the pointer to NULL, since the
|
|
|
+ * table is not fully mapped at this time.
|
|
|
+ */
|
|
|
+ table_desc = &acpi_gbl_root_table_list.tables[table_index];
|
|
|
+
|
|
|
+ table_desc->address = address;
|
|
|
+ table_desc->pointer = NULL;
|
|
|
+ table_desc->length = table->length;
|
|
|
+ table_desc->flags = ACPI_TABLE_ORIGIN_MAPPED;
|
|
|
+ ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature);
|
|
|
+
|
|
|
/*
|
|
|
* ACPI Table Override:
|
|
|
*
|
|
|
* Before we install the table, let the host OS override it with a new
|
|
|
* one if desired. Any table within the RSDT/XSDT can be replaced,
|
|
|
* including the DSDT which is pointed to by the FADT.
|
|
|
+ *
|
|
|
+ * NOTE: If the table is overridden, then final_table will contain a
|
|
|
+ * mapped pointer to the full new table. If the table is not overridden,
|
|
|
+ * or if there has been a physical override, then the table will be
|
|
|
+ * fully mapped later (in verify table). In any case, we must
|
|
|
+ * unmap the header that was mapped above.
|
|
|
*/
|
|
|
- status = acpi_os_table_override(mapped_table, &override_table);
|
|
|
- if (ACPI_SUCCESS(status) && override_table) {
|
|
|
- ACPI_INFO((AE_INFO,
|
|
|
- "%4.4s @ 0x%p Table override, replaced with:",
|
|
|
- mapped_table->signature, ACPI_CAST_PTR(void,
|
|
|
- address)));
|
|
|
-
|
|
|
- acpi_gbl_root_table_list.tables[table_index].pointer =
|
|
|
- override_table;
|
|
|
- address = ACPI_PTR_TO_PHYSADDR(override_table);
|
|
|
-
|
|
|
- table_to_install = override_table;
|
|
|
- flags = ACPI_TABLE_ORIGIN_OVERRIDE;
|
|
|
- } else {
|
|
|
- table_to_install = mapped_table;
|
|
|
- flags = ACPI_TABLE_ORIGIN_MAPPED;
|
|
|
+ final_table = acpi_tb_table_override(table, table_desc);
|
|
|
+ if (!final_table) {
|
|
|
+ final_table = table; /* There was no override */
|
|
|
}
|
|
|
|
|
|
- /* Initialize the table entry */
|
|
|
+ acpi_tb_print_table_header(table_desc->address, final_table);
|
|
|
|
|
|
- acpi_gbl_root_table_list.tables[table_index].address = address;
|
|
|
- acpi_gbl_root_table_list.tables[table_index].length =
|
|
|
- table_to_install->length;
|
|
|
- acpi_gbl_root_table_list.tables[table_index].flags = flags;
|
|
|
-
|
|
|
- ACPI_MOVE_32_TO_32(&
|
|
|
- (acpi_gbl_root_table_list.tables[table_index].
|
|
|
- signature), table_to_install->signature);
|
|
|
-
|
|
|
- acpi_tb_print_table_header(address, table_to_install);
|
|
|
+ /* Set the global integer width (based upon revision of the DSDT) */
|
|
|
|
|
|
if (table_index == ACPI_TABLE_INDEX_DSDT) {
|
|
|
+ acpi_ut_set_integer_width(final_table->revision);
|
|
|
+ }
|
|
|
|
|
|
- /* Global integer width is based upon revision of the DSDT */
|
|
|
-
|
|
|
- acpi_ut_set_integer_width(table_to_install->revision);
|
|
|
+ /*
|
|
|
+ * If we have a physical override during this early loading of the ACPI
|
|
|
+ * tables, unmap the table for now. It will be mapped again later when
|
|
|
+ * it is actually used. This supports very early loading of ACPI tables,
|
|
|
+ * before virtual memory is fully initialized and running within the
|
|
|
+ * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE
|
|
|
+ * flag set and will not be deleted below.
|
|
|
+ */
|
|
|
+ if (final_table != table) {
|
|
|
+ acpi_tb_delete_table(table_desc);
|
|
|
}
|
|
|
|
|
|
unmap_and_exit:
|
|
|
- acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
|
|
|
+
|
|
|
+ /* Always unmap the table header that we mapped above */
|
|
|
+
|
|
|
+ acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
|
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|