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