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 "acpi.h" 47 #include "accommon.h" 48 #include "actables.h" 49 50 #define _COMPONENT ACPI_TABLES 51 ACPI_MODULE_NAME ("tbutils") 52 53 /* Local prototypes */ 54 55 static void 56 AcpiTbFixString ( 57 char *String, 58 ACPI_SIZE Length); 59 60 static void 61 AcpiTbCleanupTableHeader ( 62 ACPI_TABLE_HEADER *OutHeader, 63 ACPI_TABLE_HEADER *Header); 64 65 static ACPI_PHYSICAL_ADDRESS 66 AcpiTbGetRootTableEntry ( 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 84 ACPI_STATUS 85 AcpiTbInitializeFacs ( 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 110 BOOLEAN 111 AcpiTbTablesLoaded ( 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 138 static void 139 AcpiTbFixString ( 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 170 static void 171 AcpiTbCleanupTableHeader ( 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 198 void 199 AcpiTbPrintTableHeader ( 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 263 ACPI_STATUS 264 AcpiTbVerifyChecksum ( 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 306 UINT8 307 AcpiTbChecksum ( 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 338 void 339 AcpiTbCheckDsdtHeader ( 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 375 ACPI_TABLE_HEADER * 376 AcpiTbCopyDsdt ( 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 424 void 425 AcpiTbInstallTable ( 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 /* If a particular signature is expected (DSDT/FACS), it must match */ 453 454 if (Signature && 455 !ACPI_COMPARE_NAME (MappedTable->Signature, Signature)) 456 { 457 ACPI_ERROR ((AE_INFO, 458 "Invalid signature 0x%X for ACPI table, expected [%s]", 459 *ACPI_CAST_PTR (UINT32, MappedTable->Signature), Signature)); 460 goto UnmapAndExit; 461 } 462 463 /* 464 * ACPI Table Override: 465 * 466 * Before we install the table, let the host OS override it with a new 467 * one if desired. Any table within the RSDT/XSDT can be replaced, 468 * including the DSDT which is pointed to by the FADT. 469 */ 470 Status = AcpiOsTableOverride (MappedTable, &OverrideTable); 471 if (ACPI_SUCCESS (Status) && OverrideTable) 472 { 473 ACPI_INFO ((AE_INFO, 474 "%4.4s @ 0x%p Table override, replaced with:", 475 MappedTable->Signature, ACPI_CAST_PTR (void, Address))); 476 477 AcpiGbl_RootTableList.Tables[TableIndex].Pointer = OverrideTable; 478 Address = ACPI_PTR_TO_PHYSADDR (OverrideTable); 479 480 TableToInstall = OverrideTable; 481 Flags = ACPI_TABLE_ORIGIN_OVERRIDE; 482 } 483 else 484 { 485 TableToInstall = MappedTable; 486 Flags = ACPI_TABLE_ORIGIN_MAPPED; 487 } 488 489 /* Initialize the table entry */ 490 491 AcpiGbl_RootTableList.Tables[TableIndex].Address = Address; 492 AcpiGbl_RootTableList.Tables[TableIndex].Length = TableToInstall->Length; 493 AcpiGbl_RootTableList.Tables[TableIndex].Flags = Flags; 494 495 ACPI_MOVE_32_TO_32 ( 496 &(AcpiGbl_RootTableList.Tables[TableIndex].Signature), 497 TableToInstall->Signature); 498 499 AcpiTbPrintTableHeader (Address, TableToInstall); 500 501 if (TableIndex == ACPI_TABLE_INDEX_DSDT) 502 { 503 /* Global integer width is based upon revision of the DSDT */ 504 505 AcpiUtSetIntegerWidth (TableToInstall->Revision); 506 } 507 508 UnmapAndExit: 509 AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER)); 510 } 511 512 513 /******************************************************************************* 514 * 515 * FUNCTION: AcpiTbGetRootTableEntry 516 * 517 * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry 518 * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT) 519 * 520 * RETURN: Physical address extracted from the root table 521 * 522 * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on 523 * both 32-bit and 64-bit platforms 524 * 525 * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on 526 * 64-bit platforms. 527 * 528 ******************************************************************************/ 529 530 static ACPI_PHYSICAL_ADDRESS 531 AcpiTbGetRootTableEntry ( 532 UINT8 *TableEntry, 533 UINT32 TableEntrySize) 534 { 535 UINT64 Address64; 536 537 538 /* 539 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): 540 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT 541 */ 542 if (TableEntrySize == sizeof (UINT32)) 543 { 544 /* 545 * 32-bit platform, RSDT: Return 32-bit table entry 546 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return 547 */ 548 return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (UINT32, TableEntry))); 549 } 550 else 551 { 552 /* 553 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return 554 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, 555 * return 64-bit 556 */ 557 ACPI_MOVE_64_TO_64 (&Address64, TableEntry); 558 559 #if ACPI_MACHINE_WIDTH == 32 560 if (Address64 > ACPI_UINT32_MAX) 561 { 562 /* Will truncate 64-bit address to 32 bits, issue warning */ 563 564 ACPI_WARNING ((AE_INFO, 565 "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X)," 566 " truncating", 567 ACPI_FORMAT_UINT64 (Address64))); 568 } 569 #endif 570 return ((ACPI_PHYSICAL_ADDRESS) (Address64)); 571 } 572 } 573 574 575 /******************************************************************************* 576 * 577 * FUNCTION: AcpiTbParseRootTable 578 * 579 * PARAMETERS: Rsdp - Pointer to the RSDP 580 * 581 * RETURN: Status 582 * 583 * DESCRIPTION: This function is called to parse the Root System Description 584 * Table (RSDT or XSDT) 585 * 586 * NOTE: Tables are mapped (not copied) for efficiency. The FACS must 587 * be mapped and cannot be copied because it contains the actual 588 * memory location of the ACPI Global Lock. 589 * 590 ******************************************************************************/ 591 592 ACPI_STATUS 593 AcpiTbParseRootTable ( 594 ACPI_PHYSICAL_ADDRESS RsdpAddress) 595 { 596 ACPI_TABLE_RSDP *Rsdp; 597 UINT32 TableEntrySize; 598 UINT32 i; 599 UINT32 TableCount; 600 ACPI_TABLE_HEADER *Table; 601 ACPI_PHYSICAL_ADDRESS Address; 602 UINT32 Length; 603 UINT8 *TableEntry; 604 ACPI_STATUS Status; 605 606 607 ACPI_FUNCTION_TRACE (TbParseRootTable); 608 609 610 /* 611 * Map the entire RSDP and extract the address of the RSDT or XSDT 612 */ 613 Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP)); 614 if (!Rsdp) 615 { 616 return_ACPI_STATUS (AE_NO_MEMORY); 617 } 618 619 AcpiTbPrintTableHeader (RsdpAddress, 620 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp)); 621 622 /* Differentiate between RSDT and XSDT root tables */ 623 624 if (Rsdp->Revision > 1 && Rsdp->XsdtPhysicalAddress) 625 { 626 /* 627 * Root table is an XSDT (64-bit physical addresses). We must use the 628 * XSDT if the revision is > 1 and the XSDT pointer is present, as per 629 * the ACPI specification. 630 */ 631 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress; 632 TableEntrySize = sizeof (UINT64); 633 } 634 else 635 { 636 /* Root table is an RSDT (32-bit physical addresses) */ 637 638 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress; 639 TableEntrySize = sizeof (UINT32); 640 } 641 642 /* 643 * It is not possible to map more than one entry in some environments, 644 * so unmap the RSDP here before mapping other tables 645 */ 646 AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP)); 647 648 649 /* Map the RSDT/XSDT table header to get the full table length */ 650 651 Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 652 if (!Table) 653 { 654 return_ACPI_STATUS (AE_NO_MEMORY); 655 } 656 657 AcpiTbPrintTableHeader (Address, Table); 658 659 /* Get the length of the full table, verify length and map entire table */ 660 661 Length = Table->Length; 662 AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 663 664 if (Length < sizeof (ACPI_TABLE_HEADER)) 665 { 666 ACPI_ERROR ((AE_INFO, "Invalid length 0x%X in RSDT/XSDT", Length)); 667 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); 668 } 669 670 Table = AcpiOsMapMemory (Address, Length); 671 if (!Table) 672 { 673 return_ACPI_STATUS (AE_NO_MEMORY); 674 } 675 676 /* Validate the root table checksum */ 677 678 Status = AcpiTbVerifyChecksum (Table, Length); 679 if (ACPI_FAILURE (Status)) 680 { 681 AcpiOsUnmapMemory (Table, Length); 682 return_ACPI_STATUS (Status); 683 } 684 685 /* Calculate the number of tables described in the root table */ 686 687 TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) / 688 TableEntrySize); 689 690 /* 691 * First two entries in the table array are reserved for the DSDT 692 * and FACS, which are not actually present in the RSDT/XSDT - they 693 * come from the FADT 694 */ 695 TableEntry = ACPI_CAST_PTR (UINT8, Table) + sizeof (ACPI_TABLE_HEADER); 696 AcpiGbl_RootTableList.CurrentTableCount = 2; 697 698 /* 699 * Initialize the root table array from the RSDT/XSDT 700 */ 701 for (i = 0; i < TableCount; i++) 702 { 703 if (AcpiGbl_RootTableList.CurrentTableCount >= 704 AcpiGbl_RootTableList.MaxTableCount) 705 { 706 /* There is no more room in the root table array, attempt resize */ 707 708 Status = AcpiTbResizeRootTableList (); 709 if (ACPI_FAILURE (Status)) 710 { 711 ACPI_WARNING ((AE_INFO, "Truncating %u table entries!", 712 (unsigned) (TableCount - 713 (AcpiGbl_RootTableList.CurrentTableCount - 2)))); 714 break; 715 } 716 } 717 718 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ 719 720 AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount].Address = 721 AcpiTbGetRootTableEntry (TableEntry, TableEntrySize); 722 723 TableEntry += TableEntrySize; 724 AcpiGbl_RootTableList.CurrentTableCount++; 725 } 726 727 /* 728 * It is not possible to map more than one entry in some environments, 729 * so unmap the root table here before mapping other tables 730 */ 731 AcpiOsUnmapMemory (Table, Length); 732 733 /* 734 * Complete the initialization of the root table array by examining 735 * the header of each table 736 */ 737 for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 738 { 739 AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address, 740 NULL, i); 741 742 /* Special case for FADT - get the DSDT and FACS */ 743 744 if (ACPI_COMPARE_NAME ( 745 &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT)) 746 { 747 AcpiTbParseFadt (i); 748 } 749 } 750 751 return_ACPI_STATUS (AE_OK); 752 } 753