ACPICA: Add acpi_os_physical_table_override interface

This interface allows the host to override a table via a
physical address, instead of the logical address required by
acpi_os_table_override. This simplifies the host implementation.
Initial implementation by Thomas Renninger. ACPICA implementation
creates a single function for table overrides that attempts both
a logical and a physical override.

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Bob Moore
2012-02-14 18:31:56 +08:00
gecommit door Len Brown
bovenliggende ea143604c5
commit f7b004a17c
5 gewijzigde bestanden met toevoegingen van 166 en 63 verwijderingen

Bestand weergeven

@@ -114,7 +114,6 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
{
u32 i;
acpi_status status = AE_OK;
struct acpi_table_header *override_table = NULL;
ACPI_FUNCTION_TRACE(tb_add_table);
@@ -224,25 +223,10 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
/*
* ACPI Table Override:
* Allow the host to override dynamically loaded tables.
* NOTE: the table is fully mapped at this point, and the mapping will
* be deleted by tb_table_override if the table is actually overridden.
*/
status = acpi_os_table_override(table_desc->pointer, &override_table);
if (ACPI_SUCCESS(status) && override_table) {
ACPI_INFO((AE_INFO,
"%4.4s @ 0x%p Table override, replaced with:",
table_desc->pointer->signature,
ACPI_CAST_PTR(void, table_desc->address)));
/* We can delete the table that was passed as a parameter */
acpi_tb_delete_table(table_desc);
/* Setup descriptor for the new table */
table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
table_desc->pointer = override_table;
table_desc->length = override_table->length;
table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
}
(void)acpi_tb_table_override(table_desc->pointer, table_desc);
/* Add the table to the global root table list */
@@ -261,6 +245,95 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_table_override
*
* PARAMETERS: table_header - Header for the original table
* table_desc - Table descriptor initialized for the
* original table. May or may not be mapped.
*
* RETURN: Pointer to the entire new table. NULL if table not overridden.
* If overridden, installs the new table within the input table
* descriptor.
*
* DESCRIPTION: Attempt table override by calling the OSL override functions.
* Note: If the table is overridden, then the entire new table
* is mapped and returned by this function.
*
******************************************************************************/
struct acpi_table_header *acpi_tb_table_override(struct acpi_table_header
*table_header,
struct acpi_table_desc
*table_desc)
{
acpi_status status;
struct acpi_table_header *new_table = NULL;
acpi_physical_address new_address = 0;
u32 new_table_length = 0;
u8 new_flags;
char *override_type;
/* (1) Attempt logical override (returns a logical address) */
status = acpi_os_table_override(table_header, &new_table);
if (ACPI_SUCCESS(status) && new_table) {
new_address = ACPI_PTR_TO_PHYSADDR(new_table);
new_table_length = new_table->length;
new_flags = ACPI_TABLE_ORIGIN_OVERRIDE;
override_type = "Logical";
goto finish_override;
}
/* (2) Attempt physical override (returns a physical address) */
status = acpi_os_physical_table_override(table_header,
&new_address,
&new_table_length);
if (ACPI_SUCCESS(status) && new_address && new_table_length) {
/* Map the entire new table */
new_table = acpi_os_map_memory(new_address, new_table_length);
if (!new_table) {
ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY,
"%4.4s %p Attempted physical table override failed",
table_header->signature,
ACPI_CAST_PTR(void,
table_desc->address)));
return (NULL);
}
override_type = "Physical";
new_flags = ACPI_TABLE_ORIGIN_MAPPED;
goto finish_override;
}
return (NULL); /* There was no override */
finish_override:
ACPI_INFO((AE_INFO,
"%4.4s %p %s table override, new table: %p",
table_header->signature,
ACPI_CAST_PTR(void, table_desc->address),
override_type, new_table));
/* We can now unmap/delete the original table (if fully mapped) */
acpi_tb_delete_table(table_desc);
/* Setup descriptor for the new table */
table_desc->address = new_address;
table_desc->pointer = new_table;
table_desc->length = new_table_length;
table_desc->flags = new_flags;
return (new_table);
}
/*******************************************************************************
*
* FUNCTION: acpi_tb_resize_root_table_list
@@ -396,7 +469,11 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
case ACPI_TABLE_ORIGIN_ALLOCATED:
ACPI_FREE(table_desc->pointer);
break;
default:;
/* Not mapped or allocated, there is nothing we can do */
default:
return;
}
table_desc->pointer = NULL;