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