xref: /freebsd/sys/contrib/dev/acpica/components/tables/tbinstal.c (revision 147972555f2c70f64cc54182dc18326456e46b92)
1 /******************************************************************************
2  *
3  * Module Name: tbinstal - ACPI table installation and removal
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, 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 
45 #define __TBINSTAL_C__
46 
47 #include <contrib/dev/acpica/include/acpi.h>
48 #include <contrib/dev/acpica/include/accommon.h>
49 #include <contrib/dev/acpica/include/acnamesp.h>
50 #include <contrib/dev/acpica/include/actables.h>
51 
52 
53 #define _COMPONENT          ACPI_TABLES
54         ACPI_MODULE_NAME    ("tbinstal")
55 
56 
57 /******************************************************************************
58  *
59  * FUNCTION:    AcpiTbVerifyTable
60  *
61  * PARAMETERS:  TableDesc           - table
62  *
63  * RETURN:      Status
64  *
65  * DESCRIPTION: this function is called to verify and map table
66  *
67  *****************************************************************************/
68 
69 ACPI_STATUS
70 AcpiTbVerifyTable (
71     ACPI_TABLE_DESC         *TableDesc)
72 {
73     ACPI_STATUS             Status = AE_OK;
74 
75 
76     ACPI_FUNCTION_TRACE (TbVerifyTable);
77 
78 
79     /* Map the table if necessary */
80 
81     if (!TableDesc->Pointer)
82     {
83         if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
84             ACPI_TABLE_ORIGIN_MAPPED)
85         {
86             TableDesc->Pointer = AcpiOsMapMemory (
87                 TableDesc->Address, TableDesc->Length);
88         }
89 
90         if (!TableDesc->Pointer)
91         {
92             return_ACPI_STATUS (AE_NO_MEMORY);
93         }
94     }
95 
96     /* FACS is the odd table, has no standard ACPI header and no checksum */
97 
98     if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
99     {
100         /* Always calculate checksum, ignore bad checksum if requested */
101 
102         Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
103     }
104 
105     return_ACPI_STATUS (Status);
106 }
107 
108 
109 /*******************************************************************************
110  *
111  * FUNCTION:    AcpiTbAddTable
112  *
113  * PARAMETERS:  TableDesc           - Table descriptor
114  *              TableIndex          - Where the table index is returned
115  *
116  * RETURN:      Status
117  *
118  * DESCRIPTION: This function is called to add an ACPI table. It is used to
119  *              dynamically load tables via the Load and LoadTable AML
120  *              operators.
121  *
122  ******************************************************************************/
123 
124 ACPI_STATUS
125 AcpiTbAddTable (
126     ACPI_TABLE_DESC         *TableDesc,
127     UINT32                  *TableIndex)
128 {
129     UINT32                  i;
130     ACPI_STATUS             Status = AE_OK;
131 
132 
133     ACPI_FUNCTION_TRACE (TbAddTable);
134 
135 
136     if (!TableDesc->Pointer)
137     {
138         Status = AcpiTbVerifyTable (TableDesc);
139         if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
140         {
141             return_ACPI_STATUS (Status);
142         }
143     }
144 
145     /*
146      * Validate the incoming table signature.
147      *
148      * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
149      * 2) We added support for OEMx tables, signature "OEM".
150      * 3) Valid tables were encountered with a null signature, so we just
151      *    gave up on validating the signature, (05/2008).
152      * 4) We encountered non-AML tables such as the MADT, which caused
153      *    interpreter errors and kernel faults. So now, we once again allow
154      *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
155      */
156     if ((TableDesc->Pointer->Signature[0] != 0x00) &&
157        (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
158        (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
159     {
160         ACPI_ERROR ((AE_INFO,
161             "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx",
162             AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ?
163                 TableDesc->Pointer->Signature : "????",
164             *(UINT32 *) TableDesc->Pointer->Signature));
165 
166         return_ACPI_STATUS (AE_BAD_SIGNATURE);
167     }
168 
169     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
170 
171     /* Check if table is already registered */
172 
173     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
174     {
175         if (!AcpiGbl_RootTableList.Tables[i].Pointer)
176         {
177             Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
178             if (ACPI_FAILURE (Status) ||
179                 !AcpiGbl_RootTableList.Tables[i].Pointer)
180             {
181                 continue;
182             }
183         }
184 
185         /*
186          * Check for a table match on the entire table length,
187          * not just the header.
188          */
189         if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
190         {
191             continue;
192         }
193 
194         if (ACPI_MEMCMP (TableDesc->Pointer,
195                 AcpiGbl_RootTableList.Tables[i].Pointer,
196                 AcpiGbl_RootTableList.Tables[i].Length))
197         {
198             continue;
199         }
200 
201         /*
202          * Note: the current mechanism does not unregister a table if it is
203          * dynamically unloaded. The related namespace entries are deleted,
204          * but the table remains in the root table list.
205          *
206          * The assumption here is that the number of different tables that
207          * will be loaded is actually small, and there is minimal overhead
208          * in just keeping the table in case it is needed again.
209          *
210          * If this assumption changes in the future (perhaps on large
211          * machines with many table load/unload operations), tables will
212          * need to be unregistered when they are unloaded, and slots in the
213          * root table list should be reused when empty.
214          */
215 
216         /*
217          * Table is already registered.
218          * We can delete the table that was passed as a parameter.
219          */
220         AcpiTbDeleteTable (TableDesc);
221         *TableIndex = i;
222 
223         if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
224         {
225             /* Table is still loaded, this is an error */
226 
227             Status = AE_ALREADY_EXISTS;
228             goto Release;
229         }
230         else
231         {
232             /* Table was unloaded, allow it to be reloaded */
233 
234             TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
235             TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
236             Status = AE_OK;
237             goto PrintHeader;
238         }
239     }
240 
241     /*
242      * ACPI Table Override:
243      * Allow the host to override dynamically loaded tables.
244      * NOTE: the table is fully mapped at this point, and the mapping will
245      * be deleted by TbTableOverride if the table is actually overridden.
246      */
247     (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc);
248 
249     /* Add the table to the global root table list */
250 
251     Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
252                 TableDesc->Length, TableDesc->Flags, TableIndex);
253     if (ACPI_FAILURE (Status))
254     {
255         goto Release;
256     }
257 
258 PrintHeader:
259     AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
260 
261 Release:
262     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
263     return_ACPI_STATUS (Status);
264 }
265 
266 
267 /*******************************************************************************
268  *
269  * FUNCTION:    AcpiTbTableOverride
270  *
271  * PARAMETERS:  TableHeader         - Header for the original table
272  *              TableDesc           - Table descriptor initialized for the
273  *                                    original table. May or may not be mapped.
274  *
275  * RETURN:      Pointer to the entire new table. NULL if table not overridden.
276  *              If overridden, installs the new table within the input table
277  *              descriptor.
278  *
279  * DESCRIPTION: Attempt table override by calling the OSL override functions.
280  *              Note: If the table is overridden, then the entire new table
281  *              is mapped and returned by this function.
282  *
283  ******************************************************************************/
284 
285 ACPI_TABLE_HEADER *
286 AcpiTbTableOverride (
287     ACPI_TABLE_HEADER       *TableHeader,
288     ACPI_TABLE_DESC         *TableDesc)
289 {
290     ACPI_STATUS             Status;
291     ACPI_TABLE_HEADER       *NewTable = NULL;
292     ACPI_PHYSICAL_ADDRESS   NewAddress = 0;
293     UINT32                  NewTableLength = 0;
294     UINT8                   NewFlags;
295     char                    *OverrideType;
296 
297 
298     /* (1) Attempt logical override (returns a logical address) */
299 
300     Status = AcpiOsTableOverride (TableHeader, &NewTable);
301     if (ACPI_SUCCESS (Status) && NewTable)
302     {
303         NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
304         NewTableLength = NewTable->Length;
305         NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
306         OverrideType = "Logical";
307         goto FinishOverride;
308     }
309 
310     /* (2) Attempt physical override (returns a physical address) */
311 
312     Status = AcpiOsPhysicalTableOverride (TableHeader,
313         &NewAddress, &NewTableLength);
314     if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
315     {
316         /* Map the entire new table */
317 
318         NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
319         if (!NewTable)
320         {
321             ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
322                 "%4.4s %p Attempted physical table override failed",
323                 TableHeader->Signature,
324                 ACPI_CAST_PTR (void, TableDesc->Address)));
325             return (NULL);
326         }
327 
328         OverrideType = "Physical";
329         NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
330         goto FinishOverride;
331     }
332 
333     return (NULL); /* There was no override */
334 
335 
336 FinishOverride:
337 
338     ACPI_INFO ((AE_INFO,
339         "%4.4s %p %s table override, new table: %p",
340         TableHeader->Signature,
341         ACPI_CAST_PTR (void, TableDesc->Address),
342         OverrideType, NewTable));
343 
344     /* We can now unmap/delete the original table (if fully mapped) */
345 
346     AcpiTbDeleteTable (TableDesc);
347 
348     /* Setup descriptor for the new table */
349 
350     TableDesc->Address = NewAddress;
351     TableDesc->Pointer = NewTable;
352     TableDesc->Length = NewTableLength;
353     TableDesc->Flags = NewFlags;
354 
355     return (NewTable);
356 }
357 
358 
359 /*******************************************************************************
360  *
361  * FUNCTION:    AcpiTbResizeRootTableList
362  *
363  * PARAMETERS:  None
364  *
365  * RETURN:      Status
366  *
367  * DESCRIPTION: Expand the size of global table array
368  *
369  ******************************************************************************/
370 
371 ACPI_STATUS
372 AcpiTbResizeRootTableList (
373     void)
374 {
375     ACPI_TABLE_DESC         *Tables;
376 
377 
378     ACPI_FUNCTION_TRACE (TbResizeRootTableList);
379 
380 
381     /* AllowResize flag is a parameter to AcpiInitializeTables */
382 
383     if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
384     {
385         ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
386         return_ACPI_STATUS (AE_SUPPORT);
387     }
388 
389     /* Increase the Table Array size */
390 
391     Tables = ACPI_ALLOCATE_ZEROED (
392         ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount +
393             ACPI_ROOT_TABLE_SIZE_INCREMENT) *
394         sizeof (ACPI_TABLE_DESC));
395     if (!Tables)
396     {
397         ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
398         return_ACPI_STATUS (AE_NO_MEMORY);
399     }
400 
401     /* Copy and free the previous table array */
402 
403     if (AcpiGbl_RootTableList.Tables)
404     {
405         ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
406             (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC));
407 
408         if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
409         {
410             ACPI_FREE (AcpiGbl_RootTableList.Tables);
411         }
412     }
413 
414     AcpiGbl_RootTableList.Tables = Tables;
415     AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT;
416     AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED;
417 
418     return_ACPI_STATUS (AE_OK);
419 }
420 
421 
422 /*******************************************************************************
423  *
424  * FUNCTION:    AcpiTbStoreTable
425  *
426  * PARAMETERS:  Address             - Table address
427  *              Table               - Table header
428  *              Length              - Table length
429  *              Flags               - flags
430  *
431  * RETURN:      Status and table index.
432  *
433  * DESCRIPTION: Add an ACPI table to the global table list
434  *
435  ******************************************************************************/
436 
437 ACPI_STATUS
438 AcpiTbStoreTable (
439     ACPI_PHYSICAL_ADDRESS   Address,
440     ACPI_TABLE_HEADER       *Table,
441     UINT32                  Length,
442     UINT8                   Flags,
443     UINT32                  *TableIndex)
444 {
445     ACPI_STATUS             Status;
446     ACPI_TABLE_DESC         *NewTable;
447 
448 
449     /* Ensure that there is room for the table in the Root Table List */
450 
451     if (AcpiGbl_RootTableList.CurrentTableCount >=
452         AcpiGbl_RootTableList.MaxTableCount)
453     {
454         Status = AcpiTbResizeRootTableList();
455         if (ACPI_FAILURE (Status))
456         {
457             return (Status);
458         }
459     }
460 
461     NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
462 
463     /* Initialize added table */
464 
465     NewTable->Address = Address;
466     NewTable->Pointer = Table;
467     NewTable->Length = Length;
468     NewTable->OwnerId = 0;
469     NewTable->Flags = Flags;
470 
471     ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
472 
473     *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
474     AcpiGbl_RootTableList.CurrentTableCount++;
475     return (AE_OK);
476 }
477 
478 
479 /*******************************************************************************
480  *
481  * FUNCTION:    AcpiTbDeleteTable
482  *
483  * PARAMETERS:  TableIndex          - Table index
484  *
485  * RETURN:      None
486  *
487  * DESCRIPTION: Delete one internal ACPI table
488  *
489  ******************************************************************************/
490 
491 void
492 AcpiTbDeleteTable (
493     ACPI_TABLE_DESC         *TableDesc)
494 {
495 
496     /* Table must be mapped or allocated */
497 
498     if (!TableDesc->Pointer)
499     {
500         return;
501     }
502 
503     switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
504     {
505     case ACPI_TABLE_ORIGIN_MAPPED:
506         AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
507         break;
508 
509     case ACPI_TABLE_ORIGIN_ALLOCATED:
510         ACPI_FREE (TableDesc->Pointer);
511         break;
512 
513     default:
514         break;
515     }
516 
517     TableDesc->Pointer = NULL;
518 }
519 
520 
521 /*******************************************************************************
522  *
523  * FUNCTION:    AcpiTbTerminate
524  *
525  * PARAMETERS:  None
526  *
527  * RETURN:      None
528  *
529  * DESCRIPTION: Delete all internal ACPI tables
530  *
531  ******************************************************************************/
532 
533 void
534 AcpiTbTerminate (
535     void)
536 {
537     UINT32                  i;
538 
539 
540     ACPI_FUNCTION_TRACE (TbTerminate);
541 
542 
543     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
544 
545     /* Delete the individual tables */
546 
547     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
548     {
549         AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
550     }
551 
552     /*
553      * Delete the root table array if allocated locally. Array cannot be
554      * mapped, so we don't need to check for that flag.
555      */
556     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
557     {
558         ACPI_FREE (AcpiGbl_RootTableList.Tables);
559     }
560 
561     AcpiGbl_RootTableList.Tables = NULL;
562     AcpiGbl_RootTableList.Flags = 0;
563     AcpiGbl_RootTableList.CurrentTableCount = 0;
564 
565     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
566     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
567 }
568 
569 
570 /*******************************************************************************
571  *
572  * FUNCTION:    AcpiTbDeleteNamespaceByOwner
573  *
574  * PARAMETERS:  TableIndex          - Table index
575  *
576  * RETURN:      Status
577  *
578  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
579  *
580  ******************************************************************************/
581 
582 ACPI_STATUS
583 AcpiTbDeleteNamespaceByOwner (
584     UINT32                  TableIndex)
585 {
586     ACPI_OWNER_ID           OwnerId;
587     ACPI_STATUS             Status;
588 
589 
590     ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
591 
592 
593     Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
594     if (ACPI_FAILURE (Status))
595     {
596         return_ACPI_STATUS (Status);
597     }
598 
599     if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
600     {
601         /* The table index does not exist */
602 
603         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
604         return_ACPI_STATUS (AE_NOT_EXIST);
605     }
606 
607     /* Get the owner ID for this table, used to delete namespace nodes */
608 
609     OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
610     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
611 
612     /*
613      * Need to acquire the namespace writer lock to prevent interference
614      * with any concurrent namespace walks. The interpreter must be
615      * released during the deletion since the acquisition of the deletion
616      * lock may block, and also since the execution of a namespace walk
617      * must be allowed to use the interpreter.
618      */
619     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
620     Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
621 
622     AcpiNsDeleteNamespaceByOwner (OwnerId);
623     if (ACPI_FAILURE (Status))
624     {
625         return_ACPI_STATUS (Status);
626     }
627 
628     AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
629 
630     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
631     return_ACPI_STATUS (Status);
632 }
633 
634 
635 /*******************************************************************************
636  *
637  * FUNCTION:    AcpiTbAllocateOwnerId
638  *
639  * PARAMETERS:  TableIndex          - Table index
640  *
641  * RETURN:      Status
642  *
643  * DESCRIPTION: Allocates OwnerId in TableDesc
644  *
645  ******************************************************************************/
646 
647 ACPI_STATUS
648 AcpiTbAllocateOwnerId (
649     UINT32                  TableIndex)
650 {
651     ACPI_STATUS             Status = AE_BAD_PARAMETER;
652 
653 
654     ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
655 
656 
657     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
658     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
659     {
660         Status = AcpiUtAllocateOwnerId
661                     (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
662     }
663 
664     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
665     return_ACPI_STATUS (Status);
666 }
667 
668 
669 /*******************************************************************************
670  *
671  * FUNCTION:    AcpiTbReleaseOwnerId
672  *
673  * PARAMETERS:  TableIndex          - Table index
674  *
675  * RETURN:      Status
676  *
677  * DESCRIPTION: Releases OwnerId in TableDesc
678  *
679  ******************************************************************************/
680 
681 ACPI_STATUS
682 AcpiTbReleaseOwnerId (
683     UINT32                  TableIndex)
684 {
685     ACPI_STATUS             Status = AE_BAD_PARAMETER;
686 
687 
688     ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
689 
690 
691     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
692     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
693     {
694         AcpiUtReleaseOwnerId (
695             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
696         Status = AE_OK;
697     }
698 
699     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
700     return_ACPI_STATUS (Status);
701 }
702 
703 
704 /*******************************************************************************
705  *
706  * FUNCTION:    AcpiTbGetOwnerId
707  *
708  * PARAMETERS:  TableIndex          - Table index
709  *              OwnerId             - Where the table OwnerId is returned
710  *
711  * RETURN:      Status
712  *
713  * DESCRIPTION: returns OwnerId for the ACPI table
714  *
715  ******************************************************************************/
716 
717 ACPI_STATUS
718 AcpiTbGetOwnerId (
719     UINT32                  TableIndex,
720     ACPI_OWNER_ID           *OwnerId)
721 {
722     ACPI_STATUS             Status = AE_BAD_PARAMETER;
723 
724 
725     ACPI_FUNCTION_TRACE (TbGetOwnerId);
726 
727 
728     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
729     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
730     {
731         *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
732         Status = AE_OK;
733     }
734 
735     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
736     return_ACPI_STATUS (Status);
737 }
738 
739 
740 /*******************************************************************************
741  *
742  * FUNCTION:    AcpiTbIsTableLoaded
743  *
744  * PARAMETERS:  TableIndex          - Table index
745  *
746  * RETURN:      Table Loaded Flag
747  *
748  ******************************************************************************/
749 
750 BOOLEAN
751 AcpiTbIsTableLoaded (
752     UINT32                  TableIndex)
753 {
754     BOOLEAN                 IsLoaded = FALSE;
755 
756 
757     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
758     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
759     {
760         IsLoaded = (BOOLEAN)
761             (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
762             ACPI_TABLE_IS_LOADED);
763     }
764 
765     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
766     return (IsLoaded);
767 }
768 
769 
770 /*******************************************************************************
771  *
772  * FUNCTION:    AcpiTbSetTableLoadedFlag
773  *
774  * PARAMETERS:  TableIndex          - Table index
775  *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
776  *
777  * RETURN:      None
778  *
779  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
780  *
781  ******************************************************************************/
782 
783 void
784 AcpiTbSetTableLoadedFlag (
785     UINT32                  TableIndex,
786     BOOLEAN                 IsLoaded)
787 {
788 
789     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
790     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
791     {
792         if (IsLoaded)
793         {
794             AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
795                 ACPI_TABLE_IS_LOADED;
796         }
797         else
798         {
799             AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
800                 ~ACPI_TABLE_IS_LOADED;
801         }
802     }
803 
804     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
805 }
806 
807