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