1/****************************************************************************** 2 * 3 * Module Name: tbutils - table utilities 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2011, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44#define __TBUTILS_C__ 45 46#include <contrib/dev/acpica/include/acpi.h> 47#include <contrib/dev/acpica/include/accommon.h> 48#include <contrib/dev/acpica/include/actables.h> 49 50#define _COMPONENT ACPI_TABLES 51 ACPI_MODULE_NAME ("tbutils") 52 53/* Local prototypes */ 54 55static void 56AcpiTbFixString ( 57 char *String, 58 ACPI_SIZE Length); 59 60static void 61AcpiTbCleanupTableHeader ( 62 ACPI_TABLE_HEADER *OutHeader, 63 ACPI_TABLE_HEADER *Header); 64 65static ACPI_PHYSICAL_ADDRESS 66AcpiTbGetRootTableEntry ( 67 UINT8 *TableEntry, 68 UINT32 TableEntrySize); 69 70 71/******************************************************************************* 72 * 73 * FUNCTION: AcpiTbInitializeFacs 74 * 75 * PARAMETERS: None 76 * 77 * RETURN: Status 78 * 79 * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global 80 * for accessing the Global Lock and Firmware Waking Vector 81 * 82 ******************************************************************************/ 83 84ACPI_STATUS 85AcpiTbInitializeFacs ( 86 void) 87{ 88 ACPI_STATUS Status; 89 90 91 Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, 92 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS)); 93 return (Status); 94} 95 96 97/******************************************************************************* 98 * 99 * FUNCTION: AcpiTbTablesLoaded 100 * 101 * PARAMETERS: None 102 * 103 * RETURN: TRUE if required ACPI tables are loaded 104 * 105 * DESCRIPTION: Determine if the minimum required ACPI tables are present 106 * (FADT, FACS, DSDT) 107 * 108 ******************************************************************************/ 109 110BOOLEAN 111AcpiTbTablesLoaded ( 112 void) 113{ 114 115 if (AcpiGbl_RootTableList.CurrentTableCount >= 3) 116 { 117 return (TRUE); 118 } 119 120 return (FALSE); 121} 122 123 124/******************************************************************************* 125 * 126 * FUNCTION: AcpiTbFixString 127 * 128 * PARAMETERS: String - String to be repaired 129 * Length - Maximum length 130 * 131 * RETURN: None 132 * 133 * DESCRIPTION: Replace every non-printable or non-ascii byte in the string 134 * with a question mark '?'. 135 * 136 ******************************************************************************/ 137 138static void 139AcpiTbFixString ( 140 char *String, 141 ACPI_SIZE Length) 142{ 143 144 while (Length && *String) 145 { 146 if (!ACPI_IS_PRINT (*String)) 147 { 148 *String = '?'; 149 } 150 String++; 151 Length--; 152 } 153} 154 155 156/******************************************************************************* 157 * 158 * FUNCTION: AcpiTbCleanupTableHeader 159 * 160 * PARAMETERS: OutHeader - Where the cleaned header is returned 161 * Header - Input ACPI table header 162 * 163 * RETURN: Returns the cleaned header in OutHeader 164 * 165 * DESCRIPTION: Copy the table header and ensure that all "string" fields in 166 * the header consist of printable characters. 167 * 168 ******************************************************************************/ 169 170static void 171AcpiTbCleanupTableHeader ( 172 ACPI_TABLE_HEADER *OutHeader, 173 ACPI_TABLE_HEADER *Header) 174{ 175 176 ACPI_MEMCPY (OutHeader, Header, sizeof (ACPI_TABLE_HEADER)); 177 178 AcpiTbFixString (OutHeader->Signature, ACPI_NAME_SIZE); 179 AcpiTbFixString (OutHeader->OemId, ACPI_OEM_ID_SIZE); 180 AcpiTbFixString (OutHeader->OemTableId, ACPI_OEM_TABLE_ID_SIZE); 181 AcpiTbFixString (OutHeader->AslCompilerId, ACPI_NAME_SIZE); 182} 183 184 185/******************************************************************************* 186 * 187 * FUNCTION: AcpiTbPrintTableHeader 188 * 189 * PARAMETERS: Address - Table physical address 190 * Header - Table header 191 * 192 * RETURN: None 193 * 194 * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. 195 * 196 ******************************************************************************/ 197 198void 199AcpiTbPrintTableHeader ( 200 ACPI_PHYSICAL_ADDRESS Address, 201 ACPI_TABLE_HEADER *Header) 202{ 203 ACPI_TABLE_HEADER LocalHeader; 204 205 206 /* 207 * The reason that the Address is cast to a void pointer is so that we 208 * can use %p which will work properly on both 32-bit and 64-bit hosts. 209 */ 210 if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_FACS)) 211 { 212 /* FACS only has signature and length fields */ 213 214 ACPI_INFO ((AE_INFO, "%4.4s %p %05X", 215 Header->Signature, ACPI_CAST_PTR (void, Address), 216 Header->Length)); 217 } 218 else if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_RSDP)) 219 { 220 /* RSDP has no common fields */ 221 222 ACPI_MEMCPY (LocalHeader.OemId, 223 ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId, ACPI_OEM_ID_SIZE); 224 AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE); 225 226 ACPI_INFO ((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", 227 ACPI_CAST_PTR (void, Address), 228 (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ? 229 ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20, 230 ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision, 231 LocalHeader.OemId)); 232 } 233 else 234 { 235 /* Standard ACPI table with full common header */ 236 237 AcpiTbCleanupTableHeader (&LocalHeader, Header); 238 239 ACPI_INFO ((AE_INFO, 240 "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", 241 LocalHeader.Signature, ACPI_CAST_PTR (void, Address), 242 LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId, 243 LocalHeader.OemTableId, LocalHeader.OemRevision, 244 LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision)); 245 } 246} 247 248 249/******************************************************************************* 250 * 251 * FUNCTION: AcpiTbValidateChecksum 252 * 253 * PARAMETERS: Table - ACPI table to verify 254 * Length - Length of entire table 255 * 256 * RETURN: Status 257 * 258 * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns 259 * exception on bad checksum. 260 * 261 ******************************************************************************/ 262 263ACPI_STATUS 264AcpiTbVerifyChecksum ( 265 ACPI_TABLE_HEADER *Table, 266 UINT32 Length) 267{ 268 UINT8 Checksum; 269 270 271 /* Compute the checksum on the table */ 272 273 Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Length); 274 275 /* Checksum ok? (should be zero) */ 276 277 if (Checksum) 278 { 279 ACPI_WARNING ((AE_INFO, 280 "Incorrect checksum in table [%4.4s] - 0x%2.2X, should be 0x%2.2X", 281 Table->Signature, Table->Checksum, 282 (UINT8) (Table->Checksum - Checksum))); 283 284#if (ACPI_CHECKSUM_ABORT) 285 return (AE_BAD_CHECKSUM); 286#endif 287 } 288 289 return (AE_OK); 290} 291 292 293/******************************************************************************* 294 * 295 * FUNCTION: AcpiTbChecksum 296 * 297 * PARAMETERS: Buffer - Pointer to memory region to be checked 298 * Length - Length of this memory region 299 * 300 * RETURN: Checksum (UINT8) 301 * 302 * DESCRIPTION: Calculates circular checksum of memory region. 303 * 304 ******************************************************************************/ 305 306UINT8 307AcpiTbChecksum ( 308 UINT8 *Buffer, 309 UINT32 Length) 310{ 311 UINT8 Sum = 0; 312 UINT8 *End = Buffer + Length; 313 314 315 while (Buffer < End) 316 { 317 Sum = (UINT8) (Sum + *(Buffer++)); 318 } 319 320 return Sum; 321} 322 323 324/******************************************************************************* 325 * 326 * FUNCTION: AcpiTbCheckDsdtHeader 327 * 328 * PARAMETERS: None 329 * 330 * RETURN: None 331 * 332 * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect 333 * if the DSDT has been replaced from outside the OS and/or if 334 * the DSDT header has been corrupted. 335 * 336 ******************************************************************************/ 337 338void 339AcpiTbCheckDsdtHeader ( 340 void) 341{ 342 343 /* Compare original length and checksum to current values */ 344 345 if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length || 346 AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum) 347 { 348 ACPI_ERROR ((AE_INFO, 349 "The DSDT has been corrupted or replaced - old, new headers below")); 350 AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader); 351 AcpiTbPrintTableHeader (0, AcpiGbl_DSDT); 352 353 /* Disable further error messages */ 354 355 AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length; 356 AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum; 357 } 358} 359 360 361/******************************************************************************* 362 * 363 * FUNCTION: AcpiTbCopyDsdt 364 * 365 * PARAMETERS: TableDesc - Installed table to copy 366 * 367 * RETURN: None 368 * 369 * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory. 370 * Some very bad BIOSs are known to either corrupt the DSDT or 371 * install a new, bad DSDT. This copy works around the problem. 372 * 373 ******************************************************************************/ 374 375ACPI_TABLE_HEADER * 376AcpiTbCopyDsdt ( 377 UINT32 TableIndex) 378{ 379 ACPI_TABLE_HEADER *NewTable; 380 ACPI_TABLE_DESC *TableDesc; 381 382 383 TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex]; 384 385 NewTable = ACPI_ALLOCATE (TableDesc->Length); 386 if (!NewTable) 387 { 388 ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X", 389 TableDesc->Length)); 390 return (NULL); 391 } 392 393 ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length); 394 AcpiTbDeleteTable (TableDesc); 395 TableDesc->Pointer = NewTable; 396 TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED; 397 398 ACPI_INFO ((AE_INFO, 399 "Forced DSDT copy: length 0x%05X copied locally, original unmapped", 400 NewTable->Length)); 401 402 return (NewTable); 403} 404 405 406/******************************************************************************* 407 * 408 * FUNCTION: AcpiTbInstallTable 409 * 410 * PARAMETERS: Address - Physical address of DSDT or FACS 411 * Signature - Table signature, NULL if no need to 412 * match 413 * TableIndex - Index into root table array 414 * 415 * RETURN: None 416 * 417 * DESCRIPTION: Install an ACPI table into the global data structure. The 418 * table override mechanism is implemented here to allow the host 419 * OS to replace any table before it is installed in the root 420 * table array. 421 * 422 ******************************************************************************/ 423 424void 425AcpiTbInstallTable ( 426 ACPI_PHYSICAL_ADDRESS Address, 427 char *Signature, 428 UINT32 TableIndex) 429{ 430 UINT8 Flags; 431 ACPI_STATUS Status; 432 ACPI_TABLE_HEADER *TableToInstall; 433 ACPI_TABLE_HEADER *MappedTable; 434 ACPI_TABLE_HEADER *OverrideTable = NULL; 435 436 437 if (!Address) 438 { 439 ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", 440 Signature)); 441 return; 442 } 443 444 /* Map just the table header */ 445 446 MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 447 if (!MappedTable) 448 { 449 return; 450 } 451 452 /* Skip SSDT when DSDT is overriden */ 453 454 if (ACPI_COMPARE_NAME (MappedTable->Signature, ACPI_SIG_SSDT) && 455 (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags & 456 ACPI_TABLE_ORIGIN_OVERRIDE)) 457 { 458 ACPI_INFO ((AE_INFO, 459 "%4.4s @ 0x%p Table override, replaced with:", ACPI_SIG_SSDT, 460 ACPI_CAST_PTR (void, Address))); 461 AcpiTbPrintTableHeader ( 462 AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Address, 463 AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer); 464 goto UnmapAndExit; 465 } 466 467 /* If a particular signature is expected (DSDT/FACS), it must match */ 468 469 if (Signature && 470 !ACPI_COMPARE_NAME (MappedTable->Signature, Signature)) 471 { 472 ACPI_ERROR ((AE_INFO, 473 "Invalid signature 0x%X for ACPI table, expected [%s]", 474 *ACPI_CAST_PTR (UINT32, MappedTable->Signature), Signature)); 475 goto UnmapAndExit; 476 } 477 478 /* 479 * ACPI Table Override: 480 * 481 * Before we install the table, let the host OS override it with a new 482 * one if desired. Any table within the RSDT/XSDT can be replaced, 483 * including the DSDT which is pointed to by the FADT. 484 */ 485 Status = AcpiOsTableOverride (MappedTable, &OverrideTable); 486 if (ACPI_SUCCESS (Status) && OverrideTable) 487 { 488 ACPI_INFO ((AE_INFO, 489 "%4.4s @ 0x%p Table override, replaced with:", 490 MappedTable->Signature, ACPI_CAST_PTR (void, Address))); 491 492 AcpiGbl_RootTableList.Tables[TableIndex].Pointer = OverrideTable; 493 Address = ACPI_PTR_TO_PHYSADDR (OverrideTable); 494 495 TableToInstall = OverrideTable; 496 Flags = ACPI_TABLE_ORIGIN_OVERRIDE; 497 } 498 else 499 { 500 TableToInstall = MappedTable; 501 Flags = ACPI_TABLE_ORIGIN_MAPPED; 502 } 503 504 /* Initialize the table entry */ 505 506 AcpiGbl_RootTableList.Tables[TableIndex].Address = Address; 507 AcpiGbl_RootTableList.Tables[TableIndex].Length = TableToInstall->Length; 508 AcpiGbl_RootTableList.Tables[TableIndex].Flags = Flags; 509 510 ACPI_MOVE_32_TO_32 ( 511 &(AcpiGbl_RootTableList.Tables[TableIndex].Signature), 512 TableToInstall->Signature); 513 514 AcpiTbPrintTableHeader (Address, TableToInstall); 515 516 if (TableIndex == ACPI_TABLE_INDEX_DSDT) 517 { 518 /* Global integer width is based upon revision of the DSDT */ 519 520 AcpiUtSetIntegerWidth (TableToInstall->Revision); 521 } 522 523UnmapAndExit: 524 AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER)); 525} 526 527 528/******************************************************************************* 529 * 530 * FUNCTION: AcpiTbGetRootTableEntry 531 * 532 * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry 533 * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT) 534 * 535 * RETURN: Physical address extracted from the root table 536 * 537 * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on 538 * both 32-bit and 64-bit platforms 539 * 540 * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on 541 * 64-bit platforms. 542 * 543 ******************************************************************************/ 544 545static ACPI_PHYSICAL_ADDRESS 546AcpiTbGetRootTableEntry ( 547 UINT8 *TableEntry, 548 UINT32 TableEntrySize) 549{ 550 UINT64 Address64; 551 552 553 /* 554 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): 555 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT 556 */ 557 if (TableEntrySize == sizeof (UINT32)) 558 { 559 /* 560 * 32-bit platform, RSDT: Return 32-bit table entry 561 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return 562 */ 563 return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (UINT32, TableEntry))); 564 } 565 else 566 { 567 /* 568 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return 569 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, 570 * return 64-bit 571 */ 572 ACPI_MOVE_64_TO_64 (&Address64, TableEntry); 573 574#if ACPI_MACHINE_WIDTH == 32 575 if (Address64 > ACPI_UINT32_MAX) 576 { 577 /* Will truncate 64-bit address to 32 bits, issue warning */ 578 579 ACPI_WARNING ((AE_INFO, 580 "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X)," 581 " truncating", 582 ACPI_FORMAT_UINT64 (Address64))); 583 } 584#endif 585 return ((ACPI_PHYSICAL_ADDRESS) (Address64)); 586 } 587} 588 589 590/******************************************************************************* 591 * 592 * FUNCTION: AcpiTbParseRootTable 593 * 594 * PARAMETERS: Rsdp - Pointer to the RSDP 595 * 596 * RETURN: Status 597 * 598 * DESCRIPTION: This function is called to parse the Root System Description 599 * Table (RSDT or XSDT) 600 * 601 * NOTE: Tables are mapped (not copied) for efficiency. The FACS must 602 * be mapped and cannot be copied because it contains the actual 603 * memory location of the ACPI Global Lock. 604 * 605 ******************************************************************************/ 606 607ACPI_STATUS 608AcpiTbParseRootTable ( 609 ACPI_PHYSICAL_ADDRESS RsdpAddress) 610{ 611 ACPI_TABLE_RSDP *Rsdp; 612 UINT32 TableEntrySize; 613 UINT32 i; 614 UINT32 TableCount; 615 ACPI_TABLE_HEADER *Table; 616 ACPI_PHYSICAL_ADDRESS Address; 617 UINT32 Length; 618 UINT8 *TableEntry; 619 ACPI_STATUS Status; 620 621 622 ACPI_FUNCTION_TRACE (TbParseRootTable); 623 624 625 /* 626 * Map the entire RSDP and extract the address of the RSDT or XSDT 627 */ 628 Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP)); 629 if (!Rsdp) 630 { 631 return_ACPI_STATUS (AE_NO_MEMORY); 632 } 633 634 AcpiTbPrintTableHeader (RsdpAddress, 635 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp)); 636 637 /* Differentiate between RSDT and XSDT root tables */ 638 639 if (Rsdp->Revision > 1 && Rsdp->XsdtPhysicalAddress) 640 { 641 /* 642 * Root table is an XSDT (64-bit physical addresses). We must use the 643 * XSDT if the revision is > 1 and the XSDT pointer is present, as per 644 * the ACPI specification. 645 */ 646 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress; 647 TableEntrySize = sizeof (UINT64); 648 } 649 else 650 { 651 /* Root table is an RSDT (32-bit physical addresses) */ 652 653 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress; 654 TableEntrySize = sizeof (UINT32); 655 } 656 657 /* 658 * It is not possible to map more than one entry in some environments, 659 * so unmap the RSDP here before mapping other tables 660 */ 661 AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP)); 662 663 664 /* Map the RSDT/XSDT table header to get the full table length */ 665 666 Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 667 if (!Table) 668 { 669 return_ACPI_STATUS (AE_NO_MEMORY); 670 } 671 672 AcpiTbPrintTableHeader (Address, Table); 673 674 /* Get the length of the full table, verify length and map entire table */ 675 676 Length = Table->Length; 677 AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 678 679 if (Length < sizeof (ACPI_TABLE_HEADER)) 680 { 681 ACPI_ERROR ((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", Length)); 682 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); 683 } 684 685 Table = AcpiOsMapMemory (Address, Length); 686 if (!Table) 687 { 688 return_ACPI_STATUS (AE_NO_MEMORY); 689 } 690 691 /* Validate the root table checksum */ 692 693 Status = AcpiTbVerifyChecksum (Table, Length); 694 if (ACPI_FAILURE (Status)) 695 { 696 AcpiOsUnmapMemory (Table, Length); 697 return_ACPI_STATUS (Status); 698 } 699 700 /* Calculate the number of tables described in the root table */ 701 702 TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) / 703 TableEntrySize); 704 705 /* 706 * First two entries in the table array are reserved for the DSDT 707 * and FACS, which are not actually present in the RSDT/XSDT - they 708 * come from the FADT 709 */ 710 TableEntry = ACPI_CAST_PTR (UINT8, Table) + sizeof (ACPI_TABLE_HEADER); 711 AcpiGbl_RootTableList.CurrentTableCount = 2; 712 713 /* 714 * Initialize the root table array from the RSDT/XSDT 715 */ 716 for (i = 0; i < TableCount; i++) 717 { 718 if (AcpiGbl_RootTableList.CurrentTableCount >= 719 AcpiGbl_RootTableList.MaxTableCount) 720 { 721 /* There is no more room in the root table array, attempt resize */ 722 723 Status = AcpiTbResizeRootTableList (); 724 if (ACPI_FAILURE (Status)) 725 { 726 ACPI_WARNING ((AE_INFO, "Truncating %u table entries!", 727 (unsigned) (TableCount - 728 (AcpiGbl_RootTableList.CurrentTableCount - 2)))); 729 break; 730 } 731 } 732 733 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ 734 735 AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount].Address = 736 AcpiTbGetRootTableEntry (TableEntry, TableEntrySize); 737 738 TableEntry += TableEntrySize; 739 AcpiGbl_RootTableList.CurrentTableCount++; 740 } 741 742 /* 743 * It is not possible to map more than one entry in some environments, 744 * so unmap the root table here before mapping other tables 745 */ 746 AcpiOsUnmapMemory (Table, Length); 747 748 /* 749 * Complete the initialization of the root table array by examining 750 * the header of each table 751 */ 752 for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 753 { 754 AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address, 755 NULL, i); 756 757 /* Special case for FADT - get the DSDT and FACS */ 758 759 if (ACPI_COMPARE_NAME ( 760 &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT)) 761 { 762 AcpiTbParseFadt (i); 763 } 764 } 765 766 return_ACPI_STATUS (AE_OK); 767} 768