aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/tbutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/tbutils.c')
-rw-r--r--drivers/acpi/acpica/tbutils.c101
1 files changed, 90 insertions, 11 deletions
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 02723a9fb10..34f9c2bc5e1 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -158,7 +158,7 @@ acpi_status acpi_tb_initialize_facs(void)
158u8 acpi_tb_tables_loaded(void) 158u8 acpi_tb_tables_loaded(void)
159{ 159{
160 160
161 if (acpi_gbl_root_table_list.count >= 3) { 161 if (acpi_gbl_root_table_list.current_table_count >= 3) {
162 return (TRUE); 162 return (TRUE);
163 } 163 }
164 164
@@ -309,7 +309,7 @@ acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
309 309
310 if (checksum) { 310 if (checksum) {
311 ACPI_WARNING((AE_INFO, 311 ACPI_WARNING((AE_INFO,
312 "Incorrect checksum in table [%4.4s] - %2.2X, should be %2.2X", 312 "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X",
313 table->signature, table->checksum, 313 table->signature, table->checksum,
314 (u8) (table->checksum - checksum))); 314 (u8) (table->checksum - checksum)));
315 315
@@ -349,6 +349,84 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length)
349 349
350/******************************************************************************* 350/*******************************************************************************
351 * 351 *
352 * FUNCTION: acpi_tb_check_dsdt_header
353 *
354 * PARAMETERS: None
355 *
356 * RETURN: None
357 *
358 * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
359 * if the DSDT has been replaced from outside the OS and/or if
360 * the DSDT header has been corrupted.
361 *
362 ******************************************************************************/
363
364void acpi_tb_check_dsdt_header(void)
365{
366
367 /* Compare original length and checksum to current values */
368
369 if (acpi_gbl_original_dsdt_header.length != acpi_gbl_DSDT->length ||
370 acpi_gbl_original_dsdt_header.checksum != acpi_gbl_DSDT->checksum) {
371 ACPI_ERROR((AE_INFO,
372 "The DSDT has been corrupted or replaced - old, new headers below"));
373 acpi_tb_print_table_header(0, &acpi_gbl_original_dsdt_header);
374 acpi_tb_print_table_header(0, acpi_gbl_DSDT);
375
376 ACPI_ERROR((AE_INFO,
377 "Please send DMI info to linux-acpi@vger.kernel.org\n"
378 "If system does not work as expected, please boot with acpi=copy_dsdt"));
379
380 /* Disable further error messages */
381
382 acpi_gbl_original_dsdt_header.length = acpi_gbl_DSDT->length;
383 acpi_gbl_original_dsdt_header.checksum =
384 acpi_gbl_DSDT->checksum;
385 }
386}
387
388/*******************************************************************************
389 *
390 * FUNCTION: acpi_tb_copy_dsdt
391 *
392 * PARAMETERS: table_desc - Installed table to copy
393 *
394 * RETURN: None
395 *
396 * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
397 * Some very bad BIOSs are known to either corrupt the DSDT or
398 * install a new, bad DSDT. This copy works around the problem.
399 *
400 ******************************************************************************/
401
402struct acpi_table_header *acpi_tb_copy_dsdt(u32 table_index)
403{
404 struct acpi_table_header *new_table;
405 struct acpi_table_desc *table_desc;
406
407 table_desc = &acpi_gbl_root_table_list.tables[table_index];
408
409 new_table = ACPI_ALLOCATE(table_desc->length);
410 if (!new_table) {
411 ACPI_ERROR((AE_INFO, "Could not copy DSDT of length 0x%X",
412 table_desc->length));
413 return (NULL);
414 }
415
416 ACPI_MEMCPY(new_table, table_desc->pointer, table_desc->length);
417 acpi_tb_delete_table(table_desc);
418 table_desc->pointer = new_table;
419 table_desc->flags = ACPI_TABLE_ORIGIN_ALLOCATED;
420
421 ACPI_INFO((AE_INFO,
422 "Forced DSDT copy: length 0x%05X copied locally, original unmapped",
423 new_table->length));
424
425 return (new_table);
426}
427
428/*******************************************************************************
429 *
352 * FUNCTION: acpi_tb_install_table 430 * FUNCTION: acpi_tb_install_table
353 * 431 *
354 * PARAMETERS: Address - Physical address of DSDT or FACS 432 * PARAMETERS: Address - Physical address of DSDT or FACS
@@ -496,7 +574,7 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
496 /* Will truncate 64-bit address to 32 bits, issue warning */ 574 /* Will truncate 64-bit address to 32 bits, issue warning */
497 575
498 ACPI_WARNING((AE_INFO, 576 ACPI_WARNING((AE_INFO,
499 "64-bit Physical Address in XSDT is too large (%8.8X%8.8X)," 577 "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X),"
500 " truncating", 578 " truncating",
501 ACPI_FORMAT_UINT64(address64))); 579 ACPI_FORMAT_UINT64(address64)));
502 } 580 }
@@ -629,14 +707,14 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
629 */ 707 */
630 table_entry = 708 table_entry =
631 ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); 709 ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
632 acpi_gbl_root_table_list.count = 2; 710 acpi_gbl_root_table_list.current_table_count = 2;
633 711
634 /* 712 /*
635 * Initialize the root table array from the RSDT/XSDT 713 * Initialize the root table array from the RSDT/XSDT
636 */ 714 */
637 for (i = 0; i < table_count; i++) { 715 for (i = 0; i < table_count; i++) {
638 if (acpi_gbl_root_table_list.count >= 716 if (acpi_gbl_root_table_list.current_table_count >=
639 acpi_gbl_root_table_list.size) { 717 acpi_gbl_root_table_list.max_table_count) {
640 718
641 /* There is no more room in the root table array, attempt resize */ 719 /* There is no more room in the root table array, attempt resize */
642 720
@@ -646,19 +724,20 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
646 "Truncating %u table entries!", 724 "Truncating %u table entries!",
647 (unsigned) (table_count - 725 (unsigned) (table_count -
648 (acpi_gbl_root_table_list. 726 (acpi_gbl_root_table_list.
649 count - 2)))); 727 current_table_count -
728 2))));
650 break; 729 break;
651 } 730 }
652 } 731 }
653 732
654 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ 733 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */
655 734
656 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 735 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.
657 address = 736 current_table_count].address =
658 acpi_tb_get_root_table_entry(table_entry, table_entry_size); 737 acpi_tb_get_root_table_entry(table_entry, table_entry_size);
659 738
660 table_entry += table_entry_size; 739 table_entry += table_entry_size;
661 acpi_gbl_root_table_list.count++; 740 acpi_gbl_root_table_list.current_table_count++;
662 } 741 }
663 742
664 /* 743 /*
@@ -671,7 +750,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
671 * Complete the initialization of the root table array by examining 750 * Complete the initialization of the root table array by examining
672 * the header of each table 751 * the header of each table
673 */ 752 */
674 for (i = 2; i < acpi_gbl_root_table_list.count; i++) { 753 for (i = 2; i < acpi_gbl_root_table_list.current_table_count; i++) {
675 acpi_tb_install_table(acpi_gbl_root_table_list.tables[i]. 754 acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
676 address, NULL, i); 755 address, NULL, i);
677 756