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 "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 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 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 685 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 686 687 AcpiNsDeleteNamespaceByOwner (OwnerId); 688 if (ACPI_FAILURE (Status)) 689 { 690 return_ACPI_STATUS (Status); 691 } 692 693 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 694 695 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 696 return_ACPI_STATUS (Status); 697 } 698 699 700 /******************************************************************************* 701 * 702 * FUNCTION: AcpiTbAllocateOwnerId 703 * 704 * PARAMETERS: TableIndex - Table index 705 * 706 * RETURN: Status 707 * 708 * DESCRIPTION: Allocates OwnerId in TableDesc 709 * 710 ******************************************************************************/ 711 712 ACPI_STATUS 713 AcpiTbAllocateOwnerId ( 714 UINT32 TableIndex) 715 { 716 ACPI_STATUS Status = AE_BAD_PARAMETER; 717 718 719 ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 720 721 722 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 723 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 724 { 725 Status = AcpiUtAllocateOwnerId ( 726 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 727 } 728 729 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 730 return_ACPI_STATUS (Status); 731 } 732 733 734 /******************************************************************************* 735 * 736 * FUNCTION: AcpiTbReleaseOwnerId 737 * 738 * PARAMETERS: TableIndex - Table index 739 * 740 * RETURN: Status 741 * 742 * DESCRIPTION: Releases OwnerId in TableDesc 743 * 744 ******************************************************************************/ 745 746 ACPI_STATUS 747 AcpiTbReleaseOwnerId ( 748 UINT32 TableIndex) 749 { 750 ACPI_STATUS Status = AE_BAD_PARAMETER; 751 752 753 ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 754 755 756 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 757 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 758 { 759 AcpiUtReleaseOwnerId ( 760 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 761 Status = AE_OK; 762 } 763 764 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 765 return_ACPI_STATUS (Status); 766 } 767 768 769 /******************************************************************************* 770 * 771 * FUNCTION: AcpiTbGetOwnerId 772 * 773 * PARAMETERS: TableIndex - Table index 774 * OwnerId - Where the table OwnerId is returned 775 * 776 * RETURN: Status 777 * 778 * DESCRIPTION: returns OwnerId for the ACPI table 779 * 780 ******************************************************************************/ 781 782 ACPI_STATUS 783 AcpiTbGetOwnerId ( 784 UINT32 TableIndex, 785 ACPI_OWNER_ID *OwnerId) 786 { 787 ACPI_STATUS Status = AE_BAD_PARAMETER; 788 789 790 ACPI_FUNCTION_TRACE (TbGetOwnerId); 791 792 793 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 794 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 795 { 796 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 797 Status = AE_OK; 798 } 799 800 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 801 return_ACPI_STATUS (Status); 802 } 803 804 805 /******************************************************************************* 806 * 807 * FUNCTION: AcpiTbIsTableLoaded 808 * 809 * PARAMETERS: TableIndex - Index into the root table 810 * 811 * RETURN: Table Loaded Flag 812 * 813 ******************************************************************************/ 814 815 BOOLEAN 816 AcpiTbIsTableLoaded ( 817 UINT32 TableIndex) 818 { 819 BOOLEAN IsLoaded = FALSE; 820 821 822 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 823 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 824 { 825 IsLoaded = (BOOLEAN) 826 (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 827 ACPI_TABLE_IS_LOADED); 828 } 829 830 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 831 return (IsLoaded); 832 } 833 834 835 /******************************************************************************* 836 * 837 * FUNCTION: AcpiTbSetTableLoadedFlag 838 * 839 * PARAMETERS: TableIndex - Table index 840 * IsLoaded - TRUE if table is loaded, FALSE otherwise 841 * 842 * RETURN: None 843 * 844 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 845 * 846 ******************************************************************************/ 847 848 void 849 AcpiTbSetTableLoadedFlag ( 850 UINT32 TableIndex, 851 BOOLEAN IsLoaded) 852 { 853 854 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 855 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 856 { 857 if (IsLoaded) 858 { 859 AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 860 ACPI_TABLE_IS_LOADED; 861 } 862 else 863 { 864 AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 865 ~ACPI_TABLE_IS_LOADED; 866 } 867 } 868 869 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 870 } 871 872 873 /******************************************************************************* 874 * 875 * FUNCTION: AcpiTbLoadTable 876 * 877 * PARAMETERS: TableIndex - Table index 878 * ParentNode - Where table index is returned 879 * 880 * RETURN: Status 881 * 882 * DESCRIPTION: Load an ACPI table 883 * 884 ******************************************************************************/ 885 886 ACPI_STATUS 887 AcpiTbLoadTable ( 888 UINT32 TableIndex, 889 ACPI_NAMESPACE_NODE *ParentNode) 890 { 891 ACPI_TABLE_HEADER *Table; 892 ACPI_STATUS Status; 893 ACPI_OWNER_ID OwnerId; 894 895 896 ACPI_FUNCTION_TRACE (TbLoadTable); 897 898 899 /* 900 * Note: Now table is "INSTALLED", it must be validated before 901 * using. 902 */ 903 Status = AcpiGetTableByIndex (TableIndex, &Table); 904 if (ACPI_FAILURE (Status)) 905 { 906 return_ACPI_STATUS (Status); 907 } 908 909 Status = AcpiNsLoadTable (TableIndex, ParentNode); 910 911 /* Execute any module-level code that was found in the table */ 912 913 if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode) 914 { 915 AcpiNsExecModuleCodeList (); 916 } 917 918 /* 919 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is 920 * responsible for discovering any new wake GPEs by running _PRW methods 921 * that may have been loaded by this table. 922 */ 923 Status = AcpiTbGetOwnerId (TableIndex, &OwnerId); 924 if (ACPI_SUCCESS (Status)) 925 { 926 AcpiEvUpdateGpes (OwnerId); 927 } 928 929 /* Invoke table handler if present */ 930 931 if (AcpiGbl_TableHandler) 932 { 933 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, 934 AcpiGbl_TableHandlerContext); 935 } 936 937 return_ACPI_STATUS (Status); 938 } 939 940 941 /******************************************************************************* 942 * 943 * FUNCTION: AcpiTbInstallAndLoadTable 944 * 945 * PARAMETERS: Table - Pointer to the table 946 * Address - Physical address of the table 947 * Flags - Allocation flags of the table 948 * TableIndex - Where table index is returned 949 * 950 * RETURN: Status 951 * 952 * DESCRIPTION: Install and load an ACPI table 953 * 954 ******************************************************************************/ 955 956 ACPI_STATUS 957 AcpiTbInstallAndLoadTable ( 958 ACPI_TABLE_HEADER *Table, 959 ACPI_PHYSICAL_ADDRESS Address, 960 UINT8 Flags, 961 BOOLEAN Override, 962 UINT32 *TableIndex) 963 { 964 ACPI_STATUS Status; 965 UINT32 i; 966 ACPI_OWNER_ID OwnerId; 967 968 969 ACPI_FUNCTION_TRACE (AcpiLoadTable); 970 971 972 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 973 974 /* Install the table and load it into the namespace */ 975 976 Status = AcpiTbInstallStandardTable (Address, Flags, TRUE, 977 Override, &i); 978 if (ACPI_FAILURE (Status)) 979 { 980 goto UnlockAndExit; 981 } 982 983 /* 984 * Note: Now table is "INSTALLED", it must be validated before 985 * using. 986 */ 987 Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); 988 if (ACPI_FAILURE (Status)) 989 { 990 goto UnlockAndExit; 991 } 992 993 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 994 Status = AcpiNsLoadTable (i, AcpiGbl_RootNode); 995 996 /* Execute any module-level code that was found in the table */ 997 998 if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode) 999 { 1000 AcpiNsExecModuleCodeList (); 1001 } 1002 1003 /* 1004 * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is 1005 * responsible for discovering any new wake GPEs by running _PRW methods 1006 * that may have been loaded by this table. 1007 */ 1008 Status = AcpiTbGetOwnerId (i, &OwnerId); 1009 if (ACPI_SUCCESS (Status)) 1010 { 1011 AcpiEvUpdateGpes (OwnerId); 1012 } 1013 1014 /* Invoke table handler if present */ 1015 1016 if (AcpiGbl_TableHandler) 1017 { 1018 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, 1019 AcpiGbl_TableHandlerContext); 1020 } 1021 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 1022 1023 UnlockAndExit: 1024 *TableIndex = i; 1025 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 1026 return_ACPI_STATUS (Status); 1027 } 1028