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