1 /****************************************************************************** 2 * 3 * Module Name: tbdata - Table manager data structure functions 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 <contrib/dev/acpica/include/acpi.h> 45 #include <contrib/dev/acpica/include/accommon.h> 46 #include <contrib/dev/acpica/include/acnamesp.h> 47 #include <contrib/dev/acpica/include/actables.h> 48 #include <contrib/dev/acpica/include/acevents.h> 49 50 #define _COMPONENT ACPI_TABLES 51 ACPI_MODULE_NAME ("tbdata") 52 53 54 /******************************************************************************* 55 * 56 * FUNCTION: AcpiTbInitTableDescriptor 57 * 58 * PARAMETERS: TableDesc - Table descriptor 59 * Address - Physical address of the table 60 * Flags - Allocation flags of the table 61 * Table - Pointer to the table 62 * 63 * RETURN: None 64 * 65 * DESCRIPTION: Initialize a new table descriptor 66 * 67 ******************************************************************************/ 68 69 void 70 AcpiTbInitTableDescriptor ( 71 ACPI_TABLE_DESC *TableDesc, 72 ACPI_PHYSICAL_ADDRESS Address, 73 UINT8 Flags, 74 ACPI_TABLE_HEADER *Table) 75 { 76 77 /* 78 * Initialize the table descriptor. Set the pointer to NULL, since the 79 * table is not fully mapped at this time. 80 */ 81 memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC)); 82 TableDesc->Address = Address; 83 TableDesc->Length = Table->Length; 84 TableDesc->Flags = Flags; 85 ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); 86 } 87 88 89 /******************************************************************************* 90 * 91 * FUNCTION: AcpiTbAcquireTable 92 * 93 * PARAMETERS: TableDesc - Table descriptor 94 * TablePtr - Where table is returned 95 * TableLength - Where table length is returned 96 * TableFlags - Where table allocation flags are returned 97 * 98 * RETURN: Status 99 * 100 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not 101 * maintained in the AcpiGbl_RootTableList. 102 * 103 ******************************************************************************/ 104 105 ACPI_STATUS 106 AcpiTbAcquireTable ( 107 ACPI_TABLE_DESC *TableDesc, 108 ACPI_TABLE_HEADER **TablePtr, 109 UINT32 *TableLength, 110 UINT8 *TableFlags) 111 { 112 ACPI_TABLE_HEADER *Table = NULL; 113 114 115 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 116 { 117 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 118 119 Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length); 120 break; 121 122 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 123 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 124 125 Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 126 ACPI_PHYSADDR_TO_PTR (TableDesc->Address)); 127 break; 128 129 default: 130 131 break; 132 } 133 134 /* Table is not valid yet */ 135 136 if (!Table) 137 { 138 return (AE_NO_MEMORY); 139 } 140 141 /* Fill the return values */ 142 143 *TablePtr = Table; 144 *TableLength = TableDesc->Length; 145 *TableFlags = TableDesc->Flags; 146 return (AE_OK); 147 } 148 149 150 /******************************************************************************* 151 * 152 * FUNCTION: AcpiTbReleaseTable 153 * 154 * PARAMETERS: Table - Pointer for the table 155 * TableLength - Length for the table 156 * TableFlags - Allocation flags for the table 157 * 158 * RETURN: None 159 * 160 * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable(). 161 * 162 ******************************************************************************/ 163 164 void 165 AcpiTbReleaseTable ( 166 ACPI_TABLE_HEADER *Table, 167 UINT32 TableLength, 168 UINT8 TableFlags) 169 { 170 171 switch (TableFlags & ACPI_TABLE_ORIGIN_MASK) 172 { 173 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 174 175 AcpiOsUnmapMemory (Table, TableLength); 176 break; 177 178 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 179 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 180 default: 181 182 break; 183 } 184 } 185 186 187 /******************************************************************************* 188 * 189 * FUNCTION: AcpiTbAcquireTempTable 190 * 191 * PARAMETERS: TableDesc - Table descriptor to be acquired 192 * Address - Address of the table 193 * Flags - Allocation flags of the table 194 * 195 * RETURN: Status 196 * 197 * DESCRIPTION: This function validates the table header to obtain the length 198 * of a table and fills the table descriptor to make its state as 199 * "INSTALLED". Such a table descriptor is only used for verified 200 * installation. 201 * 202 ******************************************************************************/ 203 204 ACPI_STATUS 205 AcpiTbAcquireTempTable ( 206 ACPI_TABLE_DESC *TableDesc, 207 ACPI_PHYSICAL_ADDRESS Address, 208 UINT8 Flags) 209 { 210 ACPI_TABLE_HEADER *TableHeader; 211 212 213 switch (Flags & ACPI_TABLE_ORIGIN_MASK) 214 { 215 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 216 217 /* Get the length of the full table from the header */ 218 219 TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); 220 if (!TableHeader) 221 { 222 return (AE_NO_MEMORY); 223 } 224 225 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); 226 AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER)); 227 return (AE_OK); 228 229 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 230 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 231 232 TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 233 ACPI_PHYSADDR_TO_PTR (Address)); 234 if (!TableHeader) 235 { 236 return (AE_NO_MEMORY); 237 } 238 239 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); 240 return (AE_OK); 241 242 default: 243 244 break; 245 } 246 247 /* Table is not valid yet */ 248 249 return (AE_NO_MEMORY); 250 } 251 252 253 /******************************************************************************* 254 * 255 * FUNCTION: AcpiTbReleaseTempTable 256 * 257 * PARAMETERS: TableDesc - Table descriptor to be released 258 * 259 * RETURN: Status 260 * 261 * DESCRIPTION: The inverse of AcpiTbAcquireTempTable(). 262 * 263 *****************************************************************************/ 264 265 void 266 AcpiTbReleaseTempTable ( 267 ACPI_TABLE_DESC *TableDesc) 268 { 269 270 /* 271 * Note that the .Address is maintained by the callers of 272 * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable() 273 * where .Address will be freed. 274 */ 275 AcpiTbInvalidateTable (TableDesc); 276 } 277 278 279 /****************************************************************************** 280 * 281 * FUNCTION: AcpiTbValidateTable 282 * 283 * PARAMETERS: TableDesc - Table descriptor 284 * 285 * RETURN: Status 286 * 287 * DESCRIPTION: This function is called to validate the table, the returned 288 * table descriptor is in "VALIDATED" state. 289 * 290 *****************************************************************************/ 291 292 ACPI_STATUS 293 AcpiTbValidateTable ( 294 ACPI_TABLE_DESC *TableDesc) 295 { 296 ACPI_STATUS Status = AE_OK; 297 298 299 ACPI_FUNCTION_TRACE (TbValidateTable); 300 301 302 /* Validate the table if necessary */ 303 304 if (!TableDesc->Pointer) 305 { 306 Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer, 307 &TableDesc->Length, &TableDesc->Flags); 308 if (!TableDesc->Pointer) 309 { 310 Status = AE_NO_MEMORY; 311 } 312 } 313 314 return_ACPI_STATUS (Status); 315 } 316 317 318 /******************************************************************************* 319 * 320 * FUNCTION: AcpiTbInvalidateTable 321 * 322 * PARAMETERS: TableDesc - Table descriptor 323 * 324 * RETURN: None 325 * 326 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of 327 * AcpiTbValidateTable(). 328 * 329 ******************************************************************************/ 330 331 void 332 AcpiTbInvalidateTable ( 333 ACPI_TABLE_DESC *TableDesc) 334 { 335 336 ACPI_FUNCTION_TRACE (TbInvalidateTable); 337 338 339 /* Table must be validated */ 340 341 if (!TableDesc->Pointer) 342 { 343 return_VOID; 344 } 345 346 AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length, 347 TableDesc->Flags); 348 TableDesc->Pointer = NULL; 349 350 return_VOID; 351 } 352 353 354 /****************************************************************************** 355 * 356 * FUNCTION: AcpiTbValidateTempTable 357 * 358 * PARAMETERS: TableDesc - Table descriptor 359 * 360 * RETURN: Status 361 * 362 * DESCRIPTION: This function is called to validate the table, the returned 363 * table descriptor is in "VALIDATED" state. 364 * 365 *****************************************************************************/ 366 367 ACPI_STATUS 368 AcpiTbValidateTempTable ( 369 ACPI_TABLE_DESC *TableDesc) 370 { 371 372 if (!TableDesc->Pointer && !AcpiGbl_VerifyTableChecksum) 373 { 374 /* 375 * Only validates the header of the table. 376 * Note that Length contains the size of the mapping after invoking 377 * this work around, this value is required by 378 * AcpiTbReleaseTempTable(). 379 * We can do this because in AcpiInitTableDescriptor(), the Length 380 * field of the installed descriptor is filled with the actual 381 * table length obtaining from the table header. 382 */ 383 TableDesc->Length = sizeof (ACPI_TABLE_HEADER); 384 } 385 386 return (AcpiTbValidateTable (TableDesc)); 387 } 388 389 390 /****************************************************************************** 391 * 392 * FUNCTION: AcpiTbVerifyTempTable 393 * 394 * PARAMETERS: TableDesc - Table descriptor 395 * Signature - Table signature to verify 396 * 397 * RETURN: Status 398 * 399 * DESCRIPTION: This function is called to validate and verify the table, the 400 * returned table descriptor is in "VALIDATED" state. 401 * 402 *****************************************************************************/ 403 404 ACPI_STATUS 405 AcpiTbVerifyTempTable ( 406 ACPI_TABLE_DESC *TableDesc, 407 char *Signature) 408 { 409 ACPI_STATUS Status = AE_OK; 410 411 412 ACPI_FUNCTION_TRACE (TbVerifyTempTable); 413 414 415 /* Validate the table */ 416 417 Status = AcpiTbValidateTempTable (TableDesc); 418 if (ACPI_FAILURE (Status)) 419 { 420 return_ACPI_STATUS (AE_NO_MEMORY); 421 } 422 423 /* If a particular signature is expected (DSDT/FACS), it must match */ 424 425 if (Signature && 426 !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature)) 427 { 428 ACPI_BIOS_ERROR ((AE_INFO, 429 "Invalid signature 0x%X for ACPI table, expected [%s]", 430 TableDesc->Signature.Integer, Signature)); 431 Status = AE_BAD_SIGNATURE; 432 goto InvalidateAndExit; 433 } 434 435 /* Verify the checksum */ 436 437 if (AcpiGbl_VerifyTableChecksum) 438 { 439 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); 440 if (ACPI_FAILURE (Status)) 441 { 442 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, 443 "%4.4s 0x%8.8X%8.8X" 444 " Attempted table install failed", 445 AcpiUtValidNameseg (TableDesc->Signature.Ascii) ? 446 TableDesc->Signature.Ascii : "????", 447 ACPI_FORMAT_UINT64 (TableDesc->Address))); 448 449 goto InvalidateAndExit; 450 } 451 } 452 453 return_ACPI_STATUS (AE_OK); 454 455 InvalidateAndExit: 456 AcpiTbInvalidateTable (TableDesc); 457 return_ACPI_STATUS (Status); 458 } 459 460 461 /******************************************************************************* 462 * 463 * FUNCTION: AcpiTbResizeRootTableList 464 * 465 * PARAMETERS: None 466 * 467 * RETURN: Status 468 * 469 * DESCRIPTION: Expand the size of global table array 470 * 471 ******************************************************************************/ 472 473 ACPI_STATUS 474 AcpiTbResizeRootTableList ( 475 void) 476 { 477 ACPI_TABLE_DESC *Tables; 478 UINT32 TableCount; 479 480 481 ACPI_FUNCTION_TRACE (TbResizeRootTableList); 482 483 484 /* AllowResize flag is a parameter to AcpiInitializeTables */ 485 486 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 487 { 488 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 489 return_ACPI_STATUS (AE_SUPPORT); 490 } 491 492 /* Increase the Table Array size */ 493 494 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 495 { 496 TableCount = AcpiGbl_RootTableList.MaxTableCount; 497 } 498 else 499 { 500 TableCount = AcpiGbl_RootTableList.CurrentTableCount; 501 } 502 503 Tables = ACPI_ALLOCATE_ZEROED ( 504 ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) * 505 sizeof (ACPI_TABLE_DESC)); 506 if (!Tables) 507 { 508 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 509 return_ACPI_STATUS (AE_NO_MEMORY); 510 } 511 512 /* Copy and free the previous table array */ 513 514 if (AcpiGbl_RootTableList.Tables) 515 { 516 memcpy (Tables, AcpiGbl_RootTableList.Tables, 517 (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC)); 518 519 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 520 { 521 ACPI_FREE (AcpiGbl_RootTableList.Tables); 522 } 523 } 524 525 AcpiGbl_RootTableList.Tables = Tables; 526 AcpiGbl_RootTableList.MaxTableCount = 527 TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; 528 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 529 530 return_ACPI_STATUS (AE_OK); 531 } 532 533 534 /******************************************************************************* 535 * 536 * FUNCTION: AcpiTbGetNextTableDescriptor 537 * 538 * PARAMETERS: TableIndex - Where table index is returned 539 * TableDesc - Where table descriptor is returned 540 * 541 * RETURN: Status and table index/descriptor. 542 * 543 * DESCRIPTION: Allocate a new ACPI table entry to the global table list 544 * 545 ******************************************************************************/ 546 547 ACPI_STATUS 548 AcpiTbGetNextTableDescriptor ( 549 UINT32 *TableIndex, 550 ACPI_TABLE_DESC **TableDesc) 551 { 552 ACPI_STATUS Status; 553 UINT32 i; 554 555 556 /* Ensure that there is room for the table in the Root Table List */ 557 558 if (AcpiGbl_RootTableList.CurrentTableCount >= 559 AcpiGbl_RootTableList.MaxTableCount) 560 { 561 Status = AcpiTbResizeRootTableList(); 562 if (ACPI_FAILURE (Status)) 563 { 564 return (Status); 565 } 566 } 567 568 i = AcpiGbl_RootTableList.CurrentTableCount; 569 AcpiGbl_RootTableList.CurrentTableCount++; 570 571 if (TableIndex) 572 { 573 *TableIndex = i; 574 } 575 if (TableDesc) 576 { 577 *TableDesc = &AcpiGbl_RootTableList.Tables[i]; 578 } 579 580 return (AE_OK); 581 } 582 583 584 /******************************************************************************* 585 * 586 * FUNCTION: AcpiTbTerminate 587 * 588 * PARAMETERS: None 589 * 590 * RETURN: None 591 * 592 * DESCRIPTION: Delete all internal ACPI tables 593 * 594 ******************************************************************************/ 595 596 void 597 AcpiTbTerminate ( 598 void) 599 { 600 UINT32 i; 601 602 603 ACPI_FUNCTION_TRACE (TbTerminate); 604 605 606 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 607 608 /* Delete the individual tables */ 609 610 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 611 { 612 AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]); 613 } 614 615 /* 616 * Delete the root table array if allocated locally. Array cannot be 617 * mapped, so we don't need to check for that flag. 618 */ 619 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 620 { 621 ACPI_FREE (AcpiGbl_RootTableList.Tables); 622 } 623 624 AcpiGbl_RootTableList.Tables = NULL; 625 AcpiGbl_RootTableList.Flags = 0; 626 AcpiGbl_RootTableList.CurrentTableCount = 0; 627 628 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 629 630 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 631 return_VOID; 632 } 633 634 635 /******************************************************************************* 636 * 637 * FUNCTION: AcpiTbDeleteNamespaceByOwner 638 * 639 * PARAMETERS: TableIndex - Table index 640 * 641 * RETURN: Status 642 * 643 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 644 * 645 ******************************************************************************/ 646 647 ACPI_STATUS 648 AcpiTbDeleteNamespaceByOwner ( 649 UINT32 TableIndex) 650 { 651 ACPI_OWNER_ID OwnerId; 652 ACPI_STATUS Status; 653 654 655 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 656 657 658 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 659 if (ACPI_FAILURE (Status)) 660 { 661 return_ACPI_STATUS (Status); 662 } 663 664 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 665 { 666 /* The table index does not exist */ 667 668 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 669 return_ACPI_STATUS (AE_NOT_EXIST); 670 } 671 672 /* Get the owner ID for this table, used to delete namespace nodes */ 673 674 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 675 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 676 677 /* 678 * Need to acquire the namespace writer lock to prevent interference 679 * with any concurrent namespace walks. The interpreter must be 680 * released during the deletion since the acquisition of the deletion 681 * lock may block, and also since the execution of a namespace walk 682 * must be allowed to use the interpreter. 683 */ 684 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 685 if (ACPI_FAILURE (Status)) 686 { 687 return_ACPI_STATUS (Status); 688 } 689 AcpiNsDeleteNamespaceByOwner (OwnerId); 690 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 691 return_ACPI_STATUS (Status); 692 } 693 694 695 /******************************************************************************* 696 * 697 * FUNCTION: AcpiTbAllocateOwnerId 698 * 699 * PARAMETERS: TableIndex - Table index 700 * 701 * RETURN: Status 702 * 703 * DESCRIPTION: Allocates OwnerId in TableDesc 704 * 705 ******************************************************************************/ 706 707 ACPI_STATUS 708 AcpiTbAllocateOwnerId ( 709 UINT32 TableIndex) 710 { 711 ACPI_STATUS Status = AE_BAD_PARAMETER; 712 713 714 ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 715 716 717 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 718 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 719 { 720 Status = AcpiUtAllocateOwnerId ( 721 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 722 } 723 724 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 725 return_ACPI_STATUS (Status); 726 } 727 728 729 /******************************************************************************* 730 * 731 * FUNCTION: AcpiTbReleaseOwnerId 732 * 733 * PARAMETERS: TableIndex - Table index 734 * 735 * RETURN: Status 736 * 737 * DESCRIPTION: Releases OwnerId in TableDesc 738 * 739 ******************************************************************************/ 740 741 ACPI_STATUS 742 AcpiTbReleaseOwnerId ( 743 UINT32 TableIndex) 744 { 745 ACPI_STATUS Status = AE_BAD_PARAMETER; 746 747 748 ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 749 750 751 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 752 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 753 { 754 AcpiUtReleaseOwnerId ( 755 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 756 Status = AE_OK; 757 } 758 759 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 760 return_ACPI_STATUS (Status); 761 } 762 763 764 /******************************************************************************* 765 * 766 * FUNCTION: AcpiTbGetOwnerId 767 * 768 * PARAMETERS: TableIndex - Table index 769 * OwnerId - Where the table OwnerId is returned 770 * 771 * RETURN: Status 772 * 773 * DESCRIPTION: returns OwnerId for the ACPI table 774 * 775 ******************************************************************************/ 776 777 ACPI_STATUS 778 AcpiTbGetOwnerId ( 779 UINT32 TableIndex, 780 ACPI_OWNER_ID *OwnerId) 781 { 782 ACPI_STATUS Status = AE_BAD_PARAMETER; 783 784 785 ACPI_FUNCTION_TRACE (TbGetOwnerId); 786 787 788 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 789 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 790 { 791 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 792 Status = AE_OK; 793 } 794 795 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 796 return_ACPI_STATUS (Status); 797 } 798 799 800 /******************************************************************************* 801 * 802 * FUNCTION: AcpiTbIsTableLoaded 803 * 804 * PARAMETERS: TableIndex - Index into the root table 805 * 806 * RETURN: Table Loaded Flag 807 * 808 ******************************************************************************/ 809 810 BOOLEAN 811 AcpiTbIsTableLoaded ( 812 UINT32 TableIndex) 813 { 814 BOOLEAN IsLoaded = FALSE; 815 816 817 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 818 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 819 { 820 IsLoaded = (BOOLEAN) 821 (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 822 ACPI_TABLE_IS_LOADED); 823 } 824 825 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 826 return (IsLoaded); 827 } 828 829 830 /******************************************************************************* 831 * 832 * FUNCTION: AcpiTbSetTableLoadedFlag 833 * 834 * PARAMETERS: TableIndex - Table index 835 * IsLoaded - TRUE if table is loaded, FALSE otherwise 836 * 837 * RETURN: None 838 * 839 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 840 * 841 ******************************************************************************/ 842 843 void 844 AcpiTbSetTableLoadedFlag ( 845 UINT32 TableIndex, 846 BOOLEAN IsLoaded) 847 { 848 849 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 850 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 851 { 852 if (IsLoaded) 853 { 854 AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 855 ACPI_TABLE_IS_LOADED; 856 } 857 else 858 { 859 AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 860 ~ACPI_TABLE_IS_LOADED; 861 } 862 } 863 864 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 865 } 866 867 868 /******************************************************************************* 869 * 870 * FUNCTION: AcpiTbLoadTable 871 * 872 * PARAMETERS: TableIndex - Table index 873 * ParentNode - Where table index is returned 874 * 875 * RETURN: Status 876 * 877 * DESCRIPTION: Load an ACPI table 878 * 879 ******************************************************************************/ 880 881 ACPI_STATUS 882 AcpiTbLoadTable ( 883 UINT32 TableIndex, 884 ACPI_NAMESPACE_NODE *ParentNode) 885 { 886 ACPI_TABLE_HEADER *Table; 887 ACPI_STATUS Status; 888 ACPI_OWNER_ID OwnerId; 889 890 891 ACPI_FUNCTION_TRACE (TbLoadTable); 892 893 894 /* 895 * Note: Now table is "INSTALLED", it must be validated before 896 * using. 897 */ 898 Status = AcpiGetTableByIndex (TableIndex, &Table); 899 if (ACPI_FAILURE (Status)) 900 { 901 return_ACPI_STATUS (Status); 902 } 903 904 Status = AcpiNsLoadTable (TableIndex, ParentNode); 905 906 /* Execute any module-level code that was found in the table */ 907 908 if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode) 909 { 910 AcpiNsExecModuleCodeList (); 911 } 912 913 /* 914 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is 915 * responsible for discovering any new wake GPEs by running _PRW methods 916 * that may have been loaded by this table. 917 */ 918 Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); 919 if (ACPI_SUCCESS (Status)) 920 { 921 AcpiEvUpdateGpes (OwnerId); 922 } 923 924 /* Invoke table handler if present */ 925 926 if (AcpiGbl_TableHandler) 927 { 928 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, 929 AcpiGbl_TableHandlerContext); 930 } 931 932 return_ACPI_STATUS (Status); 933 } 934 935 936 /******************************************************************************* 937 * 938 * FUNCTION: AcpiTbInstallAndLoadTable 939 * 940 * PARAMETERS: Address - Physical address of the table 941 * Flags - Allocation flags of the table 942 * Override - Whether override should be performed 943 * TableIndex - Where table index is returned 944 * 945 * RETURN: Status 946 * 947 * DESCRIPTION: Install and load an ACPI table 948 * 949 ******************************************************************************/ 950 951 ACPI_STATUS 952 AcpiTbInstallAndLoadTable ( 953 ACPI_PHYSICAL_ADDRESS Address, 954 UINT8 Flags, 955 BOOLEAN Override, 956 UINT32 *TableIndex) 957 { 958 ACPI_STATUS Status; 959 UINT32 i; 960 961 962 ACPI_FUNCTION_TRACE (TbInstallAndLoadTable); 963 964 965 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 966 967 /* Install the table and load it into the namespace */ 968 969 Status = AcpiTbInstallStandardTable (Address, Flags, TRUE, 970 Override, &i); 971 if (ACPI_FAILURE (Status)) 972 { 973 goto UnlockAndExit; 974 } 975 976 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 977 Status = AcpiTbLoadTable (i, AcpiGbl_RootNode); 978 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 979 980 UnlockAndExit: 981 *TableIndex = i; 982 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 983 return_ACPI_STATUS (Status); 984 } 985 986 987 /******************************************************************************* 988 * 989 * FUNCTION: AcpiTbUnloadTable 990 * 991 * PARAMETERS: TableIndex - Table index 992 * 993 * RETURN: Status 994 * 995 * DESCRIPTION: Unload an ACPI table 996 * 997 ******************************************************************************/ 998 999 ACPI_STATUS 1000 AcpiTbUnloadTable ( 1001 UINT32 TableIndex) 1002 { 1003 ACPI_STATUS Status = AE_OK; 1004 ACPI_TABLE_HEADER *Table; 1005 1006 1007 ACPI_FUNCTION_TRACE (TbUnloadTable); 1008 1009 1010 /* Ensure the table is still loaded */ 1011 1012 if (!AcpiTbIsTableLoaded (TableIndex)) 1013 { 1014 return_ACPI_STATUS (AE_NOT_EXIST); 1015 } 1016 1017 /* Invoke table handler if present */ 1018 1019 if (AcpiGbl_TableHandler) 1020 { 1021 Status = AcpiGetTableByIndex (TableIndex, &Table); 1022 if (ACPI_SUCCESS (Status)) 1023 { 1024 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table, 1025 AcpiGbl_TableHandlerContext); 1026 } 1027 } 1028 1029 /* Delete the portion of the namespace owned by this table */ 1030 1031 Status = AcpiTbDeleteNamespaceByOwner (TableIndex); 1032 if (ACPI_FAILURE (Status)) 1033 { 1034 return_ACPI_STATUS (Status); 1035 } 1036 1037 (void) AcpiTbReleaseOwnerId (TableIndex); 1038 AcpiTbSetTableLoadedFlag (TableIndex, FALSE); 1039 return_ACPI_STATUS (Status); 1040 } 1041