Home | History | Annotate | Line # | Download | only in tables
tbdata.c revision 1.8
      1 /******************************************************************************
      2  *
      3  * Module Name: tbdata - Table manager data structure functions
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2017, 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     const 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