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