tbinstal.c revision 193267
167754Smsmith/******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: tbinstal - ACPI table installation and removal
467754Smsmith *
567754Smsmith *****************************************************************************/
667754Smsmith
767754Smsmith/******************************************************************************
867754Smsmith *
967754Smsmith * 1. Copyright Notice
1067754Smsmith *
11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
1270243Smsmith * All rights reserved.
1367754Smsmith *
1467754Smsmith * 2. License
1567754Smsmith *
1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1767754Smsmith * rights.  You may have additional license terms from the party that provided
1867754Smsmith * you this software, covering your right to use that party's intellectual
1967754Smsmith * property rights.
2067754Smsmith *
2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2667754Smsmith * Code in any form, with the right to sublicense such rights; and
2767754Smsmith *
2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
2967754Smsmith * license (with the right to sublicense), under only those claims of Intel
3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3367754Smsmith * license, and in no event shall the patent license extend to any additions
3467754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3567754Smsmith * is granted directly or by implication, estoppel or otherwise;
3667754Smsmith *
3767754Smsmith * The above copyright and patent license is granted only if the following
3867754Smsmith * conditions are met:
3967754Smsmith *
4067754Smsmith * 3. Conditions
4167754Smsmith *
4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4367754Smsmith * Redistribution of source code of any substantial portion of the Covered
4467754Smsmith * Code or modification with rights to further distribute source must include
4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4667754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered
4967754Smsmith * Code and the date of any change.  Licensee must include in that file the
5067754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5167754Smsmith * must include a prominent statement that the modification is derived,
5267754Smsmith * directly or indirectly, from Original Intel Code.
5367754Smsmith *
5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5567754Smsmith * Redistribution of source code of any substantial portion of the Covered
5667754Smsmith * Code or modification without rights to further distribute source must
5767754Smsmith * include the following Disclaimer and Export Compliance provision in the
5867754Smsmith * documentation and/or other materials provided with distribution.  In
5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6167754Smsmith * license from Licensee to its licensee is limited to the intellectual
6267754Smsmith * property embodied in the software Licensee provides to its licensee, and
6367754Smsmith * not to intellectual property embodied in modifications its licensee may
6467754Smsmith * make.
6567754Smsmith *
6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the
6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
6967754Smsmith * provision in the documentation and/or other materials provided with the
7067754Smsmith * distribution.
7167754Smsmith *
7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7367754Smsmith * Intel Code.
7467754Smsmith *
7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7767754Smsmith * other dealings in products derived from or relating to the Covered Code
7867754Smsmith * without prior written authorization from Intel.
7967754Smsmith *
8067754Smsmith * 4. Disclaimer and Export Compliance
8167754Smsmith *
8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8367754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8867754Smsmith * PARTICULAR PURPOSE.
8967754Smsmith *
9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9767754Smsmith * LIMITED REMEDY.
9867754Smsmith *
9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10067754Smsmith * software or system incorporating such software without first obtaining any
10167754Smsmith * required license or other approval from the U. S. Department of Commerce or
10267754Smsmith * any other agency or department of the United States Government.  In the
10367754Smsmith * event Licensee exports any such software from the United States or
10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10567754Smsmith * ensure that the distribution and export/re-export of the software is in
10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
10967754Smsmith * software, or service, directly or indirectly, to any country for which the
11067754Smsmith * United States government or any agency thereof requires an export license,
11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11267754Smsmith * such license, approval or letter.
11367754Smsmith *
11467754Smsmith *****************************************************************************/
11567754Smsmith
11667754Smsmith
11767754Smsmith#define __TBINSTAL_C__
11867754Smsmith
119193251Sjkim#include "acpi.h"
120193267Sjkim#include "accommon.h"
121193251Sjkim#include "acnamesp.h"
122193251Sjkim#include "actables.h"
12367754Smsmith
12467754Smsmith
12577424Smsmith#define _COMPONENT          ACPI_TABLES
12691116Smsmith        ACPI_MODULE_NAME    ("tbinstal")
12767754Smsmith
12867754Smsmith
129167802Sjkim/******************************************************************************
13067754Smsmith *
131167802Sjkim * FUNCTION:    AcpiTbVerifyTable
13291116Smsmith *
133167802Sjkim * PARAMETERS:  TableDesc           - table
13491116Smsmith *
13591116Smsmith * RETURN:      Status
13691116Smsmith *
137167802Sjkim * DESCRIPTION: this function is called to verify and map table
13891116Smsmith *
139167802Sjkim *****************************************************************************/
14091116Smsmith
141167802SjkimACPI_STATUS
142167802SjkimAcpiTbVerifyTable (
143167802Sjkim    ACPI_TABLE_DESC         *TableDesc)
14491116Smsmith{
145167802Sjkim    ACPI_STATUS             Status = AE_OK;
14691116Smsmith
14791116Smsmith
148167802Sjkim    ACPI_FUNCTION_TRACE (TbVerifyTable);
14991116Smsmith
15091116Smsmith
151167802Sjkim    /* Map the table if necessary */
152151937Sjkim
153167802Sjkim    if (!TableDesc->Pointer)
15491116Smsmith    {
155167802Sjkim        if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
156167802Sjkim            ACPI_TABLE_ORIGIN_MAPPED)
157100966Siwasaki        {
158193267Sjkim            TableDesc->Pointer = AcpiOsMapMemory (
159193267Sjkim                TableDesc->Address, TableDesc->Length);
160100966Siwasaki        }
161100966Siwasaki
162167802Sjkim        if (!TableDesc->Pointer)
16391116Smsmith        {
164167802Sjkim            return_ACPI_STATUS (AE_NO_MEMORY);
165167802Sjkim        }
166167802Sjkim    }
16791116Smsmith
168167802Sjkim    /* FACS is the odd table, has no standard ACPI header and no checksum */
16991116Smsmith
170167802Sjkim    if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
171167802Sjkim    {
172167802Sjkim        /* Always calculate checksum, ignore bad checksum if requested */
17391116Smsmith
174167802Sjkim        Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
17591116Smsmith    }
17691116Smsmith
177167802Sjkim    return_ACPI_STATUS (Status);
17891116Smsmith}
17991116Smsmith
18091116Smsmith
18191116Smsmith/*******************************************************************************
18291116Smsmith *
183167802Sjkim * FUNCTION:    AcpiTbAddTable
18467754Smsmith *
185167802Sjkim * PARAMETERS:  TableDesc           - Table descriptor
186167802Sjkim *              TableIndex          - Where the table index is returned
18767754Smsmith *
18867754Smsmith * RETURN:      Status
18967754Smsmith *
190193267Sjkim * DESCRIPTION: This function is called to add an ACPI table. It is used to
191193267Sjkim *              dynamically load tables via the Load and LoadTable AML
192193267Sjkim *              operators.
19367754Smsmith *
19467754Smsmith ******************************************************************************/
19567754Smsmith
19667754SmsmithACPI_STATUS
197167802SjkimAcpiTbAddTable (
198167802Sjkim    ACPI_TABLE_DESC         *TableDesc,
199193267Sjkim    UINT32                  *TableIndex)
20067754Smsmith{
201193267Sjkim    UINT32                  i;
202167802Sjkim    ACPI_STATUS             Status = AE_OK;
203193267Sjkim    ACPI_TABLE_HEADER       *OverrideTable = NULL;
20467754Smsmith
205151937Sjkim
206167802Sjkim    ACPI_FUNCTION_TRACE (TbAddTable);
20767754Smsmith
20867754Smsmith
209167802Sjkim    if (!TableDesc->Pointer)
210167802Sjkim    {
211167802Sjkim        Status = AcpiTbVerifyTable (TableDesc);
212167802Sjkim        if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
213167802Sjkim        {
214167802Sjkim            return_ACPI_STATUS (Status);
215167802Sjkim        }
216167802Sjkim    }
21767754Smsmith
218193267Sjkim    /*
219193267Sjkim     * Originally, we checked the table signature for "SSDT" or "PSDT" here.
220193267Sjkim     * Next, we added support for OEMx tables, signature "OEM".
221193267Sjkim     * Valid tables were encountered with a null signature, so we've just
222193267Sjkim     * given up on validating the signature, since it seems to be a waste
223193267Sjkim     * of code. The original code was removed (05/2008).
224193267Sjkim     */
225167802Sjkim
226167802Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
227167802Sjkim
228167802Sjkim    /* Check if table is already registered */
229167802Sjkim
230167802Sjkim    for (i = 0; i < AcpiGbl_RootTableList.Count; ++i)
231151937Sjkim    {
232167802Sjkim        if (!AcpiGbl_RootTableList.Tables[i].Pointer)
233167802Sjkim        {
234167802Sjkim            Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
235193267Sjkim            if (ACPI_FAILURE (Status) ||
236193267Sjkim                !AcpiGbl_RootTableList.Tables[i].Pointer)
237167802Sjkim            {
238167802Sjkim                continue;
239167802Sjkim            }
240167802Sjkim        }
241167802Sjkim
242193267Sjkim        /*
243193267Sjkim         * Check for a table match on the entire table length,
244193267Sjkim         * not just the header.
245193267Sjkim         */
246193267Sjkim        if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
247193267Sjkim        {
248193267Sjkim            continue;
249193267Sjkim        }
250193267Sjkim
251167802Sjkim        if (ACPI_MEMCMP (TableDesc->Pointer,
252193267Sjkim                AcpiGbl_RootTableList.Tables[i].Pointer,
253193267Sjkim                AcpiGbl_RootTableList.Tables[i].Length))
254167802Sjkim        {
255167802Sjkim            continue;
256167802Sjkim        }
257167802Sjkim
258193267Sjkim        /*
259193267Sjkim         * Note: the current mechanism does not unregister a table if it is
260193267Sjkim         * dynamically unloaded. The related namespace entries are deleted,
261193267Sjkim         * but the table remains in the root table list.
262193267Sjkim         *
263193267Sjkim         * The assumption here is that the number of different tables that
264193267Sjkim         * will be loaded is actually small, and there is minimal overhead
265193267Sjkim         * in just keeping the table in case it is needed again.
266193267Sjkim         *
267193267Sjkim         * If this assumption changes in the future (perhaps on large
268193267Sjkim         * machines with many table load/unload operations), tables will
269193267Sjkim         * need to be unregistered when they are unloaded, and slots in the
270193267Sjkim         * root table list should be reused when empty.
271193267Sjkim         */
272167802Sjkim
273193267Sjkim        /*
274193267Sjkim         * Table is already registered.
275193267Sjkim         * We can delete the table that was passed as a parameter.
276193267Sjkim         */
277167802Sjkim        AcpiTbDeleteTable (TableDesc);
278167802Sjkim        *TableIndex = i;
279193267Sjkim
280193267Sjkim        if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
281193267Sjkim        {
282193267Sjkim            /* Table is still loaded, this is an error */
283193267Sjkim
284193267Sjkim            Status = AE_ALREADY_EXISTS;
285193267Sjkim            goto Release;
286193267Sjkim        }
287193267Sjkim        else
288193267Sjkim        {
289193267Sjkim            /* Table was unloaded, allow it to be reloaded */
290193267Sjkim
291193267Sjkim            TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
292193267Sjkim            TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
293193267Sjkim            Status = AE_OK;
294193267Sjkim            goto PrintHeader;
295193267Sjkim        }
296151937Sjkim    }
297151937Sjkim
298167802Sjkim    /*
299193267Sjkim     * ACPI Table Override:
300193267Sjkim     * Allow the host to override dynamically loaded tables.
301167802Sjkim     */
302193267Sjkim    Status = AcpiOsTableOverride (TableDesc->Pointer, &OverrideTable);
303193267Sjkim    if (ACPI_SUCCESS (Status) && OverrideTable)
304193267Sjkim    {
305193267Sjkim        ACPI_INFO ((AE_INFO,
306193267Sjkim            "%4.4s @ 0x%p Table override, replaced with:",
307193267Sjkim            TableDesc->Pointer->Signature,
308193267Sjkim            ACPI_CAST_PTR (void, TableDesc->Address)));
309193267Sjkim
310193267Sjkim        /* We can delete the table that was passed as a parameter */
311193267Sjkim
312193267Sjkim        AcpiTbDeleteTable (TableDesc);
313193267Sjkim
314193267Sjkim        /* Setup descriptor for the new table */
315193267Sjkim
316193267Sjkim        TableDesc->Address = ACPI_PTR_TO_PHYSADDR (OverrideTable);
317193267Sjkim        TableDesc->Pointer = OverrideTable;
318193267Sjkim        TableDesc->Length = OverrideTable->Length;
319193267Sjkim        TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
320193267Sjkim    }
321193267Sjkim
322193267Sjkim    /* Add the table to the global root table list */
323193267Sjkim
324167802Sjkim    Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
325167802Sjkim                TableDesc->Length, TableDesc->Flags, TableIndex);
326100966Siwasaki    if (ACPI_FAILURE (Status))
327100966Siwasaki    {
328167802Sjkim        goto Release;
329100966Siwasaki    }
33067754Smsmith
331193267SjkimPrintHeader:
332167802Sjkim    AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
33367754Smsmith
334167802SjkimRelease:
33591116Smsmith    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
33667754Smsmith    return_ACPI_STATUS (Status);
33767754Smsmith}
33867754Smsmith
33967754Smsmith
34067754Smsmith/*******************************************************************************
34167754Smsmith *
342167802Sjkim * FUNCTION:    AcpiTbResizeRootTableList
34367754Smsmith *
344167802Sjkim * PARAMETERS:  None
34567754Smsmith *
34667754Smsmith * RETURN:      Status
34767754Smsmith *
348167802Sjkim * DESCRIPTION: Expand the size of global table array
34967754Smsmith *
35067754Smsmith ******************************************************************************/
35167754Smsmith
35267754SmsmithACPI_STATUS
353167802SjkimAcpiTbResizeRootTableList (
354167802Sjkim    void)
35567754Smsmith{
356167802Sjkim    ACPI_TABLE_DESC         *Tables;
35767754Smsmith
35867754Smsmith
359167802Sjkim    ACPI_FUNCTION_TRACE (TbResizeRootTableList);
36067754Smsmith
36167754Smsmith
362167802Sjkim    /* AllowResize flag is a parameter to AcpiInitializeTables */
36367754Smsmith
364167802Sjkim    if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
36567754Smsmith    {
366167802Sjkim        ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
367167802Sjkim        return_ACPI_STATUS (AE_SUPPORT);
36867754Smsmith    }
36967754Smsmith
370167802Sjkim    /* Increase the Table Array size */
371167802Sjkim
372167802Sjkim    Tables = ACPI_ALLOCATE_ZEROED (
373193267Sjkim        ((ACPI_SIZE) AcpiGbl_RootTableList.Size +
374193267Sjkim            ACPI_ROOT_TABLE_SIZE_INCREMENT) *
375193267Sjkim        sizeof (ACPI_TABLE_DESC));
376167802Sjkim    if (!Tables)
37767754Smsmith    {
378167802Sjkim        ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
379167802Sjkim        return_ACPI_STATUS (AE_NO_MEMORY);
38099146Siwasaki    }
38191116Smsmith
382167802Sjkim    /* Copy and free the previous table array */
383167802Sjkim
384167802Sjkim    if (AcpiGbl_RootTableList.Tables)
38599146Siwasaki    {
386167802Sjkim        ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
387193267Sjkim            (ACPI_SIZE) AcpiGbl_RootTableList.Size * sizeof (ACPI_TABLE_DESC));
388167802Sjkim
389167802Sjkim        if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
390167802Sjkim        {
391167802Sjkim            ACPI_FREE (AcpiGbl_RootTableList.Tables);
392167802Sjkim        }
39399146Siwasaki    }
39491116Smsmith
395167802Sjkim    AcpiGbl_RootTableList.Tables = Tables;
396167802Sjkim    AcpiGbl_RootTableList.Size += ACPI_ROOT_TABLE_SIZE_INCREMENT;
397167802Sjkim    AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED;
39899146Siwasaki
399167802Sjkim    return_ACPI_STATUS (AE_OK);
40067754Smsmith}
40167754Smsmith
40267754Smsmith
40367754Smsmith/*******************************************************************************
40467754Smsmith *
405167802Sjkim * FUNCTION:    AcpiTbStoreTable
40667754Smsmith *
407167802Sjkim * PARAMETERS:  Address             - Table address
408167802Sjkim *              Table               - Table header
409167802Sjkim *              Length              - Table length
410167802Sjkim *              Flags               - flags
41167754Smsmith *
412167802Sjkim * RETURN:      Status and table index.
41367754Smsmith *
414167802Sjkim * DESCRIPTION: Add an ACPI table to the global table list
41567754Smsmith *
41667754Smsmith ******************************************************************************/
41767754Smsmith
41867754SmsmithACPI_STATUS
419167802SjkimAcpiTbStoreTable (
420167802Sjkim    ACPI_PHYSICAL_ADDRESS   Address,
421167802Sjkim    ACPI_TABLE_HEADER       *Table,
422167802Sjkim    UINT32                  Length,
423167802Sjkim    UINT8                   Flags,
424193267Sjkim    UINT32                  *TableIndex)
42567754Smsmith{
426167802Sjkim    ACPI_STATUS             Status = AE_OK;
42767754Smsmith
42867754Smsmith
429167802Sjkim    /* Ensure that there is room for the table in the Root Table List */
43067754Smsmith
431167802Sjkim    if (AcpiGbl_RootTableList.Count >= AcpiGbl_RootTableList.Size)
432117521Snjl    {
433167802Sjkim        Status = AcpiTbResizeRootTableList();
434167802Sjkim        if (ACPI_FAILURE (Status))
435167802Sjkim        {
436167802Sjkim            return (Status);
437167802Sjkim        }
438117521Snjl    }
439117521Snjl
440167802Sjkim    /* Initialize added table */
441151937Sjkim
442167802Sjkim    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Address = Address;
443167802Sjkim    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Pointer = Table;
444167802Sjkim    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Length = Length;
445167802Sjkim    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].OwnerId = 0;
446167802Sjkim    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Flags = Flags;
447151937Sjkim
448167802Sjkim    ACPI_MOVE_32_TO_32 (
449167802Sjkim        &(AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Signature),
450167802Sjkim        Table->Signature);
451151937Sjkim
452167802Sjkim    *TableIndex = AcpiGbl_RootTableList.Count;
453167802Sjkim    AcpiGbl_RootTableList.Count++;
454167802Sjkim    return (Status);
455167802Sjkim}
45667754Smsmith
457123315Snjl
458167802Sjkim/*******************************************************************************
459167802Sjkim *
460167802Sjkim * FUNCTION:    AcpiTbDeleteTable
461167802Sjkim *
462167802Sjkim * PARAMETERS:  TableIndex          - Table index
463167802Sjkim *
464167802Sjkim * RETURN:      None
465167802Sjkim *
466167802Sjkim * DESCRIPTION: Delete one internal ACPI table
467167802Sjkim *
468167802Sjkim ******************************************************************************/
469123315Snjl
470167802Sjkimvoid
471167802SjkimAcpiTbDeleteTable (
472167802Sjkim    ACPI_TABLE_DESC         *TableDesc)
473167802Sjkim{
474123315Snjl
475167802Sjkim    /* Table must be mapped or allocated */
476167802Sjkim
477167802Sjkim    if (!TableDesc->Pointer)
478123315Snjl    {
479167802Sjkim        return;
480117521Snjl    }
48167754Smsmith
482167802Sjkim    switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
483167802Sjkim    {
484167802Sjkim    case ACPI_TABLE_ORIGIN_MAPPED:
485167802Sjkim        AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
486167802Sjkim        break;
48767754Smsmith
488167802Sjkim    case ACPI_TABLE_ORIGIN_ALLOCATED:
489167802Sjkim        ACPI_FREE (TableDesc->Pointer);
490167802Sjkim        break;
49167754Smsmith
492167802Sjkim    default:
493167802Sjkim        break;
49467754Smsmith    }
49567754Smsmith
496167802Sjkim    TableDesc->Pointer = NULL;
49767754Smsmith}
49867754Smsmith
49967754Smsmith
50067754Smsmith/*******************************************************************************
50167754Smsmith *
502167802Sjkim * FUNCTION:    AcpiTbTerminate
50367754Smsmith *
504167802Sjkim * PARAMETERS:  None
50567754Smsmith *
506167802Sjkim * RETURN:      None
50767754Smsmith *
50867754Smsmith * DESCRIPTION: Delete all internal ACPI tables
50967754Smsmith *
51067754Smsmith ******************************************************************************/
51167754Smsmith
51267754Smsmithvoid
513167802SjkimAcpiTbTerminate (
514151937Sjkim    void)
51567754Smsmith{
516193267Sjkim    UINT32                  i;
51767754Smsmith
51867754Smsmith
519167802Sjkim    ACPI_FUNCTION_TRACE (TbTerminate);
520167802Sjkim
521167802Sjkim
522167802Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
523167802Sjkim
524167802Sjkim    /* Delete the individual tables */
525167802Sjkim
526167802Sjkim    for (i = 0; i < AcpiGbl_RootTableList.Count; i++)
527167802Sjkim    {
528167802Sjkim        AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
529167802Sjkim    }
530167802Sjkim
53167754Smsmith    /*
532167802Sjkim     * Delete the root table array if allocated locally. Array cannot be
533167802Sjkim     * mapped, so we don't need to check for that flag.
53467754Smsmith     */
535167802Sjkim    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
53667754Smsmith    {
537167802Sjkim        ACPI_FREE (AcpiGbl_RootTableList.Tables);
53867754Smsmith    }
539167802Sjkim
540167802Sjkim    AcpiGbl_RootTableList.Tables = NULL;
541167802Sjkim    AcpiGbl_RootTableList.Flags = 0;
542167802Sjkim    AcpiGbl_RootTableList.Count = 0;
543167802Sjkim
544167802Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
545167802Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
54667754Smsmith}
54767754Smsmith
54867754Smsmith
54967754Smsmith/*******************************************************************************
55067754Smsmith *
551167802Sjkim * FUNCTION:    AcpiTbDeleteNamespaceByOwner
55267754Smsmith *
553167802Sjkim * PARAMETERS:  TableIndex          - Table index
55467754Smsmith *
555193267Sjkim * RETURN:      Status
55667754Smsmith *
557167802Sjkim * DESCRIPTION: Delete all namespace objects created when this table was loaded.
55867754Smsmith *
55967754Smsmith ******************************************************************************/
56067754Smsmith
561193267SjkimACPI_STATUS
562167802SjkimAcpiTbDeleteNamespaceByOwner (
563193267Sjkim    UINT32                  TableIndex)
56467754Smsmith{
565167802Sjkim    ACPI_OWNER_ID           OwnerId;
566193267Sjkim    ACPI_STATUS             Status;
56767754Smsmith
56867754Smsmith
569193267Sjkim    ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
570193267Sjkim
571193267Sjkim
572193267Sjkim    Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
573193267Sjkim    if (ACPI_FAILURE (Status))
57467754Smsmith    {
575193267Sjkim        return_ACPI_STATUS (Status);
57667754Smsmith    }
577193267Sjkim
578193267Sjkim    if (TableIndex >= AcpiGbl_RootTableList.Count)
57991116Smsmith    {
580193267Sjkim        /* The table index does not exist */
581193267Sjkim
582167802Sjkim        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
583193267Sjkim        return_ACPI_STATUS (AE_NOT_EXIST);
58491116Smsmith    }
58567754Smsmith
586193267Sjkim    /* Get the owner ID for this table, used to delete namespace nodes */
587193267Sjkim
588193267Sjkim    OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
589167802Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
590193267Sjkim
591193267Sjkim    /*
592193267Sjkim     * Need to acquire the namespace writer lock to prevent interference
593193267Sjkim     * with any concurrent namespace walks. The interpreter must be
594193267Sjkim     * released during the deletion since the acquisition of the deletion
595193267Sjkim     * lock may block, and also since the execution of a namespace walk
596193267Sjkim     * must be allowed to use the interpreter.
597193267Sjkim     */
598193267Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
599193267Sjkim    Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
600193267Sjkim
601167802Sjkim    AcpiNsDeleteNamespaceByOwner (OwnerId);
602193267Sjkim    if (ACPI_FAILURE (Status))
603193267Sjkim    {
604193267Sjkim        return_ACPI_STATUS (Status);
605193267Sjkim    }
606193267Sjkim
607193267Sjkim    AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
608193267Sjkim
609193267Sjkim    Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
610193267Sjkim    return_ACPI_STATUS (Status);
611167802Sjkim}
61267754Smsmith
61367754Smsmith
614167802Sjkim/*******************************************************************************
615167802Sjkim *
616167802Sjkim * FUNCTION:    AcpiTbAllocateOwnerId
617167802Sjkim *
618167802Sjkim * PARAMETERS:  TableIndex          - Table index
619167802Sjkim *
620167802Sjkim * RETURN:      Status
621167802Sjkim *
622167802Sjkim * DESCRIPTION: Allocates OwnerId in TableDesc
623167802Sjkim *
624167802Sjkim ******************************************************************************/
62567754Smsmith
626167802SjkimACPI_STATUS
627167802SjkimAcpiTbAllocateOwnerId (
628193267Sjkim    UINT32                  TableIndex)
629167802Sjkim{
630167802Sjkim    ACPI_STATUS             Status = AE_BAD_PARAMETER;
63167754Smsmith
63267754Smsmith
633167802Sjkim    ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
63467754Smsmith
63567754Smsmith
636167802Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
637167802Sjkim    if (TableIndex < AcpiGbl_RootTableList.Count)
63867754Smsmith    {
639167802Sjkim        Status = AcpiUtAllocateOwnerId
640167802Sjkim                    (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
64167754Smsmith    }
64267754Smsmith
643117521Snjl    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
644167802Sjkim    return_ACPI_STATUS (Status);
64567754Smsmith}
64667754Smsmith
64767754Smsmith
64867754Smsmith/*******************************************************************************
64967754Smsmith *
650167802Sjkim * FUNCTION:    AcpiTbReleaseOwnerId
65167754Smsmith *
652167802Sjkim * PARAMETERS:  TableIndex          - Table index
65367754Smsmith *
654167802Sjkim * RETURN:      Status
65567754Smsmith *
656167802Sjkim * DESCRIPTION: Releases OwnerId in TableDesc
65767754Smsmith *
65867754Smsmith ******************************************************************************/
65967754Smsmith
660167802SjkimACPI_STATUS
661167802SjkimAcpiTbReleaseOwnerId (
662193267Sjkim    UINT32                  TableIndex)
66367754Smsmith{
664167802Sjkim    ACPI_STATUS             Status = AE_BAD_PARAMETER;
66567754Smsmith
666117521Snjl
667167802Sjkim    ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
66867754Smsmith
669117521Snjl
670167802Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
671167802Sjkim    if (TableIndex < AcpiGbl_RootTableList.Count)
67267754Smsmith    {
673193267Sjkim        AcpiUtReleaseOwnerId (
674193267Sjkim            &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
675167802Sjkim        Status = AE_OK;
676167802Sjkim    }
67767754Smsmith
678167802Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
679167802Sjkim    return_ACPI_STATUS (Status);
68067754Smsmith}
68167754Smsmith
68267754Smsmith
68367754Smsmith/*******************************************************************************
68467754Smsmith *
685167802Sjkim * FUNCTION:    AcpiTbGetOwnerId
68667754Smsmith *
687167802Sjkim * PARAMETERS:  TableIndex          - Table index
688167802Sjkim *              OwnerId             - Where the table OwnerId is returned
68967754Smsmith *
690167802Sjkim * RETURN:      Status
69167754Smsmith *
692167802Sjkim * DESCRIPTION: returns OwnerId for the ACPI table
69367754Smsmith *
69467754Smsmith ******************************************************************************/
69567754Smsmith
696167802SjkimACPI_STATUS
697167802SjkimAcpiTbGetOwnerId (
698193267Sjkim    UINT32                  TableIndex,
699167802Sjkim    ACPI_OWNER_ID           *OwnerId)
70067754Smsmith{
701167802Sjkim    ACPI_STATUS             Status = AE_BAD_PARAMETER;
70267754Smsmith
70367754Smsmith
704167802Sjkim    ACPI_FUNCTION_TRACE (TbGetOwnerId);
70567754Smsmith
70667754Smsmith
707167802Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
708167802Sjkim    if (TableIndex < AcpiGbl_RootTableList.Count)
70967754Smsmith    {
710167802Sjkim        *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
711167802Sjkim        Status = AE_OK;
71267754Smsmith    }
71367754Smsmith
714167802Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
715167802Sjkim    return_ACPI_STATUS (Status);
716167802Sjkim}
71767754Smsmith
71867754Smsmith
719167802Sjkim/*******************************************************************************
720167802Sjkim *
721167802Sjkim * FUNCTION:    AcpiTbIsTableLoaded
722167802Sjkim *
723167802Sjkim * PARAMETERS:  TableIndex          - Table index
724167802Sjkim *
725167802Sjkim * RETURN:      Table Loaded Flag
726167802Sjkim *
727167802Sjkim ******************************************************************************/
728117521Snjl
729167802SjkimBOOLEAN
730167802SjkimAcpiTbIsTableLoaded (
731193267Sjkim    UINT32                  TableIndex)
732167802Sjkim{
733167802Sjkim    BOOLEAN                 IsLoaded = FALSE;
734167802Sjkim
735167802Sjkim
736167802Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
737167802Sjkim    if (TableIndex < AcpiGbl_RootTableList.Count)
73867754Smsmith    {
739167802Sjkim        IsLoaded = (BOOLEAN)
740193267Sjkim            (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
741193267Sjkim            ACPI_TABLE_IS_LOADED);
74267754Smsmith    }
74367754Smsmith
744167802Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
745167802Sjkim    return (IsLoaded);
746167802Sjkim}
74767754Smsmith
74867754Smsmith
749167802Sjkim/*******************************************************************************
750167802Sjkim *
751167802Sjkim * FUNCTION:    AcpiTbSetTableLoadedFlag
752167802Sjkim *
753167802Sjkim * PARAMETERS:  TableIndex          - Table index
754167802Sjkim *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
755167802Sjkim *
756167802Sjkim * RETURN:      None
757167802Sjkim *
758167802Sjkim * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
759167802Sjkim *
760167802Sjkim ******************************************************************************/
76167754Smsmith
762167802Sjkimvoid
763167802SjkimAcpiTbSetTableLoadedFlag (
764193267Sjkim    UINT32                  TableIndex,
765167802Sjkim    BOOLEAN                 IsLoaded)
766167802Sjkim{
76767754Smsmith
768167802Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
769167802Sjkim    if (TableIndex < AcpiGbl_RootTableList.Count)
770167802Sjkim    {
771167802Sjkim        if (IsLoaded)
772167802Sjkim        {
773193267Sjkim            AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
774193267Sjkim                ACPI_TABLE_IS_LOADED;
775167802Sjkim        }
776167802Sjkim        else
777167802Sjkim        {
778193267Sjkim            AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
779193267Sjkim                ~ACPI_TABLE_IS_LOADED;
780167802Sjkim        }
781167802Sjkim    }
78267754Smsmith
783167802Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
78467754Smsmith}
78567754Smsmith
786