ACPICA: Update DSDT copy/detection.
Move initialization of DSDT pointer. Emit address of DSDT in the dump of both table headers (good/bad DSDT). Now handles the case where the root table can be reallocated, which would invalidate the original pointer. 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>
This commit is contained in:
parent
69ec87efa8
commit
43323cb4c4
@ -175,7 +175,7 @@ ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
|
|||||||
|
|
||||||
/* DSDT information. Used to check for DSDT corruption */
|
/* DSDT information. Used to check for DSDT corruption */
|
||||||
|
|
||||||
ACPI_EXTERN struct acpi_table_desc *acpi_gbl_DSDT;
|
ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT;
|
||||||
ACPI_EXTERN struct acpi_table_header acpi_gbl_original_dsdt_header;
|
ACPI_EXTERN struct acpi_table_header acpi_gbl_original_dsdt_header;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -109,7 +109,7 @@ acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);
|
|||||||
|
|
||||||
void acpi_tb_check_dsdt_header(void);
|
void acpi_tb_check_dsdt_header(void);
|
||||||
|
|
||||||
void acpi_tb_copy_dsdt(struct acpi_table_desc *table_desc);
|
struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index);
|
||||||
|
|
||||||
void
|
void
|
||||||
acpi_tb_install_table(acpi_physical_address address,
|
acpi_tb_install_table(acpi_physical_address address,
|
||||||
|
@ -366,22 +366,18 @@ void acpi_tb_check_dsdt_header(void)
|
|||||||
|
|
||||||
/* Compare original length and checksum to current values */
|
/* Compare original length and checksum to current values */
|
||||||
|
|
||||||
if (acpi_gbl_original_dsdt_header.length !=
|
if (acpi_gbl_original_dsdt_header.length != acpi_gbl_DSDT->length ||
|
||||||
acpi_gbl_DSDT->pointer->length
|
acpi_gbl_original_dsdt_header.checksum != acpi_gbl_DSDT->checksum) {
|
||||||
|| acpi_gbl_original_dsdt_header.checksum !=
|
|
||||||
acpi_gbl_DSDT->pointer->checksum) {
|
|
||||||
ACPI_ERROR((AE_INFO,
|
ACPI_ERROR((AE_INFO,
|
||||||
"The DSDT has been corrupted or replaced - old, new headers below"));
|
"The DSDT has been corrupted or replaced - old, new headers below"));
|
||||||
acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header);
|
acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header);
|
||||||
acpi_tb_print_table_header(acpi_gbl_DSDT->address,
|
acpi_tb_print_table_header(0, acpi_gbl_DSDT);
|
||||||
acpi_gbl_DSDT->pointer);
|
|
||||||
|
|
||||||
/* Disable further error messages */
|
/* Disable further error messages */
|
||||||
|
|
||||||
acpi_gbl_original_dsdt_header.length =
|
acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length;
|
||||||
acpi_gbl_DSDT->pointer->length;
|
|
||||||
acpi_gbl_original_dsdt_header.checksum =
|
acpi_gbl_original_dsdt_header.checksum =
|
||||||
acpi_gbl_DSDT->pointer->checksum;
|
acpi_gbl_DSDT->checksum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,15 +395,18 @@ void acpi_tb_check_dsdt_header(void)
|
|||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void acpi_tb_copy_dsdt(struct acpi_table_desc *table_desc)
|
struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
|
||||||
{
|
{
|
||||||
struct acpi_table_header *new_table;
|
struct acpi_table_header *new_table;
|
||||||
|
struct acpi_table_desc *table_desc;
|
||||||
|
|
||||||
|
table_desc = &acpi_gbl_root_table_list.tables[table_index];
|
||||||
|
|
||||||
new_table = ACPI_ALLOCATE(table_desc->length);
|
new_table = ACPI_ALLOCATE(table_desc->length);
|
||||||
if (!new_table) {
|
if (!new_table) {
|
||||||
ACPI_ERROR((AE_INFO, "Could not copy DSDT of length 0x%X",
|
ACPI_ERROR((AE_INFO, "Could not copy DSDT of length 0x%X",
|
||||||
table_desc->length));
|
table_desc->length));
|
||||||
return;
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length);
|
ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length);
|
||||||
@ -418,6 +417,8 @@ void acpi_tb_copy_dsdt(struct acpi_table_desc *table_desc)
|
|||||||
ACPI_INFO((AE_INFO,
|
ACPI_INFO((AE_INFO,
|
||||||
"Forced DSDT copy: length 0x%05X copied locally, original unmapped",
|
"Forced DSDT copy: length 0x%05X copied locally, original unmapped",
|
||||||
new_table->length));
|
new_table->length));
|
||||||
|
|
||||||
|
return (new_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -513,24 +513,38 @@ static acpi_status acpi_tb_load_namespace(void)
|
|||||||
{
|
{
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
struct acpi_table_header *new_dsdt;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(tb_load_namespace);
|
ACPI_FUNCTION_TRACE(tb_load_namespace);
|
||||||
|
|
||||||
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
|
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
|
||||||
|
|
||||||
acpi_gbl_DSDT = &acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the namespace. The DSDT is required, but any SSDT and
|
* Load the namespace. The DSDT is required, but any SSDT and
|
||||||
* PSDT tables are optional. Verify the DSDT.
|
* PSDT tables are optional. Verify the DSDT.
|
||||||
*/
|
*/
|
||||||
if (!acpi_gbl_root_table_list.count ||
|
if (!acpi_gbl_root_table_list.count ||
|
||||||
!ACPI_COMPARE_NAME(&acpi_gbl_DSDT->signature, ACPI_SIG_DSDT) ||
|
!ACPI_COMPARE_NAME(&
|
||||||
ACPI_FAILURE(acpi_tb_verify_table(acpi_gbl_DSDT))) {
|
(acpi_gbl_root_table_list.
|
||||||
|
tables[ACPI_TABLE_INDEX_DSDT].signature),
|
||||||
|
ACPI_SIG_DSDT)
|
||||||
|
||
|
||||||
|
ACPI_FAILURE(acpi_tb_verify_table
|
||||||
|
(&acpi_gbl_root_table_list.
|
||||||
|
tables[ACPI_TABLE_INDEX_DSDT]))) {
|
||||||
status = AE_NO_ACPI_TABLES;
|
status = AE_NO_ACPI_TABLES;
|
||||||
goto unlock_and_exit;
|
goto unlock_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the DSDT pointer for simple access. This is the mapped memory
|
||||||
|
* address. We must take care here because the address of the .Tables
|
||||||
|
* array can change dynamically as tables are loaded at run-time. Note:
|
||||||
|
* .Pointer field is not validated until after call to acpi_tb_verify_table.
|
||||||
|
*/
|
||||||
|
acpi_gbl_DSDT =
|
||||||
|
acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optionally copy the entire DSDT to local memory (instead of simply
|
* Optionally copy the entire DSDT to local memory (instead of simply
|
||||||
* mapping it.) There are some BIOSs that corrupt or replace the original
|
* mapping it.) There are some BIOSs that corrupt or replace the original
|
||||||
@ -538,14 +552,17 @@ static acpi_status acpi_tb_load_namespace(void)
|
|||||||
* the DSDT.
|
* the DSDT.
|
||||||
*/
|
*/
|
||||||
if (acpi_gbl_copy_dsdt_locally) {
|
if (acpi_gbl_copy_dsdt_locally) {
|
||||||
acpi_tb_copy_dsdt(acpi_gbl_DSDT);
|
new_dsdt = acpi_tb_copy_dsdt(ACPI_TABLE_INDEX_DSDT);
|
||||||
|
if (new_dsdt) {
|
||||||
|
acpi_gbl_DSDT = new_dsdt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save the original DSDT header for detection of table corruption
|
* Save the original DSDT header for detection of table corruption
|
||||||
* and/or replacement of the DSDT from outside the OS.
|
* and/or replacement of the DSDT from outside the OS.
|
||||||
*/
|
*/
|
||||||
ACPI_MEMCPY(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT->pointer,
|
ACPI_MEMCPY(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT,
|
||||||
sizeof(struct acpi_table_header));
|
sizeof(struct acpi_table_header));
|
||||||
|
|
||||||
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
|
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
|
||||||
|
@ -785,6 +785,7 @@ acpi_status acpi_ut_init_globals(void)
|
|||||||
|
|
||||||
/* Miscellaneous variables */
|
/* Miscellaneous variables */
|
||||||
|
|
||||||
|
acpi_gbl_DSDT = NULL;
|
||||||
acpi_gbl_cm_single_step = FALSE;
|
acpi_gbl_cm_single_step = FALSE;
|
||||||
acpi_gbl_db_terminate_threads = FALSE;
|
acpi_gbl_db_terminate_threads = FALSE;
|
||||||
acpi_gbl_shutdown = FALSE;
|
acpi_gbl_shutdown = FALSE;
|
||||||
|
Loading…
Reference in New Issue
Block a user