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:  Table                   - Pointer to the table
941  *              Address                 - Physical address of the table
942  *              Flags                   - Allocation flags of the table
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_TABLE_HEADER       *Table,
954     ACPI_PHYSICAL_ADDRESS   Address,
955     UINT8                   Flags,
956     BOOLEAN                 Override,
957     UINT32                  *TableIndex)
958 {
959     ACPI_STATUS             Status;
960     UINT32                  i;
961     ACPI_OWNER_ID           OwnerId;
962 
963 
964     ACPI_FUNCTION_TRACE (AcpiLoadTable);
965 
966 
967     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
968 
969     /* Install the table and load it into the namespace */
970 
971     Status = AcpiTbInstallStandardTable (Address, Flags, TRUE,
972         Override, &i);
973     if (ACPI_FAILURE (Status))
974     {
975         goto UnlockAndExit;
976     }
977 
978     /*
979      * Note: Now table is "INSTALLED", it must be validated before
980      * using.
981      */
982     Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
983     if (ACPI_FAILURE (Status))
984     {
985         goto UnlockAndExit;
986     }
987 
988     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
989     Status = AcpiNsLoadTable (i, AcpiGbl_RootNode);
990 
991     /* Execute any module-level code that was found in the table */
992 
993     if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
994     {
995         AcpiNsExecModuleCodeList ();
996     }
997 
998     /*
999      * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
1000      * responsible for discovering any new wake GPEs by running _PRW methods
1001      * that may have been loaded by this table.
1002      */
1003     Status = AcpiTbGetOwnerId (i, &OwnerId);
1004     if (ACPI_SUCCESS (Status))
1005     {
1006         AcpiEvUpdateGpes (OwnerId);
1007     }
1008 
1009     /* Invoke table handler if present */
1010 
1011     if (AcpiGbl_TableHandler)
1012     {
1013         (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
1014             AcpiGbl_TableHandlerContext);
1015     }
1016     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1017 
1018 UnlockAndExit:
1019     *TableIndex = i;
1020     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1021     return_ACPI_STATUS (Status);
1022 }
1023