1 /******************************************************************************
2  *
3  * Module Name: tbdata - Table manager data structure functions
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2014, 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 #define __TBDATA_C__
45 
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "acnamesp.h"
49 #include "actables.h"
50 
51 #define _COMPONENT          ACPI_TABLES
52         ACPI_MODULE_NAME    ("tbdata")
53 
54 
55 /*******************************************************************************
56  *
57  * FUNCTION:    AcpiTbInitTableDescriptor
58  *
59  * PARAMETERS:  TableDesc               - Table descriptor
60  *              Address                 - Physical address of the table
61  *              Flags                   - Allocation flags of the table
62  *              Table                   - Pointer to the table
63  *
64  * RETURN:      None
65  *
66  * DESCRIPTION: Initialize a new table descriptor
67  *
68  ******************************************************************************/
69 
70 void
71 AcpiTbInitTableDescriptor (
72     ACPI_TABLE_DESC         *TableDesc,
73     ACPI_PHYSICAL_ADDRESS   Address,
74     UINT8                   Flags,
75     ACPI_TABLE_HEADER       *Table)
76 {
77 
78     /*
79      * Initialize the table descriptor. Set the pointer to NULL, since the
80      * table is not fully mapped at this time.
81      */
82     ACPI_MEMSET (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
83     TableDesc->Address = Address;
84     TableDesc->Length = Table->Length;
85     TableDesc->Flags = Flags;
86     ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
87 }
88 
89 
90 /*******************************************************************************
91  *
92  * FUNCTION:    AcpiTbAcquireTable
93  *
94  * PARAMETERS:  TableDesc           - Table descriptor
95  *              TablePtr            - Where table is returned
96  *              TableLength         - Where table length is returned
97  *              TableFlags          - Where table allocation flags are returned
98  *
99  * RETURN:      Status
100  *
101  * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
102  *              maintained in the AcpiGbl_RootTableList.
103  *
104  ******************************************************************************/
105 
106 ACPI_STATUS
107 AcpiTbAcquireTable (
108     ACPI_TABLE_DESC         *TableDesc,
109     ACPI_TABLE_HEADER       **TablePtr,
110     UINT32                  *TableLength,
111     UINT8                   *TableFlags)
112 {
113     ACPI_TABLE_HEADER       *Table = NULL;
114 
115 
116     switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
117     {
118     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
119 
120         Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length);
121         break;
122 
123     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
124     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
125 
126         Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, TableDesc->Address);
127         break;
128 
129     default:
130 
131         break;
132     }
133 
134     /* Table is not valid yet */
135 
136     if (!Table)
137     {
138         return (AE_NO_MEMORY);
139     }
140 
141     /* Fill the return values */
142 
143     *TablePtr = Table;
144     *TableLength = TableDesc->Length;
145     *TableFlags = TableDesc->Flags;
146     return (AE_OK);
147 }
148 
149 
150 /*******************************************************************************
151  *
152  * FUNCTION:    AcpiTbReleaseTable
153  *
154  * PARAMETERS:  Table               - Pointer for the table
155  *              TableLength         - Length for the table
156  *              TableFlags          - Allocation flags for the table
157  *
158  * RETURN:      None
159  *
160  * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
161  *
162  ******************************************************************************/
163 
164 void
165 AcpiTbReleaseTable (
166     ACPI_TABLE_HEADER       *Table,
167     UINT32                  TableLength,
168     UINT8                   TableFlags)
169 {
170 
171     switch (TableFlags & ACPI_TABLE_ORIGIN_MASK)
172     {
173     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
174 
175         AcpiOsUnmapMemory (Table, TableLength);
176         break;
177 
178     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
179     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
180     default:
181 
182         break;
183     }
184 }
185 
186 
187 /*******************************************************************************
188  *
189  * FUNCTION:    AcpiTbAcquireTempTable
190  *
191  * PARAMETERS:  TableDesc           - Table descriptor to be acquired
192  *              Address             - Address of the table
193  *              Flags               - Allocation flags of the table
194  *
195  * RETURN:      Status
196  *
197  * DESCRIPTION: This function validates the table header to obtain the length
198  *              of a table and fills the table descriptor to make its state as
199  *              "INSTALLED". Such a table descriptor is only used for verified
200  *              installation.
201  *
202  ******************************************************************************/
203 
204 ACPI_STATUS
205 AcpiTbAcquireTempTable (
206     ACPI_TABLE_DESC         *TableDesc,
207     ACPI_PHYSICAL_ADDRESS   Address,
208     UINT8                   Flags)
209 {
210     ACPI_TABLE_HEADER       *TableHeader;
211 
212 
213     switch (Flags & ACPI_TABLE_ORIGIN_MASK)
214     {
215     case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
216 
217         /* Get the length of the full table from the header */
218 
219         TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
220         if (!TableHeader)
221         {
222             return (AE_NO_MEMORY);
223         }
224 
225         AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
226         AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER));
227         return (AE_OK);
228 
229     case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
230     case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
231 
232         TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, 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
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
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
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:    AcpiTbVerifyTable
356  *
357  * PARAMETERS:  TableDesc           - Table descriptor
358  *              Signature           - Table signature to verify
359  *
360  * RETURN:      Status
361  *
362  * DESCRIPTION: This function is called to validate and verify the table, the
363  *              returned table descriptor is in "VALIDATED" state.
364  *
365  *****************************************************************************/
366 
367 ACPI_STATUS
368 AcpiTbVerifyTable (
369     ACPI_TABLE_DESC         *TableDesc,
370     char                    *Signature)
371 {
372     ACPI_STATUS             Status = AE_OK;
373 
374 
375     ACPI_FUNCTION_TRACE (TbVerifyTable);
376 
377 
378     /* Validate the table */
379 
380     Status = AcpiTbValidateTable (TableDesc);
381     if (ACPI_FAILURE (Status))
382     {
383         return_ACPI_STATUS (AE_NO_MEMORY);
384     }
385 
386     /* If a particular signature is expected (DSDT/FACS), it must match */
387 
388     if (Signature &&
389         !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
390     {
391         ACPI_BIOS_ERROR ((AE_INFO,
392             "Invalid signature 0x%X for ACPI table, expected [%s]",
393             TableDesc->Signature.Integer, Signature));
394         Status = AE_BAD_SIGNATURE;
395         goto InvalidateAndExit;
396     }
397 
398     /* Verify the checksum */
399 
400     Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
401     if (ACPI_FAILURE (Status))
402     {
403         ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
404             "%4.4s " ACPI_PRINTF_UINT
405             " Attempted table install failed",
406             AcpiUtValidAcpiName (TableDesc->Signature.Ascii) ?
407                 TableDesc->Signature.Ascii : "????",
408             ACPI_FORMAT_TO_UINT (TableDesc->Address)));
409         goto InvalidateAndExit;
410     }
411 
412     return_ACPI_STATUS (AE_OK);
413 
414 InvalidateAndExit:
415     AcpiTbInvalidateTable (TableDesc);
416     return_ACPI_STATUS (Status);
417 }
418 
419 
420 /*******************************************************************************
421  *
422  * FUNCTION:    AcpiTbResizeRootTableList
423  *
424  * PARAMETERS:  None
425  *
426  * RETURN:      Status
427  *
428  * DESCRIPTION: Expand the size of global table array
429  *
430  ******************************************************************************/
431 
432 ACPI_STATUS
433 AcpiTbResizeRootTableList (
434     void)
435 {
436     ACPI_TABLE_DESC         *Tables;
437     UINT32                  TableCount;
438 
439 
440     ACPI_FUNCTION_TRACE (TbResizeRootTableList);
441 
442 
443     /* AllowResize flag is a parameter to AcpiInitializeTables */
444 
445     if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
446     {
447         ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
448         return_ACPI_STATUS (AE_SUPPORT);
449     }
450 
451     /* Increase the Table Array size */
452 
453     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
454     {
455         TableCount = AcpiGbl_RootTableList.MaxTableCount;
456     }
457     else
458     {
459         TableCount = AcpiGbl_RootTableList.CurrentTableCount;
460     }
461 
462     Tables = ACPI_ALLOCATE_ZEROED (
463         ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
464         sizeof (ACPI_TABLE_DESC));
465     if (!Tables)
466     {
467         ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
468         return_ACPI_STATUS (AE_NO_MEMORY);
469     }
470 
471     /* Copy and free the previous table array */
472 
473     if (AcpiGbl_RootTableList.Tables)
474     {
475         ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
476             (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
477 
478         if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
479         {
480             ACPI_FREE (AcpiGbl_RootTableList.Tables);
481         }
482     }
483 
484     AcpiGbl_RootTableList.Tables = Tables;
485     AcpiGbl_RootTableList.MaxTableCount =
486         TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
487     AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
488 
489     return_ACPI_STATUS (AE_OK);
490 }
491 
492 
493 /*******************************************************************************
494  *
495  * FUNCTION:    AcpiTbGetNextRootIndex
496  *
497  * PARAMETERS:  TableIndex          - Where table index is returned
498  *
499  * RETURN:      Status and table index.
500  *
501  * DESCRIPTION: Allocate a new ACPI table entry to the global table list
502  *
503  ******************************************************************************/
504 
505 ACPI_STATUS
506 AcpiTbGetNextRootIndex (
507     UINT32                  *TableIndex)
508 {
509     ACPI_STATUS             Status;
510 
511 
512     /* Ensure that there is room for the table in the Root Table List */
513 
514     if (AcpiGbl_RootTableList.CurrentTableCount >=
515         AcpiGbl_RootTableList.MaxTableCount)
516     {
517         Status = AcpiTbResizeRootTableList();
518         if (ACPI_FAILURE (Status))
519         {
520             return (Status);
521         }
522     }
523 
524     *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
525     AcpiGbl_RootTableList.CurrentTableCount++;
526     return (AE_OK);
527 }
528 
529 
530 /*******************************************************************************
531  *
532  * FUNCTION:    AcpiTbTerminate
533  *
534  * PARAMETERS:  None
535  *
536  * RETURN:      None
537  *
538  * DESCRIPTION: Delete all internal ACPI tables
539  *
540  ******************************************************************************/
541 
542 void
543 AcpiTbTerminate (
544     void)
545 {
546     UINT32                  i;
547 
548 
549     ACPI_FUNCTION_TRACE (TbTerminate);
550 
551 
552     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
553 
554     /* Delete the individual tables */
555 
556     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
557     {
558         AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]);
559     }
560 
561     /*
562      * Delete the root table array if allocated locally. Array cannot be
563      * mapped, so we don't need to check for that flag.
564      */
565     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
566     {
567         ACPI_FREE (AcpiGbl_RootTableList.Tables);
568     }
569 
570     AcpiGbl_RootTableList.Tables = NULL;
571     AcpiGbl_RootTableList.Flags = 0;
572     AcpiGbl_RootTableList.CurrentTableCount = 0;
573 
574     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
575 
576     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
577     return_VOID;
578 }
579 
580 
581 /*******************************************************************************
582  *
583  * FUNCTION:    AcpiTbDeleteNamespaceByOwner
584  *
585  * PARAMETERS:  TableIndex          - Table index
586  *
587  * RETURN:      Status
588  *
589  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
590  *
591  ******************************************************************************/
592 
593 ACPI_STATUS
594 AcpiTbDeleteNamespaceByOwner (
595     UINT32                  TableIndex)
596 {
597     ACPI_OWNER_ID           OwnerId;
598     ACPI_STATUS             Status;
599 
600 
601     ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
602 
603 
604     Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
605     if (ACPI_FAILURE (Status))
606     {
607         return_ACPI_STATUS (Status);
608     }
609 
610     if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
611     {
612         /* The table index does not exist */
613 
614         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
615         return_ACPI_STATUS (AE_NOT_EXIST);
616     }
617 
618     /* Get the owner ID for this table, used to delete namespace nodes */
619 
620     OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
621     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
622 
623     /*
624      * Need to acquire the namespace writer lock to prevent interference
625      * with any concurrent namespace walks. The interpreter must be
626      * released during the deletion since the acquisition of the deletion
627      * lock may block, and also since the execution of a namespace walk
628      * must be allowed to use the interpreter.
629      */
630     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
631     Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
632 
633     AcpiNsDeleteNamespaceByOwner (OwnerId);
634     if (ACPI_FAILURE (Status))
635     {
636         return_ACPI_STATUS (Status);
637     }
638 
639     AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
640 
641     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
642     return_ACPI_STATUS (Status);
643 }
644 
645 
646 /*******************************************************************************
647  *
648  * FUNCTION:    AcpiTbAllocateOwnerId
649  *
650  * PARAMETERS:  TableIndex          - Table index
651  *
652  * RETURN:      Status
653  *
654  * DESCRIPTION: Allocates OwnerId in TableDesc
655  *
656  ******************************************************************************/
657 
658 ACPI_STATUS
659 AcpiTbAllocateOwnerId (
660     UINT32                  TableIndex)
661 {
662     ACPI_STATUS             Status = AE_BAD_PARAMETER;
663 
664 
665     ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
666 
667 
668     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
669     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
670     {
671         Status = AcpiUtAllocateOwnerId (
672                     &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
673     }
674 
675     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
676     return_ACPI_STATUS (Status);
677 }
678 
679 
680 /*******************************************************************************
681  *
682  * FUNCTION:    AcpiTbReleaseOwnerId
683  *
684  * PARAMETERS:  TableIndex          - Table index
685  *
686  * RETURN:      Status
687  *
688  * DESCRIPTION: Releases OwnerId in TableDesc
689  *
690  ******************************************************************************/
691 
692 ACPI_STATUS
693 AcpiTbReleaseOwnerId (
694     UINT32                  TableIndex)
695 {
696     ACPI_STATUS             Status = AE_BAD_PARAMETER;
697 
698 
699     ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
700 
701 
702     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
703     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
704     {
705         AcpiUtReleaseOwnerId (
706             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
707         Status = AE_OK;
708     }
709 
710     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
711     return_ACPI_STATUS (Status);
712 }
713 
714 
715 /*******************************************************************************
716  *
717  * FUNCTION:    AcpiTbGetOwnerId
718  *
719  * PARAMETERS:  TableIndex          - Table index
720  *              OwnerId             - Where the table OwnerId is returned
721  *
722  * RETURN:      Status
723  *
724  * DESCRIPTION: returns OwnerId for the ACPI table
725  *
726  ******************************************************************************/
727 
728 ACPI_STATUS
729 AcpiTbGetOwnerId (
730     UINT32                  TableIndex,
731     ACPI_OWNER_ID           *OwnerId)
732 {
733     ACPI_STATUS             Status = AE_BAD_PARAMETER;
734 
735 
736     ACPI_FUNCTION_TRACE (TbGetOwnerId);
737 
738 
739     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
740     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
741     {
742         *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
743         Status = AE_OK;
744     }
745 
746     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
747     return_ACPI_STATUS (Status);
748 }
749 
750 
751 /*******************************************************************************
752  *
753  * FUNCTION:    AcpiTbIsTableLoaded
754  *
755  * PARAMETERS:  TableIndex          - Index into the root table
756  *
757  * RETURN:      Table Loaded Flag
758  *
759  ******************************************************************************/
760 
761 BOOLEAN
762 AcpiTbIsTableLoaded (
763     UINT32                  TableIndex)
764 {
765     BOOLEAN                 IsLoaded = FALSE;
766 
767 
768     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
769     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
770     {
771         IsLoaded = (BOOLEAN)
772             (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
773             ACPI_TABLE_IS_LOADED);
774     }
775 
776     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
777     return (IsLoaded);
778 }
779 
780 
781 /*******************************************************************************
782  *
783  * FUNCTION:    AcpiTbSetTableLoadedFlag
784  *
785  * PARAMETERS:  TableIndex          - Table index
786  *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
787  *
788  * RETURN:      None
789  *
790  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
791  *
792  ******************************************************************************/
793 
794 void
795 AcpiTbSetTableLoadedFlag (
796     UINT32                  TableIndex,
797     BOOLEAN                 IsLoaded)
798 {
799 
800     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
801     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
802     {
803         if (IsLoaded)
804         {
805             AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
806                 ACPI_TABLE_IS_LOADED;
807         }
808         else
809         {
810             AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
811                 ~ACPI_TABLE_IS_LOADED;
812         }
813     }
814 
815     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
816 }
817