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     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
685     Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
686 
687     AcpiNsDeleteNamespaceByOwner (OwnerId);
688     if (ACPI_FAILURE (Status))
689     {
690         return_ACPI_STATUS (Status);
691     }
692 
693     AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
694 
695     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
696     return_ACPI_STATUS (Status);
697 }
698 
699 
700 /*******************************************************************************
701  *
702  * FUNCTION:    AcpiTbAllocateOwnerId
703  *
704  * PARAMETERS:  TableIndex          - Table index
705  *
706  * RETURN:      Status
707  *
708  * DESCRIPTION: Allocates OwnerId in TableDesc
709  *
710  ******************************************************************************/
711 
712 ACPI_STATUS
713 AcpiTbAllocateOwnerId (
714     UINT32                  TableIndex)
715 {
716     ACPI_STATUS             Status = AE_BAD_PARAMETER;
717 
718 
719     ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
720 
721 
722     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
723     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
724     {
725         Status = AcpiUtAllocateOwnerId (
726             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
727     }
728 
729     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
730     return_ACPI_STATUS (Status);
731 }
732 
733 
734 /*******************************************************************************
735  *
736  * FUNCTION:    AcpiTbReleaseOwnerId
737  *
738  * PARAMETERS:  TableIndex          - Table index
739  *
740  * RETURN:      Status
741  *
742  * DESCRIPTION: Releases OwnerId in TableDesc
743  *
744  ******************************************************************************/
745 
746 ACPI_STATUS
747 AcpiTbReleaseOwnerId (
748     UINT32                  TableIndex)
749 {
750     ACPI_STATUS             Status = AE_BAD_PARAMETER;
751 
752 
753     ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
754 
755 
756     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
757     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
758     {
759         AcpiUtReleaseOwnerId (
760             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
761         Status = AE_OK;
762     }
763 
764     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
765     return_ACPI_STATUS (Status);
766 }
767 
768 
769 /*******************************************************************************
770  *
771  * FUNCTION:    AcpiTbGetOwnerId
772  *
773  * PARAMETERS:  TableIndex          - Table index
774  *              OwnerId             - Where the table OwnerId is returned
775  *
776  * RETURN:      Status
777  *
778  * DESCRIPTION: returns OwnerId for the ACPI table
779  *
780  ******************************************************************************/
781 
782 ACPI_STATUS
783 AcpiTbGetOwnerId (
784     UINT32                  TableIndex,
785     ACPI_OWNER_ID           *OwnerId)
786 {
787     ACPI_STATUS             Status = AE_BAD_PARAMETER;
788 
789 
790     ACPI_FUNCTION_TRACE (TbGetOwnerId);
791 
792 
793     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
794     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
795     {
796         *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
797         Status = AE_OK;
798     }
799 
800     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
801     return_ACPI_STATUS (Status);
802 }
803 
804 
805 /*******************************************************************************
806  *
807  * FUNCTION:    AcpiTbIsTableLoaded
808  *
809  * PARAMETERS:  TableIndex          - Index into the root table
810  *
811  * RETURN:      Table Loaded Flag
812  *
813  ******************************************************************************/
814 
815 BOOLEAN
816 AcpiTbIsTableLoaded (
817     UINT32                  TableIndex)
818 {
819     BOOLEAN                 IsLoaded = FALSE;
820 
821 
822     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
823     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
824     {
825         IsLoaded = (BOOLEAN)
826             (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
827             ACPI_TABLE_IS_LOADED);
828     }
829 
830     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
831     return (IsLoaded);
832 }
833 
834 
835 /*******************************************************************************
836  *
837  * FUNCTION:    AcpiTbSetTableLoadedFlag
838  *
839  * PARAMETERS:  TableIndex          - Table index
840  *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
841  *
842  * RETURN:      None
843  *
844  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
845  *
846  ******************************************************************************/
847 
848 void
849 AcpiTbSetTableLoadedFlag (
850     UINT32                  TableIndex,
851     BOOLEAN                 IsLoaded)
852 {
853 
854     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
855     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
856     {
857         if (IsLoaded)
858         {
859             AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
860                 ACPI_TABLE_IS_LOADED;
861         }
862         else
863         {
864             AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
865                 ~ACPI_TABLE_IS_LOADED;
866         }
867     }
868 
869     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
870 }
871 
872 
873 /*******************************************************************************
874  *
875  * FUNCTION:    AcpiTbLoadTable
876  *
877  * PARAMETERS:  TableIndex              - Table index
878  *              ParentNode              - Where table index is returned
879  *
880  * RETURN:      Status
881  *
882  * DESCRIPTION: Load an ACPI table
883  *
884  ******************************************************************************/
885 
886 ACPI_STATUS
887 AcpiTbLoadTable (
888     UINT32                  TableIndex,
889     ACPI_NAMESPACE_NODE     *ParentNode)
890 {
891     ACPI_TABLE_HEADER       *Table;
892     ACPI_STATUS             Status;
893     ACPI_OWNER_ID           OwnerId;
894 
895 
896     ACPI_FUNCTION_TRACE (TbLoadTable);
897 
898 
899     /*
900      * Note: Now table is "INSTALLED", it must be validated before
901      * using.
902      */
903     Status = AcpiGetTableByIndex (TableIndex, &Table);
904     if (ACPI_FAILURE (Status))
905     {
906         return_ACPI_STATUS (Status);
907     }
908 
909     Status = AcpiNsLoadTable (TableIndex, ParentNode);
910 
911     /* Execute any module-level code that was found in the table */
912 
913     if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
914     {
915         AcpiNsExecModuleCodeList ();
916     }
917 
918     /*
919      * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
920      * responsible for discovering any new wake GPEs by running _PRW methods
921      * that may have been loaded by this table.
922      */
923     Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
924     if (ACPI_SUCCESS (Status))
925     {
926         AcpiEvUpdateGpes (OwnerId);
927     }
928 
929     /* Invoke table handler if present */
930 
931     if (AcpiGbl_TableHandler)
932     {
933         (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
934             AcpiGbl_TableHandlerContext);
935     }
936 
937     return_ACPI_STATUS (Status);
938 }
939 
940 
941 /*******************************************************************************
942  *
943  * FUNCTION:    AcpiTbInstallAndLoadTable
944  *
945  * PARAMETERS:  Table                   - Pointer to the table
946  *              Address                 - Physical address of the table
947  *              Flags                   - Allocation flags of the table
948  *              TableIndex              - Where table index is returned
949  *
950  * RETURN:      Status
951  *
952  * DESCRIPTION: Install and load an ACPI table
953  *
954  ******************************************************************************/
955 
956 ACPI_STATUS
957 AcpiTbInstallAndLoadTable (
958     ACPI_TABLE_HEADER       *Table,
959     ACPI_PHYSICAL_ADDRESS   Address,
960     UINT8                   Flags,
961     BOOLEAN                 Override,
962     UINT32                  *TableIndex)
963 {
964     ACPI_STATUS             Status;
965     UINT32                  i;
966     ACPI_OWNER_ID           OwnerId;
967 
968 
969     ACPI_FUNCTION_TRACE (AcpiLoadTable);
970 
971 
972     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
973 
974     /* Install the table and load it into the namespace */
975 
976     Status = AcpiTbInstallStandardTable (Address, Flags, TRUE,
977         Override, &i);
978     if (ACPI_FAILURE (Status))
979     {
980         goto UnlockAndExit;
981     }
982 
983     /*
984      * Note: Now table is "INSTALLED", it must be validated before
985      * using.
986      */
987     Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
988     if (ACPI_FAILURE (Status))
989     {
990         goto UnlockAndExit;
991     }
992 
993     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
994     Status = AcpiNsLoadTable (i, AcpiGbl_RootNode);
995 
996     /* Execute any module-level code that was found in the table */
997 
998     if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
999     {
1000         AcpiNsExecModuleCodeList ();
1001     }
1002 
1003     /*
1004      * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
1005      * responsible for discovering any new wake GPEs by running _PRW methods
1006      * that may have been loaded by this table.
1007      */
1008     Status = AcpiTbGetOwnerId (i, &OwnerId);
1009     if (ACPI_SUCCESS (Status))
1010     {
1011         AcpiEvUpdateGpes (OwnerId);
1012     }
1013 
1014     /* Invoke table handler if present */
1015 
1016     if (AcpiGbl_TableHandler)
1017     {
1018         (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
1019             AcpiGbl_TableHandlerContext);
1020     }
1021     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1022 
1023 UnlockAndExit:
1024     *TableIndex = i;
1025     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1026     return_ACPI_STATUS (Status);
1027 }
1028