aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2010-04-06 23:05:11 -0400
committerLen Brown <len.brown@intel.com>2010-04-20 10:43:16 -0400
commit43323cb4c4b619414913f54fef9d492aabadd033 (patch)
treef5b434b93688972995eeed01ec86260f24311925 /drivers/acpi/acpica
parent69ec87efa815d69140423014bb5f91e034faac22 (diff)
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>
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r--drivers/acpi/acpica/acglobal.h2
-rw-r--r--drivers/acpi/acpica/actables.h2
-rw-r--r--drivers/acpi/acpica/tbutils.c23
-rw-r--r--drivers/acpi/acpica/tbxface.c29
-rw-r--r--drivers/acpi/acpica/utglobal.c1
5 files changed, 38 insertions, 19 deletions
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index e3813d290b4f..87f21d9d2a66 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -175,7 +175,7 @@ ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
175 175
176/* DSDT information. Used to check for DSDT corruption */ 176/* DSDT information. Used to check for DSDT corruption */
177 177
178ACPI_EXTERN struct acpi_table_desc *acpi_gbl_DSDT; 178ACPI_EXTERN struct acpi_table_header *acpi_gbl_DSDT;
179ACPI_EXTERN struct acpi_table_header acpi_gbl_original_dsdt_header; 179ACPI_EXTERN struct acpi_table_header acpi_gbl_original_dsdt_header;
180 180
181/* 181/*
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index b7197bf4af0b..62a576e34361 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -109,7 +109,7 @@ acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);
109 109
110void acpi_tb_check_dsdt_header(void); 110void acpi_tb_check_dsdt_header(void);
111 111
112void acpi_tb_copy_dsdt(struct acpi_table_desc *table_desc); 112struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index);
113 113
114void 114void
115acpi_tb_install_table(acpi_physical_address address, 115acpi_tb_install_table(acpi_physical_address address,
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 1efb0940e8b2..54a8712bae62 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -366,22 +366,18 @@ void acpi_tb_check_dsdt_header(void)
366 366
367 /* Compare original length and checksum to current values */ 367 /* Compare original length and checksum to current values */
368 368
369 if (acpi_gbl_original_dsdt_header.length != 369 if (acpi_gbl_original_dsdt_header.length != acpi_gbl_DSDT->length ||
370 acpi_gbl_DSDT->pointer->length 370 acpi_gbl_original_dsdt_header.checksum != acpi_gbl_DSDT->checksum) {
371 || acpi_gbl_original_dsdt_header.checksum !=
372 acpi_gbl_DSDT->pointer->checksum) {
373 ACPI_ERROR((AE_INFO, 371 ACPI_ERROR((AE_INFO,
374 "The DSDT has been corrupted or replaced - old, new headers below")); 372 "The DSDT has been corrupted or replaced - old, new headers below"));
375 acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header); 373 acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header);
376 acpi_tb_print_table_header(acpi_gbl_DSDT->address, 374 acpi_tb_print_table_header(0, acpi_gbl_DSDT);
377 acpi_gbl_DSDT->pointer);
378 375
379 /* Disable further error messages */ 376 /* Disable further error messages */
380 377
381 acpi_gbl_original_dsdt_header.length = 378 acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length;
382 acpi_gbl_DSDT->pointer->length;
383 acpi_gbl_original_dsdt_header.checksum = 379 acpi_gbl_original_dsdt_header.checksum =
384 acpi_gbl_DSDT->pointer->checksum; 380 acpi_gbl_DSDT->checksum;
385 } 381 }
386} 382}
387 383
@@ -399,15 +395,18 @@ void acpi_tb_check_dsdt_header(void)
399 * 395 *
400 ******************************************************************************/ 396 ******************************************************************************/
401 397
402void acpi_tb_copy_dsdt(struct acpi_table_desc *table_desc) 398struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
403{ 399{
404 struct acpi_table_header *new_table; 400 struct acpi_table_header *new_table;
401 struct acpi_table_desc *table_desc;
402
403 table_desc = &acpi_gbl_root_table_list.tables[table_index];
405 404
406 new_table = ACPI_ALLOCATE(table_desc->length); 405 new_table = ACPI_ALLOCATE(table_desc->length);
407 if (!new_table) { 406 if (!new_table) {
408 ACPI_ERROR((AE_INFO, "Could not copy DSDT of length 0x%X", 407 ACPI_ERROR((AE_INFO, "Could not copy DSDT of length 0x%X",
409 table_desc->length)); 408 table_desc->length));
410 return; 409 return (NULL);
411 } 410 }
412 411
413 ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length); 412 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)
418 ACPI_INFO((AE_INFO, 417 ACPI_INFO((AE_INFO,
419 "Forced DSDT copy: length 0x%05X copied locally, original unmapped", 418 "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
420 new_table->length)); 419 new_table->length));
420
421 return (new_table);
421} 422}
422 423
423/******************************************************************************* 424/*******************************************************************************
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index f5378fc302b3..adb7f56b853e 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -513,39 +513,56 @@ static acpi_status acpi_tb_load_namespace(void)
513{ 513{
514 acpi_status status; 514 acpi_status status;
515 u32 i; 515 u32 i;
516 struct acpi_table_header *new_dsdt;
516 517
517 ACPI_FUNCTION_TRACE(tb_load_namespace); 518 ACPI_FUNCTION_TRACE(tb_load_namespace);
518 519
519 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 520 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
520 521
521 acpi_gbl_DSDT = &acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT];
522
523 /* 522 /*
524 * Load the namespace. The DSDT is required, but any SSDT and 523 * Load the namespace. The DSDT is required, but any SSDT and
525 * PSDT tables are optional. Verify the DSDT. 524 * PSDT tables are optional. Verify the DSDT.
526 */ 525 */
527 if (!acpi_gbl_root_table_list.count || 526 if (!acpi_gbl_root_table_list.count ||
528 !ACPI_COMPARE_NAME(&acpi_gbl_DSDT->signature, ACPI_SIG_DSDT) || 527 !ACPI_COMPARE_NAME(&
529 ACPI_FAILURE(acpi_tb_verify_table(acpi_gbl_DSDT))) { 528 (acpi_gbl_root_table_list.
529 tables[ACPI_TABLE_INDEX_DSDT].signature),
530 ACPI_SIG_DSDT)
531 ||
532 ACPI_FAILURE(acpi_tb_verify_table
533 (&acpi_gbl_root_table_list.
534 tables[ACPI_TABLE_INDEX_DSDT]))) {
530 status = AE_NO_ACPI_TABLES; 535 status = AE_NO_ACPI_TABLES;
531 goto unlock_and_exit; 536 goto unlock_and_exit;
532 } 537 }
533 538
534 /* 539 /*
540 * Save the DSDT pointer for simple access. This is the mapped memory
541 * address. We must take care here because the address of the .Tables
542 * array can change dynamically as tables are loaded at run-time. Note:
543 * .Pointer field is not validated until after call to acpi_tb_verify_table.
544 */
545 acpi_gbl_DSDT =
546 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer;
547
548 /*
535 * Optionally copy the entire DSDT to local memory (instead of simply 549 * Optionally copy the entire DSDT to local memory (instead of simply
536 * mapping it.) There are some BIOSs that corrupt or replace the original 550 * mapping it.) There are some BIOSs that corrupt or replace the original
537 * DSDT, creating the need for this option. Default is FALSE, do not copy 551 * DSDT, creating the need for this option. Default is FALSE, do not copy
538 * the DSDT. 552 * the DSDT.
539 */ 553 */
540 if (acpi_gbl_copy_dsdt_locally) { 554 if (acpi_gbl_copy_dsdt_locally) {
541 acpi_tb_copy_dsdt(acpi_gbl_DSDT); 555 new_dsdt = acpi_tb_copy_dsdt(ACPI_TABLE_INDEX_DSDT);
556 if (new_dsdt) {
557 acpi_gbl_DSDT = new_dsdt;
558 }
542 } 559 }
543 560
544 /* 561 /*
545 * Save the original DSDT header for detection of table corruption 562 * Save the original DSDT header for detection of table corruption
546 * and/or replacement of the DSDT from outside the OS. 563 * and/or replacement of the DSDT from outside the OS.
547 */ 564 */
548 ACPI_MEMCPY(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT->pointer, 565 ACPI_MEMCPY(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT,
549 sizeof(struct acpi_table_header)); 566 sizeof(struct acpi_table_header));
550 567
551 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 568 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index eda3e656c4af..66116750a0f9 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -785,6 +785,7 @@ acpi_status acpi_ut_init_globals(void)
785 785
786 /* Miscellaneous variables */ 786 /* Miscellaneous variables */
787 787
788 acpi_gbl_DSDT = NULL;
788 acpi_gbl_cm_single_step = FALSE; 789 acpi_gbl_cm_single_step = FALSE;
789 acpi_gbl_db_terminate_threads = FALSE; 790 acpi_gbl_db_terminate_threads = FALSE;
790 acpi_gbl_shutdown = FALSE; 791 acpi_gbl_shutdown = FALSE;