aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables/tbxfroot.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/tables/tbxfroot.c')
-rw-r--r--drivers/acpi/tables/tbxfroot.c120
1 files changed, 71 insertions, 49 deletions
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index dc3c3f6a9f62..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
78acpi_status
79acpi_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
227 return_ACPI_STATUS (AE_BAD_SIGNATURE);
228 }
229
230 if (acpi_tb_checksum (acpi_gbl_RSDP, ACPI_RSDP_CHECKSUM_LENGTH) != 0) {
231 /* Nope, BAD Checksum */
232 267
233 return_ACPI_STATUS (AE_BAD_CHECKSUM); 268 status = acpi_tb_validate_rsdp (acpi_gbl_RSDP);
269 if (ACPI_FAILURE (status)) {
270 return_ACPI_STATUS (status);
234 } 271 }
235 } 272 }
236 273
@@ -287,9 +324,11 @@ acpi_get_firmware_table (
287 * requested table 324 * requested table
288 */ 325 */
289 for (i = 0, j = 0; i < table_count; i++) { 326 for (i = 0, j = 0; i < table_count; i++) {
290 /* Get the next table pointer, handle RSDT vs. XSDT */ 327 /*
291 328 * Get the next table pointer, handle RSDT vs. XSDT
292 if (acpi_gbl_RSDP->revision < 2) { 329 * RSDT pointers are 32 bits, XSDT pointers are 64 bits
330 */
331 if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
293 address.pointer.value = (ACPI_CAST_PTR ( 332 address.pointer.value = (ACPI_CAST_PTR (
294 RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i]; 333 RSDT_DESCRIPTOR, rsdt_info->pointer))->table_offset_entry[i];
295 } 334 }
@@ -331,8 +370,10 @@ acpi_get_firmware_table (
331 370
332 371
333cleanup: 372cleanup:
334 acpi_os_unmap_memory (rsdt_info->pointer, 373 if (rsdt_info->pointer) {
335 (acpi_size) rsdt_info->pointer->length); 374 acpi_os_unmap_memory (rsdt_info->pointer,
375 (acpi_size) rsdt_info->pointer->length);
376 }
336 ACPI_MEM_FREE (rsdt_info); 377 ACPI_MEM_FREE (rsdt_info);
337 378
338 if (header) { 379 if (header) {
@@ -410,9 +451,9 @@ acpi_tb_scan_memory_for_rsdp (
410 u8 *start_address, 451 u8 *start_address,
411 u32 length) 452 u32 length)
412{ 453{
454 acpi_status status;
413 u8 *mem_rover; 455 u8 *mem_rover;
414 u8 *end_address; 456 u8 *end_address;
415 u8 checksum;
416 457
417 458
418 ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp"); 459 ACPI_FUNCTION_TRACE ("tb_scan_memory_for_rsdp");
@@ -424,45 +465,25 @@ acpi_tb_scan_memory_for_rsdp (
424 465
425 for (mem_rover = start_address; mem_rover < end_address; 466 for (mem_rover = start_address; mem_rover < end_address;
426 mem_rover += ACPI_RSDP_SCAN_STEP) { 467 mem_rover += ACPI_RSDP_SCAN_STEP) {
427 /* The signature and checksum must both be correct */ 468 /* The RSDP signature and checksum must both be correct */
428
429 if (ACPI_STRNCMP ((char *) mem_rover,
430 RSDP_SIG, sizeof (RSDP_SIG) - 1) != 0) {
431 /* No signature match, keep looking */
432
433 continue;
434 }
435
436 /* Signature matches, check the appropriate checksum */
437
438 if ((ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover))->revision < 2) {
439 /* ACPI version 1.0 */
440 469
441 checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_CHECKSUM_LENGTH); 470 status = acpi_tb_validate_rsdp (ACPI_CAST_PTR (struct rsdp_descriptor, mem_rover));
442 } 471 if (ACPI_SUCCESS (status)) {
443 else { 472 /* Sig and checksum valid, we have found a real RSDP */
444 /* Post ACPI 1.0, use extended_checksum */
445
446 checksum = acpi_tb_checksum (mem_rover, ACPI_RSDP_XCHECKSUM_LENGTH);
447 }
448
449 if (checksum == 0) {
450 /* Checksum valid, we have found a valid RSDP */
451 473
452 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 474 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
453 "RSDP located at physical address %p\n", mem_rover)); 475 "RSDP located at physical address %p\n", mem_rover));
454 return_PTR (mem_rover); 476 return_PTR (mem_rover);
455 } 477 }
456 478
457 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 479 /* No sig match or bad checksum, keep searching */
458 "Found an RSDP at physical address %p, but it has a bad checksum\n",
459 mem_rover));
460 } 480 }
461 481
462 /* Searched entire block, no RSDP was found */ 482 /* Searched entire block, no RSDP was found */
463 483
464 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 484 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
465 "Searched entire block, no valid RSDP was found.\n")); 485 "Searched entire block from %p, valid RSDP was not found\n",
486 start_address));
466 return_PTR (NULL); 487 return_PTR (NULL);
467} 488}
468 489
@@ -550,7 +571,7 @@ acpi_tb_find_rsdp (
550 acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE); 571 acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);
551 572
552 if (mem_rover) { 573 if (mem_rover) {
553 /* Found it, return the physical address */ 574 /* Return the physical address */
554 575
555 physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr); 576 physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);
556 577
@@ -579,7 +600,7 @@ acpi_tb_find_rsdp (
579 acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE); 600 acpi_os_unmap_memory (table_ptr, ACPI_HI_RSDP_WINDOW_SIZE);
580 601
581 if (mem_rover) { 602 if (mem_rover) {
582 /* Found it, return the physical address */ 603 /* Return the physical address */
583 604
584 physical_address = 605 physical_address =
585 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);
@@ -610,7 +631,7 @@ acpi_tb_find_rsdp (
610 ACPI_PHYSADDR_TO_PTR (physical_address), 631 ACPI_PHYSADDR_TO_PTR (physical_address),
611 ACPI_EBDA_WINDOW_SIZE); 632 ACPI_EBDA_WINDOW_SIZE);
612 if (mem_rover) { 633 if (mem_rover) {
613 /* Found it, return the physical address */ 634 /* Return the physical address */
614 635
615 table_info->physical_address = ACPI_TO_INTEGER (mem_rover); 636 table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
616 return_ACPI_STATUS (AE_OK); 637 return_ACPI_STATUS (AE_OK);
@@ -630,8 +651,9 @@ acpi_tb_find_rsdp (
630 } 651 }
631 } 652 }
632 653
633 /* RSDP signature was not found */ 654 /* A valid RSDP was not found */
634 655
656 ACPI_REPORT_ERROR (("No valid RSDP was found\n"));
635 return_ACPI_STATUS (AE_NOT_FOUND); 657 return_ACPI_STATUS (AE_NOT_FOUND);
636} 658}
637 659