Skip to content

Commit

Permalink
ACPICA: Allow OS override of all ACPI tables
Browse files Browse the repository at this point in the history
Previously, the table override mechanism was implemented for the
DSDT only. Now, any table in the RSDT/XSDT can be replaced by
the host OS. (including the DSDT).

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Bob Moore authored and Len Brown committed Mar 26, 2009
1 parent 4bbfb85 commit ac5f98d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 46 deletions.
1 change: 0 additions & 1 deletion drivers/acpi/acpica/acglobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,6 @@ ACPI_EXTERN char *acpi_gbl_db_buffer;
ACPI_EXTERN char *acpi_gbl_db_filename;
ACPI_EXTERN u32 acpi_gbl_db_debug_level;
ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;

/*
Expand Down
59 changes: 46 additions & 13 deletions drivers/acpi/acpica/tbutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,15 +287,21 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length)
*
* RETURN: None
*
* DESCRIPTION: Install an ACPI table into the global data structure.
* DESCRIPTION: Install an ACPI table into the global data structure. The
* table override mechanism is implemented here to allow the host
* OS to replace any table before it is installed in the root
* table array.
*
******************************************************************************/

void
acpi_tb_install_table(acpi_physical_address address,
u8 flags, char *signature, u32 table_index)
{
struct acpi_table_header *table;
acpi_status status;
struct acpi_table_header *table_to_install;
struct acpi_table_header *mapped_table;
struct acpi_table_header *override_table = NULL;

if (!address) {
ACPI_ERROR((AE_INFO,
Expand All @@ -306,41 +312,68 @@ acpi_tb_install_table(acpi_physical_address address,

/* Map just the table header */

table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
if (!table) {
mapped_table =
acpi_os_map_memory(address, sizeof(struct acpi_table_header));
if (!mapped_table) {
return;
}

/* If a particular signature is expected, signature must match */
/* If a particular signature is expected (DSDT/FACS), it must match */

if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
ACPI_ERROR((AE_INFO,
"Invalid signature 0x%X for ACPI table [%s]",
*ACPI_CAST_PTR(u32, table->signature), signature));
"Invalid signature 0x%X for ACPI table, expected [%s]",
*ACPI_CAST_PTR(u32, mapped_table->signature),
signature));
goto unmap_and_exit;
}

/*
* 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.
*/
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;
flags = ACPI_TABLE_ORIGIN_OVERRIDE;
address = ACPI_PTR_TO_PHYSADDR(override_table);

table_to_install = override_table;
} else {
table_to_install = mapped_table;
}

/* Initialize the table entry */

acpi_gbl_root_table_list.tables[table_index].address = address;
acpi_gbl_root_table_list.tables[table_index].length = table->length;
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->signature);
signature), table_to_install->signature);

acpi_tb_print_table_header(address, table);
acpi_tb_print_table_header(address, table_to_install);

if (table_index == ACPI_TABLE_INDEX_DSDT) {

/* Global integer width is based upon revision of the DSDT */

acpi_ut_set_integer_width(table->revision);
acpi_ut_set_integer_width(table_to_install->revision);
}

unmap_and_exit:
acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
}

/*******************************************************************************
Expand Down
31 changes: 1 addition & 30 deletions drivers/acpi/acpica/tbxface.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,6 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
static acpi_status acpi_tb_load_namespace(void)
{
acpi_status status;
struct acpi_table_header *table;
u32 i;

ACPI_FUNCTION_TRACE(tb_load_namespace);
Expand All @@ -515,41 +514,13 @@ static acpi_status acpi_tb_load_namespace(void)
goto unlock_and_exit;
}

/*
* Find DSDT table
*/
status =
acpi_os_table_override(acpi_gbl_root_table_list.
tables[ACPI_TABLE_INDEX_DSDT].pointer,
&table);
if (ACPI_SUCCESS(status) && table) {
/*
* DSDT table has been found
*/
acpi_tb_delete_table(&acpi_gbl_root_table_list.
tables[ACPI_TABLE_INDEX_DSDT]);
acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
table;
acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
table->length;
acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
ACPI_TABLE_ORIGIN_UNKNOWN;

ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
acpi_tb_print_table_header(0, table);

if (no_auto_ssdt == 0) {
printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
}
}
/* A valid DSDT is required */

status =
acpi_tb_verify_table(&acpi_gbl_root_table_list.
tables[ACPI_TABLE_INDEX_DSDT]);
if (ACPI_FAILURE(status)) {

/* A valid DSDT is required */

status = AE_NO_ACPI_TABLES;
goto unlock_and_exit;
}
Expand Down
5 changes: 3 additions & 2 deletions include/acpi/actbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,9 @@ struct acpi_table_desc {
#define ACPI_TABLE_ORIGIN_UNKNOWN (0)
#define ACPI_TABLE_ORIGIN_MAPPED (1)
#define ACPI_TABLE_ORIGIN_ALLOCATED (2)
#define ACPI_TABLE_ORIGIN_MASK (3)
#define ACPI_TABLE_IS_LOADED (4)
#define ACPI_TABLE_ORIGIN_OVERRIDE (4)
#define ACPI_TABLE_ORIGIN_MASK (7)
#define ACPI_TABLE_IS_LOADED (8)

/*
* Get the remaining ACPI tables
Expand Down

0 comments on commit ac5f98d

Please sign in to comment.