1263851Sjkim/******************************************************************************
2263851Sjkim *
3263851Sjkim * Module Name: tbdata - Table manager data structure functions
4263851Sjkim *
5263851Sjkim *****************************************************************************/
6263851Sjkim
7316303Sjkim/******************************************************************************
8316303Sjkim *
9316303Sjkim * 1. Copyright Notice
10316303Sjkim *
11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12263851Sjkim * All rights reserved.
13263851Sjkim *
14316303Sjkim * 2. License
15316303Sjkim *
16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property
17316303Sjkim * rights. You may have additional license terms from the party that provided
18316303Sjkim * you this software, covering your right to use that party's intellectual
19316303Sjkim * property rights.
20316303Sjkim *
21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an
23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy,
25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered
26316303Sjkim * Code in any form, with the right to sublicense such rights; and
27316303Sjkim *
28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29316303Sjkim * license (with the right to sublicense), under only those claims of Intel
30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell,
31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof
32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright
33316303Sjkim * license, and in no event shall the patent license extend to any additions
34316303Sjkim * to or modifications of the Original Intel Code. No other license or right
35316303Sjkim * is granted directly or by implication, estoppel or otherwise;
36316303Sjkim *
37316303Sjkim * The above copyright and patent license is granted only if the following
38316303Sjkim * conditions are met:
39316303Sjkim *
40316303Sjkim * 3. Conditions
41316303Sjkim *
42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43316303Sjkim * Redistribution of source code of any substantial portion of the Covered
44316303Sjkim * Code or modification with rights to further distribute source must include
45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions,
46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition,
47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to
48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered
49316303Sjkim * Code and the date of any change. Licensee must include in that file the
50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee
51316303Sjkim * must include a prominent statement that the modification is derived,
52316303Sjkim * directly or indirectly, from Original Intel Code.
53316303Sjkim *
54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55316303Sjkim * Redistribution of source code of any substantial portion of the Covered
56316303Sjkim * Code or modification without rights to further distribute source must
57316303Sjkim * include the following Disclaimer and Export Compliance provision in the
58316303Sjkim * documentation and/or other materials provided with distribution. In
59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any
60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the
61316303Sjkim * license from Licensee to its licensee is limited to the intellectual
62316303Sjkim * property embodied in the software Licensee provides to its licensee, and
63316303Sjkim * not to intellectual property embodied in modifications its licensee may
64316303Sjkim * make.
65316303Sjkim *
66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any
67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the
68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance
69316303Sjkim * provision in the documentation and/or other materials provided with the
70316303Sjkim * distribution.
71316303Sjkim *
72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original
73316303Sjkim * Intel Code.
74316303Sjkim *
75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or
77316303Sjkim * other dealings in products derived from or relating to the Covered Code
78316303Sjkim * without prior written authorization from Intel.
79316303Sjkim *
80316303Sjkim * 4. Disclaimer and Export Compliance
81316303Sjkim *
82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88316303Sjkim * PARTICULAR PURPOSE.
89316303Sjkim *
90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97316303Sjkim * LIMITED REMEDY.
98316303Sjkim *
99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this
100316303Sjkim * software or system incorporating such software without first obtaining any
101316303Sjkim * required license or other approval from the U. S. Department of Commerce or
102316303Sjkim * any other agency or department of the United States Government. In the
103316303Sjkim * event Licensee exports any such software from the United States or
104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall
105316303Sjkim * ensure that the distribution and export/re-export of the software is in
106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the
107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process,
109316303Sjkim * software, or service, directly or indirectly, to any country for which the
110316303Sjkim * United States government or any agency thereof requires an export license,
111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining
112316303Sjkim * such license, approval or letter.
113316303Sjkim *
114316303Sjkim *****************************************************************************
115316303Sjkim *
116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
117316303Sjkim * following license:
118316303Sjkim *
119263851Sjkim * Redistribution and use in source and binary forms, with or without
120263851Sjkim * modification, are permitted provided that the following conditions
121263851Sjkim * are met:
122263851Sjkim * 1. Redistributions of source code must retain the above copyright
123263851Sjkim *    notice, this list of conditions, and the following disclaimer,
124263851Sjkim *    without modification.
125263851Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126263851Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
127263851Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
128263851Sjkim *    including a substantially similar Disclaimer requirement for further
129263851Sjkim *    binary redistribution.
130263851Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
131263851Sjkim *    of any contributors may be used to endorse or promote products derived
132263851Sjkim *    from this software without specific prior written permission.
133263851Sjkim *
134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145316303Sjkim *
146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the
147263851Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
148263851Sjkim * Software Foundation.
149263851Sjkim *
150316303Sjkim *****************************************************************************/
151263851Sjkim
152272444Sjkim#include <contrib/dev/acpica/include/acpi.h>
153272444Sjkim#include <contrib/dev/acpica/include/accommon.h>
154272444Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
155272444Sjkim#include <contrib/dev/acpica/include/actables.h>
156316303Sjkim#include <contrib/dev/acpica/include/acevents.h>
157263851Sjkim
158263851Sjkim#define _COMPONENT          ACPI_TABLES
159263851Sjkim        ACPI_MODULE_NAME    ("tbdata")
160263851Sjkim
161322877Sjkim/* Local prototypes */
162263851Sjkim
163322877Sjkimstatic ACPI_STATUS
164322877SjkimAcpiTbCheckDuplication (
165322877Sjkim    ACPI_TABLE_DESC         *TableDesc,
166322877Sjkim    UINT32                  *TableIndex);
167322877Sjkim
168322877Sjkimstatic BOOLEAN
169322877SjkimAcpiTbCompareTables (
170322877Sjkim    ACPI_TABLE_DESC         *TableDesc,
171322877Sjkim    UINT32                  TableIndex);
172322877Sjkim
173322877Sjkim
174263851Sjkim/*******************************************************************************
175263851Sjkim *
176322877Sjkim * FUNCTION:    AcpiTbCompareTables
177322877Sjkim *
178322877Sjkim * PARAMETERS:  TableDesc           - Table 1 descriptor to be compared
179322877Sjkim *              TableIndex          - Index of table 2 to be compared
180322877Sjkim *
181322877Sjkim * RETURN:      TRUE if both tables are identical.
182322877Sjkim *
183322877Sjkim * DESCRIPTION: This function compares a table with another table that has
184322877Sjkim *              already been installed in the root table list.
185322877Sjkim *
186322877Sjkim ******************************************************************************/
187322877Sjkim
188322877Sjkimstatic BOOLEAN
189322877SjkimAcpiTbCompareTables (
190322877Sjkim    ACPI_TABLE_DESC         *TableDesc,
191322877Sjkim    UINT32                  TableIndex)
192322877Sjkim{
193322877Sjkim    ACPI_STATUS             Status = AE_OK;
194322877Sjkim    BOOLEAN                 IsIdentical;
195322877Sjkim    ACPI_TABLE_HEADER       *Table;
196322877Sjkim    UINT32                  TableLength;
197322877Sjkim    UINT8                   TableFlags;
198322877Sjkim
199322877Sjkim
200322877Sjkim    Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex],
201322877Sjkim        &Table, &TableLength, &TableFlags);
202322877Sjkim    if (ACPI_FAILURE (Status))
203322877Sjkim    {
204322877Sjkim        return (FALSE);
205322877Sjkim    }
206322877Sjkim
207322877Sjkim    /*
208322877Sjkim     * Check for a table match on the entire table length,
209322877Sjkim     * not just the header.
210322877Sjkim     */
211322877Sjkim    IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength ||
212322877Sjkim        memcmp (TableDesc->Pointer, Table, TableLength)) ?
213322877Sjkim        FALSE : TRUE);
214322877Sjkim
215322877Sjkim    /* Release the acquired table */
216322877Sjkim
217322877Sjkim    AcpiTbReleaseTable (Table, TableLength, TableFlags);
218322877Sjkim    return (IsIdentical);
219322877Sjkim}
220322877Sjkim
221322877Sjkim
222322877Sjkim/*******************************************************************************
223322877Sjkim *
224263851Sjkim * FUNCTION:    AcpiTbInitTableDescriptor
225263851Sjkim *
226263851Sjkim * PARAMETERS:  TableDesc               - Table descriptor
227263851Sjkim *              Address                 - Physical address of the table
228263851Sjkim *              Flags                   - Allocation flags of the table
229263851Sjkim *              Table                   - Pointer to the table
230263851Sjkim *
231263851Sjkim * RETURN:      None
232263851Sjkim *
233263851Sjkim * DESCRIPTION: Initialize a new table descriptor
234263851Sjkim *
235263851Sjkim ******************************************************************************/
236263851Sjkim
237263851Sjkimvoid
238263851SjkimAcpiTbInitTableDescriptor (
239263851Sjkim    ACPI_TABLE_DESC         *TableDesc,
240263851Sjkim    ACPI_PHYSICAL_ADDRESS   Address,
241263851Sjkim    UINT8                   Flags,
242263851Sjkim    ACPI_TABLE_HEADER       *Table)
243263851Sjkim{
244263851Sjkim
245263851Sjkim    /*
246263851Sjkim     * Initialize the table descriptor. Set the pointer to NULL, since the
247263851Sjkim     * table is not fully mapped at this time.
248263851Sjkim     */
249284583Sjkim    memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
250263851Sjkim    TableDesc->Address = Address;
251263851Sjkim    TableDesc->Length = Table->Length;
252263851Sjkim    TableDesc->Flags = Flags;
253263851Sjkim    ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
254263851Sjkim}
255263851Sjkim
256263851Sjkim
257263851Sjkim/*******************************************************************************
258263851Sjkim *
259263851Sjkim * FUNCTION:    AcpiTbAcquireTable
260263851Sjkim *
261263851Sjkim * PARAMETERS:  TableDesc           - Table descriptor
262263851Sjkim *              TablePtr            - Where table is returned
263263851Sjkim *              TableLength         - Where table length is returned
264263851Sjkim *              TableFlags          - Where table allocation flags are returned
265263851Sjkim *
266263851Sjkim * RETURN:      Status
267263851Sjkim *
268263851Sjkim * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
269263851Sjkim *              maintained in the AcpiGbl_RootTableList.
270263851Sjkim *
271263851Sjkim ******************************************************************************/
272263851Sjkim
273263851SjkimACPI_STATUS
274263851SjkimAcpiTbAcquireTable (
275263851Sjkim    ACPI_TABLE_DESC         *TableDesc,
276263851Sjkim    ACPI_TABLE_HEADER       **TablePtr,
277263851Sjkim    UINT32                  *TableLength,
278263851Sjkim    UINT8                   *TableFlags)
279263851Sjkim{
280263851Sjkim    ACPI_TABLE_HEADER       *Table = NULL;
281263851Sjkim
282263851Sjkim
283263851Sjkim    switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
284263851Sjkim    {
285263851Sjkim    case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
286263851Sjkim
287263851Sjkim        Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length);
288263851Sjkim        break;
289263851Sjkim
290263851Sjkim    case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
291263851Sjkim    case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
292263851Sjkim
293281396Sjkim        Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
294298714Sjkim            ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
295263851Sjkim        break;
296263851Sjkim
297263851Sjkim    default:
298263851Sjkim
299263851Sjkim        break;
300263851Sjkim    }
301263851Sjkim
302263851Sjkim    /* Table is not valid yet */
303263851Sjkim
304263851Sjkim    if (!Table)
305263851Sjkim    {
306263851Sjkim        return (AE_NO_MEMORY);
307263851Sjkim    }
308263851Sjkim
309263851Sjkim    /* Fill the return values */
310263851Sjkim
311263851Sjkim    *TablePtr = Table;
312263851Sjkim    *TableLength = TableDesc->Length;
313263851Sjkim    *TableFlags = TableDesc->Flags;
314263851Sjkim    return (AE_OK);
315263851Sjkim}
316263851Sjkim
317263851Sjkim
318263851Sjkim/*******************************************************************************
319263851Sjkim *
320263851Sjkim * FUNCTION:    AcpiTbReleaseTable
321263851Sjkim *
322263851Sjkim * PARAMETERS:  Table               - Pointer for the table
323263851Sjkim *              TableLength         - Length for the table
324263851Sjkim *              TableFlags          - Allocation flags for the table
325263851Sjkim *
326263851Sjkim * RETURN:      None
327263851Sjkim *
328263851Sjkim * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
329263851Sjkim *
330263851Sjkim ******************************************************************************/
331263851Sjkim
332263851Sjkimvoid
333263851SjkimAcpiTbReleaseTable (
334263851Sjkim    ACPI_TABLE_HEADER       *Table,
335263851Sjkim    UINT32                  TableLength,
336263851Sjkim    UINT8                   TableFlags)
337263851Sjkim{
338263851Sjkim
339263851Sjkim    switch (TableFlags & ACPI_TABLE_ORIGIN_MASK)
340263851Sjkim    {
341263851Sjkim    case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
342263851Sjkim
343263851Sjkim        AcpiOsUnmapMemory (Table, TableLength);
344263851Sjkim        break;
345263851Sjkim
346263851Sjkim    case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
347263851Sjkim    case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
348263851Sjkim    default:
349263851Sjkim
350263851Sjkim        break;
351263851Sjkim    }
352263851Sjkim}
353263851Sjkim
354263851Sjkim
355263851Sjkim/*******************************************************************************
356263851Sjkim *
357263851Sjkim * FUNCTION:    AcpiTbAcquireTempTable
358263851Sjkim *
359263851Sjkim * PARAMETERS:  TableDesc           - Table descriptor to be acquired
360263851Sjkim *              Address             - Address of the table
361263851Sjkim *              Flags               - Allocation flags of the table
362263851Sjkim *
363263851Sjkim * RETURN:      Status
364263851Sjkim *
365263851Sjkim * DESCRIPTION: This function validates the table header to obtain the length
366263851Sjkim *              of a table and fills the table descriptor to make its state as
367263851Sjkim *              "INSTALLED". Such a table descriptor is only used for verified
368263851Sjkim *              installation.
369263851Sjkim *
370263851Sjkim ******************************************************************************/
371263851Sjkim
372263851SjkimACPI_STATUS
373263851SjkimAcpiTbAcquireTempTable (
374263851Sjkim    ACPI_TABLE_DESC         *TableDesc,
375263851Sjkim    ACPI_PHYSICAL_ADDRESS   Address,
376263851Sjkim    UINT8                   Flags)
377263851Sjkim{
378263851Sjkim    ACPI_TABLE_HEADER       *TableHeader;
379263851Sjkim
380263851Sjkim
381263851Sjkim    switch (Flags & ACPI_TABLE_ORIGIN_MASK)
382263851Sjkim    {
383263851Sjkim    case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
384263851Sjkim
385263851Sjkim        /* Get the length of the full table from the header */
386263851Sjkim
387263851Sjkim        TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
388263851Sjkim        if (!TableHeader)
389263851Sjkim        {
390263851Sjkim            return (AE_NO_MEMORY);
391263851Sjkim        }
392263851Sjkim
393263851Sjkim        AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
394263851Sjkim        AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER));
395263851Sjkim        return (AE_OK);
396263851Sjkim
397263851Sjkim    case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
398263851Sjkim    case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
399263851Sjkim
400281396Sjkim        TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
401298714Sjkim            ACPI_PHYSADDR_TO_PTR (Address));
402263851Sjkim        if (!TableHeader)
403263851Sjkim        {
404263851Sjkim            return (AE_NO_MEMORY);
405263851Sjkim        }
406263851Sjkim
407263851Sjkim        AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
408263851Sjkim        return (AE_OK);
409263851Sjkim
410263851Sjkim    default:
411263851Sjkim
412263851Sjkim        break;
413263851Sjkim    }
414263851Sjkim
415263851Sjkim    /* Table is not valid yet */
416263851Sjkim
417263851Sjkim    return (AE_NO_MEMORY);
418263851Sjkim}
419263851Sjkim
420263851Sjkim
421263851Sjkim/*******************************************************************************
422263851Sjkim *
423263851Sjkim * FUNCTION:    AcpiTbReleaseTempTable
424263851Sjkim *
425263851Sjkim * PARAMETERS:  TableDesc           - Table descriptor to be released
426263851Sjkim *
427263851Sjkim * RETURN:      Status
428263851Sjkim *
429263851Sjkim * DESCRIPTION: The inverse of AcpiTbAcquireTempTable().
430263851Sjkim *
431263851Sjkim *****************************************************************************/
432263851Sjkim
433263851Sjkimvoid
434263851SjkimAcpiTbReleaseTempTable (
435263851Sjkim    ACPI_TABLE_DESC         *TableDesc)
436263851Sjkim{
437263851Sjkim
438263851Sjkim    /*
439263851Sjkim     * Note that the .Address is maintained by the callers of
440263851Sjkim     * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable()
441263851Sjkim     * where .Address will be freed.
442263851Sjkim     */
443263851Sjkim    AcpiTbInvalidateTable (TableDesc);
444263851Sjkim}
445263851Sjkim
446263851Sjkim
447263851Sjkim/******************************************************************************
448263851Sjkim *
449263851Sjkim * FUNCTION:    AcpiTbValidateTable
450263851Sjkim *
451263851Sjkim * PARAMETERS:  TableDesc           - Table descriptor
452263851Sjkim *
453263851Sjkim * RETURN:      Status
454263851Sjkim *
455263851Sjkim * DESCRIPTION: This function is called to validate the table, the returned
456263851Sjkim *              table descriptor is in "VALIDATED" state.
457263851Sjkim *
458263851Sjkim *****************************************************************************/
459263851Sjkim
460263851SjkimACPI_STATUS
461263851SjkimAcpiTbValidateTable (
462263851Sjkim    ACPI_TABLE_DESC         *TableDesc)
463263851Sjkim{
464263851Sjkim    ACPI_STATUS             Status = AE_OK;
465263851Sjkim
466263851Sjkim
467263851Sjkim    ACPI_FUNCTION_TRACE (TbValidateTable);
468263851Sjkim
469263851Sjkim
470263851Sjkim    /* Validate the table if necessary */
471263851Sjkim
472263851Sjkim    if (!TableDesc->Pointer)
473263851Sjkim    {
474263851Sjkim        Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer,
475298714Sjkim            &TableDesc->Length, &TableDesc->Flags);
476263851Sjkim        if (!TableDesc->Pointer)
477263851Sjkim        {
478263851Sjkim            Status = AE_NO_MEMORY;
479263851Sjkim        }
480263851Sjkim    }
481263851Sjkim
482263851Sjkim    return_ACPI_STATUS (Status);
483263851Sjkim}
484263851Sjkim
485263851Sjkim
486263851Sjkim/*******************************************************************************
487263851Sjkim *
488263851Sjkim * FUNCTION:    AcpiTbInvalidateTable
489263851Sjkim *
490263851Sjkim * PARAMETERS:  TableDesc           - Table descriptor
491263851Sjkim *
492263851Sjkim * RETURN:      None
493263851Sjkim *
494263851Sjkim * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
495263851Sjkim *              AcpiTbValidateTable().
496263851Sjkim *
497263851Sjkim ******************************************************************************/
498263851Sjkim
499263851Sjkimvoid
500263851SjkimAcpiTbInvalidateTable (
501263851Sjkim    ACPI_TABLE_DESC         *TableDesc)
502263851Sjkim{
503263851Sjkim
504263851Sjkim    ACPI_FUNCTION_TRACE (TbInvalidateTable);
505263851Sjkim
506263851Sjkim
507263851Sjkim    /* Table must be validated */
508263851Sjkim
509263851Sjkim    if (!TableDesc->Pointer)
510263851Sjkim    {
511263851Sjkim        return_VOID;
512263851Sjkim    }
513263851Sjkim
514263851Sjkim    AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length,
515263851Sjkim        TableDesc->Flags);
516263851Sjkim    TableDesc->Pointer = NULL;
517263851Sjkim
518263851Sjkim    return_VOID;
519263851Sjkim}
520263851Sjkim
521263851Sjkim
522263851Sjkim/******************************************************************************
523263851Sjkim *
524272444Sjkim * FUNCTION:    AcpiTbValidateTempTable
525263851Sjkim *
526263851Sjkim * PARAMETERS:  TableDesc           - Table descriptor
527272444Sjkim *
528272444Sjkim * RETURN:      Status
529272444Sjkim *
530272444Sjkim * DESCRIPTION: This function is called to validate the table, the returned
531272444Sjkim *              table descriptor is in "VALIDATED" state.
532272444Sjkim *
533272444Sjkim *****************************************************************************/
534272444Sjkim
535272444SjkimACPI_STATUS
536272444SjkimAcpiTbValidateTempTable (
537272444Sjkim    ACPI_TABLE_DESC         *TableDesc)
538272444Sjkim{
539272444Sjkim
540322877Sjkim    if (!TableDesc->Pointer && !AcpiGbl_EnableTableValidation)
541272444Sjkim    {
542272444Sjkim        /*
543272444Sjkim         * Only validates the header of the table.
544272444Sjkim         * Note that Length contains the size of the mapping after invoking
545272444Sjkim         * this work around, this value is required by
546272444Sjkim         * AcpiTbReleaseTempTable().
547272444Sjkim         * We can do this because in AcpiInitTableDescriptor(), the Length
548272444Sjkim         * field of the installed descriptor is filled with the actual
549272444Sjkim         * table length obtaining from the table header.
550272444Sjkim         */
551272444Sjkim        TableDesc->Length = sizeof (ACPI_TABLE_HEADER);
552272444Sjkim    }
553272444Sjkim
554272444Sjkim    return (AcpiTbValidateTable (TableDesc));
555272444Sjkim}
556272444Sjkim
557272444Sjkim
558322877Sjkim/*******************************************************************************
559322877Sjkim *
560322877Sjkim * FUNCTION:    AcpiTbCheckDuplication
561322877Sjkim *
562322877Sjkim * PARAMETERS:  TableDesc           - Table descriptor
563322877Sjkim *              TableIndex          - Where the table index is returned
564322877Sjkim *
565322877Sjkim * RETURN:      Status
566322877Sjkim *
567322877Sjkim * DESCRIPTION: Avoid installing duplicated tables. However table override and
568322877Sjkim *              user aided dynamic table load is allowed, thus comparing the
569322877Sjkim *              address of the table is not sufficient, and checking the entire
570322877Sjkim *              table content is required.
571322877Sjkim *
572322877Sjkim ******************************************************************************/
573322877Sjkim
574322877Sjkimstatic ACPI_STATUS
575322877SjkimAcpiTbCheckDuplication (
576322877Sjkim    ACPI_TABLE_DESC         *TableDesc,
577322877Sjkim    UINT32                  *TableIndex)
578322877Sjkim{
579322877Sjkim    UINT32                  i;
580322877Sjkim
581322877Sjkim
582322877Sjkim    ACPI_FUNCTION_TRACE (TbCheckDuplication);
583322877Sjkim
584322877Sjkim
585322877Sjkim    /* Check if table is already registered */
586322877Sjkim
587322877Sjkim    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
588322877Sjkim    {
589322877Sjkim        /* Do not compare with unverified tables */
590322877Sjkim
591322877Sjkim        if (!(AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_VERIFIED))
592322877Sjkim        {
593322877Sjkim            continue;
594322877Sjkim        }
595322877Sjkim
596322877Sjkim        /*
597322877Sjkim         * Check for a table match on the entire table length,
598322877Sjkim         * not just the header.
599322877Sjkim         */
600322877Sjkim        if (!AcpiTbCompareTables (TableDesc, i))
601322877Sjkim        {
602322877Sjkim            continue;
603322877Sjkim        }
604322877Sjkim
605322877Sjkim        /*
606322877Sjkim         * Note: the current mechanism does not unregister a table if it is
607322877Sjkim         * dynamically unloaded. The related namespace entries are deleted,
608322877Sjkim         * but the table remains in the root table list.
609322877Sjkim         *
610322877Sjkim         * The assumption here is that the number of different tables that
611322877Sjkim         * will be loaded is actually small, and there is minimal overhead
612322877Sjkim         * in just keeping the table in case it is needed again.
613322877Sjkim         *
614322877Sjkim         * If this assumption changes in the future (perhaps on large
615322877Sjkim         * machines with many table load/unload operations), tables will
616322877Sjkim         * need to be unregistered when they are unloaded, and slots in the
617322877Sjkim         * root table list should be reused when empty.
618322877Sjkim         */
619322877Sjkim        if (AcpiGbl_RootTableList.Tables[i].Flags &
620322877Sjkim            ACPI_TABLE_IS_LOADED)
621322877Sjkim        {
622322877Sjkim            /* Table is still loaded, this is an error */
623322877Sjkim
624322877Sjkim            return_ACPI_STATUS (AE_ALREADY_EXISTS);
625322877Sjkim        }
626322877Sjkim        else
627322877Sjkim        {
628322877Sjkim            *TableIndex = i;
629322877Sjkim            return_ACPI_STATUS (AE_CTRL_TERMINATE);
630322877Sjkim        }
631322877Sjkim    }
632322877Sjkim
633322877Sjkim    /* Indicate no duplication to the caller */
634322877Sjkim
635322877Sjkim    return_ACPI_STATUS (AE_OK);
636322877Sjkim}
637322877Sjkim
638322877Sjkim
639272444Sjkim/******************************************************************************
640272444Sjkim *
641272444Sjkim * FUNCTION:    AcpiTbVerifyTempTable
642272444Sjkim *
643272444Sjkim * PARAMETERS:  TableDesc           - Table descriptor
644263851Sjkim *              Signature           - Table signature to verify
645322877Sjkim *              TableIndex          - Where the table index is returned
646263851Sjkim *
647263851Sjkim * RETURN:      Status
648263851Sjkim *
649263851Sjkim * DESCRIPTION: This function is called to validate and verify the table, the
650263851Sjkim *              returned table descriptor is in "VALIDATED" state.
651322877Sjkim *              Note that 'TableIndex' is required to be set to !NULL to
652322877Sjkim *              enable duplication check.
653263851Sjkim *
654263851Sjkim *****************************************************************************/
655263851Sjkim
656263851SjkimACPI_STATUS
657272444SjkimAcpiTbVerifyTempTable (
658263851Sjkim    ACPI_TABLE_DESC         *TableDesc,
659322877Sjkim    char                    *Signature,
660322877Sjkim    UINT32                  *TableIndex)
661263851Sjkim{
662263851Sjkim    ACPI_STATUS             Status = AE_OK;
663263851Sjkim
664263851Sjkim
665272444Sjkim    ACPI_FUNCTION_TRACE (TbVerifyTempTable);
666263851Sjkim
667263851Sjkim
668263851Sjkim    /* Validate the table */
669263851Sjkim
670272444Sjkim    Status = AcpiTbValidateTempTable (TableDesc);
671263851Sjkim    if (ACPI_FAILURE (Status))
672263851Sjkim    {
673263851Sjkim        return_ACPI_STATUS (AE_NO_MEMORY);
674263851Sjkim    }
675263851Sjkim
676263851Sjkim    /* If a particular signature is expected (DSDT/FACS), it must match */
677263851Sjkim
678263851Sjkim    if (Signature &&
679263851Sjkim        !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
680263851Sjkim    {
681263851Sjkim        ACPI_BIOS_ERROR ((AE_INFO,
682263851Sjkim            "Invalid signature 0x%X for ACPI table, expected [%s]",
683263851Sjkim            TableDesc->Signature.Integer, Signature));
684263851Sjkim        Status = AE_BAD_SIGNATURE;
685263851Sjkim        goto InvalidateAndExit;
686263851Sjkim    }
687263851Sjkim
688322877Sjkim    if (AcpiGbl_EnableTableValidation)
689322877Sjkim    {
690322877Sjkim        /* Verify the checksum */
691263851Sjkim
692272444Sjkim        Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
693272444Sjkim        if (ACPI_FAILURE (Status))
694272444Sjkim        {
695272444Sjkim            ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
696281396Sjkim                "%4.4s 0x%8.8X%8.8X"
697272444Sjkim                " Attempted table install failed",
698298714Sjkim                AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
699272444Sjkim                    TableDesc->Signature.Ascii : "????",
700281396Sjkim                ACPI_FORMAT_UINT64 (TableDesc->Address)));
701298714Sjkim
702272444Sjkim            goto InvalidateAndExit;
703272444Sjkim        }
704322877Sjkim
705322877Sjkim        /* Avoid duplications */
706322877Sjkim
707322877Sjkim        if (TableIndex)
708322877Sjkim        {
709322877Sjkim            Status = AcpiTbCheckDuplication (TableDesc, TableIndex);
710322877Sjkim            if (ACPI_FAILURE (Status))
711322877Sjkim            {
712322877Sjkim                if (Status != AE_CTRL_TERMINATE)
713322877Sjkim                {
714322877Sjkim                    ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
715322877Sjkim                        "%4.4s 0x%8.8X%8.8X"
716322877Sjkim                        " Table is duplicated",
717322877Sjkim                        AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
718322877Sjkim                            TableDesc->Signature.Ascii : "????",
719322877Sjkim                        ACPI_FORMAT_UINT64 (TableDesc->Address)));
720322877Sjkim                }
721322877Sjkim
722322877Sjkim                goto InvalidateAndExit;
723322877Sjkim            }
724322877Sjkim        }
725322877Sjkim
726322877Sjkim        TableDesc->Flags |= ACPI_TABLE_IS_VERIFIED;
727263851Sjkim    }
728263851Sjkim
729322877Sjkim    return_ACPI_STATUS (Status);
730263851Sjkim
731263851SjkimInvalidateAndExit:
732263851Sjkim    AcpiTbInvalidateTable (TableDesc);
733263851Sjkim    return_ACPI_STATUS (Status);
734263851Sjkim}
735263851Sjkim
736263851Sjkim
737263851Sjkim/*******************************************************************************
738263851Sjkim *
739263851Sjkim * FUNCTION:    AcpiTbResizeRootTableList
740263851Sjkim *
741263851Sjkim * PARAMETERS:  None
742263851Sjkim *
743263851Sjkim * RETURN:      Status
744263851Sjkim *
745263851Sjkim * DESCRIPTION: Expand the size of global table array
746263851Sjkim *
747263851Sjkim ******************************************************************************/
748263851Sjkim
749263851SjkimACPI_STATUS
750263851SjkimAcpiTbResizeRootTableList (
751263851Sjkim    void)
752263851Sjkim{
753263851Sjkim    ACPI_TABLE_DESC         *Tables;
754263851Sjkim    UINT32                  TableCount;
755322877Sjkim    UINT32                  CurrentTableCount, MaxTableCount;
756322877Sjkim    UINT32                  i;
757263851Sjkim
758263851Sjkim
759263851Sjkim    ACPI_FUNCTION_TRACE (TbResizeRootTableList);
760263851Sjkim
761263851Sjkim
762263851Sjkim    /* AllowResize flag is a parameter to AcpiInitializeTables */
763263851Sjkim
764263851Sjkim    if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
765263851Sjkim    {
766263851Sjkim        ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
767263851Sjkim        return_ACPI_STATUS (AE_SUPPORT);
768263851Sjkim    }
769263851Sjkim
770263851Sjkim    /* Increase the Table Array size */
771263851Sjkim
772263851Sjkim    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
773263851Sjkim    {
774263851Sjkim        TableCount = AcpiGbl_RootTableList.MaxTableCount;
775263851Sjkim    }
776263851Sjkim    else
777263851Sjkim    {
778263851Sjkim        TableCount = AcpiGbl_RootTableList.CurrentTableCount;
779263851Sjkim    }
780263851Sjkim
781322877Sjkim    MaxTableCount = TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
782263851Sjkim    Tables = ACPI_ALLOCATE_ZEROED (
783322877Sjkim        ((ACPI_SIZE) MaxTableCount) * sizeof (ACPI_TABLE_DESC));
784263851Sjkim    if (!Tables)
785263851Sjkim    {
786263851Sjkim        ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
787263851Sjkim        return_ACPI_STATUS (AE_NO_MEMORY);
788263851Sjkim    }
789263851Sjkim
790263851Sjkim    /* Copy and free the previous table array */
791263851Sjkim
792322877Sjkim    CurrentTableCount = 0;
793263851Sjkim    if (AcpiGbl_RootTableList.Tables)
794263851Sjkim    {
795322877Sjkim        for (i = 0; i < TableCount; i++)
796322877Sjkim        {
797322877Sjkim            if (AcpiGbl_RootTableList.Tables[i].Address)
798322877Sjkim            {
799322877Sjkim                memcpy (Tables + CurrentTableCount,
800322877Sjkim                    AcpiGbl_RootTableList.Tables + i,
801322877Sjkim                    sizeof (ACPI_TABLE_DESC));
802322877Sjkim                CurrentTableCount++;
803322877Sjkim            }
804322877Sjkim        }
805263851Sjkim
806263851Sjkim        if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
807263851Sjkim        {
808263851Sjkim            ACPI_FREE (AcpiGbl_RootTableList.Tables);
809263851Sjkim        }
810263851Sjkim    }
811263851Sjkim
812263851Sjkim    AcpiGbl_RootTableList.Tables = Tables;
813322877Sjkim    AcpiGbl_RootTableList.MaxTableCount = MaxTableCount;
814322877Sjkim    AcpiGbl_RootTableList.CurrentTableCount = CurrentTableCount;
815263851Sjkim    AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
816263851Sjkim
817263851Sjkim    return_ACPI_STATUS (AE_OK);
818263851Sjkim}
819263851Sjkim
820263851Sjkim
821263851Sjkim/*******************************************************************************
822263851Sjkim *
823281396Sjkim * FUNCTION:    AcpiTbGetNextTableDescriptor
824263851Sjkim *
825263851Sjkim * PARAMETERS:  TableIndex          - Where table index is returned
826281396Sjkim *              TableDesc           - Where table descriptor is returned
827263851Sjkim *
828281396Sjkim * RETURN:      Status and table index/descriptor.
829263851Sjkim *
830263851Sjkim * DESCRIPTION: Allocate a new ACPI table entry to the global table list
831263851Sjkim *
832263851Sjkim ******************************************************************************/
833263851Sjkim
834263851SjkimACPI_STATUS
835281396SjkimAcpiTbGetNextTableDescriptor (
836281396Sjkim    UINT32                  *TableIndex,
837281396Sjkim    ACPI_TABLE_DESC         **TableDesc)
838263851Sjkim{
839263851Sjkim    ACPI_STATUS             Status;
840281396Sjkim    UINT32                  i;
841263851Sjkim
842263851Sjkim
843263851Sjkim    /* Ensure that there is room for the table in the Root Table List */
844263851Sjkim
845263851Sjkim    if (AcpiGbl_RootTableList.CurrentTableCount >=
846263851Sjkim        AcpiGbl_RootTableList.MaxTableCount)
847263851Sjkim    {
848263851Sjkim        Status = AcpiTbResizeRootTableList();
849263851Sjkim        if (ACPI_FAILURE (Status))
850263851Sjkim        {
851263851Sjkim            return (Status);
852263851Sjkim        }
853263851Sjkim    }
854263851Sjkim
855281396Sjkim    i = AcpiGbl_RootTableList.CurrentTableCount;
856263851Sjkim    AcpiGbl_RootTableList.CurrentTableCount++;
857281396Sjkim
858281396Sjkim    if (TableIndex)
859281396Sjkim    {
860281396Sjkim        *TableIndex = i;
861281396Sjkim    }
862281396Sjkim    if (TableDesc)
863281396Sjkim    {
864281396Sjkim        *TableDesc = &AcpiGbl_RootTableList.Tables[i];
865281396Sjkim    }
866281396Sjkim
867263851Sjkim    return (AE_OK);
868263851Sjkim}
869263851Sjkim
870263851Sjkim
871263851Sjkim/*******************************************************************************
872263851Sjkim *
873263851Sjkim * FUNCTION:    AcpiTbTerminate
874263851Sjkim *
875263851Sjkim * PARAMETERS:  None
876263851Sjkim *
877263851Sjkim * RETURN:      None
878263851Sjkim *
879263851Sjkim * DESCRIPTION: Delete all internal ACPI tables
880263851Sjkim *
881263851Sjkim ******************************************************************************/
882263851Sjkim
883263851Sjkimvoid
884263851SjkimAcpiTbTerminate (
885263851Sjkim    void)
886263851Sjkim{
887263851Sjkim    UINT32                  i;
888263851Sjkim
889263851Sjkim
890263851Sjkim    ACPI_FUNCTION_TRACE (TbTerminate);
891263851Sjkim
892263851Sjkim
893263851Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
894263851Sjkim
895263851Sjkim    /* Delete the individual tables */
896263851Sjkim
897263851Sjkim    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
898263851Sjkim    {
899263851Sjkim        AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]);
900263851Sjkim    }
901263851Sjkim
902263851Sjkim    /*
903263851Sjkim     * Delete the root table array if allocated locally. Array cannot be
904263851Sjkim     * mapped, so we don't need to check for that flag.
905263851Sjkim     */
906263851Sjkim    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
907263851Sjkim    {
908263851Sjkim        ACPI_FREE (AcpiGbl_RootTableList.Tables);
909263851Sjkim    }
910263851Sjkim
911263851Sjkim    AcpiGbl_RootTableList.Tables = NULL;
912263851Sjkim    AcpiGbl_RootTableList.Flags = 0;
913263851Sjkim    AcpiGbl_RootTableList.CurrentTableCount = 0;
914263851Sjkim
915263851Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
916263851Sjkim
917263851Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
918263851Sjkim    return_VOID;
919263851Sjkim}
920263851Sjkim
921263851Sjkim
922263851Sjkim/*******************************************************************************
923263851Sjkim *
924263851Sjkim * FUNCTION:    AcpiTbDeleteNamespaceByOwner
925263851Sjkim *
926263851Sjkim * PARAMETERS:  TableIndex          - Table index
927263851Sjkim *
928263851Sjkim * RETURN:      Status
929263851Sjkim *
930263851Sjkim * DESCRIPTION: Delete all namespace objects created when this table was loaded.
931263851Sjkim *
932263851Sjkim ******************************************************************************/
933263851Sjkim
934263851SjkimACPI_STATUS
935263851SjkimAcpiTbDeleteNamespaceByOwner (
936263851Sjkim    UINT32                  TableIndex)
937263851Sjkim{
938263851Sjkim    ACPI_OWNER_ID           OwnerId;
939263851Sjkim    ACPI_STATUS             Status;
940263851Sjkim
941263851Sjkim
942263851Sjkim    ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
943263851Sjkim
944263851Sjkim
945263851Sjkim    Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
946263851Sjkim    if (ACPI_FAILURE (Status))
947263851Sjkim    {
948263851Sjkim        return_ACPI_STATUS (Status);
949263851Sjkim    }
950263851Sjkim
951263851Sjkim    if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
952263851Sjkim    {
953263851Sjkim        /* The table index does not exist */
954263851Sjkim
955263851Sjkim        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
956263851Sjkim        return_ACPI_STATUS (AE_NOT_EXIST);
957263851Sjkim    }
958263851Sjkim
959263851Sjkim    /* Get the owner ID for this table, used to delete namespace nodes */
960263851Sjkim
961263851Sjkim    OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
962263851Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
963263851Sjkim
964263851Sjkim    /*
965263851Sjkim     * Need to acquire the namespace writer lock to prevent interference
966263851Sjkim     * with any concurrent namespace walks. The interpreter must be
967263851Sjkim     * released during the deletion since the acquisition of the deletion
968263851Sjkim     * lock may block, and also since the execution of a namespace walk
969263851Sjkim     * must be allowed to use the interpreter.
970263851Sjkim     */
971263851Sjkim    Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
972263851Sjkim    if (ACPI_FAILURE (Status))
973263851Sjkim    {
974263851Sjkim        return_ACPI_STATUS (Status);
975263851Sjkim    }
976316303Sjkim    AcpiNsDeleteNamespaceByOwner (OwnerId);
977263851Sjkim    AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
978263851Sjkim    return_ACPI_STATUS (Status);
979263851Sjkim}
980263851Sjkim
981263851Sjkim
982263851Sjkim/*******************************************************************************
983263851Sjkim *
984263851Sjkim * FUNCTION:    AcpiTbAllocateOwnerId
985263851Sjkim *
986263851Sjkim * PARAMETERS:  TableIndex          - Table index
987263851Sjkim *
988263851Sjkim * RETURN:      Status
989263851Sjkim *
990263851Sjkim * DESCRIPTION: Allocates OwnerId in TableDesc
991263851Sjkim *
992263851Sjkim ******************************************************************************/
993263851Sjkim
994263851SjkimACPI_STATUS
995263851SjkimAcpiTbAllocateOwnerId (
996263851Sjkim    UINT32                  TableIndex)
997263851Sjkim{
998263851Sjkim    ACPI_STATUS             Status = AE_BAD_PARAMETER;
999263851Sjkim
1000263851Sjkim
1001263851Sjkim    ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
1002263851Sjkim
1003263851Sjkim
1004263851Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1005263851Sjkim    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1006263851Sjkim    {
1007263851Sjkim        Status = AcpiUtAllocateOwnerId (
1008298714Sjkim            &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
1009263851Sjkim    }
1010263851Sjkim
1011263851Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1012263851Sjkim    return_ACPI_STATUS (Status);
1013263851Sjkim}
1014263851Sjkim
1015263851Sjkim
1016263851Sjkim/*******************************************************************************
1017263851Sjkim *
1018263851Sjkim * FUNCTION:    AcpiTbReleaseOwnerId
1019263851Sjkim *
1020263851Sjkim * PARAMETERS:  TableIndex          - Table index
1021263851Sjkim *
1022263851Sjkim * RETURN:      Status
1023263851Sjkim *
1024263851Sjkim * DESCRIPTION: Releases OwnerId in TableDesc
1025263851Sjkim *
1026263851Sjkim ******************************************************************************/
1027263851Sjkim
1028263851SjkimACPI_STATUS
1029263851SjkimAcpiTbReleaseOwnerId (
1030263851Sjkim    UINT32                  TableIndex)
1031263851Sjkim{
1032263851Sjkim    ACPI_STATUS             Status = AE_BAD_PARAMETER;
1033263851Sjkim
1034263851Sjkim
1035263851Sjkim    ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
1036263851Sjkim
1037263851Sjkim
1038263851Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1039263851Sjkim    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1040263851Sjkim    {
1041263851Sjkim        AcpiUtReleaseOwnerId (
1042263851Sjkim            &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
1043263851Sjkim        Status = AE_OK;
1044263851Sjkim    }
1045263851Sjkim
1046263851Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1047263851Sjkim    return_ACPI_STATUS (Status);
1048263851Sjkim}
1049263851Sjkim
1050263851Sjkim
1051263851Sjkim/*******************************************************************************
1052263851Sjkim *
1053263851Sjkim * FUNCTION:    AcpiTbGetOwnerId
1054263851Sjkim *
1055263851Sjkim * PARAMETERS:  TableIndex          - Table index
1056263851Sjkim *              OwnerId             - Where the table OwnerId is returned
1057263851Sjkim *
1058263851Sjkim * RETURN:      Status
1059263851Sjkim *
1060263851Sjkim * DESCRIPTION: returns OwnerId for the ACPI table
1061263851Sjkim *
1062263851Sjkim ******************************************************************************/
1063263851Sjkim
1064263851SjkimACPI_STATUS
1065263851SjkimAcpiTbGetOwnerId (
1066263851Sjkim    UINT32                  TableIndex,
1067263851Sjkim    ACPI_OWNER_ID           *OwnerId)
1068263851Sjkim{
1069263851Sjkim    ACPI_STATUS             Status = AE_BAD_PARAMETER;
1070263851Sjkim
1071263851Sjkim
1072263851Sjkim    ACPI_FUNCTION_TRACE (TbGetOwnerId);
1073263851Sjkim
1074263851Sjkim
1075263851Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1076263851Sjkim    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1077263851Sjkim    {
1078263851Sjkim        *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
1079263851Sjkim        Status = AE_OK;
1080263851Sjkim    }
1081263851Sjkim
1082263851Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1083263851Sjkim    return_ACPI_STATUS (Status);
1084263851Sjkim}
1085263851Sjkim
1086263851Sjkim
1087263851Sjkim/*******************************************************************************
1088263851Sjkim *
1089263851Sjkim * FUNCTION:    AcpiTbIsTableLoaded
1090263851Sjkim *
1091263851Sjkim * PARAMETERS:  TableIndex          - Index into the root table
1092263851Sjkim *
1093263851Sjkim * RETURN:      Table Loaded Flag
1094263851Sjkim *
1095263851Sjkim ******************************************************************************/
1096263851Sjkim
1097263851SjkimBOOLEAN
1098263851SjkimAcpiTbIsTableLoaded (
1099263851Sjkim    UINT32                  TableIndex)
1100263851Sjkim{
1101263851Sjkim    BOOLEAN                 IsLoaded = FALSE;
1102263851Sjkim
1103263851Sjkim
1104263851Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1105263851Sjkim    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1106263851Sjkim    {
1107263851Sjkim        IsLoaded = (BOOLEAN)
1108263851Sjkim            (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
1109263851Sjkim            ACPI_TABLE_IS_LOADED);
1110263851Sjkim    }
1111263851Sjkim
1112263851Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1113263851Sjkim    return (IsLoaded);
1114263851Sjkim}
1115263851Sjkim
1116263851Sjkim
1117263851Sjkim/*******************************************************************************
1118263851Sjkim *
1119263851Sjkim * FUNCTION:    AcpiTbSetTableLoadedFlag
1120263851Sjkim *
1121263851Sjkim * PARAMETERS:  TableIndex          - Table index
1122263851Sjkim *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
1123263851Sjkim *
1124263851Sjkim * RETURN:      None
1125263851Sjkim *
1126263851Sjkim * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
1127263851Sjkim *
1128263851Sjkim ******************************************************************************/
1129263851Sjkim
1130263851Sjkimvoid
1131263851SjkimAcpiTbSetTableLoadedFlag (
1132263851Sjkim    UINT32                  TableIndex,
1133263851Sjkim    BOOLEAN                 IsLoaded)
1134263851Sjkim{
1135263851Sjkim
1136263851Sjkim    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1137263851Sjkim    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
1138263851Sjkim    {
1139263851Sjkim        if (IsLoaded)
1140263851Sjkim        {
1141263851Sjkim            AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
1142263851Sjkim                ACPI_TABLE_IS_LOADED;
1143263851Sjkim        }
1144263851Sjkim        else
1145263851Sjkim        {
1146263851Sjkim            AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
1147263851Sjkim                ~ACPI_TABLE_IS_LOADED;
1148263851Sjkim        }
1149263851Sjkim    }
1150263851Sjkim
1151263851Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1152263851Sjkim}
1153316303Sjkim
1154316303Sjkim
1155316303Sjkim/*******************************************************************************
1156316303Sjkim *
1157316303Sjkim * FUNCTION:    AcpiTbLoadTable
1158316303Sjkim *
1159316303Sjkim * PARAMETERS:  TableIndex              - Table index
1160316303Sjkim *              ParentNode              - Where table index is returned
1161316303Sjkim *
1162316303Sjkim * RETURN:      Status
1163316303Sjkim *
1164316303Sjkim * DESCRIPTION: Load an ACPI table
1165316303Sjkim *
1166316303Sjkim ******************************************************************************/
1167316303Sjkim
1168316303SjkimACPI_STATUS
1169316303SjkimAcpiTbLoadTable (
1170316303Sjkim    UINT32                  TableIndex,
1171316303Sjkim    ACPI_NAMESPACE_NODE     *ParentNode)
1172316303Sjkim{
1173316303Sjkim    ACPI_TABLE_HEADER       *Table;
1174316303Sjkim    ACPI_STATUS             Status;
1175316303Sjkim    ACPI_OWNER_ID           OwnerId;
1176316303Sjkim
1177316303Sjkim
1178316303Sjkim    ACPI_FUNCTION_TRACE (TbLoadTable);
1179316303Sjkim
1180316303Sjkim
1181316303Sjkim    /*
1182316303Sjkim     * Note: Now table is "INSTALLED", it must be validated before
1183316303Sjkim     * using.
1184316303Sjkim     */
1185316303Sjkim    Status = AcpiGetTableByIndex (TableIndex, &Table);
1186316303Sjkim    if (ACPI_FAILURE (Status))
1187316303Sjkim    {
1188316303Sjkim        return_ACPI_STATUS (Status);
1189316303Sjkim    }
1190316303Sjkim
1191316303Sjkim    Status = AcpiNsLoadTable (TableIndex, ParentNode);
1192316303Sjkim
1193316303Sjkim    /* Execute any module-level code that was found in the table */
1194316303Sjkim
1195316303Sjkim    if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
1196316303Sjkim    {
1197316303Sjkim        AcpiNsExecModuleCodeList ();
1198316303Sjkim    }
1199316303Sjkim
1200316303Sjkim    /*
1201316303Sjkim     * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
1202316303Sjkim     * responsible for discovering any new wake GPEs by running _PRW methods
1203316303Sjkim     * that may have been loaded by this table.
1204316303Sjkim     */
1205316303Sjkim    Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
1206316303Sjkim    if (ACPI_SUCCESS (Status))
1207316303Sjkim    {
1208316303Sjkim        AcpiEvUpdateGpes (OwnerId);
1209316303Sjkim    }
1210316303Sjkim
1211322877Sjkim    /* Invoke table handler */
1212316303Sjkim
1213322877Sjkim    AcpiTbNotifyTable (ACPI_TABLE_EVENT_LOAD, Table);
1214316303Sjkim    return_ACPI_STATUS (Status);
1215316303Sjkim}
1216316303Sjkim
1217316303Sjkim
1218316303Sjkim/*******************************************************************************
1219316303Sjkim *
1220316303Sjkim * FUNCTION:    AcpiTbInstallAndLoadTable
1221316303Sjkim *
1222316303Sjkim * PARAMETERS:  Address                 - Physical address of the table
1223316303Sjkim *              Flags                   - Allocation flags of the table
1224316303Sjkim *              Override                - Whether override should be performed
1225316303Sjkim *              TableIndex              - Where table index is returned
1226316303Sjkim *
1227316303Sjkim * RETURN:      Status
1228316303Sjkim *
1229316303Sjkim * DESCRIPTION: Install and load an ACPI table
1230316303Sjkim *
1231316303Sjkim ******************************************************************************/
1232316303Sjkim
1233316303SjkimACPI_STATUS
1234316303SjkimAcpiTbInstallAndLoadTable (
1235316303Sjkim    ACPI_PHYSICAL_ADDRESS   Address,
1236316303Sjkim    UINT8                   Flags,
1237316303Sjkim    BOOLEAN                 Override,
1238316303Sjkim    UINT32                  *TableIndex)
1239316303Sjkim{
1240316303Sjkim    ACPI_STATUS             Status;
1241316303Sjkim    UINT32                  i;
1242316303Sjkim
1243316303Sjkim
1244316303Sjkim    ACPI_FUNCTION_TRACE (TbInstallAndLoadTable);
1245316303Sjkim
1246316303Sjkim
1247316303Sjkim    /* Install the table and load it into the namespace */
1248316303Sjkim
1249316303Sjkim    Status = AcpiTbInstallStandardTable (Address, Flags, TRUE,
1250316303Sjkim        Override, &i);
1251316303Sjkim    if (ACPI_FAILURE (Status))
1252316303Sjkim    {
1253322877Sjkim        goto Exit;
1254316303Sjkim    }
1255316303Sjkim
1256316303Sjkim    Status = AcpiTbLoadTable (i, AcpiGbl_RootNode);
1257316303Sjkim
1258322877SjkimExit:
1259316303Sjkim    *TableIndex = i;
1260316303Sjkim    return_ACPI_STATUS (Status);
1261316303Sjkim}
1262316303Sjkim
1263316303Sjkim
1264316303Sjkim/*******************************************************************************
1265316303Sjkim *
1266316303Sjkim * FUNCTION:    AcpiTbUnloadTable
1267316303Sjkim *
1268316303Sjkim * PARAMETERS:  TableIndex              - Table index
1269316303Sjkim *
1270316303Sjkim * RETURN:      Status
1271316303Sjkim *
1272316303Sjkim * DESCRIPTION: Unload an ACPI table
1273316303Sjkim *
1274316303Sjkim ******************************************************************************/
1275316303Sjkim
1276316303SjkimACPI_STATUS
1277316303SjkimAcpiTbUnloadTable (
1278316303Sjkim    UINT32                  TableIndex)
1279316303Sjkim{
1280316303Sjkim    ACPI_STATUS             Status = AE_OK;
1281316303Sjkim    ACPI_TABLE_HEADER       *Table;
1282316303Sjkim
1283316303Sjkim
1284316303Sjkim    ACPI_FUNCTION_TRACE (TbUnloadTable);
1285316303Sjkim
1286316303Sjkim
1287316303Sjkim    /* Ensure the table is still loaded */
1288316303Sjkim
1289316303Sjkim    if (!AcpiTbIsTableLoaded (TableIndex))
1290316303Sjkim    {
1291316303Sjkim        return_ACPI_STATUS (AE_NOT_EXIST);
1292316303Sjkim    }
1293316303Sjkim
1294322877Sjkim    /* Invoke table handler */
1295316303Sjkim
1296322877Sjkim    Status = AcpiGetTableByIndex (TableIndex, &Table);
1297322877Sjkim    if (ACPI_SUCCESS (Status))
1298316303Sjkim    {
1299322877Sjkim        AcpiTbNotifyTable (ACPI_TABLE_EVENT_UNLOAD, Table);
1300316303Sjkim    }
1301316303Sjkim
1302316303Sjkim    /* Delete the portion of the namespace owned by this table */
1303316303Sjkim
1304316303Sjkim    Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
1305316303Sjkim    if (ACPI_FAILURE (Status))
1306316303Sjkim    {
1307316303Sjkim        return_ACPI_STATUS (Status);
1308316303Sjkim    }
1309316303Sjkim
1310316303Sjkim    (void) AcpiTbReleaseOwnerId (TableIndex);
1311316303Sjkim    AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
1312316303Sjkim    return_ACPI_STATUS (Status);
1313316303Sjkim}
1314322877Sjkim
1315322877Sjkim
1316322877Sjkim/*******************************************************************************
1317322877Sjkim *
1318322877Sjkim * FUNCTION:    AcpiTbNotifyTable
1319322877Sjkim *
1320322877Sjkim * PARAMETERS:  Event               - Table event
1321322877Sjkim *              Table               - Validated table pointer
1322322877Sjkim *
1323322877Sjkim * RETURN:      None
1324322877Sjkim *
1325322877Sjkim * DESCRIPTION: Notify a table event to the users.
1326322877Sjkim *
1327322877Sjkim ******************************************************************************/
1328322877Sjkim
1329322877Sjkimvoid
1330322877SjkimAcpiTbNotifyTable (
1331322877Sjkim    UINT32                          Event,
1332322877Sjkim    void                            *Table)
1333322877Sjkim{
1334322877Sjkim    /* Invoke table handler if present */
1335322877Sjkim
1336322877Sjkim    if (AcpiGbl_TableHandler)
1337322877Sjkim    {
1338322877Sjkim        (void) AcpiGbl_TableHandler (Event, Table,
1339322877Sjkim            AcpiGbl_TableHandlerContext);
1340322877Sjkim    }
1341322877Sjkim}
1342