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 - 2023, 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 <contrib/dev/acpica/include/acpi.h> 153 #include <contrib/dev/acpica/include/accommon.h> 154 #include <contrib/dev/acpica/include/acnamesp.h> 155 #include <contrib/dev/acpica/include/actables.h> 156 #include <contrib/dev/acpica/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 for external 247 * tables, since the 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 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 256 { 257 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 258 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 259 260 TableDesc->Pointer = Table; 261 break; 262 263 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 264 default: 265 266 break; 267 } 268 } 269 270 271 /******************************************************************************* 272 * 273 * FUNCTION: AcpiTbAcquireTable 274 * 275 * PARAMETERS: TableDesc - Table descriptor 276 * TablePtr - Where table is returned 277 * TableLength - Where table length is returned 278 * TableFlags - Where table allocation flags are returned 279 * 280 * RETURN: Status 281 * 282 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not 283 * maintained in the AcpiGbl_RootTableList. 284 * 285 ******************************************************************************/ 286 287 ACPI_STATUS 288 AcpiTbAcquireTable ( 289 ACPI_TABLE_DESC *TableDesc, 290 ACPI_TABLE_HEADER **TablePtr, 291 UINT32 *TableLength, 292 UINT8 *TableFlags) 293 { 294 ACPI_TABLE_HEADER *Table = NULL; 295 296 297 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 298 { 299 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 300 301 Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length); 302 break; 303 304 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 305 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 306 307 Table = TableDesc->Pointer; 308 break; 309 310 default: 311 312 break; 313 } 314 315 /* Table is not valid yet */ 316 317 if (!Table) 318 { 319 return (AE_NO_MEMORY); 320 } 321 322 /* Fill the return values */ 323 324 *TablePtr = Table; 325 *TableLength = TableDesc->Length; 326 *TableFlags = TableDesc->Flags; 327 return (AE_OK); 328 } 329 330 331 /******************************************************************************* 332 * 333 * FUNCTION: AcpiTbReleaseTable 334 * 335 * PARAMETERS: Table - Pointer for the table 336 * TableLength - Length for the table 337 * TableFlags - Allocation flags for the table 338 * 339 * RETURN: None 340 * 341 * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable(). 342 * 343 ******************************************************************************/ 344 345 void 346 AcpiTbReleaseTable ( 347 ACPI_TABLE_HEADER *Table, 348 UINT32 TableLength, 349 UINT8 TableFlags) 350 { 351 352 switch (TableFlags & ACPI_TABLE_ORIGIN_MASK) 353 { 354 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 355 356 AcpiOsUnmapMemory (Table, TableLength); 357 break; 358 359 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 360 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 361 default: 362 363 break; 364 } 365 } 366 367 368 /******************************************************************************* 369 * 370 * FUNCTION: AcpiTbAcquireTempTable 371 * 372 * PARAMETERS: TableDesc - Table descriptor to be acquired 373 * Address - Address of the table 374 * Flags - Allocation flags of the table 375 * Table - Pointer to the table (required for virtual 376 * origins, optional for physical) 377 * 378 * RETURN: Status 379 * 380 * DESCRIPTION: This function validates the table header to obtain the length 381 * of a table and fills the table descriptor to make its state as 382 * "INSTALLED". Such a table descriptor is only used for verified 383 * installation. 384 * 385 ******************************************************************************/ 386 387 ACPI_STATUS 388 AcpiTbAcquireTempTable ( 389 ACPI_TABLE_DESC *TableDesc, 390 ACPI_PHYSICAL_ADDRESS Address, 391 UINT8 Flags, 392 ACPI_TABLE_HEADER *Table) 393 { 394 BOOLEAN MappedTable = FALSE; 395 396 397 switch (Flags & ACPI_TABLE_ORIGIN_MASK) 398 { 399 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 400 401 /* Get the length of the full table from the header */ 402 403 if (!Table) 404 { 405 Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 406 if (!Table) 407 { 408 return (AE_NO_MEMORY); 409 } 410 411 MappedTable = TRUE; 412 } 413 414 break; 415 416 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 417 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 418 419 if (!Table) 420 { 421 return (AE_BAD_PARAMETER); 422 } 423 424 break; 425 426 default: 427 428 /* Table is not valid yet */ 429 430 return (AE_NO_MEMORY); 431 } 432 433 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, Table); 434 if (MappedTable) 435 { 436 AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); 437 } 438 439 return (AE_OK); 440 } 441 442 443 /******************************************************************************* 444 * 445 * FUNCTION: AcpiTbReleaseTempTable 446 * 447 * PARAMETERS: TableDesc - Table descriptor to be released 448 * 449 * RETURN: Status 450 * 451 * DESCRIPTION: The inverse of AcpiTbAcquireTempTable(). 452 * 453 *****************************************************************************/ 454 455 void 456 AcpiTbReleaseTempTable ( 457 ACPI_TABLE_DESC *TableDesc) 458 { 459 460 /* 461 * Note that the .Address is maintained by the callers of 462 * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable() 463 * where .Address will be freed. 464 */ 465 AcpiTbInvalidateTable (TableDesc); 466 } 467 468 469 /****************************************************************************** 470 * 471 * FUNCTION: AcpiTbValidateTable 472 * 473 * PARAMETERS: TableDesc - Table descriptor 474 * 475 * RETURN: Status 476 * 477 * DESCRIPTION: This function is called to validate the table, the returned 478 * table descriptor is in "VALIDATED" state. 479 * 480 *****************************************************************************/ 481 482 ACPI_STATUS 483 AcpiTbValidateTable ( 484 ACPI_TABLE_DESC *TableDesc) 485 { 486 ACPI_STATUS Status = AE_OK; 487 488 489 ACPI_FUNCTION_TRACE (TbValidateTable); 490 491 492 /* Validate the table if necessary */ 493 494 if (!TableDesc->Pointer) 495 { 496 Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer, 497 &TableDesc->Length, &TableDesc->Flags); 498 if (!TableDesc->Pointer) 499 { 500 Status = AE_NO_MEMORY; 501 } 502 } 503 504 return_ACPI_STATUS (Status); 505 } 506 507 508 /******************************************************************************* 509 * 510 * FUNCTION: AcpiTbInvalidateTable 511 * 512 * PARAMETERS: TableDesc - Table descriptor 513 * 514 * RETURN: None 515 * 516 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of 517 * AcpiTbValidateTable(). 518 * 519 ******************************************************************************/ 520 521 void 522 AcpiTbInvalidateTable ( 523 ACPI_TABLE_DESC *TableDesc) 524 { 525 526 ACPI_FUNCTION_TRACE (TbInvalidateTable); 527 528 529 /* Table must be validated */ 530 531 if (!TableDesc->Pointer) 532 { 533 return_VOID; 534 } 535 536 AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length, 537 TableDesc->Flags); 538 539 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 540 { 541 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 542 543 TableDesc->Pointer = NULL; 544 break; 545 546 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 547 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 548 default: 549 550 break; 551 } 552 553 return_VOID; 554 } 555 556 557 /****************************************************************************** 558 * 559 * FUNCTION: AcpiTbValidateTempTable 560 * 561 * PARAMETERS: TableDesc - Table descriptor 562 * 563 * RETURN: Status 564 * 565 * DESCRIPTION: This function is called to validate the table, the returned 566 * table descriptor is in "VALIDATED" state. 567 * 568 *****************************************************************************/ 569 570 ACPI_STATUS 571 AcpiTbValidateTempTable ( 572 ACPI_TABLE_DESC *TableDesc) 573 { 574 575 if (!TableDesc->Pointer && !AcpiGbl_EnableTableValidation) 576 { 577 /* 578 * Only validates the header of the table. 579 * Note that Length contains the size of the mapping after invoking 580 * this work around, this value is required by 581 * AcpiTbReleaseTempTable(). 582 * We can do this because in AcpiInitTableDescriptor(), the Length 583 * field of the installed descriptor is filled with the actual 584 * table length obtaining from the table header. 585 */ 586 TableDesc->Length = sizeof (ACPI_TABLE_HEADER); 587 } 588 589 return (AcpiTbValidateTable (TableDesc)); 590 } 591 592 593 /******************************************************************************* 594 * 595 * FUNCTION: AcpiTbCheckDuplication 596 * 597 * PARAMETERS: TableDesc - Table descriptor 598 * TableIndex - Where the table index is returned 599 * 600 * RETURN: Status 601 * 602 * DESCRIPTION: Avoid installing duplicated tables. However table override and 603 * user aided dynamic table load is allowed, thus comparing the 604 * address of the table is not sufficient, and checking the entire 605 * table content is required. 606 * 607 ******************************************************************************/ 608 609 static ACPI_STATUS 610 AcpiTbCheckDuplication ( 611 ACPI_TABLE_DESC *TableDesc, 612 UINT32 *TableIndex) 613 { 614 UINT32 i; 615 616 617 ACPI_FUNCTION_TRACE (TbCheckDuplication); 618 619 620 /* Check if table is already registered */ 621 622 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 623 { 624 /* Do not compare with unverified tables */ 625 626 if (!(AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_VERIFIED)) 627 { 628 continue; 629 } 630 631 /* 632 * Check for a table match on the entire table length, 633 * not just the header. 634 */ 635 if (!AcpiTbCompareTables (TableDesc, i)) 636 { 637 continue; 638 } 639 640 /* 641 * Note: the current mechanism does not unregister a table if it is 642 * dynamically unloaded. The related namespace entries are deleted, 643 * but the table remains in the root table list. 644 * 645 * The assumption here is that the number of different tables that 646 * will be loaded is actually small, and there is minimal overhead 647 * in just keeping the table in case it is needed again. 648 * 649 * If this assumption changes in the future (perhaps on large 650 * machines with many table load/unload operations), tables will 651 * need to be unregistered when they are unloaded, and slots in the 652 * root table list should be reused when empty. 653 */ 654 if (AcpiGbl_RootTableList.Tables[i].Flags & 655 ACPI_TABLE_IS_LOADED) 656 { 657 /* Table is still loaded, this is an error */ 658 659 return_ACPI_STATUS (AE_ALREADY_EXISTS); 660 } 661 else 662 { 663 *TableIndex = i; 664 return_ACPI_STATUS (AE_CTRL_TERMINATE); 665 } 666 } 667 668 /* Indicate no duplication to the caller */ 669 670 return_ACPI_STATUS (AE_OK); 671 } 672 673 674 /****************************************************************************** 675 * 676 * FUNCTION: AcpiTbVerifyTempTable 677 * 678 * PARAMETERS: TableDesc - Table descriptor 679 * Signature - Table signature to verify 680 * TableIndex - Where the table index is returned 681 * 682 * RETURN: Status 683 * 684 * DESCRIPTION: This function is called to validate and verify the table, the 685 * returned table descriptor is in "VALIDATED" state. 686 * Note that 'TableIndex' is required to be set to !NULL to 687 * enable duplication check. 688 * 689 *****************************************************************************/ 690 691 ACPI_STATUS 692 AcpiTbVerifyTempTable ( 693 ACPI_TABLE_DESC *TableDesc, 694 char *Signature, 695 UINT32 *TableIndex) 696 { 697 ACPI_STATUS Status = AE_OK; 698 699 700 ACPI_FUNCTION_TRACE (TbVerifyTempTable); 701 702 703 /* Validate the table */ 704 705 Status = AcpiTbValidateTempTable (TableDesc); 706 if (ACPI_FAILURE (Status)) 707 { 708 return_ACPI_STATUS (AE_NO_MEMORY); 709 } 710 711 /* If a particular signature is expected (DSDT/FACS), it must match */ 712 713 if (Signature && 714 !ACPI_COMPARE_NAMESEG (&TableDesc->Signature, Signature)) 715 { 716 ACPI_BIOS_ERROR ((AE_INFO, 717 "Invalid signature 0x%X for ACPI table, expected [%s]", 718 TableDesc->Signature.Integer, Signature)); 719 Status = AE_BAD_SIGNATURE; 720 goto InvalidateAndExit; 721 } 722 723 if (AcpiGbl_EnableTableValidation) 724 { 725 /* Verify the checksum */ 726 727 Status = AcpiUtVerifyChecksum (TableDesc->Pointer, TableDesc->Length); 728 if (ACPI_FAILURE (Status)) 729 { 730 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 731 "%4.4s 0x%8.8X%8.8X" 732 " Attempted table install failed", 733 AcpiUtValidNameseg (TableDesc->Signature.Ascii) ? 734 TableDesc->Signature.Ascii : "????", 735 ACPI_FORMAT_UINT64 (TableDesc->Address))); 736 737 goto InvalidateAndExit; 738 } 739 740 /* Avoid duplications */ 741 742 if (TableIndex) 743 { 744 Status = AcpiTbCheckDuplication (TableDesc, TableIndex); 745 if (ACPI_FAILURE (Status)) 746 { 747 if (Status != AE_CTRL_TERMINATE) 748 { 749 ACPI_EXCEPTION ((AE_INFO, Status, 750 "%4.4s 0x%8.8X%8.8X" 751 " Table is already loaded", 752 AcpiUtValidNameseg (TableDesc->Signature.Ascii) ? 753 TableDesc->Signature.Ascii : "????", 754 ACPI_FORMAT_UINT64 (TableDesc->Address))); 755 } 756 757 goto InvalidateAndExit; 758 } 759 } 760 761 TableDesc->Flags |= ACPI_TABLE_IS_VERIFIED; 762 } 763 764 return_ACPI_STATUS (Status); 765 766 InvalidateAndExit: 767 AcpiTbInvalidateTable (TableDesc); 768 return_ACPI_STATUS (Status); 769 } 770 771 772 /******************************************************************************* 773 * 774 * FUNCTION: AcpiTbResizeRootTableList 775 * 776 * PARAMETERS: None 777 * 778 * RETURN: Status 779 * 780 * DESCRIPTION: Expand the size of global table array 781 * 782 ******************************************************************************/ 783 784 ACPI_STATUS 785 AcpiTbResizeRootTableList ( 786 void) 787 { 788 ACPI_TABLE_DESC *Tables; 789 UINT32 TableCount; 790 UINT32 CurrentTableCount, MaxTableCount; 791 UINT32 i; 792 793 794 ACPI_FUNCTION_TRACE (TbResizeRootTableList); 795 796 797 /* AllowResize flag is a parameter to AcpiInitializeTables */ 798 799 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 800 { 801 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 802 return_ACPI_STATUS (AE_SUPPORT); 803 } 804 805 /* Increase the Table Array size */ 806 807 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 808 { 809 TableCount = AcpiGbl_RootTableList.MaxTableCount; 810 } 811 else 812 { 813 TableCount = AcpiGbl_RootTableList.CurrentTableCount; 814 } 815 816 MaxTableCount = TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; 817 Tables = ACPI_ALLOCATE_ZEROED ( 818 ((ACPI_SIZE) MaxTableCount) * sizeof (ACPI_TABLE_DESC)); 819 if (!Tables) 820 { 821 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 822 return_ACPI_STATUS (AE_NO_MEMORY); 823 } 824 825 /* Copy and free the previous table array */ 826 827 CurrentTableCount = 0; 828 if (AcpiGbl_RootTableList.Tables) 829 { 830 for (i = 0; i < TableCount; i++) 831 { 832 if (AcpiGbl_RootTableList.Tables[i].Address) 833 { 834 memcpy (Tables + CurrentTableCount, 835 AcpiGbl_RootTableList.Tables + i, 836 sizeof (ACPI_TABLE_DESC)); 837 CurrentTableCount++; 838 } 839 } 840 841 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 842 { 843 ACPI_FREE (AcpiGbl_RootTableList.Tables); 844 } 845 } 846 847 AcpiGbl_RootTableList.Tables = Tables; 848 AcpiGbl_RootTableList.MaxTableCount = MaxTableCount; 849 AcpiGbl_RootTableList.CurrentTableCount = CurrentTableCount; 850 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 851 852 return_ACPI_STATUS (AE_OK); 853 } 854 855 856 /******************************************************************************* 857 * 858 * FUNCTION: AcpiTbGetNextTableDescriptor 859 * 860 * PARAMETERS: TableIndex - Where table index is returned 861 * TableDesc - Where table descriptor is returned 862 * 863 * RETURN: Status and table index/descriptor. 864 * 865 * DESCRIPTION: Allocate a new ACPI table entry to the global table list 866 * 867 ******************************************************************************/ 868 869 ACPI_STATUS 870 AcpiTbGetNextTableDescriptor ( 871 UINT32 *TableIndex, 872 ACPI_TABLE_DESC **TableDesc) 873 { 874 ACPI_STATUS Status; 875 UINT32 i; 876 877 878 /* Ensure that there is room for the table in the Root Table List */ 879 880 if (AcpiGbl_RootTableList.CurrentTableCount >= 881 AcpiGbl_RootTableList.MaxTableCount) 882 { 883 Status = AcpiTbResizeRootTableList(); 884 if (ACPI_FAILURE (Status)) 885 { 886 return (Status); 887 } 888 } 889 890 i = AcpiGbl_RootTableList.CurrentTableCount; 891 AcpiGbl_RootTableList.CurrentTableCount++; 892 893 if (TableIndex) 894 { 895 *TableIndex = i; 896 } 897 if (TableDesc) 898 { 899 *TableDesc = &AcpiGbl_RootTableList.Tables[i]; 900 } 901 902 return (AE_OK); 903 } 904 905 906 /******************************************************************************* 907 * 908 * FUNCTION: AcpiTbTerminate 909 * 910 * PARAMETERS: None 911 * 912 * RETURN: None 913 * 914 * DESCRIPTION: Delete all internal ACPI tables 915 * 916 ******************************************************************************/ 917 918 void 919 AcpiTbTerminate ( 920 void) 921 { 922 UINT32 i; 923 924 925 ACPI_FUNCTION_TRACE (TbTerminate); 926 927 928 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 929 930 /* Delete the individual tables */ 931 932 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 933 { 934 AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]); 935 } 936 937 /* 938 * Delete the root table array if allocated locally. Array cannot be 939 * mapped, so we don't need to check for that flag. 940 */ 941 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 942 { 943 ACPI_FREE (AcpiGbl_RootTableList.Tables); 944 } 945 946 AcpiGbl_RootTableList.Tables = NULL; 947 AcpiGbl_RootTableList.Flags = 0; 948 AcpiGbl_RootTableList.CurrentTableCount = 0; 949 950 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 951 952 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 953 return_VOID; 954 } 955 956 957 /******************************************************************************* 958 * 959 * FUNCTION: AcpiTbDeleteNamespaceByOwner 960 * 961 * PARAMETERS: TableIndex - Table index 962 * 963 * RETURN: Status 964 * 965 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 966 * 967 ******************************************************************************/ 968 969 ACPI_STATUS 970 AcpiTbDeleteNamespaceByOwner ( 971 UINT32 TableIndex) 972 { 973 ACPI_OWNER_ID OwnerId; 974 ACPI_STATUS Status; 975 976 977 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 978 979 980 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 981 if (ACPI_FAILURE (Status)) 982 { 983 return_ACPI_STATUS (Status); 984 } 985 986 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 987 { 988 /* The table index does not exist */ 989 990 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 991 return_ACPI_STATUS (AE_NOT_EXIST); 992 } 993 994 /* Get the owner ID for this table, used to delete namespace nodes */ 995 996 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 997 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 998 999 /* 1000 * Need to acquire the namespace writer lock to prevent interference 1001 * with any concurrent namespace walks. The interpreter must be 1002 * released during the deletion since the acquisition of the deletion 1003 * lock may block, and also since the execution of a namespace walk 1004 * must be allowed to use the interpreter. 1005 */ 1006 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 1007 if (ACPI_FAILURE (Status)) 1008 { 1009 return_ACPI_STATUS (Status); 1010 } 1011 1012 AcpiNsDeleteNamespaceByOwner (OwnerId); 1013 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 1014 return_ACPI_STATUS (Status); 1015 } 1016 1017 1018 /******************************************************************************* 1019 * 1020 * FUNCTION: AcpiTbAllocateOwnerId 1021 * 1022 * PARAMETERS: TableIndex - Table index 1023 * 1024 * RETURN: Status 1025 * 1026 * DESCRIPTION: Allocates OwnerId in TableDesc 1027 * 1028 ******************************************************************************/ 1029 1030 ACPI_STATUS 1031 AcpiTbAllocateOwnerId ( 1032 UINT32 TableIndex) 1033 { 1034 ACPI_STATUS Status = AE_BAD_PARAMETER; 1035 1036 1037 ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 1038 1039 1040 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1041 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1042 { 1043 Status = AcpiUtAllocateOwnerId ( 1044 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 1045 } 1046 1047 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1048 return_ACPI_STATUS (Status); 1049 } 1050 1051 1052 /******************************************************************************* 1053 * 1054 * FUNCTION: AcpiTbReleaseOwnerId 1055 * 1056 * PARAMETERS: TableIndex - Table index 1057 * 1058 * RETURN: Status 1059 * 1060 * DESCRIPTION: Releases OwnerId in TableDesc 1061 * 1062 ******************************************************************************/ 1063 1064 ACPI_STATUS 1065 AcpiTbReleaseOwnerId ( 1066 UINT32 TableIndex) 1067 { 1068 ACPI_STATUS Status = AE_BAD_PARAMETER; 1069 1070 1071 ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 1072 1073 1074 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1075 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1076 { 1077 AcpiUtReleaseOwnerId ( 1078 &(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: AcpiTbGetOwnerId 1090 * 1091 * PARAMETERS: TableIndex - Table index 1092 * OwnerId - Where the table OwnerId is returned 1093 * 1094 * RETURN: Status 1095 * 1096 * DESCRIPTION: returns OwnerId for the ACPI table 1097 * 1098 ******************************************************************************/ 1099 1100 ACPI_STATUS 1101 AcpiTbGetOwnerId ( 1102 UINT32 TableIndex, 1103 ACPI_OWNER_ID *OwnerId) 1104 { 1105 ACPI_STATUS Status = AE_BAD_PARAMETER; 1106 1107 1108 ACPI_FUNCTION_TRACE (TbGetOwnerId); 1109 1110 1111 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1112 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1113 { 1114 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 1115 Status = AE_OK; 1116 } 1117 1118 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1119 return_ACPI_STATUS (Status); 1120 } 1121 1122 1123 /******************************************************************************* 1124 * 1125 * FUNCTION: AcpiTbIsTableLoaded 1126 * 1127 * PARAMETERS: TableIndex - Index into the root table 1128 * 1129 * RETURN: Table Loaded Flag 1130 * 1131 ******************************************************************************/ 1132 1133 BOOLEAN 1134 AcpiTbIsTableLoaded ( 1135 UINT32 TableIndex) 1136 { 1137 BOOLEAN IsLoaded = FALSE; 1138 1139 1140 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1141 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1142 { 1143 IsLoaded = (BOOLEAN) 1144 (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 1145 ACPI_TABLE_IS_LOADED); 1146 } 1147 1148 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1149 return (IsLoaded); 1150 } 1151 1152 1153 /******************************************************************************* 1154 * 1155 * FUNCTION: AcpiTbSetTableLoadedFlag 1156 * 1157 * PARAMETERS: TableIndex - Table index 1158 * IsLoaded - TRUE if table is loaded, FALSE otherwise 1159 * 1160 * RETURN: None 1161 * 1162 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 1163 * 1164 ******************************************************************************/ 1165 1166 void 1167 AcpiTbSetTableLoadedFlag ( 1168 UINT32 TableIndex, 1169 BOOLEAN IsLoaded) 1170 { 1171 1172 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1173 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 1174 { 1175 if (IsLoaded) 1176 { 1177 AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 1178 ACPI_TABLE_IS_LOADED; 1179 } 1180 else 1181 { 1182 AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 1183 ~ACPI_TABLE_IS_LOADED; 1184 } 1185 } 1186 1187 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1188 } 1189 1190 1191 /******************************************************************************* 1192 * 1193 * FUNCTION: AcpiTbLoadTable 1194 * 1195 * PARAMETERS: TableIndex - Table index 1196 * ParentNode - Where table index is returned 1197 * 1198 * RETURN: Status 1199 * 1200 * DESCRIPTION: Load an ACPI table 1201 * 1202 ******************************************************************************/ 1203 1204 ACPI_STATUS 1205 AcpiTbLoadTable ( 1206 UINT32 TableIndex, 1207 ACPI_NAMESPACE_NODE *ParentNode) 1208 { 1209 ACPI_TABLE_HEADER *Table; 1210 ACPI_STATUS Status; 1211 ACPI_OWNER_ID OwnerId; 1212 1213 1214 ACPI_FUNCTION_TRACE (TbLoadTable); 1215 1216 1217 /* 1218 * Note: Now table is "INSTALLED", it must be validated before 1219 * using. 1220 */ 1221 Status = AcpiGetTableByIndex (TableIndex, &Table); 1222 if (ACPI_FAILURE (Status)) 1223 { 1224 return_ACPI_STATUS (Status); 1225 } 1226 1227 Status = AcpiNsLoadTable (TableIndex, ParentNode); 1228 if (ACPI_FAILURE (Status)) 1229 { 1230 return_ACPI_STATUS (Status); 1231 } 1232 1233 /* 1234 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is 1235 * responsible for discovering any new wake GPEs by running _PRW methods 1236 * that may have been loaded by this table. 1237 */ 1238 Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); 1239 if (ACPI_SUCCESS (Status)) 1240 { 1241 AcpiEvUpdateGpes (OwnerId); 1242 } 1243 1244 /* Invoke table handler */ 1245 1246 AcpiTbNotifyTable (ACPI_TABLE_EVENT_LOAD, Table); 1247 return_ACPI_STATUS (Status); 1248 } 1249 1250 1251 /******************************************************************************* 1252 * 1253 * FUNCTION: AcpiTbInstallAndLoadTable 1254 * 1255 * PARAMETERS: Address - Physical address of the table 1256 * Flags - Allocation flags of the table 1257 * Table - Pointer to the table (required for 1258 * virtual origins, optional for 1259 * physical) 1260 * Override - Whether override should be performed 1261 * TableIndex - Where table index is returned 1262 * 1263 * RETURN: Status 1264 * 1265 * DESCRIPTION: Install and load an ACPI table 1266 * 1267 ******************************************************************************/ 1268 1269 ACPI_STATUS 1270 AcpiTbInstallAndLoadTable ( 1271 ACPI_PHYSICAL_ADDRESS Address, 1272 UINT8 Flags, 1273 ACPI_TABLE_HEADER *Table, 1274 BOOLEAN Override, 1275 UINT32 *TableIndex) 1276 { 1277 ACPI_STATUS Status; 1278 UINT32 i; 1279 1280 1281 ACPI_FUNCTION_TRACE (TbInstallAndLoadTable); 1282 1283 1284 /* Install the table and load it into the namespace */ 1285 1286 Status = AcpiTbInstallStandardTable (Address, Flags, Table, TRUE, 1287 Override, &i); 1288 if (ACPI_FAILURE (Status)) 1289 { 1290 goto Exit; 1291 } 1292 1293 Status = AcpiTbLoadTable (i, AcpiGbl_RootNode); 1294 1295 Exit: 1296 *TableIndex = i; 1297 return_ACPI_STATUS (Status); 1298 } 1299 1300 1301 /******************************************************************************* 1302 * 1303 * FUNCTION: AcpiTbUnloadTable 1304 * 1305 * PARAMETERS: TableIndex - Table index 1306 * 1307 * RETURN: Status 1308 * 1309 * DESCRIPTION: Unload an ACPI table 1310 * 1311 ******************************************************************************/ 1312 1313 ACPI_STATUS 1314 AcpiTbUnloadTable ( 1315 UINT32 TableIndex) 1316 { 1317 ACPI_STATUS Status = AE_OK; 1318 ACPI_TABLE_HEADER *Table; 1319 1320 1321 ACPI_FUNCTION_TRACE (TbUnloadTable); 1322 1323 1324 /* Ensure the table is still loaded */ 1325 1326 if (!AcpiTbIsTableLoaded (TableIndex)) 1327 { 1328 return_ACPI_STATUS (AE_NOT_EXIST); 1329 } 1330 1331 /* Invoke table handler */ 1332 1333 Status = AcpiGetTableByIndex (TableIndex, &Table); 1334 if (ACPI_SUCCESS (Status)) 1335 { 1336 AcpiTbNotifyTable (ACPI_TABLE_EVENT_UNLOAD, Table); 1337 } 1338 1339 /* Delete the portion of the namespace owned by this table */ 1340 1341 Status = AcpiTbDeleteNamespaceByOwner (TableIndex); 1342 if (ACPI_FAILURE (Status)) 1343 { 1344 return_ACPI_STATUS (Status); 1345 } 1346 1347 (void) AcpiTbReleaseOwnerId (TableIndex); 1348 AcpiTbSetTableLoadedFlag (TableIndex, FALSE); 1349 return_ACPI_STATUS (Status); 1350 } 1351 1352 1353 /******************************************************************************* 1354 * 1355 * FUNCTION: AcpiTbNotifyTable 1356 * 1357 * PARAMETERS: Event - Table event 1358 * Table - Validated table pointer 1359 * 1360 * RETURN: None 1361 * 1362 * DESCRIPTION: Notify a table event to the users. 1363 * 1364 ******************************************************************************/ 1365 1366 void 1367 AcpiTbNotifyTable ( 1368 UINT32 Event, 1369 void *Table) 1370 { 1371 /* Invoke table handler if present */ 1372 1373 if (AcpiGbl_TableHandler) 1374 { 1375 (void) AcpiGbl_TableHandler (Event, Table, 1376 AcpiGbl_TableHandlerContext); 1377 } 1378 } 1379