tbinstal.c revision 167802
1/******************************************************************************
2 *
3 * Module Name: tbinstal - ACPI table installation and removal
4 *              $Revision: 1.91 $
5 *
6 *****************************************************************************/
7
8/******************************************************************************
9 *
10 * 1. Copyright Notice
11 *
12 * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
13 * All rights reserved.
14 *
15 * 2. License
16 *
17 * 2.1. This is your license from Intel Corp. under its intellectual property
18 * rights.  You may have additional license terms from the party that provided
19 * you this software, covering your right to use that party's intellectual
20 * property rights.
21 *
22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23 * copy of the source code appearing in this file ("Covered Code") an
24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25 * base code distributed originally by Intel ("Original Intel Code") to copy,
26 * make derivatives, distribute, use and display any portion of the Covered
27 * Code in any form, with the right to sublicense such rights; and
28 *
29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30 * license (with the right to sublicense), under only those claims of Intel
31 * patents that are infringed by the Original Intel Code, to make, use, sell,
32 * offer to sell, and import the Covered Code and derivative works thereof
33 * solely to the minimum extent necessary to exercise the above copyright
34 * license, and in no event shall the patent license extend to any additions
35 * to or modifications of the Original Intel Code.  No other license or right
36 * is granted directly or by implication, estoppel or otherwise;
37 *
38 * The above copyright and patent license is granted only if the following
39 * conditions are met:
40 *
41 * 3. Conditions
42 *
43 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44 * Redistribution of source code of any substantial portion of the Covered
45 * Code or modification with rights to further distribute source must include
46 * the above Copyright Notice, the above License, this list of Conditions,
47 * and the following Disclaimer and Export Compliance provision.  In addition,
48 * Licensee must cause all Covered Code to which Licensee contributes to
49 * contain a file documenting the changes Licensee made to create that Covered
50 * Code and the date of any change.  Licensee must include in that file the
51 * documentation of any changes made by any predecessor Licensee.  Licensee
52 * must include a prominent statement that the modification is derived,
53 * directly or indirectly, from Original Intel Code.
54 *
55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56 * Redistribution of source code of any substantial portion of the Covered
57 * Code or modification without rights to further distribute source must
58 * include the following Disclaimer and Export Compliance provision in the
59 * documentation and/or other materials provided with distribution.  In
60 * addition, Licensee may not authorize further sublicense of source of any
61 * portion of the Covered Code, and must include terms to the effect that the
62 * license from Licensee to its licensee is limited to the intellectual
63 * property embodied in the software Licensee provides to its licensee, and
64 * not to intellectual property embodied in modifications its licensee may
65 * make.
66 *
67 * 3.3. Redistribution of Executable. Redistribution in executable form of any
68 * substantial portion of the Covered Code or modification must reproduce the
69 * above Copyright Notice, and the following Disclaimer and Export Compliance
70 * provision in the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3.4. Intel retains all right, title, and interest in and to the Original
74 * Intel Code.
75 *
76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77 * Intel shall be used in advertising or otherwise to promote the sale, use or
78 * other dealings in products derived from or relating to the Covered Code
79 * without prior written authorization from Intel.
80 *
81 * 4. Disclaimer and Export Compliance
82 *
83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89 * PARTICULAR PURPOSE.
90 *
91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98 * LIMITED REMEDY.
99 *
100 * 4.3. Licensee shall not export, either directly or indirectly, any of this
101 * software or system incorporating such software without first obtaining any
102 * required license or other approval from the U. S. Department of Commerce or
103 * any other agency or department of the United States Government.  In the
104 * event Licensee exports any such software from the United States or
105 * re-exports any such software from a foreign destination, Licensee shall
106 * ensure that the distribution and export/re-export of the software is in
107 * compliance with all laws, regulations, orders, or other restrictions of the
108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109 * any of its subsidiaries will export/re-export any technical data, process,
110 * software, or service, directly or indirectly, to any country for which the
111 * United States government or any agency thereof requires an export license,
112 * other governmental approval, or letter of assurance, without first obtaining
113 * such license, approval or letter.
114 *
115 *****************************************************************************/
116
117
118#define __TBINSTAL_C__
119
120#include <contrib/dev/acpica/acpi.h>
121#include <contrib/dev/acpica/acnamesp.h>
122#include <contrib/dev/acpica/actables.h>
123
124
125#define _COMPONENT          ACPI_TABLES
126        ACPI_MODULE_NAME    ("tbinstal")
127
128
129/******************************************************************************
130 *
131 * FUNCTION:    AcpiTbVerifyTable
132 *
133 * PARAMETERS:  TableDesc           - table
134 *
135 * RETURN:      Status
136 *
137 * DESCRIPTION: this function is called to verify and map table
138 *
139 *****************************************************************************/
140
141ACPI_STATUS
142AcpiTbVerifyTable (
143    ACPI_TABLE_DESC         *TableDesc)
144{
145    ACPI_STATUS             Status = AE_OK;
146
147
148    ACPI_FUNCTION_TRACE (TbVerifyTable);
149
150
151    /* Map the table if necessary */
152
153    if (!TableDesc->Pointer)
154    {
155        if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
156            ACPI_TABLE_ORIGIN_MAPPED)
157        {
158            TableDesc->Pointer = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length);
159        }
160
161        if (!TableDesc->Pointer)
162        {
163            return_ACPI_STATUS (AE_NO_MEMORY);
164        }
165    }
166
167    /* FACS is the odd table, has no standard ACPI header and no checksum */
168
169    if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
170    {
171        /* Always calculate checksum, ignore bad checksum if requested */
172
173        Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
174    }
175
176    return_ACPI_STATUS (Status);
177}
178
179
180/*******************************************************************************
181 *
182 * FUNCTION:    AcpiTbAddTable
183 *
184 * PARAMETERS:  TableDesc           - Table descriptor
185 *              TableIndex          - Where the table index is returned
186 *
187 * RETURN:      Status
188 *
189 * DESCRIPTION: This function is called to add the ACPI table
190 *
191 ******************************************************************************/
192
193ACPI_STATUS
194AcpiTbAddTable (
195    ACPI_TABLE_DESC         *TableDesc,
196    ACPI_NATIVE_UINT        *TableIndex)
197{
198    ACPI_NATIVE_UINT        i;
199    ACPI_NATIVE_UINT        Length;
200    ACPI_STATUS             Status = AE_OK;
201
202
203    ACPI_FUNCTION_TRACE (TbAddTable);
204
205
206    if (!TableDesc->Pointer)
207    {
208        Status = AcpiTbVerifyTable (TableDesc);
209        if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
210        {
211            return_ACPI_STATUS (Status);
212        }
213    }
214
215    /* The table must be either an SSDT or a PSDT */
216
217    if ((!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_PSDT)) &&
218        (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)))
219    {
220        ACPI_ERROR ((AE_INFO,
221            "Table has invalid signature [%4.4s], must be SSDT or PSDT",
222            TableDesc->Pointer->Signature));
223        return_ACPI_STATUS (AE_BAD_SIGNATURE);
224    }
225
226    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
227
228    /* Check if table is already registered */
229
230    for (i = 0; i < AcpiGbl_RootTableList.Count; ++i)
231    {
232        if (!AcpiGbl_RootTableList.Tables[i].Pointer)
233        {
234            Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
235            if (ACPI_FAILURE (Status) || !AcpiGbl_RootTableList.Tables[i].Pointer)
236            {
237                continue;
238            }
239        }
240
241        Length = ACPI_MIN (TableDesc->Length,
242                    AcpiGbl_RootTableList.Tables[i].Length);
243        if (ACPI_MEMCMP (TableDesc->Pointer,
244                AcpiGbl_RootTableList.Tables[i].Pointer, Length))
245        {
246            continue;
247        }
248
249        /* Table is already registered */
250
251        AcpiTbDeleteTable (TableDesc);
252        *TableIndex = i;
253        goto Release;
254    }
255
256    /*
257     * Add the table to the global table list
258     */
259    Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
260                TableDesc->Length, TableDesc->Flags, TableIndex);
261    if (ACPI_FAILURE (Status))
262    {
263        goto Release;
264    }
265
266    AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
267
268Release:
269    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
270    return_ACPI_STATUS (Status);
271}
272
273
274/*******************************************************************************
275 *
276 * FUNCTION:    AcpiTbResizeRootTableList
277 *
278 * PARAMETERS:  None
279 *
280 * RETURN:      Status
281 *
282 * DESCRIPTION: Expand the size of global table array
283 *
284 ******************************************************************************/
285
286ACPI_STATUS
287AcpiTbResizeRootTableList (
288    void)
289{
290    ACPI_TABLE_DESC         *Tables;
291
292
293    ACPI_FUNCTION_TRACE (TbResizeRootTableList);
294
295
296    /* AllowResize flag is a parameter to AcpiInitializeTables */
297
298    if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
299    {
300        ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
301        return_ACPI_STATUS (AE_SUPPORT);
302    }
303
304    /* Increase the Table Array size */
305
306    Tables = ACPI_ALLOCATE_ZEROED (
307                (AcpiGbl_RootTableList.Size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
308                * sizeof (ACPI_TABLE_DESC));
309    if (!Tables)
310    {
311        ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
312        return_ACPI_STATUS (AE_NO_MEMORY);
313    }
314
315    /* Copy and free the previous table array */
316
317    if (AcpiGbl_RootTableList.Tables)
318    {
319        ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
320            AcpiGbl_RootTableList.Size * sizeof (ACPI_TABLE_DESC));
321
322        if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
323        {
324            ACPI_FREE (AcpiGbl_RootTableList.Tables);
325        }
326    }
327
328    AcpiGbl_RootTableList.Tables = Tables;
329    AcpiGbl_RootTableList.Size += ACPI_ROOT_TABLE_SIZE_INCREMENT;
330    AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED;
331
332    return_ACPI_STATUS (AE_OK);
333}
334
335
336/*******************************************************************************
337 *
338 * FUNCTION:    AcpiTbStoreTable
339 *
340 * PARAMETERS:  Address             - Table address
341 *              Table               - Table header
342 *              Length              - Table length
343 *              Flags               - flags
344 *
345 * RETURN:      Status and table index.
346 *
347 * DESCRIPTION: Add an ACPI table to the global table list
348 *
349 ******************************************************************************/
350
351ACPI_STATUS
352AcpiTbStoreTable (
353    ACPI_PHYSICAL_ADDRESS   Address,
354    ACPI_TABLE_HEADER       *Table,
355    UINT32                  Length,
356    UINT8                   Flags,
357    ACPI_NATIVE_UINT        *TableIndex)
358{
359    ACPI_STATUS             Status = AE_OK;
360
361
362    /* Ensure that there is room for the table in the Root Table List */
363
364    if (AcpiGbl_RootTableList.Count >= AcpiGbl_RootTableList.Size)
365    {
366        Status = AcpiTbResizeRootTableList();
367        if (ACPI_FAILURE (Status))
368        {
369            return (Status);
370        }
371    }
372
373    /* Initialize added table */
374
375    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Address = Address;
376    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Pointer = Table;
377    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Length = Length;
378    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].OwnerId = 0;
379    AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Flags = Flags;
380
381    ACPI_MOVE_32_TO_32 (
382        &(AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.Count].Signature),
383        Table->Signature);
384
385    *TableIndex = AcpiGbl_RootTableList.Count;
386    AcpiGbl_RootTableList.Count++;
387    return (Status);
388}
389
390
391/*******************************************************************************
392 *
393 * FUNCTION:    AcpiTbDeleteTable
394 *
395 * PARAMETERS:  TableIndex          - Table index
396 *
397 * RETURN:      None
398 *
399 * DESCRIPTION: Delete one internal ACPI table
400 *
401 ******************************************************************************/
402
403void
404AcpiTbDeleteTable (
405    ACPI_TABLE_DESC         *TableDesc)
406{
407
408    /* Table must be mapped or allocated */
409
410    if (!TableDesc->Pointer)
411    {
412        return;
413    }
414
415    switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
416    {
417    case ACPI_TABLE_ORIGIN_MAPPED:
418        AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
419        break;
420
421    case ACPI_TABLE_ORIGIN_ALLOCATED:
422        ACPI_FREE (TableDesc->Pointer);
423        break;
424
425    default:
426        break;
427    }
428
429    TableDesc->Pointer = NULL;
430}
431
432
433/*******************************************************************************
434 *
435 * FUNCTION:    AcpiTbTerminate
436 *
437 * PARAMETERS:  None
438 *
439 * RETURN:      None
440 *
441 * DESCRIPTION: Delete all internal ACPI tables
442 *
443 ******************************************************************************/
444
445void
446AcpiTbTerminate (
447    void)
448{
449    ACPI_NATIVE_UINT        i;
450
451
452    ACPI_FUNCTION_TRACE (TbTerminate);
453
454
455    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
456
457    /* Delete the individual tables */
458
459    for (i = 0; i < AcpiGbl_RootTableList.Count; i++)
460    {
461        AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
462    }
463
464    /*
465     * Delete the root table array if allocated locally. Array cannot be
466     * mapped, so we don't need to check for that flag.
467     */
468    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
469    {
470        ACPI_FREE (AcpiGbl_RootTableList.Tables);
471    }
472
473    AcpiGbl_RootTableList.Tables = NULL;
474    AcpiGbl_RootTableList.Flags = 0;
475    AcpiGbl_RootTableList.Count = 0;
476
477    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
478    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
479}
480
481
482/*******************************************************************************
483 *
484 * FUNCTION:    AcpiTbDeleteNamespaceByOwner
485 *
486 * PARAMETERS:  TableIndex          - Table index
487 *
488 * RETURN:      None
489 *
490 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
491 *
492 ******************************************************************************/
493
494void
495AcpiTbDeleteNamespaceByOwner (
496    ACPI_NATIVE_UINT        TableIndex)
497{
498    ACPI_OWNER_ID           OwnerId;
499
500
501    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
502    if (TableIndex < AcpiGbl_RootTableList.Count)
503    {
504        OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
505    }
506    else
507    {
508        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
509        return;
510    }
511
512    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
513    AcpiNsDeleteNamespaceByOwner (OwnerId);
514}
515
516
517/*******************************************************************************
518 *
519 * FUNCTION:    AcpiTbAllocateOwnerId
520 *
521 * PARAMETERS:  TableIndex          - Table index
522 *
523 * RETURN:      Status
524 *
525 * DESCRIPTION: Allocates OwnerId in TableDesc
526 *
527 ******************************************************************************/
528
529ACPI_STATUS
530AcpiTbAllocateOwnerId (
531    ACPI_NATIVE_UINT        TableIndex)
532{
533    ACPI_STATUS             Status = AE_BAD_PARAMETER;
534
535
536    ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
537
538
539    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
540    if (TableIndex < AcpiGbl_RootTableList.Count)
541    {
542        Status = AcpiUtAllocateOwnerId
543                    (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
544    }
545
546    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
547    return_ACPI_STATUS (Status);
548}
549
550
551/*******************************************************************************
552 *
553 * FUNCTION:    AcpiTbReleaseOwnerId
554 *
555 * PARAMETERS:  TableIndex          - Table index
556 *
557 * RETURN:      Status
558 *
559 * DESCRIPTION: Releases OwnerId in TableDesc
560 *
561 ******************************************************************************/
562
563ACPI_STATUS
564AcpiTbReleaseOwnerId (
565    ACPI_NATIVE_UINT        TableIndex)
566{
567    ACPI_STATUS             Status = AE_BAD_PARAMETER;
568
569
570    ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
571
572
573    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
574    if (TableIndex < AcpiGbl_RootTableList.Count)
575    {
576        AcpiUtReleaseOwnerId (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
577        Status = AE_OK;
578    }
579
580    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
581    return_ACPI_STATUS (Status);
582}
583
584
585/*******************************************************************************
586 *
587 * FUNCTION:    AcpiTbGetOwnerId
588 *
589 * PARAMETERS:  TableIndex          - Table index
590 *              OwnerId             - Where the table OwnerId is returned
591 *
592 * RETURN:      Status
593 *
594 * DESCRIPTION: returns OwnerId for the ACPI table
595 *
596 ******************************************************************************/
597
598ACPI_STATUS
599AcpiTbGetOwnerId (
600    ACPI_NATIVE_UINT        TableIndex,
601    ACPI_OWNER_ID           *OwnerId)
602{
603    ACPI_STATUS             Status = AE_BAD_PARAMETER;
604
605
606    ACPI_FUNCTION_TRACE (TbGetOwnerId);
607
608
609    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
610    if (TableIndex < AcpiGbl_RootTableList.Count)
611    {
612        *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
613        Status = AE_OK;
614    }
615
616    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
617    return_ACPI_STATUS (Status);
618}
619
620
621/*******************************************************************************
622 *
623 * FUNCTION:    AcpiTbIsTableLoaded
624 *
625 * PARAMETERS:  TableIndex          - Table index
626 *
627 * RETURN:      Table Loaded Flag
628 *
629 ******************************************************************************/
630
631BOOLEAN
632AcpiTbIsTableLoaded (
633    ACPI_NATIVE_UINT        TableIndex)
634{
635    BOOLEAN                 IsLoaded = FALSE;
636
637
638    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
639    if (TableIndex < AcpiGbl_RootTableList.Count)
640    {
641        IsLoaded = (BOOLEAN)
642            (AcpiGbl_RootTableList.Tables[TableIndex].Flags & ACPI_TABLE_IS_LOADED);
643    }
644
645    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
646    return (IsLoaded);
647}
648
649
650/*******************************************************************************
651 *
652 * FUNCTION:    AcpiTbSetTableLoadedFlag
653 *
654 * PARAMETERS:  TableIndex          - Table index
655 *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
656 *
657 * RETURN:      None
658 *
659 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
660 *
661 ******************************************************************************/
662
663void
664AcpiTbSetTableLoadedFlag (
665    ACPI_NATIVE_UINT        TableIndex,
666    BOOLEAN                 IsLoaded)
667{
668
669    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
670    if (TableIndex < AcpiGbl_RootTableList.Count)
671    {
672        if (IsLoaded)
673        {
674            AcpiGbl_RootTableList.Tables[TableIndex].Flags |= ACPI_TABLE_IS_LOADED;
675        }
676        else
677        {
678            AcpiGbl_RootTableList.Tables[TableIndex].Flags &= ~ACPI_TABLE_IS_LOADED;
679        }
680    }
681
682    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
683}
684
685