diff options
Diffstat (limited to 'drivers/acpi/tables/tbxfroot.c')
-rw-r--r-- | drivers/acpi/tables/tbxfroot.c | 106 |
1 files changed, 62 insertions, 44 deletions
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index fe9c8317df46..abb4c9346560 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c | |||
@@ -65,6 +65,51 @@ acpi_tb_scan_memory_for_rsdp ( | |||
65 | 65 | ||
66 | /******************************************************************************* | 66 | /******************************************************************************* |
67 | * | 67 | * |
68 | * FUNCTION: acpi_tb_validate_rsdp | ||
69 | * | ||
70 | * PARAMETERS: Rsdp - Pointer to unvalidated RSDP | ||
71 | * | ||
72 | * RETURN: Status | ||
73 | * | ||
74 | * DESCRIPTION: Validate the RSDP (ptr) | ||
75 | * | ||
76 | ******************************************************************************/ | ||
77 | |||
78 | acpi_status | ||
79 | acpi_tb_validate_rsdp ( | ||
80 | struct rsdp_descriptor *rsdp) | ||
81 | { | ||
82 | ACPI_FUNCTION_ENTRY (); | ||
83 | |||
84 | |||
85 | /* | ||
86 | * The signature and checksum must both be correct | ||
87 | */ | ||
88 | if (ACPI_STRNCMP ((char *) rsdp, RSDP_SIG, sizeof (RSDP_SIG)-1) != 0) { | ||
89 | /* Nope, BAD Signature */ | ||
90 | |||
91 | return (AE_BAD_SIGNATURE); | ||
92 | } | ||
93 | |||
94 | /* Check the standard checksum */ | ||
95 | |||
96 | if (acpi_tb_checksum (rsdp, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | ||
97 | return (AE_BAD_CHECKSUM); | ||
98 | } | ||
99 | |||
100 | /* Check extended checksum if table version >= 2 */ | ||
101 | |||
102 | if ((rsdp->revision >= 2) && | ||
103 | (acpi_tb_checksum (rsdp, ACPI_RSDP_XCHECKSUM_LENGTH) != 0)) { | ||
104 | return (AE_BAD_CHECKSUM); | ||
105 | } | ||
106 | |||
107 | return (AE_OK); | ||
108 | } | ||
109 | |||
110 | |||
111 | /******************************************************************************* | ||
112 | * | ||
68 | * FUNCTION: acpi_tb_find_table | 113 | * FUNCTION: acpi_tb_find_table |
69 | * | 114 | * |
70 | * PARAMETERS: Signature - String with ACPI table signature | 115 | * PARAMETERS: Signature - String with ACPI table signature |
@@ -218,19 +263,11 @@ acpi_get_firmware_table ( | |||
218 | acpi_gbl_RSDP = address.pointer.logical; | 263 | acpi_gbl_RSDP = address.pointer.logical; |
219 | } | 264 | } |
220 | 265 | ||
221 | /* The signature and checksum must both be correct */ | 266 | /* The RDSP signature and checksum must both be correct */ |
222 | |||
223 | if (ACPI_STRNCMP ((char *) acpi_gbl_RSDP, RSDP_SIG, | ||
224 | sizeof (RSDP_SIG)-1) != 0) { | ||
225 | /* Nope, BAD Signature */ | ||
226 | 267 | ||
227 | return_ACPI_STATUS (AE_BAD_SIGNATURE); | 268 | status = acpi_tb_validate_rsdp (acpi_gbl_RSDP); |
228 | } | 269 | if (ACPI_FAILURE (status)) { |
229 | 270 | return_ACPI_STATUS (status); | |
230 | if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) { | ||
231 | /* Nope, BAD Checksum */ | ||
232 | |||
233 | return_ACPI_STATUS (AE_BAD_CHECKSUM); | ||
234 | } | 271 | } |
235 | } | 272 | } |
236 | 273 | ||
@@ -414,9 +451,9 @@ acpi_tb_scan_memory_for_rsdp ( | |||
414 | u8 *start_address, | 451 | u8 *start_address, |
415 | u32 length) | 452 | u32 length) |
416 | { | 453 | { |
454 | acpi_status status; | ||
417 | u8 *mem_rover; | 455 | u8 *mem_rover; |
418 | u8 *end_address; | 456 | u8 *end_address; |
419 | u8 checksum; | ||
420 | 457 | ||
421 | 458 | ||
422 | ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp"); | 459 | ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp"); |
@@ -428,45 +465,25 @@ acpi_tb_scan_memory_for_rsdp ( | |||
428 | 465 | ||
429 | for (mem_rover = start_address; mem_rover < end_address; | 466 | for (mem_rover = start_address; mem_rover < end_address; |
430 | mem_rover += ACPI_RSDP_SCAN_STEP) { | 467 | mem_rover += ACPI_RSDP_SCAN_STEP) { |
431 | /* The signature and checksum must both be correct */ | 468 | /* The RSDP signature and checksum must both be correct */ |
432 | 469 | ||
433 | if (ACPI_STRNCMP ((char *) mem_rover, | 470 | status = acpi_tb_validate_rsdp (ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover)); |
434 | RSDP_SIG, sizeof (RSDP_SIG) - 1) != 0) { | 471 | if (ACPI_SUCCESS (status)) { |
435 | /* No signature match, keep looking */ | 472 | /* Sig and checksum valid, we have found a real RSDP */ |
436 | |||
437 | continue; | ||
438 | } | ||
439 | |||
440 | /* Signature matches, check the appropriate checksum */ | ||
441 | |||
442 | if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) { | ||
443 | /* ACPI version 1.0 */ | ||
444 | |||
445 | checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH); | ||
446 | } | ||
447 | else { | ||
448 | /* Post ACPI 1.0, use extended_checksum */ | ||
449 | |||
450 | checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH); | ||
451 | } | ||
452 | |||
453 | if (checksum == 0) { | ||
454 | /* Checksum valid, we have found a valid RSDP */ | ||
455 | 473 | ||
456 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | 474 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, |
457 | "RSDP located at physical address %p\n", mem_rover)); | 475 | "RSDP located at physical address %p\n", mem_rover)); |
458 | return_PTR (mem_rover); | 476 | return_PTR (mem_rover); |
459 | } | 477 | } |
460 | 478 | ||
461 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | 479 | /* No sig match or bad checksum, keep searching */ |
462 | "Found an RSDP at physical address %p, but it has a bad checksum\n", | ||
463 | mem_rover)); | ||
464 | } | 480 | } |
465 | 481 | ||
466 | /* Searched entire block, no RSDP was found */ | 482 | /* Searched entire block, no RSDP was found */ |
467 | 483 | ||
468 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, | 484 | ACPI_DEBUG_PRINT ((ACPI_DB_INFO, |
469 | "Searched entire block, no valid RSDP was found.\n")); | 485 | "Searched entire block from %p, valid RSDP was not found\n", |
486 | start_address)); | ||
470 | return_PTR (NULL); | 487 | return_PTR (NULL); |
471 | } | 488 | } |
472 | 489 | ||
@@ -554,7 +571,7 @@ acpi_tb_find_rsdp ( | |||
554 | acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE); | 571 | acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE); |
555 | 572 | ||
556 | if (mem_rover) { | 573 | if (mem_rover) { |
557 | /* Found it, return the physical address */ | 574 | /* Return the physical address */ |
558 | 575 | ||
559 | physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr); | 576 | physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr); |
560 | 577 | ||
@@ -583,7 +600,7 @@ acpi_tb_find_rsdp ( | |||
583 | acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); | 600 | acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); |
584 | 601 | ||
585 | if (mem_rover) { | 602 | if (mem_rover) { |
586 | /* Found it, return the physical address */ | 603 | /* Return the physical address */ |
587 | 604 | ||
588 | physical_address = | 605 | physical_address = |
589 | ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr); | 606 | ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr); |
@@ -614,7 +631,7 @@ acpi_tb_find_rsdp ( | |||
614 | ACPI_PHYSADDR_TO_PTR (physical_address), | 631 | ACPI_PHYSADDR_TO_PTR (physical_address), |
615 | ACPI_EBDA_WINDOW_SIZE); | 632 | ACPI_EBDA_WINDOW_SIZE); |
616 | if (mem_rover) { | 633 | if (mem_rover) { |
617 | /* Found it, return the physical address */ | 634 | /* Return the physical address */ |
618 | 635 | ||
619 | table_info->physical_address = ACPI_TO_INTEGER (mem_rover); | 636 | table_info->physical_address = ACPI_TO_INTEGER (mem_rover); |
620 | return_ACPI_STATUS (AE_OK); | 637 | return_ACPI_STATUS (AE_OK); |
@@ -634,8 +651,9 @@ acpi_tb_find_rsdp ( | |||
634 | } | 651 | } |
635 | } | 652 | } |
636 | 653 | ||
637 | /* RSDP signature was not found */ | 654 | /* A valid RSDP was not found */ |
638 | 655 | ||
656 | ACPI_REPORT_ERROR (("No valid RSDP was found\n")); | ||
639 | return_ACPI_STATUS (AE_NOT_FOUND); | 657 | return_ACPI_STATUS (AE_NOT_FOUND); |
640 | } | 658 | } |
641 | 659 | ||