1 /******************************************************************************
   2  *
   3  * Module Name: tbinstal - ACPI table installation and removal
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, 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 
  45 #define __TBINSTAL_C__
  46 
  47 #include "acpi.h"
  48 #include "accommon.h"
  49 #include "acnamesp.h"
  50 #include "actables.h"
  51 
  52 
  53 #define _COMPONENT          ACPI_TABLES
  54         ACPI_MODULE_NAME    ("tbinstal")
  55 
  56 
  57 /******************************************************************************
  58  *
  59  * FUNCTION:    AcpiTbVerifyTable
  60  *
  61  * PARAMETERS:  TableDesc           - table
  62  *
  63  * RETURN:      Status
  64  *
  65  * DESCRIPTION: this function is called to verify and map table
  66  *
  67  *****************************************************************************/
  68 
  69 ACPI_STATUS
  70 AcpiTbVerifyTable (
  71     ACPI_TABLE_DESC         *TableDesc)
  72 {
  73     ACPI_STATUS             Status = AE_OK;
  74 
  75 
  76     ACPI_FUNCTION_TRACE (TbVerifyTable);
  77 
  78 
  79     /* Map the table if necessary */
  80 
  81     if (!TableDesc->Pointer)
  82     {
  83         if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
  84             ACPI_TABLE_ORIGIN_MAPPED)
  85         {
  86             TableDesc->Pointer = AcpiOsMapMemory (
  87                 TableDesc->Address, TableDesc->Length);
  88         }
  89 
  90         if (!TableDesc->Pointer)
  91         {
  92             return_ACPI_STATUS (AE_NO_MEMORY);
  93         }
  94     }
  95 
  96     /* Always calculate checksum, ignore bad checksum if requested */
  97 
  98     Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
  99 
 100     return_ACPI_STATUS (Status);
 101 }
 102 
 103 
 104 /*******************************************************************************
 105  *
 106  * FUNCTION:    AcpiTbAddTable
 107  *
 108  * PARAMETERS:  TableDesc           - Table descriptor
 109  *              TableIndex          - Where the table index is returned
 110  *
 111  * RETURN:      Status
 112  *
 113  * DESCRIPTION: This function is called to add an ACPI table. It is used to
 114  *              dynamically load tables via the Load and LoadTable AML
 115  *              operators.
 116  *
 117  ******************************************************************************/
 118 
 119 ACPI_STATUS
 120 AcpiTbAddTable (
 121     ACPI_TABLE_DESC         *TableDesc,
 122     UINT32                  *TableIndex)
 123 {
 124     UINT32                  i;
 125     ACPI_STATUS             Status = AE_OK;
 126 
 127 
 128     ACPI_FUNCTION_TRACE (TbAddTable);
 129 
 130 
 131     if (!TableDesc->Pointer)
 132     {
 133         Status = AcpiTbVerifyTable (TableDesc);
 134         if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
 135         {
 136             return_ACPI_STATUS (Status);
 137         }
 138     }
 139 
 140     /*
 141      * Validate the incoming table signature.
 142      *
 143      * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
 144      * 2) We added support for OEMx tables, signature "OEM".
 145      * 3) Valid tables were encountered with a null signature, so we just
 146      *    gave up on validating the signature, (05/2008).
 147      * 4) We encountered non-AML tables such as the MADT, which caused
 148      *    interpreter errors and kernel faults. So now, we once again allow
 149      *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
 150      */
 151     if ((TableDesc->Pointer->Signature[0] != 0x00) &&
 152        (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
 153        (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
 154     {
 155         ACPI_BIOS_ERROR ((AE_INFO,
 156             "Table has invalid signature [%4.4s] (0x%8.8X), "
 157             "must be SSDT or OEMx",
 158             AcpiUtValidAcpiName (TableDesc->Pointer->Signature) ?
 159                 TableDesc->Pointer->Signature : "????",
 160             *(UINT32 *) TableDesc->Pointer->Signature));
 161 
 162         return_ACPI_STATUS (AE_BAD_SIGNATURE);
 163     }
 164 
 165     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 166 
 167     /* Check if table is already registered */
 168 
 169     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
 170     {
 171         if (!AcpiGbl_RootTableList.Tables[i].Pointer)
 172         {
 173             Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
 174             if (ACPI_FAILURE (Status) ||
 175                 !AcpiGbl_RootTableList.Tables[i].Pointer)
 176             {
 177                 continue;
 178             }
 179         }
 180 
 181         /*
 182          * Check for a table match on the entire table length,
 183          * not just the header.
 184          */
 185         if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
 186         {
 187             continue;
 188         }
 189 
 190         if (ACPI_MEMCMP (TableDesc->Pointer,
 191                 AcpiGbl_RootTableList.Tables[i].Pointer,
 192                 AcpiGbl_RootTableList.Tables[i].Length))
 193         {
 194             continue;
 195         }
 196 
 197         /*
 198          * Note: the current mechanism does not unregister a table if it is
 199          * dynamically unloaded. The related namespace entries are deleted,
 200          * but the table remains in the root table list.
 201          *
 202          * The assumption here is that the number of different tables that
 203          * will be loaded is actually small, and there is minimal overhead
 204          * in just keeping the table in case it is needed again.
 205          *
 206          * If this assumption changes in the future (perhaps on large
 207          * machines with many table load/unload operations), tables will
 208          * need to be unregistered when they are unloaded, and slots in the
 209          * root table list should be reused when empty.
 210          */
 211 
 212         /*
 213          * Table is already registered.
 214          * We can delete the table that was passed as a parameter.
 215          */
 216         AcpiTbDeleteTable (TableDesc);
 217         *TableIndex = i;
 218 
 219         if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
 220         {
 221             /* Table is still loaded, this is an error */
 222 
 223             Status = AE_ALREADY_EXISTS;
 224             goto Release;
 225         }
 226         else
 227         {
 228             /* Table was unloaded, allow it to be reloaded */
 229 
 230             TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
 231             TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
 232             Status = AE_OK;
 233             goto PrintHeader;
 234         }
 235     }
 236 
 237     /*
 238      * ACPI Table Override:
 239      * Allow the host to override dynamically loaded tables.
 240      * NOTE: the table is fully mapped at this point, and the mapping will
 241      * be deleted by TbTableOverride if the table is actually overridden.
 242      */
 243     (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc);
 244 
 245     /* Add the table to the global root table list */
 246 
 247     Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
 248                 TableDesc->Length, TableDesc->Flags, TableIndex);
 249     if (ACPI_FAILURE (Status))
 250     {
 251         goto Release;
 252     }
 253 
 254 PrintHeader:
 255     AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
 256 
 257 Release:
 258     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 259     return_ACPI_STATUS (Status);
 260 }
 261 
 262 
 263 /*******************************************************************************
 264  *
 265  * FUNCTION:    AcpiTbTableOverride
 266  *
 267  * PARAMETERS:  TableHeader         - Header for the original table
 268  *              TableDesc           - Table descriptor initialized for the
 269  *                                    original table. May or may not be mapped.
 270  *
 271  * RETURN:      Pointer to the entire new table. NULL if table not overridden.
 272  *              If overridden, installs the new table within the input table
 273  *              descriptor.
 274  *
 275  * DESCRIPTION: Attempt table override by calling the OSL override functions.
 276  *              Note: If the table is overridden, then the entire new table
 277  *              is mapped and returned by this function.
 278  *
 279  ******************************************************************************/
 280 
 281 ACPI_TABLE_HEADER *
 282 AcpiTbTableOverride (
 283     ACPI_TABLE_HEADER       *TableHeader,
 284     ACPI_TABLE_DESC         *TableDesc)
 285 {
 286     ACPI_STATUS             Status;
 287     ACPI_TABLE_HEADER       *NewTable = NULL;
 288     ACPI_PHYSICAL_ADDRESS   NewAddress = 0;
 289     UINT32                  NewTableLength = 0;
 290     UINT8                   NewFlags;
 291     char                    *OverrideType;
 292 
 293 
 294     /* (1) Attempt logical override (returns a logical address) */
 295 
 296     Status = AcpiOsTableOverride (TableHeader, &NewTable);
 297     if (ACPI_SUCCESS (Status) && NewTable)
 298     {
 299         NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
 300         NewTableLength = NewTable->Length;
 301         NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
 302         OverrideType = "Logical";
 303         goto FinishOverride;
 304     }
 305 
 306     /* (2) Attempt physical override (returns a physical address) */
 307 
 308     Status = AcpiOsPhysicalTableOverride (TableHeader,
 309         &NewAddress, &NewTableLength);
 310     if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
 311     {
 312         /* Map the entire new table */
 313 
 314         NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
 315         if (!NewTable)
 316         {
 317             ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
 318                 "%4.4s " ACPI_PRINTF_UINT
 319                 " Attempted physical table override failed",
 320                 TableHeader->Signature,
 321                 ACPI_FORMAT_TO_UINT (TableDesc->Address)));
 322             return (NULL);
 323         }
 324 
 325         OverrideType = "Physical";
 326         NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
 327         goto FinishOverride;
 328     }
 329 
 330     return (NULL); /* There was no override */
 331 
 332 
 333 FinishOverride:
 334 
 335     ACPI_INFO ((AE_INFO, "%4.4s " ACPI_PRINTF_UINT
 336         " %s table override, new table: " ACPI_PRINTF_UINT,
 337         TableHeader->Signature,
 338         ACPI_FORMAT_TO_UINT (TableDesc->Address),
 339         OverrideType, ACPI_FORMAT_TO_UINT (NewTable)));
 340 
 341     /* We can now unmap/delete the original table (if fully mapped) */
 342 
 343     AcpiTbDeleteTable (TableDesc);
 344 
 345     /* Setup descriptor for the new table */
 346 
 347     TableDesc->Address = NewAddress;
 348     TableDesc->Pointer = NewTable;
 349     TableDesc->Length = NewTableLength;
 350     TableDesc->Flags = NewFlags;
 351 
 352     return (NewTable);
 353 }
 354 
 355 
 356 /*******************************************************************************
 357  *
 358  * FUNCTION:    AcpiTbResizeRootTableList
 359  *
 360  * PARAMETERS:  None
 361  *
 362  * RETURN:      Status
 363  *
 364  * DESCRIPTION: Expand the size of global table array
 365  *
 366  ******************************************************************************/
 367 
 368 ACPI_STATUS
 369 AcpiTbResizeRootTableList (
 370     void)
 371 {
 372     ACPI_TABLE_DESC         *Tables;
 373     UINT32                  TableCount;
 374 
 375 
 376     ACPI_FUNCTION_TRACE (TbResizeRootTableList);
 377 
 378 
 379     /* AllowResize flag is a parameter to AcpiInitializeTables */
 380 
 381     if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
 382     {
 383         ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
 384         return_ACPI_STATUS (AE_SUPPORT);
 385     }
 386 
 387     /* Increase the Table Array size */
 388 
 389     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
 390     {
 391         TableCount = AcpiGbl_RootTableList.MaxTableCount;
 392     }
 393     else
 394     {
 395         TableCount = AcpiGbl_RootTableList.CurrentTableCount;
 396     }
 397 
 398     Tables = ACPI_ALLOCATE_ZEROED (
 399         ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
 400         sizeof (ACPI_TABLE_DESC));
 401     if (!Tables)
 402     {
 403         ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
 404         return_ACPI_STATUS (AE_NO_MEMORY);
 405     }
 406 
 407     /* Copy and free the previous table array */
 408 
 409     if (AcpiGbl_RootTableList.Tables)
 410     {
 411         ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
 412             (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
 413 
 414         if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
 415         {
 416             ACPI_FREE (AcpiGbl_RootTableList.Tables);
 417         }
 418     }
 419 
 420     AcpiGbl_RootTableList.Tables = Tables;
 421     AcpiGbl_RootTableList.MaxTableCount =
 422         TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
 423     AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
 424 
 425     return_ACPI_STATUS (AE_OK);
 426 }
 427 
 428 
 429 /*******************************************************************************
 430  *
 431  * FUNCTION:    AcpiTbStoreTable
 432  *
 433  * PARAMETERS:  Address             - Table address
 434  *              Table               - Table header
 435  *              Length              - Table length
 436  *              Flags               - flags
 437  *
 438  * RETURN:      Status and table index.
 439  *
 440  * DESCRIPTION: Add an ACPI table to the global table list
 441  *
 442  ******************************************************************************/
 443 
 444 ACPI_STATUS
 445 AcpiTbStoreTable (
 446     ACPI_PHYSICAL_ADDRESS   Address,
 447     ACPI_TABLE_HEADER       *Table,
 448     UINT32                  Length,
 449     UINT8                   Flags,
 450     UINT32                  *TableIndex)
 451 {
 452     ACPI_STATUS             Status;
 453     ACPI_TABLE_DESC         *NewTable;
 454 
 455 
 456     /* Ensure that there is room for the table in the Root Table List */
 457 
 458     if (AcpiGbl_RootTableList.CurrentTableCount >=
 459         AcpiGbl_RootTableList.MaxTableCount)
 460     {
 461         Status = AcpiTbResizeRootTableList();
 462         if (ACPI_FAILURE (Status))
 463         {
 464             return (Status);
 465         }
 466     }
 467 
 468     NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
 469 
 470     /* Initialize added table */
 471 
 472     NewTable->Address = Address;
 473     NewTable->Pointer = Table;
 474     NewTable->Length = Length;
 475     NewTable->OwnerId = 0;
 476     NewTable->Flags = Flags;
 477 
 478     ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
 479 
 480     *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
 481     AcpiGbl_RootTableList.CurrentTableCount++;
 482     return (AE_OK);
 483 }
 484 
 485 
 486 /*******************************************************************************
 487  *
 488  * FUNCTION:    AcpiTbDeleteTable
 489  *
 490  * PARAMETERS:  TableIndex          - Table index
 491  *
 492  * RETURN:      None
 493  *
 494  * DESCRIPTION: Delete one internal ACPI table
 495  *
 496  ******************************************************************************/
 497 
 498 void
 499 AcpiTbDeleteTable (
 500     ACPI_TABLE_DESC         *TableDesc)
 501 {
 502 
 503     /* Table must be mapped or allocated */
 504 
 505     if (!TableDesc->Pointer)
 506     {
 507         return;
 508     }
 509 
 510     switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
 511     {
 512     case ACPI_TABLE_ORIGIN_MAPPED:
 513 
 514         AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
 515         break;
 516 
 517     case ACPI_TABLE_ORIGIN_ALLOCATED:
 518 
 519         ACPI_FREE (TableDesc->Pointer);
 520         break;
 521 
 522     /* Not mapped or allocated, there is nothing we can do */
 523 
 524     default:
 525 
 526         return;
 527     }
 528 
 529     TableDesc->Pointer = NULL;
 530 }
 531 
 532 
 533 /*******************************************************************************
 534  *
 535  * FUNCTION:    AcpiTbTerminate
 536  *
 537  * PARAMETERS:  None
 538  *
 539  * RETURN:      None
 540  *
 541  * DESCRIPTION: Delete all internal ACPI tables
 542  *
 543  ******************************************************************************/
 544 
 545 void
 546 AcpiTbTerminate (
 547     void)
 548 {
 549     UINT32                  i;
 550 
 551 
 552     ACPI_FUNCTION_TRACE (TbTerminate);
 553 
 554 
 555     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 556 
 557     /* Delete the individual tables */
 558 
 559     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
 560     {
 561         AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
 562     }
 563 
 564     /*
 565      * Delete the root table array if allocated locally. Array cannot be
 566      * mapped, so we don't need to check for that flag.
 567      */
 568     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
 569     {
 570         ACPI_FREE (AcpiGbl_RootTableList.Tables);
 571     }
 572 
 573     AcpiGbl_RootTableList.Tables = NULL;
 574     AcpiGbl_RootTableList.Flags = 0;
 575     AcpiGbl_RootTableList.CurrentTableCount = 0;
 576 
 577     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
 578     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 579 
 580     return_VOID;
 581 }
 582 
 583 
 584 /*******************************************************************************
 585  *
 586  * FUNCTION:    AcpiTbDeleteNamespaceByOwner
 587  *
 588  * PARAMETERS:  TableIndex          - Table index
 589  *
 590  * RETURN:      Status
 591  *
 592  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
 593  *
 594  ******************************************************************************/
 595 
 596 ACPI_STATUS
 597 AcpiTbDeleteNamespaceByOwner (
 598     UINT32                  TableIndex)
 599 {
 600     ACPI_OWNER_ID           OwnerId;
 601     ACPI_STATUS             Status;
 602 
 603 
 604     ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
 605 
 606 
 607     Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 608     if (ACPI_FAILURE (Status))
 609     {
 610         return_ACPI_STATUS (Status);
 611     }
 612 
 613     if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
 614     {
 615         /* The table index does not exist */
 616 
 617         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 618         return_ACPI_STATUS (AE_NOT_EXIST);
 619     }
 620 
 621     /* Get the owner ID for this table, used to delete namespace nodes */
 622 
 623     OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
 624     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 625 
 626     /*
 627      * Need to acquire the namespace writer lock to prevent interference
 628      * with any concurrent namespace walks. The interpreter must be
 629      * released during the deletion since the acquisition of the deletion
 630      * lock may block, and also since the execution of a namespace walk
 631      * must be allowed to use the interpreter.
 632      */
 633     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
 634     Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
 635 
 636     AcpiNsDeleteNamespaceByOwner (OwnerId);
 637     if (ACPI_FAILURE (Status))
 638     {
 639         return_ACPI_STATUS (Status);
 640     }
 641 
 642     AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
 643 
 644     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
 645     return_ACPI_STATUS (Status);
 646 }
 647 
 648 
 649 /*******************************************************************************
 650  *
 651  * FUNCTION:    AcpiTbAllocateOwnerId
 652  *
 653  * PARAMETERS:  TableIndex          - Table index
 654  *
 655  * RETURN:      Status
 656  *
 657  * DESCRIPTION: Allocates OwnerId in TableDesc
 658  *
 659  ******************************************************************************/
 660 
 661 ACPI_STATUS
 662 AcpiTbAllocateOwnerId (
 663     UINT32                  TableIndex)
 664 {
 665     ACPI_STATUS             Status = AE_BAD_PARAMETER;
 666 
 667 
 668     ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
 669 
 670 
 671     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 672     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
 673     {
 674         Status = AcpiUtAllocateOwnerId
 675                     (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
 676     }
 677 
 678     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 679     return_ACPI_STATUS (Status);
 680 }
 681 
 682 
 683 /*******************************************************************************
 684  *
 685  * FUNCTION:    AcpiTbReleaseOwnerId
 686  *
 687  * PARAMETERS:  TableIndex          - Table index
 688  *
 689  * RETURN:      Status
 690  *
 691  * DESCRIPTION: Releases OwnerId in TableDesc
 692  *
 693  ******************************************************************************/
 694 
 695 ACPI_STATUS
 696 AcpiTbReleaseOwnerId (
 697     UINT32                  TableIndex)
 698 {
 699     ACPI_STATUS             Status = AE_BAD_PARAMETER;
 700 
 701 
 702     ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
 703 
 704 
 705     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 706     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
 707     {
 708         AcpiUtReleaseOwnerId (
 709             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
 710         Status = AE_OK;
 711     }
 712 
 713     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 714     return_ACPI_STATUS (Status);
 715 }
 716 
 717 
 718 /*******************************************************************************
 719  *
 720  * FUNCTION:    AcpiTbGetOwnerId
 721  *
 722  * PARAMETERS:  TableIndex          - Table index
 723  *              OwnerId             - Where the table OwnerId is returned
 724  *
 725  * RETURN:      Status
 726  *
 727  * DESCRIPTION: returns OwnerId for the ACPI table
 728  *
 729  ******************************************************************************/
 730 
 731 ACPI_STATUS
 732 AcpiTbGetOwnerId (
 733     UINT32                  TableIndex,
 734     ACPI_OWNER_ID           *OwnerId)
 735 {
 736     ACPI_STATUS             Status = AE_BAD_PARAMETER;
 737 
 738 
 739     ACPI_FUNCTION_TRACE (TbGetOwnerId);
 740 
 741 
 742     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 743     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
 744     {
 745         *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
 746         Status = AE_OK;
 747     }
 748 
 749     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 750     return_ACPI_STATUS (Status);
 751 }
 752 
 753 
 754 /*******************************************************************************
 755  *
 756  * FUNCTION:    AcpiTbIsTableLoaded
 757  *
 758  * PARAMETERS:  TableIndex          - Table index
 759  *
 760  * RETURN:      Table Loaded Flag
 761  *
 762  ******************************************************************************/
 763 
 764 BOOLEAN
 765 AcpiTbIsTableLoaded (
 766     UINT32                  TableIndex)
 767 {
 768     BOOLEAN                 IsLoaded = FALSE;
 769 
 770 
 771     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 772     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
 773     {
 774         IsLoaded = (BOOLEAN)
 775             (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
 776             ACPI_TABLE_IS_LOADED);
 777     }
 778 
 779     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 780     return (IsLoaded);
 781 }
 782 
 783 
 784 /*******************************************************************************
 785  *
 786  * FUNCTION:    AcpiTbSetTableLoadedFlag
 787  *
 788  * PARAMETERS:  TableIndex          - Table index
 789  *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
 790  *
 791  * RETURN:      None
 792  *
 793  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
 794  *
 795  ******************************************************************************/
 796 
 797 void
 798 AcpiTbSetTableLoadedFlag (
 799     UINT32                  TableIndex,
 800     BOOLEAN                 IsLoaded)
 801 {
 802 
 803     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
 804     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
 805     {
 806         if (IsLoaded)
 807         {
 808             AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
 809                 ACPI_TABLE_IS_LOADED;
 810         }
 811         else
 812         {
 813             AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
 814                 ~ACPI_TABLE_IS_LOADED;
 815         }
 816     }
 817 
 818     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
 819 }