1 /****************************************************************************** 2 * 3 * Module Name: tbdata - Table manager data structure functions 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2018, 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 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include "acpi.h" 153 #include "accommon.h" 154 #include "acnamesp.h" 155 #include "actables.h" 156 #include "acevents.h" 157 158 #define _COMPONENT ACPI_TABLES 159 ACPI_MODULE_NAME ("tbdata") 160 161 /* Local prototypes */ 162 163 static ACPI_STATUS 164 AcpiTbCheckDuplication ( 165 ACPI_TABLE_DESC *TableDesc, 166 UINT32 *TableIndex); 167 168 static BOOLEAN 169 AcpiTbCompareTables ( 170 ACPI_TABLE_DESC *TableDesc, 171 UINT32 TableIndex); 172 173 174 /******************************************************************************* 175 * 176 * FUNCTION: AcpiTbCompareTables 177 * 178 * PARAMETERS: TableDesc - Table 1 descriptor to be compared 179 * TableIndex - Index of table 2 to be compared 180 * 181 * RETURN: TRUE if both tables are identical. 182 * 183 * DESCRIPTION: This function compares a table with another table that has 184 * already been installed in the root table list. 185 * 186 ******************************************************************************/ 187 188 static BOOLEAN 189 AcpiTbCompareTables ( 190 ACPI_TABLE_DESC *TableDesc, 191 UINT32 TableIndex) 192 { 193 ACPI_STATUS Status = AE_OK; 194 BOOLEAN IsIdentical; 195 ACPI_TABLE_HEADER *Table; 196 UINT32 TableLength; 197 UINT8 TableFlags; 198 199 200 Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex], 201 &Table, &TableLength, &TableFlags); 202 if (ACPI_FAILURE (Status)) 203 { 204 return (FALSE); 205 } 206 207 /* 208 * Check for a table match on the entire table length, 209 * not just the header. 210 */ 211 IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength || 212 memcmp (TableDesc->Pointer, Table, TableLength)) ? 213 FALSE : TRUE); 214 215 /* Release the acquired table */ 216 217 AcpiTbReleaseTable (Table, TableLength, TableFlags); 218 return (IsIdentical); 219 } 220 221 222 /******************************************************************************* 223 * 224 * FUNCTION: AcpiTbInitTableDescriptor 225 * 226 * PARAMETERS: TableDesc - Table descriptor 227 * Address - Physical address of the table 228 * Flags - Allocation flags of the table 229 * Table - Pointer to the table 230 * 231 * RETURN: None 232 * 233 * DESCRIPTION: Initialize a new table descriptor 234 * 235 ******************************************************************************/ 236 237 void 238 AcpiTbInitTableDescriptor ( 239 ACPI_TABLE_DESC *TableDesc, 240 ACPI_PHYSICAL_ADDRESS Address, 241 UINT8 Flags, 242 ACPI_TABLE_HEADER *Table) 243 { 244 245 /* 246 * Initialize the table descriptor. Set the pointer to NULL, since the 247 * table is not fully mapped at this time. 248 */ 249 memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC)); 250 TableDesc->Address = Address; 251 TableDesc->Length = Table->Length; 252 TableDesc->Flags = Flags; 253 ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); 254 } 255 256 257 /******************************************************************************* 258 * 259 * FUNCTION: AcpiTbAcquireTable 260 * 261 * PARAMETERS: TableDesc - Table descriptor 262 * TablePtr - Where table is returned 263 * TableLength - Where table length is returned 264 * TableFlags - Where table allocation flags are returned 265 * 266 * RETURN: Status 267 * 268 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not 269 * maintained in the AcpiGbl_RootTableList. 270 * 271 ******************************************************************************/ 272 273 ACPI_STATUS 274 AcpiTbAcquireTable ( 275 ACPI_TABLE_DESC *TableDesc, 276 ACPI_TABLE_HEADER **TablePtr, 277 UINT32 *TableLength, 278 UINT8 *TableFlags) 279 { 280 ACPI_TABLE_HEADER *Table = NULL; 281 282 283 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 284 { 285 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 286 287 Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length); 288 break; 289 290 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 291 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 292 293 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 294 ACPI_PHYSADDR_TO_PTR (TableDesc->Address)); 295 break; 296 297 default: 298 299 break; 300 } 301 302 /* Table is not valid yet */ 303 304 if (!Table) 305 { 306 return (AE_NO_MEMORY); 307 } 308 309 /* Fill the return values */ 310 311 *TablePtr = Table; 312 *TableLength = TableDesc->Length; 313 *TableFlags = TableDesc->Flags; 314 return (AE_OK); 315 } 316 317 318 /******************************************************************************* 319 * 320 * FUNCTION: AcpiTbReleaseTable 321 * 322 * PARAMETERS: Table - Pointer for the table 323 * TableLength - Length for the table 324 * TableFlags - Allocation flags for the table 325 * 326 * RETURN: None 327 * 328 * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable(). 329 * 330 ******************************************************************************/ 331 332 void 333 AcpiTbReleaseTable ( 334 ACPI_TABLE_HEADER *Table, 335 UINT32 TableLength, 336 UINT8 TableFlags) 337 { 338 339 switch (TableFlags & ACPI_TABLE_ORIGIN_MASK) 340 { 341 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 342 343 AcpiOsUnmapMemory (Table, TableLength); 344 break; 345 346 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 347 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 348 default: 349 350 break; 351 } 352 } 353 354 355 /******************************************************************************* 356 * 357 * FUNCTION: AcpiTbAcquireTempTable 358 * 359 * PARAMETERS: TableDesc - Table descriptor to be acquired 360 * Address - Address of the table 361 * Flags - Allocation flags of the table 362 * 363 * RETURN: Status 364 * 365 * DESCRIPTION: This function validates the table header to obtain the length 366 * of a table and fills the table descriptor to make its state as 367 * "INSTALLED". Such a table descriptor is only used for verified 368 * installation. 369 * 370 ******************************************************************************/ 371 372 ACPI_STATUS 373 AcpiTbAcquireTempTable ( 374 ACPI_TABLE_DESC *TableDesc, 375 ACPI_PHYSICAL_ADDRESS Address, 376 UINT8 Flags) 377 { 378 ACPI_TABLE_HEADER *TableHeader; 379 380 381 switch (Flags & ACPI_TABLE_ORIGIN_MASK) 382 { 383 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 384 385 /* Get the length of the full table from the header */ 386 387 TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 388 if (!TableHeader) 389 { 390 return (AE_NO_MEMORY); 391 } 392 393 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); 394 AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER)); 395 return (AE_OK); 396 397 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 398 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 399 400 TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 401 ACPI_PHYSADDR_TO_PTR (Address)); 402 if (!TableHeader) 403 { 404 return (AE_NO_MEMORY); 405 } 406 407 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); 408 return (AE_OK); 409 410 default: 411 412 break; 413 } 414 415 /* Table is not valid yet */ 416 417 return (AE_NO_MEMORY); 418 } 419 420 421 /******************************************************************************* 422 * 423 * FUNCTION: AcpiTbReleaseTempTable 424 * 425 * PARAMETERS: TableDesc - Table descriptor to be released 426 * 427 * RETURN: Status 428 * 429 * DESCRIPTION: The inverse of AcpiTbAcquireTempTable(). 430 * 431 *****************************************************************************/ 432 433 void 434 AcpiTbReleaseTempTable ( 435 ACPI_TABLE_DESC *TableDesc) 436 { 437 438 /* 439 * Note that the .Address is maintained by the callers of 440 * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable() 441 * where .Address will be freed. 442 */ 443 AcpiTbInvalidateTable (TableDesc); 444 } 445 446 447 /****************************************************************************** 448 * 449 * FUNCTION: AcpiTbValidateTable 450 * 451 * PARAMETERS: TableDesc - Table descriptor 452 * 453 * RETURN: Status 454 * 455 * DESCRIPTION: This function is called to validate the table, the returned 456 * table descriptor is in "VALIDATED" state. 457 * 458 *****************************************************************************/ 459 460 ACPI_STATUS 461 AcpiTbValidateTable ( 462 ACPI_TABLE_DESC *TableDesc) 463 { 464 ACPI_STATUS Status = AE_OK; 465 466 467 ACPI_FUNCTION_TRACE (TbValidateTable); 468 469 470 /* Validate the table if necessary */ 471 472 if (!TableDesc->Pointer) 473 { 474 Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer, 475 &TableDesc->Length, &TableDesc->Flags); 476 if (!TableDesc->Pointer) 477 { 478 Status = AE_NO_MEMORY; 479 } 480 } 481 482 return_ACPI_STATUS (Status); 483 } 484 485 486 /******************************************************************************* 487 * 488 * FUNCTION: AcpiTbInvalidateTable 489 * 490 * PARAMETERS: TableDesc - Table descriptor 491 * 492 * RETURN: None 493 * 494 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of 495 * AcpiTbValidateTable(). 496 * 497 ******************************************************************************/ 498 499 void 500 AcpiTbInvalidateTable ( 501 ACPI_TABLE_DESC *TableDesc) 502 { 503 504 ACPI_FUNCTION_TRACE (TbInvalidateTable); 505 506 507 /* Table must be validated */ 508 509 if (!TableDesc->Pointer) 510 { 511 return_VOID; 512 } 513 514 AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length, 515 TableDesc->Flags); 516 TableDesc->Pointer = NULL; 517 518 return_VOID; 519 } 520 521 522 /****************************************************************************** 523 * 524 * FUNCTION: AcpiTbValidateTempTable 525 * 526 * PARAMETERS: TableDesc - Table descriptor 527 * 528 * RETURN: Status 529 * 530 * DESCRIPTION: This function is called to validate the table, the returned 531 * table descriptor is in "VALIDATED" state. 532 * 533 *****************************************************************************/ 534 535 ACPI_STATUS 536 AcpiTbValidateTempTable ( 537 ACPI_TABLE_DESC *TableDesc) 538 { 539 540 if (!TableDesc->Pointer && !AcpiGbl_EnableTableValidation) 541 { 542 /* 543 * Only validates the header of the table. 544 * Note that Length contains the size of the mapping after invoking 545 * this work around, this value is required by 546 * AcpiTbReleaseTempTable(). 547 * We can do this because in AcpiInitTableDescriptor(), the Length 548 * field of the installed descriptor is filled with the actual 549 * table length obtaining from the table header. 550 */ 551 TableDesc->Length = sizeof (ACPI_TABLE_HEADER); 552 } 553 554 return (AcpiTbValidateTable (TableDesc)); 555 } 556 557 558 /******************************************************************************* 559 * 560 * FUNCTION: AcpiTbCheckDuplication 561 * 562 * PARAMETERS: TableDesc - Table descriptor 563 * TableIndex - Where the table index is returned 564 * 565 * RETURN: Status 566 * 567 * DESCRIPTION: Avoid installing duplicated tables. However table override and 568 * user aided dynamic table load is allowed, thus comparing the 569 * address of the table is not sufficient, and checking the entire 570 * table content is required. 571 * 572 ******************************************************************************/ 573 574 static ACPI_STATUS 575 AcpiTbCheckDuplication ( 576 ACPI_TABLE_DESC *TableDesc, 577 UINT32 *TableIndex) 578 { 579 UINT32 i; 580 581 582 ACPI_FUNCTION_TRACE (TbCheckDuplication); 583 584 585 /* Check if table is already registered */ 586 587 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 588 { 589 /* Do not compare with unverified tables */ 590 591 if (!(AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_VERIFIED)) 592 { 593 continue; 594 } 595 596 /* 597 * Check for a table match on the entire table length, 598 * not just the header. 599 */ 600 if (!AcpiTbCompareTables (TableDesc, i)) 601 { 602 continue; 603 } 604 605 /* 606 * Note: the current mechanism does not unregister a table if it is 607 * dynamically unloaded. The related namespace entries are deleted, 608 * but the table remains in the root table list. 609 * 610 * The assumption here is that the number of different tables that 611 * will be loaded is actually small, and there is minimal overhead 612 * in just keeping the table in case it is needed again. 613 * 614 * If this assumption changes in the future (perhaps on large 615 * machines with many table load/unload operations), tables will 616 * need to be unregistered when they are unloaded, and slots in the 617 * root table list should be reused when empty. 618 */ 619 if (AcpiGbl_RootTableList.Tables[i].Flags & 620 ACPI_TABLE_IS_LOADED) 621 { 622 /* Table is still loaded, this is an error */ 623 624 return_ACPI_STATUS (AE_ALREADY_EXISTS); 625 } 626 else 627 { 628 *TableIndex = i; 629 return_ACPI_STATUS (AE_CTRL_TERMINATE); 630 } 631 } 632 633 /* Indicate no duplication to the caller */ 634 635 return_ACPI_STATUS (AE_OK); 636 } 637 638 639 /****************************************************************************** 640 * 641 * FUNCTION: AcpiTbVerifyTempTable 642 * 643 * PARAMETERS: TableDesc - Table descriptor 644 * Signature - Table signature to verify 645 * TableIndex - Where the table index is returned 646 * 647 * RETURN: Status 648 * 649 * DESCRIPTION: This function is called to validate and verify the table, the 650 * returned table descriptor is in "VALIDATED" state. 651 * Note that 'TableIndex' is required to be set to !NULL to 652 * enable duplication check. 653 * 654 *****************************************************************************/ 655 656 ACPI_STATUS 657 AcpiTbVerifyTempTable ( 658 ACPI_TABLE_DESC *TableDesc, 659 char *Signature, 660 UINT32 *TableIndex) 661 { 662 ACPI_STATUS Status = AE_OK; 663 664 665 ACPI_FUNCTION_TRACE (TbVerifyTempTable); 666 667 668 /* Validate the table */ 669 670 Status = AcpiTbValidateTempTable (TableDesc); 671 if (ACPI_FAILURE (Status)) 672 { 673 return_ACPI_STATUS (AE_NO_MEMORY); 674 } 675 676 /* If a particular signature is expected (DSDT/FACS), it must match */ 677 678 if (Signature && 679 !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature)) 680 { 681 ACPI_BIOS_ERROR ((AE_INFO, 682 "Invalid signature 0x%X for ACPI table, expected [%s]", 683 TableDesc->Signature.Integer, Signature)); 684 Status = AE_BAD_SIGNATURE; 685 goto InvalidateAndExit; 686 } 687 688 if (AcpiGbl_EnableTableValidation) 689 { 690 /* Verify the checksum */ 691 692 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); 693 if (ACPI_FAILURE (Status)) 694 { 695 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 696 "%4.4s 0x%8.8X%8.8X" 697 " Attempted table install failed", 698 AcpiUtValidNameseg (TableDesc->Signature.Ascii) ? 699 TableDesc->Signature.Ascii : "????", 700 ACPI_FORMAT_UINT64 (TableDesc->Address))); 701 702 goto InvalidateAndExit; 703 } 704 705 /* Avoid duplications */ 706 707 if (TableIndex) 708 { 709 Status = AcpiTbCheckDuplication (TableDesc, TableIndex); 710 if (ACPI_FAILURE (Status)) 711 { 712 if (Status != AE_CTRL_TERMINATE) 713 { 714 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 715 "%4.4s 0x%8.8X%8.8X" 716 " Table is duplicated", 717 AcpiUtValidNameseg (TableDesc->Signature.Ascii) ? 718 TableDesc->Signature.Ascii : "????", 719 ACPI_FORMAT_UINT64 (TableDesc->Address))); 720 } 721 722 goto InvalidateAndExit; 723 } 724 } 725 726 TableDesc->Flags |= ACPI_TABLE_IS_VERIFIED; 727 } 728 729 return_ACPI_STATUS (Status); 730 731 InvalidateAndExit: 732 AcpiTbInvalidateTable (TableDesc); 733 return_ACPI_STATUS (Status); 734 } 735 736 737 /******************************************************************************* 738 * 739 * FUNCTION: AcpiTbResizeRootTableList 740 * 741 * PARAMETERS: None 742 * 743 * RETURN: Status 744 * 745 * DESCRIPTION: Expand the size of global table array 746 * 747 ******************************************************************************/ 748 749 ACPI_STATUS 750 AcpiTbResizeRootTableList ( 751 void) 752 { 753 ACPI_TABLE_DESC *Tables; 754 UINT32 TableCount; 755 UINT32 CurrentTableCount, MaxTableCount; 756 UINT32 i; 757 758 759 ACPI_FUNCTION_TRACE (TbResizeRootTableList); 760 761 762 /* AllowResize flag is a parameter to AcpiInitializeTables */ 763 764 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 765 { 766 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 767 return_ACPI_STATUS (AE_SUPPORT); 768 } 769 770 /* Increase the Table Array size */ 771 772 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 773 { 774 TableCount = AcpiGbl_RootTableList.MaxTableCount; 775 } 776 else 777 { 778 TableCount = AcpiGbl_RootTableList.CurrentTableCount; 779 } 780 781 MaxTableCount = TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; 782 Tables = ACPI_ALLOCATE_ZEROED ( 783 ((ACPI_SIZE) MaxTableCount) * sizeof (ACPI_TABLE_DESC)); 784 if (!Tables) 785 { 786 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 787 return_ACPI_STATUS (AE_NO_MEMORY); 788 } 789 790 /* Copy and free the previous table array */ 791 792 CurrentTableCount = 0; 793 if (AcpiGbl_RootTableList.Tables) 794 { 795 for (i = 0; i < TableCount; i++) 796 { 797 if (AcpiGbl_RootTableList.Tables[i].Address) 798 { 799 memcpy (Tables + CurrentTableCount, 800 AcpiGbl_RootTableList.Tables + i, 801 sizeof (ACPI_TABLE_DESC)); 802 CurrentTableCount++; 803 } 804 } 805 806 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 807 { 808 ACPI_FREE (AcpiGbl_RootTableList.Tables); 809 } 810 } 811 812 AcpiGbl_RootTableList.Tables = Tables; 813 AcpiGbl_RootTableList.MaxTableCount = MaxTableCount; 814 AcpiGbl_RootTableList.CurrentTableCount = CurrentTableCount; 815 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 816 817 return_ACPI_STATUS (AE_OK); 818 } 819 820 821 /******************************************************************************* 822 * 823 * FUNCTION: AcpiTbGetNextTableDescriptor 824 * 825 * PARAMETERS: TableIndex - Where table index is returned 826 * TableDesc - Where table descriptor is returned 827 * 828 * RETURN: Status and table index/descriptor. 829 * 830 * DESCRIPTION: Allocate a new ACPI table entry to the global table list 831 * 832 ******************************************************************************/ 833 834 ACPI_STATUS 835 AcpiTbGetNextTableDescriptor ( 836 UINT32 *TableIndex, 837 ACPI_TABLE_DESC **TableDesc) 838 { 839 ACPI_STATUS Status; 840 UINT32 i; 841 842 843 /* Ensure that there is room for the table in the Root Table List */ 844 845 if (AcpiGbl_RootTableList.CurrentTableCount >= 846 AcpiGbl_RootTableList.MaxTableCount) 847 { 848 Status = AcpiTbResizeRootTableList(); 849 if (ACPI_FAILURE (Status)) 850 { 851 return (Status); 852 } 853 } 854 855 i = AcpiGbl_RootTableList.CurrentTableCount; 856 AcpiGbl_RootTableList.CurrentTableCount++; 857 858 if (TableIndex) 859 { 860 *TableIndex = i; 861 } 862 if (TableDesc) 863 { 864 *TableDesc = &AcpiGbl_RootTableList.Tables[i]; 865 } 866 867 return (AE_OK); 868 } 869 870 871 /******************************************************************************* 872 * 873 * FUNCTION: AcpiTbTerminate 874 * 875 * PARAMETERS: None 876 * 877 * RETURN: None 878 * 879 * DESCRIPTION: Delete all internal ACPI tables 880 * 881 ******************************************************************************/ 882 883 void 884 AcpiTbTerminate ( 885 void) 886 { 887 UINT32 i; 888 889 890 ACPI_FUNCTION_TRACE (TbTerminate); 891 892 893 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 894 895 /* Delete the individual tables */ 896 897 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 898 { 899 AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]); 900 } 901 902 /* 903 * Delete the root table array if allocated locally. Array cannot be 904 * mapped, so we don't need to check for that flag. 905 */ 906 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 907 { 908 ACPI_FREE (AcpiGbl_RootTableList.Tables); 909 } 910 911 AcpiGbl_RootTableList.Tables = NULL; 912 AcpiGbl_RootTableList.Flags = 0; 913 AcpiGbl_RootTableList.CurrentTableCount = 0; 914 915 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 916 917 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 918 return_VOID; 919 } 920 921 922 /******************************************************************************* 923 * 924 * FUNCTION: AcpiTbDeleteNamespaceByOwner 925 * 926 * PARAMETERS: TableIndex - Table index 927 * 928 * RETURN: Status 929 * 930 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 931 * 932 ******************************************************************************/ 933 934 ACPI_STATUS 935 AcpiTbDeleteNamespaceByOwner ( 936 UINT32 TableIndex) 937 { 938 ACPI_OWNER_ID OwnerId; 939 ACPI_STATUS Status; 940 941 942 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 943 944 945 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 946 if (ACPI_FAILURE (Status)) 947 { 948 return_ACPI_STATUS (Status); 949 } 950 951 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 952 { 953 /* The table index does not exist */ 954 955 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 956 return_ACPI_STATUS (AE_NOT_EXIST); 957 } 958 959 /* Get the owner ID for this table, used to delete namespace nodes */ 960 961 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 962 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 963 964 /* 965 * Need to acquire the namespace writer lock to prevent interference 966 * with any concurrent namespace walks. The interpreter must be 967 * released during the deletion since the acquisition of the deletion 968 * lock may block, and also since the execution of a namespace walk 969 * must be allowed to use the interpreter. 970 */ 971 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 972 if (ACPI_FAILURE (Status)) 973 { 974 return_ACPI_STATUS (Status); 975 } 976 AcpiNsDeleteNamespaceByOwner (OwnerId); 977 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 978 return_ACPI_STATUS (Status); 979 } 980 981 982 /******************************************************************************* 983 * 984 * FUNCTION: AcpiTbAllocateOwnerId 985 * 986 * PARAMETERS: TableIndex - Table index 987 * 988 * RETURN: Status 989 * 990 * DESCRIPTION: Allocates OwnerId in TableDesc 991 * 992 ******************************************************************************/ 993 994 ACPI_STATUS 995 AcpiTbAllocateOwnerId ( 996 UINT32 TableIndex) 997 { 998 ACPI_STATUS Status = AE_BAD_PARAMETER; 999 1000 1001 ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 1002 1003 1004 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1005 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1006 { 1007 Status = AcpiUtAllocateOwnerId ( 1008 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 1009 } 1010 1011 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1012 return_ACPI_STATUS (Status); 1013 } 1014 1015 1016 /******************************************************************************* 1017 * 1018 * FUNCTION: AcpiTbReleaseOwnerId 1019 * 1020 * PARAMETERS: TableIndex - Table index 1021 * 1022 * RETURN: Status 1023 * 1024 * DESCRIPTION: Releases OwnerId in TableDesc 1025 * 1026 ******************************************************************************/ 1027 1028 ACPI_STATUS 1029 AcpiTbReleaseOwnerId ( 1030 UINT32 TableIndex) 1031 { 1032 ACPI_STATUS Status = AE_BAD_PARAMETER; 1033 1034 1035 ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 1036 1037 1038 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1039 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1040 { 1041 AcpiUtReleaseOwnerId ( 1042 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 1043 Status = AE_OK; 1044 } 1045 1046 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1047 return_ACPI_STATUS (Status); 1048 } 1049 1050 1051 /******************************************************************************* 1052 * 1053 * FUNCTION: AcpiTbGetOwnerId 1054 * 1055 * PARAMETERS: TableIndex - Table index 1056 * OwnerId - Where the table OwnerId is returned 1057 * 1058 * RETURN: Status 1059 * 1060 * DESCRIPTION: returns OwnerId for the ACPI table 1061 * 1062 ******************************************************************************/ 1063 1064 ACPI_STATUS 1065 AcpiTbGetOwnerId ( 1066 UINT32 TableIndex, 1067 ACPI_OWNER_ID *OwnerId) 1068 { 1069 ACPI_STATUS Status = AE_BAD_PARAMETER; 1070 1071 1072 ACPI_FUNCTION_TRACE (TbGetOwnerId); 1073 1074 1075 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1076 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1077 { 1078 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 1079 Status = AE_OK; 1080 } 1081 1082 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1083 return_ACPI_STATUS (Status); 1084 } 1085 1086 1087 /******************************************************************************* 1088 * 1089 * FUNCTION: AcpiTbIsTableLoaded 1090 * 1091 * PARAMETERS: TableIndex - Index into the root table 1092 * 1093 * RETURN: Table Loaded Flag 1094 * 1095 ******************************************************************************/ 1096 1097 BOOLEAN 1098 AcpiTbIsTableLoaded ( 1099 UINT32 TableIndex) 1100 { 1101 BOOLEAN IsLoaded = FALSE; 1102 1103 1104 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1105 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1106 { 1107 IsLoaded = (BOOLEAN) 1108 (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 1109 ACPI_TABLE_IS_LOADED); 1110 } 1111 1112 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1113 return (IsLoaded); 1114 } 1115 1116 1117 /******************************************************************************* 1118 * 1119 * FUNCTION: AcpiTbSetTableLoadedFlag 1120 * 1121 * PARAMETERS: TableIndex - Table index 1122 * IsLoaded - TRUE if table is loaded, FALSE otherwise 1123 * 1124 * RETURN: None 1125 * 1126 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 1127 * 1128 ******************************************************************************/ 1129 1130 void 1131 AcpiTbSetTableLoadedFlag ( 1132 UINT32 TableIndex, 1133 BOOLEAN IsLoaded) 1134 { 1135 1136 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1137 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1138 { 1139 if (IsLoaded) 1140 { 1141 AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 1142 ACPI_TABLE_IS_LOADED; 1143 } 1144 else 1145 { 1146 AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 1147 ~ACPI_TABLE_IS_LOADED; 1148 } 1149 } 1150 1151 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1152 } 1153 1154 1155 /******************************************************************************* 1156 * 1157 * FUNCTION: AcpiTbLoadTable 1158 * 1159 * PARAMETERS: TableIndex - Table index 1160 * ParentNode - Where table index is returned 1161 * 1162 * RETURN: Status 1163 * 1164 * DESCRIPTION: Load an ACPI table 1165 * 1166 ******************************************************************************/ 1167 1168 ACPI_STATUS 1169 AcpiTbLoadTable ( 1170 UINT32 TableIndex, 1171 ACPI_NAMESPACE_NODE *ParentNode) 1172 { 1173 ACPI_TABLE_HEADER *Table; 1174 ACPI_STATUS Status; 1175 ACPI_OWNER_ID OwnerId; 1176 1177 1178 ACPI_FUNCTION_TRACE (TbLoadTable); 1179 1180 1181 /* 1182 * Note: Now table is "INSTALLED", it must be validated before 1183 * using. 1184 */ 1185 Status = AcpiGetTableByIndex (TableIndex, &Table); 1186 if (ACPI_FAILURE (Status)) 1187 { 1188 return_ACPI_STATUS (Status); 1189 } 1190 1191 Status = AcpiNsLoadTable (TableIndex, ParentNode); 1192 1193 /* 1194 * This case handles the legacy option that groups all module-level 1195 * code blocks together and defers execution until all of the tables 1196 * are loaded. Execute all of these blocks at this time. 1197 * Execute any module-level code that was detected during the table 1198 * load phase. 1199 * 1200 * Note: this option is deprecated and will be eliminated in the 1201 * future. Use of this option can cause problems with AML code that 1202 * depends upon in-order immediate execution of module-level code. 1203 */ 1204 AcpiNsExecModuleCodeList (); 1205 1206 /* 1207 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is 1208 * responsible for discovering any new wake GPEs by running _PRW methods 1209 * that may have been loaded by this table. 1210 */ 1211 Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); 1212 if (ACPI_SUCCESS (Status)) 1213 { 1214 AcpiEvUpdateGpes (OwnerId); 1215 } 1216 1217 /* Invoke table handler */ 1218 1219 AcpiTbNotifyTable (ACPI_TABLE_EVENT_LOAD, Table); 1220 return_ACPI_STATUS (Status); 1221 } 1222 1223 1224 /******************************************************************************* 1225 * 1226 * FUNCTION: AcpiTbInstallAndLoadTable 1227 * 1228 * PARAMETERS: Address - Physical address of the table 1229 * Flags - Allocation flags of the table 1230 * Override - Whether override should be performed 1231 * TableIndex - Where table index is returned 1232 * 1233 * RETURN: Status 1234 * 1235 * DESCRIPTION: Install and load an ACPI table 1236 * 1237 ******************************************************************************/ 1238 1239 ACPI_STATUS 1240 AcpiTbInstallAndLoadTable ( 1241 ACPI_PHYSICAL_ADDRESS Address, 1242 UINT8 Flags, 1243 BOOLEAN Override, 1244 UINT32 *TableIndex) 1245 { 1246 ACPI_STATUS Status; 1247 UINT32 i; 1248 1249 1250 ACPI_FUNCTION_TRACE (TbInstallAndLoadTable); 1251 1252 1253 /* Install the table and load it into the namespace */ 1254 1255 Status = AcpiTbInstallStandardTable (Address, Flags, TRUE, 1256 Override, &i); 1257 if (ACPI_FAILURE (Status)) 1258 { 1259 goto Exit; 1260 } 1261 1262 Status = AcpiTbLoadTable (i, AcpiGbl_RootNode); 1263 1264 Exit: 1265 *TableIndex = i; 1266 return_ACPI_STATUS (Status); 1267 } 1268 1269 1270 /******************************************************************************* 1271 * 1272 * FUNCTION: AcpiTbUnloadTable 1273 * 1274 * PARAMETERS: TableIndex - Table index 1275 * 1276 * RETURN: Status 1277 * 1278 * DESCRIPTION: Unload an ACPI table 1279 * 1280 ******************************************************************************/ 1281 1282 ACPI_STATUS 1283 AcpiTbUnloadTable ( 1284 UINT32 TableIndex) 1285 { 1286 ACPI_STATUS Status = AE_OK; 1287 ACPI_TABLE_HEADER *Table; 1288 1289 1290 ACPI_FUNCTION_TRACE (TbUnloadTable); 1291 1292 1293 /* Ensure the table is still loaded */ 1294 1295 if (!AcpiTbIsTableLoaded (TableIndex)) 1296 { 1297 return_ACPI_STATUS (AE_NOT_EXIST); 1298 } 1299 1300 /* Invoke table handler */ 1301 1302 Status = AcpiGetTableByIndex (TableIndex, &Table); 1303 if (ACPI_SUCCESS (Status)) 1304 { 1305 AcpiTbNotifyTable (ACPI_TABLE_EVENT_UNLOAD, Table); 1306 } 1307 1308 /* Delete the portion of the namespace owned by this table */ 1309 1310 Status = AcpiTbDeleteNamespaceByOwner (TableIndex); 1311 if (ACPI_FAILURE (Status)) 1312 { 1313 return_ACPI_STATUS (Status); 1314 } 1315 1316 (void) AcpiTbReleaseOwnerId (TableIndex); 1317 AcpiTbSetTableLoadedFlag (TableIndex, FALSE); 1318 return_ACPI_STATUS (Status); 1319 } 1320 1321 1322 /******************************************************************************* 1323 * 1324 * FUNCTION: AcpiTbNotifyTable 1325 * 1326 * PARAMETERS: Event - Table event 1327 * Table - Validated table pointer 1328 * 1329 * RETURN: None 1330 * 1331 * DESCRIPTION: Notify a table event to the users. 1332 * 1333 ******************************************************************************/ 1334 1335 void 1336 AcpiTbNotifyTable ( 1337 UINT32 Event, 1338 void *Table) 1339 { 1340 /* Invoke table handler if present */ 1341 1342 if (AcpiGbl_TableHandler) 1343 { 1344 (void) AcpiGbl_TableHandler (Event, Table, 1345 AcpiGbl_TableHandlerContext); 1346 } 1347 } 1348