1 /****************************************************************************** 2 * 3 * Module Name: tbutils - table utilities 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 *****************************************************************************/ 115 116 #define __TBUTILS_C__ 117 118 #include "acpi.h" 119 #include "accommon.h" 120 #include "actables.h" 121 122 #define _COMPONENT ACPI_TABLES 123 ACPI_MODULE_NAME ("tbutils") 124 125 126 /* Local prototypes */ 127 128 static void 129 AcpiTbFixString ( 130 char *String, 131 ACPI_SIZE Length); 132 133 static void 134 AcpiTbCleanupTableHeader ( 135 ACPI_TABLE_HEADER *OutHeader, 136 ACPI_TABLE_HEADER *Header); 137 138 static ACPI_PHYSICAL_ADDRESS 139 AcpiTbGetRootTableEntry ( 140 UINT8 *TableEntry, 141 UINT32 TableEntrySize); 142 143 144 #if (!ACPI_REDUCED_HARDWARE) 145 /******************************************************************************* 146 * 147 * FUNCTION: AcpiTbInitializeFacs 148 * 149 * PARAMETERS: None 150 * 151 * RETURN: Status 152 * 153 * DESCRIPTION: Create a permanent mapping for the FADT and save it in a global 154 * for accessing the Global Lock and Firmware Waking Vector 155 * 156 ******************************************************************************/ 157 158 ACPI_STATUS 159 AcpiTbInitializeFacs ( 160 void) 161 { 162 ACPI_STATUS Status; 163 164 165 /* If Hardware Reduced flag is set, there is no FACS */ 166 167 if (AcpiGbl_ReducedHardware) 168 { 169 AcpiGbl_FACS = NULL; 170 return (AE_OK); 171 } 172 173 Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, 174 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &AcpiGbl_FACS)); 175 return (Status); 176 } 177 #endif /* !ACPI_REDUCED_HARDWARE */ 178 179 180 /******************************************************************************* 181 * 182 * FUNCTION: AcpiTbTablesLoaded 183 * 184 * PARAMETERS: None 185 * 186 * RETURN: TRUE if required ACPI tables are loaded 187 * 188 * DESCRIPTION: Determine if the minimum required ACPI tables are present 189 * (FADT, FACS, DSDT) 190 * 191 ******************************************************************************/ 192 193 BOOLEAN 194 AcpiTbTablesLoaded ( 195 void) 196 { 197 198 if (AcpiGbl_RootTableList.CurrentTableCount >= 3) 199 { 200 return (TRUE); 201 } 202 203 return (FALSE); 204 } 205 206 207 /******************************************************************************* 208 * 209 * FUNCTION: AcpiTbFixString 210 * 211 * PARAMETERS: String - String to be repaired 212 * Length - Maximum length 213 * 214 * RETURN: None 215 * 216 * DESCRIPTION: Replace every non-printable or non-ascii byte in the string 217 * with a question mark '?'. 218 * 219 ******************************************************************************/ 220 221 static void 222 AcpiTbFixString ( 223 char *String, 224 ACPI_SIZE Length) 225 { 226 227 while (Length && *String) 228 { 229 if (!ACPI_IS_PRINT (*String)) 230 { 231 *String = '?'; 232 } 233 String++; 234 Length--; 235 } 236 } 237 238 239 /******************************************************************************* 240 * 241 * FUNCTION: AcpiTbCleanupTableHeader 242 * 243 * PARAMETERS: OutHeader - Where the cleaned header is returned 244 * Header - Input ACPI table header 245 * 246 * RETURN: Returns the cleaned header in OutHeader 247 * 248 * DESCRIPTION: Copy the table header and ensure that all "string" fields in 249 * the header consist of printable characters. 250 * 251 ******************************************************************************/ 252 253 static void 254 AcpiTbCleanupTableHeader ( 255 ACPI_TABLE_HEADER *OutHeader, 256 ACPI_TABLE_HEADER *Header) 257 { 258 259 ACPI_MEMCPY (OutHeader, Header, sizeof (ACPI_TABLE_HEADER)); 260 261 AcpiTbFixString (OutHeader->Signature, ACPI_NAME_SIZE); 262 AcpiTbFixString (OutHeader->OemId, ACPI_OEM_ID_SIZE); 263 AcpiTbFixString (OutHeader->OemTableId, ACPI_OEM_TABLE_ID_SIZE); 264 AcpiTbFixString (OutHeader->AslCompilerId, ACPI_NAME_SIZE); 265 } 266 267 268 /******************************************************************************* 269 * 270 * FUNCTION: AcpiTbPrintTableHeader 271 * 272 * PARAMETERS: Address - Table physical address 273 * Header - Table header 274 * 275 * RETURN: None 276 * 277 * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP. 278 * 279 ******************************************************************************/ 280 281 void 282 AcpiTbPrintTableHeader ( 283 ACPI_PHYSICAL_ADDRESS Address, 284 ACPI_TABLE_HEADER *Header) 285 { 286 ACPI_TABLE_HEADER LocalHeader; 287 288 289 /* 290 * The reason that the Address is cast to a void pointer is so that we 291 * can use %p which will work properly on both 32-bit and 64-bit hosts. 292 */ 293 if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_FACS)) 294 { 295 /* FACS only has signature and length fields */ 296 297 ACPI_INFO ((AE_INFO, "%4.4s %p %05X", 298 Header->Signature, ACPI_CAST_PTR (void, Address), 299 Header->Length)); 300 } 301 else if (ACPI_COMPARE_NAME (Header->Signature, ACPI_SIG_RSDP)) 302 { 303 /* RSDP has no common fields */ 304 305 ACPI_MEMCPY (LocalHeader.OemId, 306 ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->OemId, ACPI_OEM_ID_SIZE); 307 AcpiTbFixString (LocalHeader.OemId, ACPI_OEM_ID_SIZE); 308 309 ACPI_INFO ((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", 310 ACPI_CAST_PTR (void, Address), 311 (ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision > 0) ? 312 ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Length : 20, 313 ACPI_CAST_PTR (ACPI_TABLE_RSDP, Header)->Revision, 314 LocalHeader.OemId)); 315 } 316 else 317 { 318 /* Standard ACPI table with full common header */ 319 320 AcpiTbCleanupTableHeader (&LocalHeader, Header); 321 322 ACPI_INFO ((AE_INFO, 323 "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", 324 LocalHeader.Signature, ACPI_CAST_PTR (void, Address), 325 LocalHeader.Length, LocalHeader.Revision, LocalHeader.OemId, 326 LocalHeader.OemTableId, LocalHeader.OemRevision, 327 LocalHeader.AslCompilerId, LocalHeader.AslCompilerRevision)); 328 } 329 } 330 331 332 /******************************************************************************* 333 * 334 * FUNCTION: AcpiTbValidateChecksum 335 * 336 * PARAMETERS: Table - ACPI table to verify 337 * Length - Length of entire table 338 * 339 * RETURN: Status 340 * 341 * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns 342 * exception on bad checksum. 343 * 344 ******************************************************************************/ 345 346 ACPI_STATUS 347 AcpiTbVerifyChecksum ( 348 ACPI_TABLE_HEADER *Table, 349 UINT32 Length) 350 { 351 UINT8 Checksum; 352 353 354 /* Compute the checksum on the table */ 355 356 Checksum = AcpiTbChecksum (ACPI_CAST_PTR (UINT8, Table), Length); 357 358 /* Checksum ok? (should be zero) */ 359 360 if (Checksum) 361 { 362 ACPI_BIOS_WARNING ((AE_INFO, 363 "Incorrect checksum in table [%4.4s] - 0x%2.2X, " 364 "should be 0x%2.2X", 365 Table->Signature, Table->Checksum, 366 (UINT8) (Table->Checksum - Checksum))); 367 368 #if (ACPI_CHECKSUM_ABORT) 369 return (AE_BAD_CHECKSUM); 370 #endif 371 } 372 373 return (AE_OK); 374 } 375 376 377 /******************************************************************************* 378 * 379 * FUNCTION: AcpiTbChecksum 380 * 381 * PARAMETERS: Buffer - Pointer to memory region to be checked 382 * Length - Length of this memory region 383 * 384 * RETURN: Checksum (UINT8) 385 * 386 * DESCRIPTION: Calculates circular checksum of memory region. 387 * 388 ******************************************************************************/ 389 390 UINT8 391 AcpiTbChecksum ( 392 UINT8 *Buffer, 393 UINT32 Length) 394 { 395 UINT8 Sum = 0; 396 UINT8 *End = Buffer + Length; 397 398 399 while (Buffer < End) 400 { 401 Sum = (UINT8) (Sum + *(Buffer++)); 402 } 403 404 return Sum; 405 } 406 407 408 /******************************************************************************* 409 * 410 * FUNCTION: AcpiTbCheckDsdtHeader 411 * 412 * PARAMETERS: None 413 * 414 * RETURN: None 415 * 416 * DESCRIPTION: Quick compare to check validity of the DSDT. This will detect 417 * if the DSDT has been replaced from outside the OS and/or if 418 * the DSDT header has been corrupted. 419 * 420 ******************************************************************************/ 421 422 void 423 AcpiTbCheckDsdtHeader ( 424 void) 425 { 426 427 /* Compare original length and checksum to current values */ 428 429 if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length || 430 AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum) 431 { 432 ACPI_BIOS_ERROR ((AE_INFO, 433 "The DSDT has been corrupted or replaced - " 434 "old, new headers below")); 435 AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader); 436 AcpiTbPrintTableHeader (0, AcpiGbl_DSDT); 437 438 /* Disable further error messages */ 439 440 AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length; 441 AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum; 442 } 443 } 444 445 446 /******************************************************************************* 447 * 448 * FUNCTION: AcpiTbCopyDsdt 449 * 450 * PARAMETERS: TableDesc - Installed table to copy 451 * 452 * RETURN: None 453 * 454 * DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory. 455 * Some very bad BIOSs are known to either corrupt the DSDT or 456 * install a new, bad DSDT. This copy works around the problem. 457 * 458 ******************************************************************************/ 459 460 ACPI_TABLE_HEADER * 461 AcpiTbCopyDsdt ( 462 UINT32 TableIndex) 463 { 464 ACPI_TABLE_HEADER *NewTable; 465 ACPI_TABLE_DESC *TableDesc; 466 467 468 TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex]; 469 470 NewTable = ACPI_ALLOCATE (TableDesc->Length); 471 if (!NewTable) 472 { 473 ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X", 474 TableDesc->Length)); 475 return (NULL); 476 } 477 478 ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length); 479 AcpiTbDeleteTable (TableDesc); 480 TableDesc->Pointer = NewTable; 481 TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED; 482 483 ACPI_INFO ((AE_INFO, 484 "Forced DSDT copy: length 0x%05X copied locally, original unmapped", 485 NewTable->Length)); 486 487 return (NewTable); 488 } 489 490 491 /******************************************************************************* 492 * 493 * FUNCTION: AcpiTbInstallTable 494 * 495 * PARAMETERS: Address - Physical address of DSDT or FACS 496 * Signature - Table signature, NULL if no need to 497 * match 498 * TableIndex - Index into root table array 499 * 500 * RETURN: None 501 * 502 * DESCRIPTION: Install an ACPI table into the global data structure. The 503 * table override mechanism is called to allow the host 504 * OS to replace any table before it is installed in the root 505 * table array. 506 * 507 ******************************************************************************/ 508 509 void 510 AcpiTbInstallTable ( 511 ACPI_PHYSICAL_ADDRESS Address, 512 char *Signature, 513 UINT32 TableIndex) 514 { 515 ACPI_TABLE_HEADER *Table; 516 ACPI_TABLE_HEADER *FinalTable; 517 ACPI_TABLE_DESC *TableDesc; 518 519 520 if (!Address) 521 { 522 ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", 523 Signature)); 524 return; 525 } 526 527 /* Map just the table header */ 528 529 Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 530 if (!Table) 531 { 532 ACPI_ERROR ((AE_INFO, "Could not map memory for table [%s] at %p", 533 Signature, ACPI_CAST_PTR (void, Address))); 534 return; 535 } 536 537 /* If a particular signature is expected (DSDT/FACS), it must match */ 538 539 if (Signature && 540 !ACPI_COMPARE_NAME (Table->Signature, Signature)) 541 { 542 ACPI_BIOS_ERROR ((AE_INFO, 543 "Invalid signature 0x%X for ACPI table, expected [%s]", 544 *ACPI_CAST_PTR (UINT32, Table->Signature), Signature)); 545 goto UnmapAndExit; 546 } 547 548 /* 549 * Initialize the table entry. Set the pointer to NULL, since the 550 * table is not fully mapped at this time. 551 */ 552 TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex]; 553 554 TableDesc->Address = Address; 555 TableDesc->Pointer = NULL; 556 TableDesc->Length = Table->Length; 557 TableDesc->Flags = ACPI_TABLE_ORIGIN_MAPPED; 558 ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); 559 560 /* 561 * ACPI Table Override: 562 * 563 * Before we install the table, let the host OS override it with a new 564 * one if desired. Any table within the RSDT/XSDT can be replaced, 565 * including the DSDT which is pointed to by the FADT. 566 * 567 * NOTE: If the table is overridden, then FinalTable will contain a 568 * mapped pointer to the full new table. If the table is not overridden, 569 * or if there has been a physical override, then the table will be 570 * fully mapped later (in verify table). In any case, we must 571 * unmap the header that was mapped above. 572 */ 573 FinalTable = AcpiTbTableOverride (Table, TableDesc); 574 if (!FinalTable) 575 { 576 FinalTable = Table; /* There was no override */ 577 } 578 579 AcpiTbPrintTableHeader (TableDesc->Address, FinalTable); 580 581 /* Set the global integer width (based upon revision of the DSDT) */ 582 583 if (TableIndex == ACPI_TABLE_INDEX_DSDT) 584 { 585 AcpiUtSetIntegerWidth (FinalTable->Revision); 586 } 587 588 /* 589 * If we have a physical override during this early loading of the ACPI 590 * tables, unmap the table for now. It will be mapped again later when 591 * it is actually used. This supports very early loading of ACPI tables, 592 * before virtual memory is fully initialized and running within the 593 * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE 594 * flag set and will not be deleted below. 595 */ 596 if (FinalTable != Table) 597 { 598 AcpiTbDeleteTable (TableDesc); 599 } 600 601 602 UnmapAndExit: 603 604 /* Always unmap the table header that we mapped above */ 605 606 AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 607 } 608 609 610 /******************************************************************************* 611 * 612 * FUNCTION: AcpiTbGetRootTableEntry 613 * 614 * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry 615 * TableEntrySize - sizeof 32 or 64 (RSDT or XSDT) 616 * 617 * RETURN: Physical address extracted from the root table 618 * 619 * DESCRIPTION: Get one root table entry. Handles 32-bit and 64-bit cases on 620 * both 32-bit and 64-bit platforms 621 * 622 * NOTE: ACPI_PHYSICAL_ADDRESS is 32-bit on 32-bit platforms, 64-bit on 623 * 64-bit platforms. 624 * 625 ******************************************************************************/ 626 627 static ACPI_PHYSICAL_ADDRESS 628 AcpiTbGetRootTableEntry ( 629 UINT8 *TableEntry, 630 UINT32 TableEntrySize) 631 { 632 UINT64 Address64; 633 634 635 /* 636 * Get the table physical address (32-bit for RSDT, 64-bit for XSDT): 637 * Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT 638 */ 639 if (TableEntrySize == sizeof (UINT32)) 640 { 641 /* 642 * 32-bit platform, RSDT: Return 32-bit table entry 643 * 64-bit platform, RSDT: Expand 32-bit to 64-bit and return 644 */ 645 return ((ACPI_PHYSICAL_ADDRESS) (*ACPI_CAST_PTR (UINT32, TableEntry))); 646 } 647 else 648 { 649 /* 650 * 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return 651 * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, 652 * return 64-bit 653 */ 654 ACPI_MOVE_64_TO_64 (&Address64, TableEntry); 655 656 #if ACPI_MACHINE_WIDTH == 32 657 if (Address64 > ACPI_UINT32_MAX) 658 { 659 /* Will truncate 64-bit address to 32 bits, issue warning */ 660 661 ACPI_BIOS_WARNING ((AE_INFO, 662 "64-bit Physical Address in XSDT is too large (0x%8.8X%8.8X)," 663 " truncating", 664 ACPI_FORMAT_UINT64 (Address64))); 665 } 666 #endif 667 return ((ACPI_PHYSICAL_ADDRESS) (Address64)); 668 } 669 } 670 671 672 /******************************************************************************* 673 * 674 * FUNCTION: AcpiTbParseRootTable 675 * 676 * PARAMETERS: Rsdp - Pointer to the RSDP 677 * 678 * RETURN: Status 679 * 680 * DESCRIPTION: This function is called to parse the Root System Description 681 * Table (RSDT or XSDT) 682 * 683 * NOTE: Tables are mapped (not copied) for efficiency. The FACS must 684 * be mapped and cannot be copied because it contains the actual 685 * memory location of the ACPI Global Lock. 686 * 687 ******************************************************************************/ 688 689 ACPI_STATUS 690 AcpiTbParseRootTable ( 691 ACPI_PHYSICAL_ADDRESS RsdpAddress) 692 { 693 ACPI_TABLE_RSDP *Rsdp; 694 UINT32 TableEntrySize; 695 UINT32 i; 696 UINT32 TableCount; 697 ACPI_TABLE_HEADER *Table; 698 ACPI_PHYSICAL_ADDRESS Address; 699 UINT32 Length; 700 UINT8 *TableEntry; 701 ACPI_STATUS Status; 702 703 704 ACPI_FUNCTION_TRACE (TbParseRootTable); 705 706 707 /* 708 * Map the entire RSDP and extract the address of the RSDT or XSDT 709 */ 710 Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP)); 711 if (!Rsdp) 712 { 713 return_ACPI_STATUS (AE_NO_MEMORY); 714 } 715 716 AcpiTbPrintTableHeader (RsdpAddress, 717 ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp)); 718 719 /* Differentiate between RSDT and XSDT root tables */ 720 721 if (Rsdp->Revision > 1 && Rsdp->XsdtPhysicalAddress) 722 { 723 /* 724 * Root table is an XSDT (64-bit physical addresses). We must use the 725 * XSDT if the revision is > 1 and the XSDT pointer is present, as per 726 * the ACPI specification. 727 */ 728 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress; 729 TableEntrySize = sizeof (UINT64); 730 } 731 else 732 { 733 /* Root table is an RSDT (32-bit physical addresses) */ 734 735 Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress; 736 TableEntrySize = sizeof (UINT32); 737 } 738 739 /* 740 * It is not possible to map more than one entry in some environments, 741 * so unmap the RSDP here before mapping other tables 742 */ 743 AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP)); 744 745 746 /* Map the RSDT/XSDT table header to get the full table length */ 747 748 Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 749 if (!Table) 750 { 751 return_ACPI_STATUS (AE_NO_MEMORY); 752 } 753 754 AcpiTbPrintTableHeader (Address, Table); 755 756 /* Get the length of the full table, verify length and map entire table */ 757 758 Length = Table->Length; 759 AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 760 761 if (Length < sizeof (ACPI_TABLE_HEADER)) 762 { 763 ACPI_BIOS_ERROR ((AE_INFO, 764 "Invalid table length 0x%X in RSDT/XSDT", Length)); 765 return_ACPI_STATUS (AE_INVALID_TABLE_LENGTH); 766 } 767 768 Table = AcpiOsMapMemory (Address, Length); 769 if (!Table) 770 { 771 return_ACPI_STATUS (AE_NO_MEMORY); 772 } 773 774 /* Validate the root table checksum */ 775 776 Status = AcpiTbVerifyChecksum (Table, Length); 777 if (ACPI_FAILURE (Status)) 778 { 779 AcpiOsUnmapMemory (Table, Length); 780 return_ACPI_STATUS (Status); 781 } 782 783 /* Calculate the number of tables described in the root table */ 784 785 TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) / 786 TableEntrySize); 787 788 /* 789 * First two entries in the table array are reserved for the DSDT 790 * and FACS, which are not actually present in the RSDT/XSDT - they 791 * come from the FADT 792 */ 793 TableEntry = ACPI_CAST_PTR (UINT8, Table) + sizeof (ACPI_TABLE_HEADER); 794 AcpiGbl_RootTableList.CurrentTableCount = 2; 795 796 /* 797 * Initialize the root table array from the RSDT/XSDT 798 */ 799 for (i = 0; i < TableCount; i++) 800 { 801 if (AcpiGbl_RootTableList.CurrentTableCount >= 802 AcpiGbl_RootTableList.MaxTableCount) 803 { 804 /* There is no more room in the root table array, attempt resize */ 805 806 Status = AcpiTbResizeRootTableList (); 807 if (ACPI_FAILURE (Status)) 808 { 809 ACPI_WARNING ((AE_INFO, "Truncating %u table entries!", 810 (unsigned) (TableCount - 811 (AcpiGbl_RootTableList.CurrentTableCount - 2)))); 812 break; 813 } 814 } 815 816 /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ 817 818 AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount].Address = 819 AcpiTbGetRootTableEntry (TableEntry, TableEntrySize); 820 821 TableEntry += TableEntrySize; 822 AcpiGbl_RootTableList.CurrentTableCount++; 823 } 824 825 /* 826 * It is not possible to map more than one entry in some environments, 827 * so unmap the root table here before mapping other tables 828 */ 829 AcpiOsUnmapMemory (Table, Length); 830 831 /* 832 * Complete the initialization of the root table array by examining 833 * the header of each table 834 */ 835 for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 836 { 837 AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address, 838 NULL, i); 839 840 /* Special case for FADT - get the DSDT and FACS */ 841 842 if (ACPI_COMPARE_NAME ( 843 &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT)) 844 { 845 AcpiTbParseFadt (i); 846 } 847 } 848 849 return_ACPI_STATUS (AE_OK); 850 } 851