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