xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/tables/tbdata.c (revision 385ee03ba83b7a40d315e17b03031b3ca37820c0)
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 - 2016, 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 #include "acpi.h"
117 #include "accommon.h"
118 #include "acnamesp.h"
119 #include "actables.h"
120 
121 #define _COMPONENT          ACPI_TABLES
122         ACPI_MODULE_NAME    ("tbdata")
123 
124 
125 /*******************************************************************************
126  *
127  * FUNCTION:    AcpiTbInitTableDescriptor
128  *
129  * PARAMETERS:  TableDesc               - Table descriptor
130  *              Address                 - Physical address of the table
131  *              Flags                   - Allocation flags of the table
132  *              Table                   - Pointer to the table
133  *
134  * RETURN:      None
135  *
136  * DESCRIPTION: Initialize a new table descriptor
137  *
138  ******************************************************************************/
139 
140 void
141 AcpiTbInitTableDescriptor (
142     ACPI_TABLE_DESC         *TableDesc,
143     ACPI_PHYSICAL_ADDRESS   Address,
144     UINT8                   Flags,
145     ACPI_TABLE_HEADER       *Table)
146 {
147 
148     /*
149      * Initialize the table descriptor. Set the pointer to NULL, since the
150      * table is not fully mapped at this time.
151      */
152     memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
153     TableDesc->Address = Address;
154     TableDesc->Length = Table->Length;
155     TableDesc->Flags = Flags;
156     ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
157 }
158 
159 
160 /*******************************************************************************
161  *
162  * FUNCTION:    AcpiTbAcquireTable
163  *
164  * PARAMETERS:  TableDesc           - Table descriptor
165  *              TablePtr            - Where table is returned
166  *              TableLength         - Where table length is returned
167  *              TableFlags          - Where table allocation flags are returned
168  *
169  * RETURN:      Status
170  *
171  * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
172  *              maintained in the AcpiGbl_RootTableList.
173  *
174  ******************************************************************************/
175 
176 ACPI_STATUS
177 AcpiTbAcquireTable (
178     ACPI_TABLE_DESC         *TableDesc,
179     ACPI_TABLE_HEADER       **TablePtr,
180     UINT32                  *TableLength,
181     UINT8                   *TableFlags)
182 {
183     ACPI_TABLE_HEADER       *Table = NULL;
184 
185 
186     switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
187     {
188     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
189 
190         Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length);
191         break;
192 
193     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
194     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
195 
196         Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
197             ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
198         break;
199 
200     default:
201 
202         break;
203     }
204 
205     /* Table is not valid yet */
206 
207     if (!Table)
208     {
209         return (AE_NO_MEMORY);
210     }
211 
212     /* Fill the return values */
213 
214     *TablePtr = Table;
215     *TableLength = TableDesc->Length;
216     *TableFlags = TableDesc->Flags;
217     return (AE_OK);
218 }
219 
220 
221 /*******************************************************************************
222  *
223  * FUNCTION:    AcpiTbReleaseTable
224  *
225  * PARAMETERS:  Table               - Pointer for the table
226  *              TableLength         - Length for the table
227  *              TableFlags          - Allocation flags for the table
228  *
229  * RETURN:      None
230  *
231  * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
232  *
233  ******************************************************************************/
234 
235 void
236 AcpiTbReleaseTable (
237     ACPI_TABLE_HEADER       *Table,
238     UINT32                  TableLength,
239     UINT8                   TableFlags)
240 {
241 
242     switch (TableFlags & ACPI_TABLE_ORIGIN_MASK)
243     {
244     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
245 
246         AcpiOsUnmapMemory (Table, TableLength);
247         break;
248 
249     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
250     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
251     default:
252 
253         break;
254     }
255 }
256 
257 
258 /*******************************************************************************
259  *
260  * FUNCTION:    AcpiTbAcquireTempTable
261  *
262  * PARAMETERS:  TableDesc           - Table descriptor to be acquired
263  *              Address             - Address of the table
264  *              Flags               - Allocation flags of the table
265  *
266  * RETURN:      Status
267  *
268  * DESCRIPTION: This function validates the table header to obtain the length
269  *              of a table and fills the table descriptor to make its state as
270  *              "INSTALLED". Such a table descriptor is only used for verified
271  *              installation.
272  *
273  ******************************************************************************/
274 
275 ACPI_STATUS
276 AcpiTbAcquireTempTable (
277     ACPI_TABLE_DESC         *TableDesc,
278     ACPI_PHYSICAL_ADDRESS   Address,
279     UINT8                   Flags)
280 {
281     ACPI_TABLE_HEADER       *TableHeader;
282 
283 
284     switch (Flags & ACPI_TABLE_ORIGIN_MASK)
285     {
286     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
287 
288         /* Get the length of the full table from the header */
289 
290         TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
291         if (!TableHeader)
292         {
293             return (AE_NO_MEMORY);
294         }
295 
296         AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
297         AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER));
298         return (AE_OK);
299 
300     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
301     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
302 
303         TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
304             ACPI_PHYSADDR_TO_PTR (Address));
305         if (!TableHeader)
306         {
307             return (AE_NO_MEMORY);
308         }
309 
310         AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
311         return (AE_OK);
312 
313     default:
314 
315         break;
316     }
317 
318     /* Table is not valid yet */
319 
320     return (AE_NO_MEMORY);
321 }
322 
323 
324 /*******************************************************************************
325  *
326  * FUNCTION:    AcpiTbReleaseTempTable
327  *
328  * PARAMETERS:  TableDesc           - Table descriptor to be released
329  *
330  * RETURN:      Status
331  *
332  * DESCRIPTION: The inverse of AcpiTbAcquireTempTable().
333  *
334  *****************************************************************************/
335 
336 void
337 AcpiTbReleaseTempTable (
338     ACPI_TABLE_DESC         *TableDesc)
339 {
340 
341     /*
342      * Note that the .Address is maintained by the callers of
343      * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable()
344      * where .Address will be freed.
345      */
346     AcpiTbInvalidateTable (TableDesc);
347 }
348 
349 
350 /******************************************************************************
351  *
352  * FUNCTION:    AcpiTbValidateTable
353  *
354  * PARAMETERS:  TableDesc           - Table descriptor
355  *
356  * RETURN:      Status
357  *
358  * DESCRIPTION: This function is called to validate the table, the returned
359  *              table descriptor is in "VALIDATED" state.
360  *
361  *****************************************************************************/
362 
363 ACPI_STATUS
364 AcpiTbValidateTable (
365     ACPI_TABLE_DESC         *TableDesc)
366 {
367     ACPI_STATUS             Status = AE_OK;
368 
369 
370     ACPI_FUNCTION_TRACE (TbValidateTable);
371 
372 
373     /* Validate the table if necessary */
374 
375     if (!TableDesc->Pointer)
376     {
377         Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer,
378             &TableDesc->Length, &TableDesc->Flags);
379         if (!TableDesc->Pointer)
380         {
381             Status = AE_NO_MEMORY;
382         }
383     }
384 
385     return_ACPI_STATUS (Status);
386 }
387 
388 
389 /*******************************************************************************
390  *
391  * FUNCTION:    AcpiTbInvalidateTable
392  *
393  * PARAMETERS:  TableDesc           - Table descriptor
394  *
395  * RETURN:      None
396  *
397  * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
398  *              AcpiTbValidateTable().
399  *
400  ******************************************************************************/
401 
402 void
403 AcpiTbInvalidateTable (
404     ACPI_TABLE_DESC         *TableDesc)
405 {
406 
407     ACPI_FUNCTION_TRACE (TbInvalidateTable);
408 
409 
410     /* Table must be validated */
411 
412     if (!TableDesc->Pointer)
413     {
414         return_VOID;
415     }
416 
417     AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length,
418         TableDesc->Flags);
419     TableDesc->Pointer = NULL;
420 
421     return_VOID;
422 }
423 
424 
425 /******************************************************************************
426  *
427  * FUNCTION:    AcpiTbValidateTempTable
428  *
429  * PARAMETERS:  TableDesc           - Table descriptor
430  *
431  * RETURN:      Status
432  *
433  * DESCRIPTION: This function is called to validate the table, the returned
434  *              table descriptor is in "VALIDATED" state.
435  *
436  *****************************************************************************/
437 
438 ACPI_STATUS
439 AcpiTbValidateTempTable (
440     ACPI_TABLE_DESC         *TableDesc)
441 {
442 
443     if (!TableDesc->Pointer && !AcpiGbl_VerifyTableChecksum)
444     {
445         /*
446          * Only validates the header of the table.
447          * Note that Length contains the size of the mapping after invoking
448          * this work around, this value is required by
449          * AcpiTbReleaseTempTable().
450          * We can do this because in AcpiInitTableDescriptor(), the Length
451          * field of the installed descriptor is filled with the actual
452          * table length obtaining from the table header.
453          */
454         TableDesc->Length = sizeof (ACPI_TABLE_HEADER);
455     }
456 
457     return (AcpiTbValidateTable (TableDesc));
458 }
459 
460 
461 /******************************************************************************
462  *
463  * FUNCTION:    AcpiTbVerifyTempTable
464  *
465  * PARAMETERS:  TableDesc           - Table descriptor
466  *              Signature           - Table signature to verify
467  *
468  * RETURN:      Status
469  *
470  * DESCRIPTION: This function is called to validate and verify the table, the
471  *              returned table descriptor is in "VALIDATED" state.
472  *
473  *****************************************************************************/
474 
475 ACPI_STATUS
476 AcpiTbVerifyTempTable (
477     ACPI_TABLE_DESC         *TableDesc,
478     char                    *Signature)
479 {
480     ACPI_STATUS             Status = AE_OK;
481 
482 
483     ACPI_FUNCTION_TRACE (TbVerifyTempTable);
484 
485 
486     /* Validate the table */
487 
488     Status = AcpiTbValidateTempTable (TableDesc);
489     if (ACPI_FAILURE (Status))
490     {
491         return_ACPI_STATUS (AE_NO_MEMORY);
492     }
493 
494     /* If a particular signature is expected (DSDT/FACS), it must match */
495 
496     if (Signature &&
497         !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
498     {
499         ACPI_BIOS_ERROR ((AE_INFO,
500             "Invalid signature 0x%X for ACPI table, expected [%s]",
501             TableDesc->Signature.Integer, Signature));
502         Status = AE_BAD_SIGNATURE;
503         goto InvalidateAndExit;
504     }
505 
506     /* Verify the checksum */
507 
508     if (AcpiGbl_VerifyTableChecksum)
509     {
510         Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
511         if (ACPI_FAILURE (Status))
512         {
513             ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
514                 "%4.4s 0x%8.8X%8.8X"
515                 " Attempted table install failed",
516                 AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
517                     TableDesc->Signature.Ascii : "????",
518                 ACPI_FORMAT_UINT64 (TableDesc->Address)));
519 
520             goto InvalidateAndExit;
521         }
522     }
523 
524     return_ACPI_STATUS (AE_OK);
525 
526 InvalidateAndExit:
527     AcpiTbInvalidateTable (TableDesc);
528     return_ACPI_STATUS (Status);
529 }
530 
531 
532 /*******************************************************************************
533  *
534  * FUNCTION:    AcpiTbResizeRootTableList
535  *
536  * PARAMETERS:  None
537  *
538  * RETURN:      Status
539  *
540  * DESCRIPTION: Expand the size of global table array
541  *
542  ******************************************************************************/
543 
544 ACPI_STATUS
545 AcpiTbResizeRootTableList (
546     void)
547 {
548     ACPI_TABLE_DESC         *Tables;
549     UINT32                  TableCount;
550 
551 
552     ACPI_FUNCTION_TRACE (TbResizeRootTableList);
553 
554 
555     /* AllowResize flag is a parameter to AcpiInitializeTables */
556 
557     if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
558     {
559         ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
560         return_ACPI_STATUS (AE_SUPPORT);
561     }
562 
563     /* Increase the Table Array size */
564 
565     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
566     {
567         TableCount = AcpiGbl_RootTableList.MaxTableCount;
568     }
569     else
570     {
571         TableCount = AcpiGbl_RootTableList.CurrentTableCount;
572     }
573 
574     Tables = ACPI_ALLOCATE_ZEROED (
575         ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
576         sizeof (ACPI_TABLE_DESC));
577     if (!Tables)
578     {
579         ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
580         return_ACPI_STATUS (AE_NO_MEMORY);
581     }
582 
583     /* Copy and free the previous table array */
584 
585     if (AcpiGbl_RootTableList.Tables)
586     {
587         memcpy (Tables, AcpiGbl_RootTableList.Tables,
588             (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
589 
590         if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
591         {
592             ACPI_FREE (AcpiGbl_RootTableList.Tables);
593         }
594     }
595 
596     AcpiGbl_RootTableList.Tables = Tables;
597     AcpiGbl_RootTableList.MaxTableCount =
598         TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
599     AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
600 
601     return_ACPI_STATUS (AE_OK);
602 }
603 
604 
605 /*******************************************************************************
606  *
607  * FUNCTION:    AcpiTbGetNextTableDescriptor
608  *
609  * PARAMETERS:  TableIndex          - Where table index is returned
610  *              TableDesc           - Where table descriptor is returned
611  *
612  * RETURN:      Status and table index/descriptor.
613  *
614  * DESCRIPTION: Allocate a new ACPI table entry to the global table list
615  *
616  ******************************************************************************/
617 
618 ACPI_STATUS
619 AcpiTbGetNextTableDescriptor (
620     UINT32                  *TableIndex,
621     ACPI_TABLE_DESC         **TableDesc)
622 {
623     ACPI_STATUS             Status;
624     UINT32                  i;
625 
626 
627     /* Ensure that there is room for the table in the Root Table List */
628 
629     if (AcpiGbl_RootTableList.CurrentTableCount >=
630         AcpiGbl_RootTableList.MaxTableCount)
631     {
632         Status = AcpiTbResizeRootTableList();
633         if (ACPI_FAILURE (Status))
634         {
635             return (Status);
636         }
637     }
638 
639     i = AcpiGbl_RootTableList.CurrentTableCount;
640     AcpiGbl_RootTableList.CurrentTableCount++;
641 
642     if (TableIndex)
643     {
644         *TableIndex = i;
645     }
646     if (TableDesc)
647     {
648         *TableDesc = &AcpiGbl_RootTableList.Tables[i];
649     }
650 
651     return (AE_OK);
652 }
653 
654 
655 /*******************************************************************************
656  *
657  * FUNCTION:    AcpiTbTerminate
658  *
659  * PARAMETERS:  None
660  *
661  * RETURN:      None
662  *
663  * DESCRIPTION: Delete all internal ACPI tables
664  *
665  ******************************************************************************/
666 
667 void
668 AcpiTbTerminate (
669     void)
670 {
671     UINT32                  i;
672 
673 
674     ACPI_FUNCTION_TRACE (TbTerminate);
675 
676 
677     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
678 
679     /* Delete the individual tables */
680 
681     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
682     {
683         AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]);
684     }
685 
686     /*
687      * Delete the root table array if allocated locally. Array cannot be
688      * mapped, so we don't need to check for that flag.
689      */
690     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
691     {
692         ACPI_FREE (AcpiGbl_RootTableList.Tables);
693     }
694 
695     AcpiGbl_RootTableList.Tables = NULL;
696     AcpiGbl_RootTableList.Flags = 0;
697     AcpiGbl_RootTableList.CurrentTableCount = 0;
698 
699     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
700 
701     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
702     return_VOID;
703 }
704 
705 
706 /*******************************************************************************
707  *
708  * FUNCTION:    AcpiTbDeleteNamespaceByOwner
709  *
710  * PARAMETERS:  TableIndex          - Table index
711  *
712  * RETURN:      Status
713  *
714  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
715  *
716  ******************************************************************************/
717 
718 ACPI_STATUS
719 AcpiTbDeleteNamespaceByOwner (
720     UINT32                  TableIndex)
721 {
722     ACPI_OWNER_ID           OwnerId;
723     ACPI_STATUS             Status;
724 
725 
726     ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
727 
728 
729     Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
730     if (ACPI_FAILURE (Status))
731     {
732         return_ACPI_STATUS (Status);
733     }
734 
735     if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
736     {
737         /* The table index does not exist */
738 
739         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
740         return_ACPI_STATUS (AE_NOT_EXIST);
741     }
742 
743     /* Get the owner ID for this table, used to delete namespace nodes */
744 
745     OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
746     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
747 
748     /*
749      * Need to acquire the namespace writer lock to prevent interference
750      * with any concurrent namespace walks. The interpreter must be
751      * released during the deletion since the acquisition of the deletion
752      * lock may block, and also since the execution of a namespace walk
753      * must be allowed to use the interpreter.
754      */
755     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
756     Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
757 
758     AcpiNsDeleteNamespaceByOwner (OwnerId);
759     if (ACPI_FAILURE (Status))
760     {
761         return_ACPI_STATUS (Status);
762     }
763 
764     AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
765 
766     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
767     return_ACPI_STATUS (Status);
768 }
769 
770 
771 /*******************************************************************************
772  *
773  * FUNCTION:    AcpiTbAllocateOwnerId
774  *
775  * PARAMETERS:  TableIndex          - Table index
776  *
777  * RETURN:      Status
778  *
779  * DESCRIPTION: Allocates OwnerId in TableDesc
780  *
781  ******************************************************************************/
782 
783 ACPI_STATUS
784 AcpiTbAllocateOwnerId (
785     UINT32                  TableIndex)
786 {
787     ACPI_STATUS             Status = AE_BAD_PARAMETER;
788 
789 
790     ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
791 
792 
793     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
794     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
795     {
796         Status = AcpiUtAllocateOwnerId (
797             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
798     }
799 
800     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
801     return_ACPI_STATUS (Status);
802 }
803 
804 
805 /*******************************************************************************
806  *
807  * FUNCTION:    AcpiTbReleaseOwnerId
808  *
809  * PARAMETERS:  TableIndex          - Table index
810  *
811  * RETURN:      Status
812  *
813  * DESCRIPTION: Releases OwnerId in TableDesc
814  *
815  ******************************************************************************/
816 
817 ACPI_STATUS
818 AcpiTbReleaseOwnerId (
819     UINT32                  TableIndex)
820 {
821     ACPI_STATUS             Status = AE_BAD_PARAMETER;
822 
823 
824     ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
825 
826 
827     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
828     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
829     {
830         AcpiUtReleaseOwnerId (
831             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
832         Status = AE_OK;
833     }
834 
835     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
836     return_ACPI_STATUS (Status);
837 }
838 
839 
840 /*******************************************************************************
841  *
842  * FUNCTION:    AcpiTbGetOwnerId
843  *
844  * PARAMETERS:  TableIndex          - Table index
845  *              OwnerId             - Where the table OwnerId is returned
846  *
847  * RETURN:      Status
848  *
849  * DESCRIPTION: returns OwnerId for the ACPI table
850  *
851  ******************************************************************************/
852 
853 ACPI_STATUS
854 AcpiTbGetOwnerId (
855     UINT32                  TableIndex,
856     ACPI_OWNER_ID           *OwnerId)
857 {
858     ACPI_STATUS             Status = AE_BAD_PARAMETER;
859 
860 
861     ACPI_FUNCTION_TRACE (TbGetOwnerId);
862 
863 
864     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
865     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
866     {
867         *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
868         Status = AE_OK;
869     }
870 
871     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
872     return_ACPI_STATUS (Status);
873 }
874 
875 
876 /*******************************************************************************
877  *
878  * FUNCTION:    AcpiTbIsTableLoaded
879  *
880  * PARAMETERS:  TableIndex          - Index into the root table
881  *
882  * RETURN:      Table Loaded Flag
883  *
884  ******************************************************************************/
885 
886 BOOLEAN
887 AcpiTbIsTableLoaded (
888     UINT32                  TableIndex)
889 {
890     BOOLEAN                 IsLoaded = FALSE;
891 
892 
893     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
894     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
895     {
896         IsLoaded = (BOOLEAN)
897             (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
898             ACPI_TABLE_IS_LOADED);
899     }
900 
901     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
902     return (IsLoaded);
903 }
904 
905 
906 /*******************************************************************************
907  *
908  * FUNCTION:    AcpiTbSetTableLoadedFlag
909  *
910  * PARAMETERS:  TableIndex          - Table index
911  *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
912  *
913  * RETURN:      None
914  *
915  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
916  *
917  ******************************************************************************/
918 
919 void
920 AcpiTbSetTableLoadedFlag (
921     UINT32                  TableIndex,
922     BOOLEAN                 IsLoaded)
923 {
924 
925     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
926     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
927     {
928         if (IsLoaded)
929         {
930             AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
931                 ACPI_TABLE_IS_LOADED;
932         }
933         else
934         {
935             AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
936                 ~ACPI_TABLE_IS_LOADED;
937         }
938     }
939 
940     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
941 }
942